# 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 guide 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`.

- HTML version: https://rambozambodotdev.gitlab.io/aer1-hub/signal-watch-package.html
- Start free: https://zambo.dev/add/
- Endpoint: https://zambo.dev/mcp
- Verify any receipt: https://zambo.dev/verify/

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. Author: Brennan Zambo.

## 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 https://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 (https://zambo.dev/run/a78b8851-5ab7-4b4d-bf70-a90a46a87b6c), ETH at $2,244.62 (https://zambo.dev/run/b1adb980-2b13-4680-bc97-2b3b4e54c745), and SOL at $91.29 (https://zambo.dev/run/25da9cc8-616d-4383-9498-3aaad7ee5f27), then saved the baseline fact with the rule and all three receipts inside it: https://zambo.dev/run/a6fe88a7-a882-4880-90f8-5437bb05aa7d

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 (https://zambo.dev/run/cb8202ea-3913-468f-b7b8-f281c8cf6122), ETH at $2,245.12 (https://zambo.dev/run/adf91ada-41b8-4253-a396-54fa019d5bdd), and SOL at $91.34 (https://zambo.dev/run/598d63b7-8144-46f8-9707-b4a15169acd8). 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 (https://zambo.dev/run/12b0616b-e825-4574-9501-ac88ef06f2d6) and the quiet-day digest wrapped: https://zambo.dev/handover/121aa53f-1981-4330-9133-49e386aabf1e . 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: https://zambo.dev/handover/8654e4d4-765a-47ef-955a-fa67e84cab6d .)

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: https://zambo.dev/handover/a82cead1-e4e3-4fa9-abee-05baf4c96e80 ; npm install: https://zambo.dev/handover/0048c820-2519-41e8-80b3-c9db1840acc1).

## Audit this run

Pick any link above and open it. Each receipt shows the saved result of that call, and the check at https://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](https://zambo.dev/run/1ff0cf90-aa2f-4aac-8142-9b1dd88fab94)) and its check pass wrapped the digest as [handover ef9b1633](https://zambo.dev/handover/ef9b1633-6096-48f3-8ffd-f64c1c239cbb). From a clean npm install, the bundle byte-identical to the PyPI one, the baseline saved as [e6960255](https://zambo.dev/run/e6960255-9366-468f-bbca-41e879aa225a) and the digest wrapped as [handover d91d82c8](https://zambo.dev/handover/d91d82c8-d6f7-4b4a-bc92-da250f84edef) (wrap receipts [e0d58c41](https://zambo.dev/run/e0d58c41-6687-43d7-a589-c4d84f2d021a) and [5a4f7639](https://zambo.dev/run/5a4f7639-73bb-4bbc-9a14-4a9cf4444c83)). 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.

## 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?** 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.

**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.

**Why save readings on quiet days?** Because a record with gaps on quiet days cannot prove the watch was running. A digest wrapped on every pass, quiet ones included, is the evidence the alert day stands on.

**What does a daily watch cost on the free tier?** 20 calls + 1 wrap-up free every day per agent, pickup always free. Baseline pass 4 counted calls, each check pass 5, the wrap is the free wrap-up. A daily three-signal watch runs free at 5 counted calls a day after day one. Day Pass $0.99 for one agent, unlimited 24 hours; Zambo Pass $29 for one agent for 30 days; one-time payments, never subscriptions.

**Can I run this pattern with no code?** Yes: the paste above, in a chat AI on a loop. The installable package (`pip install zambo-watch`, `npm install zambo-watch`) carries the same paste plus runnable code.

## Related

- This guide as HTML: https://rambozambodotdev.gitlab.io/aer1-hub/signal-watch-package.html
- The package on PyPI: https://pypi.org/project/zambo-watch/
- The package on npm: https://www.npmjs.com/package/zambo-watch
- The package repo: https://github.com/zambodotdev/zambo-signal-watch
- The scheduled agent heartbeat: https://rambozambodotdev.gitlab.io/aer1-hub/scheduled-agent-heartbeat.html
- The swarm shape: https://rambozambodotdev.gitlab.io/aer1-hub/swarm-coordination-on-zambo.html
- The loop by use case: https://rambozambodotdev.gitlab.io/aer1-hub/the-loop-by-use-case.html
- Start free: https://zambo.dev/add/

## The Loop kit

- The data: https://dev.to/rambozambo/4247-callers-came-17-stayed-here-is-the-loop-the-17-run-2o51
- The recipe: https://rambozambodotdev.gitlab.io/aer1-hub/scheduled-agent-heartbeat.html
- The library: https://rambozambodotdev.gitlab.io/aer1-hub/the-loop-by-use-case.html
- The morning shape: https://rambozambodotdev.gitlab.io/aer1-hub/morning-standup-continuity.html
- The switching shape: https://rambozambodotdev.gitlab.io/aer1-hub/pick-up-your-work-in-another-ai.html
- The swarm shape: https://rambozambodotdev.gitlab.io/aer1-hub/swarm-coordination-on-zambo.html
- The watch shape: https://rambozambodotdev.gitlab.io/aer1-hub/signal-watch-package.html
- The starter: https://github.com/zambodotdev/zambo-memory-loop-starter

## 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)](swarm-coordination-on-zambo.html): many agents, one shared job, per-agent receipts, and a coordinator who verifies instead of trusting. Install: `pip install zambo-swarm` or `npm install zambo-swarm`.
- [The daily loop (zambo-loop)](daily-loop-package.html): 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)](verify-pass-package.html): 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-pass` or `npm install zambo-verify-pass`.
- [Delivery proof (zambo-delivery)](delivery-proof-package.html): 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-delivery` or `npm install zambo-delivery`.
- [Signal watch (zambo-watch)](signal-watch-package.html): a baseline remembered, a threshold rule stated, every reading saved, and a digest wrapped whether the rule fires or not. Install: `pip install zambo-watch` or `npm install zambo-watch`.

