Skip to content

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/)

LocationRole today
apps/sdlc/skills/task-work/preflight_permissions.ts#BLANKET_EDIT_MODESThe 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#resolveSpecToAbsoluteResolves 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#mainRenders 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.mdStep 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.tsBun 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.

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.

  1. In preflight_permissions.ts, add "auto" to BLANKET_EDIT_MODES and update the constant’s docstring plus the module-header prose (the “The same three files supply defaultMode” paragraph) to name all three modes.

  2. Add an exported helper singleSlashAbsoluteNearMiss(entries, tool, targetPath): string | null. For each entry in entries, parse it with the existing parseToolRule; when the spec starts with exactly one / (that is, spec.startsWith("/") && !spec.startsWith("//")), re-test it as a filesystem-absolute glob via globCovers(spec, targetPath). Return the first entry (verbatim rule text) whose absolute reading covers targetPath; return null when none does. Iterate entries in insertion order so the reported rule is deterministic.

  3. In main’s file-mutation loop, when perms.allowsTool(tool, worktreePath) is false, call the helper against perms.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.

  4. 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.

  5. Update apps/sdlc/skills/task-work/SKILL.md Step 3b: list auto among the blanket defaultMode values and document the near-miss suffix on the exit-1 stdout shape.

  6. Extend apps/sdlc/skills/task-work/tests/preflight_permissions.test.ts with unit coverage for auto as a blanket mode and end-to-end coverage of the three file-mutation outcomes (near-miss hit, plain absence, non-covering single-slash rule).

LocationKindChange
apps/sdlc/skills/task-work/preflight_permissions.tsmodifyAdd "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.tsmodifyAdd 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.mdmodifyStep 3b: name auto as a blanket defaultMode and document the near-miss suffix on the exit-1 file-mutation gap line.
  • AC-1: BLANKET_EDIT_MODES in apps/sdlc/skills/task-work/preflight_permissions.ts contains exactly acceptEdits, bypassPermissions, and auto.
  • AC-2: new ResolvedPermissions(new Set(), new Set(), "auto").allowsTool("Edit", p) returns true for any absolute path p, and the same holds for "Write".
  • AC-3: Given settings whose permissions.allow carries Edit(/<abs-worktree-path>/**) and Write(/<abs-worktree-path>/**) (single leading slash) and no defaultMode, the probe exits 1 and each of its two stdout lines contains the substring near-miss, the offending rule verbatim, and the //-doubled corrected form.
  • AC-4: Given settings with no Write/Edit rule at all and no defaultMode, the probe exits 1 and each file-mutation stdout line equals the existing <tool>: missing <tool>(<worktree-glob>) shape with no near-miss substring.
  • 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 no near-miss substring.
  • AC-6: bun test run against apps/sdlc/skills/task-work/tests/preflight_permissions.test.ts passes 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.md Step 3b names auto among the blanket defaultMode values and shows the near-miss suffix in its exit-1 stdout-shape description.
  • Reading the effective runtime permission mode when no settings file carries defaultMode at 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 the Write/Edit file-mutation probe only.
  • Near-miss detection on the deny side — 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.
  • none

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.


← Back to Tasks