cleargate 0.14.0 → 0.15.1
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.
- package/CHANGELOG.md +21 -0
- package/dist/MANIFEST.json +72 -16
- package/dist/admin-api/index.cjs +0 -1
- package/dist/admin-api/index.js +1 -2
- package/dist/auth/factory.cjs +0 -1
- package/dist/auth/factory.js +2 -3
- package/dist/auth/require-token.cjs +0 -1
- package/dist/auth/require-token.js +1 -2
- package/dist/auth/token-store.cjs +0 -1
- package/dist/auth/token-store.js +1 -2
- package/dist/{bootstrap-root-QKSA5V75.js → bootstrap-root-2H5HVTCC.js} +1 -2
- package/dist/{chunk-PDE37WFQ.js → chunk-A7MSQUU7.js} +2 -3
- package/dist/{chunk-BTSZOEWC.js → chunk-P6KEDAK2.js} +0 -1
- package/dist/{chunk-E3X7IE5E.js → chunk-PY6FHGV5.js} +1 -2
- package/dist/{chunk-5DI2Z3C2.js → chunk-Y53ZZYYU.js} +1 -2
- package/dist/cli.cjs +1564 -1414
- package/dist/cli.js +1514 -1364
- package/dist/lib/ledger.cjs +0 -1
- package/dist/lib/ledger.js +1 -2
- package/dist/lib/lifecycle-reconcile.cjs +0 -1
- package/dist/lib/lifecycle-reconcile.js +2 -3
- package/dist/{whoami-EANGN46Z.js → whoami-JKQQPABQ.js} +3 -4
- package/package.json +4 -3
- package/templates/cleargate-planning/.claude/agents/architect-synth.md +2 -0
- package/templates/cleargate-planning/.claude/agents/architect.md +4 -2
- package/templates/cleargate-planning/.claude/agents/developer.md +4 -11
- package/templates/cleargate-planning/.claude/agents/qa.md +14 -6
- package/templates/cleargate-planning/.claude/hooks/pending-task-sentinel.sh +2 -2
- package/templates/cleargate-planning/.claude/skills/sprint-execution/SKILL.md +19 -1
- package/templates/cleargate-planning/.cleargate/config.example.yml +16 -0
- package/templates/cleargate-planning/.cleargate/scripts/close_sprint.deferred-verify.red.node.test.ts +245 -0
- package/templates/cleargate-planning/.cleargate/scripts/close_sprint.mjs +227 -0
- package/templates/cleargate-planning/.cleargate/scripts/gate-checks.json +5 -4
- package/templates/cleargate-planning/.cleargate/scripts/init_sprint.mjs +75 -2
- package/templates/cleargate-planning/.cleargate/scripts/pre_gate_common.sh +48 -0
- package/templates/cleargate-planning/.cleargate/scripts/pre_gate_runner.sh +57 -1
- package/templates/cleargate-planning/.cleargate/scripts/provision_worktree_config.sh +155 -0
- package/templates/cleargate-planning/.cleargate/scripts/qa_red_lint.mjs +380 -0
- package/templates/cleargate-planning/.cleargate/scripts/run_script.sh +34 -1
- package/templates/cleargate-planning/.cleargate/scripts/test/cr077_eviction.red.sh +113 -0
- package/templates/cleargate-planning/.cleargate/scripts/test/cr078_init.test.sh +309 -0
- package/templates/cleargate-planning/.cleargate/scripts/test/cr079_provision.red.sh +262 -0
- package/templates/cleargate-planning/.cleargate/scripts/test/cr080_wrapper.test.sh +177 -0
- package/templates/cleargate-planning/.cleargate/scripts/test/cr081_qa_red_lint.red.sh +348 -0
- package/templates/cleargate-planning/.cleargate/sprint-runs/_off-sprint/.session-totals.json +1 -0
- package/templates/cleargate-planning/.cleargate/sprint-runs/_off-sprint/token-ledger.jsonl +222 -0
- package/templates/cleargate-planning/.cleargate/templates/sprint_context.md +17 -0
- package/templates/cleargate-planning/.cleargate/templates/story.md +1 -0
- package/templates/cleargate-planning/MANIFEST.json +72 -16
- package/dist/admin-api/index.cjs.map +0 -1
- package/dist/admin-api/index.js.map +0 -1
- package/dist/auth/factory.cjs.map +0 -1
- package/dist/auth/factory.js.map +0 -1
- package/dist/auth/require-token.cjs.map +0 -1
- package/dist/auth/require-token.js.map +0 -1
- package/dist/auth/token-store.cjs.map +0 -1
- package/dist/auth/token-store.js.map +0 -1
- package/dist/bootstrap-root-QKSA5V75.js.map +0 -1
- package/dist/chunk-5DI2Z3C2.js.map +0 -1
- package/dist/chunk-BTSZOEWC.js.map +0 -1
- package/dist/chunk-E3X7IE5E.js.map +0 -1
- package/dist/chunk-PDE37WFQ.js.map +0 -1
- package/dist/cli.cjs.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/lib/ledger.cjs.map +0 -1
- package/dist/lib/ledger.js.map +0 -1
- package/dist/lib/lifecycle-reconcile.cjs.map +0 -1
- package/dist/lib/lifecycle-reconcile.js.map +0 -1
- package/dist/templates/cleargate-planning/.claude/agents/architect-reader.md +0 -61
- package/dist/templates/cleargate-planning/.claude/agents/architect-synth.md +0 -124
- package/dist/templates/cleargate-planning/.claude/agents/architect.md +0 -230
- package/dist/templates/cleargate-planning/.claude/agents/cleargate-wiki-contradict.md +0 -108
- package/dist/templates/cleargate-planning/.claude/agents/cleargate-wiki-ingest.md +0 -194
- package/dist/templates/cleargate-planning/.claude/agents/cleargate-wiki-lint.md +0 -261
- package/dist/templates/cleargate-planning/.claude/agents/cleargate-wiki-query.md +0 -143
- package/dist/templates/cleargate-planning/.claude/agents/developer.md +0 -185
- package/dist/templates/cleargate-planning/.claude/agents/devops.md +0 -257
- package/dist/templates/cleargate-planning/.claude/agents/qa.md +0 -171
- package/dist/templates/cleargate-planning/.claude/agents/reporter.md +0 -274
- package/dist/templates/cleargate-planning/.claude/hooks/pending-task-sentinel.sh +0 -209
- package/dist/templates/cleargate-planning/.claude/hooks/pre-commit-surface-gate.sh +0 -33
- package/dist/templates/cleargate-planning/.claude/hooks/pre-commit-test-ratchet.sh +0 -58
- package/dist/templates/cleargate-planning/.claude/hooks/pre-commit.sh +0 -19
- package/dist/templates/cleargate-planning/.claude/hooks/pre-edit-gate.sh +0 -162
- package/dist/templates/cleargate-planning/.claude/hooks/pre-tool-use-autonomy.sh +0 -58
- package/dist/templates/cleargate-planning/.claude/hooks/pre-tool-use-task.sh +0 -148
- package/dist/templates/cleargate-planning/.claude/hooks/session-start.sh +0 -75
- package/dist/templates/cleargate-planning/.claude/hooks/stamp-and-gate.sh +0 -43
- package/dist/templates/cleargate-planning/.claude/hooks/token-ledger.sh +0 -590
- package/dist/templates/cleargate-planning/.claude/settings.json +0 -68
- package/dist/templates/cleargate-planning/.claude/skills/flashcard/SKILL.md +0 -102
- package/dist/templates/cleargate-planning/.claude/skills/sprint-execution/SKILL.md +0 -742
- package/dist/templates/cleargate-planning/.cleargate/FLASHCARD.md +0 -7
- package/dist/templates/cleargate-planning/.cleargate/config.example.yml +0 -67
- package/dist/templates/cleargate-planning/.cleargate/config.yml +0 -18
- package/dist/templates/cleargate-planning/.cleargate/delivery/archive/.gitkeep +0 -0
- package/dist/templates/cleargate-planning/.cleargate/delivery/pending-sync/.gitkeep +0 -0
- package/dist/templates/cleargate-planning/.cleargate/knowledge/cleargate-enforcement.md +0 -551
- package/dist/templates/cleargate-planning/.cleargate/knowledge/cleargate-protocol.md +0 -878
- package/dist/templates/cleargate-planning/.cleargate/knowledge/mid-sprint-triage-rubric.md +0 -160
- package/dist/templates/cleargate-planning/.cleargate/knowledge/readiness-gates.md +0 -213
- package/dist/templates/cleargate-planning/.cleargate/knowledge/sprint-closeout-checklist.md +0 -71
- package/dist/templates/cleargate-planning/.cleargate/scripts/_migrate-schema-v3.mjs +0 -120
- package/dist/templates/cleargate-planning/.cleargate/scripts/assert_story_files.mjs +0 -265
- package/dist/templates/cleargate-planning/.cleargate/scripts/close_sprint.mjs +0 -1012
- package/dist/templates/cleargate-planning/.cleargate/scripts/collision_surface.sh +0 -114
- package/dist/templates/cleargate-planning/.cleargate/scripts/constants.mjs +0 -62
- package/dist/templates/cleargate-planning/.cleargate/scripts/dedupe_frontmatter.mjs +0 -219
- package/dist/templates/cleargate-planning/.cleargate/scripts/file_surface_diff.sh +0 -320
- package/dist/templates/cleargate-planning/.cleargate/scripts/gate-checks.json +0 -15
- package/dist/templates/cleargate-planning/.cleargate/scripts/init_gate_config.sh +0 -38
- package/dist/templates/cleargate-planning/.cleargate/scripts/init_sprint.mjs +0 -240
- package/dist/templates/cleargate-planning/.cleargate/scripts/launch_wave.mjs +0 -341
- package/dist/templates/cleargate-planning/.cleargate/scripts/lib/report-filename.mjs +0 -54
- package/dist/templates/cleargate-planning/.cleargate/scripts/pre_gate_common.sh +0 -206
- package/dist/templates/cleargate-planning/.cleargate/scripts/pre_gate_runner.sh +0 -371
- package/dist/templates/cleargate-planning/.cleargate/scripts/prefill_report.mjs +0 -280
- package/dist/templates/cleargate-planning/.cleargate/scripts/prep_doc_refresh.mjs +0 -378
- package/dist/templates/cleargate-planning/.cleargate/scripts/prep_qa_context.mjs +0 -888
- package/dist/templates/cleargate-planning/.cleargate/scripts/run_script.sh +0 -209
- package/dist/templates/cleargate-planning/.cleargate/scripts/sprint_trends.mjs +0 -71
- package/dist/templates/cleargate-planning/.cleargate/scripts/state.schema.json +0 -127
- package/dist/templates/cleargate-planning/.cleargate/scripts/suggest_improvements.mjs +0 -717
- package/dist/templates/cleargate-planning/.cleargate/scripts/surface-whitelist.txt +0 -27
- package/dist/templates/cleargate-planning/.cleargate/scripts/test/test_assert_story_files.sh +0 -261
- package/dist/templates/cleargate-planning/.cleargate/scripts/test/test_file_surface.sh +0 -210
- package/dist/templates/cleargate-planning/.cleargate/scripts/test/test_flashcard_gate.sh +0 -190
- package/dist/templates/cleargate-planning/.cleargate/scripts/test/test_prep_qa_context.sh +0 -482
- package/dist/templates/cleargate-planning/.cleargate/scripts/test/test_test_ratchet.sh +0 -327
- package/dist/templates/cleargate-planning/.cleargate/scripts/test_ratchet.mjs +0 -261
- package/dist/templates/cleargate-planning/.cleargate/scripts/update_state.mjs +0 -246
- package/dist/templates/cleargate-planning/.cleargate/scripts/validate_bounce_readiness.mjs +0 -111
- package/dist/templates/cleargate-planning/.cleargate/scripts/validate_state.mjs +0 -184
- package/dist/templates/cleargate-planning/.cleargate/scripts/write_dispatch.sh +0 -172
- package/dist/templates/cleargate-planning/.cleargate/templates/Bug.md +0 -126
- package/dist/templates/cleargate-planning/.cleargate/templates/CR.md +0 -130
- package/dist/templates/cleargate-planning/.cleargate/templates/Sprint Plan Template.md +0 -137
- package/dist/templates/cleargate-planning/.cleargate/templates/epic.md +0 -166
- package/dist/templates/cleargate-planning/.cleargate/templates/hotfix.md +0 -111
- package/dist/templates/cleargate-planning/.cleargate/templates/initiative.md +0 -122
- package/dist/templates/cleargate-planning/.cleargate/templates/sprint_context.md +0 -50
- package/dist/templates/cleargate-planning/.cleargate/templates/sprint_report.md +0 -224
- package/dist/templates/cleargate-planning/.cleargate/templates/story.md +0 -213
- package/dist/templates/cleargate-planning/CLAUDE.md +0 -66
- package/dist/templates/cleargate-planning/MANIFEST.json +0 -503
- package/dist/templates/synthesis/active-sprint.md +0 -30
- package/dist/templates/synthesis/open-gates.md +0 -38
- package/dist/templates/synthesis/product-state.md +0 -31
- package/dist/templates/synthesis/roadmap.md +0 -63
- package/dist/whoami-EANGN46Z.js.map +0 -1
|
@@ -1,878 +0,0 @@
|
|
|
1
|
-
# ClearGate Protocol
|
|
2
|
-
|
|
3
|
-
You are operating in a ClearGate-enabled repository. Read this file in full before responding to any user request. These rules override your default behavior.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Code-Truth Principle
|
|
8
|
-
|
|
9
|
-
ClearGate's epistemic stack: source code is canonical; wiki, memory, and `context_source` are derived caches. Every triage and draft answers four layers, in order:
|
|
10
|
-
|
|
11
|
-
- **L0 — Code is source of truth.** On any conflict between cache and code, the code wins; the cache rebuilds. Verify capability claims by grep before stating them.
|
|
12
|
-
- **L1 — Reuse before rebuild.** Before drafting a work item that names an integration, feature, or capability, grep the source tree for existing implementations. Cite findings in `## Existing Surfaces`. If an existing surface covers ≥80% of the requirement, the work item is an extension (CR), not a new build (Story).
|
|
13
|
-
- **L2 — Right-size at triage.** Could this be a config change? a parameter addition? a one-line edit? If yes, it's not a Story — it's a PR or a tiny CR. Smallest viable form first.
|
|
14
|
-
- **L3 — Justify complexity.** Every Epic and Story includes `## Why not simpler?` answering: what's the smallest existing surface; why isn't extension/parameterization/config sufficient.
|
|
15
|
-
|
|
16
|
-
This is the same epistemic discipline the Knowledge Wiki applies to documents (raw → wiki → schema; source → cache → derived view), extended from planning artifacts to source code.
|
|
17
|
-
|
|
18
|
-
---
|
|
19
|
-
|
|
20
|
-
## 0. The Five Phases
|
|
21
|
-
|
|
22
|
-
ClearGate operates in five named phases. Every work item moves through them in order; every gate fires at a phase boundary.
|
|
23
|
-
|
|
24
|
-
| Phase | Activity | Gate at exit |
|
|
25
|
-
|---|---|---|
|
|
26
|
-
| **Plan** | Triage user request → draft work item using template → present Brief → resolve open questions → ambiguity 🟢 | **Gate 1 — Brief** (per work item; implicitly grants MCP push) |
|
|
27
|
-
| **Prepare** | Sprint planning. AI auto-picks sprint number, drafts Sprint Plan as Brief, Architect writes §2 Sprint Design Review. | **Gate 2 — Sprint Ready** (plan quality) → **Gate 3 — Sprint Execution** (env health) |
|
|
28
|
-
| **Execute** | Four-agent loop: Architect (per-milestone plan) → Developer → QA → (Reporter at end). One story = one worktree = one commit. | (transitions to Observe when all stories merge to sprint branch) |
|
|
29
|
-
| **Observe** | User walkthrough on sprint branch. Feedback classified `UR:bug` or `UR:review-feedback`. Bugs fixed before merge to main. | (transitions to Close when all `UR:bug` resolved) |
|
|
30
|
-
| **Close** | Lifecycle reconciler → Reporter writes `SPRINT-<#>_REPORT.md` → status flips Completed. | **Gate 4 — Close-Ack** |
|
|
31
|
-
|
|
32
|
-
Read this section first. Drill into §1–§14 + §21 only as needed for the current task.
|
|
33
|
-
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
## 1. Your Role
|
|
37
|
-
|
|
38
|
-
You are the **Execution Agent**. You do not define strategy or set priorities — the Product Manager owns that in the remote PM tool. Your responsibilities are:
|
|
39
|
-
|
|
40
|
-
1. **Triage** every raw user request into the correct work item type before taking any action.
|
|
41
|
-
2. **Draft** technically accurate artifacts using the templates in `.cleargate/templates/`.
|
|
42
|
-
3. **Halt** at every approval gate and wait for explicit human sign-off.
|
|
43
|
-
4. **Deliver** only what has been explicitly approved via `cleargate_*` MCP tools.
|
|
44
|
-
|
|
45
|
-
You never push to the PM tool without approval. You never skip a level in the document hierarchy. You never guess at file paths.
|
|
46
|
-
|
|
47
|
-
---
|
|
48
|
-
|
|
49
|
-
## 2. The Front Gate (Triage)
|
|
50
|
-
|
|
51
|
-
**When the user submits any request, classify it first. Do not start drafting until you know the type.**
|
|
52
|
-
|
|
53
|
-
### Classification Table
|
|
54
|
-
|
|
55
|
-
| User Intent | Work Item Type | Template |
|
|
56
|
-
|---|---|---|
|
|
57
|
-
| Multi-part feature needing architecture decisions or multiple sprints | **Epic** | `templates/epic.md` |
|
|
58
|
-
| Net-new functionality that does not yet exist | **Story** | `templates/story.md` |
|
|
59
|
-
| Change, replace, or remove existing behavior | **CR** | `templates/CR.md` |
|
|
60
|
-
| Fix broken/unintended behavior in already-shipped code | **Bug** | `templates/Bug.md` |
|
|
61
|
-
| Sync a remote initiative or sprint down to local | **Pull** | `cleargate_pull_initiative` → `templates/initiative.md` or `templates/Sprint Plan Template.md` |
|
|
62
|
-
| Push an approved local item to the PM tool | **Push** | `cleargate_push_item` (only if `approved: true`) |
|
|
63
|
-
|
|
64
|
-
### Signal Words
|
|
65
|
-
|
|
66
|
-
- Epic: "feature", "system", "module", "redesign", "multi-sprint"
|
|
67
|
-
- Story: "add", "build", "implement", "new", "create"
|
|
68
|
-
- CR: "change", "replace", "update how X works", "remove", "refactor" (existing behavior)
|
|
69
|
-
- Bug: "broken", "error", "crash", "not working", "wrong output", "fix"
|
|
70
|
-
- Pull: "pull", "sync", "what's in Linear/Jira", "show me the sprint"
|
|
71
|
-
- Push: "push", "cleargate push", "sync this item"
|
|
72
|
-
|
|
73
|
-
### Ambiguous Requests
|
|
74
|
-
|
|
75
|
-
If the type is not clear, ask **one targeted question** before proceeding. Do not guess.
|
|
76
|
-
|
|
77
|
-
Example: *"Is this adding functionality that doesn't exist yet (Story) or changing how an existing feature works (CR)?"*
|
|
78
|
-
|
|
79
|
-
### Always Start with a Brief
|
|
80
|
-
|
|
81
|
-
Every drafted work item — Epic, Story, CR, Bug, Hotfix — gets a Brief presented to the human in chat after the document is written. The Brief is mechanically extracted from the document's own sections per the template's `<instructions>` block (Summary / Open Questions / Edge Cases / Risks / Ambiguity). Conversation resolves open questions; ambiguity flips 🔴 → 🟢 → **Gate 1 passes**.
|
|
82
|
-
|
|
83
|
-
**Initiative-class scope** uses the `initiative.md` template — multi-Epic work where a persistent file-based Brief is genuinely useful before decomposition begins. For everything else (single Epic / Story / CR / Bug / Hotfix), the agent triages the request directly into the appropriate template and presents the Brief. The legacy Proposal step has been retired (CR-025 SPRINT-19); see §14.5 for the stakeholder-authored intake flow that retains the `cleargate:proposal` external label as backwards-compat.
|
|
84
|
-
|
|
85
|
-
---
|
|
86
|
-
|
|
87
|
-
## 3. Document Hierarchy
|
|
88
|
-
|
|
89
|
-
### Hierarchy Rules
|
|
90
|
-
|
|
91
|
-
- **No orphans.** Every Story has a `parent_epic_ref:` pointing to a real Epic file. Every Bug or CR references the affected Epic, Story, or knowledge document.
|
|
92
|
-
- **Epic before Story.** A Story file cannot exist without a `parent_epic_ref:` to a 🟢 Epic.
|
|
93
|
-
- **Initiative is optional.** A multi-Epic Initiative MAY exist as a file-persisted Brief in `pending-sync/INITIATIVE-NNN_*.md`. It is not required for any single-Epic-or-smaller work.
|
|
94
|
-
- **Cascade ambiguity.** A CR that invalidates an existing Epic or Story flips that document back to 🔴; downstream items inherit.
|
|
95
|
-
|
|
96
|
-
---
|
|
97
|
-
|
|
98
|
-
## 4. The Four Gates
|
|
99
|
-
|
|
100
|
-
### Gate 1 — Brief (per work item, Plan phase)
|
|
101
|
-
|
|
102
|
-
After drafting any work item, the agent presents a Brief in chat:
|
|
103
|
-
- **Summary** (1–2 sentences from §1 / User Story)
|
|
104
|
-
- **Open Questions** (with recommended answers)
|
|
105
|
-
- **Edge Cases** (with recommended handling)
|
|
106
|
-
- **Risks** (with recommended mitigations)
|
|
107
|
-
- **Ambiguity level** (current 🔴 / 🟡 / 🟢)
|
|
108
|
-
|
|
109
|
-
Conversation resolves the open questions. When all are resolved → ambiguity flips 🟢 → Gate 1 passes. **The same approval implicitly grants the MCP push** — agent calls `cleargate_push_item` immediately. No separate "now confirm the push" step.
|
|
110
|
-
|
|
111
|
-
**Initiative intake (post-CR-025).** Stakeholder-shaped input (multi-Epic scope, persistent Brief useful) lands in `pending-sync/INITIATIVE-NNN_*.md` via two paths: (1) MCP pull — `cleargate_pull_initiative` with the remote ID writes the file automatically; (2) Manual paste — agent triages the input and writes the file using `templates/initiative.md`. Either path then runs the standard Brief loop above. After Gate 1 passes, the Initiative file moves to `archive/` stamped with `triaged_at: <ISO-8601>` and `spawned_items: ["EPIC-NNN", "EPIC-MMM", ...]` listing the work items it decomposed into.
|
|
112
|
-
|
|
113
|
-
### Gate 2 — Sprint Ready (per sprint, Prepare phase internal)
|
|
114
|
-
|
|
115
|
-
Sprint Plan moves Draft → Ready when (a) every referenced item is decomposed + 🟢, (b) the sprint-level Brief is resolved, (c) the Architect Sprint Design Review (§2 of the Sprint Plan) is written under `execution_mode: v2`. Without all three, the sprint cannot transition.
|
|
116
|
-
|
|
117
|
-
### Gate 3 — Sprint Execution (per sprint, Prepare → Execute boundary)
|
|
118
|
-
|
|
119
|
-
Before sprint execution begins, `cleargate sprint preflight <sprint-id>` runs **five** checks: previous sprint Completed, no leftover worktrees, sprint branch ref free, `main` clean, and per-item readiness gates pass for every work item in §1 Consolidated Deliverables. Under `execution_mode: v2` a failing per-item gate hard-blocks; under `v1` it warns. See `cleargate-enforcement.md` §<N> for full enforcement spec; specified by CR-021 (env health) + CR-027 (composite per-item gate + Discovery/Risk criteria).
|
|
120
|
-
|
|
121
|
-
### Gate 4 — Close-Ack (per sprint, Close phase)
|
|
122
|
-
|
|
123
|
-
`close_sprint.mjs` halts at Step 5 with the prompt "Review the report, then confirm close by re-running with --assume-ack." Orchestrator surfaces the prompt verbatim and halts. Human reads the sprint report, then either re-runs the script with `--assume-ack` themselves or explicitly tells the orchestrator "approved, close it" — at which point the orchestrator may pass the flag.
|
|
124
|
-
|
|
125
|
-
`--assume-ack` is reserved for **automated test environments only**. Conversational orchestrators MUST NOT pass it autonomously. Violation is a Gate-4 breach equivalent to an unauthorized push.
|
|
126
|
-
|
|
127
|
-
> Gate check is machine-assisted via `cleargate gate check`; see §12.
|
|
128
|
-
> (See §13 for scaffold lifecycle commands)
|
|
129
|
-
|
|
130
|
-
---
|
|
131
|
-
|
|
132
|
-
## 5. Delivery Workflow ("Local First, Sync, Update")
|
|
133
|
-
|
|
134
|
-
Follow these steps in exact order:
|
|
135
|
-
|
|
136
|
-
```
|
|
137
|
-
1. DRAFT — Fill the appropriate template.
|
|
138
|
-
Save to: .cleargate/delivery/pending-sync/{TYPE}-{ID}-{Name}.md
|
|
139
|
-
|
|
140
|
-
2. BRIEF — Present the Brief in chat. Halt for human review. Resolve open questions.
|
|
141
|
-
|
|
142
|
-
3. SYNC — When ambiguity flips 🟢, call cleargate_push_item automatically
|
|
143
|
-
(Gate 1 covers approval).
|
|
144
|
-
|
|
145
|
-
4. ARCHIVE — Inject returned remote ID into frontmatter; move file to
|
|
146
|
-
.cleargate/delivery/archive/.
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
**On MCP failure:** Leave the file in `pending-sync/`. Report the exact error to the human. Do not retry in a loop. Do not attempt a workaround.
|
|
150
|
-
|
|
151
|
-
**On PM tool unreachable:** Same as above. Local state is the source of truth. Never mutate local files to reflect a push that did not succeed.
|
|
152
|
-
|
|
153
|
-
---
|
|
154
|
-
|
|
155
|
-
## 6. MCP Tools Reference
|
|
156
|
-
|
|
157
|
-
**MCP is the only sync surface.** From the AI's perspective, MCP *is* the PM tool. The `cleargate_*` MCP tools (`cleargate_pull_initiative`, `cleargate_push_item`, `cleargate_sync_status`, plus the work-item / sync-log surface added in SPRINT-16) are the only interfaces. Whatever upstream systems MCP fans out to (Linear / Jira / GitHub Issues / others) is MCP's concern, not yours. Never write custom HTTP calls, API scripts, or other SDK invocations.
|
|
158
|
-
|
|
159
|
-
| Tool | When to Call |
|
|
160
|
-
|---|---|
|
|
161
|
-
| `cleargate_pull_initiative` | User wants to pull a remote initiative or sprint into local context. Pass `remote_id`. Writes to `.cleargate/plans/`. |
|
|
162
|
-
| `cleargate_push_item` | An approved local file needs to be pushed. Pass `file_path`, `item_type`, and `parent_id` if it is a Story. Requires `approved: true`. |
|
|
163
|
-
| `cleargate_sync_status` | A work item changes state (e.g., moved to Done). Pass `remote_id` and `new_status`. |
|
|
164
|
-
|
|
165
|
-
---
|
|
166
|
-
|
|
167
|
-
## 7. Scope Discipline
|
|
168
|
-
|
|
169
|
-
These rules prevent hallucinated or out-of-scope changes.
|
|
170
|
-
|
|
171
|
-
- **Only modify files explicitly listed** in the "Technical Grounding > Affected Files" section (Epic/Story) or "Execution Sandbox" section (Bug/CR).
|
|
172
|
-
- **Do not refactor, optimize, or clean up** code that is not in scope. If you notice an issue outside scope, note it and ask the human whether to create a separate Story or CR.
|
|
173
|
-
- **Do not create new files** unless they appear under "New Files Needed" in the Implementation Guide.
|
|
174
|
-
- **Do not assume file paths.** All affected file paths must originate from an approved Initiative. If a path is missing or unverified, add it to §6 AI Interrogation Loop — do not guess.
|
|
175
|
-
|
|
176
|
-
---
|
|
177
|
-
|
|
178
|
-
## 8. Planning Phase (Pull Workflow)
|
|
179
|
-
|
|
180
|
-
When the user wants to ingest context from the PM tool before any execution:
|
|
181
|
-
|
|
182
|
-
1. Call `cleargate_pull_initiative` with the remote ID provided by the user.
|
|
183
|
-
2. The tool writes the result to `.cleargate/plans/` using the appropriate local format.
|
|
184
|
-
3. Read the pulled file to understand scope, constraints, and sprint context.
|
|
185
|
-
4. Use this as the input context when beginning an Initiative draft.
|
|
186
|
-
|
|
187
|
-
You do not push during the Planning Phase. Planning Phase ends when the user confirms they want to begin drafting an Initiative.
|
|
188
|
-
|
|
189
|
-
---
|
|
190
|
-
|
|
191
|
-
## 9. Quick Decision Reference
|
|
192
|
-
|
|
193
|
-
```
|
|
194
|
-
User prompt received
|
|
195
|
-
↓
|
|
196
|
-
Is this a PULL request? ──YES──→ cleargate_pull_initiative → read result → done
|
|
197
|
-
│ NO
|
|
198
|
-
↓
|
|
199
|
-
Is this a PUSH request? ──YES──→ check approved: true → cleargate_push_item → archive
|
|
200
|
-
│ NO
|
|
201
|
-
↓
|
|
202
|
-
Classify: Epic / Story / CR / Bug
|
|
203
|
-
↓
|
|
204
|
-
Does an approved: true Initiative exist for this work?
|
|
205
|
-
├── NO → Draft Initiative → HALT at Gate 1
|
|
206
|
-
└── YES → Draft work item (Epic/Story/CR/Bug) → HALT at Gate 2
|
|
207
|
-
↓
|
|
208
|
-
Human resolves §6 + sets 🟢
|
|
209
|
-
↓
|
|
210
|
-
Human confirms push → cleargate_push_item → archive
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
---
|
|
214
|
-
|
|
215
|
-
## 10. Knowledge Wiki Protocol
|
|
216
|
-
|
|
217
|
-
The Knowledge Wiki is the compiled awareness layer at `.cleargate/wiki/`. Read it before reading raw delivery files — it surfaces relationships and status that individual raw files do not expose. The wiki is always derived: when a raw file under `.cleargate/delivery/**` contradicts a wiki page, the raw file wins.
|
|
218
|
-
|
|
219
|
-
---
|
|
220
|
-
|
|
221
|
-
### §10.1 Directory Layout
|
|
222
|
-
|
|
223
|
-
```
|
|
224
|
-
.cleargate/wiki/
|
|
225
|
-
index.md ← master page registry (one row per page)
|
|
226
|
-
log.md ← append-only audit log of all ingest events
|
|
227
|
-
product-state.md ← synthesised product health snapshot
|
|
228
|
-
roadmap.md ← synthesised roadmap view
|
|
229
|
-
active-sprint.md ← synthesised current-sprint progress
|
|
230
|
-
open-gates.md ← synthesised blocked-item registry
|
|
231
|
-
epics/ ← one page per Epic (EPIC-NNN.md)
|
|
232
|
-
stories/ ← one page per Story (STORY-NNN-NN.md)
|
|
233
|
-
bugs/ ← one page per Bug
|
|
234
|
-
proposals/ ← one page per Proposal
|
|
235
|
-
crs/ ← one page per CR
|
|
236
|
-
sprints/ ← one page per Sprint
|
|
237
|
-
topics/ ← cross-cutting topic pages (written by query --persist only)
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
---
|
|
241
|
-
|
|
242
|
-
### §10.2 Three Operations
|
|
243
|
-
|
|
244
|
-
**ingest**
|
|
245
|
-
|
|
246
|
-
Triggered automatically by a PostToolUse hook on Write or Edit operations under `.cleargate/delivery/**`. When the hook is unavailable, every agent that writes a raw delivery file must invoke the `cleargate-wiki-ingest` subagent directly (protocol-rule fallback — see §10.9). On each ingest: one per-item wiki page is created or updated, one YAML event is appended to `log.md`, and every synthesis page affected by the item is recompiled (`product-state.md`, `roadmap.md`, `active-sprint.md`, `open-gates.md`). Ingest is always safe to re-run.
|
|
247
|
-
|
|
248
|
-
**query**
|
|
249
|
-
|
|
250
|
-
Invoked automatically at triage (read-only). Searches the wiki index and existing pages to surface related work items before any new draft begins. Explicit queries use `cleargate wiki query <terms>`. Append `--persist` to write the result as a topic page at `wiki/topics/<slug>.md`. Topic pages are never written by ingest — only by `query --persist`.
|
|
251
|
-
|
|
252
|
-
**lint**
|
|
253
|
-
|
|
254
|
-
Enforcement run. Checks for drift between wiki pages and their raw source files. Exits non-zero on any violation; a non-zero exit halts Gate 1 (Initiative approval) and Gate 3 (Push). Run with `--suggest` to receive candidate cross-ref patches without blocking (exits 0).
|
|
255
|
-
|
|
256
|
-
---
|
|
257
|
-
|
|
258
|
-
### §10.3 Exclusions
|
|
259
|
-
|
|
260
|
-
Ingest skips the following directories — they are static configuration or orchestration-only and must not generate wiki pages:
|
|
261
|
-
|
|
262
|
-
- `.cleargate/knowledge/`
|
|
263
|
-
- `.cleargate/templates/`
|
|
264
|
-
- `.cleargate/sprint-runs/`
|
|
265
|
-
- `.cleargate/hook-log/`
|
|
266
|
-
|
|
267
|
-
---
|
|
268
|
-
|
|
269
|
-
### §10.4 Page Schema
|
|
270
|
-
|
|
271
|
-
Every wiki page has a YAML frontmatter block followed by a short prose body.
|
|
272
|
-
|
|
273
|
-
```markdown
|
|
274
|
-
---
|
|
275
|
-
type: story
|
|
276
|
-
id: "STORY-042-01"
|
|
277
|
-
parent: "[[EPIC-042]]"
|
|
278
|
-
children: []
|
|
279
|
-
status: "🟢"
|
|
280
|
-
remote_id: "LIN-1042"
|
|
281
|
-
raw_path: ".cleargate/delivery/archive/STORY-042-01_name.md"
|
|
282
|
-
last_ingest: "2026-04-19T10:00:00Z"
|
|
283
|
-
last_ingest_commit: "a1b2c3d4e5f6..."
|
|
284
|
-
repo: "planning"
|
|
285
|
-
last_contradict_sha: "" # optional — populated by ingest Phase 4 (§10.10)
|
|
286
|
-
---
|
|
287
|
-
|
|
288
|
-
# STORY-042-01: Short title
|
|
289
|
-
|
|
290
|
-
Summary in one or two sentences.
|
|
291
|
-
|
|
292
|
-
## Blast radius
|
|
293
|
-
Affects: [[EPIC-042]], [[service-auth]]
|
|
294
|
-
|
|
295
|
-
## Open questions
|
|
296
|
-
None.
|
|
297
|
-
```
|
|
298
|
-
|
|
299
|
-
Field notes:
|
|
300
|
-
|
|
301
|
-
- `last_ingest_commit` — the SHA returned by `git log -1 --format=%H -- <raw_path>` at ingest time. Used for idempotency (see §10.7).
|
|
302
|
-
- `repo` — derived from `raw_path` prefix: `cleargate-cli/` → `cli`; `mcp/` → `mcp`; `.cleargate/` or `cleargate-planning/` → `planning`. Never manually set.
|
|
303
|
-
- `last_contradict_sha` (optional) — populated by ingest Phase 4 (§10.10). Pages without this field MUST continue to pass lint. Value is the SHA returned by `git log -1 --format=%H -- <raw_path>` at the moment Phase 4 last ran.
|
|
304
|
-
|
|
305
|
-
---
|
|
306
|
-
|
|
307
|
-
### §10.5 Backlink Syntax
|
|
308
|
-
|
|
309
|
-
Use `[[WORK-ITEM-ID]]` (Obsidian-style double-bracket links) to express relationships between pages. Every parent/child pair declared in frontmatter must have a corresponding backlink in the body of each page. `cleargate wiki lint` verifies bidirectionality: a `parent:` entry without a matching `[[parent-id]]` reference in the parent's `children:` list is a lint violation.
|
|
310
|
-
|
|
311
|
-
---
|
|
312
|
-
|
|
313
|
-
### §10.6 `log.md` Event Shape
|
|
314
|
-
|
|
315
|
-
One YAML list entry is appended to `wiki/log.md` on every ingest. Fields:
|
|
316
|
-
|
|
317
|
-
```yaml
|
|
318
|
-
- timestamp: "2026-04-19T10:00:00Z"
|
|
319
|
-
actor: "cleargate-draft-proposal"
|
|
320
|
-
action: "create"
|
|
321
|
-
target: "PROPOSAL-stripe-webhooks"
|
|
322
|
-
path: ".cleargate/delivery/pending-sync/PROPOSAL-stripe-webhooks.md"
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
- `timestamp` — ISO 8601 UTC.
|
|
326
|
-
- `actor` — subagent name (e.g. `cleargate-wiki-ingest`) or `vibe-coder` for manual writes.
|
|
327
|
-
- `action` — one of `create`, `update`, `delete`, `approve`.
|
|
328
|
-
- `target` — work-item ID (e.g. `STORY-042-01`).
|
|
329
|
-
- `path` — absolute path to the raw source file.
|
|
330
|
-
|
|
331
|
-
---
|
|
332
|
-
|
|
333
|
-
### §10.7 Idempotency Rule
|
|
334
|
-
|
|
335
|
-
Re-ingesting a file is a no-op when **both** of the following are true:
|
|
336
|
-
|
|
337
|
-
(a) The file content is byte-identical to the content at last ingest.
|
|
338
|
-
(b) `git log -1 --format=%H -- <raw_path>` matches the `last_ingest_commit` stored in the page frontmatter.
|
|
339
|
-
|
|
340
|
-
Drift detection is commit-SHA comparison — not content hashing — eliminating any dependency on external hash storage or EPIC-001 infrastructure. If either condition is false, ingest proceeds and the page is overwritten.
|
|
341
|
-
|
|
342
|
-
---
|
|
343
|
-
|
|
344
|
-
### §10.8 Gate Enforcement
|
|
345
|
-
|
|
346
|
-
`cleargate wiki lint` exits non-zero and blocks execution at:
|
|
347
|
-
|
|
348
|
-
- **Gate 1 (Initiative approval):** lint must pass before the agent may proceed past the Initiative halt.
|
|
349
|
-
- **Gate 3 (Push):** lint must pass before `cleargate_push_item` is called.
|
|
350
|
-
|
|
351
|
-
Lint checks performed:
|
|
352
|
-
|
|
353
|
-
- Orphan pages — wiki pages whose `raw_path` no longer exists.
|
|
354
|
-
- Missing backlinks — parent/child pairs without bidirectional `[[ID]]` references.
|
|
355
|
-
- `raw_path` ↔ `repo` tag mismatch — `repo` field does not match the prefix of `raw_path`.
|
|
356
|
-
- Stale `last_ingest_commit` — stored SHA differs from current `git log -1` for the raw file.
|
|
357
|
-
- Invalidated topic citations — a `wiki/topics/*.md` page cites an item that has been archived or status-set to cancelled.
|
|
358
|
-
|
|
359
|
-
The gate-check hook (§12.5) runs before ingest; staleness (§12.4) is a lint error.
|
|
360
|
-
|
|
361
|
-
---
|
|
362
|
-
|
|
363
|
-
### §10.9 Fallback Chain
|
|
364
|
-
|
|
365
|
-
Ingest reliability follows a three-level fallback:
|
|
366
|
-
|
|
367
|
-
1. **PostToolUse hook (primary)** — fires automatically on every Write or Edit under `.cleargate/delivery/**`. No agent action required.
|
|
368
|
-
2. **Protocol rule (secondary)** — when the hook is unavailable (e.g. non-Claude-Code environment), every agent that writes a raw delivery file must explicitly invoke the `cleargate-wiki-ingest` subagent before returning.
|
|
369
|
-
3. **Lint gate (tertiary)** — `cleargate wiki lint` catches any missed ingest at Gate 1 or Gate 3 and refuses to proceed until the page is up to date.
|
|
370
|
-
|
|
371
|
-
---
|
|
372
|
-
|
|
373
|
-
### §10.10 Wiki Contradiction Detection
|
|
374
|
-
|
|
375
|
-
After each ingest pass recompiles synthesis pages (Phase 3), the ingest subagent runs an optional Phase 4 contradiction check on any freshly ingested page whose `status` is `Draft` or `In Review`. Phase 4 is synchronous and advisory — it never blocks ingest, never causes a non-zero exit, and never modifies anything other than the wiki page's `last_contradict_sha` field and the append-only `wiki/contradictions.md` log.
|
|
376
|
-
|
|
377
|
-
Rules:
|
|
378
|
-
|
|
379
|
-
- **Trigger point.** Phase 4 fires after Phase 3 (synthesis recompile) completes, once per ingested page, only when the page status is `Draft` or `In Review`. All other statuses (`Approved`, `Done`, `Active`, etc.) are skipped silently.
|
|
380
|
-
- **Neighborhood rule.** The neighborhood for a given draft page consists of: (1) all pages explicitly cited via `[[ID]]` in the raw draft body, (2) the draft's parent epic page, and (3) any sibling stories under the same parent epic. The neighborhood is capped at 12 pages; when more than 12 qualify, the closest-cited pages take priority and the finding record sets `truncated: true`.
|
|
381
|
-
- **Idempotency rule.** Phase 4 is skipped when `last_contradict_sha` stored on the wiki page equals `git log -1 --format=%H -- <raw_path>` at the moment Phase 4 would run. A match means the draft has not changed since the last contradiction check; no re-check is needed.
|
|
382
|
-
- **Status filter.** Only `Draft` and `In Review` raw-file statuses trigger Phase 4. The filter reads the raw frontmatter `status` field, not the wiki page's emoji status field.
|
|
383
|
-
- **Advisory exit.** Phase 4 always exits 0. Contradiction findings are written to `wiki/contradictions.md` as an append-only YAML log (see §10.10 schema). No gate is blocked. A future enforcing-mode proposal must clear the calibration precondition (see below) before Phase 4 may exit non-zero.
|
|
384
|
-
- **Subagent contract.** Phase 4 invokes the `cleargate-wiki-contradict` subagent with `{ draft_path, neighborhood: string[] }` inputs. The subagent emits zero or more `contradiction: <draft-id> vs <neighbor-id> · <claim-summary ≤80 chars>` lines plus one paragraph of reasoning per finding, then exits 0.
|
|
385
|
-
- **Log schema.** Each finding appended to `wiki/contradictions.md` has the keys: `draft`, `neighbor`, `claim`, `ingest_sha`, `truncated`, `label`. The `label` field is `null` until a human applies `true-positive`, `false-positive`, or `nitpick`.
|
|
386
|
-
|
|
387
|
-
**Calibration plan.** Phase 4 enters advisory-only mode unconditionally for an initial 30-day calibration window. A future enforcing-mode proposal may be filed only after the advisory log contains at least 20 human-labeled findings with a true-positive rate of ≥ 80%. Until that precondition is met, any proposal to make Phase 4 exit non-zero is out of scope.
|
|
388
|
-
|
|
389
|
-
---
|
|
390
|
-
|
|
391
|
-
## 11. Document Metadata Lifecycle
|
|
392
|
-
|
|
393
|
-
Every work item file managed by ClearGate carries timestamp and version fields that track when it was created, last modified, and last pushed to the remote PM tool. This section defines those fields, how they are populated, and when they are frozen.
|
|
394
|
-
|
|
395
|
-
---
|
|
396
|
-
|
|
397
|
-
### §11.1 Field Semantics
|
|
398
|
-
|
|
399
|
-
| Field | Type | Description |
|
|
400
|
-
|---|---|---|
|
|
401
|
-
| `created_at` | ISO 8601 UTC string | Timestamp set once on first `cleargate stamp` invocation. Never updated after creation. |
|
|
402
|
-
| `updated_at` | ISO 8601 UTC string | Timestamp updated on every `cleargate stamp` invocation that changes the file. Equal to `created_at` at creation time. |
|
|
403
|
-
| `created_at_version` | string | Codebase version string at time of first stamp. See §11.3 for format. Never updated after creation. |
|
|
404
|
-
| `updated_at_version` | string | Codebase version string at time of most recent stamp. Equal to `created_at_version` at creation time. |
|
|
405
|
-
| `server_pushed_at_version` | string \| null | Codebase version string at the time this file was last successfully pushed via `cleargate_push_item`. `null` until the first push succeeds. Present on write-template files (epic/story/bug/CR/proposal) only. |
|
|
406
|
-
|
|
407
|
-
---
|
|
408
|
-
|
|
409
|
-
### §11.2 Stamp Invocation Rule
|
|
410
|
-
|
|
411
|
-
After any Write or Edit operation on a file under `.cleargate/delivery/`, the author must invoke:
|
|
412
|
-
|
|
413
|
-
```
|
|
414
|
-
cleargate stamp <path>
|
|
415
|
-
```
|
|
416
|
-
|
|
417
|
-
This updates `updated_at` and `updated_at_version` in place. The `created_at` and `created_at_version` fields are set on the first invocation and are never overwritten thereafter.
|
|
418
|
-
|
|
419
|
-
In Claude Code environments, a PostToolUse hook fires automatically on Write/Edit under `.cleargate/delivery/**` and calls `cleargate stamp` without any agent action (hook wiring is STORY-008-06 scope, M3). Until that hook is active, every agent that writes a delivery file must call `cleargate stamp` explicitly before returning.
|
|
420
|
-
|
|
421
|
-
---
|
|
422
|
-
|
|
423
|
-
### §11.3 Dirty-SHA Convention
|
|
424
|
-
|
|
425
|
-
The version string embedded in `created_at_version` and `updated_at_version` is produced by `getCodebaseVersion()` (STORY-001-03). Its format follows this precedence:
|
|
426
|
-
|
|
427
|
-
1. If inside a git repo and `git status --porcelain` is non-empty (uncommitted changes present): `<short-sha>-dirty` (e.g. `a3f2e91-dirty`).
|
|
428
|
-
2. If inside a git repo and the working tree is clean: `<short-sha>` (e.g. `a3f2e91`), where `<short-sha>` is the 7-character output of `git rev-parse --short HEAD`.
|
|
429
|
-
3. If no git repo is present but a `package.json` is found in an ancestor directory: the `version` field value from that file (e.g. `1.4.2`).
|
|
430
|
-
4. If neither is available: the literal string `"unknown"`, and a warning is emitted to stderr.
|
|
431
|
-
|
|
432
|
-
The `-dirty` suffix signals that the version string was captured from a working tree with uncommitted changes. Consumers comparing version strings must treat `a3f2e91-dirty` and `a3f2e91` as belonging to the same base commit but different workspace states.
|
|
433
|
-
|
|
434
|
-
---
|
|
435
|
-
|
|
436
|
-
### §11.4 Archive Immutability
|
|
437
|
-
|
|
438
|
-
Files that have been moved to `.cleargate/delivery/archive/` are frozen. `cleargate stamp` is a no-op on any path matching `.cleargate/delivery/archive/`. No fields are written, no file bytes change.
|
|
439
|
-
|
|
440
|
-
Rationale: archived files represent the accepted state at push time. Retroactively updating their timestamps would break the audit trail used by the wiki lint stale-detection check (§11.6).
|
|
441
|
-
|
|
442
|
-
---
|
|
443
|
-
|
|
444
|
-
### §11.5 Git-Absent Fallback
|
|
445
|
-
|
|
446
|
-
When `cleargate stamp` runs outside a git repository (e.g. a freshly unzipped scaffold before `git init`), the version resolution falls back in order:
|
|
447
|
-
|
|
448
|
-
1. Walk up from the current working directory looking for a `package.json`. If found, use its `version` field as the version string.
|
|
449
|
-
2. If no `package.json` ancestor exists, use the literal string `"unknown"` and emit a warning to stderr: `"cleargate stamp: cannot determine codebase version — no git repo or package.json found"`.
|
|
450
|
-
|
|
451
|
-
The `"unknown"` value is valid frontmatter; downstream consumers (stamp, lint, wiki-ingest) must accept it without error.
|
|
452
|
-
|
|
453
|
-
---
|
|
454
|
-
|
|
455
|
-
### §11.6 Stale Detection Threshold
|
|
456
|
-
|
|
457
|
-
A wiki page for a work item is considered **stale** when the following condition holds:
|
|
458
|
-
|
|
459
|
-
> The number of merge commits in `git log --merges <updated_at_version>..HEAD -- <raw_path>` is ≥ 1.
|
|
460
|
-
|
|
461
|
-
That is: if at least one merge commit has landed on the default branch since the file was last stamped, the wiki page is out of date and `cleargate wiki lint` reports a stale-detection violation.
|
|
462
|
-
|
|
463
|
-
Implementation notes:
|
|
464
|
-
- `updated_at_version` must be a resolvable git ref (short SHA or tag). If the value is `"unknown"` or `"strategy-phase-pre-init"`, lint skips the stale check for that file and emits a warning rather than an error.
|
|
465
|
-
- The `-dirty` suffix is stripped before resolving the ref: `a3f2e91-dirty` → `a3f2e91`.
|
|
466
|
-
- This check is consumed by `cleargate wiki lint` (STORY-008-07) and the wiki-ingest subagent's idempotency evaluation (§10.7).
|
|
467
|
-
|
|
468
|
-
---
|
|
469
|
-
|
|
470
|
-
### §11.7 Hierarchy Keys
|
|
471
|
-
|
|
472
|
-
Two optional frontmatter keys declare canonical hierarchy for every work item (STORY-015-06):
|
|
473
|
-
|
|
474
|
-
- `parent_cleargate_id: <string | null>` — the canonical ClearGate ID of the parent work item (e.g. `"EPIC-022"`). Use for items that belong to an epic or parent story. Null for top-level items.
|
|
475
|
-
- `sprint_cleargate_id: <string | null>` — the canonical ClearGate ID of the owning sprint (e.g. `"SPRINT-15"`). Null for off-sprint or speculative items.
|
|
476
|
-
|
|
477
|
-
**Relationship to legacy keys.** The existing fields `parent_ref`, `parent_epic_ref`, `sprint_id`, and `sprint` remain the **authoritative** source of parent/sprint membership until a future deprecation sprint explicitly retires them. `parent_cleargate_id` and `sprint_cleargate_id` are additive mirrors — consumers must not assume both forms are always present simultaneously. A future deprecation notice will be added to this section when the legacy keys are retired.
|
|
478
|
-
|
|
479
|
-
**Propagation.** The `cleargate push` command forwards both keys into the `cleargate_push_item` MCP call payload via the existing `payload.*` shallow-clone path. The `cleargate wiki ingest` command copies them verbatim into the compiled wiki page frontmatter. The backfill script `.cleargate/scripts/backfill_hierarchy.mjs` sniffs legacy keys to populate missing values one-time on existing corpus files.
|
|
480
|
-
|
|
481
|
-
**Idempotency contract.** Both keys default to `null` in templates. The backfill script skips any file where both keys are already non-null. Re-running the backfill is a byte-identical no-op.
|
|
482
|
-
|
|
483
|
-
---
|
|
484
|
-
|
|
485
|
-
## 12. Token Cost Stamping & Readiness Gates
|
|
486
|
-
|
|
487
|
-
### §12.1 Overview
|
|
488
|
-
Two-capability bundle: (1) `draft_tokens` frontmatter stamp populated by a PostToolUse hook from the sprint token ledger; (2) closed-set predicate engine + `cleargate gate check` CLI writing `cached_gate_result` into frontmatter, blocking wiki-lint on enforcing types (Epic/Story/CR/Bug), advising on Proposals.
|
|
489
|
-
|
|
490
|
-
### §12.2 Token stamp semantics
|
|
491
|
-
- Idempotent within a session (re-stamp = no-op when last_stamp + totals unchanged).
|
|
492
|
-
- Accumulative across sessions: `sessions[]` gains one entry per session; top-level totals are sums; `model` is comma-joined across distinct values.
|
|
493
|
-
- Missing ledger row → `draft_tokens:{…null…, stamp_error:"<reason>"}` — never fabricate.
|
|
494
|
-
- Archive-path stamping is a no-op (freeze-on-archive).
|
|
495
|
-
- Sprint files record only planning-phase tokens; story tokens attribute to their own files (no double-count).
|
|
496
|
-
|
|
497
|
-
### §12.3 Readiness gates
|
|
498
|
-
- Central definitions: `.cleargate/knowledge/readiness-gates.md` keyed by `{work_item_type, transition}`.
|
|
499
|
-
- Predicates are a CLOSED set (6 shapes): `frontmatter(...)`, `body contains`, `section(N) has count`, `file-exists`, `link-target-exists`, `status-of`. No shell-out, no network.
|
|
500
|
-
- Severity: Proposal = advisory (exit 0, records `pass:false` without blocking). Epic/Story/CR/Bug = enforcing (exit non-zero at CLI; wiki lint refuses).
|
|
501
|
-
|
|
502
|
-
### §12.4 Enforcement points
|
|
503
|
-
- v1: `wiki lint` only. MCP-side `push_item` enforcement is deferred post-PROP-007.
|
|
504
|
-
- Staleness: `cached_gate_result.last_gate_check < updated_at` → lint error for ALL types (catches silent hook failures).
|
|
505
|
-
|
|
506
|
-
### §12.5 Hook lifecycle
|
|
507
|
-
- PostToolUse `stamp-and-gate.sh` chains `stamp-tokens → gate check → wiki ingest` on every Write/Edit under `.cleargate/delivery/**`. Exit always 0.
|
|
508
|
-
- SessionStart `session-start.sh` pipes `cleargate doctor --session-start` (≤100 LLM-tokens, ≤10 items + overflow pointer) into context.
|
|
509
|
-
- Every invocation logs to `.cleargate/hook-log/gate-check.log`; `cleargate doctor` surfaces last-24h failures.
|
|
510
|
-
|
|
511
|
-
### §12.6 Cross-references
|
|
512
|
-
- §4 Phase Gates: "Gate 2 (Ambiguity) is machine-checked via `cleargate gate check`; see §12."
|
|
513
|
-
- §10.8 Wiki-lint enforcement: extended by the gate-check hook; staleness check added per §12.4.
|
|
514
|
-
|
|
515
|
-
---
|
|
516
|
-
|
|
517
|
-
## 13. Scaffold Manifest & Uninstall
|
|
518
|
-
|
|
519
|
-
### §13.1 Overview
|
|
520
|
-
Three-surface model: package manifest (shipped in `@cleargate/cli`), install snapshot (`.cleargate/.install-manifest.json` written at init), current state (live FS). Drift is classified pairwise into 4 states (clean / user-modified / upstream-changed / both-changed) + `untracked` for user-artifact tier. SHA256 over normalized content (LF / UTF-8 no-BOM / trailing-newline) is the file identifier.
|
|
521
|
-
|
|
522
|
-
### §13.2 Install
|
|
523
|
-
`cleargate init` copies the bundled payload, then writes `.cleargate/.install-manifest.json`:
|
|
524
|
-
|
|
525
|
-
```json
|
|
526
|
-
{
|
|
527
|
-
"cleargate_version": "0.2.0",
|
|
528
|
-
"installed_at": "2026-04-19T10:00:00Z",
|
|
529
|
-
"files": [
|
|
530
|
-
{"path": ".cleargate/knowledge/cleargate-protocol.md", "sha256": "…", "tier": "protocol", "overwrite_policy": "merge-3way", "preserve_on_uninstall": "default-remove"}
|
|
531
|
-
]
|
|
532
|
-
}
|
|
533
|
-
```
|
|
534
|
-
|
|
535
|
-
If a `.cleargate/.uninstalled` marker exists at init time, init prompts "Detected previous ClearGate install … Restore preserved items? [Y/n]". Y = blind-copy preserved paths back into the new install (v1); mismatches log a warning and do not fail.
|
|
536
|
-
|
|
537
|
-
### §13.3 Drift detection
|
|
538
|
-
`cleargate doctor --check-scaffold` compares the three surfaces and writes `.cleargate/.drift-state.json` (daily-throttled refresh). SessionStart-triggered refresh runs at most once per day. Agent never auto-overwrites on upstream-changed drift — it emits a one-line advisory at triage; `cleargate upgrade` is always human-initiated. `user-artifact` tier (sha256: null) is silently skipped in drift output; surfaces only in uninstall preview.
|
|
539
|
-
|
|
540
|
-
### §13.4 Upgrade
|
|
541
|
-
`cleargate upgrade [--dry-run] [--yes] [--only <tier>]` drives a three-way merge for `merge-3way` policy files. Per-file prompt: `[k]eep mine / [t]ake theirs / [e]dit in $EDITOR`. Execution is incremental: successes are committed to disk + `.install-manifest.json` updated before the next file is processed; a mid-run error leaves earlier successes intact.
|
|
542
|
-
|
|
543
|
-
### §13.5 Uninstall
|
|
544
|
-
`cleargate uninstall [--dry-run] [--preserve …] [--remove …] [--yes] [--path <dir>] [--force]` is preservation-first. Defaults: `.cleargate/delivery/archive/**`, `FLASHCARD.md`, `sprint-runs/*/REPORT.md`, `pending-sync/**` → keep. `.cleargate/knowledge/`, `.cleargate/templates/`, `.cleargate/wiki/`, `.cleargate/hook-log/` → remove. Safety rails: typed confirmation (project name), single-target (no recursion into nested `.cleargate/`), refuse on uncommitted manifest-tracked changes without `--force`, CLAUDE.md marker-presence check. Always-removed (no prompt): `.claude/agents/*.md`, ClearGate hooks, `flashcard/` skill, CLAUDE.md CLEARGATE block, `@cleargate/cli` in `package.json`, `.install-manifest.json`, `.drift-state.json`. Writes `.cleargate/.uninstalled` marker:
|
|
545
|
-
|
|
546
|
-
```json
|
|
547
|
-
{
|
|
548
|
-
"uninstalled_at": "2026-04-19T11:00:00Z",
|
|
549
|
-
"prior_version": "0.2.0",
|
|
550
|
-
"preserved": [".cleargate/FLASHCARD.md", ".cleargate/delivery/archive/**"],
|
|
551
|
-
"removed": [".cleargate/knowledge/cleargate-protocol.md"]
|
|
552
|
-
}
|
|
553
|
-
```
|
|
554
|
-
|
|
555
|
-
Future `cleargate init` in the same dir detects this marker and offers restore.
|
|
556
|
-
|
|
557
|
-
### §13.6 Publishing notes
|
|
558
|
-
`MANIFEST.json` is built at `npm run build` (prebuild step in `cleargate-cli/package.json`) and shipped in the npm tarball (`files[]`). Never computed at install time. `generate-changelog-diff.ts` diffs `MANIFEST.json` between the previous published version and the current one at release time; CHANGELOG.md auto-opens with a "Scaffold files changed" block per release. Content-identical entries (path-moved-only, metadata-changed-only) are collapsed to avoid noise.
|
|
559
|
-
|
|
560
|
-
---
|
|
561
|
-
|
|
562
|
-
## 14. Multi-Participant Sync
|
|
563
|
-
|
|
564
|
-
### §14.1 Sync matrix & authority split
|
|
565
|
-
|
|
566
|
-
**Rule:** Remote is authoritative for status, assignees, and comments; local is authoritative for work-item body.
|
|
567
|
-
|
|
568
|
-
When both sides change the same field, the authoritative side wins without prompt (except body+body — see §14.2). This split prevents accidental overwrites of carefully authored local prose while still tracking PM-tool state transitions faithfully. Source: EPIC-010 §4 authority table; `cleargate-cli/src/commands/sync.ts` conflict-detector snapshot shape.
|
|
569
|
-
|
|
570
|
-
### §14.2 Conflict resolution
|
|
571
|
-
|
|
572
|
-
**Rule:** content+content → interactive 3-way merge prompt; status+status → remote-wins silently; delete+edit (either direction) → refuse; unrecognized conflict shape → `halt`.
|
|
573
|
-
|
|
574
|
-
Nine conflict states are recognized (`content-content`, `status-status`, `remote-delete-local-edit`, `local-delete-remote-edit`, `remote-only`, `local-only`, `remote-status-only`, `local-content-only`, `unknown`). Resolution values are `three-way-merge`, `remote-wins`, `local-wins`, `refuse`, `halt`, `remote-only-apply`, `local-only-apply`. The `halt` resolution surfaces an actionable error rather than silently discarding data. Source: `cleargate-cli/src/lib/conflict-detector.ts`; `cleargate-cli/src/commands/sync.ts:307-367`.
|
|
575
|
-
|
|
576
|
-
### §14.3 Sync ordering invariant
|
|
577
|
-
|
|
578
|
-
**Rule:** `cleargate sync` MUST execute pull → classify → resolve → push in that order; reversal amplifies conflicts.
|
|
579
|
-
|
|
580
|
-
Executing a push before all pulls are complete risks overwriting a remote state change that the local resolve step would have otherwise detected. The 6-step driver enforces this order at the code level; a unit test asserts step ordering as a dataflow invariant. Source: `cleargate-cli/src/commands/sync.ts` driver doc comment (steps 1–6); R2 mitigation.
|
|
581
|
-
|
|
582
|
-
### §14.4 Identity resolution precedence
|
|
583
|
-
|
|
584
|
-
**Rule:** `.cleargate/.participant.json` → `CLEARGATE_USER` env → `git config user.email` → `host+user` fallback.
|
|
585
|
-
|
|
586
|
-
Identity is per-repo, not global, so two participants on the same machine with different `.participant.json` files get distinct attribution. The env var override allows CI or scripted sync. Source: `cleargate-cli/src/lib/identity.ts`; R5 mitigation.
|
|
587
|
-
|
|
588
|
-
### §14.5 Stakeholder-authored proposal flow
|
|
589
|
-
|
|
590
|
-
**Rule:** Remote items labeled `cleargate:proposal` (configurable via `CLEARGATE_PROPOSAL_LABEL` env) and absent locally land in `pending-sync/PROPOSAL-NNN-remote-<slug>.md` with `source: "remote-authored"` and `approved: false`.
|
|
591
|
-
|
|
592
|
-
This prevents external stakeholders from bypassing the approval gate: the proposal arrives locally for human review before any push. The label name is configurable so teams can map to their own PM-tool taxonomy. Source: `cleargate-cli/src/lib/intake.ts`; `cleargate-cli/src/commands/sync.ts:167-183`.
|
|
593
|
-
|
|
594
|
-
### §14.6 Comment policy
|
|
595
|
-
|
|
596
|
-
**Rule:** Comments pull as read-only snapshots, active items only (current sprint + last 30 days), rendered under `## Remote comments` with literal-string delimiters. Never pushed upstream.
|
|
597
|
-
|
|
598
|
-
Pulling comments for stale items wastes tokens and clutters archives; the 30-day window keeps recent feedback visible. The `## Remote comments` block uses byte-stable literal delimiters so repeated pulls are idempotent. A 429 rate-limit on any single item causes that item to be skipped silently. Source: `cleargate-cli/src/lib/wiki-comments-render.ts`; `cleargate-cli/src/lib/active-criteria.ts`; R4/R6 mitigations.
|
|
599
|
-
|
|
600
|
-
### §14.7 Push preconditions
|
|
601
|
-
|
|
602
|
-
**Rule:** `cleargate_push_item` requires `payload.approved === true` unless the caller passes `skipApprovedGate: true` (reserved for `sync_status` internal callers). `pushed_by` is stamped from `members.email` via JWT `sub` → member lookup, NOT the raw JWT `sub` value.
|
|
603
|
-
|
|
604
|
-
The `skipApprovedGate` bypass is an internal escape hatch for status-only updates triggered by `cleargate_sync_status`; it is not exposed as a public CLI flag. The email lookup ensures human-readable attribution independent of UUID-based JWT subjects. Source: `mcp/src/tools/push-item.ts`; flashcard `#mcp #jwt #attribution`.
|
|
605
|
-
|
|
606
|
-
### §14.8 Revert policy
|
|
607
|
-
|
|
608
|
-
**Rule:** `cleargate push --revert <id>` soft-reverts by calling `cleargate_sync_status` with `new_status: "archived-without-shipping"`; it never deletes the remote item. `--force` is required when local `status: done`.
|
|
609
|
-
|
|
610
|
-
Soft revert preserves audit history on the PM-tool side. Refusing to revert done items without `--force` prevents accidental archival of shipped work. Source: `cleargate-cli/src/commands/push.ts` revert branch; `cleargate-cli/src/cli.ts:268-273`.
|
|
611
|
-
|
|
612
|
-
### §14.9 Sync cadence
|
|
613
|
-
|
|
614
|
-
**Rule:** All sync actions are manual (`cleargate sync` / `cleargate pull <id>` / `cleargate push <file>`). The SessionStart hook SUGGESTS via `cleargate sync --check` — it never auto-pulls or auto-pushes. MCP probes are throttled to at most one per 24 hours per repo.
|
|
615
|
-
|
|
616
|
-
Auto-push without human review would bypass the approval gate; auto-pull would overwrite in-progress local edits without conflict detection. The 24-hour throttle prevents session-start latency accumulation. Throttle state is stored in `.cleargate/.sync-marker.json` with schema `{ "last_check": "<ISO-8601>" }` (v1; unknown keys are ignored on read for forward compatibility). Source: `.claude/hooks/session-start.sh`; `.cleargate/.sync-marker.json`; R7 mitigation.
|
|
617
|
-
|
|
618
|
-
## 21. Status Vocabulary
|
|
619
|
-
|
|
620
|
-
Raw work-item frontmatter `status:` values must be drawn from this canonical set:
|
|
621
|
-
|
|
622
|
-
| Status | Meaning |
|
|
623
|
-
|---|---|
|
|
624
|
-
| `Draft` | Newly authored; not yet ambiguity-gated |
|
|
625
|
-
| `Ready` | Ambiguity gate passed; eligible for sprint planning |
|
|
626
|
-
| `Approved` | Epic approved for execution |
|
|
627
|
-
| `Planned` | Sprint planned; not yet started |
|
|
628
|
-
| `Active` | Work in progress |
|
|
629
|
-
| `Completed` | Shipped (sprints, epics) |
|
|
630
|
-
| `Done` | Shipped (stories) — treated as alias of `Completed` for terminal-status checks |
|
|
631
|
-
| `Abandoned` | Work deliberately stopped without shipping. The artifact stays in `archive/` for historical record. Not eligible for the Active index. |
|
|
632
|
-
| `Closed` | Closed without shipping (administrative close) |
|
|
633
|
-
| `Resolved` | Bug or CR confirmed resolved |
|
|
634
|
-
|
|
635
|
-
### §21.1 Index Token Ceiling
|
|
636
|
-
|
|
637
|
-
`cleargate wiki lint` enforces a ceiling on `.cleargate/wiki/index.md` size, measured as `bytes ÷ 4` approximate tokens. Default ceiling: `8000`. Override via `.cleargate/config.yml`:
|
|
638
|
-
|
|
639
|
-
```yaml
|
|
640
|
-
wiki:
|
|
641
|
-
index_token_ceiling: 8000
|
|
642
|
-
```
|
|
643
|
-
|
|
644
|
-
Exceeding the ceiling fails `cleargate wiki lint` (enforcement mode). Under `--suggest`, the usage percentage is reported but the check does not fail. Reference: EPIC-015.
|
|
645
|
-
|
|
646
|
-
### §21.2 Ingest Bucket Allowlist
|
|
647
|
-
|
|
648
|
-
By default the wiki ingests every bucket (`epics`, `stories`, `sprints`, `proposals`, `initiatives`, `crs`, `bugs`). A repo can narrow this to an allowlist via `.cleargate/config.yml`:
|
|
649
|
-
|
|
650
|
-
```yaml
|
|
651
|
-
wiki:
|
|
652
|
-
ingest_buckets:
|
|
653
|
-
- epics
|
|
654
|
-
- sprints # sprint reports
|
|
655
|
-
- crs
|
|
656
|
-
- bugs
|
|
657
|
-
- initiatives
|
|
658
|
-
```
|
|
659
|
-
|
|
660
|
-
When set, only the listed buckets get per-item wiki pages, index rows, and synthesis listings — `cleargate wiki build`, `cleargate wiki ingest`, and the PostToolUse ingest hook all skip every other bucket (exit 0, no-op). Omit the key entirely to ingest all buckets. This is how a repo keeps high-churn `stories` (and unused `proposals`) out of the wiki while still tracking them in the raw delivery tree and sprint reports.
|
|
661
|
-
|
|
662
|
-
---
|
|
663
|
-
|
|
664
|
-
## Type & Payload Contract
|
|
665
|
-
|
|
666
|
-
Every item pushed to the MCP server (`cleargate_push_item`) must conform to the following contract. Adapter authors implementing new PM-tool integrations MUST satisfy all requirements below before the server accepts the payload.
|
|
667
|
-
|
|
668
|
-
### Open-type validator
|
|
669
|
-
|
|
670
|
-
`type` is validated as an open vocabulary (new types do not require a server upgrade):
|
|
671
|
-
|
|
672
|
-
```
|
|
673
|
-
z.string().min(1).max(64).regex(/^[a-z][a-z0-9_-]*$/)
|
|
674
|
-
```
|
|
675
|
-
|
|
676
|
-
Applied after lowercase-normalize. Types that fail this regex are rejected at the MCP transport layer with an L1 `TYPE_INVALID` error.
|
|
677
|
-
|
|
678
|
-
### KNOWN_TYPES — advisory registry (8 entries)
|
|
679
|
-
|
|
680
|
-
These 8 types have first-class gate and reporting support. Any type outside this list passes validation but triggers an L2 `TYPE_UNKNOWN` warning in the server log.
|
|
681
|
-
|
|
682
|
-
| Type | Description |
|
|
683
|
-
|---|---|
|
|
684
|
-
| `initiative` | High-level strategic investment |
|
|
685
|
-
| `epic` | Feature-level work breakdown |
|
|
686
|
-
| `story` | Executable unit of work (one sprint, one commit) |
|
|
687
|
-
| `bug` | Defect report + fix |
|
|
688
|
-
| `cr` | Change request — scope amendment or approach change |
|
|
689
|
-
| `proposal` | Stakeholder-authored item awaiting triage |
|
|
690
|
-
| `sprint` | Sprint plan artifact |
|
|
691
|
-
| `sprint_report` | Sprint closeout report |
|
|
692
|
-
|
|
693
|
-
### RESERVED_PAYLOAD_KEYS (5 entries)
|
|
694
|
-
|
|
695
|
-
The following keys are set exclusively by the MCP server or the CLI sync engine. Callers MUST NOT include them in `payload`; the server strips or rejects them on receipt.
|
|
696
|
-
|
|
697
|
-
| Key | Owner | Reason |
|
|
698
|
-
|---|---|---|
|
|
699
|
-
| `cleargate_id` | CLI stamp engine | Must match the frontmatter `cleargate_id` — server validates; caller cannot override |
|
|
700
|
-
| `pushed_by` | Server | Set from JWT `sub` → member lookup; client-supplied value is ignored |
|
|
701
|
-
| `pushed_at` | Server | Set to server UTC timestamp; client-supplied value is ignored |
|
|
702
|
-
| `last_synced_body_sha` | Sync engine | Conflict-detection cursor; tampering causes spurious diffs |
|
|
703
|
-
| `_version` | Server | Internal optimistic-lock counter; client tampering causes 409 |
|
|
704
|
-
|
|
705
|
-
### Minimum payload contract
|
|
706
|
-
|
|
707
|
-
Every push MUST include:
|
|
708
|
-
|
|
709
|
-
| Key | Level | Note |
|
|
710
|
-
|---|---|---|
|
|
711
|
-
| `cleargate_id` | **Required (L1 error if absent)** | `TYPE-NNN` or 5-digit numeric (see formats below) |
|
|
712
|
-
| `type` | **Required (L1 error if absent)** | Open vocabulary, validated by regex above |
|
|
713
|
-
| `title` | Recommended (L2 warning if absent) | Human-readable item title |
|
|
714
|
-
| `status` | Recommended (L2 warning if absent) | From §21 status vocabulary |
|
|
715
|
-
|
|
716
|
-
### `payload.origin` convention
|
|
717
|
-
|
|
718
|
-
`payload.origin` identifies the surface that produced the push. Gates fire or are bypassed based on this value:
|
|
719
|
-
|
|
720
|
-
| Value pattern | Gate behavior |
|
|
721
|
-
|---|---|
|
|
722
|
-
| `cleargate-cli` | All readiness gates run (standard path) |
|
|
723
|
-
| `adapter:<vendor>` | Gates bypass — adapter is assumed to have already validated externally. Example: `adapter:linear`, `adapter:jira` |
|
|
724
|
-
| `system:<service>` | Gates bypass — system-generated push (e.g. `system:reporter`, `system:wiki-ingest`) |
|
|
725
|
-
| absent / null | Treated as `cleargate-cli`; gates run |
|
|
726
|
-
|
|
727
|
-
### `cleargate_id` formats (2 valid forms)
|
|
728
|
-
|
|
729
|
-
| Format | Pattern | Example | Used for |
|
|
730
|
-
|---|---|---|---|
|
|
731
|
-
| Type-prefixed | `TYPE-NNN` (TYPE = uppercase letters, NNN = 1–5 digits) | `STORY-027-05`, `EPIC-003` | All standard work items |
|
|
732
|
-
| 5-digit numeric | Exactly 5 decimal digits | `00042` | Legacy PM-tool remote IDs; internal migration use only |
|
|
733
|
-
|
|
734
|
-
### L1 errorCode taxonomy (7 codes)
|
|
735
|
-
|
|
736
|
-
L1 errors cause the MCP tool call to return a structured error payload with shape `{ code, message, hint }` and HTTP 422 (or equivalent MCP error).
|
|
737
|
-
|
|
738
|
-
| Code | Condition | Hint |
|
|
739
|
-
|---|---|---|
|
|
740
|
-
| `TYPE_INVALID` | `type` fails regex validation | Normalize to lowercase-kebab; max 64 chars |
|
|
741
|
-
| `ID_INVALID` | `cleargate_id` does not match either valid format | Use `TYPE-NNN` or 5-digit numeric |
|
|
742
|
-
| `ID_MISSING` | `cleargate_id` absent from payload | Required field — stamp it before push |
|
|
743
|
-
| `TYPE_MISSING` | `type` absent from payload | Required field |
|
|
744
|
-
| `RESERVED_KEY` | Payload contains a `RESERVED_PAYLOAD_KEYS` member | Remove the key; server owns it |
|
|
745
|
-
| `APPROVED_GATE` | `payload.approved !== true` and `skipApprovedGate` not set | Set `approved: true` after human sign-off |
|
|
746
|
-
| `PROJECT_NOT_FOUND` | JWT `project_id` claim has no matching project row | Re-join with a valid invite URL |
|
|
747
|
-
|
|
748
|
-
### L2 warningCode taxonomy (3 codes)
|
|
749
|
-
|
|
750
|
-
L2 warnings are non-blocking. The push succeeds, but the server appends `[advisory: <code>]` to the item body and logs the warning.
|
|
751
|
-
|
|
752
|
-
| Code | Condition | Field |
|
|
753
|
-
|---|---|---|
|
|
754
|
-
| `TITLE_MISSING` | `title` absent or empty | `title` |
|
|
755
|
-
| `STATUS_MISSING` | `status` absent or not in §21 vocabulary | `status` |
|
|
756
|
-
| `TYPE_UNKNOWN` | `type` is not in `KNOWN_TYPES` advisory registry | `type` |
|
|
757
|
-
|
|
758
|
-
---
|
|
759
|
-
|
|
760
|
-
## Codebase / PM-Tool Boundary
|
|
761
|
-
|
|
762
|
-
**Rule:** `cleargate-cli/src/**` and `.claude/**` MUST NOT import any PM-tool SDK. PM-tool adapters live exclusively in `mcp/src/adapters/`. Credentials and connection config live in admin DB rows, configured via the admin console UI.
|
|
763
|
-
|
|
764
|
-
### Rationale
|
|
765
|
-
|
|
766
|
-
ClearGate must remain PM-tool-agnostic at the CLI and agent-definition layer so that:
|
|
767
|
-
1. The CLI can be installed in any repo regardless of which PM tool the team uses.
|
|
768
|
-
2. Agent prompts (`.claude/**`) do not hard-code vendor assumptions.
|
|
769
|
-
3. A new PM-tool adapter can be added by dropping a file in `mcp/src/adapters/` without touching `cleargate-cli/` or `.claude/`.
|
|
770
|
-
|
|
771
|
-
### Forbidden import patterns
|
|
772
|
-
|
|
773
|
-
Any `import` or `require` statement in `cleargate-cli/src/**/*.ts` or `.claude/**/*.{ts,sh,md}` that references the following patterns fails CI:
|
|
774
|
-
|
|
775
|
-
| Pattern | PM tool |
|
|
776
|
-
|---|---|
|
|
777
|
-
| `@linear/sdk` | Linear |
|
|
778
|
-
| `linear-sdk` | Linear (alt package) |
|
|
779
|
-
| `jira-client` | Jira |
|
|
780
|
-
| `node-jira-client` | Jira (alt package) |
|
|
781
|
-
| `jira.js` | Jira (alt package) |
|
|
782
|
-
| `azure-devops` | Azure DevOps |
|
|
783
|
-
| `@atlassian/` | Atlassian family |
|
|
784
|
-
|
|
785
|
-
### Allowed surface for PM-tool code
|
|
786
|
-
|
|
787
|
-
`mcp/src/adapters/` is the only surface where PM-tool SDK imports are permitted. Each adapter file is responsible for importing its SDK, mapping ClearGate payload shapes to PM-tool API calls, and surfacing errors as structured MCP errors.
|
|
788
|
-
|
|
789
|
-
### CI enforcement
|
|
790
|
-
|
|
791
|
-
`scripts/ci-no-pm-sdk.mjs` scans the two forbidden surfaces and exits non-zero on any match. Run via:
|
|
792
|
-
|
|
793
|
-
```
|
|
794
|
-
node scripts/ci-no-pm-sdk.mjs
|
|
795
|
-
npm run check:no-pm-sdk
|
|
796
|
-
```
|
|
797
|
-
|
|
798
|
-
Comments (lines starting with `//`, `#`, `/*`, or `*`) are excluded from the scan. The script prints `✓ no forbidden PM-SDK imports` on a clean tree.
|
|
799
|
-
|
|
800
|
-
## 23. Parallel-Wave Execution Contract
|
|
801
|
-
|
|
802
|
-
Once a sprint declares `execution_mode: v2-parallel`, the Orchestrator may execute each
|
|
803
|
-
Architect-planned wave as one fire-and-forget `parallel()` Workflow of worktree-isolated
|
|
804
|
-
per-story **segments** that return a schema-typed verdict, consolidated at a serial
|
|
805
|
-
**barrier**. This section is the binding contract for that flow. It **inherits §22** — every
|
|
806
|
-
true-blocker rule, the autonomy contract, and the five true-blocker kinds carry over
|
|
807
|
-
unchanged; §23 only adds the parallel-execution-specific invariants.
|
|
808
|
-
|
|
809
|
-
**Kill-switch (zero behavior change).** `execution_mode: v2-serial` (the default for v2
|
|
810
|
-
sprints) OR `CLEARGATE_PARALLEL_WAVES=off` in the session env routes to the existing serial
|
|
811
|
-
five-dispatch Phase C loop with **zero behavior change** — no `launch_wave.mjs` invocation
|
|
812
|
-
occurs, and each story runs one at a time. The parallel-wave code never executes on the
|
|
813
|
-
kill-switch path. `execution_mode: v2-parallel` with no override selects the wave loop.
|
|
814
|
-
|
|
815
|
-
### 23.1 Segment verdict schema (discriminated union)
|
|
816
|
-
|
|
817
|
-
Every segment returns exactly one verdict object. The discriminant is `verdict`:
|
|
818
|
-
|
|
819
|
-
| Field | Type | Required | Notes |
|
|
820
|
-
|---|---|---|---|
|
|
821
|
-
| `verdict` | `'GREEN' \| 'ESCALATED' \| 'BLOCKED'` | always | the discriminant |
|
|
822
|
-
| `storyId` | string | always | the story this segment executed (e.g. `STORY-033-04`) |
|
|
823
|
-
| `runId` | string | always | the segment's stable, distinct `RUN_ID` |
|
|
824
|
-
| `devSha` | string | always | Developer commit SHA |
|
|
825
|
-
| `qaSha` | string | always | QA-Verify commit SHA |
|
|
826
|
-
| `archSha` | string | optional | Architect-pass SHA (standard lane v2 only) |
|
|
827
|
-
| `flashcards_flagged` | string[] | always (may be empty) | cards processed at the between-wave barrier |
|
|
828
|
-
| `counters` | `{ qa_bounces, arch_bounces, breaker_hits }` | always | all three numeric |
|
|
829
|
-
| `tokens` | `{ input, output, cache_creation, cache_read, model }` | always | per-segment cost the ledger consumes |
|
|
830
|
-
| `blocker` | `{ type, message }` | **required iff `verdict != GREEN`** | `type` ∈ the five §22 true-blocker kinds |
|
|
831
|
-
|
|
832
|
-
A `blocker.type` is one of the five §22 true-blocker kinds: `destructive`, `secret`,
|
|
833
|
-
`user-intent`, `technical-impossibility`, `spec-contradiction`. The validator
|
|
834
|
-
(`validateVerdicts`, exported from `.cleargate/scripts/launch_wave.mjs`) accepts a
|
|
835
|
-
well-formed verdict array and **raises a validation Error naming the offending `storyId`**
|
|
836
|
-
on any malformed verdict (missing required field, unknown `verdict` discriminant, or a
|
|
837
|
-
non-GREEN verdict without a valid `blocker`). The named segment is marked `ESCALATED` and
|
|
838
|
-
gets **no ledger row**; sibling GREEN verdicts consolidate normally.
|
|
839
|
-
|
|
840
|
-
### 23.2 RUN_ID attribution invariant
|
|
841
|
-
|
|
842
|
-
Per the STORY-033-01 spike, `agent()` fires `SubagentStop` with the **orchestrator**
|
|
843
|
-
transcript/session_id even under worktree isolation, and `PreToolUse:Task` never fires under
|
|
844
|
-
workflows — so per-agent transcript attribution is **dead**. The barrier therefore writes
|
|
845
|
-
**one ledger row per segment from `verdict.tokens`, keyed by the segment's `RUN_ID`**
|
|
846
|
-
(STORY-033-02 owns the write; this contract owns producing the `tokens` and the `RUN_ID`).
|
|
847
|
-
Each segment mints a **stable, distinct** `RUN_ID` so sibling segments never collide on the
|
|
848
|
-
RUN_ID-keyed `.session-totals.json` row, and so a `resumeFromRunId` replay re-keys the same
|
|
849
|
-
segment. The RUN_ID attribution invariant: per-story cost is attributed solely via the
|
|
850
|
-
verdict's `tokens` written at the barrier under the segment's `RUN_ID` — never via
|
|
851
|
-
`SubagentStop`, never via a dispatch marker.
|
|
852
|
-
|
|
853
|
-
### 23.3 Barrier consolidation + serial merge rule
|
|
854
|
-
|
|
855
|
-
At the barrier the Orchestrator, in order: (1) runs `validateVerdicts` over the returned
|
|
856
|
-
array; (2) processes the union of every segment's `flashcards_flagged[]` and writes the
|
|
857
|
-
`.processed-<hash>` markers **between waves** (the relocated flashcard gate — set
|
|
858
|
-
`SKIP_FLASHCARD_GATE=1` pre-launch, restore at the barrier); (3) **serially** merges each
|
|
859
|
-
GREEN `story/STORY-X` to `sprint/S-NN` — **one worktree at a time, never two concurrently**
|
|
860
|
-
(the shared sprint branch is a single-writer axis; per-worktree `.git` indexes mean the
|
|
861
|
-
pre-commit surface gate never races, but the merge does); (4) restores the prior
|
|
862
|
-
`SKIP_FLASHCARD_GATE` value. A mixed GREEN+ESCALATED wave merges the GREEN stories
|
|
863
|
-
immediately (serial), then resumes only the ESCALATED segment via `resumeFromRunId` — GREEN
|
|
864
|
-
segments short-circuit on resume (zero new ledger rows). Segments are **idempotent** so a
|
|
865
|
-
resume or partial-failure re-run produces no duplicate side effects.
|
|
866
|
-
|
|
867
|
-
### 23.4 In-segment true-blocker re-map (§22 inheritance)
|
|
868
|
-
|
|
869
|
-
A segment runs inside a `parallel()` Workflow that **cannot halt for a human mid-run**, so
|
|
870
|
-
the synchronous-Ask escalation form of §22 is **forbidden in-segment**. When a segment hits
|
|
871
|
-
a §22 destructive or secret condition (or any of the five true-blocker kinds), it RETURNS
|
|
872
|
-
`verdict: BLOCKED` with `blocker.type ∈ {destructive, secret, user-intent,
|
|
873
|
-
technical-impossibility, spec-contradiction}` and a `blocker.message`, and writes a blockers
|
|
874
|
-
report — it issues **no `AskUserQuestion`**. The Orchestrator halts the wave loop on the
|
|
875
|
-
`BLOCKED`/`ESCALATED` verdict and surfaces it to the human, then resumes via
|
|
876
|
-
`resumeFromRunId` after resolution. Fully autonomous up to that halt (§22 autonomy contract,
|
|
877
|
-
§6 Q3): once Gate 2 is signed off, every wave auto-launches with no per-wave "go"; only a
|
|
878
|
-
non-GREEN verdict interrupts.
|