Repository navigation
Guard native exits against uncollected child work - #148
Conversation
PR SummaryHigh Risk Overview On macOS/Linux, collectors register kernel-exclusive waiter locks ( Eligible completed—or verified failed-with-route—native parents may launch one automatic keyed Reviewed by Cursor Bugbot for commit 7ae3de5. Configure here. |
Codex Review Summary: ✅ CompletedThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
* chore: build with Go 1.26.11 (GO-2026-6859 in net/http) The v0.21.9 release build failed its vulnerability scan: net/http in go1.26.10 is affected by GO-2026-6859, fixed in go1.26.11. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com> * fix: reject Go 1.27.3 release builds for GO-2026-6859 The per-line release floor still accepted go1.27.3 after the net/http bump. GO-2026-6859 is fixed in go1.26.11 and go1.27.4. --------- Co-authored-by: Claude Fable 5.2 <noreply@anthropic.com> Co-authored-by: Cursor Agent <cursoragent@cursor.com>
|
The review-6 duplicate-member finding is repaired in New regressions reproduce 11 semantic false-clean cases against A fresh independent review is running on this exact frozen head. Hosted checks and that review remain required; this comment does not claim a merge verdict or release. |
Native parents can exit with child work that still needs collection. This adds bounded exit evidence and exact collect commands, one durably claimed automatic continuation through a supported frozen native recipe, and actionable inbox entries for routes that cannot resume. Native CLIs and Multica retain execution authority. The original parent stays terminal; collect an automatic successor through
child_exit_guard.continuation_id.Integrated main
fd950e73600611165ada674fba35754877c69903normally, including #147's final strict evidence/membership guards and #150's OpenCode recovery. This PR now targets main; #147 is merged and is no longer a stacked dependency.Exit, coverage and collection contract
child_exit_rechecksurvives mixed-version projection rewrites, including covered-only exits. Covered children cause no present-uncollected warning or unnecessary continuation. Inbox rechecks after waiter death/cancellation or subscription expiry/cancellation, even after collection of the parent's own result. Inbox never launches continuations.awaitand foregrounddelegate/continue --waithold unique kernel waiter locks on macOS/Linux through delivery. Process death releases the lock; unlocked files prove nothing. Registration is best effort. Attention and terminal unacknowledged rows remain actionable. A parent waiter does not cover children; await-any is not per-child coverage. Local exact-ID awaits can cover remote forwarding rows; local subscriptions cannot prove remote completion.continueand the frozen recipe, with no fresh-session fallback. The claim is durable before launch and immutable successor provenance prevents recursion. Cancellation and the original deadline remain binding.delegation.child_exit_auto_continue: falsedisables automatic continuation while retaining exit evidence/inbox actions (default on). Childless runs do not change.Review repairs
Collected history no longer consumes active child-recheck capacity. Inbox selects parents from its existing complete hydrated execution and explicit acknowledgement snapshots, under one held read-only handle. Every retained nonterminal child remains an obligation regardless of waiter coverage. Terminal children settle only on actual validated collection. There is no new mutable settlement state, read-side write, speculative global scan or remote authority.
The additional false-settlement defect is repaired: acknowledgement JSON identity cannot override its authoritative typed bucket key. Inbox and scoped child queries share strict identity, source and nonzero-time validation. Corruption returns exit 70 with
inbox_acknowledgement_corrupt,complete:falseand no success result. The new CLI regression demonstrably fails on d4c94e1's old production paths for wrong-key, invalid-source and missing-time records; valid collected/uncollected controls and read-only byte comparisons pass after repair.Independent round 4 found one retained-membership negative-evidence gap: missing execution rows could make the snapshot prefilter skip the authoritative query and report a clean inbox. The repair validates selected parent-index membership before retiring a marked parent. Live members must resolve in the complete hydrated snapshot; missing rows require matching valid expiry tombstones, even when a collection stamp exists. Invalid or incomplete evidence retains
children_query_incompleteand a read-only scoped recheck action. Query/proof share the strict expiry decoder. No schema, epoch, migration, mutable settlement, read-side repair or external/API shape change is introduced.The new precise CLI regression fails on
336e8e94897af3b8e58fee20a682f7b829a73ef7for missing rows, missing acknowledged rows, missing children covered at exit, and invalid expiry identity/scope. Retained collected/uncollected and valid compact/full expiry controls pass. Complete journal bytes are compared before/after. Writable-handle, partial-snapshot and cancelled-proof controls fail closed. Committed round-4 repair evidence.Independent round 5 refined the same retained-membership negative-evidence mechanism: scope-only/key-only, present-null/empty metadata, and missing/invalid digests were being accepted as expiry. The shared decoder now accepts compact expiry only when both scope/key fields are absent, or full expiry only when both match the authoritative index. Both require the attribution producer's
sha256:plus 64 lowercase hex digest representation. A tombstone cannot hide a retained execution. No other record semantics or API/schema shapes change.The extended CLI regression reproduced false-clean Children/inbox output on
3d5bb77841f67250e0e9d2e3e9511c9de818d533before the production fix. It now requiresErrCorruptfrom Children and the precise incomplete inbox guard/reason/read-only action, with full journal byte comparisons. Valid controls include actual attribution metadata and a real compact replay record produced by retention Plan/Apply; the full compatibility control adds the attribution producer's exact scope/key. Committed round-5 producer/repair evidence. This remains the round-4/5 mechanism, not a new root by field name.The membership proof only seeks selected parent prefixes under the same held read-only journal handle. It validates certification/generations in one stable transaction, with shared 1.5s/100k scope-entry/64MiB index/1MiB value bounds and no subscription/waiter/event/outcome reads. The existing separate 1.5s live-child recheck budget starts afterward, so validated history cannot spend it. These bounded phases may add up to 3s after existing snapshot loads.
The deterministic scale regression retains 1,200 collected historical pairs, an older active parent and both 1,024/1,025 valid-subscription cases. Historical markers cannot crowd that parent off a 200-item inbox page. Subscription loading remains lazy and bounded, using #147's shared strict fanout decoder/compatibility filter. Required-bucket/tombstone corruption handling, targeted membership generations, all certified writer paths, legacy fences, ABA/cleanup and remote semantics are preserved.
Committed reproduction/integration evidence: PR148 collection repair. Full contract: child work. Schemas, help, portable skill and embedded assets are synchronized.
Validation
Frozen head:
7c80c548a53918bdab7da8401e4afe3eef9183a6; main base:fd950e73600611165ada674fba35754877c69903.go test -race -p 1 -count=1passed: cmd/agentctl 105.718s, store 60.342s, runtime 1.552s. This includes producer-generated expiry and malformed-field controls, membership/acknowledgement corruption, the 1,200-history/1,024–1,025 subscription cases, fanout, hydration/legacy-writer/cleanup/ABA fences, waiter loss and continuation/CAS/recursion/cancellation/deadline/native-recovery controls.make pre-push, the sharedmake cisubset. All three CI-only targets (check-distribution,check-release-skew,build) also passed separately, avoiding a duplicate unchanged local full suite. Schema/portable-asset checks andgit diff --checkpassed; the worktree is clean. No force or hook bypass.make ci), Go vulnerability scan and full stateful races. CodeQL Actions/Go/Python analyses and aggregate check passed. All seven reported checks are successful before ready-for-review.3d5bb778, the first hosted race attempt failed only the source-unchangedTestReview4ANXExitTerminatesDescendants/0/closedpulse-file assertion. Its failed-job retry at the same head and 20 isolated local race repetitions passed. No ANX source changes or unrelated production repair are claimed. Current-head local and hosted gates passed on their first attempts; the ANX anomaly did not recur.Limits and remaining gate
Read-only child queries/rechecks retain the existing 1.5s shared processing budget and count/byte/page/lock limits; active overload remains explicitly incomplete. Waiter evidence proves a live collector, not consumption of its output. Remote state remains cached and lost receipts retain identical-key recovery. A process killed before terminal commit cannot perform an owner-exit check; a claimed automatic attempt is never retried after owner loss. Parent-graph retention is unchanged.
The parent owns mandatory fresh independent review round 6 and the merge decision. This lane launched no independent review. If the same mechanism remains unresolved there, the parent owns the requested ANX ask/recommendation/default; no waiver is implied. No merge, tag, release or host installation was performed by this lane.