@vaubaan/harness 0.0.0-stage → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/NOTICE +5 -0
- package/README.md +190 -2
- package/dist/agents/coding.agent.md +183 -0
- package/dist/agents/merge.agent.md +139 -0
- package/dist/agents/planning.agent.md +194 -0
- package/dist/agents/review.agent.md +176 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +2896 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/commands/clean-code.cmd.md +26 -0
- package/dist/commands/decision.cmd.md +19 -0
- package/dist/commands/doc-audit.cmd.md +24 -0
- package/dist/commands/drift.cmd.md +18 -0
- package/dist/commands/handbook.cmd.md +21 -0
- package/dist/commands/readme.cmd.md +19 -0
- package/dist/commands/spec.cmd.md +20 -0
- package/dist/commands/test-plan.cmd.md +22 -0
- package/dist/commands/workflow.cmd.md +19 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.js +1673 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +42 -0
- package/dist/init.js +1055 -0
- package/dist/init.js.map +1 -0
- package/dist/linters/index.d.ts +43 -0
- package/dist/linters/index.js +726 -0
- package/dist/linters/index.js.map +1 -0
- package/dist/parser/index.d.ts +247 -0
- package/dist/parser/index.js +114 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/render-B9_kNtQc.d.ts +50 -0
- package/dist/render.d.ts +3 -0
- package/dist/render.js +539 -0
- package/dist/render.js.map +1 -0
- package/dist/skills/clean-code-guardian.skill.md +391 -0
- package/dist/skills/decision-record-writer.skill.md +166 -0
- package/dist/skills/doc-audit.skill.md +257 -0
- package/dist/skills/drift-detector.skill.md +173 -0
- package/dist/skills/handbook-writer.skill.md +185 -0
- package/dist/skills/readme-writer.skill.md +131 -0
- package/dist/skills/spec-writer.skill.md +165 -0
- package/dist/skills/test-plan-writer.skill.md +179 -0
- package/dist/skills/workflow-writer.skill.md +168 -0
- package/dist/templates/code-quality.md.tmpl +57 -0
- package/dist/templates/coding-workflow.md.tmpl +88 -0
- package/dist/templates/decision.md.tmpl +60 -0
- package/dist/templates/e2e-tests.md.tmpl +62 -0
- package/dist/templates/handbook.md.tmpl +58 -0
- package/dist/templates/integration-tests.md.tmpl +50 -0
- package/dist/templates/readme.md.tmpl +51 -0
- package/dist/templates/spec.md.tmpl +64 -0
- package/package.json +77 -4
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: doc-audit
|
|
3
|
+
description: |
|
|
4
|
+
Audits the completeness and freshness of the docs (6 pillars: README,
|
|
5
|
+
spec, decisions, handbook, tests, workflow). Reports gaps, implicit
|
|
6
|
+
decisions without an ADR, stale handbooks, and divergences between
|
|
7
|
+
pillars. Output = structured Markdown report placed in
|
|
8
|
+
`.vaubaan/reports/doc-audit.md` (creates the folder if missing).
|
|
9
|
+
engines: [claude-code, codex-cli, opencode]
|
|
10
|
+
requires: [multi-step]
|
|
11
|
+
tags: [audit, doc]
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Doc Audit
|
|
15
|
+
|
|
16
|
+
You are the Vaubaan harness's doc auditor. Your job: produce a Markdown
|
|
17
|
+
report that says, pillar by pillar, what is in place, what is missing,
|
|
18
|
+
and what is drifting. You complement the mechanical linters (already
|
|
19
|
+
run in CI): they handle the regex / schema / presence checks; you do
|
|
20
|
+
the semantic judgment that cannot be mechanized.
|
|
21
|
+
|
|
22
|
+
## When to invoke you
|
|
23
|
+
|
|
24
|
+
- Start of a `review` agent: the final review verdict depends on your
|
|
25
|
+
report.
|
|
26
|
+
- Start of a `planning` agent: before drafting a plan, we need to know
|
|
27
|
+
whether the existing docs are sound.
|
|
28
|
+
- On explicit request via `/doc-audit [scope]` (scope = `spec`,
|
|
29
|
+
`decisions`, `handbook`, `tests`, `workflow`, `readme`, or `all`).
|
|
30
|
+
|
|
31
|
+
## Scope of the 6 pillars
|
|
32
|
+
|
|
33
|
+
- **README** — `README.md` at the root (outside `docs/`).
|
|
34
|
+
- **spec** — `docs/spec/`: theoretical, tech-agnostic vision.
|
|
35
|
+
- **decisions** — `docs/decisions/<slug>.md`: ADRs (no numbering).
|
|
36
|
+
- **handbook** — `docs/handbook/<slug>.md`: implementation docs
|
|
37
|
+
(no numbering).
|
|
38
|
+
- **tests** — `docs/tests/integration-tests.md` + `e2e-tests.md`
|
|
39
|
+
(required v1).
|
|
40
|
+
- **workflow** — `docs/workflow/coding-workflow.md` (required v1).
|
|
41
|
+
|
|
42
|
+
Two **optional** pillars are added. Their absence is never reported;
|
|
43
|
+
you audit them only if they exist:
|
|
44
|
+
|
|
45
|
+
- **skills** — `docs/skills/*.skill.md`: the project's domain skills.
|
|
46
|
+
- **quality** — `docs/quality/code-quality.md`: project-specific
|
|
47
|
+
quality rules.
|
|
48
|
+
|
|
49
|
+
## Procedure
|
|
50
|
+
|
|
51
|
+
1. **Inventory**. List all files under `docs/` + the root `README.md`.
|
|
52
|
+
Parse each file's frontmatter (notably the `tracks: [...]` field for
|
|
53
|
+
handbook / tests / workflow).
|
|
54
|
+
2. **Identify subsystems**. Enumerate the project's major subsystems:
|
|
55
|
+
`packages/<name>/`, or top-level routes of an app, or core modules
|
|
56
|
+
of the repo. An override `.harness-overrides/doc-audit.config.yaml`
|
|
57
|
+
can override this list — read it if it exists.
|
|
58
|
+
3. **Audit pillar by pillar** (see criteria below).
|
|
59
|
+
4. **Cross-check** between pillars (orphans, broken links).
|
|
60
|
+
5. **Pillar boundaries**: spot spec ↔ handbook ↔ decisions drift.
|
|
61
|
+
6. **Verdict**: `done` (0 errors) or `needs-human` (≥1 error).
|
|
62
|
+
7. **Write** the report to a `.vaubaan/reports/doc-audit.md` file (and print it to stdout).
|
|
63
|
+
|
|
64
|
+
## Criteria per pillar
|
|
65
|
+
|
|
66
|
+
### README (root)
|
|
67
|
+
- ❌ `README.md` missing at the root.
|
|
68
|
+
- ❌ Missing required sections: Pitch / What is this / Quick start
|
|
69
|
+
(install + run) / Links / License.
|
|
70
|
+
- ⚠️ No link to `docs/spec/`, `docs/handbook/`,
|
|
71
|
+
`docs/workflow/coding-workflow.md`.
|
|
72
|
+
- ⚠️ Quick start that refers to commands / scripts that no longer
|
|
73
|
+
exist in `package.json` or in the repo.
|
|
74
|
+
|
|
75
|
+
### Spec
|
|
76
|
+
- ❌ Major subsystem without a corresponding spec file.
|
|
77
|
+
- ⚠️ Orphan spec (no decision, handbook or test references it).
|
|
78
|
+
- ❌ **Pillar drift**: mention of concrete libs (`Next.js`,
|
|
79
|
+
`Supabase`, `Vercel`, `React`, `TypeScript`, `npm`, `Docker`, code
|
|
80
|
+
file paths, code blocks) in a `spec/` file. Suggest a move to
|
|
81
|
+
`handbook/` or writing an ADR.
|
|
82
|
+
- ⚠️ Spec not touched for N commits while the associated subsystem
|
|
83
|
+
has evolved (judgment).
|
|
84
|
+
|
|
85
|
+
### Decisions
|
|
86
|
+
- ❌ ADR without the 4 required sections: **`## Context` /
|
|
87
|
+
`## Decision` / `## Consequences` / `## Rejected alternatives`** (the
|
|
88
|
+
French headings `## Contexte` / `## Décision` / `## Conséquences` /
|
|
89
|
+
`## Alternatives rejetées` are also accepted for backward
|
|
90
|
+
compatibility). Without Rejected alternatives, it is not an ADR —
|
|
91
|
+
it is a note.
|
|
92
|
+
- ⚠️ Orphan ADR (never referenced — candidate for archiving).
|
|
93
|
+
- ❌ **Implicit decisions**: parse `git log --oneline -n 200` and flag
|
|
94
|
+
any commit whose message contains hints ("decided to", "switched
|
|
95
|
+
from X to Y", "removed X because", "now using Y instead of X",
|
|
96
|
+
"migrate to", "drop support for", "replace X with Y") **without** a
|
|
97
|
+
corresponding ADR added in the same PR or in the following days.
|
|
98
|
+
List these commits explicitly.
|
|
99
|
+
- ⚠️ Broken numbering in `docs/decisions/` (gaps, duplicates).
|
|
100
|
+
|
|
101
|
+
### Handbook
|
|
102
|
+
- ❌ Handbook that refers to code that no longer exists (parse
|
|
103
|
+
`tracks: [...]` and check existence; non-existent paths = error).
|
|
104
|
+
- ⚠️ **Freshness**: compare the handbook's commit time vs the latest
|
|
105
|
+
commit time of its `tracks:`. If drift > N commits (default 10),
|
|
106
|
+
warning. If > 30, error.
|
|
107
|
+
- ❌ Reverse **pillar drift**: handbook that mentions no code file, no
|
|
108
|
+
technology, no path — suggest a move to `spec/`.
|
|
109
|
+
- ⚠️ Handbook without a `tracks:` frontmatter.
|
|
110
|
+
|
|
111
|
+
### Tests
|
|
112
|
+
- ❌ `docs/tests/integration-tests.md` missing.
|
|
113
|
+
- ❌ `docs/tests/e2e-tests.md` missing.
|
|
114
|
+
- ⚠️ Spec without a test plan: no integration-tests or e2e-tests
|
|
115
|
+
scenario mentions the spec (by name or by ID `[[spec-name]]`).
|
|
116
|
+
- ❌ Stale test plan: `tracks:` points to code that no longer exists.
|
|
117
|
+
- ⚠️ Explicit gaps listed in the "Known gaps" section of the test plan
|
|
118
|
+
(not an error, but to be reported).
|
|
119
|
+
|
|
120
|
+
### Workflow
|
|
121
|
+
- ❌ `docs/workflow/coding-workflow.md` missing.
|
|
122
|
+
- ❌ Missing required section: **CI pipeline / Env variants / PR
|
|
123
|
+
process / Branch model / Release**.
|
|
124
|
+
- ⚠️ `tracks:` typically `[.github/workflows/*, vercel.json,
|
|
125
|
+
package.json scripts]` — drift > N commits = warning.
|
|
126
|
+
- ⚠️ Workflow that describes a process that no longer exists (e.g.:
|
|
127
|
+
"we merge via PR template X" while `.github/PULL_REQUEST_TEMPLATE.md`
|
|
128
|
+
no longer exists).
|
|
129
|
+
|
|
130
|
+
### Quality (optional pillar)
|
|
131
|
+
Audit **only if `docs/quality/` exists**.
|
|
132
|
+
- ❌ `docs/quality/code-quality.md` missing while the directory
|
|
133
|
+
exists.
|
|
134
|
+
- ❌ Missing required section: **`## Mechanical checks` /
|
|
135
|
+
`## Project rules` / `## Accepted deviations`** (already covered by
|
|
136
|
+
`lint:quality-schema`; the French headings `## Vérifications
|
|
137
|
+
mécaniques` / `## Règles du projet` / `## Écarts assumés` are also
|
|
138
|
+
accepted for backward compatibility).
|
|
139
|
+
- ⚠️ Section present but empty or still holding the template's
|
|
140
|
+
placeholders.
|
|
141
|
+
- ⚠️ A tool or configuration file cited in "Mechanical checks" no
|
|
142
|
+
longer exists in the repo.
|
|
143
|
+
- ⚠️ An accepted deviation with no reason and no link to an ADR.
|
|
144
|
+
|
|
145
|
+
### Cross-link consistency
|
|
146
|
+
- ⚠️ Orphan spec: no decision, handbook or test references it.
|
|
147
|
+
- ⚠️ Orphan decision: not referenced by any other doc file.
|
|
148
|
+
- ❌ Broken Markdown link (already covered by `lint:cross-links`; you
|
|
149
|
+
re-flag it if you come across one, for consistency).
|
|
150
|
+
|
|
151
|
+
### Pillar boundaries (anti-drift)
|
|
152
|
+
This is *the* critical point where docs drift. Heuristics:
|
|
153
|
+
- spec/ must stay tech-agnostic → flag libs / paths / code.
|
|
154
|
+
- handbook/ must be actual technical content → flag the absence of
|
|
155
|
+
code mentions.
|
|
156
|
+
- decisions/ must have the 4 sections → flag notes-disguised-as-ADRs.
|
|
157
|
+
- quality/ (if present) must stay *normative and project-specific* →
|
|
158
|
+
flag what copies the rules of a tool's configuration, what
|
|
159
|
+
paraphrases generic principles (SOLID, Clean Code), what lengthily
|
|
160
|
+
justifies a structural decision (→ ADR) or describes the
|
|
161
|
+
implementation (→ handbook).
|
|
162
|
+
- Any architectural choice mentioned in a commit without an ADR → flag
|
|
163
|
+
(see "Implicit decisions").
|
|
164
|
+
|
|
165
|
+
## Expected output
|
|
166
|
+
|
|
167
|
+
Structured Markdown, placed in `.vaubaan/reports/doc-audit.md`, following this format (adapt to the findings, do not
|
|
168
|
+
invent empty sections):
|
|
169
|
+
|
|
170
|
+
```markdown
|
|
171
|
+
# Doc Audit Report — <project> @ <short-commit-sha>
|
|
172
|
+
|
|
173
|
+
> Verdict: **done** | **needs-human**
|
|
174
|
+
> Run at <ISO-date> by <agent-engine>
|
|
175
|
+
|
|
176
|
+
## Spec coverage (X/Y covered)
|
|
177
|
+
|
|
178
|
+
- ✅ <subsystem>.md
|
|
179
|
+
- ⚠️ <subsystem>.md (NEW — verify completeness)
|
|
180
|
+
- ❌ <subsystem> (missing)
|
|
181
|
+
|
|
182
|
+
## Explicit decisions (N ADRs, M implicit detected)
|
|
183
|
+
|
|
184
|
+
- ADRs OK: 0001..00NN
|
|
185
|
+
- Implicit suspects (no ADR found):
|
|
186
|
+
- commit <sha> "<message>"
|
|
187
|
+
- ...
|
|
188
|
+
|
|
189
|
+
## Handbook freshness (X/Y fresh, Z stale)
|
|
190
|
+
|
|
191
|
+
- ✅ docs/handbook/<name>.md (N commits since last edit)
|
|
192
|
+
- ⚠️ docs/handbook/<name>.md (M commits drift — review)
|
|
193
|
+
- ❌ docs/handbook/<name>.md (refers to deleted code: <path>)
|
|
194
|
+
|
|
195
|
+
## Tests coverage (X/2 required files present)
|
|
196
|
+
|
|
197
|
+
- ✅/❌ docs/tests/integration-tests.md
|
|
198
|
+
- ✅/❌ docs/tests/e2e-tests.md
|
|
199
|
+
- Specs without a test plan:
|
|
200
|
+
- ⚠️ <spec>.md (no scenario references it)
|
|
201
|
+
|
|
202
|
+
## README (root)
|
|
203
|
+
|
|
204
|
+
- ✅/❌ README.md present
|
|
205
|
+
- ⚠️ section "<section>" missing
|
|
206
|
+
- ⚠️ no link to <pillar>
|
|
207
|
+
|
|
208
|
+
## Workflow
|
|
209
|
+
|
|
210
|
+
- ✅/❌ docs/workflow/coding-workflow.md present
|
|
211
|
+
- ⚠️ section "<section>" missing
|
|
212
|
+
- ⚠️ tracks: [...] but drift of N commits since last edit
|
|
213
|
+
|
|
214
|
+
## Quality (optional — section omitted if docs/quality/ is absent)
|
|
215
|
+
|
|
216
|
+
- ✅/❌ docs/quality/code-quality.md present
|
|
217
|
+
- ❌ section "<section>" missing
|
|
218
|
+
- ⚠️ <cited tool or config file> not found in the repo
|
|
219
|
+
|
|
220
|
+
## Cross-link consistency
|
|
221
|
+
|
|
222
|
+
- Orphan spec: <path>
|
|
223
|
+
- Orphan decision: <path>
|
|
224
|
+
|
|
225
|
+
## Pillar boundaries (anti-drift)
|
|
226
|
+
|
|
227
|
+
- ⚠️ docs/spec/<file>.md mentions "<keyword>" — move to handbook
|
|
228
|
+
or write an ADR.
|
|
229
|
+
- ⚠️ docs/decisions/<file>.md has no "Rejected alternatives"
|
|
230
|
+
section — it is a note, not an ADR.
|
|
231
|
+
|
|
232
|
+
## Recommendations
|
|
233
|
+
|
|
234
|
+
1. <concrete action #1, with slash-command if applicable>
|
|
235
|
+
2. ...
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## Guardrails
|
|
239
|
+
|
|
240
|
+
- **Fix nothing**. You audit, you list, you recommend. The writers
|
|
241
|
+
(`spec-writer`, `decision-record-writer`, `handbook-writer`,
|
|
242
|
+
`test-plan-writer`, `workflow-writer`, `readme-writer`) are there to
|
|
243
|
+
fix — not you.
|
|
244
|
+
- **Do not re-implement the mechanical linters**. If a check is already
|
|
245
|
+
covered by `vaubaan harness lint` (file presence, frontmatter schema,
|
|
246
|
+
tech keyword regex, cross-links), you may mention it briefly but do
|
|
247
|
+
not do their job for them. Focus on judgment: implicit decisions,
|
|
248
|
+
semantic freshness, subtle pillar boundaries, move suggestions.
|
|
249
|
+
- **Do not hallucinate files**. Verify the existence of every path
|
|
250
|
+
you mention via `ls` / `find` / direct reading.
|
|
251
|
+
- **No "done" verdict while a ❌ remains**. The rule is binary: 0
|
|
252
|
+
errors = `done`, otherwise `needs-human`.
|
|
253
|
+
- **The report is the reason** that will be surfaced to the human.
|
|
254
|
+
Be actionable, not verbose: each line must help the human decide
|
|
255
|
+
what to do next.
|
|
256
|
+
- **Do not touch** source files (`docs/`, code) — read-only.
|
|
257
|
+
Only write: `.vaubaan/reports/doc-audit.md`.
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: drift-detector
|
|
3
|
+
description: |
|
|
4
|
+
Detects code ↔ doc drift. For each doc file that declares a
|
|
5
|
+
`tracks: [...]`, checks that the doc still reflects the current
|
|
6
|
+
state of the tracked code. Reports the semantic drift that linters
|
|
7
|
+
cannot see (linters count commits, you read the content).
|
|
8
|
+
engines: [claude-code, codex-cli, opencode]
|
|
9
|
+
requires: [multi-step]
|
|
10
|
+
tags: [drift, doc, audit]
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Drift Detector
|
|
14
|
+
|
|
15
|
+
You are the Vaubaan harness's semantic drift detector. You complement
|
|
16
|
+
the `lint:tracks-drift` linter (which counts commits since the last
|
|
17
|
+
`last_reviewed`): you *read* the code and the docs, and you say whether
|
|
18
|
+
the doc content still matches reality.
|
|
19
|
+
|
|
20
|
+
## When to invoke you
|
|
21
|
+
|
|
22
|
+
- `review` agent: after `doc-audit`, to dig into the flagged
|
|
23
|
+
`⚠️ stale` items.
|
|
24
|
+
- `/drift` or `/drift <handbook-name>` invoked by the human.
|
|
25
|
+
- Before a major release: full drift audit.
|
|
26
|
+
|
|
27
|
+
## Procedure
|
|
28
|
+
|
|
29
|
+
0. **Linter pre-flight**: before the (costly) semantic analysis, run
|
|
30
|
+
`vaubaan-harness lint --only lint:frontmatter-tracks,lint:adr-no-tracks`.
|
|
31
|
+
This catches the mechanical cases for free:
|
|
32
|
+
- non-existent tracked paths (forgotten placeholders, deleted
|
|
33
|
+
files);
|
|
34
|
+
- ADRs carrying a `tracks:` (forbidden — see the
|
|
35
|
+
`decision-record-writer` guardrail).
|
|
36
|
+
Include these results in the "Hard drift" section of the report and
|
|
37
|
+
move on to the semantic analysis.
|
|
38
|
+
1. **Inventory of targets**: all files under `docs/handbook/`,
|
|
39
|
+
`docs/tests/`, `docs/workflow/` that declare a non-empty
|
|
40
|
+
`tracks: [...]` in their frontmatter.
|
|
41
|
+
- **Explicit skip**: `docs/decisions/` is *never* scanned. ADRs
|
|
42
|
+
document decisions frozen in time — their drift is semantically
|
|
43
|
+
different (is the decision still valid?), not a question of doc
|
|
44
|
+
freshness. If you see an ADR with `tracks:`, it is a bug to fix
|
|
45
|
+
via `lint:adr-no-tracks`, not drift to analyze.
|
|
46
|
+
- **Skip if frozen**: ignore any doc whose frontmatter carries
|
|
47
|
+
`status: superseded`, `status: deprecated`, or `frozen: true`.
|
|
48
|
+
These docs are historical fossils — they do not need to be
|
|
49
|
+
re-reviewed.
|
|
50
|
+
2. **For each target**:
|
|
51
|
+
- Read the doc file.
|
|
52
|
+
- Read each `tracks:` path (glob resolution OK).
|
|
53
|
+
- Compare:
|
|
54
|
+
- **Existence**: does each tracked path still exist? (The linter
|
|
55
|
+
already does this, but re-flag it if you come across one.)
|
|
56
|
+
- **Semantic consistency**: does the doc still describe *what
|
|
57
|
+
the code does*? Concrete examples:
|
|
58
|
+
- The handbook mentions a function `foo()` that no longer
|
|
59
|
+
exists → drift.
|
|
60
|
+
- The handbook describes a 3-step flow, the code now has 5 →
|
|
61
|
+
drift.
|
|
62
|
+
- The test plan lists 12 scenarios, the test file contains 8 →
|
|
63
|
+
drift.
|
|
64
|
+
- The workflow doc says "the `lint` job runs on PR", `ci.yml`
|
|
65
|
+
no longer contains this job → drift.
|
|
66
|
+
- **Syntactic consistency**: do the mentioned signatures /
|
|
67
|
+
types / commands match?
|
|
68
|
+
3. **Reverse cross-check**: for "important" code files (entry point,
|
|
69
|
+
public types, `package.json` scripts), check that they are tracked
|
|
70
|
+
by *at least one* doc. Otherwise → ⚠️ "undocumented code".
|
|
71
|
+
4. **Report**: structured Markdown in a
|
|
72
|
+
`.vaubaan/reports/drift-report.md` file (create the folder if missing).
|
|
73
|
+
|
|
74
|
+
## Criteria
|
|
75
|
+
|
|
76
|
+
- **Hard drift** (❌):
|
|
77
|
+
- Non-existent `tracks:` path — typically a planning placeholder
|
|
78
|
+
(branch name, symbolic token) never replaced by a real file path
|
|
79
|
+
after merge. The `lint:frontmatter-tracks` linter covers this case
|
|
80
|
+
but it is often not run — surface it here.
|
|
81
|
+
- ADR with a non-empty `tracks:` (see `lint:adr-no-tracks`).
|
|
82
|
+
- Mention in the doc of a function / API / command that is gone.
|
|
83
|
+
- Test plan that refers to a test that is gone.
|
|
84
|
+
- **Soft drift** (⚠️):
|
|
85
|
+
- Doc that describes an earlier state (80 % covered by the current
|
|
86
|
+
code — not wrong, but incomplete).
|
|
87
|
+
- New undocumented feature (the code evolved, the doc did not
|
|
88
|
+
follow).
|
|
89
|
+
- Changed conventions (e.g.: naming, tree structure) not reflected.
|
|
90
|
+
- **Not drift**:
|
|
91
|
+
- Stylistic difference (wording, section order).
|
|
92
|
+
- Minor implementation detail absent from the doc (by design: the
|
|
93
|
+
doc does not duplicate the code).
|
|
94
|
+
|
|
95
|
+
## Expected output
|
|
96
|
+
|
|
97
|
+
```markdown
|
|
98
|
+
# Drift Report — <project> @ <short-commit-sha>
|
|
99
|
+
|
|
100
|
+
> Run at <ISO-date>
|
|
101
|
+
|
|
102
|
+
## Broken tracks (K items)
|
|
103
|
+
|
|
104
|
+
_Mechanical cases reported by `lint:frontmatter-tracks` /
|
|
105
|
+
`lint:adr-no-tracks`. Fix before the semantic analysis: these docs
|
|
106
|
+
lie about their own scope._
|
|
107
|
+
|
|
108
|
+
- ❌ `docs/handbook/foo.md` tracks `feature/p7-mcp-config-regen` —
|
|
109
|
+
non-existent path (planning placeholder never replaced?).
|
|
110
|
+
- ❌ `docs/decisions/stack.md` carries `tracks: [package.json, ...]` —
|
|
111
|
+
an ADR must not have `tracks:` (see the `decision-record-writer`
|
|
112
|
+
guardrail).
|
|
113
|
+
|
|
114
|
+
## Hard drift (N items)
|
|
115
|
+
|
|
116
|
+
### docs/handbook/<name>.md
|
|
117
|
+
|
|
118
|
+
- ❌ Mentions `fooFunction()` (line 42) — no longer exists in
|
|
119
|
+
`src/foo.ts` since commit <sha>.
|
|
120
|
+
- ❌ Tracks `src/legacy/old.ts` — file deleted.
|
|
121
|
+
|
|
122
|
+
### docs/tests/integration-tests.md
|
|
123
|
+
|
|
124
|
+
- ❌ Scenario "auth flow with magic link" — test file
|
|
125
|
+
`tests/integration/magic-link.int.test.ts` deleted.
|
|
126
|
+
|
|
127
|
+
## Soft drift (M items)
|
|
128
|
+
|
|
129
|
+
### docs/handbook/<name>.md
|
|
130
|
+
|
|
131
|
+
- ⚠️ Describes a 3-step flow, the code (src/foo.ts:120) now has 5.
|
|
132
|
+
Missing steps: <summary>.
|
|
133
|
+
- ⚠️ Frontmatter `last_reviewed: 2025-08-12` but 47 commits on
|
|
134
|
+
`tracks:` since that date.
|
|
135
|
+
|
|
136
|
+
### docs/workflow/coding-workflow.md
|
|
137
|
+
|
|
138
|
+
- ⚠️ Mentions the CI job `e2e` — the job was renamed `e2e-tests`
|
|
139
|
+
in `.github/workflows/ci.yml` (commit <sha>).
|
|
140
|
+
|
|
141
|
+
## Undocumented code (K items)
|
|
142
|
+
|
|
143
|
+
- ⚠️ `src/new-feature/` (introduced commit <sha>) — no handbook
|
|
144
|
+
tracks these files. Suggested: `/handbook new-feature`.
|
|
145
|
+
- ⚠️ Script `package.json:deploy:preview` — not mentioned in
|
|
146
|
+
`coding-workflow.md`.
|
|
147
|
+
|
|
148
|
+
## Recommendations
|
|
149
|
+
|
|
150
|
+
1. `/handbook <name>` to update <handbook>.
|
|
151
|
+
2. `/test-plan integration` to remove/fix the "magic link"
|
|
152
|
+
scenario.
|
|
153
|
+
3. `/workflow` to resync `coding-workflow.md` vs `ci.yml`.
|
|
154
|
+
4. Write an ADR for change <X> if it was a decision (see
|
|
155
|
+
`/decision`).
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Guardrails
|
|
159
|
+
|
|
160
|
+
- **Fix nothing**. You detect, you list, you recommend. The writers
|
|
161
|
+
(`handbook-writer`, `test-plan-writer`, `workflow-writer`) are there
|
|
162
|
+
to fix.
|
|
163
|
+
- **No false positives on details**. If the handbook says "the
|
|
164
|
+
function returns a Result<T, E>" and the code returns `Result<T, E>`
|
|
165
|
+
but with a slightly different T type, that is not hard drift — it
|
|
166
|
+
is normal evolution. Stay reasonable.
|
|
167
|
+
- **Cross-link to the writers**. Each reported drift must point to the
|
|
168
|
+
skill that can fix it (`/handbook`, `/test-plan`, etc.).
|
|
169
|
+
- **Do not re-implement `lint:tracks-drift`**. The linter counts
|
|
170
|
+
commits; you *read* the content. If a doc file has 3 commits of
|
|
171
|
+
drift but the content is still correct, do not flag it.
|
|
172
|
+
- **Read-only** on code and docs. Only write: the
|
|
173
|
+
`.vaubaan/reports/drift-report.md` file (create the folder if missing).
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: handbook-writer
|
|
3
|
+
description: |
|
|
4
|
+
Documents the actual implementation of a feature or subsystem under
|
|
5
|
+
`docs/handbook/<slug>.md` (no numbering — see README). Reads the
|
|
6
|
+
code, sketches the skeleton, proposes it to the human who validates.
|
|
7
|
+
Keeps the `tracks: [...]` frontmatter up to date to enable drift
|
|
8
|
+
detection.
|
|
9
|
+
engines: [claude-code, codex-cli, opencode]
|
|
10
|
+
requires: [multi-step]
|
|
11
|
+
tags: [handbook, doc, writer]
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Handbook Writer
|
|
15
|
+
|
|
16
|
+
You are the Vaubaan harness's handbook writing wizard. The handbook
|
|
17
|
+
documents *the actual implementation* — how it really works, whereas
|
|
18
|
+
the spec describes *what we want*. It is the technical doc of the
|
|
19
|
+
*how*: files, data flows, internal APIs, patterns used, extension
|
|
20
|
+
points, how to debug.
|
|
21
|
+
|
|
22
|
+
## When to invoke you
|
|
23
|
+
|
|
24
|
+
- The `coding` agent finishes a feature: create or update its handbook
|
|
25
|
+
before committing.
|
|
26
|
+
- `/handbook <name>` invoked explicitly.
|
|
27
|
+
- `doc-audit` flagged an outdated or missing handbook.
|
|
28
|
+
- Major refactor: the existing handbook no longer describes reality.
|
|
29
|
+
|
|
30
|
+
## Procedure
|
|
31
|
+
|
|
32
|
+
1. **Locate** the target: `docs/handbook/<slug>.md`. The `<slug>`
|
|
33
|
+
typically follows the name of the subsystem or feature
|
|
34
|
+
(kebab-case). **No numbering** — the slug is the durable identity;
|
|
35
|
+
no precedence or "ordered chapters" logic is carried by the file
|
|
36
|
+
name.
|
|
37
|
+
2. **Read the code**: identify the core files to track. Typically:
|
|
38
|
+
- The entry point (`src/index.ts`, `packages/<name>/src/...`).
|
|
39
|
+
- The types/schemas/contracts (Zod, TypeScript types).
|
|
40
|
+
- The business logic modules.
|
|
41
|
+
- The related configs (`vercel.json`, `package.json` scripts, env
|
|
42
|
+
vars).
|
|
43
|
+
- The tests that describe the expected behavior.
|
|
44
|
+
Build the `tracks: [...]` list.
|
|
45
|
+
3. **Read the corresponding spec** under `docs/spec/<name>.md` if it
|
|
46
|
+
exists — it is your reference for the *what*. The handbook explains
|
|
47
|
+
*how* it was implemented.
|
|
48
|
+
4. **Read neighboring handbooks** for the house style.
|
|
49
|
+
5. **Load the template** `@vaubaan/harness/templates/handbook.md.tmpl`.
|
|
50
|
+
6. **Draft** the minimal sections:
|
|
51
|
+
- **Overview**: 1-2 ¶ summarizing the implementation (architecture,
|
|
52
|
+
tech choices, core dependencies).
|
|
53
|
+
- **How it works**: explain the flow, file by file or
|
|
54
|
+
responsibility by responsibility. Explicit **cross-links** to code
|
|
55
|
+
files (`src/foo.ts:42`).
|
|
56
|
+
- **How to use it**: public API, invocation examples, CLI commands
|
|
57
|
+
if applicable.
|
|
58
|
+
- **How to debug**: logs to look at, troubleshooting env vars,
|
|
59
|
+
typical errors + resolution.
|
|
60
|
+
- **Extension** (optional): where to add a new variant, how to add
|
|
61
|
+
a plugin / handler / adapter.
|
|
62
|
+
7. **Submit** the draft to the human. Iterate. The human remains the
|
|
63
|
+
owner of the decision about what is documented vs implicit.
|
|
64
|
+
8. **Validate the `tracks:` before writing.** For each entry:
|
|
65
|
+
- Check that the path exists (file or glob matching at least one
|
|
66
|
+
file). If not — it is probably a planning placeholder
|
|
67
|
+
(`feature/foo-impl`, `<name>-rest`, etc.); ask the human to
|
|
68
|
+
provide the real path or remove the entry.
|
|
69
|
+
- **No branch names, no symbolic tokens.** If the feature does not
|
|
70
|
+
have files in place yet, deliver the handbook later or track
|
|
71
|
+
*only* the spec / issue tracker (not a placeholder that will
|
|
72
|
+
silently pass the linters).
|
|
73
|
+
- The `lint:frontmatter-tracks` linter breaks CI on non-existent
|
|
74
|
+
paths — better to find out now.
|
|
75
|
+
9. **Write** `docs/handbook/<name>.md` via `Write`, with a validated
|
|
76
|
+
`tracks: [...]` frontmatter and `last_reviewed: <today>`.
|
|
77
|
+
10. **Update the index**: if `docs/handbook/README.md` exists, add a
|
|
78
|
+
line for the new handbook.
|
|
79
|
+
|
|
80
|
+
## Criteria
|
|
81
|
+
|
|
82
|
+
- **Mention real code**. A handbook that references no file, no
|
|
83
|
+
function, no type, no path = pillar drift (it should be a spec). The
|
|
84
|
+
`lint:pillar-boundaries` linter flags this case.
|
|
85
|
+
- **Cross-link to code**. Conventional format:
|
|
86
|
+
`[\`functionName\`](../../src/foo.ts#LXX-LYY)` or
|
|
87
|
+
`\`src/foo.ts:42\``. These links must resolve to existing code
|
|
88
|
+
(`lint:cross-links` linter).
|
|
89
|
+
- **Complete `tracks:` frontmatter**. List all paths whose evolution
|
|
90
|
+
must trigger a freshness check. If a tracked file disappears, it is
|
|
91
|
+
an error (`lint:frontmatter-tracks` linter).
|
|
92
|
+
- **No spec inside**. If you find yourself explaining *why* the
|
|
93
|
+
subsystem exists or *what* it is for from a vision standpoint, that
|
|
94
|
+
is spec — redirect to `spec-writer`.
|
|
95
|
+
- **No decision inside**. If you find yourself explaining *why we
|
|
96
|
+
chose X over Y*, that is an ADR — redirect to
|
|
97
|
+
`decision-record-writer`.
|
|
98
|
+
- **Actionable**. Someone who has to debug or extend the subsystem
|
|
99
|
+
must be able to read the handbook alone (+ the code) and manage.
|
|
100
|
+
|
|
101
|
+
## Expected output
|
|
102
|
+
|
|
103
|
+
```markdown
|
|
104
|
+
---
|
|
105
|
+
title: <Feature / Subsystem>
|
|
106
|
+
tracks:
|
|
107
|
+
- src/foo.ts
|
|
108
|
+
- src/bar/index.ts
|
|
109
|
+
- packages/<name>/src/**/*.ts
|
|
110
|
+
- .github/workflows/<name>.yml
|
|
111
|
+
- package.json
|
|
112
|
+
last_reviewed: YYYY-MM-DD
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
# <Feature / Subsystem> — handbook
|
|
116
|
+
|
|
117
|
+
<1 line: what this handbook is for, point to the spec if it
|
|
118
|
+
exists.>
|
|
119
|
+
|
|
120
|
+
## Overview
|
|
121
|
+
|
|
122
|
+
<2-4 ¶. Architecture, core tech choices, external dependencies.
|
|
123
|
+
No justification (that lives in the ADRs) — just a snapshot of the
|
|
124
|
+
system's state.>
|
|
125
|
+
|
|
126
|
+
## How it works
|
|
127
|
+
|
|
128
|
+
### <Component / responsibility 1>
|
|
129
|
+
|
|
130
|
+
<Description + code links. Text diagrams if useful.>
|
|
131
|
+
|
|
132
|
+
### <Component / responsibility 2>
|
|
133
|
+
|
|
134
|
+
...
|
|
135
|
+
|
|
136
|
+
## How to use it
|
|
137
|
+
|
|
138
|
+
<Public API, signatures, copy-paste examples.>
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
// example
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## How to debug
|
|
145
|
+
|
|
146
|
+
- **Symptom A** → look at `<file>:<line>`, env var `<NAME>`, log
|
|
147
|
+
`<key>`.
|
|
148
|
+
- ...
|
|
149
|
+
|
|
150
|
+
## Extension (optional)
|
|
151
|
+
|
|
152
|
+
<How to add an X.>
|
|
153
|
+
|
|
154
|
+
## References
|
|
155
|
+
|
|
156
|
+
- Spec: `../spec/<name>.md`
|
|
157
|
+
- Related ADRs: `0007`, `0012`
|
|
158
|
+
- Tests: `../tests/integration-tests.md#scenario-foo`
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Finish by recapping:
|
|
162
|
+
- Path of the written file.
|
|
163
|
+
- List of the `tracks:` set.
|
|
164
|
+
- Suggestions for updating neighboring docs (spec, ADR, tests) if you
|
|
165
|
+
detect a gap.
|
|
166
|
+
|
|
167
|
+
## Guardrails
|
|
168
|
+
|
|
169
|
+
- **Do not guess the code**. If you have not read the file, do not
|
|
170
|
+
document it. Read before writing — otherwise you produce fictional
|
|
171
|
+
docs that will be outdated at the first refactor.
|
|
172
|
+
- **No disguised ADR**. Any *"we chose X because Y"* justification
|
|
173
|
+
must go in a separate ADR and be linked. The handbook describes
|
|
174
|
+
*what is*, not *why*.
|
|
175
|
+
- **No disguised spec**. If the handbook starts talking in abstract
|
|
176
|
+
terms without mentioning code, it is probably spec — switch to
|
|
177
|
+
`spec-writer`.
|
|
178
|
+
- **Exhaustive but minimal `tracks:`**. Include what *drives changes*
|
|
179
|
+
to the handbook (the files whose change means the doc must be
|
|
180
|
+
re-edited). Do not include every file in the repo — that would
|
|
181
|
+
dilute drift detection.
|
|
182
|
+
- **Do not delete the existing version without confirmation**. During
|
|
183
|
+
a refactor, propose an explicit diff. For sections that became
|
|
184
|
+
outdated but are referenced elsewhere, archive rather than delete.
|
|
185
|
+
- **No auto-commit**. Write only.
|