T-ZKTV-namespace-task-work-scratch-files
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 writes intermediate scratch files — captured quality-gate
output, the PR-body tempfile, the follow-ups list — without pinning their
names. Concurrent runs (the normal case under /sdlc:orchestrate, which
dispatches up to max_implementations at once) share one session scratchpad,
so an operator-invented fixed name like gate.log is written by both runs and
the second run’s truncation destroys the first run’s evidence. The skill
already namespaces its heartbeat log and PID file by task basename; extending
that rule to every scratch file it writes closes the collision.
Parallel /sdlc:task-work sessions collide in the shared session scratchpad: two concurrent runs both wrote
gate.log, and the second run’s truncation destroyed the first run’s quality-gate output after it had already been written. task-work should namespace every scratch filename it writes by the task basename so concurrent runs cannot clobber each other.
— reported from T-5G81-lease-payload-gates
| Location | Role today |
|---|---|
apps/sdlc/skills/task-work/SKILL.md | The skill prose. Its Conventions block pins worktrees to .sdlc/worktrees/<task-basename> and the branch to task/<task-basename>, and Step 6 namespaces only the heartbeat pair (.sdlc/runtime/lease-heartbeat-<basename>.log / .pid). Step 7’s quality-gate output capture, Step 10.2’s mktemp PR-body file, and Step 10.5’s follow-ups tempfile name nothing, so the operator invents a fixed name in the shared session scratchpad. |
apps/sdlc/conventions/lease-aware-skills.md | Documents the <task-id>-namespaced heartbeat log/PID shape — the existing per-task scratch-naming precedent, scoped to the heartbeat alone. |
apps/sdlc/lib/services/gate/ops/_skill_prose_contract.ts | The skill-prose gate registry. Its task-work entry pins marker and verdict prose; nothing pins scratch-file naming, so the rule can silently drift back out of the SKILL.md. |
apps/sdlc/lib/services/gate/ops/_skill_prose_contract.test.ts | Unit coverage for the registry, run by the bun test apps/sdlc quality verb. |
apps/sdlc/skills/pr-respond/SKILL.md | Sibling lease-aware skill carrying the same heartbeat-only namespacing. Not changed by this task. |
Proposed
Section titled “Proposed”apps/sdlc/skills/task-work/SKILL.md states one scratch-file naming rule in
its Conventions block — every intermediate the run writes outside the
worktree’s tracked tree is named <task-basename>-<purpose>.<ext> — and every
scratch path the skill itself names follows that shape. The skill-prose gate
pins the rule, so deleting it from the SKILL.md fails
sdlc gate skill-prose instead of regressing silently. Two concurrent
/sdlc:task-work runs on different tasks then write disjoint scratch paths,
and neither can truncate the other’s output.
Approach
Section titled “Approach”- Add a
Scratch files:bullet to the Conventions block inapps/sdlc/skills/task-work/SKILL.md, adjacent to the existingWorktrees:andBranch:bullets. It states the rule (<task-basename>-<purpose>.<ext>), gives two concrete examples, and names the reason in one clause: concurrent runs share one session scratchpad, so a fixed name lets the later writer truncate the earlier run’s evidence. Cite the heartbeat pair as the existing instance of the rule. - In Step 7 (
## 7. Local quality checks), where the prose tells the operator to re-run the executor with--logonFAIL, name the capture path<basename>-quality.log. Leave the “don’t pipe commands you gate on” rule untouched — the capture is for inspection after the gating invocation, not in place of it. - In Step 10.2, replace the bare
mktempwithmktemp -t <basename>-pr-bodyso the PR-body tempfile carries the basename even under the system temp directory. - In Step 10.5, pin
<followups-path>to<basename>-followups.txtrather than describing it as “a tempfile”. - Add a required-pattern entry to the
task-workkey ofSKILL_PROSE_REGISTRYinapps/sdlc/lib/services/gate/ops/_skill_prose_contract.tsthat pins the literal<task-basename>-scratch-name token, with anoteciting this task and the collision it prevents. Follow the shape of the neighbouring entries in the same key (pattern + note, optionalsection:hint). - Extend
apps/sdlc/lib/services/gate/ops/_skill_prose_contract.test.tswith a case asserting the new entry fires when the bullet is absent from a fixture SKILL.md body. - Run
sdlc gate skill-prose --paths apps/sdlc/skills/task-work/SKILL.mdand the project’squality_checks:verbs viasdlc quality run.
Files to touch
Section titled “Files to touch”| Location | Kind | Change |
|---|---|---|
apps/sdlc/skills/task-work/SKILL.md | modify | Add the Scratch files: Conventions bullet; namespace the Step 7 quality-log capture, the Step 10.2 PR-body tempfile, and the Step 10.5 follow-ups tempfile by task basename. |
apps/sdlc/lib/services/gate/ops/_skill_prose_contract.ts | modify | Add a required-pattern entry under the task-work registry key pinning the scratch-name rule. |
apps/sdlc/lib/services/gate/ops/_skill_prose_contract.test.ts | modify | Cover the new registry entry: present in the real SKILL.md, flagged when absent. |
Acceptance criteria
Section titled “Acceptance criteria”- AC-1: The Conventions block of
apps/sdlc/skills/task-work/SKILL.mdcontains aScratch files:bullet stating that every scratch file the run writes is named<task-basename>-<purpose>.<ext>. - AC-2: Every scratch path named in
apps/sdlc/skills/task-work/SKILL.mdcarries the basename token — the set is the lines matched bycommand grep -nE 'mktemp|\.log|\.pid|followups' apps/sdlc/skills/task-work/SKILL.md, and each matched scratch path contains<basename>or<task-basename>. - AC-3:
sdlc gate skill-prose --paths apps/sdlc/skills/task-work/SKILL.mdexits 0, and exits non-zero when theScratch files:bullet is deleted from that file. - AC-4:
bun test apps/sdlcpasses, including the new_skill_prose_contract.test.tscase.
Out of scope
Section titled “Out of scope”apps/sdlc/skills/pr-respond/SKILL.mdand other lease-aware skills. Their scratch files are the heartbeat pair, which is already namespaced; promoting the rule intoapps/sdlc/conventions/for every skill waits for a second real caller.- Any change to where the session scratchpad lives, or to the harness that supplies it. This task changes filenames only.
- Cleanup or retention of scratch files after a run ends.
- The lease heartbeat log/PID naming, which already satisfies the rule.
Dependencies
Section titled “Dependencies”- none
Discovery context
Section titled “Discovery context”Spawned by /sdlc:spawn-task-pr on 2026-08-03 UTC from
T-5G81-lease-payload-gates in git@github.com:sksizer/dev.git.