cleargate 0.8.2 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/CHANGELOG.md +190 -0
  2. package/README.md +11 -0
  3. package/dist/MANIFEST.json +259 -28
  4. package/dist/{chunk-OM4FAEA7.js → chunk-Q3BTSXCK.js} +69 -3
  5. package/dist/chunk-Q3BTSXCK.js.map +1 -0
  6. package/dist/cli.cjs +2621 -548
  7. package/dist/cli.cjs.map +1 -1
  8. package/dist/cli.js +2548 -560
  9. package/dist/cli.js.map +1 -1
  10. package/dist/lib/ledger.cjs +120 -0
  11. package/dist/lib/ledger.cjs.map +1 -0
  12. package/dist/lib/ledger.d.cts +64 -0
  13. package/dist/lib/ledger.d.ts +64 -0
  14. package/dist/lib/ledger.js +96 -0
  15. package/dist/lib/ledger.js.map +1 -0
  16. package/dist/templates/cleargate-planning/.claude/agents/architect.md +10 -8
  17. package/dist/templates/cleargate-planning/.claude/agents/cleargate-wiki-contradict.md +108 -0
  18. package/dist/templates/cleargate-planning/.claude/agents/cleargate-wiki-ingest.md +49 -3
  19. package/dist/templates/cleargate-planning/.claude/agents/cleargate-wiki-lint.md +6 -1
  20. package/dist/templates/cleargate-planning/.claude/agents/developer.md +29 -2
  21. package/dist/templates/cleargate-planning/.claude/agents/qa.md +50 -1
  22. package/dist/templates/cleargate-planning/.claude/agents/reporter.md +31 -9
  23. package/dist/templates/cleargate-planning/.claude/hooks/pre-tool-use-task.sh +148 -0
  24. package/dist/templates/cleargate-planning/.claude/hooks/session-start.sh +6 -0
  25. package/dist/templates/cleargate-planning/.claude/hooks/token-ledger.sh +314 -96
  26. package/dist/templates/cleargate-planning/.claude/settings.json +4 -0
  27. package/dist/templates/cleargate-planning/.claude/skills/sprint-execution/SKILL.md +473 -0
  28. package/dist/templates/cleargate-planning/.cleargate/config.example.yml +19 -0
  29. package/dist/templates/cleargate-planning/.cleargate/knowledge/cleargate-enforcement.md +542 -0
  30. package/dist/templates/cleargate-planning/.cleargate/knowledge/cleargate-protocol.md +102 -428
  31. package/dist/templates/cleargate-planning/.cleargate/knowledge/readiness-gates.md +31 -0
  32. package/dist/templates/cleargate-planning/.cleargate/knowledge/sprint-closeout-checklist.md +71 -0
  33. package/dist/templates/cleargate-planning/.cleargate/scripts/assert_story_files.mjs +24 -2
  34. package/dist/templates/cleargate-planning/.cleargate/scripts/close_sprint.mjs +387 -27
  35. package/dist/templates/cleargate-planning/.cleargate/scripts/dedupe_frontmatter.mjs +219 -0
  36. package/dist/templates/cleargate-planning/.cleargate/scripts/lib/report-filename.mjs +54 -0
  37. package/dist/templates/cleargate-planning/.cleargate/scripts/prep_doc_refresh.mjs +378 -0
  38. package/dist/templates/cleargate-planning/.cleargate/scripts/prep_qa_context.mjs +888 -0
  39. package/dist/templates/cleargate-planning/.cleargate/scripts/sprint_trends.mjs +71 -0
  40. package/dist/templates/cleargate-planning/.cleargate/scripts/suggest_improvements.mjs +355 -13
  41. package/dist/templates/cleargate-planning/.cleargate/scripts/test/test_flashcard_gate.sh +20 -20
  42. package/dist/templates/cleargate-planning/.cleargate/scripts/test/test_prep_qa_context.sh +482 -0
  43. package/dist/templates/cleargate-planning/.cleargate/scripts/write_dispatch.sh +125 -0
  44. package/dist/templates/cleargate-planning/.cleargate/templates/Bug.md +24 -1
  45. package/dist/templates/cleargate-planning/.cleargate/templates/CR.md +32 -1
  46. package/dist/templates/cleargate-planning/.cleargate/templates/Sprint Plan Template.md +48 -14
  47. package/dist/templates/cleargate-planning/.cleargate/templates/epic.md +37 -3
  48. package/dist/templates/cleargate-planning/.cleargate/templates/hotfix.md +50 -0
  49. package/dist/templates/cleargate-planning/.cleargate/templates/initiative.md +98 -29
  50. package/dist/templates/cleargate-planning/.cleargate/templates/proposal.md +17 -4
  51. package/dist/templates/cleargate-planning/.cleargate/templates/sprint_report.md +23 -4
  52. package/dist/templates/cleargate-planning/.cleargate/templates/story.md +55 -3
  53. package/dist/templates/cleargate-planning/CLAUDE.md +28 -10
  54. package/dist/templates/cleargate-planning/MANIFEST.json +259 -28
  55. package/dist/{whoami-CX7CXJD5.js → whoami-W4U6DPVG.js} +17 -17
  56. package/dist/whoami-W4U6DPVG.js.map +1 -0
  57. package/package.json +13 -2
  58. package/templates/cleargate-planning/.claude/agents/architect.md +10 -8
  59. package/templates/cleargate-planning/.claude/agents/cleargate-wiki-contradict.md +108 -0
  60. package/templates/cleargate-planning/.claude/agents/cleargate-wiki-ingest.md +49 -3
  61. package/templates/cleargate-planning/.claude/agents/cleargate-wiki-lint.md +6 -1
  62. package/templates/cleargate-planning/.claude/agents/developer.md +29 -2
  63. package/templates/cleargate-planning/.claude/agents/qa.md +50 -1
  64. package/templates/cleargate-planning/.claude/agents/reporter.md +31 -9
  65. package/templates/cleargate-planning/.claude/hooks/pre-tool-use-task.sh +148 -0
  66. package/templates/cleargate-planning/.claude/hooks/session-start.sh +6 -0
  67. package/templates/cleargate-planning/.claude/hooks/token-ledger.sh +314 -96
  68. package/templates/cleargate-planning/.claude/settings.json +4 -0
  69. package/templates/cleargate-planning/.claude/skills/sprint-execution/SKILL.md +473 -0
  70. package/templates/cleargate-planning/.cleargate/config.example.yml +19 -0
  71. package/templates/cleargate-planning/.cleargate/knowledge/cleargate-enforcement.md +542 -0
  72. package/templates/cleargate-planning/.cleargate/knowledge/cleargate-protocol.md +102 -428
  73. package/templates/cleargate-planning/.cleargate/knowledge/readiness-gates.md +31 -0
  74. package/templates/cleargate-planning/.cleargate/knowledge/sprint-closeout-checklist.md +71 -0
  75. package/templates/cleargate-planning/.cleargate/scripts/assert_story_files.mjs +24 -2
  76. package/templates/cleargate-planning/.cleargate/scripts/close_sprint.mjs +387 -27
  77. package/templates/cleargate-planning/.cleargate/scripts/dedupe_frontmatter.mjs +219 -0
  78. package/templates/cleargate-planning/.cleargate/scripts/lib/report-filename.mjs +54 -0
  79. package/templates/cleargate-planning/.cleargate/scripts/prep_doc_refresh.mjs +378 -0
  80. package/templates/cleargate-planning/.cleargate/scripts/prep_qa_context.mjs +888 -0
  81. package/templates/cleargate-planning/.cleargate/scripts/sprint_trends.mjs +71 -0
  82. package/templates/cleargate-planning/.cleargate/scripts/suggest_improvements.mjs +355 -13
  83. package/templates/cleargate-planning/.cleargate/scripts/test/test_flashcard_gate.sh +20 -20
  84. package/templates/cleargate-planning/.cleargate/scripts/test/test_prep_qa_context.sh +482 -0
  85. package/templates/cleargate-planning/.cleargate/scripts/write_dispatch.sh +125 -0
  86. package/templates/cleargate-planning/.cleargate/templates/Bug.md +24 -1
  87. package/templates/cleargate-planning/.cleargate/templates/CR.md +32 -1
  88. package/templates/cleargate-planning/.cleargate/templates/Sprint Plan Template.md +48 -14
  89. package/templates/cleargate-planning/.cleargate/templates/epic.md +37 -3
  90. package/templates/cleargate-planning/.cleargate/templates/hotfix.md +50 -0
  91. package/templates/cleargate-planning/.cleargate/templates/initiative.md +98 -29
  92. package/templates/cleargate-planning/.cleargate/templates/sprint_report.md +23 -4
  93. package/templates/cleargate-planning/.cleargate/templates/story.md +55 -3
  94. package/templates/cleargate-planning/CLAUDE.md +28 -10
  95. package/templates/cleargate-planning/MANIFEST.json +259 -28
  96. package/dist/chunk-OM4FAEA7.js.map +0 -1
  97. package/dist/whoami-CX7CXJD5.js.map +0 -1
  98. package/templates/cleargate-planning/.cleargate/templates/proposal.md +0 -61
@@ -0,0 +1,542 @@
1
+ # ClearGate Enforcement
2
+
3
+ Hook-enforced rules surfaced by CLI errors. AI agents read this file when a hook trips, not at session start. Source split from `cleargate-protocol.md` per EPIC-024 (2026-04-30).
4
+
5
+ ## Index
6
+
7
+ | New § | Source § | Title |
8
+ |---|---|---|
9
+ | §1 | protocol §15 | Worktree Lifecycle (v2) |
10
+ | §2 | protocol §16 | User Walkthrough on Sprint Branch (v2) |
11
+ | §3 | protocol §17 | Mid-Sprint Change Request Triage (v2) |
12
+ | §4 | protocol §18 | Immediate Flashcard Gate (v2) |
13
+ | §5 | protocol §19 | Execution Mode Routing (v2) |
14
+ | §6 | protocol §20 | File-Surface Contract (v2) |
15
+ | §7 | protocol §22 | Advisory Readiness Gates on Push (v2) — CR-010 |
16
+ | §8 | protocol §23 | Doctor Exit-Code Semantics |
17
+ | §9 | protocol §24 | Lane Routing |
18
+ | §10 | protocol §25 | Lifecycle Reconciliation (CR-017) |
19
+ | §11 | protocol §26 | Decomposition Gate (CR-017) |
20
+ | §12 | protocol §27 | Gate 3.5 — Sprint Close Acknowledgement (CR-019) |
21
+
22
+ ---
23
+
24
+ ## 1. Worktree Lifecycle (v2) (source: protocol §15)
25
+
26
+ **v1/v2 gating:** Under `execution_mode: v1` the rules in this section are **informational** — they document the intended workflow but are not enforced by any script. Under `execution_mode: v2` they are **mandatory**: every story transition that would run a Developer agent MUST follow these procedures before any file edits begin.
27
+
28
+ ### §1.1 Branch hierarchy
29
+
30
+ The branch hierarchy for a sprint is:
31
+
32
+ ```
33
+ main
34
+ └── sprint/S-XX ← cut at sprint start; never commit directly
35
+ └── story/STORY-NNN-NN ← cut when story transitions Ready → Bouncing
36
+ ```
37
+
38
+ - **Sprint branch** is cut from `main` once at the start of each sprint:
39
+ ```bash
40
+ git checkout -b sprint/S-XX main
41
+ ```
42
+ - **Story branch** is cut from the active sprint branch when the story enters `Bouncing` state:
43
+ ```bash
44
+ git checkout sprint/S-XX
45
+ git checkout -b story/STORY-NNN-NN sprint/S-XX
46
+ ```
47
+ - Story branches are **never** cut from `main` directly; they always track the sprint branch as parent.
48
+
49
+ ### §1.2 Worktree commands
50
+
51
+ Per-story working trees live under `.worktrees/` at repo root. Each story gets its own isolated filesystem view.
52
+
53
+ **Create worktree (story starts bouncing):**
54
+ ```bash
55
+ git worktree add .worktrees/STORY-NNN-NN -b story/STORY-NNN-NN sprint/S-XX
56
+ ```
57
+
58
+ **Verify worktree:**
59
+ ```bash
60
+ git worktree list
61
+ # .../repo <sha> [sprint/S-XX]
62
+ # .../repo/.worktrees/STORY-NNN-NN <sha> [story/STORY-NNN-NN]
63
+ ```
64
+
65
+ **Merge story back into sprint branch (story passes QA + Architect):**
66
+ ```bash
67
+ git checkout sprint/S-XX
68
+ git merge story/STORY-NNN-NN --no-ff -m "merge(story/STORY-NNN-NN): STORY-NNN-NN <title>"
69
+ ```
70
+
71
+ **Remove worktree and story branch (after successful merge):**
72
+ ```bash
73
+ git worktree remove .worktrees/STORY-NNN-NN
74
+ git branch -d story/STORY-NNN-NN
75
+ ```
76
+
77
+ **Prune stale worktree refs:**
78
+ ```bash
79
+ git worktree prune
80
+ ```
81
+
82
+ All commands must be run from the **repo root** (not from inside `.worktrees/`), except Developer Agent file edits which happen inside the assigned worktree path.
83
+
84
+ ### §1.3 MCP nested-repo rule
85
+
86
+ **The `mcp/` directory is a nested independent git repository.** Running `git worktree add` inside `mcp/` would create a worktree scoped to the nested repo, not to the outer ClearGate repo. This is a git footgun: the outer repo cannot track, merge, or remove the inner worktree via its own git commands.
87
+
88
+ **Rule:** Never run `git worktree add` inside `mcp/`. If a story requires edits to `mcp/`, the Developer Agent must edit `mcp/` from inside the outer worktree (`.worktrees/STORY-NNN-NN/mcp/...`) — the nested repo's files are visible there as a subdirectory, not as a separate git context. MCP-native worktree support is deferred to Q3.
89
+
90
+ ### §1.4 Local state.json is in-flight authority
91
+
92
+ During a story's execution, `state.json` at `.cleargate/sprint-runs/<sprint-id>/state.json` is the single source of truth for story state. The MCP server is a **post-facto audit** channel: it receives state updates after each transition but is never consulted during execution. If MCP is unavailable, execution continues uninterrupted; state.json records the ground truth that MCP will eventually replicate. (Source: EPIC-013 Q7 resolution.)
93
+
94
+ ### §1.5 Enforcement gates
95
+
96
+ | `execution_mode` | These rules are |
97
+ |---|---|
98
+ | `v1` | Informational — document intended workflow; not script-enforced |
99
+ | `v2` | Mandatory — `validate_bounce_readiness.mjs` checks worktree isolation before any Developer Agent edit |
100
+
101
+ Under v2, attempting to run a Developer Agent on a story without a matching `.worktrees/STORY-NNN-NN/` path present causes `validate_bounce_readiness.mjs` to exit non-zero and the orchestrator to halt the story transition.
102
+
103
+ ---
104
+
105
+ ## 2. User Walkthrough on Sprint Branch (v2) (source: protocol §16)
106
+
107
+ **v1/v2 gating:** Under `execution_mode: v1` this section is **informational**. Under `execution_mode: v2` it is **mandatory**: the sprint branch MUST NOT merge to `main` until the walkthrough is complete and all `UR:bug` items are resolved.
108
+
109
+ ### §2.1 Walkthrough trigger
110
+
111
+ After all stories in the sprint are merged into `sprint/S-XX` (every story state ∈ `TERMINAL_STATES`) and before `sprint/S-XX` merges to `main`, the orchestrator invites the user to test the running application on the sprint branch.
112
+
113
+ ### §2.2 Feedback classification
114
+
115
+ User feedback during the walkthrough is classified into exactly two event types:
116
+
117
+ | Event type | Definition | Bug-Fix Tax effect |
118
+ |---|---|---|
119
+ | `UR:review-feedback` | Enhancement, polish, copy change, or UX preference — does NOT fix broken behavior | Does NOT increment Bug-Fix Tax |
120
+ | `UR:bug` | Defect, crash, wrong output, or behavior broken relative to spec | DOES increment Bug-Fix Tax |
121
+
122
+ **Classification rule:** when in doubt, ask the user one targeted question — "Is this broken relative to spec, or a preference?" Do not default to `UR:bug`.
123
+
124
+ ### §2.3 Logging
125
+
126
+ Each piece of walkthrough feedback MUST be logged in the sprint markdown file under `## 4. Execution Log` with the event prefix:
127
+
128
+ ```
129
+ UR:review-feedback 2026-04-21 — copy should say "Sign in" not "Log in" (resolved: STORY-013-09-dev.md commit abc123)
130
+ UR:bug 2026-04-21 — create-project button 500s on submit (resolved: STORY-013-10-dev.md commit def456)
131
+ ```
132
+
133
+ ### §2.4 Resolution gate
134
+
135
+ The sprint branch MUST NOT merge to `main` while any `UR:bug` item is unresolved. `UR:review-feedback` items MAY be deferred to the next sprint with orchestrator + user acknowledgment logged.
136
+
137
+ ---
138
+
139
+ ## 3. Mid-Sprint Change Request Triage (v2) (source: protocol §17)
140
+
141
+ **v1/v2 gating:** Under `execution_mode: v1` this section is **informational**. Under `execution_mode: v2` it is **mandatory**: every user-injected change during a bounce MUST be classified before routing.
142
+
143
+ ### §3.1 Classification table
144
+
145
+ When the user injects new input during a QA bounce or active story execution, the orchestrator classifies the input into one of four categories:
146
+
147
+ | Event type | Definition | Bounce-counter effect | Routing |
148
+ |---|---|---|---|
149
+ | `CR:bug` | Defect introduced by the current story's implementation | Counts toward Bug-Fix Tax; increments `qa_bounces` | Re-open story; Developer fixes; QA re-verifies |
150
+ | `CR:spec-clarification` | Clarification of existing spec — no new scope, removes ambiguity | Does NOT increment any bounce counter | Update story acceptance criteria in place; re-run impacted test |
151
+ | `CR:scope-change` | Net-new requirement or expansion of story scope | Deferred: create a new Story in `pending-sync/`; current story continues unchanged | New Story ID assigned; current bounce counter unaffected |
152
+ | `CR:approach-change` | Switch implementation approach without changing functional spec | Does NOT increment bounce counter; resets Developer context | Re-spawn Developer with updated approach note; same story ID |
153
+
154
+ ### §3.2 Logging
155
+
156
+ Each mid-sprint CR MUST be logged in the sprint markdown file under `## 4. Execution Log` with the event prefix:
157
+
158
+ ```
159
+ CR:spec-clarification 2026-04-21 — endpoint must return project slug (clarified in STORY-013-05 §1.2; no new scope)
160
+ CR:scope-change 2026-04-21 — user requests audit log table (new STORY-013-11 created in pending-sync/)
161
+ ```
162
+
163
+ ### §3.3 Scope-change quarantine
164
+
165
+ A `CR:scope-change` MUST NOT be folded into the current story's commit. Create a new Story file and handle in a future sprint or as a mid-sprint addition (requires orchestrator + user explicit sign-off to add mid-sprint).
166
+
167
+ ---
168
+
169
+ ## 4. Immediate Flashcard Gate (v2) (source: protocol §18)
170
+
171
+ **v1/v2 gating:** Under `execution_mode: v1` this section is **informational** — the gate is advisory and the orchestrator may proceed without processing flagged cards (though it is strongly encouraged). Under `execution_mode: v2` it is **mandatory**: the orchestrator MUST NOT create the next story's worktree until all `flashcards_flagged` entries from the prior story's dev + QA reports are processed.
172
+
173
+ **V-Bounce reference:** `skills/agent-team/SKILL.md` §"Step 5.5: Immediate Flashcard Recording (Hard Gate)" at pinned SHA `2b8477ab65e39e594ee8b6d8cf13a210498eaded`.
174
+
175
+ ### §4.1 Trigger
176
+
177
+ After story N's commit merges into `sprint/S-XX` and QA approves, the orchestrator collects `flashcards_flagged` from both:
178
+ - `STORY-NNN-NN-dev.md` (Developer Agent output report)
179
+ - `STORY-NNN-NN-qa.md` (QA Agent output report)
180
+
181
+ The two lists are merged (union, deduplication by exact string match). If the combined list is empty, the gate passes immediately.
182
+
183
+ ### §4.2 Processing rule
184
+
185
+ For each entry in the merged `flashcards_flagged` list, the orchestrator MUST take exactly one of two actions before creating story N+1's worktree:
186
+
187
+ | Action | Effect | Record location |
188
+ |---|---|---|
189
+ | **Approve** | Append the one-liner verbatim to `.cleargate/FLASHCARD.md` (newest-first, per SKILL.md format) | The card itself is the record |
190
+ | **Reject** | Discard the entry — do NOT append to `FLASHCARD.md` | Sprint §4 Execution Log: `FLASHCARD-REJECT YYYY-MM-DD — "<card text>" — reason: <one sentence>` |
191
+
192
+ ### §4.3 Worktree creation gate
193
+
194
+ The orchestrator MUST NOT run `git worktree add .worktrees/STORY-NNN-NN ...` for story N+1 until the §4.2 processing loop is complete (every entry either approved or rejected). This is a blocking serial step, not a background task.
195
+
196
+ ### §4.4 Cards format
197
+
198
+ Each entry in `flashcards_flagged` MUST conform to the format required by `.claude/skills/flashcard/SKILL.md`:
199
+
200
+ ```
201
+ YYYY-MM-DD · #tag1 #tag2 · lesson ≤120 chars
202
+ ```
203
+
204
+ The orchestrator may reformat an entry that violates the format before appending, but must log the reformat in sprint §4 Execution Log.
205
+
206
+ ### §4.5 v1 dogfood note
207
+
208
+ SPRINT-09 runs under `execution_mode: v1`. From STORY-013-06 merge onwards, the orchestrator applies the §4.2 processing loop manually as a dogfood check even though the rule is informational. This is recorded in the SPRINT-09 sprint plan (line 121).
209
+
210
+ ### §4.6 PreToolUse hook enforcement (v2)
211
+
212
+ Under `execution_mode: v2`, the `pending-task-sentinel.sh` PreToolUse hook automatically enforces the flashcard gate before every Task (subagent) dispatch. This is implemented by STORY-014-03.
213
+
214
+ **Hash-marker convention:**
215
+
216
+ Each `flashcards_flagged` card is identified by the first 12 hexadecimal characters of its SHA-1 hash (computed with `shasum -a 1`):
217
+
218
+ ```bash
219
+ HASH="$(printf '%s' "<card text>" | shasum -a 1 | cut -c1-12)"
220
+ ```
221
+
222
+ Hash stability: the same card string always produces the same hash. The hash is computed over the exact card string as it appears in the report's `flashcards_flagged` list (after stripping surrounding quotes).
223
+
224
+ **Processed marker:**
225
+
226
+ To mark a card as processed (approved or rejected by the orchestrator), touch the marker file:
227
+
228
+ ```bash
229
+ touch .cleargate/sprint-runs/<sprint-id>/.processed-<hash>
230
+ ```
231
+
232
+ The marker files are gitignored via the existing `.cleargate/sprint-runs/` gitignore rule and serve only as local bookkeeping.
233
+
234
+ **Enforcement logic:**
235
+
236
+ 1. The hook globs `SPRINT_DIR/STORY-*-dev.md` and `SPRINT_DIR/STORY-*-qa.md` (flat layout — no `reports/` subdirectory).
237
+ 2. For each report file, it parses the `flashcards_flagged:` YAML list (inline `[]` and block `- "text"` forms both supported).
238
+ 3. For each card, it computes the 12-char SHA-1 hash and checks for the `.processed-<hash>` marker in `SPRINT_DIR`.
239
+ 4. If any card is unprocessed:
240
+ - **v2**: exits non-zero (blocks Task spawn) with stderr listing each unprocessed card and the `touch` command hint.
241
+ - **v1**: prints an advisory warning to stderr and exits 0 (does not block).
242
+ 5. If `flashcards_flagged: []` or no report files exist, the gate passes immediately.
243
+
244
+ **Bypass:**
245
+
246
+ Set `SKIP_FLASHCARD_GATE=1` in the environment to bypass the gate entirely (both v1 and v2). This bypass is intended for CI and bootstrap scenarios where the hook runs without sprint context. Bypasses should be disabled once M1 is closed; the orchestrator tracks this in the sprint §4 Execution Log.
247
+
248
+ ---
249
+
250
+ ## 5. Execution Mode Routing (v2) (source: protocol §19)
251
+
252
+ The `execution_mode` field in a Sprint Plan's frontmatter is the single switch that controls whether §§1–18 of this protocol are **enforcing** or **advisory** for that sprint.
253
+
254
+ ### §5.1 Flag semantics
255
+
256
+ | `execution_mode` value | Effect |
257
+ |---|---|
258
+ | `"v1"` | All §§1–18 rules are **advisory** — document intended workflow; no CLI or script enforcement. New CLI commands (`sprint init|close`, `story start|complete`, `gate qa|arch`, `state update|validate`) print an inert-mode message and exit 0. |
259
+ | `"v2"` | All §§1–18 rules are **mandatory** — CLI wrappers route to `run_script.sh` scripts; worktree isolation, pre-gate scanning, bounce counters, flashcard gate, and sprint-close pipeline are all enforced. |
260
+
261
+ ### §5.2 Sprint-scoped flag
262
+
263
+ The `execution_mode` flag is **sprint-scoped**, not global. A project may run SPRINT-10 on `v2` while SPRINT-11 planning files default to `v1` until the Architect completes a Sprint Design Review (§1.1). Setting the flag on one sprint has no effect on any other sprint file.
264
+
265
+ ### §5.3 Orchestrator routing rule
266
+
267
+ Before spawning any Developer, QA, or Reporter agent, the orchestrator MUST:
268
+
269
+ 1. Locate the active sprint file at `.cleargate/delivery/pending-sync/SPRINT-{ID}_*.md` (or the archived equivalent).
270
+ 2. Read the `execution_mode` frontmatter field. If absent, treat as `"v1"`.
271
+ 3. If `"v1"`: proceed with advisory-only loop. §§1–18 rules are informational.
272
+ 4. If `"v2"`: enforce §§1–18 before each agent spawn as mandatory gates.
273
+
274
+ ### §5.4 CLI inert-mode message
275
+
276
+ When a v2-only CLI command is invoked and the active sprint's `execution_mode` is `"v1"`, the CLI MUST print exactly:
277
+
278
+ ```
279
+ v1 mode active — command inert. Set execution_mode: v2 in sprint frontmatter to enable.
280
+ ```
281
+
282
+ and exit 0. No subprocess is spawned. This preserves backward compatibility for users who have not yet migrated to v2.
283
+
284
+ ### §5.5 Default value
285
+
286
+ The default value is `"v1"`. All sprint plans generated from the Sprint Plan Template default to `execution_mode: "v1"` until explicitly flipped. The flag should only be set to `"v2"` after all M2 EPIC-013 stories have shipped and the Architect has completed a Sprint Design Review (§1.1).
287
+
288
+ ---
289
+
290
+ ## 6. File-Surface Contract (v2) (source: protocol §20)
291
+
292
+ Under `execution_mode: v2`, each story's §3.1 "Context & Files" table is the **authoritative file surface** for that story's commit. The pre-commit hook enforces this contract automatically.
293
+
294
+ ### §6.1 Rule
295
+
296
+ A Developer agent MUST NOT stage and commit any file not declared in the active story's §3.1 table, unless that file matches a whitelist entry in `.cleargate/scripts/surface-whitelist.txt`.
297
+
298
+ Off-surface edits require one of:
299
+ 1. A CR:scope-change item approved before the commit, OR
300
+ 2. An updated §3.1 table committed in the same story (self-amending surface — rare, must be explicitly justified in the commit message).
301
+
302
+ ### §6.2 Hook mechanics
303
+
304
+ The gate runs as `.cleargate/scripts/file_surface_diff.sh` invoked via `.claude/hooks/pre-commit-surface-gate.sh` and dispatched from `.claude/hooks/pre-commit.sh`. The dispatcher is symlinked to `.git/hooks/pre-commit`.
305
+
306
+ - Under v2: off-surface files cause a non-zero exit — the commit is blocked.
307
+ - Under v1: the hook prints a warning but exits 0 (advisory only).
308
+ - `SKIP_SURFACE_GATE=1` env variable bypasses the gate entirely (use sparingly; log bypass in sprint §4 Execution Log).
309
+
310
+ ### §6.3 §3.1 table contract
311
+
312
+ The §3.1 table in `story.md` template uses a two-column `| Item | Value |` pipe table. The parser:
313
+ - Scans between the `### 3.1` heading and the next `### ` heading.
314
+ - Only processes rows where the Value cell contains `.` or `/` (path-shaped values).
315
+ - Strips backticks from values.
316
+ - Splits on `, ` to handle multiple paths in one cell.
317
+ - Ignores header and separator rows.
318
+
319
+ Non-path rows (e.g., "Mirrors", "New Files Needed: Yes/No") are silently skipped.
320
+
321
+ ### §6.4 Whitelist
322
+
323
+ `.cleargate/scripts/surface-whitelist.txt` declares auto-generated files that are always admitted regardless of story surface. Seed entries include: `cleargate-planning/MANIFEST.json`, `.cleargate/hook-log/*`, `.cleargate/sprint-runs/**/token-ledger.jsonl`, `.cleargate/sprint-runs/**/.pending-task-*.json`, `.cleargate/sprint-runs/**/state.json`.
324
+
325
+ ### §6.5 Install (dogfood)
326
+
327
+ On `cleargate init`, the scaffold automatically installs the `.git/hooks/pre-commit` symlink. For existing dogfood repositories, install once by hand:
328
+
329
+ ```bash
330
+ ln -sf ../../.claude/hooks/pre-commit.sh .git/hooks/pre-commit
331
+ ```
332
+
333
+ Log this step in the sprint §4 Execution Log.
334
+
335
+ ---
336
+
337
+ ## 7. Advisory Readiness Gates on Push (v2) — CR-010 (source: protocol §22)
338
+
339
+ ### §7.1 Two-tier push gate semantics
340
+
341
+ Push-time gate enforcement uses two distinct tiers:
342
+
343
+ **Tier 1 — `approved: true` (hard reject, unchanged):**
344
+ `cleargate_push_item` throws `PushNotApprovedError` when `payload.approved !== true`. This is the human go/no-go gate. No advisory mode or env knob overrides it.
345
+
346
+ **Tier 2 — `cached_gate_result` (advisory by default):**
347
+ When `cached_gate_result.pass === false`, the push proceeds in default advisory mode. The pushed item's body receives a single advisory prefix line placed immediately after the H1 heading (or as the first line if no H1 exists):
348
+
349
+ ```
350
+ [advisory: gate_failed — <comma-separated criterion ids>]
351
+ ```
352
+
353
+ Body content beyond the advisory prefix is byte-identical to the input. The push result includes `gate_status: 'open'` and `failing_criteria: [...]` as response metadata (not persisted to the DB schema).
354
+
355
+ ### §7.2 Strict-mode opt-in and audit log
356
+
357
+ Set `STRICT_PUSH_GATES=true` on the MCP server to restore pre-CR-010 hard-reject behavior (`PushGateFailedError`, no DB write). Default: `false` (advisory mode).
358
+
359
+ Advisory pushes (gate_status='open') are recorded in `audit_log` with `result='ok'` — the push succeeded. The `failing_criteria` are surfaced in the push response shape, not in a new audit column. No schema migration is required.
360
+ **Rationale:** PM-tool answer-collection requires items to land before readiness answers arrive; advisory mode enables this. See CR-010 §0 for full evidence.
361
+
362
+ ---
363
+
364
+ ## 8. Doctor Exit-Code Semantics (source: protocol §23)
365
+
366
+ `cleargate doctor` exits with one of three codes (all modes: default, `--session-start`, `--can-edit`, `--check-scaffold`, `--pricing`). Hooks branch on the integer, not on stdout.
367
+ - `0` — clean. No blockers, no config errors. Stdout MAY include informational lines.
368
+ - `1` — blocked items or advisory issues (gate failures, stamp errors, drifted SHAs, missing ledger rows). Stdout lists each blocker.
369
+ - `2` — ClearGate misconfigured or partially installed (missing `.cleargate/`, missing `MANIFEST.json`, missing `auth.json`, hook resolver failure). Stdout emits a remediation hint. See `cleargate doctor --help`.
370
+
371
+ ---
372
+
373
+ ## 9. Lane Routing (source: protocol §24)
374
+
375
+ A story is eligible for `lane: fast` only if all seven checks pass (any false → `standard`):
376
+ 1. **Size cap.** ≤2 files AND ≤50 LOC net (tests count; generated files do not).
377
+ 2. **No forbidden surfaces.** Story does not modify: `mcp/src/db/` / `**/migrations/` (schema); `mcp/src/auth/` / `mcp/src/admin-api/auth-*` (auth); `cleargate.config.json` / `mcp/src/config.ts` (runtime config); `mcp/src/adapters/` (adapter API); `cleargate-planning/MANIFEST.json` (scaffold manifest); security-relevant code (token handling, invite verification, gate enforcement).
378
+ 3. **No new dependency.** No new package added to any `package.json`.
379
+ 4. **Single acceptance scenario or doc-only.** Exactly one `Scenario:` block (or zero for doc-only). `Scenario Outline:` or multiple scenarios → `standard`.
380
+ 5. **Existing tests cover the runtime change.** Named test file exists and includes the affected module, OR story is doc/comment/non-runtime config only.
381
+ 6. **`expected_bounce_exposure: low`.** `med` or `high` is auto-`standard`.
382
+ 7. **No epic-spanning subsystem touches.** All affected files live under the parent epic's declared scope directories.
383
+
384
+ **Demotion mechanics.** Demotion is one-way (`fast → standard`). Trigger: pre-gate scanner failure OR post-merge test failure on a fast-lane story. On demotion: set `lane = "standard"`, write `lane_demoted_at` (ISO-8601), `lane_demotion_reason`, reset `qa_bounces = 0` and `arch_bounces = 0` (see STORY-022-02 schema). Architect plan is invoked and QA spawned per standard contract.
385
+
386
+ Event-type `LD` (Lane Demotion) is recorded in sprint markdown §4 alongside existing `UR` and `CR` events; Reporter aggregates into §3 Execution Metrics > Fast-Track Demotion Rate.
387
+
388
+ ---
389
+
390
+ ## 10. Lifecycle Reconciliation (CR-017) (source: protocol §25)
391
+
392
+ ### §10.1 Purpose
393
+
394
+ Artifact lifecycle drift occurs when a Developer agent commits `feat(STORY-NNN-NN): ...` but the artifact's `status:` field is never advanced and the file is never moved to `archive/`. CR-017 enforces status reconciliation at two sprint boundaries: sprint close and sprint kickoff.
395
+
396
+ ### §10.2 Verb-to-Status Map (v1)
397
+
398
+ | Commit verb pattern | Applies to types | Expected terminal status | Expected location |
399
+ |---|---|---|---|
400
+ | `feat(STORY-NNN-NN): ...` | STORY | `Done` | `archive/` |
401
+ | `feat(<TYPE>-NNN): ...` where TYPE ∈ {EPIC, CR} | EPIC, CR | `Completed` OR `Done` | `archive/` |
402
+ | `fix(BUG-NNN): ...` | BUG | `Verified` | `archive/` |
403
+ | `fix(HOTFIX-NNN-NN): ...` | HOTFIX | `Verified`, `Done`, OR `Completed` | `archive/` |
404
+ | `merge: <TYPE>-NNN → ...` | any | ignored — merge commits carry no expectation | n/a |
405
+ | `chore(...)`, `docs:`, `refactor:`, `test:`, `file(...)`, `plan(...)` | n/a | no expectation | n/a |
406
+ | `feat(BUG-NNN): ...` (verb mismatch) | BUG | soft warning only — does NOT block in v1 | n/a |
407
+
408
+ Multi-ID commits: scanner parses subject + first non-empty body line for ALL ID patterns matching `(STORY-\d{3}-\d{2}|CR-\d{3}|BUG-\d{3}|EPIC-\d{3}|HOTFIX-\d{3}-\d{2})`. Each ID gets independent validation. Unknown IDs (no file found) are skipped silently.
409
+
410
+ ### §10.3 Carry-Over Semantics
411
+
412
+ An artifact with `carry_over: true` in its frontmatter is silently skipped by the lifecycle reconciler — it does not appear in `drift` or `clean` counts. Carry-over is set **explicitly by the human at sprint close** as a deliberate "keep open across boundary" signal. It is never auto-inferred. `close_sprint.mjs` does NOT auto-promote `carry_over: true` artifacts into the next sprint plan.
413
+
414
+ ### §10.4 Invocation Points and Gate Mode
415
+
416
+ | Phase | Invocation | Mode |
417
+ |---|---|---|
418
+ | **Sprint close** | `close_sprint.mjs` Step 2.6 via `cleargate sprint reconcile-lifecycle <id>` | Block-by-default. Drift → exit 1 with punch list. |
419
+ | **Sprint kickoff — lifecycle layer** | `cleargate sprint init` before `init_sprint.mjs` | **warn-only** when `lifecycle_init_mode: "warn"` in sprint frontmatter (default for SPRINT-15); **block** when `lifecycle_init_mode: "block"` (SPRINT-16+). `--allow-drift` flag skips the warn/block but records a waiver in `context_source:`. |
420
+ | **v1 dormancy** | Both gates are dormant under `execution_mode: v1`. | n/a |
421
+
422
+ ### §10.5 v2 Escalation Path
423
+
424
+ `lifecycle_init_mode: "warn"` was the grace setting for SPRINT-15 (already-in-flight artifacts). Starting with SPRINT-16, set `lifecycle_init_mode: "block"` in the sprint frontmatter to enforce hard blocking at kickoff. After one clean SPRINT-15 close, the `warn` grace period ends.
425
+
426
+ ---
427
+
428
+ ## 11. Decomposition Gate (CR-017) (source: protocol §26)
429
+
430
+ ### §11.1 Purpose
431
+
432
+ A sprint that references `epics: ["EPIC-X"]` in its plan cannot activate until EPIC-X has been decomposed into at least one `STORY-X-NN_*.md` file with `parent_epic_ref: EPIC-X`. Similarly, a `proposals: ["PROPOSAL-Z"]` reference requires that an EPIC file citing PROPOSAL-Z in its `context_source:` exists. Decomposition is between-sprints transition work — not story-tracked, no Gherkin on the decomposition itself, no QA — but the gate at `cleargate sprint init` verifies the output.
433
+
434
+ ### §11.2 Gate Rules
435
+
436
+ 1. **Epic → stories.** For each ID in sprint frontmatter `epics:`, a file `EPIC-NNN_*.md` must exist in `pending-sync/` AND at least one `STORY-NNN-NN_*.md` must have `parent_epic_ref: EPIC-NNN` in its frontmatter. Violation: `reason: 'no-child-stories'`.
437
+ 2. **Proposal → epic.** For each ID in sprint frontmatter `proposals:`, a file `EPIC-NNN_*.md` must exist in `pending-sync/` with `context_source:` containing the proposal ID string. Violation: `reason: 'no-decomposed-epic'`.
438
+ 3. **Anchor file missing.** If the referenced file does not exist at all: `reason: 'file-missing'`.
439
+
440
+ ### §11.3 No-Waiver Policy
441
+
442
+ The decomposition gate cannot be waived with `--allow-drift`. Passing `--allow-drift` with an outstanding decomposition failure still exits 1 and emits:
443
+
444
+ ```
445
+ decomposition gate cannot be waived; complete the decomposition or push start_date.
446
+ ```
447
+
448
+ If the Architect cannot deliver the decomposition before the activating sprint's `start_date`, push `start_date` — do not relax the gate.
449
+
450
+ ### §11.4 Invocation
451
+
452
+ `cleargate sprint init` calls `reconcileDecomposition()` BEFORE shelling out to `init_sprint.mjs`. A non-empty `missing[]` result exits 1 with a punch list. The gate is dormant under `execution_mode: v1` (the entire `sprintInitHandler` is v1-inert).
453
+
454
+ ---
455
+
456
+ ## 12. Gate 3.5 — Sprint Close Acknowledgement (CR-019) (source: protocol §27)
457
+
458
+ ### §12.1 Gate Posture
459
+
460
+ Sprint close is a **Gate-3-class action** — same posture as `cleargate_push_item` push-approval (§4 Gate 3), which already requires `approved: true` + explicit human confirmation. Authorising the execution loop ("start sprint NN") does NOT authorise the close. Close requires its own dedicated human approval.
461
+
462
+ ### §12.2 Two-Step Protocol
463
+
464
+ 1. **Step A — Orchestrator:** runs `node .cleargate/scripts/close_sprint.mjs <sprint-id>` with no flags. The script validates Steps 1–2.6, prefills the report stub if missing, and exits 0 with the exact prompt: `Review the report, then confirm close by re-running with --assume-ack`. The orchestrator surfaces this prompt verbatim to the human and **halts**.
465
+ 2. **Step B — Human:** reviews `REPORT.md`, then either runs `node .cleargate/scripts/close_sprint.mjs <sprint-id> --assume-ack` themselves, or explicitly tells the orchestrator "approved, close it" — at which point the orchestrator may pass the flag on the human's behalf.
466
+
467
+ ### §12.3 Flag Reservation
468
+
469
+ `--assume-ack` is reserved for **automated test environments only**. The conversational orchestrator (the human-facing agent) is a non-test environment and MUST NOT pass `--assume-ack` on its own initiative. Violation of this rule is a Gate-3 breach equivalent to calling `cleargate_push_item` without `approved: true`.
470
+
471
+ ## 13. Sprint Execution Gate (Gate 3) (source: new in CR-021)
472
+
473
+ Before sprint state transitions Ready → Active, the orchestrator MUST invoke
474
+ `cleargate sprint preflight <sprint-id>` and verify all four checks pass:
475
+
476
+ 1. **Previous sprint Completed.** Scan `.cleargate/wiki/active-sprint.md` and
477
+ `pending-sync/SPRINT-*.md`. The sprint immediately preceding `<sprint-id>`
478
+ in the linear sequence must have `sprint_status: "Completed"` in its
479
+ `state.json`. Skip the check if there is no preceding sprint (SPRINT-01).
480
+
481
+ 2. **No leftover worktrees.** Run `git worktree list` and verify no path
482
+ matches `.worktrees/STORY-*`. Leftover worktrees indicate a story from a
483
+ prior sprint that wasn't merged or removed cleanly.
484
+
485
+ 3. **Sprint branch ref free.** Run `git show-ref refs/heads/sprint/S-NN`. The
486
+ ref must NOT exist (we're about to cut it). If it exists, the sprint
487
+ was previously started or the prior cleanup didn't complete.
488
+
489
+ 4. **`main` is clean.** Run `git status --porcelain` on a `main` checkout.
490
+ No uncommitted changes (modified, untracked, staged) may exist.
491
+
492
+ On any failure, the script exits 1 with a punch list. The orchestrator surfaces
493
+ the failure verbatim to the human and halts. Resolution is per-item:
494
+ - Prev sprint not closed → run `cleargate sprint close <prev-id>` first
495
+ - Leftover worktree → `git worktree remove` if abandoned, or merge if work in progress
496
+ - Branch ref exists → investigate; force-deletion only with explicit human approval
497
+ - Dirty main → human commits / stashes / discards as appropriate
498
+
499
+ This gate is **enforcing under `execution_mode: v2`** and **advisory under v1**.
500
+
501
+
502
+
503
+ ## 14. Sprint Close Gate (Gate 4) — Pre-close + Post-close additions (source: CR-022)
504
+
505
+ `close_sprint.mjs` runs an 8-step close pipeline. Steps 2.7, 2.8, 6.5, 6.6, 6.7, and 8 were added in SPRINT-19 by CR-022 to harden the close pipeline against the issues observed in SPRINT-18 (worktrees left open, sprint branch unmerged, no post-close handoff visibility).
506
+
507
+ ### §14.1 Step 2.7 — Worktree-Closed Pre-close Check
508
+
509
+ Before any close action, the script verifies no leftover story worktrees remain. Runs `git worktree list --porcelain` and matches paths under `.worktrees/`.
510
+
511
+ - **Enforcement (v2):** any leftover worktree halts the close (exit 1) with `Step 2.7 failed: leftover worktree at <path>`. Resolution: `git worktree remove` the abandoned worktree, or merge the in-flight story first.
512
+ - **Advisory (v1):** prints `Step 2.7 warning: leftover worktree at <path> (advisory in v1)` to stderr but continues.
513
+ - **Test seams:** `CLEARGATE_SKIP_WORKTREE_CHECK=1` (full bypass), `CLEARGATE_FORCE_WORKTREE_PATHS` (test injection).
514
+
515
+ ### §14.2 Step 2.8 — Sprint-Merged-to-Main Verify
516
+
517
+ Verifies the sprint branch (`sprint/S-NN`) tip is an ancestor of `main`. Runs `git merge-base --is-ancestor <sprint-tip> <main-tip>`.
518
+
519
+ - **Enforcement (v2):** unmerged sprint halts the close (exit 1) with `Step 2.8 failed: sprint branch not merged to main`. Resolution: merge `sprint/S-NN` into `main` first.
520
+ - **Advisory (v1):** prints `Step 2.8 warning: sprint branch unmerged (advisory in v1)` to stderr but continues.
521
+ - **Test seams:** `CLEARGATE_SKIP_MERGE_CHECK=1`, `CLEARGATE_FORCE_MERGE_STATUS=merged|unmerged`, `CLEARGATE_REPO_ROOT` (test override).
522
+
523
+ ### §14.3 Steps 6.5 / 6.6 / 6.7 — Post-close additions
524
+
525
+ Three non-fatal post-close steps fold into `improvement-suggestions.md`:
526
+ - **Step 6.5:** invokes `sprint_trends.mjs` (stub — full implementation deferred to CR-027).
527
+ - **Step 6.6:** scans for skill-candidate patterns via `suggest_improvements.mjs --skill-candidates`.
528
+ - **Step 6.7:** scans for stale flashcards via `suggest_improvements.mjs --flashcard-cleanup`.
529
+
530
+ Each step has its own skip seam (`CLEARGATE_SKIP_SPRINT_TRENDS=1`, `CLEARGATE_SKIP_SKILL_CANDIDATES=1`, `CLEARGATE_SKIP_FLASHCARD_CLEANUP=1`). Failures are non-fatal — printed as `Step 6.x warning:` and the pipeline continues.
531
+
532
+ ### §14.4 Step 8 — Verbose post-close handoff list
533
+
534
+ Prints a 6-item handoff to stdout summarizing: (1) commits in sprint, (2) merge state, (3) wiki ingest status, (4) flashcard count, (5) artifacts written, (6) next-sprint preflight reminder. The next-sprint ID is computed by parsing the numeric portion of the closing sprint and incrementing it (e.g., SPRINT-19 → SPRINT-20).
535
+
536
+ This step replaces the prior 3-line "pipeline complete" summary with explicit action-oriented output for the conversational orchestrator to relay to the human.
537
+
538
+ ### §14.5 `--allow-wiki-lint-debt` waiver flag
539
+
540
+ `cleargate sprint archive --allow-wiki-lint-debt` waives wiki-lint findings during archive. Reserved for cases where pre-existing wiki-lint debt blocks otherwise-clean archives (e.g., 34 broken-backlink findings carried since SPRINT-16). Without the flag, lint findings cause `archive` to roll back. The flag emits the verbatim Gherkin message `wiki-lint debt waived via --allow-wiki-lint-debt flag` and continues.
541
+
542
+ Reporter bundle cap raised from 80KB → 160KB (`MAX_BUNDLE_BYTES` in `prep_reporter_context.mjs`) to absorb heavy-strategy sprint reports. Override via `VITEST_MAX_FORKS`-style `MAX_BUNDLE_BYTES` future env.