fix: prevent reconciliation check-in false deaths - #1916
Merged
simple-agent-manager[bot] merged 4 commits intoAug 26, 2026
Conversation
Contributor
simple-agent-manager
Bot
force-pushed
the
sam/stop-reconciliation-check-false-bj75fw
branch
from
August 26, 2026 02:22
367ce7b to
33bab24
Compare
|
Contributor
Author
|
Post-rebase verification note: branch is rebased on origin/main at b966b05 and PR CI is green on head 33bab24. I attempted fresh post-rebase staging deploys (32922917151, 32923601168), but both were cancelled before jobs started by staging workflow concurrency churn from newer branch deploys. Prior staging deploy 32919441324 succeeded for this PR before the rebase; the rebase only incorporated PR #1905, which touched the separate task-runtime-liveness path per the audit sequencing note. |
simple-agent-manager
Bot
deleted the
sam/stop-reconciliation-check-false-bj75fw
branch
August 26, 2026 02:43
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
reconciliation_checkinattention markers from failing healthy tasks while current-generation ACP activity isprompting/runtime work is active or settling.reconciliation_checkincandidate before deciding whether to renew or fail. It does not expand the alarm candidate query.Validation
pnpm lintpnpm typecheckpnpm test.claude/rules/47-control-loop-io-budget.md)Validation commands run:
pnpm --filter @simple-agent-manager/api test -- attention-expiry task-terminal-transition— passed, 3 files / 12 tests.pnpm --filter @simple-agent-manager/api test -- reconciliation— passed, 6 files / 164 tests.pnpm typecheck && pnpm lint— passed; lint warnings were existing baseline warnings inpackages/acp-clientandapps/web.pnpm --filter @simple-agent-manager/api test— passed, 606 files / 8254 tests.pnpm format:check— passed.git diff --check— passed.pnpm quality:observability-noise— passed; D1 telemetry skipped becauseOBSERVABILITY_DB_IDwas not set and Workers telemetry unavailable with 403, final result reported no significant log noise.Staging Verification (REQUIRED for all code changes — merge-blocking)
Deploy Stagingworkflow triggered manually and passed for this branchapp.sammy.party(staging) using test credentials and actively tested the applicationStaging Verification Evidence
b940ed42b3ad311a1949bda6200af98d9f91bad4: https://github.com/raphaeltm/simple-agent-manager/actions/runs/3291944132412 passed (1.4m).https://app.sammy.partyandhttps://api.sammy.party, using token-login auth. Covered dashboard load, project navigation, settings navigation, API tokens tab, unauthenticated redirect, API health, CORS, and console-error checks./healthreturnedstatus: healthy,/api/admin/tasks/stuckreturned zero active transient tasks.reconciliation_checkinmarkers. Staging has no public non-destructive endpoint to mint expired markers or advance a DO alarm clock. The exact alarm path was therefore verified with real-SQL unit coverage for: active current-generation ACP prompting renewal, active runtime-work renewal, stale activity expiry, heartbeat-only expiry, genuine no-liveness terminalization, terminal status-event/timestamp/step semantics, and idempotent retry behavior. The deployed staging branch passed health/smoke/API checks after those changes.UI Compliance Checklist (Required for UI changes)
End-to-End Verification (Required for multi-component changes)
.claude/rules/10-e2e-verification.md)Data Flow Trace
reconciliation_checkinmarker inapps/api/src/durable-objects/project-data/reconciliation.tsusing the shared reconciliation deadline.ProjectData.alarm()inapps/api/src/durable-objects/project-data/index.tsand callsprocessExpiredAttentionMarkers()with project-scoped hooks.apps/api/src/durable-objects/project-data/attention-expiry.tsinspects expired markers; forreconciliation_checkin, it reads current-generation session activity from local ProjectData SQL.prompting/recoveringor runtime work isactive/settling,attention-expiry.tsrenews the marker instead of failing the task.attention-expiry.tscallshandleReconciliationDeadTarget().apps/api/src/durable-objects/project-data/reconciliation-dead-target.tscallstransitionTaskToTerminal()inapps/api/src/services/task-terminal-transition.ts.transitionTaskToTerminal()performs the terminal D1 task update with status event, timestamp/step semantics, idempotency, supersession fence, trigger sync, admission cancellation, workspace stop, and task-wait hook.Untested Gaps
The internal DO alarm cannot be safely forced on staging through a public API without manufacturing and possibly killing real staging tasks. This gap is covered by real-SQL unit tests against the same ProjectData modules and by live staging deployment/smoke/API health checks proving the branch runs in Cloudflare.
Post-Mortem (Required for bug fix PRs)
What broke
A healthy Codex task could be failed by reconciliation check-in expiry after 60 seconds of silent tool work, even while ACP was actively prompting/working and the node heartbeat was fresh.
Root cause
reconciliation_checkinmarkers were resolved only by persisted user/assistant messages. Prompt acceptance, current-generation ACP activity, runtime work, and node heartbeats did not participate in the check-in response decision. The expiry path then wrote terminal failure directly totasks, bypassing the shared terminal status contract.Class of bug
State interaction race / liveness-classification bug, compounded by an inconsistent terminal writer.
Why it wasn't caught
The pre-existing tests did not discriminate between delivered active ACP work, heartbeat-only liveness, and genuine no-delivery/no-liveness expiry. They also did not assert terminal task status event/timestamp/execution-step contract behavior for attention-expiry failures.
Process fix included in this PR
Added focused regression coverage in:
apps/api/tests/unit/durable-objects/attention-expiry.test.tsapps/api/tests/unit/services/task-terminal-transition.test.tsapps/api/tests/unit/durable-objects/reconciliation.test.tsNo rule update was needed; this PR implements the existing terminal-writer requirements from
.claude/rules/66-task-terminal-status-events.md.Post-mortem file
Task file:
tasks/archive/2026-08-26-fix-reconciliation-checkin-attention-expiry.mdSpecialist Review Evidence (Required for agent-authored PRs)
needs-human-reviewlabel added and merge deferred to human — N/A; all completed.Exceptions (If any)
Agent Preflight (Required)
Classification
External References
/reliability/audits/production-stability-audit-2026-08-25.md, file id01M0XK1XYNB34YB0X6Z41HM542.apps/api/src/durable-objects/project-data/attention-expiry.ts,apps/api/src/durable-objects/project-data/reconciliation.ts,apps/api/src/durable-objects/project-data/message-persistence.ts,.claude/rules/47-control-loop-io-budget.md,.claude/rules/59-task-supersession.md,.claude/rules/66-task-terminal-status-events.md.Codebase Impact Analysis
Affected components:
apps/api/src/durable-objects/project-data/attention-expiry.tsapps/api/src/durable-objects/project-data/reconciliation-dead-target.tsapps/api/src/durable-objects/project-data/index.tsapps/api/src/services/task-terminal-transition.tsDocumentation & Specs
tasks/backlog/2026-08-06-attention-expiry-task-status-events.mdtotasks/archive/2026-08-06-attention-expiry-task-status-events.md.Constitution & Risk Check
Checked Constitution Principle XI / no hardcoded values: the reconciliation deadline remains environment-configured through the existing shared constant/helper; no new URLs, timeouts, limits, or identifiers were hardcoded into business logic. Main risk is control-loop overhead; mitigated by a same-DO local SQL guard only on expired check-in markers, preserving genuine no-liveness expiry.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com