Order-email triage for NanoClaw: fetches order-related Gmail, maintains the orders SQLite table, and flags recent anomalies (cancellations/refunds, large purchases until delivered, overdue deliveries), with a cadence companion that runs it on a schedule. NanoClaw per-chat overlay tile.
79
99%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
Order-email triage for NanoClaw. Fetches order-related Gmail, keeps the orders SQLite table current, and flags recent anomalies — cancellations/refunds, large purchases until delivered, and overdue deliveries — surfacing only the flagged events so the alert channel stays signal-only.
Per-chat overlay tile. Install via NanoClaw's containerConfig.additionalTiles mechanism.
last_checked, sanitized inside the container before any body reaches the sessionemail_message_id into the orders table; idempotent across overlapping fetch windowsflag-anomalies.py)nightly-order-sync cadence wrapper runs the lookup on a 3-day-capped 15 6 cadence and emits the observable-silence cursor marker the silent-success watchdog readstessl install jbaruch/nanoclaw-ordersAdd to a chat's overlay tile list via update_group_config:
additionalTiles: ["nanoclaw-orders"]Load the overlay at the main or trusted tier. Two reasons: the Gmail fetch reaches Google through the OneCLI gateway, which injects credentials only for main/trusted agents (the untrusted tier runs secretMode: selective and is gated from Google by design), and the orders table lives in messages.db, which is mounted read-write only on main/trusted (read-only filtered copy on untrusted).
None. This container holds no Google credential (jbaruch/nanoclaw#638): the OneCLI TLS-MITM gateway owns the OAuth connection and injects Authorization: Bearer on the wire to the Google API hosts, refreshing the token itself. The fetch sends no auth header and reads no key from the environment — COMPOSIO_API_KEY / COMPOSIO_USER_ID are gone.
The gateway reaches the fetch via HTTPS_PROXY + the mounted CA bundle, both set on the spawn by the orchestrator. When it isn't on the request path, Google answers 401 and the fetch fails closed with an operator-actionable diagnostic rather than retrying.
The skill reads and writes the orchestrator's messages.db under the /workspace/store/ mount (read-write on main/trusted):
| Table | Access | Owner |
|---|---|---|
orders | read+write | this tile |
orders_metadata (last_checked cursor) | read+write | this tile |
nanoclaw-admin's morning-brief and check-email skills read flagged orders from the same orders table; those cross-tile reads resolve because admin co-loads with this overlay in the same chat via the shared store mount.
scripts/fetch-order-emails.py loads four shared helpers owned by nanoclaw-admin's heartbeat skill at runtime via the co-loaded tessl__heartbeat tile mount:
sanitize-email-body.py — sanitize(), applied to every text field inside the container before it reaches the sessiongoogle-rest.py — the native Google REST transport over the OneCLI gateway (google_request, surface_url, and the GatewayNotInjecting / TierAccessRestricted faults)gmail-ops.py — list_messages / get_message against the Gmail REST APIgmail-message.py — flattens a raw users.messages.get resource (nested MIME tree, base64url bodies, raw header list) into sanitized fieldsAll four resolve when admin co-loads with this overlay (the owner's main/trusted chat). The fetch fails closed if any is unavailable.
| Skill | Description |
|---|---|
| check-orders | Fetches order-related emails from Gmail, updates the orders SQLite table, and flags recent anomalies. Use when the user asks about order status, order tracking, order emails, shipment status, purchase alerts, or needs to sync Gmail order data with the orders database. |
| nightly-order-sync | Cadence wrapper (cron 15 6, precheck-gated by a 3-day cadence cursor) that runs check-orders on a schedule, surfaces only its order alerts, and emits the observable-silence cursor marker the silent-success watchdog reads. |
check-orders invokes these deterministic scripts from its SKILL.md steps:
scripts/read-last-checked.py — reads the last_checked cursor from orders_metadatascripts/fetch-order-emails.py — multi-query native Gmail fetch, cross-query dedup, in-container sanitization, compact-row projectionscripts/compute-order-id.py — deterministic SHA-1-prefix order id from (source, order_date, description)scripts/extract-amount.py — extracts the order total from a sanitized email, preferring a labeled total line over any largest-amount pickscripts/classify-order.py — maps sender domain → source and subject/snippet keywords → statusscripts/apply-order.py — upserts an order row on email_message_idscripts/apply-exclusions.py — owns the user-preference exclusion table and matching; unflags matches and emits the id list Step 8 consumes via EXCLUDED_IDSscripts/flag-anomalies.py — applies the anomaly predicates (owns the statuses, dollar threshold, age cutoffs)scripts/get-flagged-orders.py — returns currently-flagged orders for the alert channelscripts/render-order-alerts.py — HTML-escapes flagged rows into the ready-to-send Telegram alert envelopescripts/unflag-orders.py — clears flags the user has acknowledged (ad-hoc, outside the Step 6 flow)scripts/promote-stale-shipped.py — ages shipped orders past the delivery window into the overdue statescripts/within-days.py — date-window predicate helperscripts/write-orders-metadata.py — write-ahead cursor + metadata writerThe nightly-order-sync cadence wrapper carries its own scripts:
scripts/precheck-nightly-order-sync.py — fire-time precheck that gates wake-ups by the cadence cursorscripts/stamp-cursor.py — advances the success cursor after a clean runcheck-orders + its nightly-order-sync cadence wrapper from nanoclaw-admin as a standalone per-chat overlay tile (jbaruch/nanoclaw-admin#319). The wrapper materialises one scheduled_tasks row in chats that load this overlay.See CHANGELOG.md for version history.
skills
check-orders
nightly-order-sync