The kolu Atlas
kolu's second brain — an in-repo, MDX-authored knowledge base in a self-contained Astro project, dogfooded in the Code tab.
This doc dogfoods itself — authored as MDX, living in the Atlas it describes (
docs/atlas/), rendered to a self-containeddocs/atlas/dist/second-brain.htmlyou read in the Code tab. No dev server.
Premise: you already have a second brain — assign roles, don’t build a new system. kolu’s existing stores:
- GitHub Issues — lightweight, living nodes.
- In-repo docs — substantial, structured artifacts.
- The blog — the public stream.
- The Code tab — renders + annotates both.
The one routing rule
Substantial, structured artifact — or lightweight, transient node?
| Substantial → an Atlas note | Lightweight → a GitHub Issue |
|---|---|
| Proposals, designs, features, analyses, bug investigations, history | Quick bug tickets, tasks, roadmap items, questions |
- Maturity is a tag, not a divider —
seedling→budding→evergreen; never a location, never a routing axis. - Living ≠ frozen — a long-lived plan evolves for months and is still an Atlas note, never “frozen”.
- The boundary blurs by design — a concept can hold both a note and an issue.
- Extract, don’t sync — when an issue thread becomes the source of truth, lift its summary into a note.
The map
| Surface | Where | Role |
|---|---|---|
| Public | the blog (kolu.dev) + per-release changelog | outward-facing; one post per release |
| Atlas | docs/atlas/ → docs/atlas/dist/ | the working brain; markdown/MDX notes, internal-only |
- History isn’t a third place — it’s the Atlas over time: a settled note is just
evergreen, git is the history, the changelog is the release artifact.
Where it lives: a self-contained Astro project
docs/atlas/ is its own little Astro project — decoupled from the public
website/ (different audience + cadence), not published anywhere.
- Author markdown/MDX, get HTML — write
.md/.mdx+ frontmatter; Astro renders. - One layout + theme — no per-file CSS (the old HTML notes duplicated ~76 KB).
- Generated index from frontmatter — no hand-curated map (see Navigation).
- Self-contained committed output — each
dist/<slug>.htmlinlines its styles and cross-links with relative hrefs → previews in the Code tab, no server. draft: truehides a half-baked note from the index but keeps it on disk for agents.
Format — markdown prose + MDX components
- Prose in markdown — the default.
.mdxwhen a note needs more — import typed Astro/TS components, use them inline. No raw HTML, no per-note CSS.
| Why markdown for prose | Evidence |
|---|---|
| Far fewer tokens — paid on every agent read | Cloudflare: ~80% fewer tokens md vs html |
| The CLIs kolu runs prefer it | Claude Code & OpenCode send Accept: text/markdown |
| Renders where it matters | github.com renders .md; the Code tab renders it (#1093) |
Extending markdown with components
Because this note is .mdx, every component below is a live import from
docs/atlas/src/components/ — rendered here, not screenshotted. Props are
typechecked at build. The kit is tuned to what docs/plans actually uses.
Inline chips
Small typed references for the prose:
| Component | Live | Usage |
|---|---|---|
<PrLink> — GitHub PR, repo baked in | #1095 | <PrLink pr={1095} /> |
<Issue> — GitHub issue | #951 | <Issue n={951} /> |
<Commit> — short sha → commit | 7ec2566 | <Commit sha="7ec2566a" /> |
<Cite> — a linked file:line (replaces docs/plans’ 110× cite) | docs/atlas/astro.config.mjs:14-19 | <Cite file="…" lines="14-19" /> |
<Kbd> — a keyboard chord | Ctrl +B | <Kbd keys="Ctrl+B" /> |
Block components
<Callout> — a typed box with markdown inside; replaces the old
panel/card divs. kind: note · accent · good · warn · danger. Usage:
<Callout kind="warn" title="…">body</Callout>.
<Terminal> — a faux transcript. Usage:
<Terminal title="…" lines={["$ cmd", "output"]} />; in lines, $ is a
prompt + command, # a comment, anything else is output.
<AtlasMockup> — a one-off, self-contained HTML + inline-SVG prototype, for
when a note needs something markdown can’t draw:
<Toc> — a nested, auto-inserted table of contents built from the note’s
headings (h3s nest under their h2). The page route renders it (the Contents
box at the top — note how Inline chips and Block components sit under this
section), so notes never import it.
<Roadmap> + <Milestone> — a status-marked roadmap (done ✓ · now ▸ ·
next ○) with rich children. Usage:
<Milestone status="done" label="Shipped">…</Milestone>; see Roadmap
below for the live one.
Bring your own component
A note isn’t limited to the shared kit — but a note-local component lives in
the .mdx itself, never as a separate file. Keeping it inline keeps the note
self-contained; src/components/ is reserved for components reused across
notes. Two ways, both live in this note:
- Inline
export constat the top of the.mdx(JSX rules:style={{…}},className). Defined here asSpark, used live: inline. - Raw inline markup — for a true one-off, drop JSX inline with no named component: raw inline JSX.
Both rebuild with just atlas::build and pass ci::atlas-sync like the kit.
Promotion path: inline → shared kit, once a component proves reused (and
earns scoped styles + typed props as a real .astro).
Navigation — a generated index, grouped by kind
- One section per category — every note’s
kind(bug·feature·analysis·reference) lands it in a section; that’s the index’s primary skeleton. Membership is automatic (a note can never be unfiled); only the edges are authored. parentsnests notes within a section — a note lists one or moreparents(flat slugs) and nests under each same-category parent. A cross-category parent isn’t a tree edge — it’s surfaced as a related link, so topical connections survive without tearing the sections apart. Retires the hand MOC + itsdocs-moclink-gate (gone with the last legacydocs/plans/*.html, migrated 2026-06-09).- Flat, ancestry-free slugs — the filename is a handle, not a path; both category and hierarchy are metadata (
kind,parents), not the filename. - Each row shows a
maturitydot + status flags; drafts are hidden from the build. - A nested ToC (
<Toc>) is auto-inserted from each note’s headings — the box above. - Dead-link checking stays a generic linter, not a bespoke gate.
Proposals — the contributor intake lane
- A proposal is an Atlas note in its real category (
kind:bug/feature/analysis/reference) carryingstatus: proposed— it shows in that category, flagged proposed. There’s no separate proposal kind or section; the status badge is the queue. Contributors open an Atlas PR; the flow lives inCONTRIBUTING.md. - Accepting = a status flip. On acceptance a maintainer sets
status: accepted(thenimplemented); thekindwas right from the start, so nothing moves. The note stays living — git is the record, so there’s no frozen copy and no separate numbered log. proposed → accepted → implemented → supersededis a lifecycle (thestatusfield); supersession links viaparents+ status. Nodocs/proposals/and nodocs/decisions/dir needed.
Roadmap
- Shippedoriginal plans + MOC + house style + the
docs/**agent rule ( #1095 ); thedocs-mocgate +plans::checkmodule ( #1098 ). - Donethe Atlas as a self-contained
docs/atlas/project — generated index, render route, committed HTML,.apmrule +ci::atlas-syncgate, and the MDX component kit. First migrated note; the originalrelease-workflowplan removed (since re-created as the release-runbook note, #1208 ). - Donethe remaining
docs/plans/*.htmlmigrated to Atlas notes (remote-terminals,pty-daemon,pty-daemon-chrome-bar,pty-daemon-tui,surface-app);docs/plans/retired; the/atlasskill shipped.
Revised 2026-06-02: a 7-lane adversarial research pass + Hickey/Lowy/
completeness critics flipped HTML-all-the-way → markdown-first and kept the
numbered proposal log; then Astro was chosen for rendering, the Atlas extracted
into a self-contained docs/atlas/ project, and notes moved to MDX with a typed
component kit.