diff --git a/docs/superpowers/plans/2026-10-25-enforce-upstream-loop.md b/docs/superpowers/plans/2026-10-25-enforce-upstream-loop.md index 16f3727..03301de 100644 --- a/docs/superpowers/plans/2026-10-25-enforce-upstream-loop.md +++ b/docs/superpowers/plans/2026-10-25-enforce-upstream-loop.md @@ -129,7 +129,7 @@ git commit -m "feat(dsh): /approve — единственный писатель - Consumes: Task 1 (gates.js), Task 2 (command-approve.js), существующая цепочка `ctx.tools.guard` (lib/guards.js). - Produces: в `apply()`: - `DEFAULTS += { approvalGates: true }`; gatesOk — из selfcheck (tools.guard). - - В guard-цепочке после hook-проверок: Edit/Write/MultiEdit → `checkPlanWrite` + `checkApprovalWrite`; `subagent`/`subagent_fork`/`workflow` → `checkDispatch` (prompt/script из `exec.arguments`); `Bash` → если в команде грубая подстрока `docs/superpowers/plans` или `approval.md` — `spawnSync python3 hooks/harness_target.py targets '' `, цели → `checkBashTargets`. Любой deny → причина отказа (hook-стиль `BLOCKED [approval-gates]: …`). Ошибка/пропуск парсинга — allow (инвариант хуков). + - В guard-цепочке после hook-проверок: Edit/Write/MultiEdit → `checkPlanWrite` + `checkApprovalWrite` + `checkSddWrite`; `subagent`/`subagent_fork`/`workflow` → `checkDispatch` (prompt/script из `exec.arguments`); `Bash` → если в команде грубая подстрока `docs/superpowers/plans`, `approval.md` или `.superpowers/sdd` — `spawnSync python3 hooks/harness_target.py targets '' `, цели → `checkBashTargets` + `checkSddWrite` для путей под `.superpowers/sdd/`. Любой deny → причина отказа (hook-стиль `BLOCKED [approval-gates]: …`). Ошибка/пропуск парсинга — allow (инвариант хуков). - `/approve` регистрируется в том же `ctx.inject(['commands', 'userQuestions'])` (userQuestions может отсутствовать — команда сама откажет, D-12). - `repoRoot` для гейтов — cwd сессии (`sessionCwd`), как в guards. @@ -141,6 +141,10 @@ test('apply: guard allows plan write after /approve-like approval.md', ...) test('apply: guard denies subagent dispatch referencing unapproved plan', ...) test('apply: guard allows dispatch after plan approval (sha match)', ...) test('apply: bash heredoc into approval.md denied', ...) // RF4 +test('apply: bash write under .superpowers/sdd// denied without approval', ...) // checkSddWrite bash-ветка +test('apply: bash write under .superpowers/sdd// allowed with approval', ...) +test('gates: checkSddWrite sha-mismatch deny', ...) // T1.7 pin +test('gates: bare .superpowers/sdd/ dir ungated', ...) // T1.7 pin test('apply: approvalGates:false disables all gates', ...) ```