Repository navigation
feat(assistant): add tested condition waits and simplify Matter settlement - #6193
Conversation
4bd39d5 to
5b9a325
Compare
Astro-Han
left a comment
There was a problem hiding this comment.
Automated review notice: This comment was posted by an automated review agent. It is not an independent human review and does not replace one.
Reviewed 5b9a325821bd44ac04ec4582df6c1f5c7c492630 against main dc4515cd6e7637e8267d59cd4f71ad53f403f9e7. The rebase removes the already merged #6177 prerequisite; the feature commit is equivalent and the complete tree is identical to the previously tested 4bd39d597c6c33d90831e32519a241a92ac20d8a (tree 762e45a92fafa1699a430d4e65fd33261e0b57f1). The earlier conflict in proactive-matters/controller.ts is resolved; the current trial merge is clean.
The change adds tested, sandboxed read-only condition checkers and durable Matter observation records, reuses the event-wait observation engine, and replaces draft/revision arguments to MatterSettle with inline notes and a Host-verified delivered-input boundary. I checked installation/settlement transactions, observation revisions and leases, checkpoints, source permission checks, deadline/cancellation races, restart, review invalidation, submission replay, worker tool filtering, and existing task-data compatibility.
One P2 remains: docs/matter-condition-waits.md:1 lacks its required ASF header. Exact-head CI run 39413553154 fails at check:asf-headers on this file. The local check reports the same sole missing header; applying the unchanged classifier to current main's source archive finds none missing. Please add the normal Markdown ASF header and rerun CI.
I did not establish another P0–P2 runtime defect in the exercised paths. The existing Goal entry point still authenticates its storage writer and strictly decodes Goal leases; Matter uses its own lease/revision-checked store without creating a Goal or replacing Goal continuation authority. The Host protocol is unchanged, and the epoch guard passes at 225; this change does not allocate epoch 226.
Validation completed:
- Fresh dependencies/patching, normal clean root test build, all workspace type checks, lint, format and
git diff --checkpassed on the identical final tree. - 325 original event-wait/condition/settlement tests and all 189 native assistant tests passed. These include the registered condition-tool flow, same-session wakeup, review rejection/invalidation and replay behavior, with controlled agents/reviewers and source responses.
- Six additional orderings of source completion, deadline and cancellation passed, including reopen checks; a noncooperative source timed out and still produced exactly one independent deadline event.
- A database created by current main reopened under the new code with its notes, time wait, completed task and paused task preserved; the old time wait became due and could be claimed in its original session.
- The additional runtime/cache/Host group completed 481 passed, 1 failed. The failure is the existing Bash result/workspace-directory assertion; replacing the changed production modules with current main's versions reproduces the same failure at the same assertion, so I am not attributing it to this PR.
I did not run the full repository suite, desktop/Windows checks, or independently repeat the paid-model latency comparison or multi-day operation across repeated compaction. The current CI failure must be fixed before treating this head as green.
| @@ -0,0 +1,155 @@ | |||
| # Matter condition waits | |||
There was a problem hiding this comment.
[P2] Add the required ASF header to the new document
This new Markdown file has no ASF license header. CI run 39413553154 for the exact current head fails in npm run check:asf-headers, naming only this file; the local check reproduces it. The same classifier reports no missing headers in current main's source archive. Add the repository's normal Markdown ASF header so the CI job can reach the build and test stages.
There was a problem hiding this comment.
AI-assisted follow-up (OpenAI Codex): verified at current head 466338d849e1d121f9156d31734d474b1e184089 that docs/matter-condition-waits.md now starts with the standard ASF Markdown header (added in 5dd3afb58). No additional code change is needed for this finding. Leaving thread resolution to the reviewer.
Astro-Han
left a comment
There was a problem hiding this comment.
Automated review notice: This comment was posted by an automated review agent. It is not an independent human review and does not replace one.
Incremental review of 5b9a325821bd44ac04ec4582df6c1f5c7c492630 → 5c9103515359ed42b2a35e442eca1bec97e3866c. The only change adds the standard ASF header to docs/matter-condition-waits.md; the document content and all runtime sources are unchanged.
The previous P2 is fixed. The repository's actual header audit passes over the complete current source archive (4,594 covered files), and the exact current head's test check passes. No new P0–P2 findings in this increment. The earlier runtime, restart and condition-wait evidence remains applicable to the unchanged code; I did not repeat that full runtime suite for a license-header-only change.
CI is not entirely green: the current audit job fails on shipped dependency advisories for MCP client/server, follow-redirects and Hono. The dependency manifests, lockfile, audit script and workflow are unchanged from current main; this is a shared dependency blocker, not a newly introduced defect in this header fix.
Astro-Han
left a comment
There was a problem hiding this comment.
Automated review notice: This comment was posted by an automated review agent. It is not an independent human review and does not replace one.
Second-lineage review of #6193 at head 5c9103515359ed42b2a35e442eca1bec97e3866c. I reviewed main dc4515cd (the merge-base, which is also main's current tip) through the head: two commits, 33 files, +2445/-139. This is my first review of this PR from this lineage, so there are no earlier findings of mine to carry forward.
Verdict: no P0-P2 defects found. I have three P3 notes.
What I checked
- Goal boundary (#6147).
HostEventWaitManageris now a subclass of a new owner-neutralHostEventWaitObserver, and the Goal path still keeps its protections:- The authenticated
InteractiveEventWaitAuthorityWriteris still required. - The strict
decodeEventWaitRecordstill runs on every commit and authorize call. assertEventWaitTransitionstill rejects any change togoalControlLease.- Matter waits live only in the Matter SQLite file (
matter_conditions,matter_checkers,matter_condition_sources) under providermatter. They are fenced by the Matterplugin_lease. No Goal record, Goal store or Goal lease is created or loosened. The test that checks Goal decoding stays strict covers this.
- The authenticated
- Timeout, cancel and wake races. Every way a wait ends goes through a revision compare-and-set on
matter_conditionsinside the Matter transaction: observer commit, time-fallbackexpire,retireon claim, user input, and pause/cancel/check. The observer can only commit while the matter still has thisconditionWaitId, iswaiting, and has no active run. Wake events use the keycondition:<waitId>underUNIQUE(matter_id,event_key), so a late source result and the fallback cannot both deliver a wake. Observation cannot start until the activation clears, which happens only after the run finishes. - Settlement, old versus new.
expectedRevisionand the draft file are replaced by a hash ("basis") of the inbox context that was actually delivered, read back from runtime events. Settlement then sets the event cursor to exactly that delivered batch. If the delivered context is missing or stale, settlement fails closed withMATTER_REVIEW_INVALIDATED. Replays keep the stored revision and state throughmatter_submissionskeyed by operation ID, and reusing an ID with different arguments is rejected. I found no regression in invalidation or idempotency. Old review rows that were recorded with a draft basis no longer match, so they fail closed. - Old database upgrade. All new tables use
CREATE TABLE IF NOT EXISTS.conditionWaitIdis optional, so older matters take the existing time-wake path unchanged.recover()behaves as before. - Restart recovery. The pending cursor, source reservations and the time fallback are all durable. The observer starts after the lease is taken and errors from it do not block time fallbacks. The tests for restart and for a lost lease handing over to a new owner both pass.
- Protocol epoch. No protocol or epoch files are touched, so there is no epoch impact.
Findings
- P3, observation budget.
condition-observer.ts:41setsmaxAttempts: 1_000_000, butintervalMscan be as low as 1000 and the fallback up to 366 days. With intervals under about 31 s, the observer runs out of attempts before the fallback (after about 11.6 days at 1 s). It then resolvessource_unavailablewith reasonobservation_budget_exhaustedand wakes the worker early with no evidence. Nothing is lost, because the worker can re-wait. But neither the tool description nor the docs mention this. Either boundintervalMsagainst the fallback length or document the early wake. - P3, draft behaviour change.
MatterSettleno longer readsdraft.md, whileMatterWriteFileis kept as a "legacy" editor. A worker that editsdraft.mdand then calls settle withoutnoteand withoutMatterCheckpointsilently keeps the previous note. This is intended and documented, so I list it only as a behaviour change. - P3, housekeeping. Rows in
matter_submissions,matter_checkersand retiredmatter_conditionsare never pruned.deliveredInputreads every runtime event in the session whenrunIdis absent. Neither is a correctness issue.
Tests I ran locally (built core, storage, mcp, runtime and runtime-host):
matter-conditions,matter-settlement-contextandevent-wait-manager(dist): 285/285 pass.- The proactive-matters assistant suite: 80/80 pass. Two files first failed only because the sibling index-initiative test artifacts had not been prepared; they pass once prepared.
CI and mergeability. test passes and the PR is MERGEABLE (state UNSTABLE). audit is red, which is the repo-wide dependency-advisory failure. This PR only adds a ./code-mode export to packages/runtime/package.json, with no dependency or lockfile changes, so the red audit is not caused by this PR.
| ) { | ||
| return new HostEventWaitObserver({ | ||
| store: store.conditions.observationStore(owner), | ||
| policy: { maxLifetimeMs: 366 * 86400000, maxAttempts: 1_000_000, ...options.policy }, |
There was a problem hiding this comment.
P3: with intervalMs as low as 1000 and a fallback up to 366 days, the 1,000,000-attempt budget runs out first (about 11.6 days at 1 s). The observer then resolves source_unavailable/observation_budget_exhausted and wakes the worker early with no evidence. Bound intervalMs against the fallback length, or document this early wake in the tool description.
There was a problem hiding this comment.
AI-assisted follow-up (OpenAI Codex): confirmed the 1,000,000-attempt budget and early wake behavior remain intentional. Current docs/matter-condition-waits.md, Persistence and scheduling, already states: “The shared observation budget also wakes the worker on exhaustion; it never silently completes or pauses Matter.” Thus a fallback is not a promise that every polling attempt lasts until the deadline; the resumed worker must reassess/re-wait. At 1 s this can occur after roughly 11.6 days, as noted. I am retaining the documented bounded-observation behavior rather than changing polling semantics in this PR. Leaving resolution to the reviewer.
| name: 'MatterWriteFile', | ||
| description: | ||
| 'Write the entire draft.md file for this activation. This edits a working file only; publish it with MatterCheckpoint or MatterSettle. Other matter files are host-owned.', | ||
| 'Optional legacy draft editor for this activation. Publish this file with MatterCheckpoint. MatterSettle accepts an inline note instead and does not read the draft. Other matter files are host-owned.', |
There was a problem hiding this comment.
P3 behaviour note: settle no longer reads draft.md. A worker that writes the draft and settles without note (and without MatterCheckpoint) silently keeps the previous note.
There was a problem hiding this comment.
AI-assisted follow-up (OpenAI Codex): verified the intentional behavior at current head. MatterWriteFile explicitly says to publish a legacy draft via MatterCheckpoint and that MatterSettle does not read the draft; MatterSettle.note and the Settlement documentation say an omitted note preserves the previous note. The direct-settlement/optional-note regression tests passed in this follow-up. No compatibility change proposed; leaving resolution to the reviewer.
chinawch007
left a comment
There was a problem hiding this comment.
AI review — OpenAI Codex. This automated review is not an independent human approval and does not replace the review required by
CONTRIBUTING.md.
Reviewed 5c9103515359ed42b2a35e442eca1bec97e3866c against dc4515cd6e7637e8267d59cd4f71ad53f403f9e7.
One new P2 finding, attached inline: settlement validation reads only the current physical run's ledger, so a same-turn handoff successor cannot validate the task Inbox inherited from its predecessor. The model has the input, but valid settlements are repeatedly rejected. This is a new continuation-path finding; the previously reported ASF header issue is fixed.
I reproduced the issue with the real AI SDK backend, a source run paused at its handoff boundary, the actual Matter tools and SQLite store, and a controlled model. The successor sees the Inbox but emits no new Inbox context event; three settlements are rejected, including retries after MatterRead, with no reviewer call. A fresh-run control materializes the context and completes successfully. The full Host handoff transport was inspected in source, not executed end to end.
Validation on freshly built sources:
- Built core, storage, MCP, runtime, both executor plugins and runtime-host.
- Core/event-wait, Host/event-wait-manager, Matter conditions and settlement context: 325/325 passed.
- Native assistant: 185/189 passed. The four failures repeated when the two affected files ran separately. One test's 100 ms fallback expired before submission; three wait for a transient empty activation after a 250 ms fallback, although the next activation has already started. A separate native probe confirmed the new activation and followup dispatch. These failures are reported as test timing limitations, not additional product defects.
- ASF header audit and
git diff --checkpassed. An additional SQLite reopen check preserved a committed wait before activation finish and produced one overdue wake in the original session.
Reviewed condition capabilities, persistence/lease/CAS boundaries, cancellation/deadline races, Goal compatibility, settlement invalidation/replay and worker tool filtering. No product or test source changes were made. I did not run the full repository suite, desktop checks, a full Host process-crash scenario, paid-model replay or multi-day operation.
| deliveredInput: async (call) => | ||
| deliveredMatterInput((await ctx.readRuntimeEvents?.(call.sessionId, call.runId)) ?? [], call), |
There was a problem hiding this comment.
[P2] Include inherited turn context in settlement validation
AI review — OpenAI Codex.
When a sealed handoff is cancelled and this Matter turn resumes in a successor run, call.runId selects only that successor's ledger (execution-composition.ts:514–519). The continuation preserves the turn ID and replays the predecessor's Inbox, while runtime context deduplication emits no new proactive-matters.inbox event for unchanged input. Consequently deliveredMatterInput cannot find the context before the new tool call and MatterSettle returns MATTER_REVIEW_INVALIDATED despite the model having received the correct task input.
This is reachable through the live Host's sealed-handoff resume path (root-turn-coordinator.ts:3290–3328; same-turn identity in runtime-resume.ts:595–601). In an isolated backend reproduction, the source pauses after MatterRead; its same-turn successor sees the Inbox but has zero new Inbox events. MatterSettle → MatterRead → MatterSettle → MatterSettle yields three invalidations, zero reviewer calls and an active task. A fresh-run control completes. Retrying or calling MatterRead does not change the input basis, so it does not repair this path.
Validate against the authenticated continuation context preceding the call, or durably materialize the effective Inbox in each successor run. Preserve the turn/activation, input-basis and pre-call ordering checks so stale inputs still cannot settle.
There was a problem hiding this comment.
AI-assisted follow-up (OpenAI Codex): commit 466338d849e1d121f9156d31734d474b1e184089 addresses this by reading the authenticated logical continuation lineage via the existing core reader, then matching the actual calling physical run. It does not fall back to unrelated session history. I independently compiled runtime-host from this head in an isolated worktree and ran the handoff-settlement, settlement-context, matter-conditions and event-wait-manager suites: 288/288 passed. The new tests cover two sealed handoffs, SQLite reopen, stale amendment/pre-call ordering, missing continuation authority and reused tool-call IDs across physical runs. Please recheck the fix; I have not resolved this thread or treated this AI follow-up as human approval.
…ement Generated-by: Codex
Generated-by: Codex
Generated-by: Codex
469dd1c to
466338d
Compare
|
AI-assisted merge follow-up (OpenAI Codex), acting on the contributor’s explicit request to bring this PR through the normal merge process. @M4n5ter could you please take another look at the substantive post-approval handoff fix in Current verification from an isolated checkout of the exact head: runtime-host TypeScript compilation passed, and 288/288 tests passed across matter-handoff-settlement, matter-settlement-context, matter-conditions and event-wait-manager. Existing dependency artifacts were reused to avoid a large installation. This follow-up did not rerun the full repository suite, desktop UI, paid-model replay or multi-day operation. No new source changes were needed in this follow-up. All four inline findings have replies; none was unilaterally resolved. The mandatory |
Summary
Matter tasks can now wait for an Agent-authored, tested read-only condition, with an absolute deadline as fallback. The Host evaluates conditions without model calls and resumes the same task session when the condition matches, repeated source checks fail, or the deadline expires. Time-only waits remain supported; no Goal is created.
Settlement is also shorter:
MatterSettleaccepts a summary and optional inline note instead of requiring a draft file and model-supplied revision. Independent review for wait/complete, activation and input-revision checks, durable history, and idempotent submissions remain. The Host binds settlement to the exact task context delivered before the calling tool event. Delegated workers retain their own lifecycle and business tools but no longer see the Bot's delegation/management tools.Builds on the merged cache fix #6177 and includes main through
85e942724.Same-turn handoff successors validate inherited Inbox context through Runtime's authenticated continuation lineage. The reader verifies seals, claims and successor openings; it does not borrow unrelated Session history. Tool-call matching also requires the current physical run, and input arriving after the call cannot authorize that submission.
Verification
Local verification after updating main and fixing inherited-context validation:
TMPDIR=/private/tmp.git diff --checkpassed.Real-model replay before incorporating the latest main update used GPT 6.1 Sol medium, actual Runtime Host/Bot/Matter tools and independent model review. Business records were controlled through an isolated HTTP/SQLite source, not mocked model or tool responses. Four concurrent tasks covered an amended acceptance condition, source HTTP 503 and recovery, cancellation followed by a late update, deadline fallback, Host restart and duplicate terminal updates. All 25 outcome checks passed; the test environment was stopped afterward.
The final activations used
MatterRead → MemoryOriginal → MatterSettle, without draft writes or separate three-file reads. Review calls remained 10. No settlement self-invalidation loop or worker misuse of coordinator tools occurred. This is a single scenario comparison with manually timed source changes, not a latency benchmark.Known observations: the Bot twice tried to combine exclusive delegation calls; checker construction had three missing-object-field errors; one retry time expired before submission. These recovered without intervention. Two additional tool errors came from the injected 503. The deliberate Host restart aborted one Bot model call; subsequent processing and final notifications recovered. Multi-day operation across repeated context compaction has not been live-tested.
AI use
Tool(s) and scope: OpenAI Codex assisted with implementation, regression tests, the isolated live replay, and this description. Commits include
Generated-by: Codextrailers.Checklist
Does this PR entail a change in behavior?