enhance(#4221): replace installer Read() deny rules with a managed secret-read guard hook (#4236)

* feat(#4221): gsd-secret-read-guard PreToolUse hook + registration

Add hooks/gsd-secret-read-guard.js, a blocking PreToolUse guard on
Read|Grep|Bash that denies reads of .env, .env.<suffix> and .secrets
(the .env.example/.sample/.template/.dist templates stay readable).
Read checks file_path; Grep checks an explicit path and judges the glob
per brace alternative; Bash runs a two-pass token scan (quotes, comments,
redirects with fd digits, separators, $( )/backtick/<( ) recursion,
heredoc bodies never scanned as commands, nested bash -c/eval rescans,
git <ref>:<path> shapes) with a closed non-reading exemption set for
existence checks. Fail-open crash policy; 1 MiB commands are denied as
command-too-large; more than 64 glob alternatives as glob-too-complex.

Why: Claude Code 2.1.259 makes every `cd DIR && grep …` compound prompt
for approval whenever any Read() deny rule exists, even in auto mode. A
hook denial is not a permission rule and never arms that check. The
installer-written deny rules are retired in the follow-up commit.

Registration: hooks.json (Read|Grep|Bash, timeout 5), build-hooks
HOOKS_TO_COPY, managed-hooks-registry, runtime-hooks-surface (blocking
guard with BLOCKING_GUARD_TIMEOUT_S; Kimi ReadFile|Grep|Shell),
shell-command-projection managed sets, installer-migration-report,
OpenCode/Kilo plugin (grep tool mapping, include -> glob, dispatch),
docs tables in five locales, ADR-766 always-on list, regen:derived
fixtures, and a new table-driven unit suite.

* test(#4221): pin the secret-read guard in existing hook gates

Register gsd-secret-read-guard.js in every existing hook gate: the
hooks-crash-policy table (deny row; 6 -> 7 deny cases), plugin-manifest
REQUIRED_HOOKS and its Read|Grep|Bash group, docs-hooks-table-parity
EXPECTED_SURFACE_HOOKS, install.test MANAGED_JS_HOOKS, install-minimal-
hooks JS_HOOKS/BLOCKING_GUARDS, portable-node-runner GUARD_HOOKS,
kilo-upgrades PLUGIN_GUARD_HOOKS, the Kimi normalization-parity and
typed-payload floors, the OpenCode adapter (grep mapping, include ->
glob, three dispatch tests) and a Kimi TOML matcher assertion.

* fix(#4221): retire installer Read() deny rules (legacy filter)

Rename GSD_CLAUDE_DENY_PERMISSIONS to GSD_CLAUDE_LEGACY_DENY_PERMISSIONS
and stop adding the three Read(.env) / Read(.env.*) / Read(.secrets)
strings. mergeClaudePermissions now only filters them out of an existing
permissions.deny: an absent deny key stays absent, a malformed one is
still repaired to [], and an array emptied by the filter is deleted so
no `"deny": []` residue is left. Uninstall filters the same legacy list
and, symmetric with the Antigravity branch, drops an emptied allow or
deny key and an emptied permissions object.

Unlike the #2278 allow-side migration there is no surviving current
deny list, so the constant is renamed rather than mirrored. Removal is
byte-exact: a hand-written identical rule is indistinguishable from the
installer's and is removed too (the manifest never recorded permission
strings). USER-GUIDE and CONTEXT.md updated.

* test(#4221): flip install-regressions deny-rule assertions to the retired shape

The fresh-merge, non-destructive merge, idempotency, end-to-end install,
reinstall and uninstall assertions now expect no Read(.env*) deny rules
and no permissions.deny key on a fresh install; the deny:null repair case
is kept. A new describe block covers the legacy filter: retired strings
removed with a user entry kept, partial sets, near-miss strings
untouched, idempotency, GSD-only deny array deleted, a pre-existing
empty deny preserved, and uninstall symmetry for allow/deny/permissions.

* chore(#4221): add changeset fragment for PR #4236

* fix(#4221): case-fold names; scan shell stdin and xargs pipes

Review round 1 (trek-e):

- Blocker: secret-name matching is now case-insensitive in the Read,
  Grep (path and glob) and Bash paths, so `.ENV` / `.Secrets` on a
  case-insensitive filesystem are recognized as the same secret file.
- Major: a shell interpreter's script is now scanned wherever it comes
  from. The tokenizer keeps heredoc bodies as per-segment tokens and
  records separator operators; pass 2 groups by segment id and resolves
  bash/sh/zsh/dash/ksh/su invocation mode: `-c` (including combined
  `-lc`) scans the script operand, a file operand is checked as a file
  (a `<( )` operand's echo/printf output is reconstructed), otherwise
  stdin is the script and heredocs, here-strings and a piped echo/printf
  source are scanned. `eval` joins all its operands; `source`/`.` handle
  process substitution. Data heredocs (`cat <<EOF`, the commit-message
  shape) stay unscanned.
- Major: `… | xargs <cmd>` checks the upstream segment's operands as
  file names when the sub-command reads (`echo .env | xargs cat`,
  `find . -name .env | xargs cat`); `-a`/`--arg-file` suppresses the
  inference; a shell sub-command's `-c` script is scanned.

Header, USER-GUIDE bullet and changeset updated; documented gaps now
include piped scripts from non-echo sources and `exec`/`timeout`
wrappers. 60 new suite cases pin the block and allow shapes.

---------

Co-authored-by: Tom Boucher <trekkie@nomorestars.com>
This commit is contained in:
Cody Anderson
2026-09-05 02:00:08 -06:00
committed by GitHub
parent d0d542e478
commit 77e2472ca0
50 changed files with 1862 additions and 71 deletions

View File

@@ -294,6 +294,7 @@ Runtime hooks that integrate with the host AI agent:
| `gsd-prompt-guard.js` | `PreToolUse` | Scans `.planning/` writes for prompt injection patterns (advisory) |
| `gsd-read-injection-scanner.js` | `PostToolUse` | Scans Read tool output for injected instructions in untrusted content |
| `gsd-workflow-guard.js` | `PreToolUse` | Detects file edits outside GSD workflow context (advisory, opt-in via `hooks.workflow_guard`) |
| `gsd-secret-read-guard.js` | `PreToolUse` | Hard-blocks Read / Grep / Bash reads of `.env`, `.env.<suffix>` (templates such as `.env.example` exempt) and `.secrets`; replaces the installer-written `Read(.env*)` permission deny rules, which made every `cd DIR && grep …` compound prompt for approval on Claude Code ≥ 2.1.259 (#4221) |
| `gsd-read-guard.js` | `PreToolUse` | Advisory guard preventing Edit/Write on files not yet read in the session |
| `gsd-session-state.sh` | `SessionStart` | Session state tracking for shell-based runtimes |
| `gsd-validate-commit.sh` | `PreToolUse` | Commit validation for conventional commit enforcement |

View File

@@ -577,6 +577,7 @@
"gsd-prompt-guard.js",
"gsd-read-guard.js",
"gsd-read-injection-scanner.js",
"gsd-secret-read-guard.js",
"gsd-session-state.sh",
"gsd-statusline.js",
"gsd-update-banner.js",

View File

@@ -722,6 +722,7 @@ Full listing: `hooks/`.
| `gsd-worktree-path-guard.js` | `PreToolUse` | Hard-blocks Edit/Write/MultiEdit with absolute paths outside the worktree root (PR #579, #260) |
| `gsd-agent-isolation-guard.js` | `PreToolUse` | Hard-blocks an executor `Agent()` dispatch missing its harness isolation parameter when the project's resolved dispatch isolation is `harness-worktree` (#3045) |
| `gsd-write-guard.js` | `PreToolUse` | Hard-blocks a whole-file `Write` that catastrophically shrinks a curated `.planning/` artifact (ROADMAP.md, milestone roadmaps, STATE.md); override via the single-use sentinel `.planning/.gsd-allow-shrink` (workflow steps) or `GSD_ALLOW_PLANNING_SHRINK=1` (interactive) (#2255, fix 3 of #973) |
| `gsd-secret-read-guard.js` | `PreToolUse` | Hard-blocks Read / Grep / Bash reads of `.env`, `.env.<suffix>` (templates such as `.env.example` exempt) and `.secrets`; replaces the installer-written `Read(.env*)` permission deny rules, which made every `cd DIR && grep …` compound prompt for approval on Claude Code ≥ 2.1.259 (#4221) |
| `gsd-config-reload.js` | `FileChanged` | Hot-reloads GSD config context when `.planning/config.json` changes mid-session (#770) |
| `gsd-ensure-canonical-path.js` | `SessionStart` | Symlinks `~/.claude/gsd-core/{bin,contexts,references,templates,workflows}` to the plugin's bundled tree so `@~/.claude/gsd-core/...` includes resolve in marketplace plugin installs; no-op in classic installs, self-heals after `claude plugin update` (#997) |
| `gsd-session-state.sh` | `SessionStart` | Session-state tracking for shell-based runtimes |

View File

@@ -459,6 +459,7 @@ GSD generates markdown files that become LLM system prompts. This means any user
- `gsd-prompt-guard.js` — Scans Write/Edit calls to `.planning/` for injection patterns (always active, advisory-only)
- `gsd-workflow-guard.js` — Warns on file edits outside GSD workflow context (opt-in via `hooks.workflow_guard`)
- `gsd-write-guard.js` — Hard-blocks a whole-file `Write` that catastrophically shrinks a curated `.planning/` artifact (`ROADMAP.md`, milestone roadmaps, `STATE.md`) below 40% of its on-disk line count; files under 40 lines are exempt. The check is stateless per Write, comparing each payload against the file's *current* on-disk size — a single-shot collapse (the #973 shape) is blocked, but a sequence of individually-tolerated shrinks that erodes the file across several Writes is not detected. For a legitimate milestone reset or large deletion, bypass once with the single-use sentinel — write the target's path into `.planning/.gsd-allow-shrink` (fresh within 15 minutes; consumed by the allowed write) — or, interactively, with `GSD_ALLOW_PLANNING_SHRINK=1` in the runtime's environment. Scope the guarantee accordingly: this stops accidental and single-shot collapse, and is not a defense against a determined agent — the sentinel is a plain file, so anything with shell access can arm one; what it buys is that the bypass becomes a deliberate, path-bound, single-use and auditable action rather than a sentence to reason past (always active, blocking; #2255, fix 3 of #973)
- `gsd-secret-read-guard.js` — Hard-blocks reads of secret files — `.env`, `.env.<suffix>` and `.secrets`, matched case-insensitively (`.ENV`, `.Secrets`) — through Read (`file_path`), Grep (an explicit `path`, or a `glob` that selects them, judged per brace alternative) and Bash (operands, input redirects, `$( )` / backtick / `<( )` bodies, and `git show <ref>:<path>` shapes). A shell interpreter (`bash`/`sh`/`zsh`/`dash`/`ksh`) has its script scanned however it arrives — `-c '…'`, a `<( )` file operand, a heredoc / here-string, or a pipe from a knowable `echo`/`printf` source (`echo cat .env | bash`) — as do `eval`'s joined operands, a `source`/`.` process-substitution operand, and `find … | xargs cat` pipelines (upstream literal names become the sub-command's read operands). `.env.example` / `.env.sample` / `.env.template` / `.env.dist` stay readable (they are the templates GSD's own phase prompt reads — a real secret stored under one of those names is not protected), and existence checks (`[ -f .env ]`, `ls .env*`, `test`, `stat`, `rm`, `touch`, `echo`, …) pass. Not covered, by construction: `$VAR` indirection (`bash -c "$CMD"`), shell globs (`cat .e*`), interpreter one-liners, a piped script from a non-`echo`/`printf` source (`cat gen.sh | bash`, `curl … | sh`), reads inside scripts the agent runs, and a Grep `glob: '*'` reaching a `.env` that is not gitignored — none are statically resolvable by a hook. This replaces the `Read(.env)` / `Read(.env.*)` / `Read(.secrets)` permission deny rules the installer used to write: on Claude Code ≥ 2.1.259 any `Read()` deny rule makes every `cd DIR && grep …` compound prompt for approval even in `auto` mode, while a hook denial is not a permission rule and applies in `auto` and `bypassPermissions` alike (always active, blocking; #4221)
**CI Scanner:** `prompt-injection-scan.security.test.cjs` scans all agent, workflow, and command files for embedded injection vectors.
@@ -969,11 +970,6 @@ Since v1.3.1, the installer pre-populates `~/.claude/settings.json` (or
"Edit(.planning/*)",
"Read(STATE.md)",
"Edit(STATE.md)"
],
"deny": [
"Read(.env)",
"Read(.env.*)",
"Read(.secrets)"
]
}
}
@@ -984,6 +980,21 @@ merge is non-destructive — your existing permissions are preserved and GSD ent
are only appended. Uninstalling GSD removes exactly these entries and preserves
any others.
**Secret-file protection moved from deny rules to a hook (#4221).** Earlier
versions also wrote three `permissions.deny` rules — `Read(.env)`,
`Read(.env.*)` and `Read(.secrets)`. Claude Code 2.1.259 hardened the
Bash-side enforcement of `Read()` deny rules so that *any* such rule makes every
`cd DIR && grep …` / `cd DIR && cat …` compound prompt for approval, even in
`auto` mode — and GSD's subagents emit hundreds of those per session. The same
protection now ships as the always-on `gsd-secret-read-guard.js` PreToolUse hook
(Read, Grep and Bash; see Runtime Hooks above for what it covers and its
documented gaps). A hook denial is not a permission rule, so it never arms that
check, and it applies in `auto` and `bypassPermissions` modes alike. On install
and uninstall the three retired strings are removed from `permissions.deny`
(and an emptied `deny` array is dropped). Note the removal is byte-exact: a
rule you wrote by hand that is identical to one of the three is indistinguishable
from the installer's and is removed as well — re-add it if you want both layers.
### Executor Subagent Gets "Permission denied" on Bash Commands
Add the required patterns to `~/.claude/settings.json`. Core patterns needed for all stacks:

View File

@@ -30,7 +30,7 @@ The mapping is **defined, not incidental**:
| Agent surface (`agents/*.md`) | *(omitted — default `agents/` discovery)* | the explicit `agents: <string>` form is rejected by the plugin schema; relying on Claude Code's default `agents/` discovery loads them and stays self-maintaining. Agents are already plugin-safe — their `hooks`/`permissionMode` frontmatter is inert. |
| Always-on hook policy (subset of the Installer Module's `settings.json` wiring) | `hooks: "./hooks/hooks.json"` | see below. |
The hook projection is the load-bearing part of this Module, because of the external constraint: a plugin's agents cannot carry hook frontmatter, so **all plugin-path hook wiring must live in `hooks/hooks.json`**. The Module projects *only the always-on subset* of the Installer Module's Claude hook wiring — `gsd-check-update` (SessionStart), `gsd-context-monitor` (PostToolUse), and the security guards `gsd-prompt-guard` / `gsd-read-guard` / `gsd-worktree-path-guard` / `gsd-read-injection-scanner` / `gsd-write-guard` (PreToolUse, #2255) — preserving each event, matcher, and timeout. The installer's **config-gated opt-in** hooks (workflow-guard, validate-commit, graphify-update, session-state, phase-boundary, update-banner) are deliberately excluded: a static manifest cannot read a project's `.planning/config.json` to honor those gates, so projecting them would run them unconditionally — a behavior change the Module must not introduce. Hook commands reference bundled scripts through Claude Code's `${CLAUDE_PLUGIN_ROOT}` variable.
The hook projection is the load-bearing part of this Module, because of the external constraint: a plugin's agents cannot carry hook frontmatter, so **all plugin-path hook wiring must live in `hooks/hooks.json`**. The Module projects *only the always-on subset* of the Installer Module's Claude hook wiring — `gsd-check-update` (SessionStart), `gsd-context-monitor` (PostToolUse), and the security guards `gsd-prompt-guard` / `gsd-read-guard` / `gsd-worktree-path-guard` / `gsd-read-injection-scanner` / `gsd-write-guard` (PreToolUse, #2255) / `gsd-secret-read-guard` (PreToolUse `Read|Grep|Bash`, #4221) — preserving each event, matcher, and timeout. The installer's **config-gated opt-in** hooks (workflow-guard, validate-commit, graphify-update, session-state, phase-boundary, update-banner) are deliberately excluded: a static manifest cannot read a project's `.planning/config.json` to honor those gates, so projecting them would run them unconditionally — a behavior change the Module must not introduce. Hook commands reference bundled scripts through Claude Code's `${CLAUDE_PLUGIN_ROOT}` variable.
The interface of this Module is therefore a **conformance contract**, validated two ways: `claude plugin validate --strict` (the external tool's view) and an in-repo drift-guard test (`tests/plugin-manifest.test.cjs`) that locks the identity mapping, the version sync, the always-on hook contract, and the absence of opt-in hooks. Manifest component paths are resolved relative to the **plugin root** (the directory containing `.claude-plugin/`), which is the repository root.

View File

@@ -52,7 +52,7 @@ GSD registers the following Claude Code hook events automatically on install:
|---|---|---|
| `SessionStart` | `gsd-check-update.js`, `gsd-session-state.sh` | Update check, session orientation |
| `PostToolUse` | `gsd-context-monitor.js`, `gsd-read-injection-scanner.js`, `gsd-phase-boundary.sh`, `gsd-graphify-update.sh` | Context monitoring, read-time scan, phase boundary detection |
| `PreToolUse` | `gsd-prompt-guard.js`, `gsd-read-guard.js`, `gsd-workflow-guard.js`, `gsd-worktree-path-guard.js`, `gsd-agent-isolation-guard.js`, `gsd-validate-commit.sh` | Prompt guard, read-before-edit, workflow + worktree safety, agent-dispatch isolation, commit validation |
| `PreToolUse` | `gsd-prompt-guard.js`, `gsd-read-guard.js`, `gsd-workflow-guard.js`, `gsd-worktree-path-guard.js`, `gsd-agent-isolation-guard.js`, `gsd-secret-read-guard.js`, `gsd-validate-commit.sh` | Prompt guard, read-before-edit, workflow + worktree safety, agent-dispatch isolation, secret-file read protection, commit validation |
| `SubagentStop` | `gsd-context-monitor.js` | Context headroom tracking after subagent completion |
| `Stop` | `gsd-context-monitor.js` | Context headroom tracking before model stop |
| `PreCompact` | `gsd-context-monitor.js` | Context awareness before conversation compaction |
@@ -252,7 +252,7 @@ GSD wires its lifecycle hooks into Kimi's native `[[hooks]]` array in `config.to
| Event | Hook | Purpose |
|---|---|---|
| `SessionStart` | `gsd-check-update.js`, `gsd-session-state.sh` | Update check and session-state bootstrap at session open |
| `PreToolUse` | `gsd-prompt-guard.js`, `gsd-read-guard.js`, `gsd-worktree-path-guard.js`, `gsd-workflow-guard.js`, `gsd-validate-commit.sh` | Prompt-injection guard, read-before-edit guidance, worktree path safety, workflow guard, and commit validation before tool calls |
| `PreToolUse` | `gsd-prompt-guard.js`, `gsd-read-guard.js`, `gsd-worktree-path-guard.js`, `gsd-workflow-guard.js`, `gsd-secret-read-guard.js`, `gsd-validate-commit.sh` | Prompt-injection guard, read-before-edit guidance, worktree path safety, workflow guard, secret-file read protection, and commit validation before tool calls |
| `PostToolUse` | `gsd-context-monitor.js`, `gsd-phase-boundary.sh`, `gsd-read-injection-scanner.js`, `gsd-graphify-update.sh` | Context window tracking, phase-boundary detection, read-time injection scanning, and graph updates after tool calls |
| `Stop` | `gsd-context-monitor.js` | Context headroom tracking before the model stops |
| `PreCompact` | `gsd-context-monitor.js` | Context headroom tracking before compaction |
@@ -376,7 +376,7 @@ GSD registers the following events automatically on install (Claude hook event d
| Event | Hook | Purpose |
|---|---|---|
| `SessionStart` | `gsd-check-update.js`, `gsd-session-state.sh` | Update check, session orientation |
| `PreToolUse` | `gsd-prompt-guard.js`, `gsd-read-guard.js`, `gsd-workflow-guard.js`, `gsd-worktree-path-guard.js`, `gsd-agent-isolation-guard.js`, `gsd-validate-commit.sh` | Prompt guard, read-before-edit, workflow + worktree safety, agent-dispatch isolation, commit validation |
| `PreToolUse` | `gsd-prompt-guard.js`, `gsd-read-guard.js`, `gsd-workflow-guard.js`, `gsd-worktree-path-guard.js`, `gsd-agent-isolation-guard.js`, `gsd-secret-read-guard.js`, `gsd-validate-commit.sh` | Prompt guard, read-before-edit, workflow + worktree safety, agent-dispatch isolation, secret-file read protection, commit validation |
| `PostToolUse` | `gsd-context-monitor.js`, `gsd-read-injection-scanner.js`, `gsd-phase-boundary.sh`, `gsd-graphify-update.sh` | Context monitoring, read-time scan, phase boundary detection |
| `SubagentStop` | `gsd-context-monitor.js` | Context headroom tracking after subagent completion |
| `SubagentStart` | `gsd-context-monitor.js` | Context headroom tracking at subagent start |
@@ -415,7 +415,7 @@ Qwen Code supports 15 hook events. GSD registers the following events automatica
|---|---|---|
| `SessionStart` | `gsd-check-update.js`, `gsd-session-state.sh` | Update check, session orientation |
| `PostToolUse` | `gsd-context-monitor.js`, `gsd-read-injection-scanner.js`, `gsd-phase-boundary.sh`, `gsd-graphify-update.sh` | Context monitoring, read-time scan, phase boundary detection |
| `PreToolUse` | `gsd-prompt-guard.js`, `gsd-read-guard.js`, `gsd-workflow-guard.js`, `gsd-worktree-path-guard.js`, `gsd-agent-isolation-guard.js`, `gsd-validate-commit.sh` | Prompt guard, read-before-edit, workflow + worktree safety, agent-dispatch isolation, commit validation |
| `PreToolUse` | `gsd-prompt-guard.js`, `gsd-read-guard.js`, `gsd-workflow-guard.js`, `gsd-worktree-path-guard.js`, `gsd-agent-isolation-guard.js`, `gsd-secret-read-guard.js`, `gsd-validate-commit.sh` | Prompt guard, read-before-edit, workflow + worktree safety, agent-dispatch isolation, secret-file read protection, commit validation |
| `SubagentStop` | `gsd-context-monitor.js` | Context headroom tracking after subagent completion |
| `SubagentStart` | `gsd-context-monitor.js` | Context headroom tracking at subagent start |
| `Stop` | `gsd-context-monitor.js` | Context headroom tracking before model stop |

View File

@@ -217,6 +217,7 @@ eager なスキルリストはターンごとの 2 つの主要コストの一
| `gsd-check-update.js` | `SessionStart` | GSDの新バージョンをバックグラウンドで確認 |
| `gsd-prompt-guard.js` | `PreToolUse` | `.planning/` への書き込みにプロンプトインジェクションパターンがないかスキャン(アドバイザリー) |
| `gsd-workflow-guard.js` | `PreToolUse` | GSDワークフローコンテキスト外でのファイル編集を検出(アドバイザリー、`hooks.workflow_guard` によるオプトイン) |
| `gsd-secret-read-guard.js` | `PreToolUse` | Read / Grep / Bash による `.env`、`.env.<suffix>`(`.env.example` などのテンプレートは除外)、`.secrets` の読み取りをハードブロック。インストーラが書き込んでいた `Read(.env*)` の deny ルールを置き換える(#4221) |
### コマンドルーティングハブ(`gsd-core/bin/lib/command-routing-hub.cjs`)

View File

@@ -476,6 +476,7 @@
| `gsd-worktree-path-guard.js` | `PreToolUse` | ワークツリールート外の絶対パスを持つ Edit/Write/MultiEdit をハードブロック(PR #579、#260) |
| `gsd-agent-isolation-guard.js` | `PreToolUse` | プロジェクトの解決済みディスパッチ分離が `harness-worktree` の場合、ハーネス分離パラメータを欠く executor の `Agent()` ディスパッチをハードブロック(#3045) |
| `gsd-write-guard.js` | `PreToolUse` | キュレーションされた `.planning/` アーティファクト(ROADMAP.md、マイルストーンロードマップ、STATE.md)を大幅に縮小するファイル全体の `Write` をハードブロック。使い捨てセンチネル `.planning/.gsd-allow-shrink`(ワークフローステップ)または `GSD_ALLOW_PLANNING_SHRINK=1`(対話時)でオーバーライド(#2255、#973 の修正 3) |
| `gsd-secret-read-guard.js` | `PreToolUse` | Read / Grep / Bash による `.env`、`.env.<suffix>`(`.env.example` などのテンプレートは除外)、`.secrets` の読み取りをハードブロック。インストーラが書き込んでいた `Read(.env*)` の deny ルールを置き換える(#4221) |
| `gsd-session-state.sh` | `SessionStart` | シェルベースランタイム向けのセッション状態追跡 |
| `gsd-validate-commit.sh` | `PreToolUse` | Conventional Commit 適用のためのコミットバリデーション |
| `gsd-phase-boundary.sh` | `PostToolUse` | ワークフロー遷移のためのフェーズ境界検出 |

View File

@@ -246,6 +246,7 @@ GSD 워크플로우에 thinking 클래스 모델(o3, o4-mini, Gemini 2.5 Pro)을
| `gsd-prompt-guard.js` | `PreToolUse` | `.planning/` 쓰기에서 프롬프트 인젝션 패턴 스캔 (자문적) |
| `gsd-read-injection-scanner.js` | `PostToolUse` | 신뢰할 수 없는 콘텐츠에서 주입된 지시 사항을 위한 Read 도구 출력 스캔 |
| `gsd-workflow-guard.js` | `PreToolUse` | GSD 워크플로우 컨텍스트 외부의 파일 편집 감지 (자문적, `hooks.workflow_guard`를 통한 옵트인) |
| `gsd-secret-read-guard.js` | `PreToolUse` | Read / Grep / Bash로 `.env`, `.env.<suffix>`(`.env.example` 등 템플릿 제외), `.secrets`를 읽는 호출을 하드 차단. 설치 프로그램이 기록하던 `Read(.env*)` deny 규칙을 대체 (#4221) |
| `gsd-read-guard.js` | `PreToolUse` | 세션에서 아직 읽지 않은 파일에 Edit/Write를 방지하는 자문적 가드 |
| `gsd-session-state.sh` | `SessionStart` | 쉘 기반 런타임을 위한 세션 상태 추적 |
| `gsd-validate-commit.sh` | `PreToolUse` | 컨벤셔널 커밋 시행을 위한 커밋 검증 |

View File

@@ -476,6 +476,7 @@
| `gsd-worktree-path-guard.js` | `PreToolUse` | 워크트리 루트 외부의 절대 경로로 Edit/Write/MultiEdit를 하드 차단 (PR #579, #260) |
| `gsd-agent-isolation-guard.js` | `PreToolUse` | 프로젝트의 해석된 디스패치 격리가 `harness-worktree`일 때 하네스 격리 매개변수가 누락된 executor `Agent()` 디스패치를 하드 차단 (#3045) |
| `gsd-write-guard.js` | `PreToolUse` | 큐레이션된 `.planning/` 아티팩트(ROADMAP.md, 마일스톤 로드맵, STATE.md)를 치명적으로 축소하는 전체 파일 `Write`를 하드 차단. 일회용 센티널 `.planning/.gsd-allow-shrink`(워크플로 단계) 또는 `GSD_ALLOW_PLANNING_SHRINK=1`(대화형)로 우회 가능 (#2255, #973의 수정 3) |
| `gsd-secret-read-guard.js` | `PreToolUse` | Read / Grep / Bash로 `.env`, `.env.<suffix>`(`.env.example` 등 템플릿 제외), `.secrets`를 읽는 호출을 하드 차단. 설치 프로그램이 기록하던 `Read(.env*)` deny 규칙을 대체 (#4221) |
| `gsd-session-state.sh` | `SessionStart` | 셸 기반 런타임을 위한 세션 상태 추적 |
| `gsd-validate-commit.sh` | `PreToolUse` | 컨벤셔널 커밋 적용을 위한 커밋 검증 |
| `gsd-phase-boundary.sh` | `PostToolUse` | 워크플로우 전환을 위한 단계 경계 감지 |

View File

@@ -261,6 +261,7 @@ Hooks de runtime que se integram ao agente de IA anfitrião:
| `gsd-prompt-guard.js` | `PreToolUse` | Escaneia escritas em `.planning/` em busca de padrões de injeção de prompt (consultivo) |
| `gsd-read-injection-scanner.js` | `PostToolUse` | Escaneia saídas da ferramenta Read em busca de instruções injetadas em conteúdo não confiável |
| `gsd-workflow-guard.js` | `PreToolUse` | Detecta edições de arquivos fora do contexto de workflow do GSD (consultivo, ativado via `hooks.workflow_guard`) |
| `gsd-secret-read-guard.js` | `PreToolUse` | Bloqueia rigorosamente leituras de `.env`, `.env.<suffix>` (exceto templates como `.env.example`) e `.secrets` via Read / Grep / Bash; substitui as regras deny `Read(.env*)` que o instalador escrevia (#4221) |
| `gsd-read-guard.js` | `PreToolUse` | Guarda consultivo que impede Edit/Write em arquivos ainda não lidos na sessão |
| `gsd-session-state.sh` | `SessionStart` | Rastreamento de estado de sessão para runtimes baseados em shell |
| `gsd-validate-commit.sh` | `PreToolUse` | Validação de commit para aplicação de commits convencionais |

View File

@@ -476,6 +476,7 @@ Listagem completa: `hooks/`.
| `gsd-worktree-path-guard.js` | `PreToolUse` | Bloqueia rigorosamente Edit/Write/MultiEdit com caminhos absolutos fora da raiz do worktree (PR #579, #260) |
| `gsd-agent-isolation-guard.js` | `PreToolUse` | Bloqueia rigorosamente um dispatch `Agent()` de executor que não tenha o parâmetro de isolamento do harness quando o isolamento de dispatch resolvido do projeto é `harness-worktree` (#3045) |
| `gsd-write-guard.js` | `PreToolUse` | Bloqueia rigorosamente um `Write` de arquivo inteiro que encolhe catastroficamente um artefato curado de `.planning/` (ROADMAP.md, roadmaps de milestone, STATE.md); override via o sentinela de uso único `.planning/.gsd-allow-shrink` (passos de workflow) ou `GSD_ALLOW_PLANNING_SHRINK=1` (interativo) (#2255, correção 3 de #973) |
| `gsd-secret-read-guard.js` | `PreToolUse` | Bloqueia rigorosamente leituras de `.env`, `.env.<suffix>` (exceto templates como `.env.example`) e `.secrets` via Read / Grep / Bash; substitui as regras deny `Read(.env*)` que o instalador escrevia (#4221) |
| `gsd-session-state.sh` | `SessionStart` | Rastreamento de estado de sessão para runtimes baseados em shell |
| `gsd-validate-commit.sh` | `PreToolUse` | Validação de commit para aplicação de conventional-commit |
| `gsd-phase-boundary.sh` | `PostToolUse` | Detecção de limite de fase para transições de workflow |

View File

@@ -246,6 +246,7 @@ GSD Core 是一个**元提示框架**,位于用户与 AI 编码 Agent(Claude
| `gsd-prompt-guard.js` | `PreToolUse` | 扫描 `.planning/` 写入内容中的提示词注入模式(建议性) |
| `gsd-read-injection-scanner.js` | `PostToolUse` | 扫描 Read 工具输出中不受信任内容里的注入指令 |
| `gsd-workflow-guard.js` | `PreToolUse` | 检测 GSD 工作流上下文之外的文件编辑(建议性,通过 `hooks.workflow_guard` 选择启用) |
| `gsd-secret-read-guard.js` | `PreToolUse` | 硬性阻止通过 Read / Grep / Bash 读取 `.env`、`.env.<suffix>`(`.env.example` 等模板除外)和 `.secrets`;取代安装程序以前写入的 `Read(.env*)` 拒绝规则(#4221) |
| `gsd-read-guard.js` | `PreToolUse` | 建议性防护,防止对本会话中尚未读取的文件执行 Edit/Write |
| `gsd-session-state.sh` | `SessionStart` | 基于 shell 的运行时的会话状态跟踪 |
| `gsd-validate-commit.sh` | `PreToolUse` | 用于规范提交格式执行的提交验证 |

View File

@@ -476,6 +476,7 @@
| `gsd-worktree-path-guard.js` | `PreToolUse` | 硬性阻止对 worktree 根目录之外绝对路径执行 Edit/Write/MultiEdit(PR #579,#260) |
| `gsd-agent-isolation-guard.js` | `PreToolUse` | 当项目解析出的调度隔离模式为 `harness-worktree` 时,硬性阻止缺少隔离参数的 executor `Agent()` 调度(#3045) |
| `gsd-write-guard.js` | `PreToolUse` | 硬性阻止将精选的 `.planning/` 工件(ROADMAP.md、里程碑路线图、STATE.md)灾难性缩减的整文件 `Write`;可通过一次性哨兵文件 `.planning/.gsd-allow-shrink`(工作流步骤)或 `GSD_ALLOW_PLANNING_SHRINK=1`(交互式)覆盖(#2255,#973 的修复 3) |
| `gsd-secret-read-guard.js` | `PreToolUse` | 硬性阻止通过 Read / Grep / Bash 读取 `.env`、`.env.<suffix>`(`.env.example` 等模板除外)和 `.secrets`;取代安装程序以前写入的 `Read(.env*)` 拒绝规则(#4221) |
| `gsd-session-state.sh` | `SessionStart` | 基于 shell 运行时的会话状态跟踪 |
| `gsd-validate-commit.sh` | `PreToolUse` | 常规提交强制执行的提交验证 |
| `gsd-phase-boundary.sh` | `PostToolUse` | 工作流过渡的阶段边界检测 |