T-89GV-task-work-backgrounds-baseline-capture
Status: closed/superseded · Impact: medium · Complexity: small
AUTO-DEFINED: this spec was best-effort machine-authored by /sdlc:task-auto-define on 2026-08-03 because the task is autonomy: autonomous/pr. Review the Goal, Approach, Today, Files-to-touch, and Acceptance-criteria carefully before trusting it.
/sdlc:task-work Step 3a captures a quality baseline by running the project’s
full quality suite in the foreground, which on a repo with multi-minute gates
exceeds the default Bash timeout and forces the operator to re-run the capture
by hand in the background. Step 3a should background the capture by default, or
state plainly that projects with multi-minute gates need an extended timeout.
This gap was reported from [T-JOXA-task-kind-field-and-leaf-dispatch](/planning/tasks/task-kind-field-and-leaf-dispatch/) on
git@github.com:sksizer/dev.git:
task-work’s Step 3a quality baseline capture runs the full quality suite — over 10 minutes on this repo (full tsc plus the whole
bun test apps/sdlcsuite) — which exceeds the default foreground Bash timeout and forces a manual re-run in the background. Step 3a should either background the capture by default or state that projects with multi-minute gates need an extended timeout. Note for the receiver: T-2T20-task-work-backgrounds-quality-gate is marked closed/done citing PR #970, but that PR’s only changed file was the task file itself — noapps/sdlc/skills/task-work/SKILL.mdchange ever landed, and the current Step 3a (around line 396) still shows a plain foreground invocation with no backgrounding guidance. The gap is live.
| Location | Role today |
|---|---|
apps/sdlc/skills/task-work/SKILL.md:401 | Step 3a sub-step 2’s baseline-capture invocation. A plain foreground shell-out to sdlc quality baseline capture; the surrounding prose names no backgrounding affordance and no timeout expectation, so an operator following the step verbatim runs it as a default-timeout foreground Bash call. |
apps/sdlc/skills/task-work/SKILL.md:430 | Step 3a’s closing cost statement — “The baseline is cheap (one extra full run of the gate, sequenced before any code is written).” The only wall-clock signal in the step, and it reads as sub-minute. |
apps/sdlc/skills/task-work/SKILL.md:894 | The pre-PR dogfood block’s second sdlc quality baseline capture invocation, in the Step 7 section. Same verb, same foreground shape, same timeout hazard. |
sdlc.yaml | This repo’s declared quality_checks: — eleven verbs including bunx tsc --noEmit, bun test apps/sdlc, bun test ./.claude, and a full docs-site build. One capture pass runs every one of them in sequence. |
apps/sdlc/lib/services/quality/ops/baseline/capture.ts | The op Step 3a shells out to. Runs each declared verb against the current tree; its wall-clock is the sum of the project’s verbs, with no internal time budget and no backgrounding affordance of its own. |
apps/sdlc/lib/services/gate/ops/_skill_prose_contract.ts | SKILL_PROSE_REGISTRY, the gate that pins load-bearing SKILL.md prose. Its task-work entry pins the final-verdict markers and the Notes/Failure-modes sections; nothing in Step 3a is pinned, so Step 3a prose can regress silently. |
docs/planning/tasks/T-2T20-task-work-backgrounds-quality-gate.md | A closed/done task whose completion_note claims this fix shipped via PR #970. That PR’s only changed file was the task file itself, so no SKILL.md change landed and the gap it describes is still open. |
Proposed
Section titled “Proposed”Step 3a documents a capture that completes on a project whose quality suite runs
for double-digit minutes: the invocation is backgrounded by default with an
explicit completion check the operator gates on, plus a named fallback for
harnesses without a backgrounding affordance (raise the Bash timeout explicitly
rather than accept the default). The step’s cost statement reflects real
wall-clock instead of calling the capture unqualifiedly cheap. The pre-PR
dogfood capture — the same verb, later in the file — carries the same shape, so
there is one documented way to run a capture. A SKILL_PROSE_REGISTRY pin makes
the backgrounding guidance load-bearing, so a future PR that touches only the
task file cannot claim the fix a second time.
Approach
Section titled “Approach”- Rewrite Step 3a sub-step 2 in
apps/sdlc/skills/task-work/SKILL.mdso the documented invocation is backgrounded by default. Keep thesdlc quality baseline captureargv byte-identical (SHA positional,--config,--baseline-dir); change only how it is launched — the Bash tool’srun_in_background, with combined output redirected to a run-scoped log under<project-root>/.sdlc/quality-baselines/. - Add an explicit completion check as a new sub-step between the launch and
today’s sub-step 3 (the finding-count report): poll the background task until
the capture process exits, then gate on its bare exit code — no pipe through
head/tail, per the “Don’t pipe commands you gate on” rule inapps/sdlc/skills/CLAUDE.md. Only after that does the operator read the written JSON for the finding count. - Add one sentence naming the fallback for a harness with no backgrounding affordance: set an explicit non-default Bash timeout sized to the project’s suite rather than accepting the default. This is the “or state that projects with multi-minute gates need an extended timeout” half of the reported gap, kept as the documented alternative rather than the primary path.
- Replace the closing sentence at
apps/sdlc/skills/task-work/SKILL.md:430(“The baseline is cheap …”) with an accurate cost statement: the capture is one full pass of the project’s declaredquality_checks:, so its wall-clock scales with that list and runs into double-digit minutes on a large one. Keep the existing follow-on sentence about the 5-SHA prune unchanged. - Apply the same backgrounded shape to the pre-PR dogfood capture at
apps/sdlc/skills/task-work/SKILL.md:894so bothquality baseline captureinvocations in the file read the same way. Leave thesdlc quality runline in that same block on its current foreground shape — the gate verb is out of scope here. - Add a
task-workentry toSKILL_PROSE_REGISTRYinapps/sdlc/lib/services/gate/ops/_skill_prose_contract.tspinning the Step 3a backgrounding guidance: a section entry for the Step 3a heading with arequirespattern matching the backgrounding instruction, carrying anidin the establishedskill-prose/task-work/<kind><n>shape and anoteciting this task and the PR #970 non-landing as the reason the pin exists. - Verify: run
bun apps/sdlc/cli/sdlc.ts gate skill-prose(must exit 0 against the edited SKILL.md) andbun test apps/sdlc. Then confirm the pin bites by temporarily reverting the Step 3a edit and re-running the gate — it must fail — before restoring the edit.
Files to touch
Section titled “Files to touch”| Location | Kind | Change |
|---|---|---|
apps/sdlc/skills/task-work/SKILL.md | modify | Step 3a sub-step 2 launches the capture backgrounded, a new sub-step gates on its exit code, a sentence names the extended-timeout fallback, the closing “cheap” cost statement is replaced with a wall-clock-accurate one, and the pre-PR dogfood capture gets the same backgrounded shape. |
apps/sdlc/lib/services/gate/ops/_skill_prose_contract.ts | modify | Add a Step 3a section + requires pin under the existing task-work registry entry so the backgrounding guidance cannot silently disappear again. |
Acceptance criteria
Section titled “Acceptance criteria”- AC-1: Step 3a of
apps/sdlc/skills/task-work/SKILL.mdinstructs the operator to launchsdlc quality baseline captureas a background task by default, and names the completion check to gate on before reading the baseline JSON. - AC-2: Step 3a names an explicit non-default Bash timeout as the documented fallback for a harness without a backgrounding affordance.
- AC-3:
command grep -c "quality baseline capture" apps/sdlc/skills/task-work/SKILL.mdstill reports 2, and both hits sit inside a backgrounded launch block. - AC-4:
command grep -n "The baseline is cheap" apps/sdlc/skills/task-work/SKILL.mdreturns no match, and the replacement sentence names the project’squality_checks:list as what the capture’s wall-clock scales with. - AC-5:
SKILL_PROSE_REGISTRYinapps/sdlc/lib/services/gate/ops/_skill_prose_contract.tscontains atask-workentry whoserequirespattern matches the Step 3a backgrounding instruction, with anidof the formskill-prose/task-work/.... - AC-6:
bun apps/sdlc/cli/sdlc.ts gate skill-proseexits 0 on the edited tree, and exits non-zero when the Step 3a backgrounding instruction is removed. - AC-7:
bun test apps/sdlcpasses.
Out of scope
Section titled “Out of scope”- Backgrounding Step 7’s
sdlc quality rungate invocation, and passing it an explicit main-repo--baseline-dir. Those are the other two halves of T-2T20-task-work-backgrounds-quality-gate and need their own decision about baseline-dir resolution inside a worktree. - Correcting T-2T20-task-work-backgrounds-quality-gate’s
status: closed/doneandcompletion_note. That is a task-state frontmatter fix that lands onmain, not on this branch. - Changing
sdlc quality baseline captureitself — an internal time budget, parallel verb execution, or a--backgroundflag on the op. This task is a prose change in the skill plus the gate pin that holds it. docs/skills/task-work.md’s flowchart. Its Step 3a node label describes what the step does, which this fix does not change.
Dependencies
Section titled “Dependencies”- none
Discovery context
Section titled “Discovery context”Spawned by /sdlc:spawn-task-pr on 2026-08-03 UTC from
T-JOXA-task-kind-field-and-leaf-dispatch in git@github.com:sksizer/dev.git.
The receiver should note that T-2T20-task-work-backgrounds-quality-gate
already describes this gap and is marked closed/done citing PR #970 — that
PR’s only changed file was the task file itself (verified against the merged
PR), so no apps/sdlc/skills/task-work/SKILL.md change ever landed.