@nurix/etna 0.19.20 → 0.19.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/data/harness-index.json +1 -1
  2. package/data/harnesses/code/.prettierignore +6 -0
  3. package/data/harnesses/code/CLAUDE.md +15 -14
  4. package/data/harnesses/code/agents/maintenance.md +1 -1
  5. package/data/harnesses/code/codex/agents/maintenance.toml +1 -1
  6. package/data/harnesses/code/harness.json +2 -2
  7. package/data/harnesses/code/skills/boundary/SKILL.md +1 -1
  8. package/data/harnesses/code/skills/brainstorm/SKILL.md +1 -1
  9. package/data/harnesses/code/skills/documentation/SKILL.md +64 -107
  10. package/data/harnesses/code/skills/documentation/references/examples.md +83 -7
  11. package/data/harnesses/code/skills/documentation/references/frontmatter.md +44 -0
  12. package/data/harnesses/code/skills/documentation/references/style-guide.md +44 -19
  13. package/data/harnesses/code/skills/documentation/references/untemplated.md +38 -0
  14. package/data/harnesses/code/skills/documentation/scripts/doc-lint.mjs +117 -0
  15. package/data/harnesses/code/skills/documentation/templates/Readme.md +31 -0
  16. package/data/harnesses/code/skills/documentation/templates/api-reference.md +20 -0
  17. package/data/harnesses/code/skills/documentation/templates/architecture-decision.md +121 -0
  18. package/data/harnesses/code/skills/documentation/templates/backlog.md +33 -0
  19. package/data/harnesses/code/skills/documentation/templates/changelog-entry.md +62 -0
  20. package/data/harnesses/code/skills/documentation/templates/changelog-index.md +41 -0
  21. package/data/harnesses/code/skills/documentation/templates/docs-readme.md +70 -0
  22. package/data/harnesses/code/skills/documentation/templates/domain-model.md +30 -0
  23. package/data/harnesses/code/skills/documentation/templates/environment-registry.md +15 -0
  24. package/data/harnesses/code/skills/documentation/templates/feature.md +149 -0
  25. package/data/harnesses/code/skills/documentation/templates/glossary.md +11 -0
  26. package/data/harnesses/code/skills/documentation/templates/memory-main.md +25 -0
  27. package/data/harnesses/code/skills/documentation/templates/migration-runbook.md +34 -0
  28. package/data/harnesses/code/skills/documentation/templates/non-goals.md +11 -0
  29. package/data/harnesses/code/skills/documentation/templates/operations-procedure.md +36 -0
  30. package/data/harnesses/code/skills/documentation/templates/plan.md +64 -0
  31. package/data/harnesses/code/skills/documentation/templates/protected-files.md +37 -0
  32. package/data/harnesses/code/skills/documentation/templates/root-readme.md +104 -0
  33. package/data/harnesses/code/skills/documentation/templates/security-overview.md +27 -0
  34. package/data/harnesses/code/skills/documentation/templates/structure.md +65 -0
  35. package/data/harnesses/code/skills/documentation/templates/system-overview.md +32 -0
  36. package/data/harnesses/code/skills/documentation/templates/testing-strategy.md +29 -0
  37. package/data/harnesses/code/skills/workflow-mapper/SKILL.md +1 -1
  38. package/data/harnesses/discover/.prettierignore +6 -0
  39. package/data/harnesses/discover/CLAUDE.md +11 -12
  40. package/data/harnesses/discover/harness.json +2 -2
  41. package/data/harnesses/discover/tooling-recommendations.md +10 -10
  42. package/data/harnesses/discussion/.prettierignore +6 -0
  43. package/data/harnesses/discussion/harness.json +1 -1
  44. package/data/harnesses/etna/.prettierignore +6 -0
  45. package/data/harnesses/etna/CLAUDE.md +12 -11
  46. package/data/harnesses/etna/agents/maintenance.md +1 -1
  47. package/data/harnesses/etna/codex/agents/maintenance.toml +1 -1
  48. package/data/harnesses/etna/harness.json +2 -2
  49. package/data/harnesses/etna/skills/boundary/SKILL.md +1 -1
  50. package/data/harnesses/etna/skills/brainstorm/SKILL.md +1 -1
  51. package/data/harnesses/etna/skills/documentation/SKILL.md +64 -107
  52. package/data/harnesses/etna/skills/documentation/references/examples.md +83 -7
  53. package/data/harnesses/etna/skills/documentation/references/frontmatter.md +44 -0
  54. package/data/harnesses/etna/skills/documentation/references/style-guide.md +44 -19
  55. package/data/harnesses/etna/skills/documentation/references/untemplated.md +38 -0
  56. package/data/harnesses/etna/skills/documentation/scripts/doc-lint.mjs +117 -0
  57. package/data/harnesses/etna/skills/documentation/templates/Readme.md +31 -0
  58. package/data/harnesses/etna/skills/documentation/templates/api-reference.md +20 -0
  59. package/data/harnesses/etna/skills/documentation/templates/architecture-decision.md +121 -0
  60. package/data/harnesses/etna/skills/documentation/templates/backlog.md +33 -0
  61. package/data/harnesses/etna/skills/documentation/templates/changelog-entry.md +62 -0
  62. package/data/harnesses/etna/skills/documentation/templates/changelog-index.md +41 -0
  63. package/data/harnesses/etna/skills/documentation/templates/docs-readme.md +70 -0
  64. package/data/harnesses/etna/skills/documentation/templates/domain-model.md +30 -0
  65. package/data/harnesses/etna/skills/documentation/templates/environment-registry.md +15 -0
  66. package/data/harnesses/etna/skills/documentation/templates/feature.md +149 -0
  67. package/data/harnesses/etna/skills/documentation/templates/glossary.md +11 -0
  68. package/data/harnesses/etna/skills/documentation/templates/memory-main.md +25 -0
  69. package/data/harnesses/etna/skills/documentation/templates/migration-runbook.md +34 -0
  70. package/data/harnesses/etna/skills/documentation/templates/non-goals.md +11 -0
  71. package/data/harnesses/etna/skills/documentation/templates/operations-procedure.md +36 -0
  72. package/data/harnesses/etna/skills/documentation/templates/plan.md +64 -0
  73. package/data/harnesses/etna/skills/documentation/templates/protected-files.md +37 -0
  74. package/data/harnesses/etna/skills/documentation/templates/root-readme.md +104 -0
  75. package/data/harnesses/etna/skills/documentation/templates/security-overview.md +27 -0
  76. package/data/harnesses/etna/skills/documentation/templates/structure.md +65 -0
  77. package/data/harnesses/etna/skills/documentation/templates/system-overview.md +32 -0
  78. package/data/harnesses/etna/skills/documentation/templates/testing-strategy.md +29 -0
  79. package/data/harnesses/etna/skills/workflow-mapper/SKILL.md +1 -1
  80. package/data/harnesses/hr/.prettierignore +6 -0
  81. package/data/harnesses/hr/CLAUDE.md +19 -23
  82. package/data/harnesses/hr/harness.json +2 -2
  83. package/data/harnesses/hr/skills/evaluator/SKILL.md +1 -1
  84. package/data/harnesses/hr/skills/interview-eval/SKILL.md +1 -1
  85. package/data/harnesses/kb-agi/.prettierignore +6 -0
  86. package/data/harnesses/kb-agi/CLAUDE.md +12 -12
  87. package/data/harnesses/kb-agi/harness.json +1 -1
  88. package/package.json +1 -1
  89. package/data/harnesses/code/skills/documentation/references/templates.md +0 -1091
  90. package/data/harnesses/etna/skills/documentation/references/templates.md +0 -1091
@@ -0,0 +1,117 @@
1
+ // skills/documentation/scripts/doc-lint.mjs - mechanical checks over markdown docs (tense narration, dates, stubs, redirects)
2
+ // Usage: node doc-lint.mjs <file.md ...> | node doc-lint.mjs --changed (git-changed + untracked .md)
3
+ // Exit 1 when any block-severity finding survives. Escape hatch: <!-- doc-lint-disable: id[, id] --> (file-wide, or on the offending line).
4
+
5
+ import { readFileSync, existsSync } from 'node:fs';
6
+ import { execSync } from 'node:child_process';
7
+
8
+ const RULES = [
9
+ { id: 'stale-tripwire', severity: 'block', scope: 'truth', pattern: /treat (any )?[\w`./-]+ ?(references? )?as stale|superseded (by|the)|\bused to (be|target|live|hold)\b/i, message: 'stale-reference tripwire / supersession talk — fix the references, state the present fact' },
10
+ { id: 'history-narration', severity: 'block', scope: 'truth', pattern: /\bno longer\b|\bwas (renamed|removed|extracted|folded|migrated|replaced)\b|\bmoved (to|from|into) [\w`./-]+ \(?20\d{2}/i, message: 'history narration — the journey belongs in a dated record' },
11
+ { id: 'progress-marker', severity: 'block', scope: 'truth', pattern: /\bphases?\s+\d[^.\n]{0,40}\b(complete|done)\b|\b(build|implementation) (is )?(\d+%|partially) (complete|done)\b/i, message: 'progress marker — progress lives in the plan/backlog record' },
12
+ { id: 'temporal-hedge', severity: 'warn', scope: 'truth', pattern: /\bnot yet\b|\bfor now\b|\bcurrently\b|\bstill (unsupported|missing|pending|unimplemented|in progress)\b/i, message: 'temporal hedge — state the fact without "currently / not yet / for now"' },
13
+ { id: 'predecessor-frame', severity: 'warn', scope: 'truth', pattern: /\bpreviously\b|\bthe old \w+\b|\blegacy \w+ (was|is)\b/i, message: 'predecessor framing — describe the one current design' },
14
+ { id: 'status-glyph', severity: 'warn', scope: 'truth', pattern: /(^|\s)(✅|⏳|- \[[ x]\])/u, message: 'status glyph / checklist in a truth doc — tracking belongs in a record' },
15
+ { id: 'date-in-truth-doc', severity: 'warn', scope: 'truth', pattern: /\b20\d{2}-\d{2}-\d{2}\b/, message: 'date in a truth doc — only the AD Decision Changelog and structure.md Health Log tails carry dates' },
16
+ ];
17
+
18
+ // Sections inside a truth doc where dated history is sanctioned (the two bridges).
19
+ const BRIDGE_HEADINGS = /^#{1,4}\s+(decision changelog|health log)\b/i;
20
+ // Instruction files and generated trees are a different genre — out of this linter's scope.
21
+ const SKIP = /(^|\/)(\.claude|node_modules|skills|rules|agents|harness|packages\/[^/]+\/data)\/|(^|\/)(CLAUDE|AGENTS)\.md$/;
22
+ const RECORD = /(^|\/)docs\/(history|research|memory)\//;
23
+
24
+ // Classify a path: skipped genre, record, or truth.
25
+ function scopeOf(path) {
26
+ if (SKIP.test(path)) return 'skip';
27
+ return RECORD.test(path) ? 'record' : 'truth';
28
+ }
29
+
30
+ // Yield prose lines only: frontmatter, fenced code blocks, and bridge sections drop out.
31
+ function proseLines(text) {
32
+ const lines = text.split('\n');
33
+ const out = [];
34
+ let inFence = false;
35
+ let inFrontmatter = lines[0] === '---';
36
+ let inBridge = false;
37
+ let bridgeLevel = 0;
38
+ for (let i = inFrontmatter ? 1 : 0; i < lines.length; i++) {
39
+ const line = lines[i];
40
+ if (inFrontmatter) { if (line === '---') inFrontmatter = false; continue; }
41
+ if (/^\s*(```|~~~|````)/.test(line)) { inFence = !inFence; continue; }
42
+ if (inFence) continue;
43
+ const heading = line.match(/^(#{1,4})\s/);
44
+ if (heading) {
45
+ if (inBridge && heading[1].length <= bridgeLevel) inBridge = false;
46
+ if (BRIDGE_HEADINGS.test(line)) { inBridge = true; bridgeLevel = heading[1].length; }
47
+ }
48
+ if (!inBridge) out.push({ n: i + 1, line });
49
+ }
50
+ return out;
51
+ }
52
+
53
+ // Collect file-wide disabled rule ids from <!-- doc-lint-disable: a, b --> comments.
54
+ function fileDisables(text) {
55
+ const ids = new Set();
56
+ for (const m of text.matchAll(/<!--\s*doc-lint-disable:\s*([\w-,\s]+?)\s*-->/g))
57
+ m[1].split(',').forEach((id) => ids.add(id.trim()));
58
+ return ids;
59
+ }
60
+
61
+ function lintFile(path, findings) {
62
+ const scope = scopeOf(path);
63
+ if (scope === 'skip' || !existsSync(path)) return;
64
+ const text = readFileSync(path, 'utf8');
65
+ const disabled = fileDisables(text);
66
+ const lines = proseLines(text);
67
+
68
+ const nonEmpty = text.split('\n').filter((l) => l.trim()).length;
69
+ if (scope === 'truth' && nonEmpty <= 10 && /\b(moved to|relocated to|see [\w`./-]+ instead)\b/i.test(text) && !disabled.has('redirect-doc'))
70
+ findings.push({ path, n: 1, severity: 'block', id: 'redirect-doc', message: 'redirect stub — delete the file and repoint every inbound link' });
71
+
72
+ for (const rule of RULES) {
73
+ if (rule.scope !== scope || disabled.has(rule.id)) continue;
74
+ for (const { n, line } of lines) {
75
+ if (!rule.pattern.test(line)) continue;
76
+ if (line.includes(`doc-lint-disable: ${rule.id}`) || new RegExp(`doc-lint-disable:[^>]*\\b${rule.id}\\b`).test(line)) continue;
77
+ findings.push({ path, n, severity: rule.severity, id: rule.id, message: rule.message, excerpt: line.trim().slice(0, 90) });
78
+ }
79
+ }
80
+
81
+ if (scope === 'truth' && /(^|\/)docs\/features\/[^/]+\.md$/.test(path)) {
82
+ const fm = text.startsWith('---') ? text.slice(0, text.indexOf('\n---', 3)) : '';
83
+ for (const key of ['owns:', 'keywords:', 'status:'])
84
+ if (!fm.includes(key)) findings.push({ path, n: 1, severity: 'block', id: 'feature-frontmatter', message: `feature doc missing \`${key}\` frontmatter` });
85
+ }
86
+ }
87
+
88
+ // A changed plan whose committed version is already frozen must not be edited.
89
+ function checkFrozenEdits(paths, findings) {
90
+ for (const path of paths) {
91
+ if (!/(^|\/)docs\/history\/(plans|changelog|migrations)\//.test(path)) continue;
92
+ try {
93
+ const head = execSync(`git show HEAD:"${path}"`, { encoding: 'utf8', stdio: ['pipe', 'pipe', 'ignore'] });
94
+ if (/(^|\/)plans\//.test(path) && !/Status:\s*(Complete|Abandoned)/i.test(head)) continue;
95
+ findings.push({ path, n: 1, severity: 'block', id: 'frozen-record-edit', message: 'frozen record modified — records are never edited; write a new dated record that links back' });
96
+ } catch { /* new file — creating a record is fine */ }
97
+ }
98
+ }
99
+
100
+ const args = process.argv.slice(2);
101
+ let files = args.filter((a) => a !== '--changed');
102
+ const changedMode = args.includes('--changed');
103
+ if (changedMode) {
104
+ const out = execSync('git diff --name-only HEAD -- "*.md"; git ls-files --others --exclude-standard -- "*.md"', { encoding: 'utf8', shell: '/bin/bash' });
105
+ files = [...new Set([...files, ...out.split('\n').filter(Boolean)])];
106
+ }
107
+ if (!files.length) { console.error('usage: node doc-lint.mjs <file.md ...> | --changed'); process.exit(2); }
108
+
109
+ const findings = [];
110
+ files.forEach((f) => lintFile(f, findings));
111
+ if (changedMode) checkFrozenEdits(files.filter((f) => existsSync(f)), findings);
112
+
113
+ for (const f of findings.sort((a, b) => (a.severity === b.severity ? 0 : a.severity === 'block' ? -1 : 1)))
114
+ console.log(`${f.path}:${f.n} [${f.severity}] ${f.id} — ${f.message}${f.excerpt ? `: "${f.excerpt}"` : ''}`);
115
+ const blocks = findings.filter((f) => f.severity === 'block').length;
116
+ console.log(`\n${findings.length} finding(s), ${blocks} blocking, ${files.length} file(s) checked.`);
117
+ process.exit(blocks ? 1 : 0);
@@ -0,0 +1,31 @@
1
+ # Documentation Templates
2
+
3
+ One file per template. Every template is either a **truth document** (states current absolutes, updated in place) or a **record** (dated account of activity, frozen or append-only) — the split is defined in `SKILL.md` § The Two Natures, and each template names its nature in its opening line.
4
+
5
+ | Template | File | Nature |
6
+ | --- | --- | --- |
7
+ | Feature (LLD) | [feature.md](feature.md) | Truth |
8
+ | Architecture Decision (AD) | [architecture-decision.md](architecture-decision.md) | Truth (Decision Changelog tail sanctioned) |
9
+ | System overview | [system-overview.md](system-overview.md) | Truth |
10
+ | Domain model | [domain-model.md](domain-model.md) | Truth |
11
+ | Glossary | [glossary.md](glossary.md) | Truth |
12
+ | Non-goals | [non-goals.md](non-goals.md) | Truth |
13
+ | API reference | [api-reference.md](api-reference.md) | Truth |
14
+ | Environment registry | [environment-registry.md](environment-registry.md) | Truth |
15
+ | Security overview | [security-overview.md](security-overview.md) | Truth |
16
+ | Testing strategy | [testing-strategy.md](testing-strategy.md) | Truth |
17
+ | Operations procedure | [operations-procedure.md](operations-procedure.md) | Truth |
18
+ | Protected files | [protected-files.md](protected-files.md) | Truth |
19
+ | Project root README | [root-readme.md](root-readme.md) | Truth |
20
+ | docs/README.md (doc index) | [docs-readme.md](docs-readme.md) | Truth |
21
+ | docs/structure.md (authority map) | [structure.md](structure.md) | Truth (Health Log tail sanctioned) |
22
+ | Plan | [plan.md](plan.md) | Record |
23
+ | Changelog entry | [changelog-entry.md](changelog-entry.md) | Record |
24
+ | Migration runbook | [migration-runbook.md](migration-runbook.md) | Record |
25
+ | CHANGELOG master index | [changelog-index.md](changelog-index.md) | Record index (append-only) |
26
+ | Backlog | [backlog.md](backlog.md) | Record (append-only) |
27
+ | Memory (main agent) | [memory-main.md](memory-main.md) | Record (append-only ledger) |
28
+
29
+ **Baseline scaffolds** — files that must exist after every baseline; the `maintenance` agent (baseline mode) creates any that are missing: [docs-readme.md](docs-readme.md), [structure.md](structure.md), [changelog-index.md](changelog-index.md), [backlog.md](backlog.md), [memory-main.md](memory-main.md), and [root-readme.md](root-readme.md) (never overwriting an existing root README).
30
+
31
+ **Ownership.** A feature doc is the canonical reference for the code paths in its **`owns:` frontmatter** — the only ownership key. To find what a doc owns, read its `owns:` globs; to find the doc for a path, match the path against the injected ownership index (the union of every feature's `owns:` globs), narrower glob wins. See [`../references/frontmatter.md`](../references/frontmatter.md) for turning code into `owns:` globs.
@@ -0,0 +1,20 @@
1
+ # API Reference (docs/architecture/api.md)
2
+
3
+ Truth document. Use for: the consolidated catalog of the system's HTTP surface — every live route in one place. This is the **index**: request/response shapes stay in the owning feature docs; this doc answers "what exists and where is it documented." If the repo generates an OpenAPI spec, this doc points at it and carries only what the spec can't (auth model, conventions, ownership links).
4
+
5
+ Required: **Conventions**, the **route tables**. One row per live route; a route that isn't here doesn't exist.
6
+
7
+ ```
8
+ # API Reference
9
+
10
+ ## Conventions
11
+
12
+ - Base path: `/api/v{N}` · Auth: {scheme} · Envelope: `{ "status": 1, "message": "...", "data": {...} }`
13
+ - Errors: `{ "status": 0, "message": "...", "data": null }` · Codes: 200/201/400/401/403/404/500
14
+
15
+ ## {Resource group}
16
+
17
+ | Method | Path | Purpose | Auth | Owning doc |
18
+ | ------ | ---- | ------- | ---- | ---------- |
19
+ | GET | `/api/foo` | {one line} | {role} | [feature](../features/{feature}.md) |
20
+ ```
@@ -0,0 +1,121 @@
1
+ # Architecture Decision (AD)
2
+
3
+ Truth document — with the one sanctioned dated tail. Use for: the standing decision on one architectural **subject** — a system shape, a contract, a substrate choice. Lives in `docs/architecture/decisions/`. The body always states the current decision and its current reasoning. When the decision moves, rewrite the affected sections to what is now true, bump `last-updated`, and append the revision to the **Decision Changelog** — the journey lives in that tail, never in the body. Head is truth; tail is provenance.
4
+
5
+ ### One subject per AD
6
+
7
+ The unit is the subject, not the individual call. "The persistence layer", "auth", "the design-skill architecture" are subjects; every decision, reversal, and re-decision on a subject lands in that subject's one AD, however many times it moves. Write a second AD only when a genuinely separate subject emerges — never to record a revision of an existing one.
8
+
9
+ ### When to write an AD
10
+
11
+ Write an AD when **all three** apply:
12
+
13
+ 1. The decision is architectural — affects system shape, contracts, or substrate choice, not internal implementation
14
+ 2. Alternatives were genuinely considered and rejected
15
+ 3. Future maintainers will ask "why is it this way?"
16
+
17
+ Don't write an AD for:
18
+
19
+ - Standing principles or style preferences (those are stances, not decisions — put them in `docs/architecture/`)
20
+ - Routine implementation choices with no rejected alternatives
21
+ - Anything you'd be happy reversing without ceremony
22
+
23
+ ### Lifecycle
24
+
25
+ `Proposed` → `Accepted` → `Deprecated`
26
+
27
+ Frontmatter `status:` is the single lifecycle source of truth. An AD stays `Accepted` for as long as its subject is live — revisions rewrite the body and never change the status, and there is **no `Superseded` state**: supersession is an edit plus a changelog entry, not a new document. Set `Deprecated` only when the subject itself is retired (the component is gone, the contract no longer exists); state where the replacement lives, if any.
28
+
29
+ ### Naming
30
+
31
+ `AD-NNN-short-title.md` — three-digit zero-padded number, kebab-case subject. Numbers are assigned sequentially across the project and never reused.
32
+
33
+ ### Structure
34
+
35
+ Three sections are required: **Decision**, **Context**, **Consequences** — plus the **Decision Changelog** once the AD has been revised at least once. Everything else is optional — include only when warranted. Decision-first: readers should see the answer in the first paragraph.
36
+
37
+ ### Template
38
+
39
+ ```markdown
40
+ ---
41
+ title: "AD-NNN: Short title in sentence case"
42
+ status: Accepted # Proposed | Accepted | Deprecated
43
+ created: YYYY-MM-DD
44
+ last-updated: YYYY-MM-DD # bump on every revision
45
+ decision-owner: Name
46
+ reviewers: [] # optional
47
+ tags: [ad]
48
+ ---
49
+
50
+ # AD-NNN: Short Title
51
+
52
+ ## Decision
53
+
54
+ [One paragraph, active voice. "We will…" Lead with the answer — the current answer, whatever the journey was.]
55
+
56
+ ## Context
57
+
58
+ [The forces in play. What is the problem? Why does it need a decision? Technical, political, social, and project-local pressures — stated as present-tense forces, not as a history of the subject.]
59
+
60
+ ## Consequences
61
+
62
+ **Positive:**
63
+
64
+ - [What becomes easier]
65
+
66
+ **Negative:**
67
+
68
+ - [What becomes harder, what we accept reluctantly]
69
+
70
+ **Risks:**
71
+
72
+ - [Second-order effects you can already see, with mitigations if known]
73
+
74
+ <!-- Optional sections below. Include only when warranted by the decision's weight. -->
75
+
76
+ ## Decision Drivers
77
+
78
+ [Hard non-negotiables vs. strong levers. Include when alternatives exist and the criteria aren't self-evident from Context.]
79
+
80
+ ## Options Considered
81
+
82
+ | Option | Pros | Cons | Outcome |
83
+ | ------------ | ---- | ---- | --------------------- |
84
+ | **Option A** | … | … | **CHOSEN** |
85
+ | Option B | … | … | Eliminated — [reason] |
86
+
87
+ ## Deep Comparison
88
+
89
+ [Honest framing of the strongest alternative(s). Include when the table doesn't make the reasoning obvious. State the *real* reason each was rejected — not a strawman.]
90
+
91
+ ## Architecture in Detail
92
+
93
+ [Diagrams, code shape, layer responsibilities. Include when the decision implies non-trivial structure that readers need to understand alongside the *why*. Execution belongs in a plan doc (`docs/history/plans/`) — link to it, don't embed an implementation plan here.]
94
+
95
+ ## Open Questions
96
+
97
+ 1. **[Question]** — _Default_: [stated default until resolved].
98
+
99
+ ## References
100
+
101
+ - [External link or cross-reference]
102
+
103
+ ## Decision Changelog
104
+
105
+ <!-- The provenance tail — append-only, newest first. One entry per revision: what changed, the trigger, the previous choice, and the plan that implemented it. Added on the first revision; the initial acceptance is the last entry. -->
106
+
107
+ - YYYY-MM-DD — [What changed] because [trigger]. Implemented by [plan link]. (Previously: [old choice].)
108
+ - YYYY-MM-DD — Initial decision accepted. Implemented by [plan link].
109
+ ```
110
+
111
+ ### Rules
112
+
113
+ - **One subject per AD; all its revisions stay inside it.** Two genuinely different subjects means two ADs — a revision of an existing subject never does.
114
+ - **The body is always the current truth.** Rewrite affected sections on every revision; never leave a superseded choice narrated in the body — the Decision Changelog carries the journey, with each entry naming the old choice and the trigger.
115
+ - Decision-first. The first paragraph after the heading is the answer; readers should not need to scroll.
116
+ - **Consequences lists positives, negatives, AND risks.** Pros-only Consequences is the genre's classic failure — one AD's honest resulting context is the input context for the next.
117
+ - **Options Considered keeps every genuinely rejected alternative with the real reason.** Informed rejections are the most expensive knowledge to lose; a rejection made with strong prior art in view says so explicitly.
118
+ - **Keep it short — one to two pages.** Long decision docs don't get updated. How-it-works detail belongs in the owning feature doc; execution in a plan. Link, don't embed.
119
+ - No section numbering (`§5.1.1`). Use markdown headings only — inserting a section shouldn't renumber everything.
120
+ - Frontmatter `status` is the single source of truth for lifecycle. Don't also write "Status: Accepted" in the body.
121
+ - The Decision Changelog is append-only, newest first. Typo and formatting fixes don't get entries.
@@ -0,0 +1,33 @@
1
+ # Scaffold: docs/history/backlog.md
2
+
3
+ Baseline scaffold — created if missing (the `maintenance` agent's baseline calls this). Target file: `docs/history/backlog.md`.
4
+
5
+ ```
6
+ # Backlog
7
+
8
+ Tracked work items, technical debt, and planned improvements. Append new items under the appropriate priority.
9
+
10
+ ---
11
+
12
+ ## Format
13
+
14
+ - **[P0]** Description — discovered by [plan-name or agent-name]
15
+
16
+ ---
17
+
18
+ ## P0 — Critical
19
+
20
+ {items here}
21
+
22
+ ## P1 — High
23
+
24
+ {items here}
25
+
26
+ ## P2 — Medium
27
+
28
+ {items here}
29
+
30
+ ## P3 — Low
31
+
32
+ {items here}
33
+ ```
@@ -0,0 +1,62 @@
1
+ # Changelog
2
+
3
+ Record. Use for: recording code changes with function-level detail. Entries are frozen once written — they describe the change as it shipped, and are never edited to match later reality.
4
+
5
+ Change categories follow the Keep a Changelog vocabulary — **Added / Changed / Deprecated / Removed / Fixed / Security** — the same six the master `CHANGELOG.md` scaffold instructs. Include only the categories that apply; all six share the same bullet shape (function/file, then detail lines).
6
+
7
+ ```
8
+ # YYYY-MM-DD - [Title]
9
+
10
+ ## Summary
11
+
12
+ Brief description of what changed and why.
13
+
14
+ ## Changes
15
+
16
+ ### Added
17
+ - `newFunction(params)` in `path/to/file.js`
18
+ - Purpose: What it does
19
+ - Used by: Where it's called
20
+
21
+ ### Changed
22
+ - `existingFunction()` in `path/to/file.js`
23
+ - Changed: What's different
24
+ - Reason: Why it changed
25
+ - Migration: What callers must do
26
+
27
+ ### Removed
28
+ - `oldFunction()` from `path/to/file.js`
29
+ - Replaced by: `newFunction()`
30
+
31
+ ### Fixed
32
+ - `buggyFunction()` in `path/to/file.js`
33
+ - Bug: What was wrong, when it manifested
34
+ - Fix: What changed
35
+
36
+ (Deprecated / Security follow the same shape.)
37
+
38
+ ## Breaking Changes
39
+
40
+ ⚠️ **[Change description]**
41
+ - Old: Previous behavior
42
+ - New: Current behavior
43
+ - Impact: What breaks
44
+ - Migration: How to fix
45
+
46
+ ## Migration Steps
47
+
48
+ Numbered instructions for whoever applies the change — not a tracked task list (the entry is frozen once written):
49
+
50
+ 1. {Step}
51
+ 2. {Step}
52
+
53
+ ## Verified
54
+
55
+ - What was exercised end-to-end and the observed result — real runs, real fixtures, measured timings
56
+ - A future agent diagnosing a regression starts from this evidence
57
+
58
+ ## Files Changed
59
+
60
+ - `src/path/file1.js` - Core changes
61
+ - `src/path/file2.js` - Supporting updates
62
+ ```
@@ -0,0 +1,41 @@
1
+ # Scaffold: docs/history/CHANGELOG.md
2
+
3
+ Baseline scaffold — created if missing (the `maintenance` agent's baseline calls this). Target file: `docs/history/CHANGELOG.md`.
4
+
5
+ ```
6
+ # Changelog
7
+
8
+ All notable changes to {Project Name} will be documented in this file.
9
+
10
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
11
+
12
+ ---
13
+
14
+ ## [Unreleased]
15
+
16
+ {entries added here as work proceeds; promoting them under a release heading is the one sanctioned edit to this index — the dated entry files themselves stay frozen}
17
+
18
+ ---
19
+
20
+ ## Links
21
+
22
+ - [Setup Guide](../operations/setup.md)
23
+ - [Architecture](../architecture/)
24
+
25
+ ---
26
+
27
+ ## How to Update This Changelog
28
+
29
+ 1. Create a dated change file in `docs/history/changelog/`:
30
+ `docs/history/changelog/YYYY-MM-DD-feature-name.md`
31
+
32
+ 2. Update this CHANGELOG.md with a high-level summary linking to the detail file
33
+
34
+ 3. Follow Keep a Changelog categories:
35
+ - **Added** for new features
36
+ - **Changed** for changes in existing functionality
37
+ - **Deprecated** for soon-to-be removed features
38
+ - **Removed** for now removed features
39
+ - **Fixed** for bug fixes
40
+ - **Security** for security improvements
41
+ ```
@@ -0,0 +1,70 @@
1
+ # docs/README.md (Documentation Root)
2
+
3
+ Truth document. Use for: the entry point for all documentation in a repo. Created during baseline audit.
4
+
5
+ ```
6
+ # {Project Name} Documentation
7
+
8
+ Technical documentation for {project description}.
9
+
10
+ > For documentation organization, authority map, and folder rules, see **[structure.md](structure.md)**.
11
+
12
+ ---
13
+
14
+ ## Quick Links
15
+
16
+ | Document | Description |
17
+ | --------------------------------- | ------------------------------------ |
18
+ | [Structure](structure.md) | Documentation entry point and rules |
19
+ | [Setup](operations/setup.md) | Installation and configuration guide |
20
+
21
+ ---
22
+
23
+ ## Architecture
24
+
25
+ System design, steering docs, and standing decisions — the truth layer.
26
+
27
+ - [system-design.md](architecture/system-design.md) - System overview: subsystems and key flows
28
+ - [domain-model.md](architecture/domain-model.md) - Entities, relationships, state ownership
29
+ - [glossary.md](architecture/glossary.md) - Project vocabulary
30
+ - [non-goals.md](architecture/non-goals.md) - What this system deliberately does not do
31
+ - [decisions/](architecture/decisions/Readme.md) - Architecture Decisions (ADs)
32
+ {list other architecture docs — api.md, security.md — when present}
33
+
34
+ ---
35
+
36
+ ## Features
37
+
38
+ Living reference docs for implemented features (how things currently work).
39
+
40
+ - [feature-name.md](features/feature-name.md) - Feature description
41
+ {list all feature docs}
42
+
43
+ ---
44
+
45
+ ## Operations
46
+
47
+ How to run, develop, and deploy.
48
+
49
+ - [setup.md](operations/setup.md) - Installation and configuration guide
50
+ {list all operations docs — environment.md when present}
51
+
52
+ ---
53
+
54
+ ## History
55
+
56
+ The records — everything dated, frozen, or append-only.
57
+
58
+ - [CHANGELOG.md](history/CHANGELOG.md) - Master changelog index
59
+ - [changelog/](history/changelog/) - Individual changelog entries
60
+ - [plans/](history/plans/) - Implementation plans (frozen at completion)
61
+ - [migrations/](history/migrations/) - One-shot migration runbooks (frozen once executed)
62
+ - [research/](history/research/) - Deep-research artifacts (one folder per topic)
63
+ - [backlog.md](history/backlog.md) - Tracked work items and technical debt
64
+
65
+ ---
66
+
67
+ ## Contributing
68
+
69
+ See [CLAUDE.md](../CLAUDE.md) for documentation guidelines.
70
+ ```
@@ -0,0 +1,30 @@
1
+ # Domain Model (docs/architecture/domain-model.md)
2
+
3
+ Truth document. Use for: the entities the system is about — what they are, how they relate, and who owns their state. The vocabulary here must match the glossary and the code; when they disagree, fix the disagreement, don't document around it.
4
+
5
+ Required: **Entities**, **Relationships**. Optional: Lifecycle states, Invariants.
6
+
7
+ ```
8
+ # Domain Model
9
+
10
+ ## Entities
11
+
12
+ | Entity | What it is | State lives in |
13
+ | ------ | ---------- | -------------- |
14
+ | {Entity} | {one line} | {table / slice / service} |
15
+
16
+ ## Relationships
17
+
18
+ - {EntityA} 1—N {EntityB} — {the meaning of the link}
19
+ - {EntityB} N—N {EntityC} via {join} — {meaning}
20
+
21
+ ## Lifecycle states
22
+
23
+ {Only for entities with real state machines.}
24
+
25
+ - **{Entity}**: draft → active → archived — {what moves it between states}
26
+
27
+ ## Invariants
28
+
29
+ - {A relationship or state rule that must always hold, stated as a constraint}
30
+ ```
@@ -0,0 +1,15 @@
1
+ # Environment Registry (docs/operations/environment.md)
2
+
3
+ Truth document. Use for: the config surface — every variable the code reads, in one table. `.env.example` mirrors this doc's variable list.
4
+
5
+ **Placeholders only, never real values.** A real-looking password, account ID, or personal profile name in a doc is a leak, and one developer's local setup written as the canonical value is a trap for everyone else. Values in this doc are `{placeholder}` descriptions.
6
+
7
+ ```
8
+ # Environment Registry
9
+
10
+ Every variable the code reads. `.env.example` mirrors this list.
11
+
12
+ | Variable | Purpose | Required | Where set | Secret |
13
+ | -------- | ------- | -------- | --------- | ------ |
14
+ | `DATABASE_URL` | {one line} | yes / default: `{value}` | local `.env` / CI / prod | yes |
15
+ ```