haac-aikit 0.10.0 → 0.11.1

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 (37) hide show
  1. package/README.md +31 -68
  2. package/catalog/commands/decide.md +24 -0
  3. package/catalog/commands/docs.md +27 -0
  4. package/catalog/release-notes.json +38 -0
  5. package/catalog/skills/tier1/docs.md +81 -0
  6. package/catalog/skills/tier2/decide.md +52 -0
  7. package/catalog/templates/decide/template.html +244 -0
  8. package/catalog/templates/docs/starter.html +99 -0
  9. package/dist/cli.mjs +91 -336
  10. package/dist/cli.mjs.map +1 -1
  11. package/package.json +1 -1
  12. package/catalog/commands/html.md +0 -61
  13. package/catalog/docs/html-design-system.html +0 -178
  14. package/catalog/skills/tier1/html-artifacts.md +0 -205
  15. package/catalog/templates/html-artifacts/01-exploration-code-approaches.html +0 -453
  16. package/catalog/templates/html-artifacts/02-exploration-visual-designs.html +0 -515
  17. package/catalog/templates/html-artifacts/03-code-review-pr.html +0 -638
  18. package/catalog/templates/html-artifacts/04-code-understanding.html +0 -491
  19. package/catalog/templates/html-artifacts/05-design-system.html +0 -629
  20. package/catalog/templates/html-artifacts/06-component-variants.html +0 -605
  21. package/catalog/templates/html-artifacts/07-prototype-animation.html +0 -455
  22. package/catalog/templates/html-artifacts/08-prototype-interaction.html +0 -396
  23. package/catalog/templates/html-artifacts/09-slide-deck.html +0 -596
  24. package/catalog/templates/html-artifacts/10-svg-illustrations.html +0 -495
  25. package/catalog/templates/html-artifacts/11-status-report.html +0 -528
  26. package/catalog/templates/html-artifacts/12-incident-report.html +0 -596
  27. package/catalog/templates/html-artifacts/13-flowchart-diagram.html +0 -396
  28. package/catalog/templates/html-artifacts/14-research-feature-explainer.html +0 -381
  29. package/catalog/templates/html-artifacts/15-research-concept-explainer.html +0 -368
  30. package/catalog/templates/html-artifacts/16-implementation-plan.html +0 -703
  31. package/catalog/templates/html-artifacts/17-pr-writeup.html +0 -595
  32. package/catalog/templates/html-artifacts/18-editor-triage-board.html +0 -573
  33. package/catalog/templates/html-artifacts/19-editor-feature-flags.html +0 -663
  34. package/catalog/templates/html-artifacts/20-editor-prompt-tuner.html +0 -722
  35. package/catalog/templates/html-artifacts/MANIFEST.json +0 -182
  36. package/catalog/templates/html-artifacts/README.md +0 -88
  37. package/catalog/templates/html-artifacts/index.html +0 -822
package/README.md CHANGED
@@ -4,78 +4,31 @@
4
4
  [![GitHub](https://img.shields.io/badge/github-Hamad--Center%2Fhaac--aikit-blue?logo=github)](https://github.com/Hamad-Center/haac-aikit)
5
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
6
6
 
7
- One command drops a working AI-coding setup into any repo rules, skills, safety hooks, subagents, MCP stub, CI templates for Claude Code, Cursor, Copilot, Windsurf, Aider, Gemini CLI, and Codex.
8
-
9
- > [!TIP]
10
- > **Just want HTML output from Claude Code?** Skip the full kit and install only the html-artifacts skill + 20 templates:
11
- >
12
- > ```bash
13
- > npx haac-aikit init html
14
- > ```
15
-
16
- ## Quickstart
7
+ **Docs that update themselves.** A cross-tool AI-coding kit (Claude Code, Cursor, Copilot, Windsurf, Aider, Gemini, Codex) that drops opinionated rules + skills + safety hooks into any repo. Headline feature: two new skills that maintain your project's HTML documentation and decision log as the code changes.
17
8
 
18
9
  ```bash
19
10
  npx haac-aikit
20
11
  ```
21
12
 
22
- 30-second wizard, writes a `.aikitrc.json` you can commit. Re-run anytime with `aikit sync`.
23
-
24
- For CI or scripts:
25
-
26
- ```bash
27
- npx haac-aikit --yes --tools=claude,cursor,copilot --preset=standard
28
- ```
29
-
30
- ## What you get
31
-
32
- ### Minimal scope
33
-
34
- | File | Purpose |
35
- |---|---|
36
- | `AGENTS.md` | Canonical rules — your edits outside BEGIN/END markers are never touched |
37
- | `CLAUDE.md` | Five-line shim that imports `@AGENTS.md` |
38
- | `.cursor/rules/000-base.mdc` | Dialect-translated MDC (not a generic copy) |
39
- | Per-tool shims | Copilot, Gemini, Windsurf, Aider |
40
- | `.mcp.json` | MCP stub: filesystem, memory, fetch |
41
- | `.claude/settings.json` | Hardened permissions: deny list for secrets and destructive commands |
42
-
43
- ### Standard scope adds
13
+ ## The two headline skills (v0.11)
44
14
 
45
- - **18 process skills** in `.claude/skills/` TDD, brainstorming, debugging, git workflows, and more. Bodies load on demand, ~100 tokens at rest.
46
- - **14 agents** in `.claude/agents/` planner, reviewer, debugger, pr-describer, and more.
47
- - **Safety hooks** — blocks force-push to main, secret commits, `rm -rf`, reads of `.env*` / `.ssh*` / `.aws*`. Fires before the tool call, doesn't rely on the model cooperating.
48
- - **Rule observability hooks** — logs which rules load and which get violated, feeds `aikit doctor --rules`.
49
- - **HTML design system** — `docs/aikit-html-design-system.html` ships with every standard install; use `/html` to generate rich browser-viewable artifacts instead of long markdown.
50
- - CI workflows: gitleaks, standard CI, optional `@claude` PR responder.
15
+ - **`/docs`** keeps a living HTML documentation tree at `docs/` current. The agent reads only the section it needs (via marker-bounded blocks), proposes the edit in chat, writes after you confirm. Your README stops going stale.
16
+ - **`/decide`** generates one rich HTML tradeoff page per architectural choice, saved to `docs/decisions/YYYY-MM-DD-<slug>.html`. Options as cards, pros/cons as colored dots, technical bit explained in plain language. A permanent decision log accumulates.
51
17
 
52
- ### Everything scope adds
18
+ Built on Thariq Shihipar's [Unreasonable Effectiveness of HTML for Claude Code](https://thariqs.github.io/html-effectiveness/) — generating HTML instead of markdown gives you scannable, interactive output. We took the insight and built the workflows that compound the longest.
53
19
 
54
- Dev container, OTel exporter, plugin wrapper, auto-sync CI, shape-specific agents (frontend / backend / mobile).
20
+ ## What else you get
55
21
 
56
- ## What makes it different
22
+ Beyond `/docs` and `/decide`, a `standard` install drops in:
57
23
 
58
- **Rule observability.** Telemetry hooks tell you which rules fire, which get violated, and which are dead weight. `aikit doctor --rules` shows the buckets; `aikit report` formats them for a PR comment. [docs/observability.md](docs/observability.md)
24
+ - **Cross-tool rules** one canonical `AGENTS.md`, dialect-translated per tool (proper MDC for Cursor, emphasis tokens for Claude, imperative phrasing for Aider). Stop maintaining four copies.
25
+ - **Safety hooks** — block force-push to main, secret commits, `rm -rf`, reads of `.env*` / `.ssh*` / `.aws*`. Fires before the tool call.
26
+ - **Rule observability** — telemetry tells you which rules fire, get violated, or are dead weight. `aikit doctor --rules` shows the buckets.
27
+ - **Learn from PR history** — `aikit learn --limit=30` mines merged PR reviews for repeated corrections, proposes them as new rules.
28
+ - **18 process skills + 14 agents** — TDD, brainstorming, debugging, planner, reviewer, debugger, pr-describer, more.
29
+ - **CI templates** — gitleaks, standard CI, optional `@claude` PR responder.
59
30
 
60
- **Dialect translation.** One canonical `AGENTS.md`, reformatted per tool — proper MDC frontmatter for Cursor, emphasis tokens for Claude, imperative phrasing for Aider. You stop maintaining four copies of the same rules. → [docs/dialects.md](docs/dialects.md)
61
-
62
- **Learn from your PR history.** `aikit learn --limit=30` mines merged PR review comments for repeated corrections and proposes them as new rules. No ML — just regex, a stopword list, and Jaccard similarity. → [docs/learn.md](docs/learn.md)
63
-
64
- ## Commands
65
-
66
- ```
67
- aikit interactive wizard
68
- aikit sync regenerate from .aikitrc.json (idempotent)
69
- aikit update pull latest templates, show diff, prompt
70
- aikit diff show drift between current state and a fresh sync
71
- aikit add <item> add a single skill, command, agent, or hook
72
- aikit list show installed items + catalog availability
73
- aikit doctor schema, triggers, broken-link checks
74
- aikit doctor --rules rule observability buckets
75
- aikit report Markdown adherence summary
76
- aikit report --format=json same data, structured for CI
77
- aikit learn --limit=30 propose rules from your PR review history
78
- ```
31
+ Run `npx haac-aikit` for the wizard, or `npx haac-aikit --yes --tools=claude --preset=standard` for headless / CI.
79
32
 
80
33
  ## How it compares
81
34
 
@@ -86,18 +39,28 @@ aikit learn --limit=30 propose rules from your PR review history
86
39
  | Rule observability | yes | no | no | no |
87
40
  | Dialect translation | yes | no | no | no |
88
41
  | Learn from PR history | yes | no | no | no |
42
+ | Living HTML docs (`/docs`) + decision log (`/decide`) | yes | no | no | no |
89
43
  | Idempotent BEGIN/END markers | yes | no | `.bak` backups | no |
90
44
 
91
- ## Status
92
-
93
- 0.8.0. Holding 1.0 until at least three external teams have used the observability loop on real PRs. Until then, expect breaking changes between minor versions.
45
+ ## Commands
94
46
 
95
- Looking for teams to try it — feedback shapes 1.0. Comment on [issue #1](https://github.com/Hamad-Center/haac-aikit/issues/1).
47
+ ```
48
+ aikit interactive wizard
49
+ aikit sync regenerate from .aikitrc.json
50
+ aikit update pull latest templates, show diff
51
+ aikit add <item> add a single skill / command / agent / hook
52
+ aikit list show installed items + catalog
53
+ aikit doctor [--rules] sanity / observability check
54
+ aikit report [--format=...] adherence summary (markdown or json)
55
+ aikit learn --limit=30 propose rules from your PR review history
56
+ ```
96
57
 
97
- ## Contributing
58
+ ## Status & links
98
59
 
99
- Issues and PRs welcome at [github.com/Hamad-Center/haac-aikit](https://github.com/Hamad-Center/haac-aikit).
60
+ **0.11.0** holding 1.0 until at least three external teams have used the observability loop on real PRs. Expect breaking changes between minor versions until then.
100
61
 
101
- ## License
62
+ - Site: <https://hamad-center.github.io/haac-aikit/>
63
+ - Discussion / try-it sign-up: [issue #1](https://github.com/Hamad-Center/haac-aikit/issues/1)
64
+ - Why we cut the old 20-template HTML skill: [the landing page](https://hamad-center.github.io/haac-aikit/) explains it — short version: developers don't browse a 20-template menu, two real workflows do 100% of the job. Recover the deleted templates with `git checkout v0.10.0 -- catalog/templates/html-artifacts/` if you want them.
102
65
 
103
66
  MIT. See [ATTRIBUTIONS.md](ATTRIBUTIONS.md).
@@ -0,0 +1,24 @@
1
+ Generate a single rich HTML decision page using the `decide` skill.
2
+
3
+ ## Usage
4
+ `/decide <topic>`
5
+
6
+ Example: `/decide auth strategy: session cookies vs JWT vs Clerk`.
7
+
8
+ ## Steps
9
+
10
+ 1. **Confirm the options** with the user before writing. Say back: *"Decision page on `<topic>` with options `A`, `B`, `C` — okay? My pick will be `<X>` because `<one-sentence reason>`."* Wait for yes.
11
+
12
+ 2. **Read the template** at `.aikit/templates/decide/template.html`. Copy its structure verbatim — design tokens, layout grid, callout patterns, voice + a11y conventions.
13
+
14
+ 3. **Gather concrete inputs** for each option: real cost numbers, real performance figures, real code snippets if relevant. Don't fill cards with hand-waved pros/cons — use facts.
15
+
16
+ 4. **Apply the voice rule** when writing prose: plain-language verb + concrete object, jargon in `<code>` chips not the reading path. Explain the technical bit like the reader is 15.
17
+
18
+ 5. **Write the file** to `docs/decisions/YYYY-MM-DD-<slug>.html` (today's date, kebab-case slug).
19
+
20
+ 6. **Report.** Print the file path and suggest `open docs/decisions/YYYY-MM-DD-<slug>.html` (macOS) / `xdg-open` (Linux).
21
+
22
+ ## Fallback
23
+
24
+ If `.aikit/templates/decide/template.html` is missing, run `aikit sync` first.
@@ -0,0 +1,27 @@
1
+ Update the project's HTML documentation in `docs/` using the `docs` skill.
2
+
3
+ ## Usage
4
+ `/docs [optional intent]`
5
+
6
+ With args: use them as the change to document (e.g. `/docs the new auth refresh flow`).
7
+ Without args: infer from the last 5-10 turns of conversation what's worth documenting.
8
+
9
+ ## Steps
10
+
11
+ 1. **Decide what changed.** Identify (a) the doc file (`docs/<slug>.html`) and (b) the section id inside it (`overview`, `flow`, `gotchas`, etc). If no doc fits, propose creating one.
12
+
13
+ 2. **Read only the affected section.** Use `readSection(content, id, filePath)` from `src/render/markers` — never load the whole file.
14
+
15
+ 3. **Propose before writing.** One sentence in chat:
16
+ > *"I'll update `<section>` in `docs/<file>.html` to reflect <change>. Okay?"*
17
+ Wait for explicit yes. No silent edits.
18
+
19
+ 4. **Write through the marker engine.** `writeSection` to replace, `appendSection` for new sections. Anything outside markers is preserved verbatim.
20
+
21
+ 5. **Update `docs/index.html`** if you created a new doc or materially changed an existing one — refresh the matching `summary-<slug>` section.
22
+
23
+ 6. **Report.** Print the modified file paths and one-line summary of what changed.
24
+
25
+ ## Fallback
26
+
27
+ If `.aikit/templates/docs/starter.html` is missing (project synced before this kit version), run `aikit sync` first.
@@ -1,6 +1,44 @@
1
1
  {
2
2
  "version": 1,
3
3
  "releases": [
4
+ {
5
+ "version": "0.11.1",
6
+ "date": "2026-05-13",
7
+ "headline": "Docs-only patch: punchier landing + trimmed README",
8
+ "highlights": [
9
+ "Landing: new hero \"Docs that update themselves\" + without/with comparison block",
10
+ "Landing: Thariq Shihipar's HTML article elevated to a pull-quote attribution",
11
+ "README: 114 → 66 lines, /docs + /decide pulled to top as headline feature",
12
+ "No code changes — same surface as 0.11.0"
13
+ ],
14
+ "links": {
15
+ "changelog": "https://github.com/Hamad-Center/haac-aikit/blob/main/CHANGELOG.md#0111---2026-05-13"
16
+ }
17
+ },
18
+ {
19
+ "version": "0.11.0",
20
+ "date": "2026-05-13",
21
+ "headline": "/html replaced by /docs + /decide — fewer templates, sharper jobs",
22
+ "highlights": [
23
+ "NEW `/docs` skill (tier1, ~80 lines) — maintains an HTML documentation tree at `docs/` with section-bounded surgical updates",
24
+ "NEW `/decide` skill (tier2, ~50 lines) — single rich tradeoff page per decision, written to `docs/decisions/YYYY-MM-DD-<slug>.html`",
25
+ "NEW marker engine helpers `readSection`, `writeSection`, `appendSection` for `<!-- BEGIN:haac-aikit:section:<id> -->` blocks (round-trip tested)",
26
+ "REMOVED `/html` skill (was 205 lines, 9 patterns, 20 templates) and `aikit scaffold html` CLI",
27
+ "REMOVED `aikit init html` scope and `docs/aikit-html-design-system.html` shipped doc"
28
+ ],
29
+ "breaking": [
30
+ "`/html` slash command is gone — use `/docs` for living docs and `/decide` for tradeoff pages",
31
+ "`aikit init html` scope removed — use `aikit init --scope minimal` (or standard) instead",
32
+ "`aikit scaffold html` removed — agents read templates directly from `.aikit/templates/`"
33
+ ],
34
+ "migration": [
35
+ "Run `aikit sync` to pull new `/docs` and `/decide` templates into `.aikit/templates/`",
36
+ "Delete the orphaned `.aikit/templates/html-artifacts/` and `docs/aikit-html-design-system.html` if you have no local edits worth keeping"
37
+ ],
38
+ "links": {
39
+ "changelog": "https://github.com/Hamad-Center/haac-aikit/blob/main/CHANGELOG.md#0110---2026-05-13"
40
+ }
41
+ },
4
42
  {
5
43
  "version": "0.9.0",
6
44
  "date": "2026-05-12",
@@ -0,0 +1,81 @@
1
+ ---
2
+ name: docs
3
+ description: Use when the project's documentation is out of sync with the code or conversation just established a new architectural fact, feature, or gotcha worth recording. Maintains an HTML documentation tree at `docs/` — many small per-area files plus a rolled-up `docs/index.html`. Reads and writes single sections through marker-bounded `<!-- BEGIN:haac-aikit:section:<id> -->` blocks so updates are surgical and cheap.
4
+ version: "1.0.0"
5
+ source: haac-aikit
6
+ license: MIT
7
+ ---
8
+
9
+ ## When to use
10
+
11
+ - User runs `/docs` explicitly.
12
+ - Conversation just produced a documentable fact: a new feature was built, a module was refactored, a gotcha surfaced, an architectural decision was made and you've already used `/decide` to capture the choice itself.
13
+ - A doc is visibly stale (filename or section name appeared in conversation but the file's content contradicts what was just discussed).
14
+
15
+ Do **not** use for one-off explanations — those belong in chat, not docs.
16
+
17
+ ## File layout
18
+
19
+ ```
20
+ docs/
21
+ index.html ← rolled-up overview: short summary per linked doc + link
22
+ architecture.html ← one HTML file per area or feature
23
+ auth.html
24
+ db.html
25
+ features/<slug>.html ← per-feature deep dives (optional sub-folder)
26
+ ```
27
+
28
+ Every HTML file uses the marker engine for sectioning:
29
+
30
+ ```html
31
+ <!-- BEGIN:haac-aikit:section:overview -->
32
+ <section id="overview"><h2>Overview</h2>... </section>
33
+ <!-- END:haac-aikit:section:overview -->
34
+ ```
35
+
36
+ Section IDs are kebab-case alphanumeric (`overview`, `data-flow`, `gotchas`, `adr-001`). They're stable across updates so the agent can find them.
37
+
38
+ ## Update protocol — follow exactly
39
+
40
+ 1. **Identify what changed.** From the recent conversation, name (a) the doc that's affected (`auth.html`, etc.) and (b) the section ID inside it (`overview`, `flow`, etc.). If the doc doesn't exist yet, plan to create it.
41
+ 2. **Read only the section you'll edit.** Use the marker engine's `readSection(content, id, filePath)` — never load the whole file.
42
+ 3. **Propose the change to the user in chat before writing.** One sentence: *"I'll update `<section>` in `docs/<file>.html` to reflect <change>. Okay?"* Wait for explicit confirmation. No silent writes.
43
+ 4. **Write through the marker engine.** Use `writeSection` for replacing an existing section. Use `appendSection` to add a new one. Anything outside markers (user-authored prose, hand-edited content) is preserved automatically.
44
+ 5. **Update `docs/index.html`** if you created a new file or materially changed an existing doc's purpose. Replace the matching summary inside its `<!-- BEGIN:haac-aikit:section:summary-<slug> -->` block.
45
+
46
+ ## Starter template
47
+
48
+ When a doc doesn't exist yet, scaffold from `.aikit/templates/docs/starter.html` (synced from the catalog). The starter has:
49
+
50
+ - Design tokens in `:root` (`--clay`, `--slate`, `--ivory`, `--oat`, `--olive`, `--gray-*`)
51
+ - Landmark roles (`<main>`, `<nav>`, `<aside>`)
52
+ - One example sectioned block to copy
53
+ - A11y baseline: `<title>`, heading hierarchy, native form controls only
54
+
55
+ Don't invent HTML structure from scratch — read the starter first.
56
+
57
+ ## index.html maintenance
58
+
59
+ `docs/index.html` is the navigation hub. Each linked doc gets one summary card inside its own section:
60
+
61
+ ```html
62
+ <!-- BEGIN:haac-aikit:section:summary-auth -->
63
+ <a href="auth.html"><h3>Authentication</h3>
64
+ <p>How sign-in, session, and token refresh work. 1-paragraph summary kept in sync with auth.html.</p></a>
65
+ <!-- END:haac-aikit:section:summary-auth -->
66
+ ```
67
+
68
+ When you update `auth.html`'s overview, also update the matching `summary-auth` section in `index.html` so the rollup stays accurate.
69
+
70
+ ## Visual content
71
+
72
+ HTML allows inline SVG diagrams, code samples, and graphs when they earn their weight. Default to prose; add a diagram only when it explains something prose can't (a flow, a topology, a sequence).
73
+
74
+ ## Anti-patterns to avoid
75
+
76
+ - **Loading the whole file to edit one section.** Defeats the token-cost mitigation; always use `readSection` / `writeSection`.
77
+ - **Silent writes.** Every update gets one-sentence confirmation in chat first. Docs are project-facing; surprise edits erode trust.
78
+ - **Editing content outside the markers.** That's user-authored prose; preserve it verbatim.
79
+ - **Inventing HTML from scratch.** Read the starter template first.
80
+ - **Drifting `index.html`.** When a doc's purpose changes, its summary in `index.html` MUST change too — same commit.
81
+ - **One giant doc.** Split per area; the rollup gives the single-page view if the user wants it.
@@ -0,0 +1,52 @@
1
+ ---
2
+ name: decide
3
+ description: Use when the user is about to make a non-trivial choice with 2-4 viable options and wants the tradeoffs visualized as a single rich HTML page they can scan, share, and commit to the project's decision log. Generates one self-contained HTML file per decision under `docs/decisions/YYYY-MM-DD-<slug>.html`. Opt-in only — do not invoke without user request.
4
+ version: "1.0.0"
5
+ source: haac-aikit
6
+ license: MIT
7
+ ---
8
+
9
+ ## When to use
10
+
11
+ Explicit invocation only: `/decide <topic>`, "use the decide skill", "make me a decision page on X".
12
+
13
+ Do not invoke proactively. The user picks the moment they need a tradeoff laid out — silent generation creates noise.
14
+
15
+ ## Structure of a decision page
16
+
17
+ Every page has the same five blocks. Order matters: decision-makers should never have to scroll to find what they're approving.
18
+
19
+ 1. **Decision needed callout** — the question in one sentence at the top. Recommended option marked with `★`.
20
+ 2. **Option cards (2-4)** — each card has: title, one-line summary, pros (olive dots), cons (clay dots), how-it-works in 2-3 plain-language sentences.
21
+ 3. **Comparison row** — a small table or chip grid putting the options side by side on the dimensions that matter (cost, complexity, reversibility, performance — pick what's relevant).
22
+ 4. **Technical bit, explained 15-year-old simple** — one paragraph per option. Plain verbs + concrete objects. Jargon goes in `<code>` chips, not the reading path.
23
+ 5. **Recommendation + reasoning** — clay-bordered callout. State the pick, the one-sentence reason, the conditions under which the recommendation flips.
24
+
25
+ ## Output
26
+
27
+ - Path: `docs/decisions/YYYY-MM-DD-<slug>.html` (today's date, kebab-case slug from the topic)
28
+ - Template: `.aikit/templates/decide/template.html` — read first, copy structure verbatim, fill placeholders
29
+ - Self-contained: pure HTML/CSS, no CDNs, no build step
30
+ - Committed to git (permanent decision log)
31
+
32
+ ## Voice rule (non-negotiable)
33
+
34
+ - One concept per sentence.
35
+ - Plain-language verb + concrete object: *"Load images only when the reader scrolls to them"* beats *"Implement lazy-loading via IntersectionObserver."*
36
+ - Jargon lives in `<code>` chips or collapsed `<details>`, never in main prose.
37
+ - Concrete first, abstract term in parens: *"Make sure failed requests retry safely (idempotent)"*.
38
+
39
+ ## A11y baseline (every decision page)
40
+
41
+ - `<title>`, exactly one `<h1>`, heading hierarchy never skips levels.
42
+ - Landmarks: `<main>`, `<nav>` if linking to other decisions, `<aside>` for the recommendation callout.
43
+ - Color contrast ≥ 4.5:1 for body text — design tokens already meet this; don't override.
44
+ - Inline SVG diagrams get `<title>` + `aria-labelledby`. Decorative icons get `aria-hidden="true"`.
45
+
46
+ ## Anti-patterns
47
+
48
+ - **More than 4 options.** Decision pages with 5+ options become catalogs; pre-narrow the field.
49
+ - **Recommendation buried below the fold.** First paint must show the recommendation.
50
+ - **Jargon-heavy prose.** If a non-technical stakeholder can't read it, rewrite it.
51
+ - **Silent generation.** This skill is opt-in. Wait for explicit `/decide`.
52
+ - **Skipping the date in the filename.** The decision log sorts chronologically; dates are required.
@@ -0,0 +1,244 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>{{TITLE}}</title>
7
+ <meta name="description" content="{{ONE_LINE_DECISION}}">
8
+ <meta name="aikit-doc-type" content="decision">
9
+ <style>
10
+ :root {
11
+ --clay: #D97757;
12
+ --slate: #141413;
13
+ --ivory: #FAF9F5;
14
+ --oat: #E3DACC;
15
+ --olive: #788C5D;
16
+ --gray-150: #F0EEE6;
17
+ --gray-300: #D1CFC5;
18
+ --gray-500: #87867F;
19
+ --gray-700: #3D3D3A;
20
+ --white: #FFFFFF;
21
+ --serif: ui-serif, Georgia, "Times New Roman", serif;
22
+ --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
23
+ --sans: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
24
+ }
25
+ * { box-sizing: border-box; }
26
+ body {
27
+ margin: 0;
28
+ background: var(--ivory);
29
+ color: var(--slate);
30
+ font-family: var(--sans);
31
+ line-height: 1.55;
32
+ -webkit-font-smoothing: antialiased;
33
+ }
34
+ main { max-width: 1080px; margin: 0 auto; padding: 48px 24px 96px; }
35
+
36
+ h1, h2, h3 { font-family: var(--serif); margin: 0 0 8px; }
37
+ h1 { font-size: clamp(28px, 4vw, 38px); }
38
+ h2 { font-size: clamp(20px, 2.4vw, 26px); margin-top: 48px; }
39
+ h3 { font-size: 17px; margin: 0 0 6px; }
40
+
41
+ .eyebrow {
42
+ font-family: var(--mono);
43
+ font-size: 11px;
44
+ text-transform: uppercase;
45
+ letter-spacing: 0.08em;
46
+ color: var(--gray-500);
47
+ }
48
+
49
+ .decision-needed {
50
+ background: var(--white);
51
+ border: 1px solid var(--gray-300);
52
+ border-left: 4px solid var(--clay);
53
+ border-radius: 6px;
54
+ padding: 20px 24px;
55
+ margin: 24px 0 36px;
56
+ box-shadow: 0 1px 3px rgba(20, 20, 19, 0.06);
57
+ }
58
+ .decision-needed .question {
59
+ font-family: var(--serif);
60
+ font-size: 22px;
61
+ margin: 6px 0 12px;
62
+ }
63
+ .option-chips { display: flex; flex-wrap: wrap; gap: 8px; }
64
+ .option-chips .chip {
65
+ font-family: var(--mono);
66
+ font-size: 12px;
67
+ background: var(--oat);
68
+ color: var(--slate);
69
+ padding: 4px 10px;
70
+ border-radius: 999px;
71
+ }
72
+ .option-chips .chip.recommended { background: var(--olive); color: var(--white); }
73
+
74
+ .cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 16px; margin-top: 16px; }
75
+ .card {
76
+ background: var(--white);
77
+ border: 1px solid var(--gray-300);
78
+ border-radius: 6px;
79
+ padding: 18px;
80
+ }
81
+ .card.recommended { border-color: var(--olive); border-width: 2px; }
82
+ .card .summary { color: var(--gray-700); margin: 4px 0 14px; }
83
+ .card ul { list-style: none; padding: 0; margin: 8px 0; font-size: 14px; }
84
+ .card li { padding-left: 18px; position: relative; margin: 4px 0; }
85
+ .card li.pro::before {
86
+ content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--olive);
87
+ position: absolute; left: 2px; top: 8px;
88
+ }
89
+ .card li.con::before {
90
+ content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--clay);
91
+ position: absolute; left: 2px; top: 8px;
92
+ }
93
+ .card .how {
94
+ background: var(--gray-150); padding: 10px 12px; border-radius: 4px;
95
+ font-size: 13px; margin-top: 12px;
96
+ }
97
+
98
+ table { width: 100%; border-collapse: collapse; margin-top: 12px; font-size: 14px; }
99
+ th, td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--gray-300); }
100
+ th { background: var(--gray-150); font-weight: 600; font-family: var(--mono); font-size: 12px; text-transform: uppercase; }
101
+
102
+ .tech-block { background: var(--white); border: 1px solid var(--gray-300); border-radius: 6px; padding: 18px; margin-top: 12px; }
103
+ .tech-block h3 { color: var(--gray-700); }
104
+
105
+ .recommendation {
106
+ background: var(--white);
107
+ border: 1px solid var(--olive);
108
+ border-left: 4px solid var(--olive);
109
+ border-radius: 6px;
110
+ padding: 20px 24px;
111
+ margin-top: 32px;
112
+ }
113
+ .recommendation .pick {
114
+ font-family: var(--serif); font-size: 22px; margin: 0 0 8px;
115
+ }
116
+ .recommendation .reason { color: var(--gray-700); }
117
+ .recommendation .flip {
118
+ margin-top: 12px; font-size: 13px; color: var(--gray-500); font-style: italic;
119
+ }
120
+
121
+ code { font-family: var(--mono); font-size: 0.9em; background: var(--gray-150); padding: 1px 5px; border-radius: 3px; }
122
+ a { color: var(--clay); text-underline-offset: 2px; }
123
+ a:focus-visible { outline: 2px solid var(--clay); outline-offset: 2px; border-radius: 2px; }
124
+
125
+ footer.provenance {
126
+ margin-top: 48px; padding-top: 16px; border-top: 1px solid var(--gray-300);
127
+ font-family: var(--mono); font-size: 11px; color: var(--gray-500);
128
+ }
129
+
130
+ @media (max-width: 720px) {
131
+ main { padding: 24px 16px 64px; }
132
+ .cards { grid-template-columns: 1fr; }
133
+ }
134
+ </style>
135
+ </head>
136
+ <body>
137
+
138
+ <main>
139
+
140
+ <header>
141
+ <p class="eyebrow">Decision · {{DATE}}</p>
142
+ <h1>{{TITLE}}</h1>
143
+ </header>
144
+
145
+ <aside class="decision-needed" aria-labelledby="decision-question">
146
+ <p class="eyebrow">Decision needed</p>
147
+ <p id="decision-question" class="question">{{ONE_LINE_DECISION_QUESTION}}</p>
148
+ <div class="option-chips" role="list">
149
+ <span class="chip" role="listitem">A — {{OPTION_A_NAME}}</span>
150
+ <span class="chip recommended" role="listitem">B — {{OPTION_B_NAME}} ★</span>
151
+ <span class="chip" role="listitem">C — {{OPTION_C_NAME}}</span>
152
+ </div>
153
+ </aside>
154
+
155
+ <section id="options" aria-labelledby="options-heading">
156
+ <h2 id="options-heading">Options</h2>
157
+ <div class="cards">
158
+
159
+ <article class="card">
160
+ <h3>A — {{OPTION_A_NAME}}</h3>
161
+ <p class="summary">{{OPTION_A_SUMMARY}}</p>
162
+ <ul aria-label="Pros and cons of option A">
163
+ <li class="pro">{{OPTION_A_PRO_1}}</li>
164
+ <li class="pro">{{OPTION_A_PRO_2}}</li>
165
+ <li class="con">{{OPTION_A_CON_1}}</li>
166
+ </ul>
167
+ <div class="how"><strong>How it works:</strong> {{OPTION_A_HOW}}</div>
168
+ </article>
169
+
170
+ <article class="card recommended" aria-label="Recommended option">
171
+ <h3>B — {{OPTION_B_NAME}} <span aria-hidden="true">★</span></h3>
172
+ <p class="summary">{{OPTION_B_SUMMARY}}</p>
173
+ <ul aria-label="Pros and cons of option B">
174
+ <li class="pro">{{OPTION_B_PRO_1}}</li>
175
+ <li class="pro">{{OPTION_B_PRO_2}}</li>
176
+ <li class="con">{{OPTION_B_CON_1}}</li>
177
+ </ul>
178
+ <div class="how"><strong>How it works:</strong> {{OPTION_B_HOW}}</div>
179
+ </article>
180
+
181
+ <article class="card">
182
+ <h3>C — {{OPTION_C_NAME}}</h3>
183
+ <p class="summary">{{OPTION_C_SUMMARY}}</p>
184
+ <ul aria-label="Pros and cons of option C">
185
+ <li class="pro">{{OPTION_C_PRO_1}}</li>
186
+ <li class="con">{{OPTION_C_CON_1}}</li>
187
+ <li class="con">{{OPTION_C_CON_2}}</li>
188
+ </ul>
189
+ <div class="how"><strong>How it works:</strong> {{OPTION_C_HOW}}</div>
190
+ </article>
191
+
192
+ </div>
193
+ </section>
194
+
195
+ <section id="comparison" aria-labelledby="comparison-heading">
196
+ <h2 id="comparison-heading">Side by side</h2>
197
+ <table>
198
+ <thead>
199
+ <tr>
200
+ <th>Dimension</th>
201
+ <th>A — {{OPTION_A_NAME}}</th>
202
+ <th>B — {{OPTION_B_NAME}}</th>
203
+ <th>C — {{OPTION_C_NAME}}</th>
204
+ </tr>
205
+ </thead>
206
+ <tbody>
207
+ <tr><td>Cost</td><td>{{A_COST}}</td><td>{{B_COST}}</td><td>{{C_COST}}</td></tr>
208
+ <tr><td>Complexity</td><td>{{A_COMPLEXITY}}</td><td>{{B_COMPLEXITY}}</td><td>{{C_COMPLEXITY}}</td></tr>
209
+ <tr><td>Reversibility</td><td>{{A_REVERSIBILITY}}</td><td>{{B_REVERSIBILITY}}</td><td>{{C_REVERSIBILITY}}</td></tr>
210
+ </tbody>
211
+ </table>
212
+ </section>
213
+
214
+ <section id="technical" aria-labelledby="technical-heading">
215
+ <h2 id="technical-heading">The technical bit (in plain language)</h2>
216
+ <div class="tech-block">
217
+ <h3>A — {{OPTION_A_NAME}}</h3>
218
+ <p>{{OPTION_A_TECH_PLAIN}}</p>
219
+ </div>
220
+ <div class="tech-block">
221
+ <h3>B — {{OPTION_B_NAME}}</h3>
222
+ <p>{{OPTION_B_TECH_PLAIN}}</p>
223
+ </div>
224
+ <div class="tech-block">
225
+ <h3>C — {{OPTION_C_NAME}}</h3>
226
+ <p>{{OPTION_C_TECH_PLAIN}}</p>
227
+ </div>
228
+ </section>
229
+
230
+ <aside class="recommendation" aria-labelledby="recommendation-heading">
231
+ <p class="eyebrow" id="recommendation-heading">Recommendation</p>
232
+ <p class="pick">★ Pick {{RECOMMENDED_LETTER}} — {{RECOMMENDED_NAME}}</p>
233
+ <p class="reason">{{RECOMMENDATION_REASON}}</p>
234
+ <p class="flip"><strong>Flip to a different option if:</strong> {{FLIP_CONDITION}}</p>
235
+ </aside>
236
+
237
+ <footer class="provenance">
238
+ Sources: {{SOURCES}} — generated {{ISO_TIMESTAMP}}
239
+ </footer>
240
+
241
+ </main>
242
+
243
+ </body>
244
+ </html>