Repository navigation
add per-chat and per-gadget observation tracking - #881
maxwellpeterson wants to merge 10 commits into
Conversation
49f582a to
6fedeb0
Compare
Preview:
|
|
Review: 1 finding. Posted one P2 inline comment, verified with a focused Node reproduction. |
|
Review: 2 findings. Posted two inline comments—one P1 and one P2—both verified with focused Node reproductions. |
|
Review: 1 finding. Posted one new P1 inline comment, verified with a focused Node reproduction. Existing findings were not reposted. |
|
Review: 3 findings. The three existing open inline findings still apply, confirmed with focused reproductions against the current ledger implementation. No additional actionable issues found. |
|
LGTM! |
|
Review: 1 finding. Posted one P1 inline comment, verified with a focused reproduction using the actual admission and ledger code. |
|
LGTM! |
|
💬 Approved with comments — The ledger design holds up and no security problems were found. One WARNING: every legacy connection now makes an uncached describe() call on each use, and if that call fails the connection is refused. Two INFO notes: a regression test was deleted without a replacement, and admission cost has no upper bound. Findings: 1 warning · 2 info The decision is advisory: this comment never approves, blocks or requests changes on the pull request. 🔧 Fix with your agentPaste the following into your coding agent to investigate and fix these issues. 📋 Code Quality:
|
deregtd
left a comment
There was a problem hiding this comment.
Completed the full 17-file review at 89a5d575cff0eb1f483c08263dbe08db6f9d06c0 (base 835de9e8776429fc16781edbe66367d879a64b87). No additional blocking finding. The five earlier inline findings are verified resolved; the exact-head observer ledger and verification regression suites pass all 82 tests in real SQLite Durable Objects, including oversized persistence and rollback cases.
Follow-up to the inconclusive Worker Logs eval: I replayed trial 9's saved final server through the real Workshop draft GadgetClient.connectToGadget(chatId) path, with frozen dependencies. The first reset() RPC fails with an internal error on both this head and its exact base, before any ingestion batch. The same saved server's reset/ingest/summary succeeds directly in a SQLite Gadget DO. This localizes the failing call and demonstrates that this failure already exists before this PR; it does not establish an observation-tracking regression. The underlying Workshop/runtime cause remains unlocalized.
Current required build/tests, lint and CLA checks pass. Validation used local Workers with external requests intercepted; no live provider/model calls, forced-eviction acceptance run or remote CI rerun.
|
LGTM! |
- scope hook observations to receiving gadget if possible - improve subresource observation log read efficiency - add cursor-based pagination for historical observation import
14b2bdc to
61642d7
Compare
|
LGTM! |
|
LGTM! |
|
LGTM! |
Eval resultsVerdict: ⚪ Unchanged. No task moved beyond what these runs can tell apart from noise.
Failed checks
|
🔬 Eval runs reviewPerformanceAgainst main, change-calendar passed 10/10 → 9/10, chess 7/10 → 9/10, and incident-desk and worker-logs each 8/10 → 10/10; ticket-triage-agent and both compaction cases stayed fully passing, with no pass-rate or prompt-cache change beyond noise. Costs were mixed: change-calendar averaged $0.0241 → $0.0207 per run, while chess averaged $0.0430 → $0.0638. Chess accounted for the largest step increase, 45.3 → 65.1, and took 7.3 → 10.1 minutes: nine rather than seven runs reached the PGN/draw extensions, with repeated edits and lengthy implementation probes in successful trajectories. ⚪ VERDICT: NO REGRESSION FROM THIS PRThe diff adds observer attribution and verification, but the candidate’s two failed runs contain identifiable generated-code mistakes, and neither the pass-rate changes nor the mixed cost and timing changes establish a PR-caused effect. TriageFailure modes
Tool errors
What to do
|
Why
We're moving towards a world where observer verification runs independently for every chat thread and gadget in a workspace, so users aren't locked out of an entire workspace just because they don't have access to data observed in a single chat thread or gadget. This PR lays the groundwork for that model.
Summary of Changes
This PR adds a new observation tracking API for gatekeepers to use, which moves most observation bookkeeping out of the gatekeeper and into the overseer. Instead of gatekeepers tracking observed resources internally, they can now report a unique list of subresource IDs that were read when recording an observation. These resource IDs are are stored by the overseer as part of the observation's entry in the workspace activity log and verified in bulk by calling
GatekeeperUserVerifier.verifyObserverAccess(subresources)for each user's connected account.To facilitate migration from the old observation tracking API, gatekeepers that opt in to the new API must also implement a bulk import method for reading previously observed subresource IDs out of the gatekeeper facet's state and into the overseer. This bulk import method is only called when a gatekeeper upgrades to the new API after being added to a workspace.
Limitations / Security Holes
Observations made indirectly using capabilities passed between chat threads or gadgets are not correctly attributed to the caller. Observations made using external capabilities are always attributed to the context (chat thread or gadget) that the capability originated from, regardless of the context in which the capability is called. This gap could be closed in the future by wrapping each gadget and
executeCoderun in a membrane that tracks cross-context capability transfer and method calls, if such a membrane API existed.Deleting a gatekeeper connection causes observations recorded from that connection to start being ignored, and unblocks users who can't access the observed data from joining the workspace. This matches the current behavior on main. However, because observation history is now owned by the overseer instead of the gatekeeper facet, it would be much easier to continue verifying these observations after the connection is deleted if we wanted to. I stuck with the current behavior but wanted to flag that this as something we could change if we wanted to.
Observations made by chat threads do not transfer to gadgets when the chat thread calls the gadget or edits its code. Of course, chat threads may leak data to gadgets that is not caught by observer verification, but at the same time a full observation history transfer feels too conservative here.
Conversely, observations made by a gadget do not transfer to chat threads that call that gadget. As implemented, the only users who can see chat threads can also see (and pass observer verification for) all gadgets in the workspace. Transferring observation history in this case adds no sharing security benefit, since access to chat threads implies access to all gadgets. In a future world where users can join any shared workspace and only see chat threads and gadgets they have access to, gadget to chat thread observation inheritance will need to be implemented. For now it's left out of scope.
No gatekeepers currently implement this API. Every gatekeeper we own will need to be migrated, which shouldn't be too hard.