|
| 1 | +# dev-llm-wiki — Agent Schema |
| 2 | + |
| 3 | +You are the maintainer and consumer of this wiki. This file is the schema: it defines |
| 4 | +how the wiki is structured, how you route into it, how you write pages, and how you |
| 5 | +keep it healthy. Follow it exactly. When this file and your habits disagree, this file wins. |
| 6 | + |
| 7 | +## What this wiki is |
| 8 | + |
| 9 | +A case-routed knowledge base of development best practices and edge cases, written |
| 10 | +**for LLM agents to load as working context**. It is not documentation for humans to |
| 11 | +browse (humans are welcome, but every formatting rule below exists to make an agent's |
| 12 | +context precise and small). |
| 13 | + |
| 14 | +Three layers (Karpathy LLM-wiki pattern): |
| 15 | + |
| 16 | +| Layer | Path | Mutability | |
| 17 | +|-------|------|------------| |
| 18 | +| Schema | `AGENTS.md` (this file), `templates/` | Change only with repo owner approval | |
| 19 | +| Wiki | `wiki/**` , `INDEX.md`, `log.md` | You create and update via the workflows below | |
| 20 | +| Workflows | `skills/` | Change only with repo owner approval | |
| 21 | + |
| 22 | +## Directory layout |
| 23 | + |
| 24 | +``` |
| 25 | +INDEX.md # root map: domain → when to route there |
| 26 | +log.md # append-only chronological change log |
| 27 | +wiki/<domain>/index.md # domain map: category/page → when to load it |
| 28 | +wiki/<domain>/<category>/<page>.md |
| 29 | +templates/page.md # canonical page template |
| 30 | +skills/ingest|query|lint/ # the three operations |
| 31 | +``` |
| 32 | + |
| 33 | +## Routing protocol (how to consume) |
| 34 | + |
| 35 | +When working on a task and you need guidance from this wiki: |
| 36 | + |
| 37 | +1. Read `INDEX.md`. Match your task to a domain by its "route here when" line. |
| 38 | + - **Several domains match**: route to the domain that owns the artifact you will |
| 39 | + change (SQL/schema → databases; application code → backend; a failing system → |
| 40 | + debugging). Reading a second domain's index to check is cheap and sanctioned; |
| 41 | + bulk-loading pages from both is not. |
| 42 | + - **Best match is marked `scaffold`**: it has no pages. Use the cross-pointers in |
| 43 | + its index if any, take the next matching seeded domain, and append a `gap` |
| 44 | + entry to `log.md`. |
| 45 | +2. Read that domain's `wiki/<domain>/index.md`. Select pages by their **"load when" |
| 46 | + lines — these are the routing gate**. Load only pages whose line matches your |
| 47 | + situation. |
| 48 | +3. After loading, the page's "When this applies" should confirm the match. If it |
| 49 | + contradicts your situation, drop the page and append a `drift` entry to `log.md` |
| 50 | + (index line and page trigger disagree — a lint defect), unless the page content |
| 51 | + demonstrably serves your case anyway, in which case keep it and still log the drift. |
| 52 | +4. **Sanctioned extra hops**: when a loaded page routes you onward via an inline |
| 53 | + `[page-id]` reference or a `related:` id, follow it — the citing directive is the |
| 54 | + trigger. This is how constraint/index pages compose. |
| 55 | +5. If no page matches anywhere, answer from general knowledge **explicitly labeled |
| 56 | + not wiki-backed**, and append a `gap` entry to `log.md`. |
| 57 | +6. Apply the page's directives: |
| 58 | + - If your situation hits a listed edge case, follow the edge-case row, not the |
| 59 | + general rule. |
| 60 | + - Within a Do/decision table, when several rows match, apply the **most specific |
| 61 | + row** (rows are ordered general → specific); when a general row and a |
| 62 | + precondition-bearing row both fit, take the one that preserves the stated |
| 63 | + invariant. |
| 64 | + |
| 65 | +Hard rule: never load a whole domain "for background". The index lines exist so you |
| 66 | +can decide relevance without opening pages. |
| 67 | + |
| 68 | +## Page format (how to write) |
| 69 | + |
| 70 | +Every page uses `templates/page.md`. Non-negotiable rules: |
| 71 | + |
| 72 | +1. **One case per page.** A page answers one situation. If you are writing "and also…", |
| 73 | + split the page and cross-link under `related`. |
| 74 | +2. **≤ 120 lines of body.** Precision beats coverage. Link, don't inline. |
| 75 | +3. **Positive guidance only.** Every directive is "In situation X, do Y". |
| 76 | + Anti-patterns may only appear in the `Instead of` table, where each row MUST pair |
| 77 | + the anti-pattern with its replacement action. A "don't" without an "instead" is a |
| 78 | + lint failure — a prohibition with no replacement invites the reader to improvise, |
| 79 | + which is how hallucinations happen. |
| 80 | +4. **No vague qualifiers.** Words like "usually", "consider", "might want to", |
| 81 | + "generally", "as appropriate" are banned in directive sentences. State the |
| 82 | + condition that decides it: "When X, do A. When Y, do B." If you cannot state the |
| 83 | + condition, the knowledge is not ready for a page — file it in the ingest queue. |
| 84 | +5. **Sources are mandatory.** Frontmatter `sources:` lists the evidence |
| 85 | + (official docs, measured benchmarks, published post-mortems). Claims you cannot |
| 86 | + source get `confidence: unverified` and are surfaced by lint until sourced or removed. |
| 87 | +6. **Case branches are tables.** When behavior differs by situation, use a |
| 88 | + `| Case | Do |` table, not prose. Tables are what agents parse most reliably. |
| 89 | + |
| 90 | +### Frontmatter |
| 91 | + |
| 92 | +```yaml |
| 93 | +--- |
| 94 | +id: <domain>-<category>-<slug> # globally unique |
| 95 | +domain: databases |
| 96 | +category: indexing |
| 97 | +applies_to: [postgresql, mysql] # or [general] |
| 98 | +confidence: verified | field-tested | unverified |
| 99 | +sources: |
| 100 | + - <url or citation> |
| 101 | +last_verified: YYYY-MM-DD |
| 102 | +related: [<page id>, ...] |
| 103 | +--- |
| 104 | +``` |
| 105 | + |
| 106 | +`confidence` meanings — `verified`: backed by cited official docs or reproducible |
| 107 | +measurement. `field-tested`: worked in real production use; context described in the |
| 108 | +page. `unverified`: candidate knowledge; lint reports it until upgraded or removed. |
| 109 | + |
| 110 | +### Section skeleton |
| 111 | + |
| 112 | +```markdown |
| 113 | +# <Title — the situation, stated as a noun phrase> |
| 114 | +## When this applies # trigger conditions, 1-4 lines, matchable without reading further |
| 115 | +## Do this # directives; decision table if branching |
| 116 | +## Edge cases # | Case | Then | table |
| 117 | +## Instead of # | If you are about to | Do this instead | Why | (optional section) |
| 118 | +## Sources |
| 119 | +``` |
| 120 | + |
| 121 | +## Operations |
| 122 | + |
| 123 | +Run these via the skill files, which contain the full step-by-step workflows: |
| 124 | + |
| 125 | +- **Ingest** (`skills/wiki-ingest/SKILL.md`) — add new knowledge: route it to domain/category, |
| 126 | + merge into existing pages before creating new ones, cite sources, update indexes and `log.md`. |
| 127 | +- **Query** (`skills/wiki-query/SKILL.md`) — answer a question from the wiki with citations; |
| 128 | + if the answer required synthesis across pages and is re-askable, file it as a new page. |
| 129 | +- **Lint** (`skills/wiki-lint/SKILL.md`) — health check: unsourced claims, "don't"s without |
| 130 | + "instead"s, banned vague qualifiers, orphan pages, broken links, stale `last_verified`. |
| 131 | + |
| 132 | +Two further skills use the wiki to run development work (rather than maintain the wiki): |
| 133 | + |
| 134 | +- **Plan** (`skills/wiki-plan/SKILL.md`) — for a capable model: make every design decision |
| 135 | + (wiki-grounded), then decompose the work into ordered task files sized for a small |
| 136 | + model (≤3 files, ≤4 wiki pages, verifiable, self-contained), each mapping the exact |
| 137 | + wiki pages that govern it. |
| 138 | +- **Implement** (`skills/wiki-implement/SKILL.md`) — for the small model executing one task: |
| 139 | + read only the task file + its named wiki pages + named inputs, no improvisation |
| 140 | + (missing decisions are reported BLOCKED, never guessed), verify, report in a fixed format. |
| 141 | + |
| 142 | +## Naming |
| 143 | + |
| 144 | +- Domains and categories: lowercase kebab-case nouns (`query-optimization`). |
| 145 | +- A domain may nest one subtree level when it splits by stack/environment |
| 146 | + (`backend/common/`, `backend/java/`, `backend/node/`, `backend/python/`); page ids |
| 147 | + then include the subtree: `backend-java-jpa-<slug>`. The domain `index.md` routes |
| 148 | + concern-first (shared subtree) then stack; each stack subtree has its own `index.md`. |
| 149 | +- Page files: the situation, not the technology (`composite-index-column-order.md`, |
| 150 | + not `postgres-tips.md`). |
| 151 | +- Page ids: `<domain>-<category>-<slug>` matching the file path. |
| 152 | + |
| 153 | +## Maintenance invariants |
| 154 | + |
| 155 | +After any wiki change, all of these must hold (lint checks them): |
| 156 | + |
| 157 | +1. Every page is listed in its domain `index.md` with an accurate "load when" line. |
| 158 | + The line must enumerate the page's **distinct use cases** (including |
| 159 | + constraint/uniqueness/design-time uses), not only its headline framing, and must |
| 160 | + not contradict the page's "When this applies". Decision tables inside pages are |
| 161 | + ordered general → specific. |
| 162 | +2. Every domain appears in `INDEX.md`. |
| 163 | +3. `log.md` has an appended entry: `## [YYYY-MM-DD] <ingest|revise|lint> | <summary>`. |
| 164 | +4. Every `related:` id and inline link resolves to an existing page. |
| 165 | +5. No page exceeds 120 body lines. |
0 commit comments