the-grimoire-cli 0.3.2 → 0.5.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/.agents/AGENTS.md +112 -112
- package/.agents/NAVIGATOR.md +193 -168
- package/.agents/VERSION +4 -4
- package/.agents/agents/INDEX.md +7 -7
- package/.agents/agents/verifier.md +50 -50
- package/.agents/commands/INDEX.md +11 -11
- package/.agents/commands/checkpoint.md +15 -15
- package/.agents/commands/grimoire.md +14 -14
- package/.agents/commands/onboard.md +56 -56
- package/.agents/commands/present.md +23 -23
- package/.agents/commands/verify.md +20 -20
- package/.agents/grimoire.manifest +18 -18
- package/.agents/rules/00-always.md +42 -42
- package/.agents/rules/05-code-quality.md +28 -28
- package/.agents/rules/10-working-process.md +31 -31
- package/.agents/rules/15-skills.md +27 -27
- package/.agents/rules/20-modes.md +41 -41
- package/.agents/rules/25-surgical-changes.md +29 -29
- package/.agents/rules/30-verification.md +36 -36
- package/.agents/rules/35-context-economy.md +41 -41
- package/.agents/rules/40-handoff.md +25 -25
- package/.agents/rules/45-presentation.md +35 -35
- package/.agents/rules/50-security.md +30 -30
- package/.agents/rules/60-commit-style.md +14 -14
- package/.agents/rules/INDEX.md +18 -18
- package/.agents/skills/INDEX.md +8 -8
- package/.agents/skills/README.md +1 -1
- package/.agents/skills/catalog.md +106 -106
- package/.agents/skills/find-skills/SKILL.md +142 -142
- package/.agents/stack/README.md +71 -66
- package/.agents/stack/desktop.md +36 -36
- package/.agents/stack/library.md +1 -1
- package/.agents/stack/web-app.md +32 -32
- package/.agents/standards/INDEX.md +23 -23
- package/.agents/standards/accessibility.md +50 -50
- package/.agents/standards/architecture.md +39 -39
- package/.agents/standards/attribution.md +39 -39
- package/.agents/standards/clean-code.md +121 -121
- package/.agents/standards/codex.md +69 -69
- package/.agents/standards/error-codes.md +41 -41
- package/.agents/standards/general.md +46 -46
- package/.agents/standards/guardrail-tests.md +40 -40
- package/.agents/standards/knowledge-management.md +35 -35
- package/.agents/standards/launch-security-checklist.md +45 -45
- package/.agents/standards/observability.md +35 -35
- package/.agents/standards/release-versioning.md +53 -53
- package/.agents/standards/requirements.md +75 -75
- package/.agents/standards/security-scanners.md +42 -42
- package/.agents/standards/testing-strategy.md +61 -61
- package/.agents/standards/typescript.md +19 -19
- package/.agents/standards/writing.md +58 -58
- package/.agents/tooling.json +20 -19
- package/LICENSE +1 -1
- package/README.md +139 -139
- package/bin/grimoire.mjs +667 -598
- package/package.json +32 -32
- package/templates/CLAUDE.md +7 -7
- package/templates/ci/ci.yml +49 -49
- package/templates/ci/sast.yml +44 -44
- package/templates/codex/INDEX.md +18 -18
- package/templates/codex/README.md +28 -28
- package/templates/codex/decisions/0000-template.md +36 -36
- package/templates/codex/decisions/INDEX.md +11 -11
- package/templates/codex/decisions/README.md +25 -25
- package/templates/codex/domain/INDEX.md +14 -14
- package/templates/codex/domain/README.md +10 -10
- package/templates/codex/evidence/0000-extraction-template.md +36 -36
- package/templates/codex/evidence/INDEX.md +11 -11
- package/templates/codex/evidence/README.md +15 -15
- package/templates/codex/reference/INDEX.md +11 -11
- package/templates/codex/reference/README.md +15 -15
- package/templates/codex/reference/confirmed-values.md +18 -18
- package/templates/codex/requirements/INDEX.md +11 -11
- package/templates/codex/requirements/README.md +22 -22
- package/templates/codex/requirements/addons/0000-template.md +35 -35
- package/templates/codex/requirements/base.md +36 -36
- package/templates/codex/requirements/changes/0000-template.md +39 -39
- package/templates/codex/resources/INDEX.md +11 -11
- package/templates/codex/resources/README.md +17 -17
- package/templates/codex/resources/manifest.md +11 -11
- package/templates/codex/runbooks/INDEX.md +9 -9
- package/templates/codex/runbooks/README.md +8 -8
- package/templates/codex/runbooks/incident-runbook-template.md +58 -58
- package/templates/gitignore-snippet.txt +10 -12
- package/templates/journal/backlog/README.md +18 -18
- package/templates/journal/memory/MEMORY.md +15 -15
- package/templates/journal/session/archive/.gitkeep +1 -1
- package/templates/journal/session/artifacts/.gitkeep +1 -1
- package/templates/journal/session/current.md +12 -12
- package/templates/lint/README.md +25 -25
- package/templates/lint/eslint.config.mjs +33 -33
- package/templates/lint/tsconfig.base.json +11 -11
- package/templates/local/AGENTS.local.md +33 -33
- package/templates/local/README.md +55 -55
- package/templates/tests/guardrail.invariants.test.ts +59 -59
|
@@ -1,121 +1,121 @@
|
|
|
1
|
-
---
|
|
2
|
-
updated: 2026-05-31
|
|
3
|
-
status: canonical
|
|
4
|
-
description: 'The canonical code-quality standard: minimize complexity, with limits, type-safety, and performance rules.'
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Standards — clean code
|
|
8
|
-
|
|
9
|
-
The one goal: **minimize complexity** — the cognitive load to understand and safely change the code
|
|
10
|
-
(Ousterhout, *A Philosophy of Software Design*). Every rule below serves that goal; when two rules
|
|
11
|
-
seem to conflict, pick the option a reader understands faster. Supporting canon: KISS, YAGNI,
|
|
12
|
-
DRY-on-the-third-repetition, information hiding, SOLID.
|
|
13
|
-
|
|
14
|
-
> Language-agnostic core. TypeScript specifics: `standards/typescript.md`. Always-on summary:
|
|
15
|
-
> `rules/05-code-quality.md`. Mechanical enforcement: `templates/lint/`.
|
|
16
|
-
|
|
17
|
-
## When to read
|
|
18
|
-
|
|
19
|
-
Any change under `src/` (or the project's source root), and when reviewing another agent's output.
|
|
20
|
-
|
|
21
|
-
## Limits
|
|
22
|
-
|
|
23
|
-
Guardrails, not goals — a function at 49 lines is not "good" because it fits. Projects may override
|
|
24
|
-
in `local/`. Enforced by `templates/lint/` where the stack supports it.
|
|
25
|
-
|
|
26
|
-
| Constraint | Limit | Past it |
|
|
27
|
-
|---|---|---|
|
|
28
|
-
| Function length | ≤ 50 lines | extract a helper |
|
|
29
|
-
| Parameters | ≤ 4 | pass an options object |
|
|
30
|
-
| Nesting depth | ≤ 3 | guard clauses / extract |
|
|
31
|
-
| Cyclomatic complexity | ≤ 10 | split the branch logic |
|
|
32
|
-
| File length | soft 200 / hard 300 | split by responsibility |
|
|
33
|
-
|
|
34
|
-
## Readability
|
|
35
|
-
|
|
36
|
-
- Guard clauses and early returns over nested `if`/`else`.
|
|
37
|
-
- No dense one-liners that trade clarity for brevity.
|
|
38
|
-
- No magic numbers or strings — name them (`const MAX_RETRIES = 3`).
|
|
39
|
-
- Names come from the domain, not the implementation; match the surrounding code.
|
|
40
|
-
- Comments explain **why** (constraints, workarounds, invariants), never **what**. Delete comments
|
|
41
|
-
that restate the code.
|
|
42
|
-
|
|
43
|
-
## The ladder (climb before you write)
|
|
44
|
-
|
|
45
|
-
YAGNI as a reflex, not a slogan. Before writing code, stop at the **first rung that holds**:
|
|
46
|
-
|
|
47
|
-
1. **Does this need to exist?** Speculative need → skip it, say so in one line.
|
|
48
|
-
2. **Stdlib does it?** Use it.
|
|
49
|
-
3. **Native platform feature covers it?** DB constraint over app code, CSS over JS, `<input type="date">` over a picker lib.
|
|
50
|
-
4. **Already-installed dependency solves it?** Use it — never add a new dep for what a few lines do.
|
|
51
|
-
5. **One line?** One line.
|
|
52
|
-
6. **Only then:** the minimum code that works.
|
|
53
|
-
|
|
54
|
-
Two rungs work → take the higher one and move on; the ladder is a reflex, not a research project.
|
|
55
|
-
No interface with one implementation, no factory for one product, no config for a value that never
|
|
56
|
-
changes, no scaffolding "for later". Deletion over addition; the shortest working diff wins.
|
|
57
|
-
|
|
58
|
-
**Never simplify away** (lazy, not negligent): input validation at trust boundaries, error handling
|
|
59
|
-
that prevents data loss, security measures, accessibility basics, or anything explicitly requested.
|
|
60
|
-
Picking the flimsier algorithm to save a line is not laziness — it's a bug.
|
|
61
|
-
|
|
62
|
-
## Function & module design
|
|
63
|
-
|
|
64
|
-
- One responsibility per function; extract when it grows a second.
|
|
65
|
-
- Command/query separation: a function either does something or returns something, not both.
|
|
66
|
-
- No boolean flag parameters — they hide two functions in one. Split, or pass an enum/options object.
|
|
67
|
-
- Prefer pure functions; isolate and minimize side effects.
|
|
68
|
-
- Default to immutability; do not mutate inputs.
|
|
69
|
-
- Deep modules: a simple interface over meaningful work. A wrapper that only forwards calls adds
|
|
70
|
-
complexity without hiding any.
|
|
71
|
-
|
|
72
|
-
## Type safety (a quality gate, not decoration)
|
|
73
|
-
|
|
74
|
-
- No `any`. Use `unknown` and narrow, or a real type.
|
|
75
|
-
- Explicit return types on exported functions.
|
|
76
|
-
- No unjustified non-null assertions (`!`); narrow instead, or comment the invariant.
|
|
77
|
-
- Exhaustive `switch` over unions (compile-time `never` check).
|
|
78
|
-
- No floating promises — `await`, return, or explicitly `void`.
|
|
79
|
-
|
|
80
|
-
## Performance (measured, never premature)
|
|
81
|
-
|
|
82
|
-
Premature optimization is still banned (YAGNI). But do not ship known-quadratic or chatty code:
|
|
83
|
-
|
|
84
|
-
- No N+1 queries / calls — batch.
|
|
85
|
-
- Hoist invariant work out of loops.
|
|
86
|
-
- No synchronous I/O on a hot path or the UI thread.
|
|
87
|
-
- Stream or paginate large data; do not load it all into memory.
|
|
88
|
-
- Memoize only at a profiled hotspot, with the evidence noted.
|
|
89
|
-
- Avoid O(n²) on inputs that are large in production.
|
|
90
|
-
|
|
91
|
-
## Suppression policy
|
|
92
|
-
|
|
93
|
-
- `eslint-disable`, `@ts-ignore`/`@ts-expect-error`, and `any` require an inline comment naming the
|
|
94
|
-
exact constraint and a follow-up. No silent suppression.
|
|
95
|
-
- Disabling a rule to make CI green **without an equivalent guard** is tech debt — record it; open an
|
|
96
|
-
ADR (`codex/decisions/`) if it is structural.
|
|
97
|
-
- A **deliberate shortcut** (a ladder rung taken with a known ceiling — global lock, O(n²) scan, naive
|
|
98
|
-
heuristic) gets a `ponytail:` comment naming the ceiling and the upgrade path:
|
|
99
|
-
`// ponytail: global lock, per-account locks if throughput matters`. This reads the simplification as
|
|
100
|
-
intent, not ignorance, and the marker is harvestable into a debt ledger (see `stack/README.md`).
|
|
101
|
-
- Never weaken a protection (CSP, a boundary/regression test) without an equal-or-stronger replacement.
|
|
102
|
-
|
|
103
|
-
## Cleanup
|
|
104
|
-
|
|
105
|
-
- No commented-out code — delete it; git remembers.
|
|
106
|
-
- No unused exports, variables, or imports.
|
|
107
|
-
- Remove one-off scripts (migrations, generators, debug harnesses) after use.
|
|
108
|
-
|
|
109
|
-
## Review checklist (the verifier refutes against this)
|
|
110
|
-
|
|
111
|
-
- [ ] Climbed the ladder — no code that stdlib/native/an existing dep already does; no speculative
|
|
112
|
-
abstraction; deliberate shortcuts carry a `ponytail:` ceiling+upgrade comment; no guardrail
|
|
113
|
-
(validation, data-loss, security, a11y) simplified away.
|
|
114
|
-
- [ ] Within limits (length, params, nesting, complexity, file size).
|
|
115
|
-
- [ ] Reads top-to-bottom; guard clauses; no magic values; why-comments only.
|
|
116
|
-
- [ ] One responsibility per unit; no boolean-flag params; side effects isolated.
|
|
117
|
-
- [ ] No `any`; exported return types; exhaustive switches; no floating promises.
|
|
118
|
-
- [ ] No N+1, no sync I/O on hot paths, no needless O(n²); memoization is evidence-backed.
|
|
119
|
-
- [ ] No unjustified suppression; no weakened guard.
|
|
120
|
-
- [ ] No commented-out or dead code; one-off scripts removed.
|
|
121
|
-
- [ ] `verify` green (typecheck + lint + test + build); nothing mislabeled PASS.
|
|
1
|
+
---
|
|
2
|
+
updated: 2026-05-31
|
|
3
|
+
status: canonical
|
|
4
|
+
description: 'The canonical code-quality standard: minimize complexity, with limits, type-safety, and performance rules.'
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Standards — clean code
|
|
8
|
+
|
|
9
|
+
The one goal: **minimize complexity** — the cognitive load to understand and safely change the code
|
|
10
|
+
(Ousterhout, *A Philosophy of Software Design*). Every rule below serves that goal; when two rules
|
|
11
|
+
seem to conflict, pick the option a reader understands faster. Supporting canon: KISS, YAGNI,
|
|
12
|
+
DRY-on-the-third-repetition, information hiding, SOLID.
|
|
13
|
+
|
|
14
|
+
> Language-agnostic core. TypeScript specifics: `standards/typescript.md`. Always-on summary:
|
|
15
|
+
> `rules/05-code-quality.md`. Mechanical enforcement: `templates/lint/`.
|
|
16
|
+
|
|
17
|
+
## When to read
|
|
18
|
+
|
|
19
|
+
Any change under `src/` (or the project's source root), and when reviewing another agent's output.
|
|
20
|
+
|
|
21
|
+
## Limits
|
|
22
|
+
|
|
23
|
+
Guardrails, not goals — a function at 49 lines is not "good" because it fits. Projects may override
|
|
24
|
+
in `local/`. Enforced by `templates/lint/` where the stack supports it.
|
|
25
|
+
|
|
26
|
+
| Constraint | Limit | Past it |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| Function length | ≤ 50 lines | extract a helper |
|
|
29
|
+
| Parameters | ≤ 4 | pass an options object |
|
|
30
|
+
| Nesting depth | ≤ 3 | guard clauses / extract |
|
|
31
|
+
| Cyclomatic complexity | ≤ 10 | split the branch logic |
|
|
32
|
+
| File length | soft 200 / hard 300 | split by responsibility |
|
|
33
|
+
|
|
34
|
+
## Readability
|
|
35
|
+
|
|
36
|
+
- Guard clauses and early returns over nested `if`/`else`.
|
|
37
|
+
- No dense one-liners that trade clarity for brevity.
|
|
38
|
+
- No magic numbers or strings — name them (`const MAX_RETRIES = 3`).
|
|
39
|
+
- Names come from the domain, not the implementation; match the surrounding code.
|
|
40
|
+
- Comments explain **why** (constraints, workarounds, invariants), never **what**. Delete comments
|
|
41
|
+
that restate the code.
|
|
42
|
+
|
|
43
|
+
## The ladder (climb before you write)
|
|
44
|
+
|
|
45
|
+
YAGNI as a reflex, not a slogan. Before writing code, stop at the **first rung that holds**:
|
|
46
|
+
|
|
47
|
+
1. **Does this need to exist?** Speculative need → skip it, say so in one line.
|
|
48
|
+
2. **Stdlib does it?** Use it.
|
|
49
|
+
3. **Native platform feature covers it?** DB constraint over app code, CSS over JS, `<input type="date">` over a picker lib.
|
|
50
|
+
4. **Already-installed dependency solves it?** Use it — never add a new dep for what a few lines do.
|
|
51
|
+
5. **One line?** One line.
|
|
52
|
+
6. **Only then:** the minimum code that works.
|
|
53
|
+
|
|
54
|
+
Two rungs work → take the higher one and move on; the ladder is a reflex, not a research project.
|
|
55
|
+
No interface with one implementation, no factory for one product, no config for a value that never
|
|
56
|
+
changes, no scaffolding "for later". Deletion over addition; the shortest working diff wins.
|
|
57
|
+
|
|
58
|
+
**Never simplify away** (lazy, not negligent): input validation at trust boundaries, error handling
|
|
59
|
+
that prevents data loss, security measures, accessibility basics, or anything explicitly requested.
|
|
60
|
+
Picking the flimsier algorithm to save a line is not laziness — it's a bug.
|
|
61
|
+
|
|
62
|
+
## Function & module design
|
|
63
|
+
|
|
64
|
+
- One responsibility per function; extract when it grows a second.
|
|
65
|
+
- Command/query separation: a function either does something or returns something, not both.
|
|
66
|
+
- No boolean flag parameters — they hide two functions in one. Split, or pass an enum/options object.
|
|
67
|
+
- Prefer pure functions; isolate and minimize side effects.
|
|
68
|
+
- Default to immutability; do not mutate inputs.
|
|
69
|
+
- Deep modules: a simple interface over meaningful work. A wrapper that only forwards calls adds
|
|
70
|
+
complexity without hiding any.
|
|
71
|
+
|
|
72
|
+
## Type safety (a quality gate, not decoration)
|
|
73
|
+
|
|
74
|
+
- No `any`. Use `unknown` and narrow, or a real type.
|
|
75
|
+
- Explicit return types on exported functions.
|
|
76
|
+
- No unjustified non-null assertions (`!`); narrow instead, or comment the invariant.
|
|
77
|
+
- Exhaustive `switch` over unions (compile-time `never` check).
|
|
78
|
+
- No floating promises — `await`, return, or explicitly `void`.
|
|
79
|
+
|
|
80
|
+
## Performance (measured, never premature)
|
|
81
|
+
|
|
82
|
+
Premature optimization is still banned (YAGNI). But do not ship known-quadratic or chatty code:
|
|
83
|
+
|
|
84
|
+
- No N+1 queries / calls — batch.
|
|
85
|
+
- Hoist invariant work out of loops.
|
|
86
|
+
- No synchronous I/O on a hot path or the UI thread.
|
|
87
|
+
- Stream or paginate large data; do not load it all into memory.
|
|
88
|
+
- Memoize only at a profiled hotspot, with the evidence noted.
|
|
89
|
+
- Avoid O(n²) on inputs that are large in production.
|
|
90
|
+
|
|
91
|
+
## Suppression policy
|
|
92
|
+
|
|
93
|
+
- `eslint-disable`, `@ts-ignore`/`@ts-expect-error`, and `any` require an inline comment naming the
|
|
94
|
+
exact constraint and a follow-up. No silent suppression.
|
|
95
|
+
- Disabling a rule to make CI green **without an equivalent guard** is tech debt — record it; open an
|
|
96
|
+
ADR (`codex/decisions/`) if it is structural.
|
|
97
|
+
- A **deliberate shortcut** (a ladder rung taken with a known ceiling — global lock, O(n²) scan, naive
|
|
98
|
+
heuristic) gets a `ponytail:` comment naming the ceiling and the upgrade path:
|
|
99
|
+
`// ponytail: global lock, per-account locks if throughput matters`. This reads the simplification as
|
|
100
|
+
intent, not ignorance, and the marker is harvestable into a debt ledger (see `stack/README.md`).
|
|
101
|
+
- Never weaken a protection (CSP, a boundary/regression test) without an equal-or-stronger replacement.
|
|
102
|
+
|
|
103
|
+
## Cleanup
|
|
104
|
+
|
|
105
|
+
- No commented-out code — delete it; git remembers.
|
|
106
|
+
- No unused exports, variables, or imports.
|
|
107
|
+
- Remove one-off scripts (migrations, generators, debug harnesses) after use.
|
|
108
|
+
|
|
109
|
+
## Review checklist (the verifier refutes against this)
|
|
110
|
+
|
|
111
|
+
- [ ] Climbed the ladder — no code that stdlib/native/an existing dep already does; no speculative
|
|
112
|
+
abstraction; deliberate shortcuts carry a `ponytail:` ceiling+upgrade comment; no guardrail
|
|
113
|
+
(validation, data-loss, security, a11y) simplified away.
|
|
114
|
+
- [ ] Within limits (length, params, nesting, complexity, file size).
|
|
115
|
+
- [ ] Reads top-to-bottom; guard clauses; no magic values; why-comments only.
|
|
116
|
+
- [ ] One responsibility per unit; no boolean-flag params; side effects isolated.
|
|
117
|
+
- [ ] No `any`; exported return types; exhaustive switches; no floating promises.
|
|
118
|
+
- [ ] No N+1, no sync I/O on hot paths, no needless O(n²); memoization is evidence-backed.
|
|
119
|
+
- [ ] No unjustified suppression; no weakened guard.
|
|
120
|
+
- [ ] No commented-out or dead code; one-off scripts removed.
|
|
121
|
+
- [ ] `verify` green (typecheck + lint + test + build); nothing mislabeled PASS.
|
|
@@ -1,69 +1,69 @@
|
|
|
1
|
-
---
|
|
2
|
-
updated: 2026-06-06
|
|
3
|
-
status: canonical
|
|
4
|
-
description: "The codex — the project's knowledge/resource root at the repo root: read-first rule, provenance discipline, secrets boundary, and how it relates to the base contract."
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Standards — codex
|
|
8
|
-
|
|
9
|
-
`codex/` is the project's **knowledge and resource root** — what the system is, what it must do, why
|
|
10
|
-
it's built that way, and the raw materials and evidence behind those claims. It lives at the **repo
|
|
11
|
-
root** (not under `.agents/`), is **project-owned**, and `grimoire sync` never touches it; the base
|
|
12
|
-
contract holds only a *pointer* to it (`codex/INDEX.md`). It is tracked in git — knowledge is durable
|
|
13
|
-
— **except** raw secret-bearing or huge resources, which are gitignored with a tracked manifest.
|
|
14
|
-
|
|
15
|
-
codex subsumes what used to scatter across `docs/`: requirements, decisions, domain knowledge,
|
|
16
|
-
evidence, resources, runbooks. It is the rebuild's **source of truth**.
|
|
17
|
-
|
|
18
|
-
## Read-first rule
|
|
19
|
-
|
|
20
|
-
Any domain reference starts at `codex/INDEX.md`, then the relevant subfolder's `INDEX.md` (the
|
|
21
|
-
signpost). New work reads the matching INDEX **before** acting — a fresh session must not start blind
|
|
22
|
-
to recorded project knowledge. Every codex folder keeps its own `INDEX.md`.
|
|
23
|
-
|
|
24
|
-
## Structure
|
|
25
|
-
|
|
26
|
-
Canonical folders, each with an `INDEX.md` + short `README.md`:
|
|
27
|
-
|
|
28
|
-
| Folder | Holds |
|
|
29
|
-
|---|---|
|
|
30
|
-
| `domain/` | What the system **is** — glossary, context, business rules, capabilities. |
|
|
31
|
-
| `requirements/` | What it must **do** — IDed, versioned (`standards/requirements.md`). |
|
|
32
|
-
| `decisions/` | **Why** — ADRs, one per decision. |
|
|
33
|
-
| `evidence/` | Investigation / reverse-engineering / extraction outputs, each fact sourced. |
|
|
34
|
-
| `resources/` | Raw materials — datasets, vendor specs, dumps, snapshots (+ a manifest). |
|
|
35
|
-
| `reference/` | Confirmed-value tables, API/IPC catalogs, big contracts the code reads back. |
|
|
36
|
-
| `runbooks/` | The on-call answer to "production is broken." |
|
|
37
|
-
|
|
38
|
-
The structure is **extensible**: add a folder when a new kind of knowledge appears; give it an
|
|
39
|
-
`INDEX.md` and list it in `codex/INDEX.md`. Keep entry/INDEX files lean
|
|
40
|
-
(`rules/35-context-economy.md`).
|
|
41
|
-
|
|
42
|
-
## Provenance discipline
|
|
43
|
-
|
|
44
|
-
The knowledge base is the rebuild's source of truth, so it carries no unsourced guesses.
|
|
45
|
-
|
|
46
|
-
- Every recorded fact cites its **source** (file + offset/record) and a **CONFIRMED | INFERRED** tag.
|
|
47
|
-
- Unsupported claims are **removed or demoted** to "not recovered" — silence is not a finding.
|
|
48
|
-
- `INFERRED` is a lead, not a contract: confirm it from a source before code relies on it.
|
|
49
|
-
- **Pre-existing docs are not trusted until audited** to this standard. An audited doc carries
|
|
50
|
-
`audited: <date>`; an un-audited one is treated as unverified.
|
|
51
|
-
|
|
52
|
-
## Secrets / leak boundary
|
|
53
|
-
|
|
54
|
-
- Real secrets / PHI **never** go in tracked knowledge docs. They live in a **gitignored inventory**
|
|
55
|
-
recording each secret's **source + purpose** (for rotate/revoke), not the value in any tracked file.
|
|
56
|
-
- **The chat is the leak boundary**: never echo a secret or PHI into chat or agent output. Record a
|
|
57
|
-
location + purpose, not the value.
|
|
58
|
-
- **Re-audit tracked content before connecting or pushing** a repo — confirm no secret/PHI slipped
|
|
59
|
-
into a tracked doc. See `rules/50-security.md` + `standards/launch-security-checklist.md`.
|
|
60
|
-
|
|
61
|
-
## Relationship to the base
|
|
62
|
-
|
|
63
|
-
- **Requirements (what)** → `codex/requirements/`; **decisions (why)** → `codex/decisions/`. Both are
|
|
64
|
-
cited by the task contract (`rules/10-working-process.md`) and checked by the verifier
|
|
65
|
-
(`rules/30-verification.md`).
|
|
66
|
-
- **Ground-truth values** → `codex/reference/`; an ADR that changes one sets
|
|
67
|
-
`updates-confirmed-values: yes` and updates the table in the **same PR**.
|
|
68
|
-
- The base governs *how to work*; codex holds *what this project knows*. Base loads first, `local/`
|
|
69
|
-
wins — codex is project-owned knowledge, not a base override.
|
|
1
|
+
---
|
|
2
|
+
updated: 2026-06-06
|
|
3
|
+
status: canonical
|
|
4
|
+
description: "The codex — the project's knowledge/resource root at the repo root: read-first rule, provenance discipline, secrets boundary, and how it relates to the base contract."
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Standards — codex
|
|
8
|
+
|
|
9
|
+
`codex/` is the project's **knowledge and resource root** — what the system is, what it must do, why
|
|
10
|
+
it's built that way, and the raw materials and evidence behind those claims. It lives at the **repo
|
|
11
|
+
root** (not under `.agents/`), is **project-owned**, and `grimoire sync` never touches it; the base
|
|
12
|
+
contract holds only a *pointer* to it (`codex/INDEX.md`). It is tracked in git — knowledge is durable
|
|
13
|
+
— **except** raw secret-bearing or huge resources, which are gitignored with a tracked manifest.
|
|
14
|
+
|
|
15
|
+
codex subsumes what used to scatter across `docs/`: requirements, decisions, domain knowledge,
|
|
16
|
+
evidence, resources, runbooks. It is the rebuild's **source of truth**.
|
|
17
|
+
|
|
18
|
+
## Read-first rule
|
|
19
|
+
|
|
20
|
+
Any domain reference starts at `codex/INDEX.md`, then the relevant subfolder's `INDEX.md` (the
|
|
21
|
+
signpost). New work reads the matching INDEX **before** acting — a fresh session must not start blind
|
|
22
|
+
to recorded project knowledge. Every codex folder keeps its own `INDEX.md`.
|
|
23
|
+
|
|
24
|
+
## Structure
|
|
25
|
+
|
|
26
|
+
Canonical folders, each with an `INDEX.md` + short `README.md`:
|
|
27
|
+
|
|
28
|
+
| Folder | Holds |
|
|
29
|
+
|---|---|
|
|
30
|
+
| `domain/` | What the system **is** — glossary, context, business rules, capabilities. |
|
|
31
|
+
| `requirements/` | What it must **do** — IDed, versioned (`standards/requirements.md`). |
|
|
32
|
+
| `decisions/` | **Why** — ADRs, one per decision. |
|
|
33
|
+
| `evidence/` | Investigation / reverse-engineering / extraction outputs, each fact sourced. |
|
|
34
|
+
| `resources/` | Raw materials — datasets, vendor specs, dumps, snapshots (+ a manifest). |
|
|
35
|
+
| `reference/` | Confirmed-value tables, API/IPC catalogs, big contracts the code reads back. |
|
|
36
|
+
| `runbooks/` | The on-call answer to "production is broken." |
|
|
37
|
+
|
|
38
|
+
The structure is **extensible**: add a folder when a new kind of knowledge appears; give it an
|
|
39
|
+
`INDEX.md` and list it in `codex/INDEX.md`. Keep entry/INDEX files lean
|
|
40
|
+
(`rules/35-context-economy.md`).
|
|
41
|
+
|
|
42
|
+
## Provenance discipline
|
|
43
|
+
|
|
44
|
+
The knowledge base is the rebuild's source of truth, so it carries no unsourced guesses.
|
|
45
|
+
|
|
46
|
+
- Every recorded fact cites its **source** (file + offset/record) and a **CONFIRMED | INFERRED** tag.
|
|
47
|
+
- Unsupported claims are **removed or demoted** to "not recovered" — silence is not a finding.
|
|
48
|
+
- `INFERRED` is a lead, not a contract: confirm it from a source before code relies on it.
|
|
49
|
+
- **Pre-existing docs are not trusted until audited** to this standard. An audited doc carries
|
|
50
|
+
`audited: <date>`; an un-audited one is treated as unverified.
|
|
51
|
+
|
|
52
|
+
## Secrets / leak boundary
|
|
53
|
+
|
|
54
|
+
- Real secrets / PHI **never** go in tracked knowledge docs. They live in a **gitignored inventory**
|
|
55
|
+
recording each secret's **source + purpose** (for rotate/revoke), not the value in any tracked file.
|
|
56
|
+
- **The chat is the leak boundary**: never echo a secret or PHI into chat or agent output. Record a
|
|
57
|
+
location + purpose, not the value.
|
|
58
|
+
- **Re-audit tracked content before connecting or pushing** a repo — confirm no secret/PHI slipped
|
|
59
|
+
into a tracked doc. See `rules/50-security.md` + `standards/launch-security-checklist.md`.
|
|
60
|
+
|
|
61
|
+
## Relationship to the base
|
|
62
|
+
|
|
63
|
+
- **Requirements (what)** → `codex/requirements/`; **decisions (why)** → `codex/decisions/`. Both are
|
|
64
|
+
cited by the task contract (`rules/10-working-process.md`) and checked by the verifier
|
|
65
|
+
(`rules/30-verification.md`).
|
|
66
|
+
- **Ground-truth values** → `codex/reference/`; an ADR that changes one sets
|
|
67
|
+
`updates-confirmed-values: yes` and updates the table in the **same PR**.
|
|
68
|
+
- The base governs *how to work*; codex holds *what this project knows*. Base loads first, `local/`
|
|
69
|
+
wins — codex is project-owned knowledge, not a base override.
|
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
---
|
|
2
|
-
updated: 2026-05-31
|
|
3
|
-
status: canonical
|
|
4
|
-
description: Every error carries a stable code so logs, tests, and UIs switch on it, not on message strings.
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Standards — error-code catalog
|
|
8
|
-
|
|
9
|
-
Every thrown/returned error carries a stable **code** so logs, tests, and UIs can switch on it
|
|
10
|
-
without string-matching messages.
|
|
11
|
-
|
|
12
|
-
## Convention
|
|
13
|
-
|
|
14
|
-
- Code shape: `DOMAIN_REASON` in CONSTANT_CASE — e.g. `AUTH_TOKEN_EXPIRED`, `SYNC_CONFLICT`,
|
|
15
|
-
`VALIDATION_REQUIRED_FIELD`.
|
|
16
|
-
- One catalog file per project (e.g. `src/errors/catalog.ts`) — the single source of truth.
|
|
17
|
-
- Error objects expose `{ code, message, cause? }`. `message` is human-facing; `code` is the contract.
|
|
18
|
-
- A lint/check script validates that every code used exists in the catalog and that the catalog has
|
|
19
|
-
no duplicates. Wire it into the `verify` script as a gate (`lint:error-codes`): register the code **before** implementing; the build fails on an unregistered or duplicate code.
|
|
20
|
-
|
|
21
|
-
## What the template ships
|
|
22
|
-
|
|
23
|
-
- This convention.
|
|
24
|
-
- A scaffold check script stub (`stack/` profiles reference it). **The project fills the catalog** —
|
|
25
|
-
the template does not ship project-specific codes.
|
|
26
|
-
|
|
27
|
-
## Example (TypeScript)
|
|
28
|
-
|
|
29
|
-
```ts
|
|
30
|
-
export const ERROR_CODES = {
|
|
31
|
-
AUTH_TOKEN_EXPIRED: "AUTH_TOKEN_EXPIRED",
|
|
32
|
-
VALIDATION_REQUIRED_FIELD: "VALIDATION_REQUIRED_FIELD",
|
|
33
|
-
} as const;
|
|
34
|
-
export type ErrorCode = keyof typeof ERROR_CODES;
|
|
35
|
-
|
|
36
|
-
export class AppError extends Error {
|
|
37
|
-
constructor(public code: ErrorCode, message: string, public cause?: unknown) {
|
|
38
|
-
super(message);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
```
|
|
1
|
+
---
|
|
2
|
+
updated: 2026-05-31
|
|
3
|
+
status: canonical
|
|
4
|
+
description: Every error carries a stable code so logs, tests, and UIs switch on it, not on message strings.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Standards — error-code catalog
|
|
8
|
+
|
|
9
|
+
Every thrown/returned error carries a stable **code** so logs, tests, and UIs can switch on it
|
|
10
|
+
without string-matching messages.
|
|
11
|
+
|
|
12
|
+
## Convention
|
|
13
|
+
|
|
14
|
+
- Code shape: `DOMAIN_REASON` in CONSTANT_CASE — e.g. `AUTH_TOKEN_EXPIRED`, `SYNC_CONFLICT`,
|
|
15
|
+
`VALIDATION_REQUIRED_FIELD`.
|
|
16
|
+
- One catalog file per project (e.g. `src/errors/catalog.ts`) — the single source of truth.
|
|
17
|
+
- Error objects expose `{ code, message, cause? }`. `message` is human-facing; `code` is the contract.
|
|
18
|
+
- A lint/check script validates that every code used exists in the catalog and that the catalog has
|
|
19
|
+
no duplicates. Wire it into the `verify` script as a gate (`lint:error-codes`): register the code **before** implementing; the build fails on an unregistered or duplicate code.
|
|
20
|
+
|
|
21
|
+
## What the template ships
|
|
22
|
+
|
|
23
|
+
- This convention.
|
|
24
|
+
- A scaffold check script stub (`stack/` profiles reference it). **The project fills the catalog** —
|
|
25
|
+
the template does not ship project-specific codes.
|
|
26
|
+
|
|
27
|
+
## Example (TypeScript)
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
export const ERROR_CODES = {
|
|
31
|
+
AUTH_TOKEN_EXPIRED: "AUTH_TOKEN_EXPIRED",
|
|
32
|
+
VALIDATION_REQUIRED_FIELD: "VALIDATION_REQUIRED_FIELD",
|
|
33
|
+
} as const;
|
|
34
|
+
export type ErrorCode = keyof typeof ERROR_CODES;
|
|
35
|
+
|
|
36
|
+
export class AppError extends Error {
|
|
37
|
+
constructor(public code: ErrorCode, message: string, public cause?: unknown) {
|
|
38
|
+
super(message);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
```
|
|
@@ -1,46 +1,46 @@
|
|
|
1
|
-
---
|
|
2
|
-
updated: 2026-05-31
|
|
3
|
-
status: canonical
|
|
4
|
-
description: 'Baseline conventions: naming, file size, import order, error handling, formatting.'
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Standards — general
|
|
8
|
-
|
|
9
|
-
## Naming
|
|
10
|
-
|
|
11
|
-
| Thing | Case | Example |
|
|
12
|
-
|---|---|---|
|
|
13
|
-
| files / dirs | kebab-case | `user-profile.ts` |
|
|
14
|
-
| variables / functions | camelCase | `getUserProfile` |
|
|
15
|
-
| types / classes / components | PascalCase | `UserProfile` |
|
|
16
|
-
| constants | CONSTANT_CASE | `MAX_RETRIES` |
|
|
17
|
-
| booleans | `is/has/can/should` prefix | `isActive`, `canEdit` |
|
|
18
|
-
|
|
19
|
-
Names come from the **domain**, not the implementation. Match the surrounding code.
|
|
20
|
-
|
|
21
|
-
## File size
|
|
22
|
-
|
|
23
|
-
- Soft ~200 / hard 300 lines (full limits table: `standards/clean-code.md`). Past that, split by
|
|
24
|
-
responsibility.
|
|
25
|
-
- One primary export per file where practical.
|
|
26
|
-
|
|
27
|
-
## Imports (ordering)
|
|
28
|
-
|
|
29
|
-
1. std lib / runtime
|
|
30
|
-
2. third-party
|
|
31
|
-
3. internal absolute (`@/...`)
|
|
32
|
-
4. relative (`./`, `../`)
|
|
33
|
-
|
|
34
|
-
Blank line between groups. No unused imports.
|
|
35
|
-
|
|
36
|
-
## Error handling
|
|
37
|
-
|
|
38
|
-
- Throw typed errors carrying a **code** (see `error-codes.md`). Never throw bare strings.
|
|
39
|
-
- Catch only what you can handle; otherwise let it propagate.
|
|
40
|
-
- No silent catches. If you swallow an error, log *why* with context.
|
|
41
|
-
- Fail closed on the security path (`rules/50-security.md`).
|
|
42
|
-
|
|
43
|
-
## Formatting
|
|
44
|
-
|
|
45
|
-
- Formatter + linter own style (Prettier/ESLint, ruff, gofmt, …). Do not hand-format.
|
|
46
|
-
- `format:check` is part of the `verify` script and must pass.
|
|
1
|
+
---
|
|
2
|
+
updated: 2026-05-31
|
|
3
|
+
status: canonical
|
|
4
|
+
description: 'Baseline conventions: naming, file size, import order, error handling, formatting.'
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Standards — general
|
|
8
|
+
|
|
9
|
+
## Naming
|
|
10
|
+
|
|
11
|
+
| Thing | Case | Example |
|
|
12
|
+
|---|---|---|
|
|
13
|
+
| files / dirs | kebab-case | `user-profile.ts` |
|
|
14
|
+
| variables / functions | camelCase | `getUserProfile` |
|
|
15
|
+
| types / classes / components | PascalCase | `UserProfile` |
|
|
16
|
+
| constants | CONSTANT_CASE | `MAX_RETRIES` |
|
|
17
|
+
| booleans | `is/has/can/should` prefix | `isActive`, `canEdit` |
|
|
18
|
+
|
|
19
|
+
Names come from the **domain**, not the implementation. Match the surrounding code.
|
|
20
|
+
|
|
21
|
+
## File size
|
|
22
|
+
|
|
23
|
+
- Soft ~200 / hard 300 lines (full limits table: `standards/clean-code.md`). Past that, split by
|
|
24
|
+
responsibility.
|
|
25
|
+
- One primary export per file where practical.
|
|
26
|
+
|
|
27
|
+
## Imports (ordering)
|
|
28
|
+
|
|
29
|
+
1. std lib / runtime
|
|
30
|
+
2. third-party
|
|
31
|
+
3. internal absolute (`@/...`)
|
|
32
|
+
4. relative (`./`, `../`)
|
|
33
|
+
|
|
34
|
+
Blank line between groups. No unused imports.
|
|
35
|
+
|
|
36
|
+
## Error handling
|
|
37
|
+
|
|
38
|
+
- Throw typed errors carrying a **code** (see `error-codes.md`). Never throw bare strings.
|
|
39
|
+
- Catch only what you can handle; otherwise let it propagate.
|
|
40
|
+
- No silent catches. If you swallow an error, log *why* with context.
|
|
41
|
+
- Fail closed on the security path (`rules/50-security.md`).
|
|
42
|
+
|
|
43
|
+
## Formatting
|
|
44
|
+
|
|
45
|
+
- Formatter + linter own style (Prettier/ESLint, ruff, gofmt, …). Do not hand-format.
|
|
46
|
+
- `format:check` is part of the `verify` script and must pass.
|
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
---
|
|
2
|
-
updated: 2026-05-31
|
|
3
|
-
status: canonical
|
|
4
|
-
description: Structural-invariant tests that fail CI when two sources of truth drift apart.
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Standards — guardrail tests (structural invariants)
|
|
8
|
-
|
|
9
|
-
A **guardrail test** asserts a structural invariant of the codebase, not a behaviour. It diffs two
|
|
10
|
-
sources that must agree and fails CI when they drift. Unit tests catch *wrong logic*; guardrail tests
|
|
11
|
-
catch *wrong wiring* — a channel registered but not allow-listed, an error code thrown but absent
|
|
12
|
-
from the catalog, a permission used but undeclared.
|
|
13
|
-
|
|
14
|
-
## When to add one
|
|
15
|
-
|
|
16
|
-
Add a guardrail whenever two places encode the same truth and silent drift between them is a defect:
|
|
17
|
-
|
|
18
|
-
| Invariant | Sources that must agree |
|
|
19
|
-
|---|---|
|
|
20
|
-
| IPC channels | the channel registry ↔ the main-process allow-list (`rules/50` fail-closed) |
|
|
21
|
-
| Error codes | codes thrown in source ↔ `standards/error-codes.md` catalog |
|
|
22
|
-
| Permissions | `can(permission)` keys used ↔ the declared permission set |
|
|
23
|
-
| Confirmed values | values read in code ↔ the project's confirmed-values table (ADR-tracked) |
|
|
24
|
-
| Routes / events | registered handlers ↔ the typed route/event map |
|
|
25
|
-
|
|
26
|
-
## Shape
|
|
27
|
-
|
|
28
|
-
A guardrail is an ordinary test in the project's runner (it rides the existing `verify` gate). It
|
|
29
|
-
must **fail closed**: if it cannot read one side, that is a failure, not a skip. Report the diff both
|
|
30
|
-
ways — present-but-unexpected *and* expected-but-missing — so neither orphan nor gap hides.
|
|
31
|
-
|
|
32
|
-
```
|
|
33
|
-
actual = scan source for the live set // e.g. ipcMain.handle("…") call sites
|
|
34
|
-
declared = read the registry / catalog / table // the source of truth
|
|
35
|
-
expect(actual − declared).toBeEmpty() // used but undeclared → fail closed
|
|
36
|
-
expect(declared − actual).toBeEmpty() // declared but unused → stale entry
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
Starter: `templates/tests/guardrail.invariants.test.ts` (adapt the scanners to the project). Wire it
|
|
40
|
-
into CI as part of `verify` so drift fails the PR, not production.
|
|
1
|
+
---
|
|
2
|
+
updated: 2026-05-31
|
|
3
|
+
status: canonical
|
|
4
|
+
description: Structural-invariant tests that fail CI when two sources of truth drift apart.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Standards — guardrail tests (structural invariants)
|
|
8
|
+
|
|
9
|
+
A **guardrail test** asserts a structural invariant of the codebase, not a behaviour. It diffs two
|
|
10
|
+
sources that must agree and fails CI when they drift. Unit tests catch *wrong logic*; guardrail tests
|
|
11
|
+
catch *wrong wiring* — a channel registered but not allow-listed, an error code thrown but absent
|
|
12
|
+
from the catalog, a permission used but undeclared.
|
|
13
|
+
|
|
14
|
+
## When to add one
|
|
15
|
+
|
|
16
|
+
Add a guardrail whenever two places encode the same truth and silent drift between them is a defect:
|
|
17
|
+
|
|
18
|
+
| Invariant | Sources that must agree |
|
|
19
|
+
|---|---|
|
|
20
|
+
| IPC channels | the channel registry ↔ the main-process allow-list (`rules/50` fail-closed) |
|
|
21
|
+
| Error codes | codes thrown in source ↔ `standards/error-codes.md` catalog |
|
|
22
|
+
| Permissions | `can(permission)` keys used ↔ the declared permission set |
|
|
23
|
+
| Confirmed values | values read in code ↔ the project's confirmed-values table (ADR-tracked) |
|
|
24
|
+
| Routes / events | registered handlers ↔ the typed route/event map |
|
|
25
|
+
|
|
26
|
+
## Shape
|
|
27
|
+
|
|
28
|
+
A guardrail is an ordinary test in the project's runner (it rides the existing `verify` gate). It
|
|
29
|
+
must **fail closed**: if it cannot read one side, that is a failure, not a skip. Report the diff both
|
|
30
|
+
ways — present-but-unexpected *and* expected-but-missing — so neither orphan nor gap hides.
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
actual = scan source for the live set // e.g. ipcMain.handle("…") call sites
|
|
34
|
+
declared = read the registry / catalog / table // the source of truth
|
|
35
|
+
expect(actual − declared).toBeEmpty() // used but undeclared → fail closed
|
|
36
|
+
expect(declared − actual).toBeEmpty() // declared but unused → stale entry
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Starter: `templates/tests/guardrail.invariants.test.ts` (adapt the scanners to the project). Wire it
|
|
40
|
+
into CI as part of `verify` so drift fails the PR, not production.
|