the-grimoire-cli 0.3.2
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 -0
- package/.agents/NAVIGATOR.md +168 -0
- package/.agents/VERSION +4 -0
- package/.agents/agents/INDEX.md +7 -0
- package/.agents/agents/verifier.md +50 -0
- package/.agents/commands/INDEX.md +11 -0
- package/.agents/commands/checkpoint.md +15 -0
- package/.agents/commands/grimoire.md +14 -0
- package/.agents/commands/onboard.md +56 -0
- package/.agents/commands/present.md +23 -0
- package/.agents/commands/verify.md +20 -0
- package/.agents/grimoire.manifest +18 -0
- package/.agents/rules/00-always.md +42 -0
- package/.agents/rules/05-code-quality.md +28 -0
- package/.agents/rules/10-working-process.md +31 -0
- package/.agents/rules/15-skills.md +27 -0
- package/.agents/rules/20-modes.md +41 -0
- package/.agents/rules/25-surgical-changes.md +29 -0
- package/.agents/rules/30-verification.md +36 -0
- package/.agents/rules/35-context-economy.md +41 -0
- package/.agents/rules/40-handoff.md +25 -0
- package/.agents/rules/45-presentation.md +35 -0
- package/.agents/rules/50-security.md +30 -0
- package/.agents/rules/60-commit-style.md +14 -0
- package/.agents/rules/INDEX.md +18 -0
- package/.agents/skills/INDEX.md +8 -0
- package/.agents/skills/README.md +6 -0
- package/.agents/skills/catalog.md +106 -0
- package/.agents/skills/find-skills/SKILL.md +142 -0
- package/.agents/stack/INDEX.md +9 -0
- package/.agents/stack/README.md +66 -0
- package/.agents/stack/desktop.md +36 -0
- package/.agents/stack/library.md +16 -0
- package/.agents/stack/web-app.md +32 -0
- package/.agents/standards/INDEX.md +23 -0
- package/.agents/standards/accessibility.md +50 -0
- package/.agents/standards/architecture.md +39 -0
- package/.agents/standards/attribution.md +39 -0
- package/.agents/standards/clean-code.md +121 -0
- package/.agents/standards/codex.md +69 -0
- package/.agents/standards/error-codes.md +41 -0
- package/.agents/standards/general.md +46 -0
- package/.agents/standards/guardrail-tests.md +40 -0
- package/.agents/standards/knowledge-management.md +35 -0
- package/.agents/standards/launch-security-checklist.md +45 -0
- package/.agents/standards/observability.md +35 -0
- package/.agents/standards/release-versioning.md +53 -0
- package/.agents/standards/requirements.md +75 -0
- package/.agents/standards/security-scanners.md +42 -0
- package/.agents/standards/testing-strategy.md +61 -0
- package/.agents/standards/typescript.md +19 -0
- package/.agents/standards/writing.md +58 -0
- package/.agents/tooling.json +19 -0
- package/LICENSE +21 -0
- package/README.md +139 -0
- package/bin/grimoire.mjs +598 -0
- package/package.json +32 -0
- package/templates/CLAUDE.md +7 -0
- package/templates/ci/ci.yml +49 -0
- package/templates/ci/sast.yml +44 -0
- package/templates/codex/INDEX.md +18 -0
- package/templates/codex/README.md +28 -0
- package/templates/codex/decisions/0000-template.md +36 -0
- package/templates/codex/decisions/INDEX.md +11 -0
- package/templates/codex/decisions/README.md +25 -0
- package/templates/codex/domain/INDEX.md +14 -0
- package/templates/codex/domain/README.md +10 -0
- package/templates/codex/evidence/0000-extraction-template.md +36 -0
- package/templates/codex/evidence/INDEX.md +11 -0
- package/templates/codex/evidence/README.md +15 -0
- package/templates/codex/reference/INDEX.md +11 -0
- package/templates/codex/reference/README.md +15 -0
- package/templates/codex/reference/confirmed-values.md +18 -0
- package/templates/codex/requirements/INDEX.md +11 -0
- package/templates/codex/requirements/README.md +22 -0
- package/templates/codex/requirements/addons/0000-template.md +35 -0
- package/templates/codex/requirements/base.md +36 -0
- package/templates/codex/requirements/changes/0000-template.md +39 -0
- package/templates/codex/resources/INDEX.md +11 -0
- package/templates/codex/resources/README.md +17 -0
- package/templates/codex/resources/manifest.md +11 -0
- package/templates/codex/runbooks/INDEX.md +9 -0
- package/templates/codex/runbooks/README.md +8 -0
- package/templates/codex/runbooks/incident-runbook-template.md +58 -0
- package/templates/gitignore-snippet.txt +12 -0
- package/templates/journal/backlog/README.md +18 -0
- package/templates/journal/backlog/done/.gitkeep +0 -0
- package/templates/journal/memory/MEMORY.md +15 -0
- package/templates/journal/session/.gitkeep +0 -0
- package/templates/journal/session/archive/.gitkeep +1 -0
- package/templates/journal/session/artifacts/.gitkeep +1 -0
- package/templates/journal/session/current.md +12 -0
- package/templates/lint/README.md +25 -0
- package/templates/lint/eslint.config.mjs +33 -0
- package/templates/lint/tsconfig.base.json +11 -0
- package/templates/local/AGENTS.local.md +33 -0
- package/templates/local/README.md +55 -0
- package/templates/local/commands/.gitkeep +0 -0
- package/templates/local/rules/.gitkeep +0 -0
- package/templates/local/skills/.gitkeep +0 -0
- package/templates/local/stack/.gitkeep +0 -0
- package/templates/local/standards/.gitkeep +0 -0
- package/templates/tests/guardrail.invariants.test.ts +59 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Profile: desktop
|
|
2
|
+
|
|
3
|
+
Default for Electron / desktop apps (harvested from ever-sync-adapter).
|
|
4
|
+
|
|
5
|
+
| Concern | Default |
|
|
6
|
+
|---|---|
|
|
7
|
+
| Shell | Electron |
|
|
8
|
+
| Language | TypeScript (`strict`) |
|
|
9
|
+
| Lint / format | ESLint + Prettier |
|
|
10
|
+
| Test | Vitest (unit) + Playwright/Spectron-style (integration) |
|
|
11
|
+
| IPC | typed channels; document the channel table in `journal/memory/` |
|
|
12
|
+
| Release | new code paths behind env flags (single-unset rollback) |
|
|
13
|
+
| CI | typecheck + lint + test + package on tag |
|
|
14
|
+
| Testing policy | `tdd-mandatory` (override per project) |
|
|
15
|
+
|
|
16
|
+
`verify`: `tsc --noEmit && eslint . && vitest run --coverage && prettier --check .`
|
|
17
|
+
|
|
18
|
+
Note: for on-site/production tools, pair with HOTFIX mode (`rules/20-modes.md`).
|
|
19
|
+
|
|
20
|
+
## Reference defaults (adapt per project; vendor names are examples)
|
|
21
|
+
|
|
22
|
+
- **Process boundaries:** separate tsconfig per process (main / renderer / preload / shared) with
|
|
23
|
+
path aliases; explicit IPC channel registry (one `channels.ts`), preload bridge, and typed API.
|
|
24
|
+
- **IPC discipline:** adding a channel touches several files (registry, preload, types, handler, the
|
|
25
|
+
AGENTS.md/`local/` channel table) — keep that checklist explicit and, ideally, a guardrail test
|
|
26
|
+
that diffs the registry against the allow-list in CI.
|
|
27
|
+
- **Secrets at rest:** OS keystore (`safeStorage` / keychain), never plaintext in the local DB
|
|
28
|
+
(`rules/50`).
|
|
29
|
+
- **Native modules:** rebuild for Electron (`electron-rebuild`) before dev/dist; pin native driver
|
|
30
|
+
versions per backend (e.g. Oracle Instant Client per server version).
|
|
31
|
+
- **Local DB:** embedded SQLite via a typed query builder; a single factory is the only legal
|
|
32
|
+
instantiation point; temp-DB fixtures (`mkdtemp` + cleanup) for tests.
|
|
33
|
+
- **Tests:** Vitest (unit + integration) + Playwright (E2E); CSP + boundary regression as gates in
|
|
34
|
+
the `verify` chain. Desktop profile defaults to `tdd-mandatory`.
|
|
35
|
+
- **Lint preset:** start from `templates/lint/` (clean-code limits + type-safety); enforce via
|
|
36
|
+
`eslint .` in `verify`.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Profile: library
|
|
2
|
+
|
|
3
|
+
Default for published or internal reusable packages.
|
|
4
|
+
|
|
5
|
+
| Concern | Default |
|
|
6
|
+
|---|---|
|
|
7
|
+
| Build | tsup / unbuild → ESM (+ CJS if consumers need it) |
|
|
8
|
+
| Language | TypeScript (`strict`), emit `.d.ts` |
|
|
9
|
+
| Lint / format | ESLint + Prettier |
|
|
10
|
+
| Test | Vitest; high coverage bar (public API) |
|
|
11
|
+
| Public API | explicit `exports` map; no deep imports |
|
|
12
|
+
| Versioning | semver; changesets for release notes |
|
|
13
|
+
| CI | typecheck + lint + test + build + pack-check on PR |
|
|
14
|
+
| Testing policy | `tdd-mandatory` (public contract — override per project) |
|
|
15
|
+
|
|
16
|
+
`verify`: `tsc --noEmit && eslint . && vitest run --coverage && prettier --check . && npm pack --dry-run`
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Profile: web-app
|
|
2
|
+
|
|
3
|
+
Default for full-stack / front-end web projects.
|
|
4
|
+
|
|
5
|
+
| Concern | Default |
|
|
6
|
+
|---|---|
|
|
7
|
+
| Framework | Next.js (App Router) or Vite + React |
|
|
8
|
+
| Language | TypeScript (`strict`) — see `standards/typescript.md` |
|
|
9
|
+
| Lint / format | ESLint + Prettier |
|
|
10
|
+
| Test | Vitest + React Testing Library; Playwright for e2e |
|
|
11
|
+
| Coverage | reported in `verify`; threshold set per project |
|
|
12
|
+
| Validation | zod at every boundary |
|
|
13
|
+
| CI | typecheck + lint + test + build on PR |
|
|
14
|
+
| Testing policy | `test-ready-deferred` (override per project) |
|
|
15
|
+
|
|
16
|
+
`verify`: `tsc --noEmit && eslint . && vitest run --coverage && prettier --check .`
|
|
17
|
+
|
|
18
|
+
## Reference defaults (adapt per project; vendor names are examples)
|
|
19
|
+
|
|
20
|
+
- **Auth guards — one model, three call-site shapes:** a single `can(permission)` policy with
|
|
21
|
+
`requirePermission()` (throws, for actions), `requirePermissionResponse()` (returns 401, for route
|
|
22
|
+
handlers), `requirePermissionOrRedirect()` (for pages). Zero inline `role === "x"` checks.
|
|
23
|
+
- **Edge-safe auth split:** keep an edge/middleware config with **no DB** separate from the full
|
|
24
|
+
server auth that hits the DB at sign-in (Auth.js v5 pattern).
|
|
25
|
+
- **Validation:** zod at every server-action boundary; client validation is UX only (`rules/50`).
|
|
26
|
+
- **Module layering:** pure engine + read/write/projection split + schema-ownership by module
|
|
27
|
+
(`standards/architecture.md`).
|
|
28
|
+
- **Security headers in one place** (e.g. `next.config` headers): CSP, HSTS, X-Frame-Options DENY,
|
|
29
|
+
X-Content-Type-Options, Referrer-Policy, Permissions-Policy; disable `poweredByHeader`.
|
|
30
|
+
- **DB:** typed query builder / ORM with tracked migrations (generate → migrate); `db:push` dev-only.
|
|
31
|
+
- **Lint preset:** start from `templates/lint/` (clean-code limits + type-safety); `eslint .` in the
|
|
32
|
+
`verify` script enforces it.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# standards — index
|
|
2
|
+
|
|
3
|
+
<!-- GENERATED by `grimoire index`; do not edit by hand. Re-run after adding/renaming files here. -->
|
|
4
|
+
|
|
5
|
+
| File | What it covers |
|
|
6
|
+
|---|---|
|
|
7
|
+
| `accessibility.md` | Baseline accessibility (WCAG 2.x AA) for any user-facing surface — the non-negotiable floor plus how to verify it. |
|
|
8
|
+
| `architecture.md` | Module layering and boundaries distilled from real modular codebases. |
|
|
9
|
+
| `attribution.md` | Credit the external work the project builds on: what to record when adopting a tool/pattern/idea, where it goes, and the adapt-not-copy rul… |
|
|
10
|
+
| `clean-code.md` | The canonical code-quality standard: minimize complexity, with limits, type-safety, and performance rules. |
|
|
11
|
+
| `codex.md` | The codex — the project's knowledge/resource root at the repo root: read-first rule, provenance discipline, secrets boundary, and how it re… |
|
|
12
|
+
| `error-codes.md` | Every error carries a stable code so logs, tests, and UIs switch on it, not on message strings. |
|
|
13
|
+
| `general.md` | Baseline conventions: naming, file size, import order, error handling, formatting. |
|
|
14
|
+
| `guardrail-tests.md` | Structural-invariant tests that fail CI when two sources of truth drift apart. |
|
|
15
|
+
| `knowledge-management.md` | The second-brain model: three homes for work-state, and how to view memory as an optional Obsidian vault. |
|
|
16
|
+
| `launch-security-checklist.md` | Pre-launch privacy + security gate for any app that collects user data. |
|
|
17
|
+
| `observability.md` | Production logging, metrics, and tracing lessons from real data/sync tools. |
|
|
18
|
+
| `release-versioning.md` | Versioning, changelog, and release discipline across app and library profiles — what ships, how it's tagged, how it's recorded. |
|
|
19
|
+
| `requirements.md` | How requirements are captured, identified, versioned, and traced — base requirements plus addons and change requests. |
|
|
20
|
+
| `security-scanners.md` | SAST scanners by language and how to wire them into CI to catch exploitable bugs. |
|
|
21
|
+
| `testing-strategy.md` | The project-wide testing approach: the pyramid, what to test at each level, the active policy, and what 'tested' means. |
|
|
22
|
+
| `typescript.md` | TypeScript specifics: strict mode, no any, type-safety expectations. |
|
|
23
|
+
| `writing.md` | How to write agent-facing docs so they are high-signal and versioned. |
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
updated: 2026-05-31
|
|
3
|
+
status: canonical
|
|
4
|
+
description: "Baseline accessibility (WCAG 2.x AA) for any user-facing surface — the non-negotiable floor plus how to verify it."
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Standards — accessibility
|
|
8
|
+
|
|
9
|
+
Applies to every user-facing surface (web, desktop UI). Target: **WCAG 2.2 level AA**. Accessibility
|
|
10
|
+
is part of Definition of Done for UI work, not a later pass — it is cheapest built in and most
|
|
11
|
+
expensive retrofitted.
|
|
12
|
+
|
|
13
|
+
## The non-negotiable floor
|
|
14
|
+
|
|
15
|
+
- **Semantic HTML first.** Use the right element (`button`, `a`, `nav`, `main`, `label`, `table`).
|
|
16
|
+
A `div` with a click handler is not a button — it loses keyboard, focus, and screen-reader
|
|
17
|
+
semantics. Reach for ARIA only when no native element fits, and prefer a native one.
|
|
18
|
+
- **Keyboard operable.** Every interactive control is reachable and operable by keyboard alone, in a
|
|
19
|
+
logical tab order, with a **visible focus indicator**. No keyboard trap. Test by unplugging the
|
|
20
|
+
mouse.
|
|
21
|
+
- **Labels & names.** Every input has an associated `<label>`; every icon-only control has an
|
|
22
|
+
accessible name (`aria-label`); every meaningful image has `alt` (decorative → `alt=""`).
|
|
23
|
+
- **Contrast.** Text ≥ 4.5:1 (≥ 3:1 for large text); UI/graphics ≥ 3:1. Don't encode meaning by
|
|
24
|
+
**color alone** — pair it with text, icon, or pattern.
|
|
25
|
+
- **Forms & errors.** Errors are announced (not color-only), tied to their field
|
|
26
|
+
(`aria-describedby`), and the message says how to fix it. Don't disable submit silently.
|
|
27
|
+
- **Structure.** One `h1`; headings nest without skipping. Landmarks (`main`, `nav`) so AT users can
|
|
28
|
+
jump. Page has a sensible `<title>` and `lang`.
|
|
29
|
+
- **Motion & media.** Respect `prefers-reduced-motion`; no content flashes > 3×/sec; captions/text
|
|
30
|
+
alternatives for audio/video.
|
|
31
|
+
- **Targets & zoom.** Touch targets ≥ 24×24 CSS px; layout survives 200% zoom and 320px width
|
|
32
|
+
(reflow, no horizontal scroll).
|
|
33
|
+
- **Live regions.** Dynamic updates (toasts, async results) use `aria-live` so they are announced.
|
|
34
|
+
|
|
35
|
+
## Internationalization note
|
|
36
|
+
|
|
37
|
+
If the app is localized (e.g. Thai-first), set `lang` correctly, don't hardcode LTR assumptions, and
|
|
38
|
+
don't build strings by concatenation — these intersect with screen-reader correctness.
|
|
39
|
+
|
|
40
|
+
## Verify it (not by eye alone)
|
|
41
|
+
|
|
42
|
+
1. **Automated:** run an axe-based check (axe-core / Playwright `@axe-core/playwright` / Lighthouse)
|
|
43
|
+
in CI for key pages. Catches ~40% of issues — necessary, not sufficient.
|
|
44
|
+
2. **Keyboard pass:** tab through the whole flow; confirm order, focus visibility, no trap.
|
|
45
|
+
3. **Screen reader smoke:** one pass with VoiceOver/NVDA on the primary flow.
|
|
46
|
+
4. **Zoom/reflow:** 200% zoom + 320px width with no loss of content or function.
|
|
47
|
+
|
|
48
|
+
The `ecc:frontend-a11y` skill (`skills/catalog.md`) automates much of the audit; this standard is the
|
|
49
|
+
floor it audits against. For UI work, an a11y check is part of the verifier's review
|
|
50
|
+
(`rules/30-verification.md`).
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
updated: 2026-05-31
|
|
3
|
+
status: canonical
|
|
4
|
+
description: Module layering and boundaries distilled from real modular codebases.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Standards — architecture
|
|
8
|
+
|
|
9
|
+
Patterns distilled from real modular codebases. Apply where the module is non-trivial; don't
|
|
10
|
+
over-structure a thin CRUD screen (YAGNI).
|
|
11
|
+
|
|
12
|
+
## Pure domain layer
|
|
13
|
+
|
|
14
|
+
- Keep business logic in a layer with **zero framework/DB/IO imports** (call it `engine/`, `domain/`,
|
|
15
|
+
or `core/`). Plain functions in, plain data out.
|
|
16
|
+
- DB/IO lives only in dedicated read/write modules that call into the pure layer — never the reverse.
|
|
17
|
+
- Make non-determinism injectable: pass a **seeded RNG** / clock, so generation is reproducible and
|
|
18
|
+
unit-testable without mocks.
|
|
19
|
+
|
|
20
|
+
## Read / write / projection split
|
|
21
|
+
|
|
22
|
+
- **reads** — query module (`data/queries.ts`), `server-only`, returns raw rows.
|
|
23
|
+
- **writes** — action module (`actions/`), the only place that mutates.
|
|
24
|
+
- **projections** — pure shape transforms for each render surface, no DB. Independently testable.
|
|
25
|
+
- A view layer composes reads + projections and owns the cache tag.
|
|
26
|
+
|
|
27
|
+
## Schema / ownership by module
|
|
28
|
+
|
|
29
|
+
- Core owns identity-level schema only; each module owns its own tables. The shared DB client is
|
|
30
|
+
**schema-less** (doesn't import module tables at init), so modules don't become a circular hub.
|
|
31
|
+
- Modules may re-export core tables for FK convenience — never invert the dependency.
|
|
32
|
+
|
|
33
|
+
## Invariants
|
|
34
|
+
|
|
35
|
+
- Where correctness depends on a structural fact (an inner-join that excludes ghosts, an ordering, a
|
|
36
|
+
default), state it with a `// INVARIANT:` comment **and** a test. A silent structural invariant
|
|
37
|
+
breaks the first time someone writes a left-join.
|
|
38
|
+
- Validate required env at the **startup boundary** with a clear error — never `process.env.X!`
|
|
39
|
+
scattered at use sites (a missing var should fail loud at init, not as a random runtime error).
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
updated: 2026-06-14
|
|
3
|
+
status: canonical
|
|
4
|
+
description: "Credit the external work the project builds on: what to record when adopting a tool/pattern/idea, where it goes, and the adapt-not-copy rule."
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Standards — attribution
|
|
8
|
+
|
|
9
|
+
Credit the external work the project builds on. When you adopt something from outside — a tool,
|
|
10
|
+
library, framework, pattern, or idea (including an article or gist you adapt) — record it and credit
|
|
11
|
+
its author. This is ethics **and** provenance: a future reader must know what is ours, what is
|
|
12
|
+
borrowed, and where it came from. It is the same discipline as `standards/codex.md` (every fact cites
|
|
13
|
+
its source), applied to dependencies.
|
|
14
|
+
|
|
15
|
+
## What to record
|
|
16
|
+
|
|
17
|
+
For every external adoption:
|
|
18
|
+
|
|
19
|
+
- **Name** + **author** (handle / org if known)
|
|
20
|
+
- **Source** — repo URL, package name, or article/gist link
|
|
21
|
+
- **License** — and any redistribution constraint. **Verify it; never guess a license.**
|
|
22
|
+
- **What you adopted** — the tool/pattern, and whether used **as-is** or **adapted**
|
|
23
|
+
- **Where it's wired** — the adopting ADR, and the files/standards that reference it
|
|
24
|
+
- **Date**
|
|
25
|
+
|
|
26
|
+
## Where it goes
|
|
27
|
+
|
|
28
|
+
- **The adopting ADR cites the source.** Any decision to bring in an external tool/pattern names and
|
|
29
|
+
links it in `codex/decisions/` (this template repo: `docs/adr/`). The *why* carries the credit —
|
|
30
|
+
non-negotiable.
|
|
31
|
+
- **A running ledger** collects them in one place: `docs/attributions.md` at the repo root (the
|
|
32
|
+
Grimoire template uses this), or `codex/resources/manifest.md` for a consuming project's resources.
|
|
33
|
+
|
|
34
|
+
## Adapt, don't copy
|
|
35
|
+
|
|
36
|
+
When you adapt an external idea to this stack, say so and say what you changed — a vendor example is an
|
|
37
|
+
illustration, not a mandate. Credit the source for the idea even when little of its form survives.
|
|
38
|
+
|
|
39
|
+
Keep this lean (`rules/35-context-economy.md`).
|
|
@@ -0,0 +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.
|
|
@@ -0,0 +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.
|
|
@@ -0,0 +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
|
+
```
|
|
@@ -0,0 +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.
|
|
@@ -0,0 +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.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
updated: 2026-05-31
|
|
3
|
+
status: canonical
|
|
4
|
+
description: 'The second-brain model: three homes for work-state, and how to view memory as an optional Obsidian vault.'
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Standards — knowledge management
|
|
8
|
+
|
|
9
|
+
Where work-state lives so context survives across sessions and compaction. Three homes, each
|
|
10
|
+
answering one question; nothing duplicated between them. Continuity lives here, not in chat history.
|
|
11
|
+
|
|
12
|
+
## Three homes
|
|
13
|
+
|
|
14
|
+
| Layer | Answers | Home | Git |
|
|
15
|
+
|---|---|---|---|
|
|
16
|
+
| NOW | what am I doing right now? | `journal/session/current.md` | gitignored |
|
|
17
|
+
| KNOWLEDGE | what do we already know? | `journal/memory/` + `journal/memory/MEMORY.md` | tracked |
|
|
18
|
+
| QUEUE | what work is pending? | `journal/backlog/` | tracked |
|
|
19
|
+
|
|
20
|
+
Write the live state to NOW as you go; promote durable facts to KNOWLEDGE; route pending work to
|
|
21
|
+
QUEUE (`rules/40-handoff.md`). Finish a task, then compact or clear the session — the three homes
|
|
22
|
+
carry continuity, so a fresh session loses nothing that mattered.
|
|
23
|
+
|
|
24
|
+
## Memory cards
|
|
25
|
+
|
|
26
|
+
One fact per file under `journal/memory/`, linked with `[[wikilinks]]`; `MEMORY.md` is the one-line index.
|
|
27
|
+
Convert relative dates to absolute. Link liberally — a `[[name]]` with no file yet marks a card
|
|
28
|
+
worth writing later.
|
|
29
|
+
|
|
30
|
+
## Optional: view memory as an Obsidian vault
|
|
31
|
+
|
|
32
|
+
`journal/memory/` is plain Markdown using `[[wikilinks]]` — already Obsidian-native. Point an Obsidian vault
|
|
33
|
+
at it for graph view and backlinks over the agent's knowledge base. This is a **human view layer
|
|
34
|
+
only**: Grimoire never depends on Obsidian (the core stays tool-agnostic), and nothing in `journal/memory/`
|
|
35
|
+
requires it.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
updated: 2026-05-31
|
|
3
|
+
status: canonical
|
|
4
|
+
description: Pre-launch privacy + security gate for any app that collects user data.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Launch security checklist
|
|
8
|
+
|
|
9
|
+
A pre-launch gate for any app that collects user data. Do not ship to real users until every item
|
|
10
|
+
passes — legal and breach exposure scale with user count, so clear these before marketing.
|
|
11
|
+
|
|
12
|
+
## 1. Privacy & data map
|
|
13
|
+
- Publish a privacy policy (GDPR / CCPA / PDPA as applicable). PHI → HIPAA (see `skills/catalog.md`
|
|
14
|
+
Healthcare).
|
|
15
|
+
- Keep a data map: what personal data you collect, where it lives, who can read it, retention.
|
|
16
|
+
- Collect the minimum; delete what you do not need.
|
|
17
|
+
|
|
18
|
+
## 2. Row-level authorization on every user table
|
|
19
|
+
- Each row is restricted to its authenticated owner (Postgres/Supabase RLS, or app-layer checks).
|
|
20
|
+
- **Default-deny** — zero policies = a wide-open database. Verify one user cannot read another
|
|
21
|
+
user's rows (open DevTools / hit the API as user B).
|
|
22
|
+
|
|
23
|
+
## 3. Failure / abuse-path tests (not just the happy path)
|
|
24
|
+
- Wrong password ×N (lockout/backoff), reset for a non-existent email (no user enumeration),
|
|
25
|
+
expired / missing session, malformed / oversized / injection input. Attackers probe these first.
|
|
26
|
+
|
|
27
|
+
## 4. Server-side validation on every write route
|
|
28
|
+
- Validate **and** authorize on the server. Client (zod) validation is UX only — attackers call the
|
|
29
|
+
API directly with JS disabled.
|
|
30
|
+
|
|
31
|
+
## 5. Security headers + OWASP review
|
|
32
|
+
- Set headers: CSP, HSTS, X-Content-Type-Options, X-Frame-Options, Referrer-Policy.
|
|
33
|
+
- Run an OWASP Top 10 review (injection, broken auth, broken access control, XSS, SSRF…) via
|
|
34
|
+
`ecc:security-review` / `ecc:security-scan`.
|
|
35
|
+
|
|
36
|
+
## 6. SAST scan
|
|
37
|
+
- Run a static analysis scanner in CI and fix **High/Critical** before launch.
|
|
38
|
+
See `standards/security-scanners.md`.
|
|
39
|
+
|
|
40
|
+
## 7. Incident runbook reviewed
|
|
41
|
+
- A dated incident/rollback runbook exists and has had a tabletop or review — not just a green CI.
|
|
42
|
+
Shipping to production with an untested playbook is a launch risk in itself.
|
|
43
|
+
|
|
44
|
+
**Gate:** for any user-facing, data-collecting app this checklist is part of the Definition of Done
|
|
45
|
+
(`rules/30-verification.md`).
|