Add %context-lens agent for durable owner-side bot run history#5926
Add %context-lens agent for durable owner-side bot run history#5926wca4a wants to merge 7 commits into
Conversation
One agent, two roles: the bot ship accepts %context-lens-action-1 pokes from the local gateway and fans run records out to configured owners as %context-lens-signal-1 pokes (ames retries until ack); the owner ship stores runs keyed [bot id-run] with src.bowl as the trust anchor, gives facts on /v1, and answers /x/recent and /x/run scries with per-bot retention (500 runs / 30 days). Named %context-lens rather than %lens because %base already bills %lens (the HTTP dojo API) and gall agent names are global across desks — the collision makes the groups desk commit silently revert. Also fixes arm64/aarch64 vere arch detection in backend/run-tests.sh so the suite runs on Linux arm64. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Embedding the recursive stdlib $json type in mark sample types makes ford's tube nest checks diverge, stack-overflowing every json conversion build for the desk. Payloads are now opaque serialized-JSON cords end to end; the client parses once at the API edge. Also fixes a latent nest-fail in the action mark where `=, enjs:format` shadowed the ship type with its +ship arm. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1398879949
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| :: | ||
| =/ prev (~(get by runs) [bot id-run]) | ||
| =/ comp |(complete ?&(?=(^ prev) complete.u.prev)) | ||
| =/ =run:l [comp now.bowl payload] |
There was a problem hiding this comment.
Preserve the finalized payload on late events
When a %run-event arrives after a %run-final for the same [bot id-run], this keeps complete true but still overwrites payload and received with the partial event. In that out-of-order scenario the durable run record and subsequent /v1 fact can report a completed run while containing only the older partial payload, losing the finalized JSON that clients need for history. Consider ignoring late partial events once prev.complete is true, or keeping the previous final payload.
Useful? React with 👍 / 👎.
The store kept complete sticky but still overwrote payload and received with a late partial, so an out-of-order %run-event after %run-final left a completed run carrying a stale partial payload — and facted it out on /v1. Ignore partials for finalized runs entirely; a re-sent %run-final still overwrites (latest final wins). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a540b3638f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| ++ on-peek | ||
| |= =path | ||
| ^- (unit (unit cage)) | ||
| ?+ path [~ ~] | ||
| [%x %recent ~] | ||
| ``context-lens-update-1+!>(`update:v1:l`[%runs recent:cor]) |
There was a problem hiding this comment.
Restrict run-history scries to the local ship
Because /x/recent and /x/run are answered without the same ?> =(src our):bowl guard used for /v1, any remote ship that can scry this agent can read stored run payloads; /x/recent does not even require guessing a bot/run id. These payloads are described as full bot run records and may contain trigger/context/tool data, so the owner-side store should reject non-local peeks before returning them.
Useful? React with 👍 / 👎.
Guard on-peek with the same src=our assert as on-watch and the action poke, so /x/recent and /x/run only answer local callers. Gall on-peek is not served over the network in current arvo (remote scry covers only explicit publications), so this is defense in depth and guard consistency rather than a live exposure — but the store holds full run payloads, so it should never rely on that staying true. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: be2ca69075
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| cor | ||
| =/ =run:l [complete now.bowl payload] | ||
| =. runs (~(put by runs) [bot id-run] run) | ||
| =. cor (prune bot) |
There was a problem hiding this comment.
Enforce age retention without requiring a new run
When a bot stops sending updates, this write path is the only place that calls +prune, so runs for that bot that later exceed the 30-day limit remain in runs and continue to be returned by /x/recent and /x/run indefinitely. Since these payloads are retained owner-side run history and the feature promises a 30-day retention bound, prune on reads or via a timer/save path as well as on new stores.
Useful? React with 👍 / 👎.
Pruning only ran on new stores, so when a bot went quiet its expired runs stayed in state and kept being served by /x/recent and /x/run indefinitely. Now: - reads filter expired runs (on-peek can't mutate, so the age bound is enforced observably at read time regardless of timer health) - a daily behn timer prunes all bots and re-arms; state bumped %0->%1 so on-load arms it exactly once on upgrade instead of stacking a timer per desk commit - retention widened to ~d90 / 1.000 runs per bot (payloads are capped at 50KB by the gateway, so worst case is ~50MB per bot, typically far less) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 422bfd2ede
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| ++ max-runs-per-bot 1.000 | ||
| ++ max-run-age ~d90 |
There was a problem hiding this comment.
Restore the documented retention bounds
This sets the live retention to 1,000 runs and 90 days, but the feature is documented in this change and described in the commit summary as 500 runs / 30 days. In production that means owner ships retain twice as many opaque payloads and keep them three times longer than clients/operators are told, so runs older than 30 days or beyond 500 per bot will continue to be stored and returned by /x/recent//x/run.
Useful? React with 👍 / 👎.
…ment points Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Summary
%context-lensgall agent (split out of Context lens: bot run inspector (web sidebar + native screens/sheet) #5925 so the ship-side store can land and be vetted independently of the client UI). One agent, two roles:%context-lens-action-1pokes from the local OpenClaw gateway and fans run records out to configured owners as%context-lens-signal-1pokes (ames retries until ack).[bot id-run]withsrc.bowlas the trust anchor, gives%context-lens-update-1facts on/v1, and answers/x/recentand/x/runscries with per-bot retention (1000 runs / 90 days), enforced on store, on a daily behn timer, and filtered at read time.$jsonto keep the agent schema-agnostic.%context-lensrather than%lensbecause%basealready bills%lensand gall agent names are global across desks — the collision makes the groups desk commit silently revert.backend/run-tests.shso the desk test suite runs on Linux arm64.Dependencies
This is the ship-side hub of a three-part stack — it has no code dependencies on the other PRs, but they depend on it:
/v1, scries/x/recent//x/run, and pokes%configurevialensApi. Without this agent, the client's lens subscription no-ops gracefully and the UI shows no run history.Test plan
desk/tests/app/context-lens.hooncovers configure, run-final fan-out, owner-side store/retention, and scries (backend/run-tests.sh)~malmur-halmexwith the gateway and client PRs (run records fan out, facts drive live client updates)🤖 Generated with Claude Code