feat(hooks,agents): SDD discipline gate -- AGENTS.md rule + SessionStart nudge (SDD-001)#49
Merged
Merged
Conversation
…art nudge (SDD-001) Tier 1+2 of a 5-layer enforcement stack instituted after a session audit (2026-05-18) found that two recent atomic PRs (BUG-002/#47, BUG-003/#48) bypassed the SDD vault gate and spec scaffold despite meeting trigger criteria. The discipline existed in `pattern-spec-driven-development.md` but was opt-in: `git checkout -b` had no frication, and the SessionStart hook only *reported* repo specs status rather than *nudging* the agent to *apply* SDD. This PR closes the soft-enforcement gap. Hard enforcement (CI spec-gate + PR template) ships separately as SDD-003. Settings.json portability for fresh-machine hook deploy ships as SDD-002. Tier 1 (AGENTS.md): - Add `### Discipline Gate (NON-NEGOTIABLE)` subsection under the existing `## Spec-Driven Development` section. Enumerates the 5 trigger criteria, the mandatory ordered process (vault entry -> init-spec -> proposal -> tasks -> code -> verification -> archive on merge), and a banned-phrases list for vault-hygiene "later" promises that historically compound into debt. ~30 lines. Links to the canonical pattern doc for full rationale. Tier 2 (SessionStart hook injection): - `scripts/claude-session-start.{ps1,sh}` now initialise the context buffer with a `[sdd]` prefixed reminder (byte-anchored same text across OS) at the start, unconditional, runs every session regardless of CWD/repo/vault state. Reminder points to `AGENTS.md` + the new gate, lists skip criteria inline so the agent does not need a round-trip to AGENTS.md for the common case. - Refactored claude-mem heal block to use the defensive append pattern already used by the doctor block. Without this, the heal block would wipe the SDD reminder when claude-mem produced output. Fixes a latent pre-existing bug (heal could already wipe doctor output if ordering changed) while load-bearing for SDD-001 correctness. - Removed the early-exit `if (no vault and no context) exit 0` branch in both scripts: now dead code because the context buffer is always non-empty after this PR. Kept an inline comment explaining the history. Tests (additive): - `tests/agents-md.bats` (new file, 8 asserts): pre-existing H2 regression guard + new H3 subsection + 5 trigger criteria + ordered process + banned phrases + Standing Order reference. - `tests/hooks.bats` (new file, 8 asserts): both hook scripts contain the `[sdd]` marker + core text + AGENTS.md fallback path + skip criteria mention + position invariant (reminder must come before the first gated diagnostic block) + cross-OS parity lock on the core text. Spec scaffolding: - `specs/SDD-001-discipline-gate/` with proposal/tasks/verification, all filled with substantive content. Eat-our-dog-food: this PR adds the discipline gate AND follows the gate from the very first commit. Verification (empirical, this machine, 2026-05-18): - `.ps1` smoke: `echo '{"cwd":"C:\test","session_id":"test"}' | pwsh -NoProfile -File scripts/claude-session-start.ps1` -> JSON with `[sdd]` block FIRST in additionalContext, followed by existing diagnostics. - `.sh` smoke: matching shape, identical core text. - `bash -n scripts/claude-session-start.sh` clean. - PSScriptAnalyzer on `claude-session-start.ps1` reports 3 warnings -- all pre-existing ($Input automatic var, BOM, Test-RepoSpecs plural) and not introduced by this change. The script is not in the CI lint-powershell scan list, so no CI fail. Out of scope (deferred to sibling specs): - SDD-002: track `~/.claude/settings.json` in dotfiles for hook portability (deep-merge install logic, ~80 LOC, requires careful merge with third-party hooks like claude-mem and GitGuardian). - SDD-003: `.github/workflows/ci.yml` spec-gate job + `.github/ PULL_REQUEST_TEMPLATE.md` with SDD checklist (PR-time enforcement).
This was referenced May 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Tier 1+2 of a 5-layer enforcement stack instituted after a 2026-05-18 session audit found that BUG-002 (#47) and BUG-003 (#48) bypassed the SDD vault gate and spec scaffold despite meeting the trigger criteria. The discipline existed in
pattern-spec-driven-development.mdbut was opt-in.### Discipline Gate (NON-NEGOTIABLE)subsection inAGENTS.mdunder the existing## Spec-Driven Developmentsection. Trigger criteria, mandatory ordered process, banned-phrases list for vault-hygiene "later" promises..ps1+.sh) inject a[sdd]reminder at the START ofadditionalContext, unconditional, byte-anchored across OS. Refactors the claude-mem heal block to use the defensive append pattern (was an overwrite, would have wiped the reminder).Eat-our-dog-food
This PR adds the discipline AND follows it from the first commit:
10_projects/dotfiles/11-tasks.mdSDD-001-discipline-gate (added in catch-up vault hygiene this session)specs/SDD-001-discipline-gate/{proposal,tasks,verification}.mdviainit-spec.ps1(vault gate passed)tests/agents-md.bats,tests/hooks.bats) written before implementationWhy three PRs instead of one mega-PR
Per
pattern-spec-driven-development.md"one spec = one atomic PR":~/.claude/settings.jsonin dotfiles for hook portability across machines (~80 LOC + deep-merge install logic; standalone scope).spec-gateCI job + PR template (PR-time hard enforcement).Test plan
.ps1on this Windows machine:[sdd]reminder is FIRST inadditionalContext; existing diagnostics (doctor, hive, specs) append correctly (no regression).sh(Git Bash): matching JSON shape, identical core textbash -n scripts/claude-session-start.shcleanclaude-session-start.ps1reports only pre-existing warnings (none introduced; script also not in CI lint-powershell scan list -- documented)[sdd]reminder at start; agent must read AGENTS.md + apply Discipline Gate before tool useOut of scope (deferred)
claude-session-start.ps1to CI lint-powershell scan + fixing the 3 pre-existing PSScriptAnalyzer warnings (separate follow-up; would be scope creep here)Cross-references
00_meta/patterns/pattern-spec-driven-development.md(vault SSOT this PR enforces)10_projects/dotfiles/11-tasks.md"SDD-001-discipline-gate" (P0 sprint item)