T-DTAQ-preflight-probe-auto-mode-and-abs-globs
Status: closed/superseded · Impact: medium · Complexity: small
AUTO-DEFINED: this spec was best-effort machine-authored by /sdlc:task-auto-define on 2026-07-19 because the task is autonomy: autonomous/pr. Review the Goal, Approach, Today, Files-to-touch, and Acceptance-criteria carefully before trusting it.
apps/sdlc/skills/task-work/preflight_permissions.ts misreports permission
grants in two ways, both hit during [T-1YSW-amend-d0001-solutions-tier](/planning/tasks/amend-d0001-solutions-tier/) in
the sksizer/dev repo. It treats a defaultMode: auto operator as having a
hard permission gap that does not exist, and it reports a single-slash
absolute-path permission glob as a plain absence rather than as the near-miss
it is. Both make the probe’s output actively misleading to an operator who
has, in fact, granted the permission.
apps/sdlc/skills/task-work/preflight_permissions.ts misreports permission grants in two ways, both hit during T-1YSW. (1) It recognizes only ‘acceptEdits’ and ‘bypassPermissions’ as blanket defaultMode values, so an operator running defaultMode: auto sees a hard permission gap that is not real — add ‘auto’ to the recognized blanket modes. (2) An absolute-path permission glob silently matches nothing unless the leading slash is doubled (Write(//abs/path/**)); the probe reports the grant as simply missing. It should detect a single-slash absolute glob covering the worktree path and say so explicitly, rather than reporting a plain absence. Related to but distinct from T-0AM0-preflight-probe-honors-runtime-edit-grant, which covers reading the effective runtime grant when no settings file carries defaultMode at all. Touchpoint: apps/sdlc/skills/task-work/preflight_permissions.ts.
—
[T-1YSW-amend-d0001-solutions-tier](/planning/tasks/amend-d0001-solutions-tier/)
| Location | Role today |
|---|---|
apps/sdlc/skills/task-work/preflight_permissions.ts#BLANKET_EDIT_MODES | The set of defaultMode values treated as a blanket Write/Edit allow. Holds exactly acceptEdits and bypassPermissions; auto is absent, so an operator running defaultMode: auto gets a hard file-mutation gap the runtime does not actually impose. |
apps/sdlc/skills/task-work/preflight_permissions.ts#resolveSpecToAbsolute | Resolves a tool-rule path spec to an absolute glob. //abs/** is filesystem-absolute; a leading single slash (/abs/**) falls through to the repo-relative branch and is re-anchored under the repo root, so a genuine absolute path silently expands to a non-existent <repo-root>/Users/... and matches nothing. |
apps/sdlc/skills/task-work/preflight_permissions.ts#main | Renders the file-mutation gap lines. When allowsTool is false it always emits the same plain-absence shape <tool>: missing <tool>(<worktree-glob>), with no way for the operator to tell “no rule at all” from “a rule that would have matched but for the leading-slash form”. |
apps/sdlc/skills/task-work/SKILL.md | Step 3b documents the probe’s exit-1 stdout shapes and states that acceptEdits/bypassPermissions are the blanket modes. |
apps/sdlc/skills/task-work/tests/preflight_permissions.test.ts | Bun test suite for the probe. Already covers defaultMode: acceptEdits/bypassPermissions as blanket allows and //-prefixed absolute globs; no coverage for auto or for the single-slash near-miss. |
Proposed
Section titled “Proposed”The probe recognizes auto alongside acceptEdits and bypassPermissions as
a blanket file-mutation mode, and — when a Write/Edit grant is genuinely
absent — checks the operator’s allow rules for a single-slash absolute glob
that WOULD cover the worktree path if it were read as filesystem-absolute. Such
a rule still yields a gap (the grant really does not apply), but the gap line
names the offending rule and shows the //-doubled correction instead of
reporting a plain absence.
Approach
Section titled “Approach”-
In
preflight_permissions.ts, add"auto"toBLANKET_EDIT_MODESand update the constant’s docstring plus the module-header prose (the “The same three files supplydefaultMode” paragraph) to name all three modes. -
Add an exported helper
singleSlashAbsoluteNearMiss(entries, tool, targetPath): string | null. For each entry inentries, parse it with the existingparseToolRule; when the spec starts with exactly one/(that is,spec.startsWith("/") && !spec.startsWith("//")), re-test it as a filesystem-absolute glob viaglobCovers(spec, targetPath). Return the first entry (verbatim rule text) whose absolute reading coverstargetPath; returnnullwhen none does. Iterateentriesin insertion order so the reported rule is deterministic. -
In
main’s file-mutation loop, whenperms.allowsTool(tool, worktreePath)is false, call the helper againstperms.allow. On a hit, push the gap line in the near-miss shape; otherwise push the existing plain-absence shape unchanged:<tool>: missing <tool>(<worktree-glob>) — near-miss: <rule> is a single-slash absolute glob, which Claude Code reads as repo-relative; double the leading slash: <tool>(/<spec>)Keeping the existing
<tool>: missing <tool>(<worktree-glob>)prefix intact means every current consumer and test that matches on the prefix keeps working; the near-miss detail is a suffix. -
Leave the exit code at 1 for the near-miss case — the grant genuinely does not apply as written, so the probe must still gate; only the message improves.
-
Update
apps/sdlc/skills/task-work/SKILL.mdStep 3b: listautoamong the blanketdefaultModevalues and document the near-miss suffix on the exit-1 stdout shape. -
Extend
apps/sdlc/skills/task-work/tests/preflight_permissions.test.tswith unit coverage forautoas a blanket mode and end-to-end coverage of the three file-mutation outcomes (near-miss hit, plain absence, non-covering single-slash rule).
Files to touch
Section titled “Files to touch”| Location | Kind | Change |
|---|---|---|
apps/sdlc/skills/task-work/preflight_permissions.ts | modify | Add "auto" to BLANKET_EDIT_MODES; add exported singleSlashAbsoluteNearMiss; emit the near-miss suffix from main’s file-mutation loop; refresh the module-header and constant docstrings. |
apps/sdlc/skills/task-work/tests/preflight_permissions.test.ts | modify | Add tests for defaultMode: auto as a blanket allow and for near-miss / plain-absence / non-covering single-slash gap lines. |
apps/sdlc/skills/task-work/SKILL.md | modify | Step 3b: name auto as a blanket defaultMode and document the near-miss suffix on the exit-1 file-mutation gap line. |
Acceptance criteria
Section titled “Acceptance criteria”- AC-1:
BLANKET_EDIT_MODESinapps/sdlc/skills/task-work/preflight_permissions.tscontains exactlyacceptEdits,bypassPermissions, andauto. - AC-2:
new ResolvedPermissions(new Set(), new Set(), "auto").allowsTool("Edit", p)returnstruefor any absolute pathp, and the same holds for"Write". - AC-3: Given settings whose
permissions.allowcarriesEdit(/<abs-worktree-path>/**)andWrite(/<abs-worktree-path>/**)(single leading slash) and nodefaultMode, the probe exits 1 and each of its two stdout lines contains the substringnear-miss, the offending rule verbatim, and the//-doubled corrected form. - AC-4: Given settings with no
Write/Editrule at all and nodefaultMode, the probe exits 1 and each file-mutation stdout line equals the existing<tool>: missing <tool>(<worktree-glob>)shape with nonear-misssubstring. - AC-5: Given a single-slash rule that does not cover the worktree path
(e.g.
Edit(/Users/someone-else/**)), the probe emits the plain-absence line with nonear-misssubstring. - AC-6:
bun testrun againstapps/sdlc/skills/task-work/tests/preflight_permissions.test.tspasses with the new cases, and every pre-existing test in that file still passes unmodified in its assertions on the<tool>: missing <tool>(...)prefix. - AC-7:
apps/sdlc/skills/task-work/SKILL.mdStep 3b namesautoamong the blanketdefaultModevalues and shows the near-miss suffix in its exit-1 stdout-shape description.
Out of scope
Section titled “Out of scope”- Reading the effective runtime permission mode when no settings file carries
defaultModeat all, or the empirical touch-test fallback — that is[T-0AM0-preflight-probe-honors-runtime-edit-grant](/planning/tasks/preflight-probe-honors-runtime-edit-grant/). - Near-miss detection for
Bash(<verb>:*)rules; this task covers theWrite/Editfile-mutation probe only. - Near-miss detection on the
denyside — a single-slash absolute deny rule that fails to match is a permissive miss, not a false-positive gap. - Extending the probe to skill-internal scripts
(
[T-NUML-task-work-preflight-permissions-probe-extension-for-skill-internal-scripts](/planning/tasks/task-work-preflight-permissions-probe-extension-for-skill-internal-scripts/)). - Auto-rewriting the operator’s settings files; the probe reports, the operator edits.
Dependencies
Section titled “Dependencies”- none
Discovery context
Section titled “Discovery context”Spawned by /sdlc:spawn-task-pr on 2026-07-20 UTC from
[T-1YSW-amend-d0001-solutions-tier](/planning/tasks/amend-d0001-solutions-tier/) in https://github.com/sksizer/dev.