cleargate 0.2.0 → 0.3.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 (113) hide show
  1. package/LICENSE +21 -0
  2. package/dist/MANIFEST.json +59 -17
  3. package/dist/admin-api/index.cjs +88 -1
  4. package/dist/admin-api/index.cjs.map +1 -1
  5. package/dist/admin-api/index.d.cts +105 -1
  6. package/dist/admin-api/index.d.ts +105 -1
  7. package/dist/admin-api/index.js +77 -1
  8. package/dist/admin-api/index.js.map +1 -1
  9. package/dist/bootstrap-root-FGWDICDT.js +130 -0
  10. package/dist/bootstrap-root-FGWDICDT.js.map +1 -0
  11. package/dist/chunk-OM4FAEA7.js +184 -0
  12. package/dist/chunk-OM4FAEA7.js.map +1 -0
  13. package/dist/cli.cjs +7995 -3984
  14. package/dist/cli.cjs.map +1 -1
  15. package/dist/cli.js +4062 -561
  16. package/dist/cli.js.map +1 -1
  17. package/dist/templates/cleargate-planning/.claude/agents/architect.md +72 -0
  18. package/dist/templates/cleargate-planning/.claude/agents/developer.md +45 -3
  19. package/dist/templates/cleargate-planning/.claude/agents/qa.md +7 -3
  20. package/dist/templates/cleargate-planning/.claude/agents/reporter.md +72 -75
  21. package/dist/templates/cleargate-planning/.claude/hooks/pending-task-sentinel.sh +204 -0
  22. package/dist/templates/cleargate-planning/.claude/hooks/pre-commit-surface-gate.sh +10 -0
  23. package/dist/templates/cleargate-planning/.claude/hooks/pre-commit-test-ratchet.sh +58 -0
  24. package/dist/templates/cleargate-planning/.claude/hooks/pre-commit.sh +19 -0
  25. package/dist/templates/cleargate-planning/.claude/hooks/session-start.sh +51 -0
  26. package/dist/templates/cleargate-planning/.claude/hooks/token-ledger.sh +1 -1
  27. package/dist/templates/cleargate-planning/.claude/settings.json +11 -0
  28. package/dist/templates/cleargate-planning/.claude/skills/flashcard/SKILL.md +31 -12
  29. package/dist/templates/cleargate-planning/.cleargate/FLASHCARD.md +2 -1
  30. package/dist/templates/cleargate-planning/.cleargate/config.example.yml +37 -0
  31. package/dist/templates/cleargate-planning/.cleargate/knowledge/cleargate-protocol.md +407 -0
  32. package/dist/templates/cleargate-planning/.cleargate/scripts/assert_story_files.mjs +146 -0
  33. package/dist/templates/cleargate-planning/.cleargate/scripts/close_sprint.mjs +250 -0
  34. package/dist/templates/cleargate-planning/.cleargate/scripts/constants.mjs +57 -0
  35. package/dist/templates/cleargate-planning/.cleargate/scripts/file_surface_diff.sh +320 -0
  36. package/dist/templates/cleargate-planning/.cleargate/scripts/gate-checks.json +15 -0
  37. package/dist/templates/cleargate-planning/.cleargate/scripts/init_gate_config.sh +38 -0
  38. package/dist/templates/cleargate-planning/.cleargate/scripts/init_sprint.mjs +187 -0
  39. package/dist/templates/cleargate-planning/.cleargate/scripts/pre_gate_common.sh +132 -0
  40. package/dist/templates/cleargate-planning/.cleargate/scripts/pre_gate_runner.sh +307 -0
  41. package/dist/templates/cleargate-planning/.cleargate/scripts/prefill_report.mjs +280 -0
  42. package/dist/templates/cleargate-planning/.cleargate/scripts/run_script.sh +123 -0
  43. package/dist/templates/cleargate-planning/.cleargate/scripts/state.schema.json +110 -0
  44. package/dist/templates/cleargate-planning/.cleargate/scripts/suggest_improvements.mjs +247 -0
  45. package/dist/templates/cleargate-planning/.cleargate/scripts/surface-whitelist.txt +27 -0
  46. package/dist/templates/cleargate-planning/.cleargate/scripts/test/test_assert_story_files.sh +261 -0
  47. package/dist/templates/cleargate-planning/.cleargate/scripts/test/test_file_surface.sh +210 -0
  48. package/dist/templates/cleargate-planning/.cleargate/scripts/test/test_flashcard_gate.sh +190 -0
  49. package/dist/templates/cleargate-planning/.cleargate/scripts/test/test_test_ratchet.sh +327 -0
  50. package/dist/templates/cleargate-planning/.cleargate/scripts/test_ratchet.mjs +261 -0
  51. package/dist/templates/cleargate-planning/.cleargate/scripts/update_state.mjs +154 -0
  52. package/dist/templates/cleargate-planning/.cleargate/scripts/validate_bounce_readiness.mjs +111 -0
  53. package/dist/templates/cleargate-planning/.cleargate/scripts/validate_state.mjs +164 -0
  54. package/dist/templates/cleargate-planning/.cleargate/templates/Bug.md +9 -0
  55. package/dist/templates/cleargate-planning/.cleargate/templates/CR.md +9 -0
  56. package/dist/templates/cleargate-planning/.cleargate/templates/Sprint Plan Template.md +29 -3
  57. package/dist/templates/cleargate-planning/.cleargate/templates/epic.md +9 -0
  58. package/dist/templates/cleargate-planning/.cleargate/templates/proposal.md +9 -0
  59. package/dist/templates/cleargate-planning/.cleargate/templates/sprint_context.md +42 -0
  60. package/dist/templates/cleargate-planning/.cleargate/templates/sprint_report.md +175 -0
  61. package/dist/templates/cleargate-planning/.cleargate/templates/story.md +29 -0
  62. package/dist/templates/cleargate-planning/CLAUDE.md +3 -0
  63. package/dist/templates/cleargate-planning/MANIFEST.json +59 -17
  64. package/dist/whoami-CX7CXJD5.js +76 -0
  65. package/dist/whoami-CX7CXJD5.js.map +1 -0
  66. package/package.json +6 -2
  67. package/templates/cleargate-planning/.claude/agents/architect.md +72 -0
  68. package/templates/cleargate-planning/.claude/agents/developer.md +45 -3
  69. package/templates/cleargate-planning/.claude/agents/qa.md +7 -3
  70. package/templates/cleargate-planning/.claude/agents/reporter.md +72 -75
  71. package/templates/cleargate-planning/.claude/hooks/pending-task-sentinel.sh +204 -0
  72. package/templates/cleargate-planning/.claude/hooks/pre-commit-surface-gate.sh +10 -0
  73. package/templates/cleargate-planning/.claude/hooks/pre-commit-test-ratchet.sh +58 -0
  74. package/templates/cleargate-planning/.claude/hooks/pre-commit.sh +19 -0
  75. package/templates/cleargate-planning/.claude/hooks/session-start.sh +51 -0
  76. package/templates/cleargate-planning/.claude/hooks/token-ledger.sh +1 -1
  77. package/templates/cleargate-planning/.claude/settings.json +11 -0
  78. package/templates/cleargate-planning/.claude/skills/flashcard/SKILL.md +31 -12
  79. package/templates/cleargate-planning/.cleargate/FLASHCARD.md +2 -1
  80. package/templates/cleargate-planning/.cleargate/config.example.yml +37 -0
  81. package/templates/cleargate-planning/.cleargate/knowledge/cleargate-protocol.md +407 -0
  82. package/templates/cleargate-planning/.cleargate/scripts/assert_story_files.mjs +146 -0
  83. package/templates/cleargate-planning/.cleargate/scripts/close_sprint.mjs +250 -0
  84. package/templates/cleargate-planning/.cleargate/scripts/constants.mjs +57 -0
  85. package/templates/cleargate-planning/.cleargate/scripts/file_surface_diff.sh +320 -0
  86. package/templates/cleargate-planning/.cleargate/scripts/gate-checks.json +15 -0
  87. package/templates/cleargate-planning/.cleargate/scripts/init_gate_config.sh +38 -0
  88. package/templates/cleargate-planning/.cleargate/scripts/init_sprint.mjs +187 -0
  89. package/templates/cleargate-planning/.cleargate/scripts/pre_gate_common.sh +132 -0
  90. package/templates/cleargate-planning/.cleargate/scripts/pre_gate_runner.sh +307 -0
  91. package/templates/cleargate-planning/.cleargate/scripts/prefill_report.mjs +280 -0
  92. package/templates/cleargate-planning/.cleargate/scripts/run_script.sh +123 -0
  93. package/templates/cleargate-planning/.cleargate/scripts/state.schema.json +110 -0
  94. package/templates/cleargate-planning/.cleargate/scripts/suggest_improvements.mjs +247 -0
  95. package/templates/cleargate-planning/.cleargate/scripts/surface-whitelist.txt +27 -0
  96. package/templates/cleargate-planning/.cleargate/scripts/test/test_assert_story_files.sh +261 -0
  97. package/templates/cleargate-planning/.cleargate/scripts/test/test_file_surface.sh +210 -0
  98. package/templates/cleargate-planning/.cleargate/scripts/test/test_flashcard_gate.sh +190 -0
  99. package/templates/cleargate-planning/.cleargate/scripts/test/test_test_ratchet.sh +327 -0
  100. package/templates/cleargate-planning/.cleargate/scripts/test_ratchet.mjs +261 -0
  101. package/templates/cleargate-planning/.cleargate/scripts/update_state.mjs +154 -0
  102. package/templates/cleargate-planning/.cleargate/scripts/validate_bounce_readiness.mjs +111 -0
  103. package/templates/cleargate-planning/.cleargate/scripts/validate_state.mjs +164 -0
  104. package/templates/cleargate-planning/.cleargate/templates/Bug.md +9 -0
  105. package/templates/cleargate-planning/.cleargate/templates/CR.md +9 -0
  106. package/templates/cleargate-planning/.cleargate/templates/Sprint Plan Template.md +29 -3
  107. package/templates/cleargate-planning/.cleargate/templates/epic.md +9 -0
  108. package/templates/cleargate-planning/.cleargate/templates/proposal.md +9 -0
  109. package/templates/cleargate-planning/.cleargate/templates/sprint_context.md +42 -0
  110. package/templates/cleargate-planning/.cleargate/templates/sprint_report.md +175 -0
  111. package/templates/cleargate-planning/.cleargate/templates/story.md +29 -0
  112. package/templates/cleargate-planning/CLAUDE.md +3 -0
  113. package/templates/cleargate-planning/MANIFEST.json +59 -17
@@ -0,0 +1,175 @@
1
+ ---
2
+ sprint_id: "SPRINT-NN"
3
+ status: "Draft"
4
+ generated_at: "<ISO-8601>"
5
+ generated_by: "Reporter agent"
6
+ template_version: 1
7
+ ---
8
+
9
+ <!-- Sprint Report v2 Template — template_version: 1 -->
10
+ <!-- Event-type vocabulary (STORY-013-05 / protocol §§16–17):
11
+ User-Review: UR:review-feedback | UR:bug
12
+ Change-Request: CR:bug | CR:spec-clarification | CR:scope-change | CR:approach-change
13
+ Circuit-breaker: test-pattern | spec-gap | environment
14
+ These tokens appear verbatim in §2 CR Change Log and §3 Execution Metrics tallies. -->
15
+
16
+ # SPRINT-<NN> Report: <Sprint Title>
17
+
18
+ **Status:** Shipped | Partial | Blocked
19
+ **Window:** YYYY-MM-DD to YYYY-MM-DD (N calendar days)
20
+ **Stories:** N planned / M shipped / K carried over
21
+
22
+ ---
23
+
24
+ ## §1 What Was Delivered
25
+
26
+ ### User-Facing Capabilities
27
+ <!-- One bullet per user-visible outcome, grouped by business goal. Do NOT list stories here. -->
28
+ - <capability>
29
+
30
+ ### Internal / Framework Improvements
31
+ <!-- Infrastructure, tooling, or agent-contract changes not visible to end users. -->
32
+ - <improvement>
33
+
34
+ ### Carried Over
35
+ <!-- Stories that did not reach Done/Escalated/Parking Lot. If none, state "None." -->
36
+ - None
37
+
38
+ ---
39
+
40
+ ## §2 Story Results + CR Change Log
41
+
42
+ <!-- One block per story. For bounces, list each round-trip as a CR event with the exact token.
43
+ CR event types: CR:bug | CR:spec-clarification | CR:scope-change | CR:approach-change
44
+ UR event types: UR:review-feedback | UR:bug
45
+ Each CR:bug and UR:bug counts toward Bug-Fix Tax (§3). CR:scope-change increments arch_bounces. -->
46
+
47
+ ### STORY-NNN-NN: <Title>
48
+ - **Status:** Done | Escalated | Parking Lot | Carried Over
49
+ - **Complexity:** L<n>
50
+ - **Commit:** `<sha>`
51
+ - **Bounce count:** qa=N arch=N total=N
52
+ - **CR Change Log:**
53
+ | # | Event type | Description | Counter delta |
54
+ |---|---|---|---|
55
+ | 1 | CR:bug | <description> | qa_bounces +1 |
56
+ - **UR Events:**
57
+ | # | Event type | Feedback | Tax impact |
58
+ |---|---|---|---|
59
+ | 1 | UR:review-feedback | <feedback> | none (enhancement) |
60
+
61
+ ---
62
+
63
+ ## §3 Execution Metrics
64
+
65
+ <!-- Tallies use the locked event-type vocabulary:
66
+ Bug-Fix Tax = (CR:bug count + UR:bug count) / total story count × 100
67
+ Enhancement Tax = UR:review-feedback count / total story count × 100
68
+ First-pass success rate = stories with qa_bounces=0 AND arch_bounces=0 / total stories × 100
69
+ Token divergence: compare ledger-primary vs task-notification-tertiary; flag if delta >20% -->
70
+
71
+ | Metric | Value |
72
+ |---|---|
73
+ | Stories planned | N |
74
+ | Stories shipped (Done) | N |
75
+ | Stories escalated | N |
76
+ | Stories carried over | N |
77
+ | Total QA bounces | N |
78
+ | Total Arch bounces | N |
79
+ | CR:bug events | N |
80
+ | CR:spec-clarification events | N |
81
+ | CR:scope-change events | N |
82
+ | CR:approach-change events | N |
83
+ | UR:bug events | N |
84
+ | UR:review-feedback events | N |
85
+ | Circuit-breaker fires: test-pattern | N |
86
+ | Circuit-breaker fires: spec-gap | N |
87
+ | Circuit-breaker fires: environment | N |
88
+ | **Bug-Fix Tax** | N% |
89
+ | **Enhancement Tax** | N% |
90
+ | **First-pass success rate** | N% |
91
+ | Token source: ledger-primary | N tokens |
92
+ | Token source: story-doc-secondary | N tokens |
93
+ | Token source: task-notification-tertiary | N tokens |
94
+ | Token divergence (ledger vs task-notif) | N% |
95
+ | Token divergence flag (>20%) | YES / NO |
96
+
97
+ ---
98
+
99
+ ## §4 Lessons
100
+
101
+ <!-- Flashcards added during this sprint window, grouped by tag.
102
+ Preserve the stale-detection pass from reporter.md §5b — stale-candidate symbols
103
+ from each card are surfaced here for human approval. Do NOT modify FLASHCARD.md. -->
104
+
105
+ ### New Flashcards (Sprint Window)
106
+
107
+ | Date | Tags | Lesson |
108
+ |---|---|---|
109
+ | YYYY-MM-DD | #tag | <lesson> |
110
+
111
+ ### Flashcard Audit (Stale Candidates)
112
+ <!-- For each active card with no [S]/[R] marker, symbols extracted and grepped.
113
+ Candidates below have ALL extracted symbols absent from the current repo. -->
114
+
115
+ | Card (date · lead-tag · lesson head) | Missing symbols | Proposed marker |
116
+ |---|---|---|
117
+
118
+ If zero candidates: No stale flashcards detected.
119
+
120
+ ### Supersede Candidates
121
+ <!-- Newer cards whose lesson directly contradicts an older card's advice. -->
122
+
123
+ | Newer card | Older card | Proposed marker for older |
124
+ |---|---|---|
125
+
126
+ ---
127
+
128
+ ## §5 Framework Self-Assessment
129
+
130
+ <!-- Rate each dimension: Green (working well) / Yellow (friction) / Red (blocking).
131
+ "Tooling" subsection MUST include token-divergence finding if §3 divergence flag = YES. -->
132
+
133
+ ### Templates
134
+ | Item | Rating | Notes |
135
+ |---|---|---|
136
+ | Story template completeness | Green/Yellow/Red | |
137
+ | Sprint Plan Template usability | Green/Yellow/Red | |
138
+ | Sprint Report template (this one) | Green/Yellow/Red | |
139
+
140
+ ### Handoffs
141
+ | Item | Rating | Notes |
142
+ |---|---|---|
143
+ | Architect → Developer brief quality | Green/Yellow/Red | |
144
+ | Developer → QA artifact completeness | Green/Yellow/Red | |
145
+ | QA → Orchestrator kickback clarity | Green/Yellow/Red | |
146
+
147
+ ### Skills
148
+ | Item | Rating | Notes |
149
+ |---|---|---|
150
+ | Flashcard gate adherence | Green/Yellow/Red | |
151
+ | Adjacent-implementation reuse rate | Green/Yellow/Red | |
152
+
153
+ ### Process
154
+ | Item | Rating | Notes |
155
+ |---|---|---|
156
+ | Bounce cap respected | Green/Yellow/Red | |
157
+ | Three-surface landing compliance | Green/Yellow/Red | |
158
+ | Circuit-breaker fires (if any) | Green/Yellow/Red | |
159
+
160
+ ### Tooling
161
+ | Item | Rating | Notes |
162
+ |---|---|---|
163
+ | run_script.sh diagnostic coverage | Green/Yellow/Red | |
164
+ | Token ledger completeness | Green/Yellow/Red | |
165
+ | Token divergence finding | Green/Yellow/Red | If §3 divergence >20%: Red — ledger=N task-notif=N delta=N% |
166
+
167
+ ---
168
+
169
+ ## §6 Change Log
170
+
171
+ <!-- Append one line per material revision to this report after initial generation. -->
172
+
173
+ | Date | Author | Change |
174
+ |---|---|---|
175
+ | YYYY-MM-DD | Reporter agent | Initial generation |
@@ -15,6 +15,22 @@ L2: Standard — 2-3 files, known pattern, ~2-4hr (default)
15
15
  L3: Complex — Cross-cutting, spike may be needed, ~1-2 days
16
16
  L4: Uncertain — Requires probing/spiking, >2 days
17
17
 
18
+ Granularity Rubric (run this check BEFORE emitting a story during epic-decomposition):
19
+ A candidate story is too big — emit two stories instead, with consecutive IDs (e.g. STORY-007-03 and STORY-007-04, never 03a/03b) — if ANY signal trips:
20
+ • §1.2 Detailed Requirements joins unrelated user goals with "and also" / "additionally".
21
+ • §2.1 Gherkin would need >5 scenarios covering unrelated behaviors.
22
+ • §3.1 Files-to-touch span unrelated subsystems (e.g. API + UI + migration in one story).
23
+ • Complexity would land at L4 (>2 days). L4 is a planning smell — split, or carve out a spike as its own story.
24
+ • `complexity_label: L3` AND `expected_bounce_exposure: high`. L3+high consistently hits developer-agent wall-time limits (observed in SPRINT-09 on STORY-013-02/03/04, all Sonnet 4.6 stream-timeouts). Split into two L2 stories OR escalate the single L3 to Opus at dispatch — the decomposition default is to split.
25
+ Also split the inverse: two candidate stories that each touch the same 1-2 files with overlapping scenarios should merge into one L1/L2.
26
+ At epic-decomposition time there are no remote IDs yet — splits and merges are free. Prefer two focused L1/L2 stories over one L3. Prefer L3 over L4.
27
+ When the rubric is ambiguous, surface the decision to the human as a one-liner ("candidate covers A+B — split into X and Y?") rather than guessing.
28
+
29
+ §0.1 v2 Decomposition Signals:
30
+ `parallel_eligible`: "y" if this story can run concurrently with other stories in the same milestone; "n" if it has a strict predecessor dependency. Default "y". Set by Architect during Sprint Design Review.
31
+ `expected_bounce_exposure`: "low" | "med" | "high" — predicted re-work risk derived from §2.1 scenario count + §3 file-count + ambiguity level. Default "low". Set by Architect. Used by orchestrator to sequence high-exposure stories before low-exposure ones in a v2 sprint to surface risk early.
32
+ Both fields are v2-only signals. Under v1 sprints they are informational; defaults apply for stories authored before SPRINT-09.
33
+
18
34
  Do NOT output these instructions.
19
35
  </instructions>
20
36
 
@@ -26,6 +42,8 @@ ambiguity: "🔴 High"
26
42
  context_source: "PROPOSAL-{ID}.md"
27
43
  actor: "{Persona Name}"
28
44
  complexity_label: "L2"
45
+ parallel_eligible: "y"
46
+ expected_bounce_exposure: "low"
29
47
  created_at: "2026-04-17T00:00:00Z"
30
48
  updated_at: "2026-04-17T00:00:00Z"
31
49
  created_at_version: "strategy-phase-pre-init"
@@ -42,6 +60,15 @@ cached_gate_result:
42
60
  pass: null
43
61
  failing_criteria: []
44
62
  last_gate_check: null
63
+ # Sync attribution (EPIC-010). Optional; stamped by `cleargate push` / `cleargate pull`.
64
+ pushed_by: null # STORY-010-07 writer / STORY-010-04 reader
65
+ pushed_at: null # STORY-010-07 writer / STORY-010-04 reader
66
+ last_pulled_by: null # STORY-010-04 writer / STORY-010-03 reader
67
+ last_pulled_at: null # STORY-010-04 writer / STORY-010-03 reader
68
+ last_remote_update: null # STORY-010-02 writer (from MCP) / STORY-010-03 reader
69
+ source: "local-authored" # STORY-010-05 flips to "remote-authored" on intake
70
+ last_synced_status: null # STORY-010-04 writer; required for conflict-detector rule 6
71
+ last_synced_body_sha: null # STORY-010-04 writer; sha256 of body at last sync
45
72
  ---
46
73
 
47
74
  # STORY-{EpicID}-{StoryID}: {Story Name}
@@ -85,6 +112,8 @@ Feature: {Story Name}
85
112
 
86
113
  ### 3.1 Context & Files
87
114
 
115
+ > **v2 gate input:** under v2 execution mode, this table is a pre-commit gate input (protocol §20). Every file staged in this story's commit must appear in the Value column, or be covered by `.cleargate/scripts/surface-whitelist.txt`. Non-path rows (e.g. "Mirrors", "New Files Needed: Yes/No") are ignored by the parser.
116
+
88
117
  | Item | Value |
89
118
  |---|---|
90
119
  | Primary File | `{filepath/to/main/component.ts}` |
@@ -24,6 +24,7 @@ This repository uses **ClearGate** — a standalone planning framework for AI co
24
24
  - Use the templates in `.cleargate/templates/` (`proposal.md`, `epic.md`, `story.md`, `CR.md`, `Bug.md`, `Sprint Plan Template.md`, `initiative.md`).
25
25
  - Save drafts to `.cleargate/delivery/pending-sync/{TYPE}-{ID}-{Name}.md`.
26
26
  - After `cleargate_push_item` returns a Remote ID, update the frontmatter AND move the file to `.cleargate/delivery/archive/` — these two happen atomically, never one without the other.
27
+ - **Story granularity.** When decomposing an epic into stories, run the Granularity Rubric at the top of `story.md`. If a candidate story trips any signal (unrelated goals joined, >5 Gherkin scenarios, subsystems span, L4 complexity), emit two stories with consecutive IDs instead. Splits and merges are free at decomposition time — no remote IDs exist yet.
27
28
 
28
29
  **Four-agent loop (roles in `.claude/agents/`):**
29
30
  - `architect.md` — one plan per milestone; no production code.
@@ -35,6 +36,8 @@ This repository uses **ClearGate** — a standalone planning framework for AI co
35
36
 
36
37
  **Support infrastructure.** Flashcard protocol: `.claude/skills/flashcard/SKILL.md`. Token-ledger hook: `.claude/hooks/token-ledger.sh`, wired via `.claude/settings.json` (SubagentStop) — auto-logs agent cost per sprint for the Reporter.
37
38
 
39
+ **Cross-project orchestration.** When running an orchestrator from one project's repo against another project's sprint tree, export `ORCHESTRATOR_PROJECT_DIR=/absolute/path/to/target/repo` in the shell before launching the session. Overrides `CLAUDE_PROJECT_DIR`; sentinel + ledger writes route into the target's `.cleargate/sprint-runs/` tree. If the target has no `.cleargate/sprint-runs/.active` sentinel, writes land in the target's `_off-sprint` bucket — not the orchestrator's own repo.
40
+
38
41
  **Project overrides.** Content OUTSIDE this `<!-- CLEARGATE:START -->...<!-- CLEARGATE:END -->` block takes precedence where it conflicts with ClearGate defaults.
39
42
 
40
43
  **Scope reminder.** ClearGate is a *planning* framework. It scaffolds how work gets planned and how the four-agent loop runs. It does not replace your project's build system, CI, test runner, or deployment tooling.
@@ -1,10 +1,10 @@
1
1
  {
2
- "cleargate_version": "0.2.0",
3
- "generated_at": "2026-04-19T16:46:17.751Z",
2
+ "cleargate_version": "0.3.0",
3
+ "generated_at": "2026-04-24T22:02:35.096Z",
4
4
  "files": [
5
5
  {
6
6
  "path": ".claude/agents/architect.md",
7
- "sha256": "0e0e545198cfff827ea453195414d884aec5cb5413e07dc1396820aaa2014f97",
7
+ "sha256": "c9424894549b270b73c1c95145b7bb8d406cadd2057c47f8e90bf74ce1f3cda7",
8
8
  "tier": "agent",
9
9
  "overwrite_policy": "always",
10
10
  "preserve_on_uninstall": false
@@ -32,28 +32,56 @@
32
32
  },
33
33
  {
34
34
  "path": ".claude/agents/developer.md",
35
- "sha256": "bd9bcd8ce222effa248ff489939a7e37aa8e151675311fc7b374533c09ef43ee",
35
+ "sha256": "ea54db76bcd017526f2b48e05b167cb87251273aa5fd3da6bec3013c207c72fb",
36
36
  "tier": "agent",
37
37
  "overwrite_policy": "always",
38
38
  "preserve_on_uninstall": false
39
39
  },
40
40
  {
41
41
  "path": ".claude/agents/qa.md",
42
- "sha256": "9345a4f294cbc327ecc169a51446e2321b53b14917e7880f7e7b374a28ac3751",
42
+ "sha256": "e753d294d6060ace626878220db02a0595126bc7baa52526e5d1576b163f04d0",
43
43
  "tier": "agent",
44
44
  "overwrite_policy": "always",
45
45
  "preserve_on_uninstall": false
46
46
  },
47
47
  {
48
48
  "path": ".claude/agents/reporter.md",
49
- "sha256": "a83497454969e81015e7d0415e86a3bcf48cafb13741ed7f18b603f9e54cfb80",
49
+ "sha256": "5819d6f932ebd25a48e6f91a2e6227726f6d4d15968622728ec22a4ed7caa622",
50
50
  "tier": "agent",
51
51
  "overwrite_policy": "always",
52
52
  "preserve_on_uninstall": false
53
53
  },
54
+ {
55
+ "path": ".claude/hooks/pending-task-sentinel.sh",
56
+ "sha256": "8204286b19287c490cc09014b0c87e2b2686e6bd120393b7165895d215d6b49a",
57
+ "tier": "hook",
58
+ "overwrite_policy": "always",
59
+ "preserve_on_uninstall": false
60
+ },
61
+ {
62
+ "path": ".claude/hooks/pre-commit-surface-gate.sh",
63
+ "sha256": "a58f3b3c3dbb615a14bf6e2355f5122e80a5cb1e8ef9442648324f3124723ee3",
64
+ "tier": "hook",
65
+ "overwrite_policy": "always",
66
+ "preserve_on_uninstall": false
67
+ },
68
+ {
69
+ "path": ".claude/hooks/pre-commit-test-ratchet.sh",
70
+ "sha256": "67232d9d94817e512b2d66e020605b59e9795eb4a04005edf7ea75bf9a324848",
71
+ "tier": "hook",
72
+ "overwrite_policy": "always",
73
+ "preserve_on_uninstall": false
74
+ },
75
+ {
76
+ "path": ".claude/hooks/pre-commit.sh",
77
+ "sha256": "90260116726bfc88191fda353d038445d5838e7cd811db67029b5555f2dbc555",
78
+ "tier": "hook",
79
+ "overwrite_policy": "always",
80
+ "preserve_on_uninstall": false
81
+ },
54
82
  {
55
83
  "path": ".claude/hooks/session-start.sh",
56
- "sha256": "b851f34c8e40eb10d6dc71c8dbd29282f74afbaad7e823306a3e2a52a15fe21f",
84
+ "sha256": "a611286330f36e5d0bbdc5642e9409ffbfc569cc3d0b370918e973b545c50741",
57
85
  "tier": "hook",
58
86
  "overwrite_policy": "always",
59
87
  "preserve_on_uninstall": false
@@ -67,21 +95,21 @@
67
95
  },
68
96
  {
69
97
  "path": ".claude/hooks/token-ledger.sh",
70
- "sha256": "918ae12960f2c657c7ad1b0b7bc95438a4339d220f75e4abf5259ecabe8a2ca3",
98
+ "sha256": "be2b2eaa02cc30387601285160d6fe1c90ea76b37ec6cae2b7c9537f66f22783",
71
99
  "tier": "hook",
72
100
  "overwrite_policy": "always",
73
101
  "preserve_on_uninstall": false
74
102
  },
75
103
  {
76
104
  "path": ".claude/settings.json",
77
- "sha256": "1f95f5468db19ffebe75aec1c35489a26aae64eae256d246a6a88cf34581f4bb",
105
+ "sha256": "a6d63ac3d01592b7d2ed1af45067606d535349dc27a51740f744c2fd2592a0cb",
78
106
  "tier": "cli-config",
79
107
  "overwrite_policy": "merge-3way",
80
108
  "preserve_on_uninstall": false
81
109
  },
82
110
  {
83
111
  "path": ".claude/skills/flashcard/SKILL.md",
84
- "sha256": "56d6bf3797516ac26ada15876ef2f4cf43842b3af7300abef502a75bd177639e",
112
+ "sha256": "4c0fe5bb74697e1eb1f37203ff44b8e6a800f024a2f8c3fc8542aa206cd2c777",
85
113
  "tier": "skill",
86
114
  "overwrite_policy": "always",
87
115
  "preserve_on_uninstall": false
@@ -95,7 +123,7 @@
95
123
  },
96
124
  {
97
125
  "path": ".cleargate/knowledge/cleargate-protocol.md",
98
- "sha256": "fc67af361fbd11137404d3db1034ceb5f876cd8de0e4f90e208ef19ab89072a6",
126
+ "sha256": "4316444ad452e83a2c9387ad6ad96ef4e4511b1face4b30976a912c0f28866f6",
99
127
  "tier": "protocol",
100
128
  "overwrite_policy": "merge-3way",
101
129
  "preserve_on_uninstall": false
@@ -109,21 +137,21 @@
109
137
  },
110
138
  {
111
139
  "path": ".cleargate/templates/Bug.md",
112
- "sha256": "9f32165a709b30bc8794ef96c6a7220ef6484b47c30fb955e1c1c8e892698bcc",
140
+ "sha256": "3ba6e72bd2bc01cf8d0ea06390f8ea511bef3a421a33c48de033051f844dfa0e",
113
141
  "tier": "template",
114
142
  "overwrite_policy": "merge-3way",
115
143
  "preserve_on_uninstall": false
116
144
  },
117
145
  {
118
146
  "path": ".cleargate/templates/CR.md",
119
- "sha256": "55ea7a8a25c6b3d37103065dd91eb11378a78a36375d274406d376f4c35af3ef",
147
+ "sha256": "58ea4badb03991d119f8aa8870992a8239c8df6ad198e0d9ca04a805756e4bac",
120
148
  "tier": "template",
121
149
  "overwrite_policy": "merge-3way",
122
150
  "preserve_on_uninstall": false
123
151
  },
124
152
  {
125
153
  "path": ".cleargate/templates/epic.md",
126
- "sha256": "1847f1e7cedd631d4ef2aaf7ef67745e88b2ff76389b04bad6fa1f1edf973442",
154
+ "sha256": "6c85e4c9602af657e6778af9009a67936c27e47331479d0c246cdf1242177c82",
127
155
  "tier": "template",
128
156
  "overwrite_policy": "merge-3way",
129
157
  "preserve_on_uninstall": false
@@ -137,21 +165,35 @@
137
165
  },
138
166
  {
139
167
  "path": ".cleargate/templates/proposal.md",
140
- "sha256": "1a0822edf6f29a1f8d34e2fab1180b33a365edd92d84b3fc191f239a751ba373",
168
+ "sha256": "e8055dac81ecf94d01fe610e8cdaf4fa73a2f8d9953e4db90b91a20a8c81460d",
141
169
  "tier": "template",
142
170
  "overwrite_policy": "merge-3way",
143
171
  "preserve_on_uninstall": false
144
172
  },
145
173
  {
146
174
  "path": ".cleargate/templates/Sprint Plan Template.md",
147
- "sha256": "6e60b697a136edb89bc19cc40caa1bec51687366b8e1b35a6554d0072736591b",
175
+ "sha256": "9f87539691b910193c55fb9a637975de738dda181baa7e68fc48297993389613",
176
+ "tier": "template",
177
+ "overwrite_policy": "merge-3way",
178
+ "preserve_on_uninstall": false
179
+ },
180
+ {
181
+ "path": ".cleargate/templates/sprint_context.md",
182
+ "sha256": "56c8c401b56d4c654dc41a19bd524f1b8860a8006cc3cd90e784d101c3d7721a",
183
+ "tier": "template",
184
+ "overwrite_policy": "merge-3way",
185
+ "preserve_on_uninstall": false
186
+ },
187
+ {
188
+ "path": ".cleargate/templates/sprint_report.md",
189
+ "sha256": "5f3dfdbc7a1dde26758871b358be00d543e9669ab34ca3c7ead765ee6e182bcb",
148
190
  "tier": "template",
149
191
  "overwrite_policy": "merge-3way",
150
192
  "preserve_on_uninstall": false
151
193
  },
152
194
  {
153
195
  "path": ".cleargate/templates/story.md",
154
- "sha256": "3e722c51f706177f08c16b56ef984090c7841102f70384bb47d5442846991fe8",
196
+ "sha256": "266b7e2b0526c4fe37620baf9344521e98ee5e7363661d390ef90068798f9bfe",
155
197
  "tier": "template",
156
198
  "overwrite_policy": "merge-3way",
157
199
  "preserve_on_uninstall": false
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ AcquireError,
4
+ acquireAccessToken,
5
+ loadConfig,
6
+ requireMcpUrl
7
+ } from "./chunk-OM4FAEA7.js";
8
+ import "./chunk-4V4QABOJ.js";
9
+
10
+ // src/commands/whoami.ts
11
+ import { Buffer } from "buffer";
12
+ function decodeJwtPayload(jwt) {
13
+ const parts = jwt.split(".");
14
+ if (parts.length !== 3) return null;
15
+ try {
16
+ const json = Buffer.from(parts[1], "base64url").toString("utf8");
17
+ return JSON.parse(json);
18
+ } catch {
19
+ return null;
20
+ }
21
+ }
22
+ async function whoamiHandler(opts) {
23
+ const stdout = opts.stdout ?? ((s) => process.stdout.write(s));
24
+ const stderr = opts.stderr ?? ((s) => process.stderr.write(s));
25
+ const exit = opts.exit ?? ((c) => process.exit(c));
26
+ const cfg = loadConfig({ flags: { profile: opts.profile, mcpUrl: opts.mcpUrlFlag } });
27
+ let mcpUrl;
28
+ try {
29
+ mcpUrl = requireMcpUrl(cfg);
30
+ } catch (err) {
31
+ stderr(`cleargate: ${err instanceof Error ? err.message : String(err)}
32
+ `);
33
+ exit(5);
34
+ return;
35
+ }
36
+ let accessToken;
37
+ try {
38
+ accessToken = await acquireAccessToken({
39
+ mcpUrl,
40
+ profile: opts.profile,
41
+ fetch: opts.fetch
42
+ });
43
+ } catch (err) {
44
+ if (err instanceof AcquireError) {
45
+ stderr(`cleargate: ${err.message}
46
+ `);
47
+ exit(err.code === "transport" ? 2 : 5);
48
+ return;
49
+ }
50
+ stderr(`cleargate: internal error: ${err instanceof Error ? err.message : String(err)}
51
+ `);
52
+ exit(99);
53
+ return;
54
+ }
55
+ const claims = decodeJwtPayload(accessToken);
56
+ if (!claims) {
57
+ stderr("cleargate: access token received but could not decode payload.\n");
58
+ exit(7);
59
+ return;
60
+ }
61
+ stdout(
62
+ [
63
+ `mcp_url: ${mcpUrl}`,
64
+ `profile: ${opts.profile}`,
65
+ `member_id: ${claims.sub ?? "?"}`,
66
+ `project_id: ${claims.project_id ?? "?"}`,
67
+ `role: ${claims.role ?? "?"}`,
68
+ `expires_at: ${typeof claims.exp === "number" ? new Date(claims.exp * 1e3).toISOString() : "?"}`,
69
+ ""
70
+ ].join("\n")
71
+ );
72
+ }
73
+ export {
74
+ whoamiHandler
75
+ };
76
+ //# sourceMappingURL=whoami-CX7CXJD5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/whoami.ts"],"sourcesContent":["/**\n * cleargate whoami — smoke-test command that proves the stored refresh token\n * can be exchanged for a short-lived MCP access token, decodes the JWT payload\n * (no verification — just introspection), and prints identity fields.\n *\n * This is the first command to exercise the acquireAccessToken flow end-to-end;\n * sync/pull/push will be wired in follow-up stories.\n */\nimport { Buffer } from 'node:buffer';\nimport { loadConfig, requireMcpUrl } from '../config.js';\nimport { acquireAccessToken, AcquireError } from '../auth/acquire.js';\n\nexport interface WhoamiOptions {\n profile: string;\n mcpUrlFlag?: string;\n /** Test seam: replaces globalThis.fetch */\n fetch?: typeof globalThis.fetch;\n stdout?: (s: string) => void;\n stderr?: (s: string) => void;\n exit?: (code: number) => never;\n}\n\nfunction decodeJwtPayload(jwt: string): Record<string, unknown> | null {\n const parts = jwt.split('.');\n if (parts.length !== 3) return null;\n try {\n const json = Buffer.from(parts[1]!, 'base64url').toString('utf8');\n return JSON.parse(json);\n } catch {\n return null;\n }\n}\n\nexport async function whoamiHandler(opts: WhoamiOptions): Promise<void> {\n const stdout = opts.stdout ?? ((s) => process.stdout.write(s));\n const stderr = opts.stderr ?? ((s) => process.stderr.write(s));\n const exit = opts.exit ?? ((c: number): never => process.exit(c));\n\n const cfg = loadConfig({ flags: { profile: opts.profile, mcpUrl: opts.mcpUrlFlag } });\n let mcpUrl: string;\n try {\n mcpUrl = requireMcpUrl(cfg);\n } catch (err) {\n stderr(`cleargate: ${err instanceof Error ? err.message : String(err)}\\n`);\n exit(5);\n return;\n }\n\n let accessToken: string;\n try {\n accessToken = await acquireAccessToken({\n mcpUrl,\n profile: opts.profile,\n fetch: opts.fetch,\n });\n } catch (err) {\n if (err instanceof AcquireError) {\n stderr(`cleargate: ${err.message}\\n`);\n exit(err.code === 'transport' ? 2 : 5);\n return;\n }\n stderr(`cleargate: internal error: ${err instanceof Error ? err.message : String(err)}\\n`);\n exit(99);\n return;\n }\n\n const claims = decodeJwtPayload(accessToken);\n if (!claims) {\n stderr('cleargate: access token received but could not decode payload.\\n');\n exit(7);\n return;\n }\n\n stdout(\n [\n `mcp_url: ${mcpUrl}`,\n `profile: ${opts.profile}`,\n `member_id: ${claims.sub ?? '?'}`,\n `project_id: ${claims.project_id ?? '?'}`,\n `role: ${claims.role ?? '?'}`,\n `expires_at: ${typeof claims.exp === 'number' ? new Date(claims.exp * 1000).toISOString() : '?'}`,\n '',\n ].join('\\n'),\n );\n}\n"],"mappings":";;;;;;;;;;AAQA,SAAS,cAAc;AAcvB,SAAS,iBAAiB,KAA6C;AACrE,QAAM,QAAQ,IAAI,MAAM,GAAG;AAC3B,MAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,MAAI;AACF,UAAM,OAAO,OAAO,KAAK,MAAM,CAAC,GAAI,WAAW,EAAE,SAAS,MAAM;AAChE,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,cAAc,MAAoC;AACtE,QAAM,SAAS,KAAK,WAAW,CAAC,MAAM,QAAQ,OAAO,MAAM,CAAC;AAC5D,QAAM,SAAS,KAAK,WAAW,CAAC,MAAM,QAAQ,OAAO,MAAM,CAAC;AAC5D,QAAM,OAAO,KAAK,SAAS,CAAC,MAAqB,QAAQ,KAAK,CAAC;AAE/D,QAAM,MAAM,WAAW,EAAE,OAAO,EAAE,SAAS,KAAK,SAAS,QAAQ,KAAK,WAAW,EAAE,CAAC;AACpF,MAAI;AACJ,MAAI;AACF,aAAS,cAAc,GAAG;AAAA,EAC5B,SAAS,KAAK;AACZ,WAAO,cAAc,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,CAAI;AACzE,SAAK,CAAC;AACN;AAAA,EACF;AAEA,MAAI;AACJ,MAAI;AACF,kBAAc,MAAM,mBAAmB;AAAA,MACrC;AAAA,MACA,SAAS,KAAK;AAAA,MACd,OAAO,KAAK;AAAA,IACd,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,QAAI,eAAe,cAAc;AAC/B,aAAO,cAAc,IAAI,OAAO;AAAA,CAAI;AACpC,WAAK,IAAI,SAAS,cAAc,IAAI,CAAC;AACrC;AAAA,IACF;AACA,WAAO,8BAA8B,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,CAAI;AACzF,SAAK,EAAE;AACP;AAAA,EACF;AAEA,QAAM,SAAS,iBAAiB,WAAW;AAC3C,MAAI,CAAC,QAAQ;AACX,WAAO,kEAAkE;AACzE,SAAK,CAAC;AACN;AAAA,EACF;AAEA;AAAA,IACE;AAAA,MACE,eAAe,MAAM;AAAA,MACrB,eAAe,KAAK,OAAO;AAAA,MAC3B,eAAe,OAAO,OAAO,GAAG;AAAA,MAChC,eAAe,OAAO,cAAc,GAAG;AAAA,MACvC,eAAe,OAAO,QAAQ,GAAG;AAAA,MACjC,eAAe,OAAO,OAAO,QAAQ,WAAW,IAAI,KAAK,OAAO,MAAM,GAAI,EAAE,YAAY,IAAI,GAAG;AAAA,MAC/F;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb;AACF;","names":[]}
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "cleargate",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Planning framework for Claude Code agents — sprint/epic/story protocol, four-agent loop (architect/developer/qa/reporter), Karpathy-style awareness wiki.",
7
+ "license": "MIT",
7
8
  "bin": {
8
9
  "cleargate": "dist/cli.js"
9
10
  },
@@ -24,7 +25,8 @@
24
25
  "files": [
25
26
  "dist",
26
27
  "templates",
27
- "README.md"
28
+ "README.md",
29
+ "LICENSE"
28
30
  ],
29
31
  "engines": {
30
32
  "node": ">=24.0.0"
@@ -43,12 +45,14 @@
43
45
  "commander": "^12",
44
46
  "diff": "^5.2.2",
45
47
  "js-yaml": "^4.1.0",
48
+ "pg": "^8.12.0",
46
49
  "zod": "^4.3.0"
47
50
  },
48
51
  "devDependencies": {
49
52
  "@types/diff": "^5.2.3",
50
53
  "@types/js-yaml": "^4.0.9",
51
54
  "@types/node": "^24.0.0",
55
+ "@types/pg": "^8.11.10",
52
56
  "tsup": "^8",
53
57
  "tsx": "^4.21.0",
54
58
  "typescript": "^5.8.0",
@@ -43,6 +43,78 @@ Things you will NOT decide — flag them up.
43
43
 
44
44
  5. **Record flashcards on any gotcha you surface that future sprints should know.** Invoke `Skill(flashcard, "record: <one-liner>")` with a tag like `#schema`, `#auth`, `#test-harness`.
45
45
 
46
+ ## Adjacent Implementation Check
47
+
48
+ Before writing the per-story blueprint, grep merged stories in the current sprint (`git log sprint/S-XX --name-only | grep -E '^(cleargate-cli|src|\.cleargate/scripts)/'`) for exports. List any reusable module in the blueprint as `Reuse (no duplication): <name> from <file>`. If a candidate story would duplicate a listed module, flag it in `Cross-story risks`. Example: after STORY-013-02 merges, M2 stories that read state must cite `VALID_STATES`, `TERMINAL_STATES`, `SCHEMA_VERSION` from `.cleargate/scripts/constants.mjs` instead of redefining.
49
+
50
+ ## Blockers Triage
51
+
52
+ When a Developer Agent writes a Blockers Report (`STORY-NNN-NN-dev-blockers.md` under `.cleargate/sprint-runs/<id>/reports/`), route by the populated section:
53
+
54
+ | Category | Non-`N/A` section | Routing action |
55
+ |---|---|---|
56
+ | `test-pattern` | `## Test-Pattern` | Re-launch Developer with a fixture hint addressing the pattern. Pass the relevant `## Test-Pattern` sentence as an additional context note in the Developer spawn prompt. |
57
+ | `spec-gap` | `## Spec-Gap` | Return to orchestrator with a user question. Do NOT re-launch Developer until the user clarifies. Escalate: paste the `## Spec-Gap` sentence verbatim in the question. |
58
+ | `environment` | `## Environment` | Trigger a pre-gate re-run: invoke `run_script.sh pre_gate_runner.sh` to verify environment health, then re-launch Developer if pre-gate passes. |
59
+
60
+ **Escalation rule:** 3 consecutive circuit-breaker hits on the same story → invoke `run_script.sh update_state.mjs <story-id> Escalated` to flip story state to `Escalated`, then return to orchestrator for human decision. Do not attempt a 4th re-launch.
61
+
62
+ These rules apply under `execution_mode: v2`. Under v1 they are informational.
63
+
64
+ ## Sprint Design Review
65
+
66
+ Before a v2 sprint plan is confirmed by the human, you MUST write Sprint Plan §2 "Execution Strategy". This section is required for `execution_mode: v2` sprints; for `execution_mode: v1` it is optional but encouraged.
67
+
68
+ **Trigger:** Orchestrator invokes you with all story files for the sprint milestone AND signals "Design Review requested". You produce §2 content and return it as a markdown block for the orchestrator to insert into the sprint plan file.
69
+
70
+ **§2 Execution Strategy — four required subsections:**
71
+
72
+ 1. **§2.1 Phase Plan** — Group stories into parallel waves vs sequential chains. Source: `parallel_eligible` field on each story's frontmatter + dependency graph from `## 3. Implementation Guide`. Explicitly state which stories can run concurrently and which must be serialized.
73
+
74
+ 2. **§2.2 Merge Ordering** — Grep each story's "Files to modify" list for overlap. For every file touched by more than one story, determine which story lands first (typically the one that creates the section the other amends). Produce a table: `Shared File | Stories | Order | Rationale`.
75
+
76
+ 3. **§2.3 Shared-Surface Warnings** — For each pair of stories that touch the same file, flag the specific risk: section collision, rename hazard, append-vs-insert conflict. One bullet per risk pair.
77
+
78
+ 4. **§2.4 ADR-Conflict Flags** — Cross-check each story's implementation approach against existing Architectural Decision Records in `.cleargate/knowledge/` and prior sprint decisions captured in flashcards. Flag any story that diverges from a locked decision.
79
+
80
+ **V-Bounce reference:** `skills/agent-team/SKILL.md` §"Architect Sprint Design Review (Phase 2 → Phase 3 transition)" at pinned SHA `2b8477ab65e39e594ee8b6d8cf13a210498eaded`.
81
+
82
+ **Output:** A single markdown block (§§2.1–2.4 as shown above) ready for insertion into the sprint plan. Not a separate file. The orchestrator writes it into the plan.
83
+
84
+ These rules apply under `execution_mode: v2`. Under v1 the Design Review is informational.
85
+
86
+ ## Protocol Numbering Resolver
87
+
88
+ Before writing per-story blueprints that reference a new `cleargate-protocol.md` section, the Architect MUST audit the current highest-numbered section to avoid stale-§ drift (FLASHCARD `#protocol #section-numbering` 2026-04-21).
89
+
90
+ **Step 1 — find the current max §:**
91
+
92
+ ```bash
93
+ grep -n "^## [0-9]" .cleargate/knowledge/cleargate-protocol.md | sort -n -k2 | tail -1
94
+ ```
95
+
96
+ This prints the last numbered heading. Extract the section number from the output (e.g. `842:## 20. File-Surface Contract (v2)` → max = **20**).
97
+
98
+ **Step 2 — emit §(max+1) for any new append:**
99
+
100
+ The next free section number is always `max + 1`. Never reuse an existing number, even if a section was removed.
101
+
102
+ **Step 3 — rewrite stale references in story prose:**
103
+
104
+ For each story in the milestone, grep the story file for `§\d+` references:
105
+
106
+ ```bash
107
+ grep -oE '§[0-9]+' path/to/STORY-NNN-NN.md
108
+ ```
109
+
110
+ If any cited § number is ≤ max AND the section text it describes does not match the actual heading at that number in the protocol, flag it as a stale reference. Rewrite the reference in the plan to `§(max+1)` and include a note: `"STORY text cites §N — stale, rewritten to §(max+1)"`.
111
+
112
+ **Concrete example (post-SPRINT-10):**
113
+
114
+ After SPRINT-10 ships, `max = 20`. A story drafted before SPRINT-10 might cite `§10` (meaning "append after §10"). That section is already occupied by `§10 Wiki Awareness Layer`. The plan must use `§21` (next free after `§20`) and note: _"STORY text cites §10 — stale, rewritten to §21"_.
115
+
116
+ **Rule:** Never let a Developer emit a protocol section number that conflicts with an existing one. Audit first, emit second.
117
+
46
118
  ## Guardrails
47
119
  - **No production code.** You write one markdown plan file. Nothing else.
48
120
  - **No speculation.** Every claim about existing code must cite a file path + line range you read.