T-ZVR9-path-scoped-commits-over-stash
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 was spawned unattended. Review the Goal, Approach, Today, Files-to-touch, and Acceptance-criteria carefully before trusting it.
/sdlc:task-work tells an implementing agent which files to stage for the
task-state commits, but nothing in its guidance covers how to split one run’s
working-tree changes into several commits. Agents fill that gap with
git stash push --keep-index, which is repo-global: one stash reaches across
every worktree of the repo and sweeps up files belonging to other concurrent
sessions, then has to be unwound by hand. The guidance should name path-scoped
git commit -F <msgfile> -- <paths> as the sanctioned commit-splitting shape so
the shared stash is never the reach-for tool.
Splitting a task-work run’s work into separate commits used
git stash push --keep-index, which is repo-global across worktrees: it pulled in unrelated files from other concurrent sessions’ worktrees and had to be unwound by hand. The task-work commit guidance should mandate path-scopedgit commit -F <msg> -- <paths>alongside its existing ‘never stage broadly’ rule, so commit splitting never reaches for the shared stash.
| Location | Role today |
|---|---|
apps/sdlc/conventions/commit-messages.md | The canonical commit convention every SDLC skill references. Covers how a message reaches git (sdlc commit create, the heredoc fallback, the Write-tool sandbox fallback) and says nothing about which paths a commit covers. |
apps/sdlc/skills/task-work/SKILL.md | Step 6 briefs the implementation sub-agent (worktree path, branch, ACs, quality checks) with no commit-scoping instruction; Step 8 stages one explicit path for the post-mortem commit. Nothing addresses splitting a run’s changes into several commits. |
apps/sdlc/lib/services/gate/ops/_skill_prose_contract.ts | The prose-invariant registry the skill-prose gate lints against. Its task-work entry pins lease heartbeat-loop under Step 6; the nearest stash-related pin is Never auto-stash on the target repo, scoped to /sdlc:spawn-task-pr. |
apps/sdlc/skills/spawn-task-pr/SKILL.md | Carries that spawn-scoped auto-stash prohibition, which is about the target repo’s dirty state — not about how an implementer splits their own commits. |
Proposed
Section titled “Proposed”apps/sdlc/conventions/commit-messages.md grows one section covering commit
scope alongside its existing coverage of commit message routing: scope a
commit to explicit pathspecs (git commit -F <msgfile> -- <paths>, or a narrow
git add <paths> followed by sdlc commit create), with a one-line rationale
that a stash is repo-global and re-applies across worktrees. /sdlc:task-work
Step 6’s sub-agent brief gains a one-line reference bullet pointing at that
convention — a reference, not a duplicated block, per the progressive-disclosure
rule in apps/sdlc/skills/CLAUDE.md. The skill-prose gate pins that reference
so a later edit cannot silently drop it.
Approach
Section titled “Approach”- Add a
## Scoping a commit to explicit pathssection toapps/sdlc/conventions/commit-messages.md, after the antipatterns section. State the sanctioned shapes —git commit -F <msgfile> -- <paths>and narrowgit add <paths>plussdlc commit create— and give the surgical rationale: the stash is a single repo-global stack shared by every worktree, so a round-trip in one worktree can capture and re-apply another session’s files. Phrase it as direction to follow, per the positive-framing rule inapps/sdlc/skills/CLAUDE.md. - Add one bullet to
/sdlc:task-workStep 6’s sub-agent brief inapps/sdlc/skills/task-work/SKILL.md: tell the sub-agent to scope each commit to explicit paths per the commit convention atapps/sdlc/conventions/commit-messages.md, cited in the plugin-root form the rest of that SKILL.md uses. Keep it to a single line — the convention doc holds the prose. - Add a matching
Notesbullet in the same SKILL.md if itsNotessection does not already referenceapps/sdlc/conventions/commit-messages.md, following the one-line reference shape documented inapps/sdlc/skills/CLAUDE.md. - Pin the new guidance in
apps/sdlc/lib/services/gate/ops/_skill_prose_contract.ts: add arequiresentry under thetask-worksection named6. Delegate implementation to a sub-agent, with a stableid, apatternmatching literal text from the new bullet, and anoteciting this task and the cross-worktree stash incident. - Run
bun apps/sdlc/cli/sdlc.ts gate skill-proseand confirm it passes with the new pin in place; then confirm it fails when the Step 6 bullet is temporarily removed, so the pin is proven load-bearing rather than inert. - Run the repo’s quality verbs —
bunx tsc --noEmitandbun test apps/sdlc— and fix any fallout from the registry edit.
Files to touch
Section titled “Files to touch”| Location | Kind | Change |
|---|---|---|
apps/sdlc/conventions/commit-messages.md | modify | New section on scoping a commit to explicit pathspecs, with the repo-global-stash rationale. |
apps/sdlc/skills/task-work/SKILL.md | modify | One-line commit-scoping bullet in Step 6’s sub-agent brief, plus a Notes reference to the convention doc. |
apps/sdlc/lib/services/gate/ops/_skill_prose_contract.ts | modify | New requires pin under the task-work Step 6 section for the commit-scoping reference. |
Acceptance criteria
Section titled “Acceptance criteria”- AC-1:
apps/sdlc/conventions/commit-messages.mdcontains a section on commit scope that shows thegit commit -Fpathspec shape and states that the stash is shared across the repo’s worktrees. - AC-2:
apps/sdlc/skills/task-work/SKILL.mdStep 6’s sub-agent brief contains a bullet instructing the sub-agent to scope commits to explicit paths, and that bullet referencesapps/sdlc/conventions/commit-messages.mdrather than restating the convention. - AC-3:
apps/sdlc/lib/services/gate/ops/_skill_prose_contract.tscontains arequiresentry under thetask-worksection named6. Delegate implementation to a sub-agentwhosepatternmatches text present in the Step 6 bullet added by AC-2. - AC-4:
bun apps/sdlc/cli/sdlc.ts gate skill-proseexits 0 on the branch, and exits non-zero when the AC-2 bullet is deleted from the SKILL.md. - AC-5:
bunx tsc --noEmitandbun test apps/sdlcboth exit 0 on the branch.
Out of scope
Section titled “Out of scope”- Retiring the remaining
--autostashcall sites (orchestrate/SKILL.md,append_pr_url.ts) — tracked separately as B-19O7 and B-P502. - Adding a pathspec flag to the
sdlc commit createop; this task changes guidance, not the commit op’s surface. - Any machine enforcement that inspects a commit’s diff for cross-worktree contamination.
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.