fix(backlog): recover sdd-pipeline triage stuck on premature-completion placeholder - #290
Merged
Merged
Conversation
…on placeholder Item 04089969 sat in idea forever: its "sdd" pipeline mode triage call ended a single-shot claude -p turn with "I'll wait for its completion" instead of the final JSON block (no later turn exists to resume it in), and reconcileOrphanedTriageItems only ever matched still-open-and-stale sessions, not ones that had already ended cleanly with unparseable output. - headlessTriageSystemPrompt / sddTriagePromptTemplate: explicit "single, non-interactive call with no later turn" directive so a subagent reported as backgrounded is waited out within the same call, not deferred to a follow-up turn that will never arrive. - reconcileOrphanedTriageItems: also flags idea-status items whose latest triage session has already ended without transitioning the item to ready, reusing the existing StuckReasonOrphanedTriage/AutoRespawnTriage backoff-gate retry machinery from PR #274 rather than adding a new stuck reason. Regression tests reproduce the exact placeholder text from the incident log and verify the detector both flags and retries the new shape. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3683CH7Fs9zYR2yP3Dpba
Contributor
✅ Registry ValidationTest Coverage: 22/180 features have
|
Contributor
Go Benchmarks (Tier 1) |
Contributor
E2E RPC Latency |
Contributor
Frontend Terminal Throughput |
Contributor
📊 Feature E2E CoverageFeature coverage report unavailable
|
…ction and prompt guidance Adds regression coverage for three gaps a code review found in this PR's diff: reconcileOrphanedTriageItems' latestTriage selection when an item has both an older ended and a newer open triage session, the "single, non-interactive call / no later turn" guidance paragraph in both headlessTriageSystemPrompt and sddTriagePromptTemplate, and a stale test-name cross-reference in a doc comment. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3683CH7Fs9zYR2yP3Dpba
Contributor
✅ Registry ValidationTest Coverage: 22/180 features have
|
tstapler
marked this pull request as ready for review
July 30, 2026 12:35
tstapler
added a commit
that referenced
this pull request
Jul 30, 2026
…ate, root-cause investigation Merges the pre-fix audit findings (1 stuck item, both 07-28 MAJORs closed, item #5 closed) with the shipped fix's own writeup (PR #290), keeping both in chronological order. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3683CH7Fs9zYR2yP3Dpba
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
Backlog item
04089969-0f19-499c-be34-2e8bcfc4f13e(PipelineModesdd) was stranded inideastatus forever: its headless triage call ended a single-shotclaude -pturn with a "I'll wait for its completion" status message instead of the required JSON result, and no existing detector could catch a triage session that had already ended cleanly with unparseable output.Context
Root-caused via
staplersquad-2026-07-29T22-55-04.915.log.gz:32397—ParseHeadlessTriageResultcorrectly rejected the raw output,TriggerTriagetombstoned the session, but never reached theidea→readytransition.reconcileOrphanedTriageItems(PR #274's orphaned-triage detector) only matched sessions that were still open and stale — a cleanly-ended, unparseable session was invisible to it and to every other stuck detector.Root cause: the "sdd" pipeline mode's triage prompt (
session/pipeline_mode_seed.go'ssddTriagePromptTemplate) instructs the model to runsdd:3-plan, which dispatches a planning subagent and says "wait for it to complete." Aclaude -pheadless call has no later turn to resume in — once the top-level turn ends with no more pending tool calls, the process exits with whatever text was last written. The model reported the subagent as "running in the background" and ended its turn expecting a follow-up notification a one-shot call can never deliver.Changes
session/headless/features.go: added an explicit "this is a single, non-interactive call with no later turn" directive toheadlessTriageSystemPrompt— applies to every pipeline mode's triage call (defense in depth).session/pipeline_mode_seed.go: added the same guard, phrased against thesdd:3-plansubagent-dispatch step specifically, tosddTriagePromptTemplate.session/backlog_lifecycle.go:reconcileOrphanedTriageItemsnow also flags an idea-status item whose latest triage session has already ended without transitioning the item to ready — no staleness wait needed, sinceTriggerTriagealways attempts the transition immediately after a successful parse. Reuses the existingStuckReasonOrphanedTriage/AutoRespawnTriagebackoff-gate retry machinery from PR fix(backlog): wire orphaned_triage into the remediation backoff framework #274 rather than adding a new stuck reason.session/domain/backlog.go: updatedStuckReasonOrphanedTriage's doc comment to describe both shapes.docs/tasks/backlog-feature-improvement.md: added the 2026-07-30 write-up (root cause, fix, regression tests, recurring-shape classification).Known limitation: the "sdd"
PipelineModeDB row is seeded once at boot and never overwritten (by design — operator hand-edits must survive restarts). An already-seeded production row keeps the old prompt text until manually refreshed via the pipeline-modes settings UI; new/fresh deployments get the fix immediately. The detection/retry fix is independent of this and works either way.Test plan
go test ./session/... ./server/services/...— all green except the pre-existing, already-filedBUG-051flake insession/tmux(unrelated — this diff touches no file undersession/tmux/, and the flaking test passes reliably in isolation).make buildmake lintTestParseHeadlessTriageResult_PrematureCompletionPlaceholder— reproduces the exact raw string from the incident log.TestReconcileOrphanedTriageItems_should_flagImmediately_When_TriageSessionEndedWithoutTransitionTestReconcileOrphanedTriageItems_should_notFlag_When_NoTriageSessionEverRanTestReconcileOrphanedTriageRemediation_should_retryEndedWithoutTransitionRow_When_Due🤖 Generated with Claude Code
https://claude.ai/code/session_01W3683CH7Fs9zYR2yP3Dpba