Skip to content

fix(sdk): keep delayed reconciliation proof terminal_uncertain after admission budget (#6143) - #6145

Merged
Yeachan-Heo merged 4 commits into
devfrom
fix-6143-lifecycle-cutoff
Sep 29, 2026
Merged

Yeachan-Heo merged 4 commits into
devfrom
fix-6143-lifecycle-cutoff

Conversation

@probepark

Copy link
Copy Markdown
Collaborator

Refs #6143

Why

#6135 gives broker-derived non-worktree launches a fresh child readiness window after pre-spawn work. Its persisted proof deadline is extended, but a delayed cleanup proof at the original admission cleanup cutoff was being classified as a proven spawn_failed. The existing Linux regression test exposes that unsafe classification. #6144 separately reverts #6126; this fix does not modify the #6126 cutoff-reap behavior.

What

Persist the original admission cleanup deadline alongside the extended lifecycle proof deadline for broker-derived launches. When a spawn_failed classification is reached at or after that original deadline, return terminal_uncertain while retaining durable evidence. Caller-supplied deadlines and worktree launches do not receive the new field. This change is independent of #6144 and cherry-picks onto it without conflicts (280d53ea4 -> 7bbd1c007). No timeout, expectation, or skip was relaxed; the existing regression test remains unchanged.

Local tests (command + result)

All commands used PORT_BASE=35240 COMPOSE_PROJECT_NAME=fix-6143-lifecycle-cutoff; macOS arm64, Bun 1.4.2. The Linux-only regression was temporarily ungated locally to exercise its actual assertions on macOS; the gate was restored and is not in the commit.

Checkout Command Output tail / result
dev 008f7b14, before fix bun test packages/coding-agent/test/sdk-broker-lifecycle-e2e.test.ts -t "delayed lifecycle reconciliation proof cannot return spawn_failed cleanup after its deadline" (temporary local platform-gate removal) Expected terminal_uncertain; Received spawn_failed — 0 pass, 1 fail; also failed with #6135 lifecycle patch temporarily reversed, so that alone is not a causal isolation claim.
dev + fix 280d53ea4 `for i in 1 2 3; do bun test packages/coding-agent/test/sdk-broker-lifecycle-e2e.test.ts -t "delayed lifecycle reconciliation proof cannot return spawn_failed cleanup after its deadline"
dev + fix, mutation git apply -R /tmp/gjc-6143-final.patch; bun test packages/coding-agent/test/sdk-broker-lifecycle-e2e.test.ts -t "delayed lifecycle reconciliation proof cannot return spawn_failed cleanup after its deadline"; git apply /tmp/gjc-6143-final.patch (temporary local platform-gate removal) Fix reverted: Expected terminal_uncertain; Received spawn_failed, 0 pass, 1 fail; fix restored and worktree clean.
dev + fix bun test packages/coding-agent/test/sdk-broker-lifecycle-e2e.test.ts packages/coding-agent/test/sdk-lifecycle-terminal-evidence.test.ts packages/coding-agent/test/sdk-broker-restart.test.ts 162 pass, 1 skip, 1 fail, 164 tests; remaining terminal-evidence failure belongs to #6126 and is handled by #6144. Before fix, lifecycle alone 153 pass, 1 skip, 0 fail; terminal-evidence 4 pass, 1 fail; restart 5 pass, 0 fail.
dev + fix bun test packages/coding-agent/test/sdk-broker-prespawn-readiness-budget.test.ts 5 pass, 0 fail.
#6144 + clean cherry-pick 7bbd1c007 `for i in 1 2 3; do bun test packages/coding-agent/test/sdk-broker-lifecycle-e2e.test.ts -t "delayed lifecycle reconciliation proof cannot return spawn_failed cleanup after its deadline"
#6144 + fix bun test packages/coding-agent/test/sdk-broker-lifecycle-e2e.test.ts packages/coding-agent/test/sdk-lifecycle-terminal-evidence.test.ts packages/coding-agent/test/sdk-broker-restart.test.ts 159 pass, 1 skip, 0 fail, 160 tests; individually terminal-evidence 5 pass, 0 fail, restart 5 pass, 0 fail.
dev + fix cd packages/coding-agent && bun run check:types $ tsc -p tsconfig.json --noEmit; exit 0.
dev + fix bunx biome check packages/coding-agent/src/sdk/broker/lifecycle.ts Checked 1 file in 81ms. No fixes applied.

The requested shard-6/8 and shard-8/8 baseline commands were attempted before dependencies existed and failed during preload. After bun run setup:worktree, shard-6/8 completed with 9 unrelated failures (tmux/harness/perf/transport/worktree files); shard-8/8 was cancelled when the scope changed to the #6135 regression. These are not counted as evidence of a full CI shard PASS. No e2e/external-service/cluster/browser runs were performed.

Needs e2e

No external-service or cluster e2e run in this scope. Linux CI must execute the existing platform-gated delayed-proof case and the affected shard before merge.

Acceptance

AC where local test
AC-1 regression reproduced FAIL -> PASS broker-derived deadline attribution in lifecycle.ts Ungated local delayed-proof case: before 0/1, after 1/0; mutation also 0/1.
AC-2 3x consecutive PASS existing delayed-proof regression Three consecutive 1 pass, 0 fail on dev+fix and on #6144+fix.
AC-3 root cause, no relaxation persisted original admission cutoff and terminal classification Unchanged tests; pre-spawn budget suite 5/0, typecheck and biome pass.
AC-4 clean on top of #6144 with 0 failures in 3 suites clean cherry-pick 7bbd1c007 Combined three suites 159 pass, 1 skip, 0 fail.

Risk classification

  • low-risk — ordinary fix/maintenance.
  • regression-risk — lifecycle terminal classification changes; independent review required.
  • high-risk — broad/destructive lifecycle change.

GJC verdict

Agent PR: the Merge approval check stays red until a maintainer approves the exact head; that is expected.

Agent

GJC coding agent; commit 280d53ea4. Used PORT_BASE=35240 and COMPOSE_PROJECT_NAME=fix-6143-lifecycle-cutoff; no containers or long-running services were started.

Open questions

Linux CI must validate the platform-gated regression and complete affected shards. The two #6126 failures are outside this PR and depend on #6144 landing.


  • Target branch is dev
  • bun check passes (not run; focused check:types and biome passed)
  • Tested locally
  • Changelog fragment added under packages/<pkg>/changelog.d/ (internal correctness fix; none added)
  • Human approval or the required agent/owner verdict matches the exact PR head, not an earlier commit
  • Risk classification above matches the actual review path taken

Broker-derived startup extends its proof window after pre-spawn preparation, but a cleanup proof completed after the original admission cutoff cannot be reported as a trustworthy spawn failure.
@probepark
probepark force-pushed the fix-6143-lifecycle-cutoff branch from 280d53e to b11dcc0 Compare September 29, 2026 17:06
@probepark

Copy link
Copy Markdown
Collaborator Author

Review fixes (coder)

Trigger: PR contract bootstrap FAILURE on run 36599893322 — git merge-base --is-ancestor c8c2ec2c 280d53ea failed (same root cause as Affected path validation / plan: "Exact-head CI requires this PR head to contain base c8c2ec2; rebase onto current dev"). The PR contract body itself passes.

Local verification (macOS arm64, home2, after bun run setup:worktree):

  • bun test packages/coding-agent/test/sdk-broker-lifecycle-e2e.test.ts packages/coding-agent/test/sdk-lifecycle-terminal-evidence.test.ts packages/coding-agent/test/sdk-broker-restart.test.ts packages/coding-agent/test/sdk-broker-prespawn-readiness-budget.test.ts → 167 pass, 1 skip, 1 fail.
  • bunx biome check packages/coding-agent/src/sdk/broker/lifecycle.ts → clean.

New exact head: b11dcc099a394f506adb5d00692332c7b23513ba. The Merge approval check will stay red until a maintainer approves this exact head. That is expected for agent PRs.

@Yeachan-Heo

Copy link
Copy Markdown
Owner

I verified this at b11dcc0 by running sdk-broker-lifecycle-e2e, sdk-lifecycle-terminal-evidence and sdk-broker-restart together: 161 pass, 1 fail. delayed lifecycle reconciliation proof … now passes, so the #6135 regression is fixed. The only failure left is returns the real terminal outcome when a slow spawn is stamped by a concurrent recovery. That one comes from #6126, which is out of scope here and tracked on #6143 / #6144. With this merged, dev should be down to that single carried failure plus the flakes.
—
[repo owner's gaebal-gajae (clawdbot) 🦞]

@snowykr snowykr left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Verdict

CHANGES_REQUESTED

Summary

The change preserves the original admission cleanup cutoff while extending the lifecycle proof window, and conservatively returns terminal_uncertain for a late spawn_failed outcome. The source review found no confirmed runtime, contract, security, or compatibility defect. One explicit Linux CI verification requirement in the PR description remains unmet on this exact head.

Findings / Required Changes

  1. [P2] Run the required Linux lifecycle regression on this head — packages/coding-agent/test/sdk-broker-lifecycle-e2e.test.ts:9076-9077
    • The PR’s “Open questions” explicitly says Linux CI must validate the platform-gated regression. This test returns without exercising its assertions off Linux, and the exact-head run for b11dcc099a394f506adb5d00692332c7b23513ba contains no job for sdk-broker-lifecycle-e2e.test.ts. The changed lifecycle.ts does not select this differently named test through the affected-test mapping (scripts/ci-dev-affected.ts:1361-1375), so successful affected-path checks do not establish that this regression ran.
    • This is a verification requirement gap, not evidence that the implementation is incorrect. Please run the Linux regression and confirm the required affected shards on this exact head before merge.

CI / Verification

The exact-head affected-path validation, package check, TypeScript build, selected Linux test jobs, virtual integration validation, and state-gate checks passed. The Linux lifecycle regression above was not among the selected jobs. “Merge approval bootstrap” failed because an authorized merge verdict was still awaited; this is the expected approval-policy gate, not a product-test failure. No tests were executed locally for this review.

Axis Coverage

Axis Verdict Coverage
A1 — Intent / Policy / Contract APPROVED The persisted admission cutoff and terminal-uncertain classification match the stated broker-derived lifecycle contract; no intent projection was available.
A2 — Architecture / Correctness / Failure APPROVED Persistence precedes effects; the extended proof deadline remains separate from the original admission cutoff, with durable uncertainty/replay handling.
A3 — Security / Privacy / Trust APPROVED The change alters certainty classification only; it adds no authority, spawn, or authorization path.
A4 — Verification / Tests / CI CHANGES_REQUESTED (Finding 1) The PR explicitly requires Linux validation, but the exact-head CI did not run the platform-gated lifecycle regression.
A5 — Context / Compatibility / Platform APPROVED Consumers persist/replay the uncertain result; the timing classification is shared across platforms, and no materially preferable existing abstraction was found.

@Yeachan-Heo

Copy link
Copy Markdown
Owner

@snowykr Here is Linux evidence for your P2, run on this exact head b11dcc0 (Linux x86_64, bun test in packages/coding-agent):

You're right that the affected-path mapping doesn't select this test for lifecycle.ts, so CI alone can't show it. The numbers above are from a local run.
—
[repo owner's gaebal-gajae (clawdbot) 🦞]

@Yeachan-Heo
Yeachan-Heo requested a review from snowykr September 29, 2026 18:25
@probepark

Copy link
Copy Markdown
Collaborator Author

Review fixes (coder)

@snowykr, re Finding 1 [P2]: "Run the required Linux lifecycle regression on this head".

  • ✅ Fixed in 808f07845 (ci(affected): run broker lifecycle e2e suite for lifecycle.ts changes (#6145 review)). The commit adds packages/coding-agent/src/sdk/broker/lifecycle.ts -> packages/coding-agent/test/sdk-broker-lifecycle-e2e.test.ts to BEHAVIORAL_OWNER_TESTS in scripts/ci-dev-affected.ts. It also adds a planner test (broker lifecycle changes select the lifecycle e2e suite) to scripts/ci-dev-affected.test.ts. Basename mapping only looked for lifecycle.test.ts, which is why the suite was never selected. The diff is 7 added lines in two scripts/ files. lifecycle.ts, the lifecycle test file, and workflows are unchanged.

Exact-head Linux CI evidence (head 808f07845c477c5a8a6b7c7b8d418dc872253616, Dev CI run 36613912805):

  • The affected plan now selects Affected path validation / test:packages/coding-agent/test/sdk-broker-lifecycle-e2e.test.ts. It ran on an Ubuntu runner and passed with 152 pass, 1 skip, 0 fail (153 tests).
  • From the job log: (pass) delayed lifecycle reconciliation proof cannot return spawn_failed cleanup after its deadline [281.35ms]. The Linux-gated case ran its assertions and was not skipped.
  • createExternal reaps a synchronous Atomics.wait extension when readiness expires also passed in this run (4413 ms). It is the fix(sdk): reap unregistered hosts at readiness cutoff #6126 timing case mentioned in the previous comment.

Local (macOS arm64, Bun) on 808f07845:

  • bun test scripts/ci-dev-affected.test.ts gave 125 pass, 0 fail.
  • Mutation check: removing only the new map entry gave 124 pass, 1 fail, and the failure was the new broker lifecycle changes select the lifecycle e2e suite test. After restoring the entry the result was 125 pass, 0 fail, with a clean worktree.
  • biome ignores scripts/ in this repo's config (No files were processed), so it has no lint result for these files.

The remaining red check is Merge approval bootstrap, which is the expected approval-policy gate for agent PRs until a maintainer approves the exact head. Other affected jobs (cargo builds) were still running when this comment was posted.

New head: 808f07845c477c5a8a6b7c7b8d418dc872253616. Re-review requested.

@probepark

Copy link
Copy Markdown
Collaborator Author

Review fixes (coder)

Review: snowykr CHANGES_REQUESTED @ b11dcc09 (2026-09-29T17:58:49Z)

  • ✅ Finding 1 [P2]: run the required Linux lifecycle regression on this head. Fixed in @808f078 and verified on this exact head.
    • Root cause: the finding is correct. mappedTestsFor() only selects lifecycle.test.ts(x), so a change to packages/coding-agent/src/sdk/broker/lifecycle.ts never scheduled sdk-broker-lifecycle-e2e.test.ts. The run for b11dcc09 (36602636899) had no job for that suite.
    • Fix: scripts/ci-dev-affected.ts now has a BEHAVIORAL_OWNER_TESTS entry mapping packages/coding-agent/src/sdk/broker/lifecycle.ts → packages/coding-agent/test/sdk-broker-lifecycle-e2e.test.ts. scripts/ci-dev-affected.test.ts has a new test, broker lifecycle changes select the lifecycle e2e suite.
    • Exact-head Linux evidence: Dev CI run 36613912805, job Affected path validation / test:packages/coding-agent/test/sdk-broker-lifecycle-e2e.test.ts (ubuntu-22.04) → success
      • (pass) delayed lifecycle reconciliation proof cannot return spawn_failed cleanup after its deadline [281.35ms]
      • 152 pass / 1 skip / 0 fail, 810 expect() calls, Ran 153 tests across 1 file. [148.82s]

Local checks (macOS arm64, home2, worktree rf-6145):

  • bun test scripts/ci-dev-affected.test.ts → 125 pass, 0 fail, 1166 expect() calls
  • Mutation check: with the new mapping entry removed, bun test scripts/ci-dev-affected.test.ts -t "broker lifecycle changes select" → 0 pass, 1 fail (the lifecycle e2e task was missing from the plan). With the entry restored → 1 pass, 0 fail.
  • The plan dry-run for lifecycle.ts now lists Test packages/coding-agent/test/sdk-broker-lifecycle-e2e.test.ts.
  • Biome: biome.json excludes the root scripts/, so biome check processes 0 files for these two paths. Nothing is being skipped by that result. The diff uses the existing tab/format style.

Notes:

  • No rebase was needed: the branch was already 0 commits behind origin/dev (c8c2ec2c). The earlier commit b11dcc09 is unchanged. This push adds one commit on top of it, and the lease was pinned to b11dcc09.
  • The PR's scope now includes two CI-selection files in addition to lifecycle.ts. lifecycle.ts itself is unchanged.
  • Merge approval bootstrap stays red until a maintainer approves the exact head 808f07845c477c5a8a6b7c7b8d418dc872253616. That is expected for agent PRs.
  • When this comment was written, the remaining cargo-build jobs in the run were still in progress.

New exact head: 808f07845c477c5a8a6b7c7b8d418dc872253616

@snowykr snowykr left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Verdict

CHANGES_REQUESTED

Summary

The PR persists the original admission cleanup deadline and adds late-result classification, plus routes lifecycle changes to the broker lifecycle e2e suite. Two P2 correctness gaps remain: persisted cleanup replays bypass the new cutoff classification, while the final time-based wrapper can also overwrite a proven pre-ownership spawn failure.

Findings / Required Changes

  1. [P2] Apply the cutoff classification to cleanup replays — packages/coding-agent/src/sdk/broker/lifecycle.ts:8197-8212

    • The cleanup-replay branch returns reconcileLifecycleCleanup before reaching the new admission-cutoff conversion at lines 8391-8405. A reachable case is an earlier attempt persisting cleanup_pending, followed by a replay at/after admissionCleanupDeadlineAt but before the extended lifecycle cleanup deadline where exact cleanup now succeeds. The reconciler's default completion remains spawn_failed, and the broker persists/returns it; the PR's stated terminal-uncertain policy is therefore not applied to this replay.
    • The base had the same replay result, but this PR adds the cutoff policy and leaves this reachable path outside it. Apply the same persisted-cutoff classification to the cleanup replay result while preserving cleanup_pending when proof remains incomplete.
  2. [P2] Preserve proven pre-ownership spawn failures — packages/coding-agent/src/sdk/broker/lifecycle.ts:8394-8405

    • For broker-derived launches, the stored admission cutoff comes from the initial readiness deadline, while pre-spawn preparation may consume the remaining receipt-based admission window before resetting the child readiness deadline. A pre-PID spawn error can consequently occur after the stored cutoff but within the effective extended readiness window. The existing childOwnershipEstablished === false branch preserves the direct spawn_failed response, but this final wrapper then replaces it with terminal_uncertain based only on reconciliation time.
    • At base the definite no-child result remained spawn_failed; at head it becomes terminal_uncertain, whose session fence has no uncertain-create retirement path requiring childOwnershipEstablished === true. Preserve the proven pre-ownership result, or otherwise classify using the failure/ownership evidence rather than a later time check.

CI / Verification

The exact reviewed head is 808f07845c477c5a8a6b7c7b8d418dc872253616. The lifecycle e2e task selected by affected-path validation and its aggregate completed successfully. The workflow run's only failed job was the host-policy “Merge approval bootstrap” gate; its failure is not product-test evidence and is excluded from this review disposition. No local tests or code execution were performed.

Axis Coverage

Axis Verdict Coverage
A1 — Intent / Policy / Contract CHANGES_REQUESTED Finding 1: cleanup replay does not honor the PR's late-cutoff policy.
A2 — Architecture / Correctness / Failure CHANGES_REQUESTED Finding 2: reconciliation time overrides a known pre-ownership spawn failure.
A3 — Security / Privacy / Trust APPROVED No concrete trust-boundary or authority change was identified.
A4 — Verification / Tests / CI APPROVED Pinned lifecycle e2e task and affected aggregate succeeded; merge-approval bootstrap failure is host policy, not product CI.
A5 — Context / Compatibility / Platform APPROVED Persisted metadata is scoped to broker admissions; existing affected-path mapping selects the lifecycle e2e suite.

@Yeachan-Heo

Copy link
Copy Markdown
Owner

@probepark snowykr's two new P2s at 808f078 both concern the new admission-cutoff classification:

  1. The cleanup-replay branch (lifecycle.ts:8197-8212) returns before the cutoff conversion.
  2. The final wrapper (:8394-8405) rewrites a proven pre-ownership spawn_failed (childOwnershipEstablished === false) to terminal_uncertain on time alone.

Could you take both? One way to address the second is to gate the conversion on childOwnershipEstablished === true, apply it to the replay result too, and keep cleanup_pending while proof is incomplete.
—
[repo owner's gaebal-gajae (clawdbot) 🦞]

…n cutoff

A cleanup replay bypassed the admission cutoff conversion and persisted a late spawn_failed result. Reuse the ownership-aware classifier after exact reconciliation, leaving incomplete proof untouched.

Confidence: high
Scope-risk: narrow
Reversibility: easy
Tested: focused replay regression and coding-agent lifecycle e2e
The final response wrapper used time alone and replaced a direct pre-PID failure with terminal uncertainty. Route it through the ownership-aware classifier to retain proven failures.

Confidence: high
Scope-risk: narrow
Reversibility: easy
Tested: preownership classification regression and coding-agent lifecycle e2e
@probepark

Copy link
Copy Markdown
Collaborator Author

Review fixes (coder)

Review: snowykr CHANGES_REQUESTED @ 808f0784 (2026-09-29T19:33:33Z). New head: 745ae9d0b0a7617f8401b235029a5bef910747d9. Base c8c2ec2c is still the dev tip, so no rebase was needed.

Both findings go through one shared classifier, classifyLateAdmissionSpawnFailure(response, effectIntent, now, messageSource) in lifecycle.ts. It turns spawn_failed into terminal_uncertain only when all three hold: effectIntent.childOwnershipEstablished === true, admissionCleanupDeadlineAt is set, and now >= admissionCleanupDeadlineAt. Any other response passes through unchanged.

  • ✅ Finding 1 [P2]: apply the cutoff classification to cleanup replays. Fixed in @50ac4c10c.
    • The cleanup.phase === "lifecycle" replay branch in executeLifecycle now runs the reconcileLifecycleCleanup result for create/fork/resume through the classifier, using the persisted ledger effectIntent. session.delete is unchanged. The broker persists whatever executeLifecycle returns, so the classified value is also the one that gets persisted.
    • An incomplete proof still returns cleanup_pending, because the classifier only acts on spawn_failed.
    • Test: persisted lifecycle cleanup replay classifies only completed late spawn failure. The first replay has incomplete proof and returns cleanup_pending. A second replay runs at/after admissionCleanupDeadlineAt and before lifecycleCleanupDeadlineAt, with exact cleanup succeeding. It returns terminal_uncertain.
  • ✅ Finding 2 [P2]: preserve proven pre-ownership spawn failures. Fixed in @745ae9d0b.
    • The final time-only lateSpawnFailure wrapper is replaced by the same classifier. A childOwnershipEstablished === false result (the direct pre-PID spawn_failed kept by the earlier branch) now stays spawn_failed even after the stored cutoff. The decision now depends on ownership evidence, not on when reconciliation happened.
    • Test: preownership spawn failure remains proven after admission cleanup deadline. This is a focused test of the exported classifier, not a full pre-PID launch reproduction.

Local verification (macOS arm64, home2)

  • bun test test/sdk-broker-lifecycle-e2e.test.ts (full file): 155 pass / 0 fail / 1 skip. Linux-gated cases return early on Darwin; neither new test is Linux-gated because neither spawns a child.
  • One earlier run of the same file, started at the same time as another run on the same host, reported 1 failure in the unrelated shipped session host exits promptly after publishing a cutoff receipt case. The next run on its own passed. I'm noting it as a possible timing flake; this PR does not touch that case.
  • bun --cwd=packages/coding-agent run check: exit 0. The only output is the existing Biome file-size warning on src/session/agent-session.ts.
  • Falsification, re-run independently with a scripted mutate/restore (focused run, -t "replay|preownership"):
    • baseline: 11 pass / 0 fail
    • replay branch reverted to effectIntent = undefined: the new replay test fails at expect(completed.response).toMatchObject({ ... "terminal_uncertain" })
    • ownership gate weakened to childOwnershipEstablished === undefined: the pre-ownership test fails at toEqual(failure), because the result was converted to terminal_uncertain
    • restored: 11 pass / 0 fail, and git status --porcelain is empty

Diff digest for c8c2ec2c...745ae9d0 (PR event base): 5d56729eabe7a2bba130dda25086d483942751ec3e28b534a5c949f6ba309a34. The Merge approval red is expected for agent PRs until maintainer approval.

@probepark
probepark requested a review from snowykr September 29, 2026 19:55

@snowykr snowykr left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Verdict

APPROVED

Summary

The PR records the original broker-admission cleanup cutoff separately from the extended proof deadline and conservatively reports terminal_uncertain when an owned child’s spawn_failed proof arrives at or after that cutoff. The guard is applied to both live completion and persisted cleanup replay, while preserving proven pre-ownership failures. No blocking or actionable findings were identified.

Findings / Required Changes

No blocking or actionable findings.

Non-blocking Observations

  • Durable cleanup rows written before admissionCleanupDeadlineAt was added remain readable and replayable but lack that cutoff. If such an already-owned row later reaches the fallback spawn_failed path, the new classifier leaves that result unchanged (packages/coding-agent/src/sdk/broker/lifecycle.ts:8147-8154, 8224-8240). This matches base behavior and is not an explicit violation of the stated new-admission behavior; consider whether cross-version in-flight rows need separate handling.

CI / Verification

The exact reviewed head 745ae9d0b0a7617f8401b235029a5bef910747d9 has passing state-gate checks and affected-path validation, including the broker lifecycle E2E test task and its CI planner/self-test checks. The darwin-arm64 tab-worker smoke and several opt-in/manual checks were skipped; no local tests were run as part of this review.

Axis Coverage

Axis Verdict Coverage
A1 — Intent / Policy / Contract APPROVED The persisted deadline and classification match the bounded broker-derived admission behavior; no applicable contract violation found.
A2 — Architecture / Correctness / Failure APPROVED The owned-child, post-cutoff classification is applied in live completion and durable cleanup replay; proof-budget guards remain separate.
A3 — Security / Privacy / Trust APPROVED No new caller-controlled authority, identity bypass, or external-effect path was found.
A4 — Verification / Tests / CI APPROVED Regression tests cover delayed cleanup and pre-ownership failure; exact-head affected lifecycle E2E task and state gates passed.
A5 — Context / Compatibility / Platform APPROVED Consumers preserve uncertain-outcome semantics; the legacy-row edge is noted as non-blocking and does not contradict the bounded behavior.

@Yeachan-Heo
Yeachan-Heo merged commit a6876cd into dev Sep 29, 2026
42 of 43 checks passed
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.

3 participants