Direct answer
The signal watch: remember the baseline, alert only on real movement
A signal watch is one agent checking the same signal on a schedule: an asset price, a lead source, a mention feed, your own receipts and download totals. Reading the signal is the easy part. What breaks is everything around it: the baseline lives in a chat that scrolls away, the threshold is whatever the agent feels that day, quiet days leave no record, and when the alert finally fires nobody can check what it was measured against. Zambo is the layer under the watch: memory that persists between the agent's sessions under its own identity, a verifiable receipt for every call, and a digest handover for every pass. This page teaches the pattern twice: once as a paste for people new to watches, and once at full depth, with a real run and every receipt linked. The whole pattern also ships as an installable agent package: pip install zambo-watch or npm install zambo-watch.
Updated November 2, 2026. First published November 2, 2026. The worked example is a real run executed against the live service on November 2, 2026, with every receipt read back the same day.
New to watches? Start here, no code
You need one chat AI on a loop, or one you check in with daily. Add the Zambo endpoint to it first (the one-step setup at zambo.dev/add), paste the watcher block into its instructions, and tell it what to watch and what move counts as news. It saves the identity (its caller handle) the endpoint issues inside its own conversation, saves the baseline on the first pass, and recalls that baseline on every later pass. Nothing else needs to be built.
The paste, for the watcher:
Run a signal watch on Zambo:
1. Connect to https://zambo.dev/mcp. When the endpoint issues your caller handle, save it in this conversation and present it on every call. Your memory, including the baseline you are about to save, keys to that handle. Keep one job id for the whole watch and reuse it on every pass.
2. First pass only: read the signal (for a price watch, call live_price for each asset). Then save ONE fact with memory_remember: the values, each value's receipt link, and the rule in plain words, for example "alert when any watched asset moves 3 percent or more from its baseline". Keep the remember receipt.
3. Every later pass: recall the baseline with memory_recall and read the values out of the recalled fact. Never work from your chat transcript; the remembered fact is the baseline of record.
4. Read the signal again. Compute each move against the recalled baseline and apply the rule exactly as stated. A move under the threshold is a quiet day, even if it is close.
5. Save the reading with memory_remember either way: the values, the moves, and the rule's outcome. A quiet day with no saved reading is a gap in the record.
6. Wrap the pass with handover: a summary (lead with the alert and the size of the move if the rule fired; say "quiet check, no alert" with the values and moves if it did not), a goal naming the watch and the rule, the operator as recipient, and next steps. Send the operator the handover link. That link is the digest: the record anyone can verify at https://zambo.dev/verify/ .
What a watch actually struggles with
Not the signal. Price feeds, search results, and mention streams are all readable in one call. A watch struggles with time. The baseline was set in a session that ended. The threshold was a sentence in a prompt that got edited twice since. The agent that checked yesterday is not obviously the agent checking today, and on a quiet week there is no evidence the watch ran at all, right up until the day it matters that it did. Every one of those failures is a memory and record failure, and that is the layer this pattern puts on Zambo: the baseline and the rule as one remembered fact under the watcher's own handle, the readings saved pass after pass, and the whole history checkable receipt by receipt.
The pattern
One watch is one job id (a single _session_id the watcher picks once and reuses on every pass) and one identity: the watcher initializes once, is issued its own caller handle, saves that handle, and presents it on every call. Memory keys to the handle, so the baseline the watcher saves on day one is the baseline it recalls on day thirty, across restarts and reconnects, as long as the handle survives. The first pass reads the signal and saves the baseline fact: the values, the source receipts, and the rule in plain words. Each later pass recalls that fact, reads the values back out of it, reads the signal again, computes the moves, applies the rule exactly as stated, saves the reading either way, and wraps a digest handover. When the rule fires, the digest leads with the alert. When it does not, the digest is the quiet format: the values, the moves, and the words "no alert", so a reader can always tell a checked quiet day from a day the watch never ran.
The real run: a three-asset price watch, one fresh identity
November 2, 2026, one fresh identity (signal-watch-demo), one job id (signal-watch-2026-11-02), run with the package's own watch.py. The rule, stated in the baseline fact: alert when any watched asset moves 3 percent or more from its baseline.
The baseline pass (20:45 UTC) read BTC at $76,800.00 (receipt), ETH at $2,244.62 (receipt), and SOL at $91.29 (receipt), then saved the baseline fact with the rule and all three receipts inside it: the baseline, saved.
The canonical check pass recalled the baseline from memory alone (BTC 76800.0, ETH 2244.62, SOL 91.29, verbatim), then read BTC at $76,793.00 (receipt), ETH at $2,245.12 (receipt), and SOL at $91.34 (receipt). The moves: BTC -0.01 percent, ETH +0.02 percent, SOL +0.05 percent. No asset reached 3 percent, so the rule returned no alert, and that is what the record says: the reading saved (receipt) and the quiet-day digest wrapped: the digest handover. A check run minutes after its baseline should be quiet; a digest that cried alert here would be the failure. (An earlier check pass the same hour returned the same honest shape: its digest.)
The package also proves itself from fresh installs: the copies of watch.py installed from PyPI and from npm were each run baseline plus check against the live endpoint by separate fresh identities, and each wrapped its own digest (PyPI install's digest, npm install's digest).
Audit this run
Pick any link above and open it. Each receipt shows the saved result of that call, and the check at zambo.dev/verify recomputes whether the saved result was changed after it was saved. The digest handover lists the pass's steps, each opening to its own receipt. A receipt proves the saved result was not changed since it was saved; it does not prove the price was right, and nothing on this page claims otherwise. If a receipt from this run ever fails to verify, that is news and worth reporting to brennanzambo@zambo.dev.
Step zero, at depth: one handle, one watch
The watcher initializes once and is issued a caller handle (in the initialize result and the X-Zambo-Caller-Handle header). It saves that handle in its own state file before making any other call, and presents it as _caller_handle on every call, with its name as _caller_label. Memory, job timelines, and the daily free allowance all key to the handle. A second watch gets its own handle: two watches sharing one handle share one memory, and their baselines collide. The heartbeat demo that runs publicly every day on this estate holds a different identity from the watch in the run above for exactly that reason: one handle per watch, never shared, never reused across watches.
Quota rule, in the placement that works: Put _caller_handle inside the tool arguments on every call, as a field of the arguments object itself, not in _meta and not in a header. That argument placement is what meters your own daily bucket. Presenting a handle only at _meta level or in a header can route you onto a shared network bucket and wall you early.
Why quiet days get wrapped
The wrap is a handover: a summary, a goal, a named recipient, and next steps. A handover call without a summary and a recipient is refused, with its own receipt; a digest is a deliverable being published and it is held to that standard. The quiet format exists because the alert format cannot be trusted without it. If digests only appear on alert days, then a missing digest is ambiguous: quiet, or broken. When every pass wraps, the absence of a digest is itself a signal, and a reader scanning a month of digests sees the watch's whole life: baseline, readings, moves, and the one day the rule fired, each step opening to its receipt.
Proof the installed package runs
The run above was executed from source. The shipped package was then installed fresh, twice, and run from the installed copy both times. From a clean Python environment, pip install zambo-watch saved its baseline (1ff0cf90) and its check pass wrapped the digest as handover ef9b1633. From a clean npm install, the bundle byte-identical to the PyPI one, the baseline saved as e6960255 and the digest wrapped as handover d91d82c8 (wrap receipts e0d58c41 and 5a4f7639). What installs is what runs.
The accounting: what a watch costs
The free tier is per agent: 20 calls + 1 wrap-up free every day, keyed to the watcher's own caller handle, and picking up a handover is always free. The run on this page cost 4 counted calls for the baseline pass (3 prices and the baseline save) and 5 per check pass (the recall, 3 prices, the reading save); the digest wrap was the free daily wrap-up and left the counter untouched. Run once a day, a three-signal watch costs 5 counted calls a day after day one, well inside free. Past free, the line is per agent: a Day Pass is $0.99 for one agent, unlimited for 24 hours; the Zambo Pass is $29 for one agent for 30 days. One-time payments, never subscriptions. Three watches are three identities with three allowances: the estate's own public heartbeat demo, this package's run identity, and the fresh-install identities all ran today without touching each other's counters.
Standing instructions, at depth
The code route is the package's watch.py: python3 watch.py baseline on the first pass and python3 watch.py check on every later pass, with the identity persisted in a state file next to the script. Symbols, threshold, job id, and label are environment settings (ZAMBO_WATCH_SYMBOLS, ZAMBO_WATCH_THRESHOLD, ZAMBO_WATCH_JOB, ZAMBO_WATCH_LABEL), so the same file watches leads or mentions by changing what the passes read. Scheduling belongs to the reader: wire the check pass to a cron line, a framework scheduler, or a daily standup job. One caution from the record: one check per scheduled pass. A watch that checks five times an hour spends its allowance proving nothing moved; a watch that checks once a day and saves every reading builds the record that makes the alert believable when it finally fires.
What Zambo is not here
Zambo is not a scheduler and does not start the watcher's passes. It does not pick the threshold: 3 percent on three assets is the worked example, and the right rule for a lead watch or a mention watch is the operator's call, stated inside the baseline fact where a reader can argue with it. It does not make the signal correct. What it does is give the watch a memory that survives the session, a rule that cannot quietly drift, and a record where every number the digest cites opens to its own receipt.
Frequently asked questions
What is a signal watch, in plain words?
A signal watch is one agent checking the same signal again and again on a schedule: an asset price, a lead source, a mention feed, a number of your own. On the first pass the agent saves a baseline and the rule it will judge by. On every later pass it recalls the baseline, reads the signal again, computes the move, and reports a digest: an alert when the rule fires, a quiet note when it does not. The watching is the easy part. The pattern exists to fix what usually breaks: the baseline, the rule, and the record of the quiet days.
Does Zambo run the schedule?
No. Your cron, your agent loop, or your framework's scheduler starts each pass. Zambo is where the watch's memory and record live between passes: the baseline as a remembered fact under the agent's own caller handle, every reading saved, and a verifiable receipt for every call, so an alert can always be traced back to the baseline it was measured against.
Why save readings on quiet days, when nothing moved?
Because a record with gaps on quiet days cannot prove the watch was running. When the alert finally fires, the first question is whether the baseline and the passes before it are real. A digest wrapped on every pass, quiet ones included, is the evidence. It also costs nothing extra in kind: the check pass is 5 counted calls whether or not the reading gets saved, and saving it is what makes the watch a record instead of a rumor.
What does a daily watch cost on the free tier?
The free tier is per agent: 20 calls + 1 wrap-up free every day for the agent's own caller handle, and picking up a handover is always free. The run on this page cost 4 counted calls for the baseline pass and 5 per check pass, and the digest wrap was the free daily wrap-up. A daily three-signal watch therefore runs free at 5 counted calls a day after day one. When a watch outgrows the free tier, a Day Pass makes that agent unlimited for 24 hours for $0.99, and the Zambo Pass covers an agent for 30 days for $29; both are one-time payments, never subscriptions.
Can I run this pattern with no code?
Yes. Add https://zambo.dev/mcp to a chat AI, paste the watcher block from the start-here section of this guide into its instructions, and put the check pass on whatever loop the chat runs on. The AI saves the caller handle it is issued inside its conversation, saves the baseline on the first pass, and recalls it on every later pass. It is the same pattern the code runs, worked by hand. The installable package (pip install zambo-watch, npm install zambo-watch) carries the same paste plus runnable code.
Related
- This guide as plain markdown, for agent readers
- The package on PyPI: pip install zambo-watch
- The package on npm: npm install zambo-watch
- The package repo: zambo-signal-watch, a template you can take
- The scheduled agent heartbeat: pick up free, work, wrap the proof
- The swarm shape: many agents, one shared job, per-agent receipts
- The loop by use case: one routine, pre-built for every daily job
The Loop kit
One routine, every piece of it in one place: the data that found the loop, the recipe, the library of pre-built jobs, the two shapes a daily loop takes, and a starter repo with Zambo already wired in.
- The data: 4,247 callers came, 17 stayed, and the loop the 17 run
- The recipe: the scheduled agent heartbeat
- The library: the loop pre-built for every daily job
- The morning shape: the standup that reads what your agents did overnight
- The switching shape: start in one AI, pick the work up in another, free
- The swarm shape: many agents, one shared job, per-agent receipts
- The watch shape: a baseline the agent remembers, an alert it can prove
- The starter: zambo-memory-loop-starter, clone it and run the loop today
- Start free: add Zambo to your AI in two minutes
The package family
One pattern per package, each teaching by doing, with Zambo as the mechanism inside. Five guides, one family:
- Swarm coordination (zambo-swarm): many agents, one shared job, per-agent receipts, and a coordinator who verifies instead of trusting. Install:
pip install zambo-swarmornpm install zambo-swarm. - The daily loop (zambo-loop): recall, work, remember, wrap. One standing agent whose memory compounds across sessions. Registry release in progress (see that guide for the source route that works today).
- Verify pass (zambo-verify-pass): check another agent's work against its own record before relying on it, and record the verdict as its own receipted step. Install:
pip install zambo-verify-passornpm install zambo-verify-pass. - Delivery proof (zambo-delivery): client work wrapped as one handover the client opens and checks, with the pickup and sign-off as the acceptance record. Install:
pip install zambo-deliveryornpm install zambo-delivery. - Signal watch (zambo-watch): a baseline remembered, a threshold rule stated, every reading saved, and a digest wrapped whether the rule fires or not. Install:
pip install zambo-watchornpm install zambo-watch.