@infinitedusky/indusk-mcp 0.7.2 → 0.8.5

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.
@@ -27,7 +27,34 @@ if (!filePath.endsWith("/impl.md") && !filePath.endsWith("\\impl.md")) {
27
27
 
28
28
  // Check for skip-gates escape hatch
29
29
  const newContent = toolInput.new_string ?? toolInput.content ?? "";
30
- if (newContent.includes("<!-- skip-gates -->")) {
30
+
31
+ // Read gate policy from the impl file and settings
32
+ function readGatePolicy() {
33
+ try {
34
+ const content = readFileSync(filePath, "utf-8");
35
+ const fmMatch = content.match(/^---\n([\s\S]*?)\n---\n/);
36
+ if (fmMatch) {
37
+ const policyMatch = fmMatch[1].match(/gate_policy:\s*(strict|ask|auto)/);
38
+ if (policyMatch) return policyMatch[1];
39
+ }
40
+ } catch {
41
+ // ignore
42
+ }
43
+ // Check project settings
44
+ try {
45
+ const settingsPath = `${event.cwd}/.claude/settings.json`;
46
+ const settings = JSON.parse(readFileSync(settingsPath, "utf-8"));
47
+ if (settings.indusk?.gate_policy) return settings.indusk.gate_policy;
48
+ } catch {
49
+ // ignore
50
+ }
51
+ return "ask"; // default
52
+ }
53
+
54
+ const gatePolicy = readGatePolicy();
55
+
56
+ // In strict mode, skip-gates escape hatch is not allowed
57
+ if (newContent.includes("<!-- skip-gates -->") && gatePolicy !== "strict") {
31
58
  process.exit(0);
32
59
  }
33
60
 
@@ -80,6 +107,22 @@ if (event.tool_name === "Edit" && oldContent) {
80
107
  process.exit(0);
81
108
  }
82
109
 
110
+ // Detect workflow type from content frontmatter
111
+ function detectWorkflow(content) {
112
+ const fmMatch = content.match(/^---\n([\s\S]*?)\n---\n/);
113
+ const fm = fmMatch ? fmMatch[1] : "";
114
+ const m = fm.match(/workflow:\s*(bugfix|refactor|feature|spike)/);
115
+ return m ? m[1] : "feature";
116
+ }
117
+
118
+ // Which gate types are required per workflow
119
+ const WORKFLOW_GATES = {
120
+ feature: ["verification", "context", "document"],
121
+ refactor: ["verification", "context", "document"],
122
+ bugfix: ["verification", "document"],
123
+ spike: [],
124
+ };
125
+
83
126
  // Parse phases from the NEW content (after edit) and OLD content (before edit)
84
127
  function parsePhases(content) {
85
128
  // Strip frontmatter
@@ -131,6 +174,8 @@ function parsePhases(content) {
131
174
  return phases;
132
175
  }
133
176
 
177
+ const workflow = detectWorkflow(fullContent);
178
+ const requiredGates = WORKFLOW_GATES[workflow] || WORKFLOW_GATES.feature;
134
179
  const oldPhases = parsePhases(fullContent);
135
180
  const newPhases = parsePhases(newFullContent);
136
181
 
@@ -171,15 +216,24 @@ for (const item of newlyChecked) {
171
216
  for (const phase of oldPhases) {
172
217
  if (phase.number >= item.phase) break;
173
218
 
219
+ const isOverridden = (text) =>
220
+ gatePolicy !== "strict" &&
221
+ (text.includes("(none needed)") ||
222
+ text.includes("(not applicable)") ||
223
+ text.includes("skip-reason:"));
224
+
174
225
  const uncheckedGates = phase.items.filter(
175
- (i) =>
176
- !i.checked && (i.gate === "verification" || i.gate === "context" || i.gate === "document"),
226
+ (i) => !i.checked && !isOverridden(i.text) && requiredGates.includes(i.gate),
177
227
  );
178
228
 
179
229
  if (uncheckedGates.length > 0) {
180
230
  const missing = uncheckedGates.map((i) => ` [${i.gate}] ${i.text}`).join("\n");
231
+ const skipHint =
232
+ gatePolicy === "strict"
233
+ ? "Gate policy is 'strict' — no overrides allowed.\n"
234
+ : "To skip a gate item, ask the user first, then mark with (none needed) or skip-reason: {why}\n";
181
235
  process.stderr.write(
182
- `Phase ${item.phase} blocked: complete Phase ${phase.number} gates first:\n${missing}\n`,
236
+ `Phase ${item.phase} blocked (policy: ${gatePolicy}): complete Phase ${phase.number} gates first:\n${missing}\n${skipHint}`,
183
237
  );
184
238
  process.exit(2);
185
239
  }
@@ -0,0 +1,235 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * PreToolUse hook: validates that impl phases have all four gate sections.
4
+ *
5
+ * Every phase must have: implementation items, Verification, Context, Document.
6
+ * Sections can opt out with (none needed), (not applicable), or skip-reason: {why}.
7
+ *
8
+ * Exit 0 = allow the edit
9
+ * Exit 2 = block the edit (stderr sent to agent as feedback)
10
+ */
11
+
12
+ import { readFileSync } from "node:fs";
13
+
14
+ // Read hook input from stdin
15
+ let input = "";
16
+ for await (const chunk of process.stdin) {
17
+ input += chunk;
18
+ }
19
+
20
+ const event = JSON.parse(input);
21
+ const toolInput = event.tool_input ?? {};
22
+ const filePath = toolInput.file_path ?? "";
23
+
24
+ // Fast path: not an impl.md file
25
+ if (!filePath.endsWith("/impl.md") && !filePath.endsWith("\\impl.md")) {
26
+ process.exit(0);
27
+ }
28
+
29
+ // Check for skip-gates escape hatch
30
+ const newContent = toolInput.new_string ?? toolInput.content ?? "";
31
+
32
+ // Read gate policy
33
+ function readGatePolicy() {
34
+ // Check the content being written for a gate_policy in frontmatter
35
+ const contentToCheck = toolInput.content ?? toolInput.new_string ?? "";
36
+ const fmMatch = contentToCheck.match(/gate_policy:\s*(strict|ask|auto)/);
37
+ if (fmMatch) return fmMatch[1];
38
+ // Check existing file
39
+ try {
40
+ const existing = readFileSync(filePath, "utf-8");
41
+ const existingFm = existing.match(/^---\n([\s\S]*?)\n---\n/);
42
+ if (existingFm) {
43
+ const m = existingFm[1].match(/gate_policy:\s*(strict|ask|auto)/);
44
+ if (m) return m[1];
45
+ }
46
+ } catch {
47
+ // ignore
48
+ }
49
+ // Check project settings
50
+ try {
51
+ const settingsPath = `${event.cwd}/.claude/settings.json`;
52
+ const settings = JSON.parse(readFileSync(settingsPath, "utf-8"));
53
+ if (settings.indusk?.gate_policy) return settings.indusk.gate_policy;
54
+ } catch {
55
+ // ignore
56
+ }
57
+ return "ask";
58
+ }
59
+
60
+ const gatePolicy = readGatePolicy();
61
+
62
+ if (newContent.includes("<!-- skip-gates -->") && gatePolicy !== "strict") {
63
+ process.exit(0);
64
+ }
65
+
66
+ // Determine the full new content after edit
67
+ let newFullContent;
68
+ if (event.tool_name === "Edit" && toolInput.old_string) {
69
+ try {
70
+ const diskContent = readFileSync(filePath, "utf-8");
71
+ newFullContent = diskContent.replace(toolInput.old_string, newContent);
72
+ } catch {
73
+ // File doesn't exist yet — will be created by Write
74
+ newFullContent = newContent;
75
+ }
76
+ } else if (event.tool_name === "Write") {
77
+ newFullContent = toolInput.content ?? "";
78
+ } else {
79
+ process.exit(0);
80
+ }
81
+
82
+ // Only validate if this edit is adding/modifying phase structure
83
+ // Check if the edit contains phase headers
84
+ const editContent = toolInput.new_string ?? toolInput.content ?? "";
85
+ const hasPhaseHeader = /###\s+Phase\s+\d+/.test(editContent);
86
+ const hasChecklistItem = /- \[ \]/.test(editContent);
87
+
88
+ // If the edit doesn't touch phase structure, allow it
89
+ if (!hasPhaseHeader && !hasChecklistItem) {
90
+ process.exit(0);
91
+ }
92
+
93
+ // Parse frontmatter to detect workflow type
94
+ const fmMatch = newFullContent.match(/^---\n([\s\S]*?)\n---\n/);
95
+ const frontmatter = fmMatch ? fmMatch[1] : "";
96
+ const body = fmMatch ? newFullContent.slice(fmMatch[0].length) : newFullContent;
97
+
98
+ // Detect workflow type from frontmatter (workflow: bugfix|refactor|feature)
99
+ // or infer from plan structure
100
+ const workflowMatch = frontmatter.match(/workflow:\s*(bugfix|refactor|feature|spike)/);
101
+ const workflow = workflowMatch ? workflowMatch[1] : "feature";
102
+
103
+ // Different workflows have different requirements
104
+ const requirements = {
105
+ feature: { verification: true, context: true, document: true },
106
+ refactor: { verification: true, context: true, document: true },
107
+ bugfix: { verification: true, context: false, document: true },
108
+ spike: { verification: false, context: false, document: false },
109
+ }[workflow];
110
+ const lines = body.split("\n");
111
+
112
+ const phases = [];
113
+ let currentPhase = null;
114
+ let currentSection = "implementation";
115
+
116
+ for (const line of lines) {
117
+ const phaseMatch = line.match(/^###\s+Phase\s+(\d+)[:\s]+(.*)/);
118
+ if (phaseMatch) {
119
+ if (currentPhase) phases.push(currentPhase);
120
+ currentPhase = {
121
+ number: parseInt(phaseMatch[1], 10),
122
+ name: phaseMatch[2].trim(),
123
+ hasImplementation: false,
124
+ hasVerification: false,
125
+ hasContext: false,
126
+ hasDocument: false,
127
+ verificationIsOptOut: false,
128
+ contextIsOptOut: false,
129
+ documentIsOptOut: false,
130
+ };
131
+ currentSection = "implementation";
132
+ continue;
133
+ }
134
+
135
+ if (!currentPhase) continue;
136
+
137
+ // Detect gate section headers
138
+ const verMatch = line.match(/^####\s+Phase\s+\d+\s+Verification\b/);
139
+ if (verMatch) {
140
+ currentPhase.hasVerification = true;
141
+ currentSection = "verification";
142
+ continue;
143
+ }
144
+
145
+ const ctxMatch = line.match(/^####\s+Phase\s+\d+\s+Context\b/);
146
+ if (ctxMatch) {
147
+ currentPhase.hasContext = true;
148
+ currentSection = "context";
149
+ continue;
150
+ }
151
+
152
+ const docMatch = line.match(/^####\s+Phase\s+\d+\s+Document\b/);
153
+ if (docMatch) {
154
+ currentPhase.hasDocument = true;
155
+ currentSection = "document";
156
+ continue;
157
+ }
158
+
159
+ // Check for implementation items
160
+ if (currentSection === "implementation" && /^-\s+\[[ x]\]/.test(line)) {
161
+ currentPhase.hasImplementation = true;
162
+ }
163
+
164
+ // Track opt-out content in gate sections
165
+ const isOptOutLine =
166
+ line.includes("(none needed)") ||
167
+ line.includes("(not applicable)") ||
168
+ line.includes("skip-reason:");
169
+ if (currentPhase && isOptOutLine) {
170
+ if (currentSection === "verification") currentPhase.verificationIsOptOut = true;
171
+ if (currentSection === "context") currentPhase.contextIsOptOut = true;
172
+ if (currentSection === "document") currentPhase.documentIsOptOut = true;
173
+ }
174
+
175
+ // Forward intelligence doesn't count as a gate
176
+ if (line.match(/^####\s+Phase\s+\d+\s+Forward Intelligence\b/)) {
177
+ currentSection = "fi";
178
+ }
179
+ }
180
+ if (currentPhase) phases.push(currentPhase);
181
+
182
+ // Check for opt-out content in gate sections
183
+ // Re-scan to check if sections that exist have (none needed) or skip-reason:
184
+ const isOptedOut = (text) =>
185
+ text.includes("(none needed)") ||
186
+ text.includes("(not applicable)") ||
187
+ text.includes("skip-reason:");
188
+
189
+ // Validate each phase
190
+ const errors = [];
191
+ for (const phase of phases) {
192
+ if (!phase.hasImplementation) continue; // Skip phases with no impl items (might be a header-only outline)
193
+
194
+ const missing = [];
195
+ if (requirements.verification && !phase.hasVerification) missing.push("Verification");
196
+ if (requirements.context && !phase.hasContext) missing.push("Context");
197
+ if (requirements.document && !phase.hasDocument) missing.push("Document");
198
+
199
+ if (missing.length > 0) {
200
+ errors.push(`Phase ${phase.number} (${phase.name}) is missing: ${missing.join(", ")}`);
201
+ }
202
+
203
+ // In strict mode, opt-outs are not allowed — sections must have real items
204
+ if (gatePolicy === "strict") {
205
+ const optOuts = [];
206
+ if (requirements.verification && phase.hasVerification && phase.verificationIsOptOut)
207
+ optOuts.push("Verification");
208
+ if (requirements.context && phase.hasContext && phase.contextIsOptOut)
209
+ optOuts.push("Context");
210
+ if (requirements.document && phase.hasDocument && phase.documentIsOptOut)
211
+ optOuts.push("Document");
212
+ if (optOuts.length > 0) {
213
+ errors.push(
214
+ `Phase ${phase.number} (${phase.name}): ${optOuts.join(", ")} cannot use opt-outs in strict mode — add real items`,
215
+ );
216
+ }
217
+ }
218
+ }
219
+
220
+ if (errors.length > 0) {
221
+ const msg = errors.join("\n");
222
+ const reqNames = Object.entries(requirements)
223
+ .filter(([, v]) => v)
224
+ .map(([k]) => k.charAt(0).toUpperCase() + k.slice(1));
225
+ const skipHint =
226
+ gatePolicy === "strict"
227
+ ? "Gate policy is 'strict' — all sections must have real items, no overrides.\n"
228
+ : "If a section isn't needed, add it with (none needed) or skip-reason: {why}\nExample: #### Phase 1 Document\\n(none needed)\n";
229
+ process.stderr.write(
230
+ `Impl structure incomplete (workflow: ${workflow}, policy: ${gatePolicy}):\n${msg}\n\nThis workflow requires: ${reqNames.join(", ")} sections per phase.\n${skipHint}To change requirements, add 'workflow: bugfix' to the impl frontmatter.\n`,
231
+ );
232
+ process.exit(2);
233
+ }
234
+
235
+ process.exit(0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@infinitedusky/indusk-mcp",
3
- "version": "0.7.2",
3
+ "version": "0.8.5",
4
4
  "description": "InDusk development system — skills, MCP tools, and CLI for structured AI-assisted development",
5
5
  "type": "module",
6
6
  "files": [
@@ -1,11 +1,26 @@
1
1
  ---
2
2
  name: document
3
- description: Per-phase documentation gate during impl execution. Writes and updates docs in the VitePress site. Encourages Mermaid diagrams for architecture, flows, and relationships.
3
+ description: Build and maintain the project encyclopedia a human-readable record of what was built, why, and how. Every plan contributes to documentation. This is not optional metadata.
4
4
  argument-hint: "[what to document or 'check']"
5
5
  ---
6
6
 
7
7
  You know how to maintain documentation in this project.
8
8
 
9
+ ## Why Documentation Exists
10
+
11
+ Documentation is **the project's encyclopedia**. It is a human-readable record that any developer — today or a year from now — can read and understand:
12
+
13
+ - **What** was built and how it works
14
+ - **Why** it was built this way and not another
15
+ - **How** to use it, configure it, extend it
16
+ - **What changed** over time (changelogs, decision records)
17
+
18
+ This is NOT the same as CLAUDE.md (which is agent-facing project memory) or code comments (which are implementation details). Documentation is for humans who need to understand the project without reading every source file.
19
+
20
+ **Documentation is never optional.** The question is not "does this need docs?" — the question is "what docs does this need?" Even a bugfix updates the changelog. Even a refactor updates architecture diagrams. Even an internal change may need a decision record explaining why.
21
+
22
+ The fact that information exists in CLAUDE.md, planning docs, or code does NOT eliminate the need for documentation. Those are working artifacts. Documentation is the polished, organized, permanent record.
23
+
9
24
  ## What Document Does
10
25
 
11
26
  Document is a per-phase gate during impl execution, alongside verify and context. The full phase order is:
@@ -14,14 +29,25 @@ Document is a per-phase gate during impl execution, alongside verify and context
14
29
  implement → verify → context → document → advance
15
30
  ```
16
31
 
17
- After context items are done, the document gate asks one question:
32
+ After context items are done, the document gate asks:
33
+
34
+ **"What should a developer reading this project's docs learn from what this phase built?"**
18
35
 
19
- **"Does this phase change something a user or developer needs to know?"**
36
+ To answer this accurately, **REQUIRED: call `query_dependencies`** on the key files changed in this phase to understand what was affected and how broadly.
20
37
 
21
- To answer this accurately, **REQUIRED: call `query_dependencies`** on the key files changed in this phase. If the change affects files with many dependents, it likely needs documentation. If it's internal with no downstream consumers, it might not.
38
+ For each phase, consider all of these:
22
39
 
23
- - If **yes**: write or update the relevant page in `apps/indusk-docs/src/`
24
- - If **no**: skip — not every phase produces documentation. The gate asks the question but doesn't always produce output.
40
+ | What happened | What to document |
41
+ |---|---|
42
+ | New feature or tool | Reference page + guide if complex |
43
+ | Architecture change | Update architecture page + diagrams |
44
+ | New decision (ADR accepted) | Decision page distilled from ADR |
45
+ | Bug fixed | Changelog entry + update affected reference pages |
46
+ | Refactor | Update architecture diagrams + any affected reference pages |
47
+ | New convention | Update conventions/reference page |
48
+ | API change | Update API reference |
49
+ | Configuration change | Update configuration reference |
50
+ | Lesson learned | Will go in lessons/ during retrospective |
25
51
 
26
52
  ## Where Docs Live
27
53
 
@@ -97,16 +123,75 @@ flowchart TD
97
123
 
98
124
  **Never** use bare ` ```mermaid ` blocks without the wrapper. The diagrams are often too small to read inline, and the FullscreenDiagram gives users zoom and pan controls.
99
125
 
126
+ ## Two Documentation Layers
127
+
128
+ ### Standard Documentation (always)
129
+
130
+ What was built, how it works, why it's designed this way. This is the reference someone reads to understand the system. Exists regardless of mode.
131
+
132
+ ### Learning Journal (teach mode only)
133
+
134
+ When running in teach mode (`/work teach`), documentation gains a second layer: **what we learned building it**. This captures:
135
+
136
+ - What surprised us during implementation
137
+ - Why we chose this approach over the alternatives we considered
138
+ - What was harder or easier than expected
139
+ - Conceptual connections — "this pattern is similar to X because..."
140
+ - What we'd do differently next time
141
+
142
+ Learning journal entries go in `apps/indusk-docs/src/lessons/` as standalone pages, or as `## What We Learned` sections within existing guide pages. They're written in first person and read like a developer's notebook — not formal reference docs.
143
+
144
+ In teach mode, every Document gate should produce both:
145
+ 1. **Standard docs** — reference/guide updates (same as normal mode)
146
+ 2. **Learning entry** — what the developer should take away from this phase
147
+
148
+ The learning journal is what makes teach mode more than just "go slow." It builds a permanent record of understanding alongside the permanent record of what was built.
149
+
150
+ ## Documentation by Workflow Type
151
+
152
+ The depth varies by workflow type, but every workflow produces documentation.
153
+
154
+ ### Feature (full documentation)
155
+
156
+ A feature is new functionality. It gets the full treatment:
157
+ - Write new reference pages for tools, APIs, or configuration added
158
+ - Write guide pages for workflows introduced
159
+ - Create Mermaid diagrams for architecture, flows, and relationships
160
+ - Update existing pages that reference the area you changed
161
+ - Add a changelog entry describing the feature
162
+ - If an ADR was accepted, create a decision page in `decisions/`
163
+
164
+ ### Refactor (update existing docs)
165
+
166
+ A refactor restructures existing code. The docs must reflect the new reality:
167
+ - Update existing pages that reference moved/renamed code
168
+ - Update architecture diagrams to show the new structure
169
+ - Add a changelog entry explaining what was restructured and why
170
+ - If the refactor changes how developers interact with the code, update the relevant guide
171
+
172
+ ### Bugfix (document the fix)
173
+
174
+ A bugfix solves a specific problem. Even small fixes leave a paper trail:
175
+ - Add a changelog entry describing the bug and the fix
176
+ - Update any docs that described the broken behavior
177
+ - If the bug revealed a gotcha, add it to the relevant reference page
178
+ - If the fix changes a public API or configuration, update that reference page
179
+
100
180
  ## Shaping Impl Documents
101
181
 
102
- When writing an impl (via the plan skill), every phase should consider documentation:
182
+ When writing an impl (via the plan skill), every phase gets a Document section:
103
183
 
104
184
  ```markdown
105
185
  #### Phase N Document
106
186
  - [ ] {Specific docs page to write or update}
187
+ - [ ] {Changelog entry}
107
188
  ```
108
189
 
109
- The agent writing the impl must answer: **"What does a user or developer need to know about what this phase built?"** If the answer is "nothing user-facing" — no document items needed. Not every phase produces docs. But the question must be asked.
190
+ The agent writing the impl must answer: **"What should a developer reading the docs learn from what this phase built?"**
191
+
192
+ Every phase should produce at minimum a changelog entry. Beyond that, consider: does this phase add, change, or remove something that appears in the docs? If yes, list the specific pages to create or update.
193
+
194
+ The `gate_policy` setting controls whether `(none needed)` is acceptable — in `strict` mode it is not. In `ask` mode, the agent must justify and get user approval before opting out. See the work skill for details.
110
195
 
111
196
  ### Document Items Are Blocking
112
197
 
@@ -118,37 +203,18 @@ implementation items → verification items → context items → document items
118
203
 
119
204
  A phase is not complete until its document items are done.
120
205
 
121
- ## LLM-Readable Companion Files
122
-
123
- Every documentation page you create must have a corresponding **llms.txt** companion file. This makes the docs easy for AI agents to consume directly without HTML parsing.
124
-
125
- ### How It Works
126
-
127
- For every page at `apps/indusk-docs/src/{path}.md`, create a matching file at `apps/indusk-docs/public/llms/{path}.txt`.
128
-
129
- ```
130
- apps/indusk-docs/src/reference/skills/plan.md → apps/indusk-docs/public/llms/reference/skills/plan.txt
131
- apps/indusk-docs/src/guide/getting-started.md → apps/indusk-docs/public/llms/guide/getting-started.txt
132
- apps/indusk-docs/src/reference/tools/indusk-mcp.md → apps/indusk-docs/public/llms/reference/tools/indusk-mcp.txt
133
- ```
134
-
135
- ### Content Rules
136
-
137
- The llms.txt file should contain the **same content** as the markdown page, with these adjustments:
138
-
139
- - Strip Mermaid diagram blocks and FullscreenDiagram wrappers (diagrams aren't useful as text)
140
- - Keep all tables, code blocks, headings, and prose
141
- - Keep all examples — these are the most valuable part for LLMs
142
- - Add a header line: `# {Page Title} — LLM-readable version`
143
- - Add a source line: `Source: {relative path to the .md file}`
206
+ ## LLM-Readable Output (llms.txt)
144
207
 
145
- ### Why
208
+ The docs site auto-generates LLM-friendly content via `vitepress-plugin-llms`. No manual work needed.
146
209
 
147
- When an external agent needs to understand this system, you can point it at `https://your-domain/llms/reference/skills/plan.txt` and it gets clean, structured text. No HTML parsing, no JavaScript rendering, no Mermaid SVGs to decode.
210
+ At build time, the plugin produces:
211
+ - `/llms.txt` — index with links to all pages (for LLM navigation)
212
+ - `/llms-full.txt` — entire docs concatenated into one markdown file (for full ingestion)
213
+ - Per-page `.md` files accessible directly
148
214
 
149
- ### Also Create an Index
215
+ This follows the [llms.txt convention](https://llmstxt.org/) used by Vite, Vue.js, Vitest, Stripe, and Cloudflare.
150
216
 
151
- Maintain `apps/indusk-docs/public/llms.txt` as a root index listing all available LLM-readable pages with their URLs and one-line descriptions. This follows the [llms.txt convention](https://llmstxt.org/).
217
+ **Do not** manually create llms.txt files the plugin handles everything.
152
218
 
153
219
  ## Running the Docs Site
154
220
 
@@ -162,7 +228,10 @@ pnpm turbo build --filter=indusk-docs
162
228
 
163
229
  ## Important
164
230
 
165
- - Documentation is human-facing. CLAUDE.md is agent-facing. They serve different audiences don't duplicate between them.
166
- - Link, don't duplicate. If something is fully documented in a skill file or ADR, link to the docs page for it rather than copying content.
231
+ - **Documentation is the project's permanent record.** It outlives conversations, planning docs, and even the code itself. Write it like someone will read it a year from now with no other context.
232
+ - **Documentation is human-facing. CLAUDE.md is agent-facing.** They serve different audiences. CLAUDE.md helps the agent work. Docs help humans understand.
233
+ - **The existence of information elsewhere does not replace documentation.** ADRs, CLAUDE.md, planning docs, and code comments are working artifacts. Documentation is the polished, organized, permanent version.
234
+ - **Every plan contributes to documentation.** Features add pages. Refactors update pages. Bugfixes add changelog entries. There is no plan that produces zero documentation.
167
235
  - Keep reference pages focused and scannable. Use tables and diagrams over paragraphs.
168
- - The `decisions/` and `lessons/` sections are populated during retrospective only, not during normal impl work.
236
+ - The `decisions/` and `lessons/` sections are populated during retrospective, but decision pages can also be created during impl when an ADR is accepted.
237
+ - When in doubt, document more, not less. Excess documentation can be trimmed. Missing documentation is invisible.
@@ -0,0 +1,61 @@
1
+ ---
2
+ name: onboard
3
+ description: Get a new agent caught up on the project. Reads context, plans, lessons, and code graph health in one shot. Run at the start of every new session.
4
+ ---
5
+
6
+ You are starting a new session on this project. Before doing anything else, get caught up.
7
+
8
+ ## Steps (execute in order)
9
+
10
+ ### 1. Read Lessons
11
+ Call `list_lessons`. Read every lesson. These are rules learned from past mistakes — not suggestions. Internalize them before touching any code.
12
+
13
+ ### 2. Check Infrastructure
14
+ Call `check_health`. Verify FalkorDB and CGC are running. If unhealthy, tell the user what's down and how to fix it.
15
+
16
+ ### 3. Read Project Context
17
+ Call `get_context` to read CLAUDE.md. This contains:
18
+ - **Architecture** — what the project is, how it's structured
19
+ - **Conventions** — rules to follow (commit style, no DB from Next.js, no fallback URLs, etc.)
20
+ - **Key Decisions** — ADRs that have been accepted (with links)
21
+ - **Known Gotchas** — things that will bite you if you don't know about them
22
+ - **Current State** — what's been built, what's working, what's in progress
23
+
24
+ Read it fully. Don't skim.
25
+
26
+ ### 4. Check Active Plans
27
+ Call `list_plans`. This shows every plan and its status. Pay attention to:
28
+ - Plans with status `in-progress` — these are actively being worked on
29
+ - The current phase of each active plan — this is where `/work` will pick up
30
+ - Dependencies between plans — don't start a blocked plan
31
+
32
+ ### 5. Check Code Graph
33
+ Call `get_repository_stats` to understand the codebase size and structure. This gives you a sense of what's indexed and queryable.
34
+
35
+ ### 6. Summarize
36
+
37
+ After completing steps 1-5, present a brief summary to the user:
38
+
39
+ ```
40
+ **Session ready.**
41
+ - Lessons: N loaded
42
+ - Infrastructure: [healthy / issues]
43
+ - Active plans: [list with current phase]
44
+ - Codebase: [N files indexed]
45
+
46
+ Ready to work. What would you like to do?
47
+ ```
48
+
49
+ ## When to Use
50
+
51
+ - Start of every new Claude Code session
52
+ - When the user says "get caught up", "what's going on", "where are we"
53
+ - When context was compressed and you need to re-orient
54
+ - `/onboard` explicitly
55
+
56
+ ## Important
57
+
58
+ - Do NOT skip any step. Each one prevents a class of mistake.
59
+ - Do NOT start coding before completing onboarding. The lessons and context exist because of past failures.
60
+ - If CLAUDE.md seems outdated, flag it to the user — it may need a `/context` update.
61
+ - If a plan's impl has unchecked items from a previous session, that's where `/work` picks up. Don't re-do completed work.
package/skills/plan.md CHANGED
@@ -49,7 +49,14 @@ Workflow templates are in `templates/workflows/` in the package. They describe w
49
49
 
50
50
  2. **Figure out where things stand.** If a plan folder already exists, read what's there. Check frontmatter statuses. The next document to write is the first one that's missing or incomplete.
51
51
 
52
- 3. **If starting fresh**, create the plan folder and start with the first document for the workflow type:
52
+ 3. **If starting fresh**, do a quick scan of the project (read CLAUDE.md, check the code graph) to understand the context. Then **ask the user discovery questions before doing any research or writing any documents.** The goal is to understand what they're trying to achieve, not just what they named the plan. Good discovery questions:
53
+ - "What problem are you trying to solve?" or "What should this feature do for your users?"
54
+ - "Is there anything specific you've already thought through or have strong opinions about?"
55
+ - "Are there any constraints I should know about — timeline, technology preferences, things to avoid?"
56
+
57
+ For non-developers especially, this conversation is critical. They may not know the right technical terms, but they know what they want. Draw that out before proceeding.
58
+
59
+ Once you understand the intent, create the plan folder and start with the first document for the workflow type:
53
60
  - **feature**: start with research
54
61
  - **bugfix**: start with brief (streamlined template)
55
62
  - **refactor**: start with brief (includes boundary map)
@@ -62,12 +69,29 @@ Workflow templates are in `templates/workflows/` in the package. They describe w
62
69
  - Include the graph findings in research.md — concrete numbers like "X has 12 dependents across 3 apps"
63
70
  Document what you find. The research doc records findings and analysis, but saves the recommendation for the brief.
64
71
 
65
- 4. **If research is done**, write the brief. This is where a direction emerges from the research. The brief proposes what we're building and why, informed by what the research uncovered. Present for review.
72
+ 4. **If research is done**, write the brief. This is where a direction emerges from the research. The brief proposes what we're building and why, informed by what the research uncovered. **Present the brief and have a conversation about it.** Don't just ask "does this look good?" — walk the user through it: "Here's what I'm proposing we build. Does this match what you had in mind? Is there anything missing, or anything here you don't want?" Iterate until the user is genuinely happy with the direction, then mark it as `accepted`.
66
73
 
67
74
  5. **If brief is accepted** and the workflow includes an ADR (feature only), write the ADR. The ADR formalizes the decisions that were discussed during research and led to the brief. It records what was chosen, what was rejected, and why. **After the ADR is accepted**, add a one-liner to CLAUDE.md's Key Decisions section per the context skill: `- {decision summary} — see planning/{plan}/adr.md`
68
75
 
69
76
  6. **If ADR is accepted** (or brief is accepted for bugfix/refactor), write the impl. Break into phased checklists with concrete tasks. For refactor workflows, include a `## Boundary Map` section. For multi-phase impls of any type, consider adding a boundary map.
70
77
 
78
+ **Gate policy applies when writing impls.** The same `gate_policy` (strict/ask/auto) that governs work execution also governs how the impl is written:
79
+
80
+ - **`strict`**: Every phase MUST have all four sections (implementation, verification, context, document) with real items. No `(none needed)` or `skip-reason:`. If a section genuinely doesn't apply, you still must include it with a concrete item.
81
+ - **`ask`** (default): Every phase MUST have all required sections (per workflow type). If you think a section should be `(none needed)`, ask the user: "Phase 3 Document — I don't think this phase changes anything user-facing. Can I mark it (none needed)?" Only mark it after approval.
82
+ - **`auto`**: Include all sections, but you can use `(none needed)` or `skip-reason:` based on your judgment without asking.
83
+
84
+ Set the policy in the impl frontmatter:
85
+ ```yaml
86
+ ---
87
+ title: "My Plan"
88
+ gate_policy: ask
89
+ workflow: feature
90
+ ---
91
+ ```
92
+
93
+ The `validate-impl-structure` hook enforces this at write time — it will block the impl if sections are missing for the workflow type.
94
+
71
95
  7. **If impl is completed** (all items checked off by `/work`), invoke the retrospective skill (`/retrospective {plan-name}`). This handles the structured audit (docs, tests, quality, context), knowledge handoff to the docs site, and archival. Do not write a freeform retrospective — use the skill. (Bugfix and refactor workflows may skip retrospective for small changes — user's call.)
72
96
 
73
97
  8. **Always present each document for review** before moving to the next stage. The user signs off on each step.
package/skills/work.md CHANGED
@@ -61,6 +61,54 @@ Implementation plans live in `planning/{plan-name}/impl.md` as checklists. Your
61
61
 
62
62
  A phase is not complete until all four are done. **Enforced by hooks:** if you try to check off a Phase N+1 implementation item while Phase N has unchecked gates, the edit will be blocked with a message listing what's missing. Complete the gates first.
63
63
 
64
+ ## Gate Override Policy
65
+
66
+ Gates exist to prevent skipping important work. But sometimes a gate genuinely doesn't apply. The override policy controls what happens when the agent wants to skip a gate item.
67
+
68
+ Three modes, configured via `gate_policy` in the impl frontmatter or `.claude/settings.json`:
69
+
70
+ | Mode | Behavior |
71
+ |------|----------|
72
+ | **`strict`** | No overrides. Every gate item must be completed. `(none needed)` and `skip-reason:` are not accepted. Use for critical work where nothing should be skipped. |
73
+ | **`ask`** (default) | Agent must ask the user before skipping any gate item. The agent explains why it wants to skip and waits for approval. Only after the user says yes can it mark with `skip-reason:`. |
74
+ | **`auto`** | Agent can skip with `skip-reason:` without asking. Use when running autonomously or when you trust the agent's judgment. |
75
+
76
+ ### How to set the mode
77
+
78
+ **Per-plan** (in impl frontmatter):
79
+ ```yaml
80
+ ---
81
+ title: "My Plan"
82
+ gate_policy: strict
83
+ ---
84
+ ```
85
+
86
+ **Per-project** (in `.claude/settings.json`):
87
+ ```json
88
+ {
89
+ "indusk": {
90
+ "gate_policy": "ask"
91
+ }
92
+ }
93
+ ```
94
+
95
+ **Per-invocation**: `/work --strict`, `/work --ask`, `/work --auto`
96
+
97
+ Priority: per-invocation > per-plan > per-project > default (`ask`).
98
+
99
+ ### What "ask" mode looks like
100
+
101
+ When the agent encounters a gate item it thinks should be skipped:
102
+
103
+ > "Phase 2 has a Document gate: 'Write reference page for the new API.' I don't think this phase needs a new docs page because we only changed internal implementation — the public API didn't change. Can I mark this as `skip-reason: internal change, no public API change`?"
104
+
105
+ The user can say:
106
+ - **"yes"** — agent marks it with skip-reason and continues
107
+ - **"no, do it"** — agent completes the gate item
108
+ - **"no, but mark it (none needed)"** — if the gate truly doesn't apply
109
+
110
+ **The agent must NEVER skip a gate without asking in `ask` mode.** This is the core enforcement. The hooks block unauthorized skips, and the skill enforces the conversation.
111
+
64
112
  11. **Verification items.** The Verification section requires proof, not assumption. See the verify skill for full guidance.
65
113
  - Run checks in order: type check → lint → affected tests → build. Skip checks that don't apply (see verify skill's skip logic table).
66
114
  - Run commands and capture output — verification items must be specific runnable commands, not "verify it works"
@@ -91,6 +139,8 @@ When invoked as `/work teach` or `/work --teach {plan}`, slow down to a mentorin
91
139
 
92
140
  ### Before each edit:
93
141
 
142
+ **Where we are:** State the current position in the system — which plan, which phase, which gate (implementation/verification/context/document), and why this gate exists. Example: "We're in Phase 3 of the auth-system plan, working through implementation items. After these, we'll verify with type checks and tests, then update CLAUDE.md with what changed, then document it. That's the four-gate cycle that every phase goes through."
143
+
94
144
  **Why this change:** Explain what you're about to modify and why. Reference the plan, the architecture, and the reasoning. Use plain language.
95
145
 
96
146
  Then **stop and wait** for the user to say "continue" before making the edit.
@@ -103,15 +153,33 @@ Then **stop and wait** for the user to say "continue" before making the edit.
103
153
 
104
154
  Then **stop and wait** for the user to say "continue" before moving to the next item.
105
155
 
156
+ ### At gate transitions:
157
+
158
+ When moving from implementation to verification, or verification to context, or context to document — explain the transition and why this gate exists:
159
+
160
+ - **Implementation → Verification:** "The code is written. Now we prove it works. The verify skill says to run checks fastest-first: type check, lint, tests, build. This catches errors before they compound."
161
+ - **Verification → Context:** "Everything passes. Now we update CLAUDE.md so the next session knows what changed. Context is how the project remembers — without it, the next agent starts from scratch."
162
+ - **Context → Document:** "CLAUDE.md is updated. Now we write or update the project's documentation — the encyclopedia that any developer can read to understand what was built and why. In teach mode, we also write a learning entry: what surprised us, what we'd do differently, what conceptual connections to notice."
163
+ - **Phase complete → Next phase:** "All four gates passed for Phase N. The hook would have blocked us if we'd tried to skip any. Now Phase N+1 builds on what Phase N produced — here's what the boundary map says it needs..."
164
+
106
165
  ### Between checklist items:
107
166
 
108
- Summarize what was accomplished and preview the next item. Explain how they connect.
167
+ Summarize what was accomplished and preview the next item. Explain how they connect — both in terms of the feature being built and the InDusk system driving the process.
168
+
169
+ ### Document gate in teach mode:
170
+
171
+ In teach mode, every Document gate produces two things:
172
+ 1. **Standard docs** — the same reference/guide updates you'd write in normal mode
173
+ 2. **Learning entry** — what the developer should take away from this phase: what surprised us, what we chose and why, what conceptual connections to notice
174
+
175
+ See the document skill's "Two Documentation Layers" section for details. The learning journal is what makes teach mode a teaching tool, not just a slow mode.
109
176
 
110
177
  ### Important for teach mode:
111
178
 
112
179
  - Never batch multiple edits between pauses
113
180
  - Use clear headings to separate teaching from doing
114
181
  - If the user asks a question, answer it fully before continuing
182
+ - Always give both layers: the **what** (the feature/code) and the **why** (the InDusk system's reasoning)
115
183
  - Normal `/work` (without teach) remains unchanged — fast execution, no pauses
116
184
 
117
185
  ## Corrections and Context Learning