Skip to content

Add %context-lens agent for durable owner-side bot run history#5926

Open
wca4a wants to merge 7 commits into
developfrom
wsa/context-lens-agent
Open

Add %context-lens agent for durable owner-side bot run history#5926
wca4a wants to merge 7 commits into
developfrom
wsa/context-lens-agent

Conversation

@wca4a

@wca4a wca4a commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds the %context-lens gall 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:
    • Bot ship: accepts %context-lens-action-1 pokes from the local OpenClaw gateway and fans run records out to configured owners as %context-lens-signal-1 pokes (ames retries until ack).
    • Owner ship: stores runs keyed [bot id-run] with src.bowl as the trust anchor, gives %context-lens-update-1 facts on /v1, and answers /x/recent and /x/run scries with per-bot retention (1000 runs / 90 days), enforced on store, on a daily behn timer, and filtered at read time.
  • Run payloads relay as cords (serialized JSON) rather than $json to keep the agent schema-agnostic.
  • Named %context-lens rather than %lens because %base already bills %lens 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 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:

Test plan

  • desk/tests/app/context-lens.hoon covers configure, run-final fan-out, owner-side store/retention, and scries (backend/run-tests.sh)
  • Exercised end-to-end against dev ship ~malmur-halmex with the gateway and client PRs (run records fan out, facts drive live client updates)

🤖 Generated with Claude Code

wca4a and others added 2 commits June 11, 2026 17:28
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>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread desk/app/context-lens.hoon Outdated
::
=/ prev (~(get by runs) [bot id-run])
=/ comp |(complete ?&(?=(^ prev) complete.u.prev))
=/ =run:l [comp now.bowl payload]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment on lines +68 to +73
++ on-peek
|= =path
^- (unit (unit cage))
?+ path [~ ~]
[%x %recent ~]
``context-lens-update-1+!>(`update:v1:l`[%runs recent:cor])

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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 👍 / 👎.

wca4a and others added 2 commits June 11, 2026 18:30
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>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment on lines +124 to +125
++ max-runs-per-bot 1.000
++ max-run-age ~d90

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant