Skip to content

fix(api): suppress normal TaskRunner handoff mismatch warnings - #1899

Merged
simple-agent-manager[bot] merged 4 commits into
mainfrom
sam/fix-remaining-tasksession-lifecycle-yhs0qj
Aug 25, 2026
Merged

fix(api): suppress normal TaskRunner handoff mismatch warnings#1899
simple-agent-manager[bot] merged 4 commits into
mainfrom
sam/fix-remaining-tasksession-lifecycle-yhs0qj

Conversation

@simple-agent-manager

Copy link
Copy Markdown
Contributor

Summary

  • Fixes the remaining production-evidenced TaskRunner/D1 lifecycle bookkeeping noise after PR fix(recovery): stop a successful session wake from failing its own predecessor #1896 without reimplementing the shipped supersession fixes.
  • Treats TaskRunner completed=true plus currentStep=running plus active D1 in_progress task as normal orchestration handoff, not a persisted do_task_status_mismatch warning.
  • Preserves conclusive dead-runtime reconciliation, and still writes one durable diagnostic for genuine completed-DO active-state mismatches before normal handoff convergence.
  • Changes mismatch dedupe from a 30-minute repeat window to one durable diagnostic per task.

Production evidence used: post-#1896 production queries showed 0 new workspace_deleted task failures, 0 ceiling_supersession_query_failed rows, and 276 post-deploy do_task_status_mismatch rows across 24 task IDs, all sampled with completed=true, doCurrentStep=running, and live/resumable/live-superseded liveness.

Control-loop volume/cost note: candidate selection was not widened. The high-volume normal handoff path now avoids the OBSERVABILITY_DATABASE write and lookup entirely. The remaining non-normal mismatch lookup is task-scoped on platform_errors.task_id, which has idx_platform_errors_task_id, then applies the existing JSON-context substring filter.

Validation

  • pnpm lint — 13 tasks passed; warning-only pre-existing a11y/hooks findings outside this diff.
  • pnpm typecheck — 19 tasks passed.
  • pnpm test — 604 test files / 8,230 tests passed; 21 tasks passed.
  • Additional validation run: pnpm build — 9 tasks passed; existing Turbo API output warning only.
  • Additional validation run: pnpm --filter @simple-agent-manager/api test -- tests/unit/stuck-tasks.test.ts — 52 passed.
  • Additional validation run: pnpm --filter @simple-agent-manager/api test -- tests/unit/recovery-resilience.test.ts — 69 passed.
  • Additional validation run: pnpm --filter @simple-agent-manager/api typecheck — passed.
  • Additional validation run: pnpm --filter @simple-agent-manager/api lint — passed.
  • Additional validation run: git diff --check origin/main...HEAD — passed.
  • If this PR changes candidate selection for a sweep/cron/alarm loop (WHERE clause, status set, join, or equivalent), expected candidate volume and worst-case per-candidate cost are stated in the summary or validation notes (see .claude/rules/47-control-loop-io-budget.md)

Staging Verification (REQUIRED for all code changes — merge-blocking)

All checkboxes below are mandatory for any PR that changes runtime code (.ts, .tsx, .go, etc.). Write N/A: docs-only ONLY if the PR contains zero runtime code changes. See .claude/rules/13-staging-verification.md.

  • Staging deployment green — intentionally not run. User explicitly instructed: do not deploy to staging until the coordinator assigns the shared staging/merge wave.
  • Live app verified via Playwright — intentionally not run for the same coordinator-gated staging wave.
  • Existing workflows confirmed working — intentionally deferred to the shared staging/merge wave.
  • New feature/fix verified on staging — intentionally deferred to the shared staging/merge wave.
  • Infrastructure verification completed — N/A: no infra paths changed.
  • Mobile and desktop verification notes added for UI changes — N/A: no UI changes.

Staging Verification Evidence

Not run by explicit instruction. This draft PR must not be merged until the coordinator assigns the shared staging/merge wave and staging verification is completed.

UI Compliance Checklist (Required for UI changes)

  • Mobile-first layout verified — N/A: no UI changes.
  • Accessibility checks completed — N/A: no UI changes.
  • Shared UI components used or exception documented — N/A: no UI changes.
  • Playwright visual audit run locally — N/A: no UI changes.

End-to-End Verification (Required for multi-component changes)

  • Data flow traced from user input to final outcome with code path citations (see .claude/rules/10-e2e-verification.md)
  • Capability test exercises the complete happy path across system boundaries
  • All spec/doc assumptions about existing behavior verified against code (not just "read the code")
  • If any gap exists between automated test coverage and full E2E, manual verification steps documented below

Data Flow Trace

  1. apps/api/src/scheduled/stuck-tasks.ts:recoverStuckTasks() selects existing queued/delegated/in_progress candidates without widening selection.
  2. For non-stuck candidates beyond the DO mismatch grace, the sweep probes TaskRunner status and, for in-progress tasks, task-scoped runtime liveness.
  3. Conclusive dead runtime still sets isStuck=true before mismatch diagnostics, preserving terminal reconciliation and trigger sync.
  4. Normal handoff (task.status=in_progress, doStatus.completed=true, doStatus.currentStep=running) logs non-persisted info only and skips OBSERVABILITY_DATABASE writes.
  5. Non-normal completed-DO active-state mismatch checks for an existing task-scoped diagnostic, then persists at most one do_task_status_mismatch row with bounded context.

Untested Gaps

Staging verification is intentionally deferred by user instruction. The lifecycle branches are covered by deterministic unit tests through recoverStuckTasks() with realistic D1 rows, TaskRunner DO status, ProjectData/ACP liveness, session snapshot, and supersession boundary state.

Post-Mortem (Required for bug fix PRs)

What broke

Healthy or restorable task/session work was repeatedly displayed as a possible D1 mismatch because the recovery sweep persisted do_task_status_mismatch warnings for normal TaskRunner handoff tuples.

Root cause

The sweep treated TaskRunner DO completed=true as if task finalization should already have reached D1. In current lifecycle semantics, TaskRunner completion at currentStep=running means orchestration handed off successfully while the D1 task remains active until the agent/user terminal path.

Class of bug

Terminal/resumer semantic mismatch in lifecycle bookkeeping, amplified by repeated control-loop diagnostics.

Why it wasn't caught

Existing tests covered missing/error TaskRunner status and dead-runtime convergence, but not the exact production tuple: completed TaskRunner, D1 active task, and live/resumable/live-superseded liveness.

Process fix included in this PR

No new process rule was needed. This PR applies existing rules for terminal verdict/resumer symmetry, real-trigger regression tests, and control-loop I/O budgeting, with evidence recorded in tasks/active/2026-08-24-taskrunner-handoff-mismatch-bookkeeping.md.

Post-mortem file

tasks/active/2026-08-24-taskrunner-handoff-mismatch-bookkeeping.md

Specialist Review Evidence (Required for agent-authored PRs)

  • All local reviewers completed and findings addressed before merge
  • If any reviewer did NOT complete: needs-human-review label added and merge deferred to human — N/A: all completed.
Reviewer Status Outcome
test-engineer PASS Deterministic scheduled-sweep tests cover normal handoff suppression, restorable/live-superseded cases, dead-runtime convergence, genuine mismatch diagnostic, and no-repeat dedupe.
cloudflare-specialist PASS No Cloudflare config/migration changes; hot path removes observability D1 writes; remaining diagnostic lookup is task-scoped and indexed by task_id.
constitution-validator PASS No new URLs, timeouts, limits, secrets, or deployment-specific identifiers; handoff sentinel is typed shared TaskExecutionStep vocabulary.
task-completion-validator PASS Research findings and acceptance criteria map to code/tests; UI/backend and multi-resource checks are not applicable.

Exceptions (If any)

  • Scope: Staging deployment and staging Playwright verification.
  • Rationale: User explicitly instructed not to deploy to staging and not to merge until the coordinator assigns the shared staging/merge wave.
  • Expiration: Coordinator assignment of the shared staging/merge wave.

Agent Preflight (Required)

  • Preflight completed before code changes

Classification

  • external-api-change
  • cross-component-change
  • business-logic-change
  • public-surface-change
  • docs-sync-change
  • security-sensitive-change
  • ui-change
  • infra-change

External References

Codebase Impact Analysis

Affected paths:

  • apps/api/src/scheduled/stuck-tasks.ts — scheduled recovery bookkeeping and diagnostics.
  • apps/api/tests/unit/stuck-tasks.test.ts — regression coverage for normal handoff, resumable/superseded handoff, dead-runtime convergence, genuine mismatch, and no-repeat dedupe.
  • apps/api/tests/unit/recovery-resilience.test.ts — source-contract assertions updated to the new diagnostic behavior.
  • tasks/active/2026-08-24-taskrunner-handoff-mismatch-bookkeeping.md — task evidence and review record.

Documentation & Specs

No public docs changed. Active task evidence updated because this is internal lifecycle bookkeeping and staging is deferred.

Constitution & Risk Check

Checked Principle XI (no hardcoded config), canonical idleness semantics, terminal verdict/resumer symmetry, and control-loop I/O budget. Main risk is under-reporting genuine D1 drift; mitigated by keeping one durable non-normal diagnostic and preserving conclusive dead-runtime reconciliation unchanged.

@codspeed-hq

codspeed-hq Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 6 untouched benchmarks


Comparing sam/fix-remaining-tasksession-lifecycle-yhs0qj (b502276) with main (03d1e61)

Open in CodSpeed

@simple-agent-manager

Copy link
Copy Markdown
Contributor Author

CI evidence for head fb2d21a4fcdd471d29c6e9d30b5a4a80256bf97e:

Staging was intentionally not triggered per task instruction. PR remains draft and must not be merged until the coordinator assigns the shared staging/merge wave.

@simple-agent-manager
simple-agent-manager Bot force-pushed the sam/fix-remaining-tasksession-lifecycle-yhs0qj branch from fb2d21a to b502276 Compare August 25, 2026 06:50
@sonarqubecloud

Copy link
Copy Markdown

@simple-agent-manager
simple-agent-manager Bot marked this pull request as ready for review August 25, 2026 07:18
@simple-agent-manager
simple-agent-manager Bot merged commit 0e655f4 into main Aug 25, 2026
30 checks passed
@simple-agent-manager
simple-agent-manager Bot deleted the sam/fix-remaining-tasksession-lifecycle-yhs0qj branch August 25, 2026 07:19
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.

1 participant