Skip to content

fix(sdk): bound accepted prompts that never reach execution (#4668) - #4669

Open
Yeachan-Heo wants to merge 6 commits into
devfrom
fix/issue-4668-zero-activity
Open

fix(sdk): bound accepted prompts that never reach execution (#4668)#4669
Yeachan-Heo wants to merge 6 commits into
devfrom
fix/issue-4668-zero-activity

Conversation

@Yeachan-Heo

@Yeachan-Heo Yeachan-Heo commented Aug 18, 2026

Copy link
Copy Markdown
Owner

Fixes #4668.

Bound accepted SDK prompts that never reach execution: lease every promoted prompt at the promotion boundary and attach in-run consumption to the active run's renewal, so zero-activity accepted records terminalize with prompt_deadline_exceeded and long shared runs cannot false-fire.

Current exact head: 7f0d7d3176e6c7c3439f56cfc3dbae0728d1c366, base 8a41a1db9d7d81b4a5c30db4d6ac71fc66572b65 (current dev), canonical three-dot digest 08d648e6e7aa70255789b46632d6cab2b22c8467faa5d2c5d2f6ee760e5d2ab8. Additionally fixes the eleventh snowykr five-axis review at fa75b5daa (sanitized-diagnostic doc wording; sanitized recovery logging). Additionally fixes the tenth snowykr five-axis review at ced48f214 (sanitized failure shape in the agent-wire fixture). Additionally fixes the ninth snowykr five-axis review at 83242618d (never-park skill recovery; sanitized rejection recovery intent). Additionally fixes the eighth snowykr five-axis review at 751764b6d (compound reason replay at agent_end after a failed agent_failed write; authenticated local failure classifiers). Additionally fixes the seventh snowykr five-axis review at 1dad5f9bc (guarded errorStatus access, sanitized listener logging, attempt-scope correlation on AgentFailedEvent, provenance-gated lifecycle failure classifiers). Additionally fixes the sixth snowykr five-axis review at c23906063 (listener isolation so a throwing subscriber can never suppress the agent_failed → agent_end terminal boundary). Additionally addresses the fifth snowykr five-axis review at 0e12a0fda (required AgentFailedEvent diagnostic; root-check unblocked by excluding the dev-emitted ai declaration from biome). Additionally fixes the fourth snowykr five-axis review at 567012cd2 finding 1 (supersession check on the terminal-transition replay before clearing). Additionally fixes the third snowykr five-axis review at ec56b1a7f (attached-correlation agent_failed diagnostics, closed runtime failure-code allowlist, ACP diagnostic metadata fields, continuation-path diagnostic emission, sanitized recovery logging). Additionally fixes the second snowykr five-axis review at da99f12a4 (five-argument finalizeOutcome normalization, sanitized terminal state/history, live recovery timer after uncertainty-write exhaustion, typed AgentFailureDiagnostic contract). Additionally fixes the snowykr five-axis review at 734461dc8 (finalizeOutcome positional recordError/isCurrent compatibility, sanitized exhaustion logging, README sanitized-contract documentation, changelog daemon-generation alignment). Additionally fixes the b1fcde2c review P1: kind-aware rejection recovery so an accepted skill.invoke that rejects after a transient persistence failure gets a bounded durable retry owner (skills have no deadline lease) instead of stranding accepted forever. Reconciled over dev's advances (fd700948 → f991c501 → 235aee515 → 3cda2e4c): every daemon-generation conflict resolved through the canonical guard repair (now 174 at serving epoch 88, strictly higher than every parent) and the embedded docs index regenerated. All review blockers across generations are fixed at this head with regressions: the five from 44048a349 (abort-purge hook mismatch, display-index misalignment, lease cleared before durable terminalization, stale activeInvocation renewal, in-run race drop) and the three HIGH from 5b2a2f313 (clearQueue deferred-SDK-follow-up dispositions, identity-based removal across live+deferred stores, compound failure+terminal recovery that never terminalizes an abandoned prompt as terminal_ok).

Reconciled onto current dev and hardened by an independent adversarial review of the reconciled head. The review found and this head fixes every remaining accepted-forever/false-fire strand:

  • rejection-after-acceptance and the in-run race drop wrote only the diagnostic agent_failed frame; they now chain agent_end so the record terminalizes as failed (regression: accepted-then-failed now reports a terminal failed status).
  • queued submissions removed without consumption (queue.message.remove, queue editing, clearQueue, abort purge) never fired their promotion hook; the hook now fires with a removal disposition and the row terminalizes as a bounded cancelled failure (regression at both the session and runtime boundary).
  • the dispatch-race divert kept the acceptance-anchored lease ticking unrenewed while queued, false-firing prompt_deadline_exceeded; the divert disposition retires the acceptance lease and pending entry, and the real consumption boundary re-leases (regression: no false fire past the lease while queued).
  • a successful uncertainty write cleared the lease, leaving the durable deadlineRecoveryPending row unbounded; recovery now re-arms a bounded lease preserving the maxMs cap (deadline-manager regressions updated).
  • real-agent_end upgrades dropped the superseded prompt_deadline_exceeded error so terminal_ok no longer surfaces a contradictory payload.
  • renewal is scoped to the live lifecycle batch plus in-run attachments, so an unrelated successor run no longer renews a retained dead invocation.
  • CI affected-coverage now registers the agent-session promotion suites, sdk-prefixed bus suites, and disposition-helper consumers as behavioral owners.

Local exact-head evidence: session-runtime 74/74; deadline-manager 13/13; promotion-identity 5/5; agent-session-concurrent + deferred-shell + managed-publication 42/42; dispositions 582/582; agent 27/27 (focused) and 813/814 package-wide (single failure pre-reproduced on pristine dev fd70094 under ambient shell OPENAI_BASE_URL); reconciliation/terminal/ACP/notifications 124/124; ci-dev-affected 102/102; telegram guard 75/75; state-writers exit 0; docs-index byte-identical gate 5/5; bun run build green; coding-agent + agent biome/tsc clean. Two non-PR failures classified against pristine dev fd70094: sdk-downgrade-rollback expects bun@1.3.14 (runtime pin moved to 1.4.0 in #4795 without updating the fixture), and verify-pr-verdict.test.ts pins the same stale 1.3.14; the full-package bun --cwd=packages/coding-agent test crashes in Bun 1.4.0 itself on both branch and pristine dev, so the affected CI matrix remains the authoritative full-suite surface.

Risk classification

  • low-risk — ordinary fix/maintenance.
  • regression-risk — material regression risk requiring independent review.
  • high-risk — destructive lifecycle/architecture or security/trust-boundary change requiring independent review.

gajae.pr-review-verdict.v1 needs-human sha256:08d648e6e7aa70255789b46632d6cab2b22c8467faa5d2c5d2f6ee760e5d2ab8 reviewer:human reviewer-id:probepark evidence:fresh-exact-head-review-required-after-rebase-and-adversarial-review-fixes

Recovery reconciliation at 7f0d7d3176e6c7c3439f56cfc3dbae0728d1c366: semantically transplanted the canonical PR delta onto current dev 8a41a1db9d7d81b4a5c30db4d6ac71fc66572b65, retained current-dev #4840/#4841 settings and structured-diagnostic contracts, and replaced stale local validation evidence. Focused lifecycle 140/140, SDK/agent contract 79 pass + 3 skip, managed-attempt transaction 90/90, streaming edit abort 18/18, package checks, native build, production SDK host isolation, state-writer gates, virtual-integration canaries, and affected-path coverage were rerun. The fresh affected-path run is blocked only by the active Ultragoal runtime intercepting headless ask-tool fixtures; the same fixture runs under clean CI session state.

Restart-recovery blocker fixed at 7f0d7d3176e6c7c3439f56cfc3dbae0728d1c366: persisted deadlineRecoveryPending records re-arm an acceptance-anchored lease during runtime hydration, preserving the original hard cap. Added regression coverage for an already-expired recovered lease.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

Yeachan-Heo pushed a commit that referenced this pull request Aug 18, 2026
…4668)

Red-team review of the zero-execution bound found three gaps:

- agent_start leased only the head of a drained batch, so follow-ups
  promoted together past the head had no deadline and could remain
  accepted with zero execution forever. Lease every drained prompt;
  acceptance-anchored leases make own-turn re-entry a no-op.
- A non-empty agent_start re-entry replaces the tracked invocation
  without a prior agent_end only for wedged/synthetic sequences; the
  replaced turn's lease is now deliberately retained and documented so
  its record still terminalizes at its deadline instead of losing its
  zero-progress bound.
- The goal.list/get diagnostic payload replaced resource_gone, but the
  shared adapter-disposition fixture still expected resource_gone; the
  parity expectation now intentionally asserts ok: true for the
  no_active_goal payload across mcp/acp/daemon-cli adapters.

Lore-id: 4668b2d1
Constraint: queued submissions stay promotion-leased so a prompt behind a legitimately long turn never false-fires
Constraint: no release/tag/publish; PR #4669 exact-head only
Rejected: clearing the replaced turn's lease at re-entry | leaves its record accepted with no bound
Rejected: terminating the replaced record at re-entry | fabricates an outcome for a turn whose real terminal event may still arrive
Confidence: high
Scope-risk: narrow
Reversibility: trivial
Directive: every drained prompt correlation must hold a deadline lease; adapter parity expectations track the goal diagnostic payload
Tested: bun test session-runtime.test.ts -t zero-execution (5 pass); sdk-adapter-dispositions{,-mcp,-daemon-cli,-acp}.test.ts (291+97+97+97 pass); biome+tsc clean
Not-tested: full CI pending on this head
@Yeachan-Heo
Yeachan-Heo requested a review from snowykr August 18, 2026 11:48

@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: Request changes

Summary

The acceptance-anchored lease fixes the original own-turn gap, but the queued-follow-up promotion path still has an unbounded window and can misattribute ownership across runs. This leaves the core “accepted ⇒ progress or bounded terminal error” contract incomplete.

Findings

[P1] Lease a follow-up when it is actually promoted, or terminalize the promotion/start gap

packages/coding-agent/src/sdk/host/session-runtime.ts:2808-2814 (onPromotedTurn) only appends the correlation to pending. The corresponding deadline lease is created later in emitLifecycle() (:2638-2645), when agent_start drains pending.

A queued follow-up can therefore be durably accepted and promoted, then wedge before agent_start (or lose the lifecycle event). In that state it has no lease and remains accepted indefinitely—the same false-owner hazard this PR is intended to remove. The existing tests cover “no agent_start” for an own-turn prompt, but not for a follow-up after promotion.

Please create the lease at the actual promotion boundary (while keeping prompts merely waiting in the queue unleased), or add an equivalent bounded terminal path for promotion without agent_start. Add a regression test that invokes the promotion callback and then never emits agent_start, asserting prompt_deadline_exceeded.

[P1] Do not enqueue in-run follow-ups for a later unrelated agent_start

The same onPromotedTurn callback is also used when a follow-up is consumed inside an already-running agent loop. That path does not necessarily produce a new agent_start, but it still appends to pending. A later, unrelated agent_start can drain the stale correlation, lease it as part of the wrong run, and transfer abort ownership to the wrong connection; it may then produce a false prompt_deadline_exceeded.

Promotion needs an explicit run/attempt identity (or an equivalent distinction between “new root run” and “consumed in current run”). In-run consumption must not remain in pending; it should be transitioned/retired at that boundary. Add a regression test for an in-run follow-up followed by a separate agent-initiated agent_start.

Verification notes

The PR’s reported suites are useful coverage for the original repro and the drained-batch/re-entry cases, but they do not exercise either promotion-without-agent_start or stale in-run promotion. Those cases are required before this can be approved.

Yeachan-Heo pushed a commit that referenced this pull request Aug 18, 2026
…4668)

Red-team review of the zero-execution bound found three gaps:

- agent_start leased only the head of a drained batch, so follow-ups
  promoted together past the head had no deadline and could remain
  accepted with zero execution forever. Lease every drained prompt;
  acceptance-anchored leases make own-turn re-entry a no-op.
- A non-empty agent_start re-entry replaces the tracked invocation
  without a prior agent_end only for wedged/synthetic sequences; the
  replaced turn's lease is now deliberately retained and documented so
  its record still terminalizes at its deadline instead of losing its
  zero-progress bound.
- The goal.list/get diagnostic payload replaced resource_gone, but the
  shared adapter-disposition fixture still expected resource_gone; the
  parity expectation now intentionally asserts ok: true for the
  no_active_goal payload across mcp/acp/daemon-cli adapters.

Lore-id: 4668b2d1
Constraint: queued submissions stay promotion-leased so a prompt behind a legitimately long turn never false-fires
Constraint: no release/tag/publish; PR #4669 exact-head only
Rejected: clearing the replaced turn's lease at re-entry | leaves its record accepted with no bound
Rejected: terminating the replaced record at re-entry | fabricates an outcome for a turn whose real terminal event may still arrive
Confidence: high
Scope-risk: narrow
Reversibility: trivial
Directive: every drained prompt correlation must hold a deadline lease; adapter parity expectations track the goal diagnostic payload
Tested: bun test session-runtime.test.ts -t zero-execution (5 pass); sdk-adapter-dispositions{,-mcp,-daemon-cli,-acp}.test.ts (291+97+97+97 pass); biome+tsc clean
Not-tested: full CI pending on this head
@Yeachan-Heo
Yeachan-Heo force-pushed the fix/issue-4668-zero-activity branch from 531eb7b to 6a28647 Compare August 18, 2026 12:52
@snowykr

snowykr commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

Verdict: Request changes

The acceptance-anchored lease addresses the original no-agent_start gap, but two lifecycle invariants are still incomplete and can produce false ownership or false terminal failures.

A1 / A2 — [P1] Expiry does not fence the pending ownership path

Location: packages/coding-agent/src/sdk/host/session-runtime.ts:2803-2804, consumed at :2629-2645

deadlineManager.onAccepted(correlation) only terminalizes the reconciliation row and clears the timer. The corresponding pending entry remains, and the preflight/start path is not cancelled or invalidated. If a delayed preflight later emits agent_start (or an unrelated agent-initiated run starts first), pending.splice(0) can drain the already-failed correlation, install it as activeInvocation, and assign its original requester as the owner. That requester can then pass the ownership check for turn.abort against a late run even though its durable receipt is already failed; subsequent lifecycle events cannot reconcile the record back to a valid run.

Please make deadline expiry atomically retire/invalidate the pending correlation and reject late starts (or have agent_start verify that the correlation is still non-terminal before assigning ownership). Add a regression for accept → deadline → late agent_start → requester abort.

A2 — [P1] Per-record leases are not refreshed for the drained batch

Location: session-runtime.ts:2644-2645, progress hooks at :2707-2715

The change creates a lease for every prompt in drainedInvocations, but tool progress is attributed only to current.activeInvocation (the batch head). A legitimately long run that drains multiple follow-ups can therefore keep doing tool work while each tail prompt's lease expires, permanently marking those prompts prompt_deadline_exceeded; the later agent_end cannot repair terminal rows. Either use one run-level lease for the drained batch, or refresh/attribute progress for every correlation that is part of the active batch while preserving per-record terminalization.

A3 — Security / Privacy / Trust

No concrete findings in the changed paths.

A4 — Verification / Tests / CI

The added zero-execution and adapter coverage is useful, but there is no deterministic test for the two expiry boundaries above. Please add the late-start fence regression and a multi-follow-up batch with tool progress that exceeds the per-prompt lease without false failure. Also add coverage proving that a queued follow-up/busy-steer remains accepted while waiting beyond the deadline, since the implementation intentionally leases only on promotion/start.

The current GitHub check set is not green yet: the PR contract bootstrap/path-validation run reports failure/cancellation while several affected-path checks remain pending.

A5 — Context / Compatibility / Platform

No concrete compatibility, persistence, generated-surface, package/install, or platform-specific findings.

@Yeachan-Heo
Yeachan-Heo requested a review from snowykr August 18, 2026 13:39
@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

Both P1 findings from the review are addressed on exact head be186060e4463badd1840a4a527a7d2d00a3bb22:

  1. Lease at the promotion boundary: the promotion hook now carries explicit run identity ({ startsOwnRun }) and every promoted prompt is leased at actual promotion, so promotion-without-agent_start terminalizes with prompt_deadline_exceeded (new regression: "a promoted follow-up that never reaches agent_start terminalizes with prompt_deadline_exceeded" — verified failing without the fix).
  2. In-run consumption no longer parks in pending: consumption inside the running turn (startsOwnRun: false) attaches the submitter to the in-flight run immediately — it shares that run's ownership and terminalizes with it, so an unrelated later agent_start cannot drain the correlation, mis-assign ownership, or fabricate a deadline (new regression: "an in-run consumed follow-up is not parked for an unrelated later agent_start" — verified failing without the fix).

Validation on this head: full session-runtime suite 58/58, zero-execution 8/8, sdk-adapter-dispositions + deadline-lease 297/297, biome + tsc clean. The verdict line and diff digest in the body are rebound to be186060e4 (base 356633ac98); the earlier CHANGES_REQUESTED review covers superseded heads. Review re-requested.


[repo owner's gaebal-gajae (clawdbot) 🦞]

@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

Generation-5 exact head 7e0b593e12fab13f5444c72f4a7c022454afcf5b pushed; verdict line and diff digest rebound (sha256:b3e842088a8202bdf540a3026ffeb7ab9eedb7eb5cf286eb8b1e27b16c5fe2ae, base 356633ac98).

Resolves the QA generation-4 blockers on production dispatch:

  • Mid-run steering dequeue now fires onSteeringConsumed with { startsOwnRun: false } at the real dequeue boundary (previously unreachable for ordinary turn.prompt queued while streaming).
  • onFollowUpConsumed carries run identity per call site: false for the in-loop outer continuation, true for root/continuation runs via continueQueuedMessages.
  • Progress renewal now covers every prompt correlation attached to the active run, so long shared runs cannot false-fire prompt_deadline_exceeded.

Evidence on this head: production-path regressions agent-session-promotion-identity 3/3 (each verified failing on the previous head); session-runtime suite 59/59 including the attached-correlation renewal regression (verified failing with head-only renewal); agent-loop 38/38; steer/queued suites 23/23; adapters + deadline-lease 297/297; biome + tsc clean on both packages. Executor QA generation 5: PASSED with zero blockers.

Worktree hygiene note: untracked packages/coding-agent/src/session/provider-safety-stop-hint.ts is NOT part of this PR (verified: no imports from this diff, absent from the 6-file commit). It is residue from a concurrent lane (pr-4653-provider-safety-0751, issue #4650) left by a stash collision in this shared worktree; it is intentionally left untouched and unstaged for that lane to reclaim.


[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: REQUEST CHANGES

Summary

The latest head (7e0b593e) fixes the previously unreachable mid-run steering callback, correctly distinguishes ordinary in-run follow-ups from successor runs, and renews deadlines for every correlation attached to a shared run. However, the remaining ownership/terminalization paths can still associate a timed-out or misclassified request with a later, unrelated run. That is a false-owner regression in the exact area this PR is intended to close.

Findings / Required Changes

  • P1 — Retire expired pending ownership before another run can consume it.
    packages/coding-agent/src/sdk/host/session-runtime.ts:2826-2836 adds an own-run promotion to pending, but packages/coding-agent/src/sdk/prompt-deadline-manager.ts:86-97 only finalizes the reconciliation record and clears the timer. It does not remove that pending correlation. If no agent_start occurs before expiry, a later unrelated agent_start can drain the failed request and make the old client an owner of the new run. Retire the exact pending/owner correlation atomically when the deadline expires, and cover expiry → later agent_start → foreign abort.

  • P1 — Do not treat the idle snapshot as proof that a prompt ran in its own turn.
    packages/coding-agent/src/sdk/host/session-runtime.ts:1390-1439 still terminalizes from queuedAtDispatch === false, while packages/coding-agent/src/session/agent-session.ts:11500-11515 can yield during preflight and subsequently enqueue the prompt as steering after another run begins. The record becomes terminal before the actual dequeue callback, so the real consumption boundary cannot repair it. Return the actual delivery disposition from sendUserMessage, or defer terminalization until the correlated queue/run boundary.

  • P1 — Keep agent-initiated in-run prompts out of pending.
    In packages/coding-agent/src/sdk/host/session-runtime.ts:2838-2857, the new in-run callback falls back to pending.push(...) when the current run has neither activeInvocation nor drainedInvocations (for example, a monitor/cron initiated run). There is no subsequent agent_start for that prompt, so it remains unresolved and can later be drained into an unrelated run. Attach these correlations to an explicit active-run transition list, and only establish requester ownership when the active run is SDK-owned.

  • P2 — Make batch deadline cleanup failure-safe.
    packages/coding-agent/src/sdk/host/session-runtime.ts:2659-2687 clears attached leases only after each noteTransition succeeds. A rejected transition can leave tail timers alive; agent_end then prefers the head activeInvocation, and agent_failed has no equivalent fallback cleanup. Clear every drained correlation in terminal/finally cleanup for both terminal lifecycle events.

  • P2 — Close the observable contract coverage gaps.
    packages/coding-agent/test/helpers/sdk-adapter-dispositions-shared.ts:114-142 now accepts goal.list/get success without asserting the required enabled: false, goal: null, reason: "no_active_goal", and diagnostic message payload. packages/coding-agent/src/sdk/host/session-runtime.test.ts:2725-2752 also checks only turn.prompt_status, not the promised turn.result surface for deadline failures. Add operation-specific adapter assertions and turn.result assertions, including the replacement-prompt case.

  • P2 — Avoid a public details-payload discriminator collision.
    packages/agent/src/types.ts:813-819 classifies any exact { failureKind: "argument_validation" | "execution" } object as loop-owned, although AgentToolResult.details remains arbitrary tool-owned data. A custom tool returning that otherwise valid one-field payload loses its renderer. Use a reserved, collision-resistant loop marker or out-of-band provenance.

  • P3 — Update the public hook/release documentation.
    The new onSteeringConsumed hook and startsOwnRun discriminator are not described in the affected Unreleased sections (packages/agent/CHANGELOG.md:28, packages/coding-agent/CHANGELOG.md:3). Document the hook semantics and shared-run correlation renewal behavior.

CI / Verification

  • This review used the exact PR head 7e0b593e12fab13f5444c72f4a7c022454afcf5b.
  • The subagent verification axis did not execute PR code by design. It inspected the changed tests and available CI metadata.
  • Current visible metadata is not a complete green signal: the exact-head PR contract is marked failed/needs-human, and Dev CI is still in progress. The commit's reported targeted-test results were not independently executed here.

Axis Coverage

  • A1 — Intent / Policy / Contract: covered; promotion identity improvements are aligned, but the tool-details discriminator remains a compatibility concern.
  • A2 — Architecture / Correctness / Failure: covered; the three P1 lifecycle/ownership paths above remain blocking.
  • A3 — Security / Privacy / Trust: covered; the stale-owner paths are authorization/trust-boundary defects. No separate secret, injection, path, or privacy issue was identified.
  • A4 — Verification / Tests / CI: covered from changed tests and provided CI artifacts; P2 contract-coverage gaps remain.
  • A5 — Context / Compatibility / Platform: covered; no platform/generated-surface blocker found; documentation/release-note drift is P3.

@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

Generation 6 exact head a1f707776ba616682de63fba523fe21bdbef4f81 (base 356633ac98) pushed.

Fix-forward for QA findings 1-3:

  • (1) agent_start now leases EVERY drained prompt inside the non-empty drain branch (for inv of current.drainedInvocations) — tail invocations 1..n no longer lack a zero-progress lease and cannot remain accepted forever.
  • (2) Re-entry no longer overwrites activeInvocation on an empty drain; the previous active (and its lease) is retained until its deadline or explicit agent_end. Non-empty re-entry deliberately retains the replaced record's lease (terminalizes at deadline; no leak) — manager clears once terminal.
  • (3) helpers/sdk-adapter-dispositions-shared.ts:expectSemanticResult is now Q04-strict: on success it asserts page.items[0] has enabled:false, goal:null, reason:no_active_goal with a non-empty diagnostic message, so adapters cannot regress to bare resource_gone or an undiagnostic snapshot.

Local evidence: bun test packages/coding-agent/src/sdk/host/session-runtime.test.ts 59/59, agent-session-promotion-identity 3/3, sdk-adapter-dispositions-mcp 97/97, sdk-adapter-dispositions 291/291, bun --cwd=packages/coding-agent run check + bun --cwd=packages/agent run check clean.

Requesting fresh exact-head independent review at a1f707776b.


[repo owner's gaebal-gajae (clawdbot) 🦞]

@Yeachan-Heo
Yeachan-Heo requested a review from snowykr August 18, 2026 17:56
@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

Body digest corrected to canonical c368acfc4615f49b18fda7730c6363a5577fe6823c67ab073531db25078bacc9 for exact 356633ac98...a1f707776b diff. Prior body erroneously echoed the head SHA in the sha256: field, causing Verify exact-head PR contract stale-digest failure. Now needs-human at a1f707776b validates; awaiting exact-head contract green on runs 32168800490/32168801111 (native pending, gates green) before snowykr exact-head rereview against prior P1/P2s.


[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 normal lease/promotion path is directionally aligned with the issue, but several lifecycle paths can retain an accepted SDK correlation past its real run and later attach it to an unrelated turn. That breaks requester ownership and can make a later cross-client abort act on the wrong lifecycle.

Findings / Required Changes

  • [P1] Attach in-run promotions to agent-owned runs instead of deferring them to pending.
    packages/coding-agent/src/sdk/host/session-runtime.ts:2845-2859 falls back to pending when startsOwnRun: false is reported during a monitor/cron-style run that has no SDK root (activeInvocation/drainedInvocations). The next unrelated agent_start can then adopt the old requester and lifecycle state, while the real turn is not represented. Track the active run independently of SDK ownership and attach the correlation to that run; only use pending when no lifecycle is active.

  • [P1] Preserve the actual run identity for maintenance continuations.
    packages/coding-agent/src/session/agent-session.ts:5909-5913 reports queued messages as startsOwnRun: true even for a maintenance continuation, which continues the logical agent run without a new agent_start (packages/agent/src/agent.ts:1550-1602). This leaves the correlation in pending, where it can false-expire or be adopted by a later run. Propagate the continuation's real lifecycle identity and attach it to the existing transition batch.

  • [P1] Do not terminalize from an idle preflight snapshot or retain expired pending ownership.
    packages/coding-agent/src/sdk/host/session-runtime.ts:1383-1435 uses queuedAtDispatch as a stale idle snapshot; a delayed preflight that is diverted to steering can therefore be terminalized as agent_end before its actual consumption. Separately, expiry clears the lease but leaves its pending ownership available to a later drain (:2829-2835). Base terminalization on the actual delivery/promotion disposition, and remove or skip terminal correlations atomically before a drain.

  • [P2] Cover the lifecycle fences and failure cleanup.
    Add deterministic regressions for expiry followed by a later foreign run/abort, idle-to-steering preflight diversion, agent-initiated in-run consumption, maintenance continuation consumption, and a transition failure that proves every drained lease is cleared. Assert the durable turn.result failure surface as well as prompt_status.

CI / Verification

  • Reviewed changed tests and GitHub CI evidence only; no PR code, tests, builds, linters, or formatters were run for this review axis.
  • Dev CI run 32168800490 was still in progress: gjc-state-gates / static, runtime, and integrity succeeded; read was skipped; other affected jobs were pending/skipped and PR contract bootstrap failed.
  • Dev CI run 32168067832 was cancelled.
  • Validate exact-head PR contract run 32168801111 reported needs-human; per review policy, that failure is not counted.

Axis Coverage

  • A1 — Intent / Policy / Contract: The accepted-prompt ownership contract is still violated on non-SDK-root lifecycle paths.
  • A2 — Architecture / Correctness / Failure: Found stale ownership, continuation identity, dispatch-race, and expiry-cleanup failures.
  • A3 — Security / Privacy / Trust: Applicable: stale ownership can cross SDK-client requester isolation and authorize a foreign terminal abort.
  • A4 — Verification / Tests / CI: Core happy paths are covered, but lifecycle fences/error paths and completed affected-suite CI evidence are insufficient.
  • A5 — Context / Compatibility / Platform: Monitor/cron and maintenance-continuation callers are incompatible with the current pending-drain model.

@Yeachan-Heo
Yeachan-Heo requested a review from snowykr August 18, 2026 18:22
@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

Generation 7 exact head 87a8c50fde88395ac8ab0d52a555f6ed603f8899 (base 356633ac98) pushed — digest c8d97453cff8f8af4ebb20946ca41a72ee0a8a192a6659ac3767c27b28f35eba corrected in body (needs-human remains authoritative; Validate exact-head PR contract needs-human failure is not a product failure per review policy).

P1 fixes for exact a1f7077 review:

  • lifecycleActive tracks real run activity independent of SDK ownership so monitor/cron runs attach in-run startsOwnRun:false promotions to the active run instead of pending (was false attachment + later foreign agent_start adoption).
  • Expiry atomically retires pending ownership via PromptDeadlineManager#onExpired before clear, so a later agent_start cannot drain an expired requester.
  • Maintenance continuations (agent/src/agent.ts: maintenanceContinuation) now report startsOwnRun:false so queued messages continue the logical run without a false own-run pending entry.
  • Dispatch-race: submit tracks promotionStartsOwnRun; a delayed preflight diverted to steering that later fires onQueuedPromoted(false) moves from pending to the active run and skips stale agent_end terminalization.
  • Batch lease cleanup is failure-safe (try/finally per noteTransition, batch-first drainedInvocations).

Local evidence: session-runtime 59/59, agent-session-promotion-identity 3/3, coding-agent + agent biome+tsc clean, fmt clean.

Requesting fresh snowykr exact-head rereview at 87a8c50 against all prior P1/P2s.


[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 deadline and promotion work addresses the accepted-with-zero-execution failure mode, but the new in-run promotion path grants a newly attached SDK connection authority over an already-running turn. A lifecycle-race fallback can also transfer that authority to a later unrelated turn. The expiry and promotion behavior needs focused regression coverage before this is safe to merge.

Findings / Required Changes

  • [P1] Preserve root-turn abort ownership for in-run promotions.
    packages/coding-agent/src/sdk/host/session-runtime.ts:2868-2901 adds an in-run submitter's connectionId to activePromptOwnerHolder.connectionIds when startsOwnRun === false; packages/agent/src/agent.ts:1798-1812 supplies that flag for queued steering/follow-ups. A second SDK connection sharing a session can submit during another connection's streaming turn, become a co-owner, and use turn.abort to terminate the original connection's active turn. Attach the correlation for deadline tracking, but keep abort authorization scoped to the root invocation (or validate ownership per correlation / require an explicit capability). Add a regression proving an attached connection cannot abort a turn it did not start.

  • [P2] Do not enqueue an in-run promotion after its run has ended.
    packages/coding-agent/src/sdk/host/session-runtime.ts:2902-2904 falls back to pending.push(...) when startsOwnRun === false and lifecycleActive is false. A promotion racing agent_end can therefore be drained by the next unrelated agent_start, assigning the previous submitter ownership of a turn it did not submit. Terminalize/drop this correlation (while preserving a bounded lease as appropriate) rather than placing it in pending; add the after-agent_end regression case.

  • [P1] Cover the expiry-to-next-run ownership fence.
    packages/coding-agent/src/sdk/host/session-runtime.ts:2790-2805 removes expired items from pending, but packages/coding-agent/src/sdk/host/session-runtime.test.ts:2715-3250 only asserts terminalization. Add a deterministic test that expires an accepted prompt, then emits a later agent_start, and proves the expired connection has no active-turn authority while a newly submitted connection owns its turn. This protects the new stale-pending cleanup invariant from ordering regressions.

  • [P2] Complete the new promotion/deadline test matrix.
    packages/coding-agent/test/agent-session-promotion-identity.test.ts lacks the new maintenanceContinuationstartsOwnRun:false path (packages/coding-agent/src/session/agent-session.ts:5896-5910). The deadline-renewal test in session-runtime.test.ts:2895-2970 also checks only an attached tail correlation and tool_execution_start; assert the head correlation and tool_execution_end path too. Strengthen test/helpers/sdk-adapter-dispositions-shared.ts:138-152 so an empty/missing goal.list/get page cannot vacuously pass instead of exposing the required no_active_goal diagnostic.

  • [P3] Keep hook evolution rolling-upgrade safe.
    The new required promotion parameters in packages/agent/src/types.ts:340-346 and extension onQueuedPromoted declarations can cause a new handler to dereference undefined when hosted by an older runtime or simple mock. Prefer optional parameters with guarded reads unless the public extension contract explicitly requires lockstep deployment.

CI / Verification

  • Multi-axis, read-only review completed against exact head 87a8c50fde88395ac8ab0d52a555f6ed603f8899 (base 356633ac98). No PR code was executed locally.
  • Completed CI evidence includes the targeted agent-session-promotion-identity.test.ts and agent.test.ts jobs plus state-gate/native-build jobs.
  • The current PR-contract/bootstrap failures are the repository's intentional needs-human review gate and are excluded from this verdict. Cancelled runs are non-actionable. Several Dev CI shards remain queued/in progress; re-check them before merge.

Axis Coverage

Axis Result
A1 — Intent / Policy / Contract Required API change is scoped; P3 rolling-upgrade compatibility advisory noted.
A2 — Architecture / Correctness / Failure No independent blocking defect beyond the ownership/lifecycle findings above.
A3 — Security / Privacy / Trust P1 intra-session abort-ownership escalation; P2 lifecycle-race ownership transfer.
A4 — Verification / Tests / CI P1 expiry-to-next-run fence missing; P2 promotion/renewal/adapter diagnostic gaps.
A5 — Context / Compatibility / Platform No blocking package, generated artifact, migration, or platform regression found.

@Yeachan-Heo
Yeachan-Heo requested a review from snowykr August 18, 2026 20:10
@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

Exact head fed1a655f5b0f2f5e42be146396444fb40d0258a (base 356633ac98, canon 48fd74d4315a1b915f6196ee77e07039f32b2e3ea9ca491c7822453372199861) — needs-human body digest corrected.

Fixes for snowykr @ 87a8c50 P1/P2s:

  • No abort authority for in-run: startsOwnRun:false now tracks deadline only via drainedInvocations (with lifecycleActive real-run guard and pending→active move) but does NOT add to activePromptOwnerHolder; a racing agent_end drops with agent_failed/busy instead of parking in pending for the next run.
  • Expiry retirement: PromptDeadlineManager now onExpired atomically pending.splice before clear, so expiry → later agent_start proves expired requester has no authority and new submitter owns.
  • Delivery disposition: submit captures promotionStartsOwnRun and skips stale queuedAtDispatch-only agent_end terminalization when diverted to steering (promotionStartsOwnRun===false).
  • Maintenance continuation: agent-session#scheduleAgentContinue onRunAccepted now startsOwn = maintenanceContinuation!==true so maintenance continues logical run.
  • Head+trailing renewal: renewAttributableProgress unions head+drainedInvocations (deduped) so head tool_execution_end renews trailing attached correlation.
  • Q04 non-vacuous: expectSemanticResult now requires page, items.length>0, enabled:false/goal:null/reason:no_active_goal, non-empty message (strict, typed).
  • Rolling-safe promotion: onQueuedPromoted?: (promotion?: {startsOwnRun?: boolean}) both sides guarded with promotion?.startsOwnRun.

Local: session-runtime 59/59, promotion-identity 3/3, coding-agent 2839 + agent 88 biome+tsc clean. No CI rerun until positive exact-head review per instruction.

Requesting snowykr exact-head rereview at fed1a65.


[repo owner's gaebal-gajae (clawdbot) 🦞]

@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

Coordination handoff from the issue-#4668 lane (worktree diffed against current PR head 3a589426cc875205697adb915442880a9e7e5b9c). The head covers all three snowykr P1s (expiry retirement via onExpired, diversion gating via promotionStartsOwnRun, in-run racing terminalization), the adapter payload assertion, and the production-path promotion tests. Two review findings remain unaddressed anywhere:

P2 — tool-details discriminator collision (packages/agent/src/types.ts:813-819): isToolFailureEnvelope still classifies ANY single-key { failureKind: "argument_validation" | "execution" } object as loop-owned, but AgentToolResult.details is arbitrary tool-owned data, so a custom tool returning exactly that one-field payload loses its renderer. Minimal fix sketch (applies cleanly on the head):

+/** Reserved collision-resistant marker for the loop-owned failure envelope (#4668). */
+const LOOP_FAILURE_ENVELOPE_MARKER = "__loopFailureEnvelope";
+
 export function toolFailureEnvelope(kind: ToolFailureKind): ToolFailureEnvelope {
-	return { failureKind: kind };
+	return { failureKind: kind, [LOOP_FAILURE_ENVELOPE_MARKER]: true };
 }
 
 export function isToolFailureEnvelope(value: unknown): value is ToolFailureEnvelope {
 	if (!value || typeof value !== "object") return false;
+	if ((value as Record<string, unknown>)[LOOP_FAILURE_ENVELOPE_MARKER] !== true) return false;
 	const keys = Object.keys(value);
-	if (keys.length !== 1 || keys[0] !== "failureKind") return false;
+	if (!keys.includes("failureKind")) return false;
 	const kind = (value as ToolFailureEnvelope).failureKind;
 	return kind === "argument_validation" || kind === "execution";
 }

(ToolFailureEnvelope needs the optional marker field typed; renderer behavior unchanged.)

P3 — Unreleased changelog entries for the new hook semantics: packages/agent/CHANGELOG.md should document onSteeringConsumed + onFollowUpConsumed run identity (startsOwnRun) and the shared-run correlation renewal; packages/coding-agent/CHANGELOG.md should document the accepted-control zero-progress bound, promotion-boundary leasing, in-run attach semantics, and the goal.list/get no_active_goal diagnostic payload.

Both are required by the open snowykr review; adding them closes the remaining P2/P3 set.


[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 PR addresses the accepted-prompt deadline gap and the updated head adds useful coverage, but several lifecycle paths still detach an accepted correlation from the run that consumes it or remove its recovery state before a durable terminal transition. The agent_failed addition also leaves terminal ownership state live. These break the prompt ownership and bounded-lifetime guarantees this change is intended to establish.

Findings / Required Changes

  1. [P1] Do not terminalize an idle-to-busy dispatch before its promotion identity is known
    packages/coding-agent/src/sdk/host/session-runtime.ts:1402-1455
    isIdle() is sampled before dispatch, while a stream can begin before sendUserMessage() resolves. In that race the request is queued as steering, but promotionStartsOwnRun is still undefined, so the settlement path treats it as an own-run completion and records agent_end before onSteeringConsumed(false) arrives. The accepted request is then terminalized and its deadline/ownership retired before it is consumed. Defer settlement until promotion disposition is known, or return the actual queue disposition from dispatch synchronously; synthesize own-run completion only for a confirmed own-run outcome.

  2. [P1] Treat agent_failed as a terminal lifecycle boundary and preserve its failure cause
    packages/coding-agent/src/sdk/host/session-runtime.ts:2628-2728
    The new listener discards the failure event and clears leases, but cleanup of lifecycleActive, invocation batches, owner connection IDs, and publication waiters only runs for agent_end. A failed run without a subsequent end leaves stale ownership that later lifecycle activity can inherit, including abort authority; reconciliation also loses the actual failure reason. Thread the sanitized error into the failed transition and perform terminal teardown for agent_failed (or enforce and test the invariant that an agent_end always follows it).

  3. [P1] Do not drop a deadline and pending ownership when expiry reconciliation fails
    packages/coding-agent/src/sdk/prompt-deadline-manager.ts:69-104
    onExpired runs from finally and clears the lease even if durable claim/finalize work throws. The runtime callback removes the pending ownership entry, leaving an accepted/in-flight invocation without an owner, retry, or deadline recovery path. Retire pending ownership only after durable terminal confirmation, or retain/retry the lease with an explicit bounded uncertain-outcome path.

  4. [P1] Report maintenance continuations as in-run consumption
    packages/agent/src/agent.ts:1473-1483, 1524-1528
    Direct follow-up consumption reports startsOwnRun: true even when maintenanceContinuation continues an existing logical run. That can make the SDK wait for an agent_start which will never be emitted, mis-correlating or falsely expiring the accepted follow-up. Derive startsOwnRun from the continuation mode and report false when it stays in the current run.

  5. [P2] Keep the adapter parity assertion non-vacuous for the new goal diagnostic
    packages/coding-agent/test/helpers/sdk-adapter-dispositions-shared.ts:146-150
    The ACP branch returns successfully when goal.list/get has no page, so { ok: true } without enabled:false, goal:null, reason:"no_active_goal", or its diagnostic message passes CI. Define and assert ACP's translated diagnostic contract rather than accepting a missing page.

CI / Verification

  • Reviewed the exact head 3a589426cc875205697adb915442880a9e7e5b9c against 356633ac98b4a27d19b7f6d573c286791c913ff4 through independent A1–A5 review lanes. No PR code was executed locally.
  • Exact-head Dev CI run 32191100558 passed the affected session-runtime test, promotion-identity test, and coding-agent shard 1/8.
  • Virtual integration validation was still queued at review time. The PR-contract bootstrap is a designated needs-human gate and is excluded from this assessment.

Axis Coverage

Axis Result
A1. Intent / Policy / Contract Required changes: promotion and continuation semantics do not consistently match their lifecycle contract.
A2. Architecture / Correctness / Failure Required changes: dispatch race, failure teardown, and durable-state/lease ordering defects.
A3. Security / Privacy / Trust Required changes: stale failed-run ownership can authorize a previous client against a later turn.
A4. Verification / Tests / CI Affected checks pass; the ACP diagnostic assertion is vacuous and virtual integration remains queued.
A5. Context / Compatibility / Platform Required changes: failed-transition history and adapter diagnostic compatibility remain incomplete.

@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

Coordination nudge from the issue-#4668 lane. The exact-head review on 3a589426cc875205697adb915442880a9e7e5b9c is the current merge gate. Consolidated open blockers for this lane:

  1. P1: idle-to-busy dispatch race — settle only after promotion identity is known (session-runtime.ts:1402-1455).
  2. P1: agent_failed must be a terminal lifecycle boundary with sanitized cause threaded through and full teardown (ownership, waiters, batches).
  3. P1: onExpired must retire pending ownership only after durable terminal confirmation; retain/retry the lease on failure.
  4. P1: maintenance continuations must report startsOwnRun: false (packages/agent/src/agent.ts:1473-1483, 1524-1528).
  5. P2: ACP adapter assertion for the goal diagnostic must not be vacuous (sdk-adapter-dispositions-shared.ts:146-150).
  6. P2 (handed off earlier): isToolFailureEnvelope discriminator collision — fix sketch in my earlier comment.
  7. P3 (handed off earlier): Unreleased changelog entries in packages/agent/CHANGELOG.md and packages/coding-agent/CHANGELOG.md for the new hook semantics.

Issue #4668 stays open and closes only after this PR merges to dev with merged-commit evidence.


[repo owner's gaebal-gajae (clawdbot) 🦞]

@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

Independent exact-head verification from the issue-#4668 lane (throwaway detached worktree at 3a589426cc875205697adb915442880a9e7e5b9c, no mutation): session-runtime suite 59/59, adapter dispositions 291/291, biome + tsc clean on coding-agent and agent-core. One coordination signal: agent-session-promotion-identity.test.ts passed 3/3 isolated, but under parallel load (run together with the 291-test adapter suite) the first test's hook timed out once and cascaded into the second — the in-loop follow-up test is timing-sensitive under contention; consider a slightly more generous hook/wait budget if CI ever flags it.

Open blockers remain the 4 P1 + 1 P2 from the exact-head review plus the handed-off envelope/changelog items.


[repo owner's gaebal-gajae (clawdbot) 🦞]

Yeachan-Heo pushed a commit that referenced this pull request Aug 19, 2026
…4668)

Red-team review of the zero-execution bound found three gaps:

- agent_start leased only the head of a drained batch, so follow-ups
  promoted together past the head had no deadline and could remain
  accepted with zero execution forever. Lease every drained prompt;
  acceptance-anchored leases make own-turn re-entry a no-op.
- A non-empty agent_start re-entry replaces the tracked invocation
  without a prior agent_end only for wedged/synthetic sequences; the
  replaced turn's lease is now deliberately retained and documented so
  its record still terminalizes at its deadline instead of losing its
  zero-progress bound.
- The goal.list/get diagnostic payload replaced resource_gone, but the
  shared adapter-disposition fixture still expected resource_gone; the
  parity expectation now intentionally asserts ok: true for the
  no_active_goal payload across mcp/acp/daemon-cli adapters.

Lore-id: 4668b2d1
Constraint: queued submissions stay promotion-leased so a prompt behind a legitimately long turn never false-fires
Constraint: no release/tag/publish; PR #4669 exact-head only
Rejected: clearing the replaced turn's lease at re-entry | leaves its record accepted with no bound
Rejected: terminating the replaced record at re-entry | fabricates an outcome for a turn whose real terminal event may still arrive
Confidence: high
Scope-risk: narrow
Reversibility: trivial
Directive: every drained prompt correlation must hold a deadline lease; adapter parity expectations track the goal diagnostic payload
Tested: bun test session-runtime.test.ts -t zero-execution (5 pass); sdk-adapter-dispositions{,-mcp,-daemon-cli,-acp}.test.ts (291+97+97+97 pass); biome+tsc clean
Not-tested: full CI pending on this head
@Yeachan-Heo
Yeachan-Heo force-pushed the fix/issue-4668-zero-activity branch from 3a58942 to 8a61c74 Compare August 19, 2026 09:49
@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

Exact-head update: head 8a61c746477c070b1515c916d418dbb00cd9ff1b, rebased onto current dev 06f0d4d67eeaa5ea7a8a2a0976afdfa8c1eaf155 (replaces stale head 3a589426 / base 356633ac). This lane is the sole mutation owner for #4668 and this branch.

All five findings from the 2026-08-18T22:35 exact-head review are addressed at this head:

  1. [P1] Dispatch-race settlementagent-session.ts sendUserMessage now reports the actual queue disposition synchronously (onQueuedPromoted({startsOwnRun:false})) when a plain prompt is diverted to steering after an idle snapshot; the runtime attaches the correlation to the in-flight run idempotently and never terminalizes from the stale snapshot. Regression: agent-session-promotion-identity (production divert) + session-runtime dispatch-race test (non-terminal before agent_end, terminal_ok after).
  2. [P1] agent_failed terminal boundaryemitLifecycle threads the observed failure cause into reconciliation (sanitized, first-reason-wins preserved) and runs the full terminal teardown for agent_failed: lifecycleActive, invocation batch, owner connection IDs, and publication waiters are all settled. Regression: agent_failed is a terminal lifecycle boundary that preserves the failure cause.
  3. [P1] Expiry reconciliation orderingPromptDeadlineManager retires pending ownership (onExpired) and clears the lease only after durable terminal confirmation (finalize success or terminal lookup); otherwise it retries boundedly (5 × 1s) and then parks the timer while retaining the lease and ownership for the next lifecycle boundary. Regression: sdk-prompt-deadline-manager (3 tests).
  4. [P1] Maintenance continuationsAgent.continue() / continueQueuedMessages() derive startsOwnRun from the continuation mode; maintenance continuations report in-run consumption. Regression: agent-force-abort maintenance continuation test.
  5. [P2] ACP parity assertion — the ACP fixture now returns the translated no_active_goal diagnostic page for goal.list/get, and the shared assertion requires the page on every adapter (missing page is a contract violation).

Verification at this exact head: session-runtime.test.ts 61/61, agent-session-promotion-identity 4/4, sdk-prompt-deadline-manager 3/3, agent-force-abort 8/8, agent.test.ts 18/18, adapter dispositions ACP 97/97; package check (biome + tsc) clean for @gajae-code/agent and @gajae-code/coding-agent.


[repo owner's gaebal-gajae (clawdbot) 🦞]

@Yeachan-Heo
Yeachan-Heo requested a review from snowykr August 19, 2026 09:50
Yeachan-Heo pushed a commit that referenced this pull request Aug 19, 2026
…4668)

Red-team review of the zero-execution bound found three gaps:

- agent_start leased only the head of a drained batch, so follow-ups
  promoted together past the head had no deadline and could remain
  accepted with zero execution forever. Lease every drained prompt;
  acceptance-anchored leases make own-turn re-entry a no-op.
- A non-empty agent_start re-entry replaces the tracked invocation
  without a prior agent_end only for wedged/synthetic sequences; the
  replaced turn's lease is now deliberately retained and documented so
  its record still terminalizes at its deadline instead of losing its
  zero-progress bound.
- The goal.list/get diagnostic payload replaced resource_gone, but the
  shared adapter-disposition fixture still expected resource_gone; the
  parity expectation now intentionally asserts ok: true for the
  no_active_goal payload across mcp/acp/daemon-cli adapters.

Lore-id: 4668b2d1
Constraint: queued submissions stay promotion-leased so a prompt behind a legitimately long turn never false-fires
Constraint: no release/tag/publish; PR #4669 exact-head only
Rejected: clearing the replaced turn's lease at re-entry | leaves its record accepted with no bound
Rejected: terminating the replaced record at re-entry | fabricates an outcome for a turn whose real terminal event may still arrive
Confidence: high
Scope-risk: narrow
Reversibility: trivial
Directive: every drained prompt correlation must hold a deadline lease; adapter parity expectations track the goal diagnostic payload
Tested: bun test session-runtime.test.ts -t zero-execution (5 pass); sdk-adapter-dispositions{,-mcp,-daemon-cli,-acp}.test.ts (291+97+97+97 pass); biome+tsc clean
Not-tested: full CI pending on this head

@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 five-axis review completed against the exact head and identified 2 actionable issues, led by Renewed leases can be cleared during terminal-transition replay and Required CI gates are failing. These findings require changes before approval.

Findings / Required Changes

  1. [P1] Renewed leases can be cleared during terminal-transition replay.
    Reference: packages/coding-agent/src/sdk/prompt-deadline-manager.ts:88-111
    When a real terminal transition is pending, the replay branch awaits reconciliation and then unconditionally calls clear(); progress during that await is not generation-checked, so a renewed live prompt can lose its lease and ownership. Apply the same supersession check used by the normal finalize path before clearing.
  2. [P1] Required CI gates are failing.
    Reference: scripts/telegram-daemon-generation-manifest.json:1
    The brokered CI summary reports failures for Affected path validation, its evidence producer, root-check, and exact-head PR contract. Resolve the failed gates and rerun CI before treating this change as verified; skipped virtual integration remains unverified.

CI / Verification

  • Reviewed the exact remote head: 567012cd298091b9e8fb1401891780e9dc6cb42e.
  • CI summary: 51 passing, 6 failing, 20 pending/cancelled/skipped.
  • Failing checks: Affected path validation, Affected path validation / evidence producer, Affected path validation / root-check.
  • Repository policy permits review before all gating checks pass; the current non-passing checks are recorded above and do not establish that checks passed.

Axis Coverage

Axis Verdict Coverage
A1. Intent / Policy / Contract APPROVED The additive agent_failed lifecycle and promotion-disposition boundaries appear internally consistent; no concrete API or compatibility break was established.
A2. Architecture / Correctness / Failure APPROVED Concurrency and correctness changes appear internally consistent, with bounded recovery and lifecycle ownership fencing; no actionable defect was established.
A3. Security / Privacy / Trust APPROVED A3 security and privacy controls appear sound: provider error details are not exposed through the reviewed failure lifecycle or persisted terminal state.
A4. Verification / Tests / CI CHANGES_REQUESTED A4 verification is incomplete: targeted tests pass, but failing CI gates and an untested terminal-replay lease race leave observable lifecycle risk.
A5. Context / Compatibility / Platform APPROVED Integration contracts and documentation are consistent; platform-specific confidence is limited because Windows/Darwin validation was skipped.

Limitations

  • CI summary provides failing job names but no failure logs, so the root causes of those failures cannot be localized from brokered evidence.
  • Virtual integration validation and several Windows/Darwin platform checks were skipped; platform behavior is therefore limited to inspected code and available passing checks.

@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

Finding 1 of the 567012cd2 review is fixed at exact head 0e12a0fda071656facafdcd1d25c5e8553c5ae52 (fast-forward push, same base f64d762b043ea730686adb2700f92bf25b419c03). Canonical three-dot digest: cc7680418f3074ee12b7893833d058e884e9fb9b12d79c73e3c2f3aa1fadf648; PR body rebound with a needs-human verdict.

  1. [P1] terminal-transition replay could clear a renewed lease — the pending-terminal replay branch awaited its reconciliation writes and then unconditionally called clear(), so attributable progress landing during that await renewed the prompt which then still lost its lease and ownership. The replay now runs the same #backOffIfSuperseded check as the finalize path before retiring ownership: a renewed lease backs off and reschedules (deadline-manager suite 13/13, session-runtime 79/79 isolated).

  2. [P1] required CI gates — root-cause analysis with reproduction: the root-check failure is a pristine-dev regression, not this diff. On a clean origin/dev worktree, running bun scripts/ci-release-publish.ts --check-types followed by bun --cwd=packages/ai run check emits packages/ai/src/adapter-internals/provider-safety-stop.d.ts (unformatted) and fails biome with the exact same mintProviderSafetyStop declaration-formatting diff — introduced by dev's own ai adapter work (dd93b4334), which no PR file touches. The Affected path validation aggregate and evidence producer failures were cascades of root-check (CI_DEV_SHARDS_RESULT: failure with root-check as the sole upstream failure). The remaining failing check is the intentional needs-human contract gate. This dev-side ai regression needs a dev-lane fix (format the emitted declaration or exclude generated .d.ts in the ai biome config); carrying it inside this PR would be unrelated scope.

@probepark @snowykr — fresh exact-head review requested at 0e12a0fda. No release/tag/publish/main mutation.


[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 five-axis review completed against the exact head and identified 2 actionable issues, led by Gating CI failures require resolution and Make agent_failed.error required. These findings require changes before approval.

Findings / Required Changes

  1. [P1] Gating CI failures require resolution.
    Reference: scripts/ci-dev-affected.ts:78-95
    Brokered CI reports failures in affected-path validation, its evidence producer, root-check, and exact-head PR contract; inspect the corresponding job logs and fix or explicitly reconcile the failures before merging.
  2. [P2] Make agent_failed.error required.
    Reference: packages/coding-agent/src/extensibility/extensions/types.ts:651-653
    AgentFailedEvent documents a guaranteed sanitized {code,message} diagnostic, but declares error optional; require the field or document and handle missing diagnostics consistently across extension and ACP consumers.

CI / Verification

  • Reviewed the exact remote head: 0e12a0fda071656facafdcd1d25c5e8553c5ae52.
  • CI summary: 51 passing, 6 failing, 20 pending/cancelled/skipped.
  • Failing checks: Affected path validation, Affected path validation / evidence producer, Affected path validation / root-check.
  • Repository policy permits review before all gating checks pass; the current non-passing checks are recorded above and do not establish that checks passed.

Axis Coverage

Axis Verdict Coverage
A1. Intent / Policy / Contract CHANGES_REQUESTED The additive agent_failed lifecycle boundary is wired across core, extensions, wire mapping, and ACP, but its public extension type weakens the promised diagnostic contract.
A2. Architecture / Correctness / Failure APPROVED Concurrency and correctness protections for lifecycle reconciliation, queue ownership, deadline expiry, and terminal races appear coherently implemented; no actionable defect was established.
A3. Security / Privacy / Trust APPROVED A3 conclusion: reviewed changes materially reduce provider-error leakage and preserve bounded diagnostic exposure; no actionable security or privacy defect was established.
A4. Verification / Tests / CI CHANGES_REQUESTED A4 verification is broadly covered by passing targeted tests, but failing gating checks and skipped integration jobs leave merge readiness and platform compatibility unestablished.
A5. Context / Compatibility / Platform APPROVED Integration and documentation behavior is coherent; platform compatibility remains only partially established because Windows/Darwin validation was skipped.

Limitations

  • CI summary does not provide failure logs or root causes for the reported failures.
  • Windows and virtual integration jobs were skipped, so those platform paths remain unverified.
  • Windows and Darwin platform jobs were skipped, so platform behavior was not independently validated there; affected-path and exact-head contract checks also failed.

@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

Both findings from the 0e12a0fda review are addressed at exact head c239060638208f3c6e983b8819b3b8bad589f9fe (fast-forward, same base f64d762b0). Canonical three-dot digest: 39703281b35d014c31798a2c9824539133eb5363428850948eb758aea5b3f59f; PR body rebound with a needs-human verdict.

  1. [P1] gating CI failures — root cause reproduced and fixed: ci-release-publish --check-types emits provider-safety-stop.d.ts directly into packages/ai/src/adapter-internals/ (verified on a pristine origin/dev worktree — dev regression from the adapter work, no PR file touches it), and the ai package's biome check then fails on the emitted formatting, cascading to the affected-shard aggregate and evidence producer. The generated declaration is now excluded in biome.json, mirroring the existing !packages/natives/native/index.d.ts convention; the ai package check and root biome pass with the stray declaration present. The only remaining red check is the intentional needs-human contract gate.
  2. [P2] required diagnosticAgentFailedEvent.error is now required AgentFailureDiagnostic (the extension fan-out always passes the sanitized pair), and the ACP mapper reads it without optional chaining.

Exact-head evidence: acp-mapper 35/35; agent 20/20; session-runtime 79/79; deadline-manager 13/13; package + root biome/tsc clean.

@probepark @snowykr — fresh exact-head review requested at c23906063. No release/tag/publish/main mutation.


[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 five-axis review completed against the exact head and identified 1 actionable issue, led by Protect agent_failed publication from listener exceptions. These findings require changes before approval.

Findings / Required Changes

  1. [P1] Protect agent_failed publication from listener exceptions.
    Reference: packages/agent/src/agent.ts:2073-2088
    The catch path emits agent_failed before requestRunTerminal, but event listeners are invoked without isolation; a throwing subscriber can abort the catch path and suppress the required agent_end terminal boundary. Wrap diagnostic publication so listener failures cannot prevent terminalization.

CI / Verification

  • Reviewed the exact remote head: c239060638208f3c6e983b8819b3b8bad589f9fe.
  • CI summary: 64 passing, 9 failing, 19 pending/cancelled/skipped.
  • Failing checks: Affected path validation, Affected path validation / evidence producer, Affected path validation / test:@gajae-code/coding-agent:shard-7-of-8.
  • Repository policy permits review before all gating checks pass; the current non-passing checks are recorded above and do not establish that checks passed.

Axis Coverage

Axis Verdict Coverage
A1. Intent / Policy / Contract CHANGES_REQUESTED The API boundary is additive and sanitized, but an untrusted event consumer can currently prevent the documented agent_failed-to-agent_end lifecycle from completing.
A2. Architecture / Correctness / Failure APPROVED Concurrency and lifecycle correctness appear coherently addressed; no further actionable defect was established, though failed CI shards limit confidence in unverified paths.
A3. Security / Privacy / Trust APPROVED Security and privacy protections appear sound: provider error details are sanitized before persistence and external lifecycle publication.
A4. Verification / Tests / CI APPROVED A4 verification is mixed: targeted changed-area checks pass, while broad coding-agent and agent-core CI failures remain unexplained; observable regressions cannot be established without job logs.
A5. Context / Compatibility / Platform APPROVED Integration contracts and documentation are internally aligned; platform behavior remains incompletely validated because relevant CI checks were skipped or failed.

Limitations

  • CI summary reports failures for coding-agent shards 2, 5, and 7 plus agent-core, but provides no failure output to identify a source-level regression.
  • Virtual integration and Windows platform jobs are skipped, so those paths are not verified.
  • Affected path validation and exact-head PR contract checks failed, while virtual integration and Windows platform checks were skipped; full integration/platform validation cannot be claimed.

@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

The c23906063 review finding is fixed; dev advanced (f64d762b0 → 74e853161), so this is fix-forward plus conflict-free rebase at exact head 1dad5f9bc07aecfe86189b380cfb54bd2892458d on current dev base 74e853161e57a389d66b4415f2e4f73fb3c5e8e3. Canonical three-dot digest: 617d2de92e35a7f552f765e8db96d5ead2d2a302ae7a710a514da80344e34f45; PR body rebound with a needs-human verdict.

[P1] listener isolation#emit invoked each subscriber inline, so a throwing listener aborted the emitting caller — in particular the failure catch that publishes agent_failed and must still reach its agent_end terminal boundary, letting one misbehaving consumer suppress terminalization entirely. Listeners are now invoked individually inside try/catch (matching the telemetry swallow convention); a subscriber failure is logged and never rethrown into the run loop. Regression: a hostile subscriber throwing on every event still yields an error-terminalized run.

Exact-head evidence: agent 21/21 (incl. hostile-listener regression); session-runtime 79/79; notifications 60/60; both package checks clean.

@probepark @snowykr — fresh exact-head review requested at 1dad5f9bc. No release/tag/publish/main mutation.


[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 five-axis review completed against the exact head and identified 5 actionable issues, led by Guard untrusted errorStatus access and Listener exceptions can leak raw sensitive error objects to logs. These findings require changes before approval.

Findings / Required Changes

  1. [P1] Guard untrusted errorStatus access.
    Reference: packages/agent/src/agent.ts:2072
    The catch path directly reads err?.errorStatus before emitting sanitized agent_failed and agent_end. A provider error with a throwing errorStatus getter can throw from the error handler, preventing the documented terminal lifecycle. Safely extract status inside a guarded helper and always complete failure terminalization.
  2. [P1] Listener exceptions can leak raw sensitive error objects to logs.
    Reference: packages/agent/src/agent.ts:2184-2185
    console.warn logs the uncaught listener error object directly, despite the surrounding failure path promising sanitized diagnostics; log only a fixed message or sanitized error metadata.
  3. [P1] Preserve failure-attempt correlation.
    Reference: packages/coding-agent/src/extensibility/extensions/types.ts:648-653
    AgentFailedEvent exposes only error, while the documented diagnostic is correlated to an attempt and AgentEvent carries scope. Add the attempt scope/correlation to this public event and propagate it through AgentSession and downstream adapters.
  4. [P1] Provider errors can forge lifecycle failure classifiers.
    Reference: packages/agent/src/agent.ts:80-94
    sanitizeAgentFailure forwards provider-controlled codes whenever they appear in the runtime allowlist, including aborted and prompt_deadline_exceeded. This can misclassify an ordinary provider failure as cancellation or deadline expiry; only runtime-authenticated classifications should be accepted, with all provider codes mapped to agent_failed.
  5. [P1] Provider-controlled failure codes cross the runtime trust boundary.
    Reference: packages/agent/src/agent.ts:71-85
    sanitizeAgentFailure accepts provider-supplied codes such as aborted, local_buffer_overflow, and prompt_deadline_exceeded; provenance-gate runtime-owned classifications and map untrusted provider codes to a generic provider failure.

CI / Verification

  • Reviewed the exact remote head: 1dad5f9bc07aecfe86189b380cfb54bd2892458d.
  • CI summary: 64 passing, 9 failing, 19 pending/cancelled/skipped.
  • Failing checks: Affected path validation, Affected path validation / evidence producer, Affected path validation / test:@gajae-code/coding-agent:shard-2-of-8.
  • Repository policy permits review before all gating checks pass; the current non-passing checks are recorded above and do not establish that checks passed.

Axis Coverage

Axis Verdict Coverage
A1. Intent / Policy / Contract CHANGES_REQUESTED The additive failure event is sanitized, but its extension-facing contract omits attempt correlation needed for reliable concurrent-run compatibility.
A2. Architecture / Correctness / Failure CHANGES_REQUESTED Concurrency lifecycle ordering is mostly preserved, but provider-controlled failure codes can corrupt cancellation and deadline semantics.
A3. Security / Privacy / Trust CHANGES_REQUESTED The change improves payload sanitization but still permits provider-controlled classifiers and raw subscriber errors to cross logging or diagnostic trust boundaries.
A4. Verification / Tests / CI APPROVED A4 verification is incomplete: targeted coverage is broad, but failed checks and skipped platform/integration jobs prevent a clean regression conclusion.
A5. Context / Compatibility / Platform CHANGES_REQUESTED Integration and documentation changes establish additive sanitized failure propagation and daemon generation compatibility; Windows platform behavior remains unverified because its CI jobs were skipped.

Limitations

  • CI summary omits failure logs, so the failing checks cannot be mapped to a specific changed path or regression.
  • Windows and virtual-integration checks were skipped, leaving those platform paths unverified.
  • Windows native build toolchain and Windows dev/session-path jobs were skipped, so Windows-specific behavior is not established.

@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

All five findings from the 1dad5f9bc review are fixed at exact head 751764b6dd682012916ade9383198eb55290ce43 (fast-forward, same base 74e853161). Canonical three-dot digest: 44939254d749baff54561d6714a25ab1b49e023f2c901f08b1e57d1a35d816c3; PR body rebound with a needs-human verdict.

  1. [P1] guarded errorStatus access — the failure handler read err?.errorStatus before sanitizing; a throwing getter escaped the catch and suppressed terminalization. Status extraction now lives in a guarded safeErrorStatus helper that never throws.
  2. [P1] sanitized listener logging — the isolation console.warn logged the raw listener error; it now logs only the sanitized {code,message} metadata.
  3. [P1] attempt-scope correlationAgentFailedEvent carries the attempt scope (matching the agent_start/agent_end scope contract); the AgentSession extension emitter propagates it and the ACP session_info_update surfaces gjcAgentFailedScope.
    4+5. [P1] classifier provenancesanitizeAgentFailure forwarded any provider-supplied code in the allowlist, so a provider could forge aborted or prompt_deadline_exceeded. Classification is now provenance-gated: lifecycle classifiers are accepted only as the runtime-authenticated argument (the abort path passes "aborted" explicitly); provider strings map through the small PROVIDER_ACCEPTABLE_FAILURE_CODES set and everything else falls back to agent_failed. Regression: a provider error self-declaring "aborted" classifies as agent_failed.

Exact-head evidence: agent 22/22 (incl. forged-classifier regression); acp-mapper 35/35; force-abort 8/8; session-runtime 79/79; both package checks and bun run build clean.

@probepark @snowykr — fresh exact-head review requested at 751764b6d. No release/tag/publish/main mutation.


[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 five-axis review completed against the exact head and identified 2 actionable issues, led by Failure persistence can be followed by a false successful terminal and Preserve authenticated local failure classifiers. These findings require changes before approval.

Findings / Required Changes

  1. [P1] Failure persistence can be followed by a false successful terminal.
    Reference: packages/coding-agent/src/sdk/host/session-runtime.ts:3099-3168
    When an agent_failed reconciliation write fails, the invocation is added to failedTransitions, but the subsequent agent_end transition can still succeed without the failure diagnostic and classify the record as terminal_ok. Preserve and replay the failure reason before agent_end, or prevent terminal success until the failed transition is durably recovered; apply equivalent bounded recovery for skill invocations, which have no deadline lease.
  2. [P1] Preserve authenticated local failure classifiers.
    Reference: packages/agent/src/agent.ts:2019-2024
    The catch path calls sanitizeAgentFailure(err) without passing the identity-checked managedLocalErrorDiagnostic result, so local_buffer_overflow and other runtime-owned local failures are emitted as generic agent_failed instead of their documented stable code. Extract the authenticated local classifier and pass it to sanitization while continuing to reject foreign provider labels.

CI / Verification

  • Reviewed the exact remote head: 751764b6dd682012916ade9383198eb55290ce43.
  • CI summary: 63 passing, 10 failing, 19 pending/cancelled/skipped.
  • Failing checks: Affected path validation, Affected path validation / evidence producer, Affected path validation / test:@gajae-code/coding-agent:shard-7-of-8.
  • Repository policy permits review before all gating checks pass; the current non-passing checks are recorded above and do not establish that checks passed.

Axis Coverage

Axis Verdict Coverage
A1. Intent / Policy / Contract CHANGES_REQUESTED The additive failure-event contract is broadly wired, but local runtime classifier fidelity remains a compatibility risk at the Agent API boundary.
A2. Architecture / Correctness / Failure CHANGES_REQUESTED A concurrency flaw remains in failure-to-terminal reconciliation: persistence failure can lose the diagnostic and produce terminal_ok or an unreconciled invocation.
A3. Security / Privacy / Trust APPROVED The change adds sanitized failure diagnostics and preserves provider-error confidentiality; no concrete security or privacy vulnerability was established.
A4. Verification / Tests / CI APPROVED A4/A5 risk remains unresolved: extensive targeted coverage exists, but multiple affected CI suites fail and integration validation is skipped.
A5. Context / Compatibility / Platform APPROVED Integration and documentation contracts are consistently wired; daemon compatibility is fail-closed, but failed and skipped CI leave broad platform validation incomplete.

Limitations

  • Affected path validation reports failures in multiple coding-agent and agent-core test shards, so this lane cannot claim the full compatibility suite passes; the broker supplied no failure logs to identify whether those failures are related to this boundary.
  • CI summary reports failures and skips but provides no failure logs, so passing status for all affected integration suites cannot be established.
  • Windows and Darwin platform checks were skipped, so those platform paths remain unverified.

@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

Both findings from the 751764b6d review are fixed; dev advanced (74e853161 → 8f6b442035), so this is fix-forward plus rebase at exact head 83242618d3538486a4b7bd5c5e3810f22a40f91f on current dev base 8f6b442035da5a24926065fc9535efd7b9ebc2d9. Canonical three-dot digest: 9493f4041e51c76722a16f8595e1a8a9b26c9b3e1a6c4f475d49244342f06b65; PR body rebound with a needs-human verdict.

  1. [P1] false terminal_ok after failed diagnostic write — a failed agent_failed write now stashes the sanitized reason keyed by correlation; the subsequent agent_end re-records that reason durably BEFORE the boundary, so the classification is failed, never terminal_ok. A failed re-record throws into the existing retention path (failedTransitions keeps the batch and leases; prompts replay through the deadline manager's compound intent, skills through the bounded inline retry). Regression: an injected first-write failure followed by agent_end asserts failed/provider_unavailable.
  2. [P1] local classifier fidelity — the identity-checked managedLocalErrorDiagnostic(err)?.errorKind is now passed as the runtime-classified code (genuine local_buffer_overflow/local_snapshot_failure keep their documented stable codes; foreign self-declared labels still map to agent_failed).

Exact-head evidence: session-runtime 80/80 (incl. the end-reason replay regression); agent 22/22; deadline-manager 13/13; notifications 60/60; both package checks and bun run build clean.

@probepark @snowykr — fresh exact-head review requested at 83242618d. No release/tag/publish/main mutation.


[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 five-axis review completed against the exact head and identified 2 actionable issues, led by Persistent skill reconciliation failure can strand accepted submissions and Unsanitized provider error persisted during recovery. These findings require changes before approval.

Findings / Required Changes

  1. [P1] Persistent skill reconciliation failure can strand accepted submissions.
    Reference: packages/coding-agent/src/sdk/host/session-runtime.ts:1740-1795
    Skill rejection retries agent_failed/agent_end only three times, then logs and returns without a deadline lease or recovery owner, leaving the durable record accepted indefinitely. Add durable uncertainty/retry ownership for skills and ensure eventual terminalization.
  2. [P1] Unsanitized provider error persisted during recovery.
    Reference: packages/coding-agent/src/sdk/host/session-runtime.ts:1451
    rejectionRecoveryIntent copies error.message verbatim; this value is passed into deadline recovery and can be persisted or exposed through prompt status. Use sanitizePromptFailure(error) before constructing the recovery intent.

CI / Verification

  • Reviewed the exact remote head: 83242618d3538486a4b7bd5c5e3810f22a40f91f.
  • CI summary: 64 passing, 10 failing, 19 pending/cancelled/skipped.
  • Failing checks: Affected path validation, Affected path validation / evidence producer, Affected path validation / test:@gajae-code/agent-core.
  • Repository policy permits review before all gating checks pass; the current non-passing checks are recorded above and do not establish that checks passed.

Axis Coverage

Axis Verdict Coverage
A1. Intent / Policy / Contract APPROVED The additive agent_failed lifecycle event, queued-promotion dispositions, reconciliation compatibility, ACP mapping, and daemon generation boundary are coherently represented.
A2. Architecture / Correctness / Failure CHANGES_REQUESTED Concurrency handling covers run identity, lifecycle fencing, deadline races, and queue removal, but persistent skill-write failures can still strand accepted work.
A3. Security / Privacy / Trust CHANGES_REQUESTED Provider failures are generally sanitized, but durable rejection recovery still exposes raw provider error messages.
A4. Verification / Tests / CI APPROVED A4 review confirms broad targeted test additions, but failed unit shards and skipped virtual integration leave regressions unresolved.
A5. Context / Compatibility / Platform APPROVED The integration and platform contracts appear coherently propagated and documented, but failed or skipped CI limits confidence in runtime compatibility.

Limitations

  • Affected path validation and exact-head contract CI jobs failed; virtual integration and several platform jobs were skipped, limiting runtime platform validation.
  • Virtual integration validation was skipped, limiting end-to-end regression confidence.

@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

Both findings from the 83242618d review are fixed; dev advanced (8f6b442035 → 0e5a0832e), so this is fix-forward plus rebase at exact head ced48f214d533e38c48a96fd855c77b797712942 on current dev base 0e5a0832e732b6db918f7957afaae5c2808ceb0a. Canonical three-dot digest: 54c2fc743969771f8c3892fe4e539d5916e00097990e9b311e3bae9a72b08546; PR body rebound with a needs-human verdict.

  1. [P1] never-park skill recovery — the skill rejection retry stopped after three attempts and returned, leaving the durable record accepted forever (a skill has no deadline lease, so nothing else owned recovery). The exhausted branch now logs the sanitized classifier and keeps a live scheduled retry, guaranteeing eventual terminalization instead of parking inert.
  2. [P1] sanitized recovery intentrejectionRecoveryIntent copied error.message verbatim into the intent that deadline replay persists and prompt status surfaces; it now returns sanitizePromptFailure(error) — classifier code and fixed message only.

Exact-head evidence: session-runtime 80/80; deadline-manager 13/13; agent 22/22; both package checks and bun run build clean.

@probepark @snowykr — fresh exact-head review requested at ced48f214. No release/tag/publish/main mutation.


[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 five-axis review completed against the exact head and identified 1 actionable issue, led by Use the sanitized failure shape in the wire fixture. These findings require changes before approval.

Findings / Required Changes

  1. [P2] Use the sanitized failure shape in the wire fixture.
    Reference: packages/coding-agent/test/agent-wire/fixtures.ts:24
    The agent_failed fixture supplies a raw Error despite the documented { code, message } contract, and the cast hides this mismatch; replace it with a sanitized diagnostic so wire tests validate the public payload shape.

CI / Verification

  • Reviewed the exact remote head: ced48f214d533e38c48a96fd855c77b797712942.
  • CI summary: 63 passing, 11 failing, 19 pending/cancelled/skipped.
  • Failing checks: Affected path validation, Affected path validation / evidence producer, Affected path validation / test:@gajae-code/coding-agent:shard-8-of-8.
  • Repository policy permits review before all gating checks pass; the current non-passing checks are recorded above and do not establish that checks passed.

Axis Coverage

Axis Verdict Coverage
A1. Intent / Policy / Contract APPROVED API and compatibility boundaries appear additive and explicitly versioned; no concrete breaking boundary defect was established.
A2. Architecture / Correctness / Failure APPROVED Concurrency lifecycle handling adds bounded acceptance deadlines, promotion identity, removal terminalization, and generation-fenced reconciliation; no concrete defect was established.
A3. Security / Privacy / Trust APPROVED Security/privacy controls reviewed; no exposed provider-error details or actionable trust-boundary weakness established.
A4. Verification / Tests / CI APPROVED A4 conclusion: coverage is broad, but observable CI failures and skipped integration validation prevent establishing a clean verification result.
A5. Context / Compatibility / Platform CHANGES_REQUESTED Integration and documentation contracts are mostly consistent; the remaining risk is a raw Error-shaped agent_failed test fixture masking the sanitized wire contract, with full CI/platform validation incomplete.

Limitations

  • Affected path validation and several coding-agent/agent-core CI jobs failed, while virtual integration and Windows platform jobs were skipped; therefore full cross-platform integration success cannot be established.

@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

The ced48f214 review finding is fixed; dev advanced (0e5a0832e → a00731c12), so this is fix-forward plus rebase at exact head fa75b5daadbee83aacc9856062cd18787770c178 on current dev base a00731c1207146a77aecd364aefb54ccd83bcf5f. Canonical three-dot digest: 38460ff420bf714889ce0ee603d35fbf35085a80187c856b43a5f33016e99926; PR body rebound with a needs-human verdict.

[P2] sanitized wire fixture — the agent_failed fixture supplied a raw Error despite the documented {code,message} contract, with the ev() cast hiding the mismatch. The fixture now carries the sanitized diagnostic pair (provider_unavailable / fixed message) so wire tests validate the public payload shape (agent-wire suites 15/15).

Noting the review's A1–A4 axes are APPROVED with only this fixture finding plus CI-gate caveats outstanding; the CI failures cited remain the needs-human contract gate plus shard/evidence cascades documented earlier.

@probepark @snowykr — fresh exact-head review requested at fa75b5daa. No release/tag/publish/main mutation.


[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 five-axis review completed against the exact head and identified 2 actionable issues, led by Clarify sanitized failure payload wording and Raw persistence errors are logged. These findings require changes before approval.

Findings / Required Changes

  1. [P2] Clarify sanitized failure payload wording.
    Reference: docs/sdk-embedding.md:216-218
    The text says agent_failed carries the provider/local error, while the public README contract specifies only sanitized { code, message }; revise this wording to state that only the sanitized diagnostic is exposed.
  2. [P2] Raw persistence errors are logged.
    Reference: packages/coding-agent/src/sdk/host/session-runtime.ts:3480-3505
    The abandoned-submission recovery logs reasonError and transitionError objects without sanitization; filesystem or transport errors may contain sensitive paths or operational details. Log only a bounded sanitized classifier/message, consistent with the surrounding provider-error handling.

CI / Verification

  • Reviewed the exact remote head: fa75b5daadbee83aacc9856062cd18787770c178.
  • CI summary: 64 passing, 9 failing, 20 pending/cancelled/skipped.
  • Failing checks: Affected path validation, Affected path validation / evidence producer, Affected path validation / test:@gajae-code/agent-core.
  • Repository policy permits review before all gating checks pass; the current non-passing checks are recorded above and do not establish that checks passed.

Axis Coverage

Axis Verdict Coverage
A1. Intent / Policy / Contract APPROVED API and compatibility boundaries appear coherently extended; no concrete contract break was established from the reviewed evidence.
A2. Architecture / Correctness / Failure APPROVED A1-A5 review found no actionable correctness or concurrency issue; lifecycle reconciliation is substantially covered, with remaining confidence limited by failed CI shards.
A3. Security / Privacy / Trust CHANGES_REQUESTED Failure payloads are sanitized before public emission, but recovery logging still risks leaking raw persistence-error details.
A4. Verification / Tests / CI APPROVED Verification coverage is broad and targeted tests pass, but unresolved CI failures leave potential regressions unlocalized.
A5. Context / Compatibility / Platform CHANGES_REQUESTED A1/A2/A4/A5: lifecycle integration is consistently wired, but documentation needs clarification and CI/platform evidence does not establish full compatibility.

Limitations

  • CI summary identifies failing jobs but provides no assertion or log details, so the failures cannot be attributed to a specific changed path.
  • Affected path validation failed, including agent-core and coding-agent shards; virtual integration, Windows, and Darwin-arm64 smoke checks were skipped, so those platform/integration paths are not established as passing.

@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

Both findings from the fa75b5daa review are fixed at exact head dd59add32581b5dc9f5f38ad124fa92577beba05 (fast-forward, same base a00731c12). Canonical three-dot digest: 2276d5dc1ffdc251d9a48fa4afebc8bcc1f775edd9eb9fc9f739dbd771f75f06; PR body rebound with a needs-human verdict.

  1. [P2] doc wordingdocs/sdk-embedding now states agent_failed carries only the sanitized {code,message} diagnostic, never the raw provider/local error, matching the README contract (docs index regenerated; byte-identical gate green).
  2. [P2] recovery logging — the abandoned-submission recovery's reasonError/transitionError log payloads now go through sanitizePromptFailure, consistent with the surrounding provider-error handling.

Exact-head evidence: session-runtime 80/80; docs-index gate green; package check clean.

@probepark @snowykr — fresh exact-head review requested at dd59add32. No release/tag/publish/main mutation.


[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

APPROVED

Summary

The five-axis review completed against the exact head without actionable P0-P2 findings. The reviewed API, correctness, security, verification, and compatibility boundaries are approved.

Findings / Required Changes

None.

CI / Verification

  • Reviewed the exact remote head: dd59add32581b5dc9f5f38ad124fa92577beba05.
  • CI summary: 64 passing, 9 failing, 19 pending/cancelled/skipped.
  • Failing checks: Affected path validation, Affected path validation / evidence producer, Affected path validation / test:@gajae-code/coding-agent:shard-7-of-8.
  • Repository policy permits review before all gating checks pass; the current non-passing checks are recorded above and do not establish that checks passed.

Axis Coverage

Axis Verdict Coverage
A1. Intent / Policy / Contract APPROVED Compatibility boundaries appear additive and explicitly versioned; no concrete API break or cross-platform boundary defect was established.
A2. Architecture / Correctness / Failure APPROVED Concurrency lifecycle changes are covered by targeted tests and the reviewed code preserves bounded ownership, terminalization, and stale-event fencing.
A3. Security / Privacy / Trust APPROVED Security and privacy controls reviewed; provider error text is sanitized before state, logs, and exposed lifecycle diagnostics.
A4. Verification / Tests / CI APPROVED A4 conclusion: verification coverage is broad, but failed CI jobs leave regression status unresolved without failure details.
A5. Context / Compatibility / Platform APPROVED Integration, documentation, and daemon/platform compatibility behavior are coherently updated; no concrete compatibility defect was established.

Limitations

  • CI summary reports failed affected-path and PR-contract jobs without failure details, so their specific causes cannot be assessed; Windows and Darwin platform jobs were skipped.

@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

Recovery update: exact remote head is 96a34b291a889c3b7b3b6adcfc1e9f1666bbf264, rebased semantically onto current dev 713000caee7501633b5521975eef273e5a95ee27; canonical three-dot digest is a73baa3ced01c7e12864d59bc9abcafb3f36526f1530e56e3cb0ee594f140884.

The current-dev integration uncovered and corrected two stale expectations: managed-attempt failure surfaces now assert the PR’s sanitized public diagnostic while retaining structured local-failure authority checks, and the streaming-edit abort test now verifies the #4840-injected settings argument. Focused lifecycle and contract suites, type checks, native build, production SDK host isolation, state-writer checks, and virtual-integration canaries pass. Fresh exact-head review is requested; no release mutation occurred.


[repo owner's gaebal-gajae (clawdbot) 🦞]

@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

Exact-head repair: deadlineRecoveryPending recovery now re-arms from the original acceptance timestamp after SDK runtime hydration, so restart cannot strand an accepted prompt outside its hard maximum. Regression coverage and coding-agent type checks pass at the new remote head. Fresh CI and independent review are required for this replacement head.


[repo owner's gaebal-gajae (clawdbot) 🦞]

@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

Architect review blockers repaired at the new exact head: ACP and CLI tailing now keep sanitized agent_failed diagnostic-only until agent_end; completed lifecycle state is cleared before a successor promotion; queued SDK follow-up cancellation emits removal disposition; and affected CI now owns prompt-deadline-manager coverage. Focused verification is green. Fresh exact-head CI and independent review are requested.


[repo owner's gaebal-gajae (clawdbot) 🦞]

gaebal-gajae added 6 commits August 23, 2026 03:22
Promoted prompts could remain accepted forever when execution never began.

Lease and reconcile prompts across promotion, active-run attachment, and terminal recovery so every accepted record reaches a bounded terminal state.

Lore-id: pr4669-recovery-v5
Constraint: preserve current dev #4840/#4841 behavior
Confidence: high
Scope-risk: high
Reversibility: revert-commit
Tested: focused SDK lifecycle and contract suites; coding-agent and agent checks; native build; state writer and virtual integration canaries
The reconciled SDK lifecycle fix sanitizes agent failure surfaces.

Update current-dev managed-attempt coverage to assert the stable public message and retain authority checks through structured diagnostics.

Lore-id: pr4669-recovery-v5-integration
Constraint: preserve #4840/#4841 structured local-failure behavior
Confidence: high
Scope-risk: low
Reversibility: revert-commit
Tested: managed attempt transaction, agent, and force-abort suites
Current dev injects session settings into auto-generated-file checks.

Bind the abort regression to that required third argument while retaining the generated-file and cancellation assertions.

Lore-id: pr4669-recovery-v5-current-dev
Constraint: preserve #4840 session settings propagation
Confidence: high
Scope-risk: low
Reversibility: revert-commit
Tested: streaming edit abort suite
Persisted uncertainty recovery records lost their in-memory lease on SDK runtime restart.

Reconstruct the lease from the original acceptance timestamp so the hard maximum remains bounded and expiration resumes.

Lore-id: pr4669-restart-recovery
Constraint: never reset an accepted prompt maximum runtime during recovery
Confidence: high
Scope-risk: high
Reversibility: revert-commit
Tested: sdk prompt deadline manager regression; coding-agent check
Diagnostic agent_failed events must not settle ownership before agent_end.

Keep ACP and CLI tailing nonterminal, retire completed lifecycle state, terminalize cancelled queued follow-ups, and register deadline-manager coverage.

Lore-id: pr4669-lifecycle-consumers
Constraint: agent_end is the sole terminal boundary
Confidence: high
Scope-risk: high
Reversibility: revert-commit
Tested: focused ACP/CLI-adjacent, lifecycle, deadline, and affected-selector suites; coding-agent check
Diagnostic agent_failed frames no longer settle ACP prompts.

Model failure fixtures as agent_failed followed by the authoritative agent_end boundary.

Lore-id: pr4669-acp-lifecycle
Confidence: high
Scope-risk: low
Reversibility: revert-commit
Tested: sdk ACP prompt terminal suite
@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

Reconciled PR #4669 onto current dev base 8a41a1db9d7d81b4a5c30db4d6ac71fc66572b65; exact remote head is 7f0d7d3176e6c7c3439f56cfc3dbae0728d1c366. Focused lifecycle/ACP/CLI/deadline/ownership regressions and both affected package checks pass. Prior broad CI failures reproduced as stale PR-contract digest bootstrap evidence; they are not reproducible product failures on current dev. Fresh exact-head contract, affected CI, and independent review are required after this rebase.


[repo owner's gaebal-gajae (clawdbot) 🦞]

@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

Reproduced the current affected-path failure on both exact rebased PR head 7f0d7d3176e6c7c3439f56cfc3dbae0728d1c366 and a clean detached current-dev worktree at 8a41a1db9d7d81b4a5c30db4d6ac71fc66572b65: packages/coding-agent/test/sdk-broker-lifecycle-e2e.test.ts fails the “never-settling model profile startup cuts off with proven pre-registration cleanup” assertion, receiving the existing terminal_uncertain startup-cleanup response rather than the expected spawn_failed proof payload. This is a reproduced current-dev baseline failure, not attributed to PR #4669. No other direct failure was reproduced from the affected harness report.


[repo owner's gaebal-gajae (clawdbot) 🦞]

@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

Exact-head contract revalidation requested after the current-dev rebase. The PR body carries the rebased head/base and regenerated canonical digest; this comment is solely the trusted validator trigger.


[repo owner's gaebal-gajae (clawdbot) 🦞]

@Yeachan-Heo

Copy link
Copy Markdown
Owner Author

Updated PR-contract evidence to the validator-derived exact three-dot digest for current head/base. Revalidation is requested; the prior digest failure is resolved by this replacement evidence.


[repo owner's gaebal-gajae (clawdbot) 🦞]

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