Decision records¶
This is where the why behind non-obvious choices lives. It is historical context, not the product contract and not a backlog:
- current behaviour lives in the topic pages linked from the documentation index;
- planned work, bugs and delivery status live in GitHub issues;
- completed user-visible work is summarised by releases and
CHANGELOG.md.
One decision is one file, docs/decisions/D<n>-<slug>.md, and the list below
is generated from those files. Reading one costs the one file, not the register it
used to live in — the ten thematic registers this replaced held 197 records in
483 KB, so answering "why is it like this?" meant loading up to 101 KB to reach a
single paragraph.
Referring to a decision¶
In code comments and in prose the reference is the bare D<n>, with no path:
ls docs/decisions/D47-* # resolve it
rg -l 'D47' --type go # who mentions it
It costs fewer tokens than a path, and it does not break when a title is reworded. In markdown, use a real link — the test suite checks that every one of them resolves.
Adding a decision¶
-
Only for an architectural or contract choice — an invariant, an interface, an alternative a reader would otherwise re-propose. Smaller choices live in the plan issue and the PR that closes it. The number is the plan issue's, or the PR's when there is no plan (D672): nothing to reserve, and parallel sessions cannot collide. Records up to D371 were numbered sequentially; the numbers between the last of them and the first issue-numbered record are simply unused.
-
Write it at the end of implementation, not before. The plan issue is the draft; the decision file records what was actually built, including any deviation from the plan.
make decisions-new N=<issue> SLUG=my-choice TOPIC=control-plane
-
Record the decision, the rationale, and the consequences — including the uncomfortable ones. Alternatives that were considered and rejected are the part a reader six months from now actually needs. Current behaviour goes in the corresponding topic page, future work in a GitHub issue.
-
Do not regenerate the index in the same PR: the list below is regenerated on the release PR, which CI checks strictly (D328). Parallel PRs that each rewrote it conflicted with every merge.
make decisions-indexstill regenerates it locally when you want to read it current. CI fails on a file that still carries a placeholder from the template — a half-written record indexes as a blank entry, because angle brackets around a word render as an HTML tag.
Do not add status tables, milestone lists or duplicate entries. A decision has exactly one file; other pages link to it.
Numbers that have no file¶
Every D<n> written anywhere in the repository has to resolve, and make test
checks it (D208). Three states are legitimate, and only the first is a file:
| State | Where it is declared | Meaning |
|---|---|---|
| implemented | docs/decisions/D<n>-<slug>.md |
the record |
| gap | repodocs.GapDecisions, with a reason |
deliberately never written; the number must not be reused, and a file claiming it fails the build |
| reserved | repodocs.ReservedDecisions, with the plan issue |
an open plan holds it; the record arrives with the implementation, and the entry is then removed |
A plan abandoned without implementing does not stay reserved: either it gets a record saying it was not done — D130 is the worked example — or, if nothing depends on the number, it becomes a gap.
All decisions¶
529 records, one file each, grouped by the topic they belong to.
In code and in prose the reference is the bare D<n>, with no path: resolve it
with ls docs/decisions/D<n>-*. Add one with make decisions-new, then
regenerate this list with make decisions-index.
Cross-cutting architecture¶
- AD1–AD13 — Original architecture
- D219 — Windows has no execute bit, and a KB path is a slash path
- D233 — The Atlas wears the Cartographer brand
- D234 — The 3D atlas is a living elastic network
- D235 — The Atlas draws its graph only in 3D
- D238 — The Atlas UI shows a KB's artifacts in their own panel
- D239 — The reading panel is resized by a splitter over the graph
- D240 — A selection hidden by a filter stays selected, the graph draws none
- D244 — server-side importance and communities
- D281 — The reading panel stops growing at its prose measure
- D286 — The Atlas answers the reader's questions with the agents' own tools, and draws artifacts beside concepts
- D317 — communities discount boilerplate links, anchor on internal ties, and link_suggest falls back to the title for an orphan
- D818 — The Atlas surfaces the server's features in six places, and the client reports its own settings
- D820 — The Atlas shows what was retired, read from the root log, as a tab of Activity
- D888 — One motion scale for the Atlas, CSS and JavaScript alike
- D889 — The graph draws on demand, and a network too costly to tick rests its drift
- D1032 — The dev test KBs take the shape of measured real KBs, with invented content
- D1044 — A live instance shows this machine's real client, and the graph's drift slows instead of resting
- D1146 — Retirements are rows of the Activity timeline, not a tab of their own
KB model and imports¶
- D5 — Normalized content-hash
- D8 — Frontmatter: stdlib-only YAML parser
- D9 — Canonical ordering + SectionHashes
- D13 — Graph neighbors: standard markdown links
- D15 — Secret scrubbing: blocking regex, 6 patterns ✅ Removed
- D19 — Agent contract: AGENTS.md generated by Init
- D22 — Event-driven exporter: HTTP webhook + Go worker pool ✅ Removed
- D25 — KB layout:
data/conceptual root,services/carve-out inResolvePath - D28 — Removal of
raw/,mcp/,source_ingest,scrub,exporter(June 2026) - D62 — KB repo cleanup: no generated AGENTS.md/.gitignore, exclude via .git/info/exclude (WP6)
- D72 — KB refactoring ergonomics: backlink rewrite and batch in
concept_move, consistent index, inventory, explicit dossiers - D74 — Import of external non-OKF wikis/KBs:
kb-importskill + CLI scaffold + lint-driven curation - D77 — Atlas/Map/Journal hierarchy: the dossier becomes a state of the concept
- D87 — Fence-aware heading detection: shared line iterator for
ListHeadings/ExtractSection/SectionHashes - D91 — Import convenience without widening the default write surface
- D106 — Concept-owned non-Markdown assets
- D107 — Declarative lint contracts in map descriptors
- D109 — KB-owned concept templates and one-shot scaffolding
- D124 —
machine_pathdistinguishes client-local paths from a Map's operational target paths - D125 — Atomic multi-concept mutation batches:
concept_batch - D150 — What counts as a link: code fences, labelled wiki-links, extensionless assets
- D159 — Per-concept lint opt-out, home-anchored allow prefixes, related size thresholds
- D160 — Complete the concept refactor primitives: move, merge, collapse
- D162 — Authoring and ingestion papercuts: frontmatter, placeholders, repo scan, import mapping
- D241 — The link graph is a stat-validated in-memory cache
- D248 — Backlink rewrite follows the graph
- D269 — Reserve the services namespace and make concept moves namespace-aware
- D270 — Assets above 10 MiB are not versioned, and the asset listing survives stray files
- D273 — Knowledge gaps are Contradiction concepts with a reserved, non-blocking kind
- D275 — a map contract can constrain field values and forbid fields
- D276 — A KB glossary expands search and flags forbidden terms
- D277 — Asset text is searchable through its owner concept
- D278 — A source ledger of
Sourceconcepts revisits D28's removal of source ingestion - D289 — lint checks a KB against the current standard, not only against its own contracts
- D295 — Lint findings are executable on real KBs
- D296 — A KB's values converge on its own vocabulary
- D297 — Lint sees a KB decay
- D301 — A KB stays cheap to read and to maintain
- D304 — Map titles are reviewed as one set, and renamed through map_update
- D305 — A doctor session can be delegated, and the review groups a shared origin
- D306 — Every finding is fixed or accepted, and a map accepts a style once
- D307 — A duplicated "See also" link goes, and lint stops raising non-questions
- D309 — Writes never corrupt frontmatter or drop graph edges
- D310 — A link to an expanded concept's index.md is the concept, normalised in the graph
- D313 — Every finding can be accepted; structural checks stop flagging structure
- D314 — Broken shapes and template boilerplate are detected
- D315 — Page names are linted: title and heading agree, titles are labels, map titles are short
- D321 —
activemeans the page is valid, everywhere; waiting work is declared - D322 —
archivedis a reserved status: closed journal entries are harvested, then leave the active surface - D332 — Artifact findings are accepted with
lint_acceptininstructions.md, keyed by path - D336 — The doctor is called until the Observatory is empty; a new artifact is not "never used"
- D346 — A map that holds work is stale after 30 days by default
- D347 — A journal's open state can come from a contract field, not only from
status - D352 — Every page follows a template its map allows
- D354 — Lint checks are declared in one registry, and every table about them is derived
- D355 — Unattended repairs run to a per-concept fixpoint, in two stages
- D356 — Invalid pages are repairable
- D357 — The drift audit closes the blind spots
- D366 — Three doctor-only checks gain their mechanical part, and join the default auto-repair
- D371 — Every check is active by default; one that cannot run says why
- D688 — unknown_type is info outside the maps that adopted types
- D715 — concept_new template variables accept lists, only as whole values
- D746 — A KB carries its own policy in
settings.yaml, and it wins over the server - D775 — A KB's policy is one immutable snapshot replaced whole, read through one accessor
- D826 — a retired concept in a live map gets no index or orphan instruction
- D827 — A links section ends at the next heading of any level, and its repair keeps a heading the template requires
- D834 — The suppression inventory counts in lint and reads its dates from git
- D853 — Types the server keys on are known to
unknown_type - D1025 — Concept paths refuse symlinks, and lint reports them
- D1043 — Unused skills and agents are a lint problem
- D1195 — A page marked
origin: externalskips the content checks; remote shell blocks skipmachine_path - D1313 — A nested frontmatter value is refused, never written as text
MCP tools, search and lint¶
- D3 — SQLite:
modernc.org/sqliteplanned, not yet introduced - D10 —
concept_write: frontmatter from JSON map - D12 — Keyword search: pure-Go inverted index
- D14 — Lint: deterministic checks only in the Core
- D20 — Embedding: interface + Ollama adapter, wired
- D24 — Automatic keyword index update after
concept_write - D32 — Search index persisted on SQLite (
internal/sqlindex) - D36 — mcpserver: unified
Depsregistration, split per domain, shared index - D43 — Automatic SQLite index rebuild at startup if empty, without embedding
- D65 — "agent" tool profile and compact instructions: less fixed context per session
- D66 —
kb_overviewcounts concepts, not subdirectories - D67 —
concept_deleteMCP tool - D70 — Incremental update ergonomics:
concept_patch+ snippets insearchresults - D71 — MCP tools for provisioning artifacts:
artifact_read/artifact_write/artifact_list/artifact_delete - D78 — Readable per-path log,
concept_readwith size guard and outline,concept_oversizelint - D88 — Frontmatter unset in
concept_patch,map_deletetool - D89 — Multi-term search fallback and coherent search modes
- D90 — Content-hash reconciliation for derived search indexes
- D108 — On-demand backlinks and frontmatter facets
- D122 — Bounded curated-index read/patch:
index_get(with_hash)+index_patch - D123 — Expose read-only governance tools to descriptor-bound agents
- D131 —
kb_status:by_statusroll-up excludes unset status - D135 — Remove semantic search and the Ollama embedding backend
- D136 —
index_rebuildis consolidated intoreindex - D149 — One link base and one concept resolver for lint
- D151 — A KB's capabilities and mount provenance are visible from a session
- D161 — Every enforced limit and contract stated in its own tool description
- D165 —
searchscope is a literal prefix on both backends - D185 — The read path stops sending the same bytes twice
- D186 — A gate reports what can act on the verdict, not the whole archive
- D226 — Typed read projections and a read-only UI API
- D229 — A map contract can change after creation
- D242 — Graph retrieval tools: graph_context, link_suggest, graph_path
- D243 — Structural lint and supersede relations
- D245 — Search indexes follow the files
- D246 — Search weights titles and folds diacritics
- D247 — Search misses reveal knowledge gaps
- D249 — graph_neighbors on the visible graph
- D250 — changes_since reports link changes
- D251 — search uses centrality as a prior
- D271 —
concept_deleterefuses to break inbound links unlessforceis set - D285 — Tool descriptions have a size budget, enforced by a test
- D287 — A trailing links section is hidden by the Atlas, never flagged as such; its duplicates and bare lists are
- D290 — Drifted KBs are repaired by an explicit tool call, and
kb_statussignals when to - D294 — lint and kb_status stay fast on real KBs
- D298 — The server builds the doctor's work list
- D299 — A KB is kept by a budgeted loop the server proposes
- D302 — Work is a view over open states and unchecked items, not a type
- D312 — a write answers with the structural findings it caused, from a scoped lint
- D316 — Lint covers the KB's artifacts, not only its concepts
- D318 — The tools an agent is told to call are listed, and their answers parse
- D319 — Search misses close by themselves
- D323 — The server applies the safe repairs by itself; a person is asked only what needs one
- D324 — lint filters by check and paginates
- D325 — Out of the box, what keeps a KB healthy is on: new maps demand index entries, a fresh install keeps an audit log that rotates, a client with no reliable hook gets its sync timer, a new KB gets an
instructions.md - D326 — Skill and artifact usage is measured by the client from its own transcripts
- D331 —
kb_status.conformancecounts every repairable finding, beside the conformance-onlyfixable - D337 — The Atlas follows the KB by polling a revision
- D338 — Health merges the Observatory and Maintenance panels
- D339 — The reading panels share one page kit
- D340 — The dark theme sits on neutral graphite
- D342 — Lists are appended and removed server side; a silent shrink is flagged
- D343 — MCP denials name a reason, reads expose the vocabularies, search rescues thin AND results
- D344 —
concept_archiveretires a page in one commit, and a lint check catches the hand-made retirement - D345 — kb_review ignores series pages and historical links
- D349 — A write repairs the mechanical findings of the concepts it wrote
- D350 — An opt-in write gate refuses, and rolls back, a write that introduces findings
- D351 — A write answers with the fact lines it added that other concepts already carry
- D358 — The kb-doctor session runs unattended by default
- D365 — Health says who acts on each finding
- D367 — The growth replay reads each concept's birth from git
- D368 —
changes_sincetells content changes from the server's upkeep - D370 — The server keeps one lint sample a day, and Health draws the trend
- D677 — The growth replay exports as a browser-recorded video
- D691 — The growth video is rendered offline, at 60 fps, in the background
- D704 — An agent works on a KB only when the operator asks
- D708 — The Atlas opens sops secrets in the browser, never on the server
- D712 — Open agent sessions learn of a new KB through a stateless routed notice
- D713 — kb_status reports behind, last push and last sync-in
- D714 —
index_entryon creation adds a curated index entry, atomically inconcept_batch - D716 — map_oversize is reported on the write that crosses the threshold
- D720 — Indexes, Sources and proposals hold up on a large imported KB
- D721 — A write says what lint will flag and where the commit is
- D736 — A large KB is linted on every core, read once per request burst, and drawn at a fixed rate
- D759 —
concept_expandleaves a dangling asset link as written - D760 —
concept_transferis a new tool that moves concepts between KBs under both git locks, target first - D762 —
map_deletetakesforceto remove loose non-Markdown files, not a deleting lint repair - D778 — A search hit is surfaced, not read: only
concept_readstamps a read - D779 — Search hits carry their size, and a scope that matches nothing is refused
- D781 —
searchoffers arelatedblock from the link graph, on by default, off withrelated: 0 - D782 —
artifact_movemoves artifacts between KBs on the two-KB transaction of D760, as a sibling tool - D830 — concept_new renders a template's fenced sample and defaults
{{timestamp}}to today - D835 — The read tools answer three follow-ups in the first call
- D841 —
lintfolds its output with onedigestenum, not three parameters - D854 — A pair linked both ways is not a duplicate candidate
- D883 —
concept_archiverefuses a superseded page - D907 — The lint cannot be escaped: a write never introduces an avoidable finding, and nothing hides one
- D947 — The lint has no severity: every finding is a problem
- D948 — Each Atlas page answers one question: Health what is wrong, Work what waits for a person
- D1006 — Darwin
service statusreads the job state, not just its registration - D1014 — Windows
service statusreads the scheduled task state, not just its registration - D1023 — The client refuses a cleartext, non-loopback server URL
- D1069 — Lint checks for undated waits, retired supersession links and missing digests
- D1072 — source_register provides the source template
- D1078 — Review kinds for unpromoted lessons and unclassified index entries
- D1097 —
initializecarries the operating guide; a provisioned client marks itself - D1099 — The only live page of an archive is no orphan, and
concept_writetakesindex_entry - D1100 — kb_guide serves the operating guide and the bundled procedures
- D1101 — Operator-directed text follows the connection kind
- D1110 —
instructions.mdis capped at 64 KiB where it is read, andartifact_writerefuses more - D1184 —
?access=read-min: a minimal read-only tool profile - D1185 — Tool results are lighter by default: compact JSON,
searchlimit 8 and norelated, nofrontmatter_raw - D1191 — An agent with rw scope can add a secret to a KB
- D1196 — A template proposal can be adopted: open bodies, standard fields, one item per map
- D1197 — facet_sprawl proposes a closed tags vocabulary that map_update and kb_repair apply
- D1202 — A credential pasted into a concept is refused at write
- D1207 — Search names the section that matched
- D1276 — A concept file is capped at 1 MiB, and the write-time fact lookup asks the index for ids only
- D1278 — Secret references: names restrict, errors carry no server path, a broken reference is refused at write
- D1279 — A tool argument the schema does not declare is JSON-RPC -32602, checked after authorization
- D1280 — Concept IDs are canonical when they are written
- D1298 — stdio answers a bad line with a JSON-RPC error and keeps the session, through the classifier HTTP uses
- D1303 — A malformed or unknown top-level tools/call is -32602; a sibling's refusal stays a result
- D1305 —
kb_status.connection.hintis optional, andstatushas astartingstate - D1314 — One strict-type rule on every write tool: refuse an introduced undeclared type, never a type kept
- D1327 —
concept_batchgainsdelete; a list in a result is[], nevernull
HTTP, stdio and authorization¶
- D2 — Hand-rolled MCP stdio transport (no SDK)
- D16 — HTTP transport: hand-rolled Streamable HTTP
- D17 — Multi-KB: routing via query parameter
- D18 — Audit log: JSONL hash-chain with opt-in Ed25519 signature (compliance-grade)
- D44 — Structured tokens with per-KB scopes + per-KB identity/SOPS fields
- D45 — Per-KB r/rw scope enforcement: scoped
TokenStore+ body-peek HTTP guard + fail-closed read-only classification - D102 — Opt-in per-KB MCP tool-name prefix
- D118 — Fine-grained RBAC and permission-aware retrieval
- D119 — Operational audit: attempt/completion pairs, checkpointed retention, offline verification
- D120 — Tool-prefix discovery for client-owned multi-KB operations
- D128 — Serve the 2026-07-28 revision alongside the handshake era
- D129 — Report the protocol era and client identity of connected clients
- D130 — The handshake era is not retired: the plan was overtaken by D168
- D132 — Audit authorization denials; serve RFC 9728 metadata; drop the unwired HTTP handler layer
- D133 — The version header selects the era by value, not by presence
- D144 — The D102 tool-prefix mitigation reaches the agent
- D152 — Tool-prefix uniqueness is enforced, and the client warning reads the prefixes
- D153 — A tool prefix is the default for every mounted KB
- D166 — HTTP connection timeouts, and deleting three unreachable entry points
- D168 — The MCP wire format comes from the official SDK
- D179 — Invalid auth configuration fails startup instead of widening access
- D187 — One tool surface for a multi-KB server: a routed mount with the KB as an argument
- D200 — A POST's
Acceptheader is supplied, not enforced - D210 —
Mcp-Protocol-Versionis stripped on notifications - D288 — One routed topology for agent clients: the binding in the URL, tools never prefixed
- D341 — A token may name the git author of its writes
- D756 — A routed
?kbs=serves the mounted subset and reports the unknown names - D772 — A routed
?kbs=follows a renamed KB throughkb_aliases - D1096 — The routed surface and /health follow the caller's token
- D1183 — The routed
kbargument is a required string, not an enum
Commits, synchronization and conflicts¶
- D30 — Git commit per logical operation (Step 1: local commit)
- D31 — Rebase conflict handling: unversioned side registry +
degradedmarker + guided skill - D33 — Git Step 4: record→finalize conflict resolution, per-content merge
- D46 — Per-KB git identity (author/committer + SSH): per-KB env wins over the process, default committer = author
- D76 — Write-path latency: batch patch, sync coalescing, asynchronous push
- D93 — Read-path Git freshness
- D94 — Git-history changes digest
- D103 — Observable replication failures and native Git identity fallback
- D117 — Server Git profile uses a dedicated working branch and GitHub PR boundary
- D145 —
kb_statusstates the replication facts; the workflow field is named for what it means - D155 — Surviving an external process writing into a synced KB
- D164 — The search read lock spans the query, not the pointer load
- D167 — The push force flag is cleared when a push ends, not only when one starts
- D215 — The per-KB lock splits by platform, and Windows becomes a CI gate
- D237 — A bounded fetch, and a read backoff, for a remote that does not answer
- D258 — Reads refresh in the background, and never wait for the remote
- D264 — KB writes follow the remote default branch
- D265 — The author is the committer when git has none
- D272 — Writes carry an optional reason, stored as a
Reason:commit trailer - D274 — Per-concept history is a read-only tool, and
concept_readtakes a commitrev - D311 — The server settles reserved-file conflicts itself, and a write survives a failed fetch on a current base
- D335 — KB writes follow a configured branch
- D718 — Commits carry an
Agent:trailer naming the calling MCP client - D903 — Git has one way to write, on any provider, and old settings files are realigned
- D904 — The writer is the author of a commit, the server its committer, the token a trailer
- D950 — The writer commits: author and committer are the same identity, and the server file names it per KB
- D1004 — Git never prompts, and a push is bounded
- D1063 — An identity refusal is its own error, and unpushed commits are re-authored by an offline operator command
- D1093 — A server can override the KB's branch for itself, and a clean clone follows the effective branch
Skills, services and secrets¶
- D26 — Bundled skills embedded in the binary
- D47 — Per-KB SOPS:
AgeKeyEnv(env wins), flatservice_get(resolve_secrets), resolve requires rw - D96 — Operations knowledge ships as a bundled skill
- D104 — Structured SOPS pointers, scoped refs and encrypted-only writes
- D158 —
Serviceis matched case-insensitively, andsecret_resolveredacts by default - D191 — One skill validator, for the MCP channel and the git one
- D196 — The onboarding skills route to references for artifact authoring and the encryption flow
- D212 — A skill's frontmatter is validated with the parser a client uses, not with ours
- D260 — sops runs in a hermetic environment: allowlisted variables, an empty home, the per-KB key file
- D261 — service_get redacts resolved secrets unless reveal, and the audit records reveal
- D279 — One generic
kb-ingestskill ingests any primary source, patching over creating - D958 — The bundled skills take the
cartographer-prefix, and the old names keep working
Provisioned artifacts¶
- D27 — Client synchronization: manifest+revision, lockfile, layered triggers
- D34 — Synchronization: Layer 3 push over stdio + codex/kiro materialization
- D40 —
sync_pulland client-side trust; anti path-traversal guard inprovisioning.Apply - D48 — Provisioning extended to
kind: agent/hook; hooks without auto-merge intosettings.json; per-kind counts - D50 — Honest per-provider sync state:
unsupported≠needs_approval,InSyncrequires zero differences - D54 — Per-server trust persisted at
connect(replaces the recurring--auto-trustgate) - D55 — Agents also materialized on OpenCode, via frontmatter translation
- D56 —
instructionskind: KB imprinting via managed block in the global instruction files - D57 — Claude Code hooks: automatic registration in
settings.json - D58 — Real Codex CLI integration: managed-block
config.toml, TOML agents, hook engine - D59 — OpenCode hooks: generated JS plugin
- D60 — Client-side bootstrap hook: auto-sync at session start (WP4)
- D61 — Instructions: auto-generated agents section + curated
instructions.md(WP5) - D69 —
kind: mcpprovisioning: third-party MCP servers distributed by the KBs - D75 — Path portability across machines: placeholders auto-resolved via git remote
- D105 — Binary-safe provisioning artifacts and executable KB scripts
- D114 — Verify provisioning artifacts cryptographically
- D115 — MCP allow-list and hash-bound local approval
- D116 — Trusted stdio MCP descriptors with environment references
- D138 — Provenance stamp on materialized skills and agents, and two hashes per managed file
- D139 — On-disk verification: sync restores what diverged locally
- D140 — A scheduled sync trigger for clients with no session hook; Kiro has no registrable one
- D148 — Provisioning refuses a symlinked destination
- D154 — The generated steering block describes what this client received
- D170 — Selection before the merge: each provider is projected only its bound KBs
- D171 — A cross-KB collision is an error, not an alphabetical tie-break
- D172 — Sync ordering, per-provider checkpoints, and a client lock
- D178 — A file dropped from an artifact is removed with it, not stranded
- D181 — A cached repo path is validated before use, and a change of roots invalidates the cache
- D182 — Attribute and order the per-KB instruction sections
- D183 — Keyed session-global directives make a cross-KB prose conflict detectable
- D184 —
syncreports the revision each provider recorded, not the one it fetched - D193 — Workspace-scoped artifact projection: one provider, different KBs per repository
- D195 — Kiro receives subagents; its hooks are documented but not shipped
- D216 — The client half reaches parity on Windows, and the executable flag becomes lockfile state
- D230 — Codex hooks register in hooks.json
- D231 — Local clients get the loopback literal
- D236 — A Codex hook registration left in config.toml is drift
- D256 — The client pulls the KBs' manifests concurrently, and reports errors in KB order
- D257 — Sync continues past a KB that cannot be pulled
- D262 — Path placeholders are visible, fully resolved and onboarded
- D263 — A KB declares its path placeholder registry
- D267 — Hook commands bound for a POSIX shell use forward slashes on Windows, and one that cannot run is drift
- D282 — A key absent on this machine is ignored by name, and a sync warns in one line
- D283 — A dropped
toolsallow-list is reported, and an agent can opt out of being widened - D284 —
hook.jsonis validated against one declared event vocabulary, on write, at sync and in lint - D291 — An agent can carry each client's own restriction, verbatim
- D293 — A project CLAUDE.md written by sync imports AGENTS.md
- D300 — Kiro gets a session-start hook through a standalone file Cartographer owns, limited to the V3 TUI
- D320 — Upgrades and client provisioning tell the user what changed
- D353 — write findings reach the agent through a client-generated hook
- D359 — The OpenCode hook plugin is generated in the shape of the installed major
- D360 — OpenCode global skills and agents live in its config directory, and a moved destination relocates on sync
- D361 — Codex gets the write-findings hook, through
additionalContexton stdout - D362 — OpenCode 2.x gets the write-findings hook through a dedicated plugin
- D363 — Crush gets PreToolUse hooks and project mcp/hook cells
- D364 — Antigravity and Hermes get project-local cells; co-owned paths survive a prune
- D717 — A workspace projection writes Cartographer's own MCP entry, restricted to its KBs
- D719 — An unreadable OpenCode version writes the newest plugin shape, with a warning
- D737 — A workspace binding scopes the tools through a local stdio bridge
- D780 —
graph_contextis named where agents choose their tools, not fused intosearch - D864 — The Artifacts page lists every kind a KB can hold, from one list in provisioning
- D1007 — Antigravity receives SessionStart native hook and session bootstrap parity
- D1011 — status judges a workspace-scoped provider projection by projection
- D1018 — A folder under no workspace binding is served read-only
- D1019 — A repository a KB declares is bound to it
- D1057 — The Artifacts section is four tabs: agent kit, instructions, templates, secrets
- D1141 — What a KB runs on the machine is installed only after an approval
- D1166 — The first sync approves what a client already runs, unchanged
- D1172 — OpenCode's global MCP entry lives in its config directory
- D1181 — A workspace projection owns its artifacts, not the whole directory
- D1182 — The managed instructions block is brief by default
- D1198 — A derived binding registers Claude Code hooks in settings.local.json
- D1246 — The routed
kbclause of the routing sentence is short - D1325 — The server builds KB artifacts only from files git tracks
CLI, TUI and providers¶
- D23 — Multi-provider configurator: CLI flags + per-provider JSON adapters, non-destructive merge
- D29 — OpenCode format aligned to the official schema +
kb.Initcreates the git repo - D35 — Configurator: opt-in interactive TUI (
--tui) - D37 — Single binary with subcommands; client always HTTP (no stdio/
--check/--base-dir) - D42 —
cartographer disconnect: inverse ofconnect, inverse JSON merge, full provider prune - D49 — Interactive
cartographer connect: bubbletea form shared TUI/CLI - D51 — MCP server name fixed to "cartographer"; auto-trust hint with the exact command
- D52 —
.cartographer.yamlalways machine-wide (home): project/global scope removed - D63 — Complete prune: empty directories with boundaries, MCP configs reduced to empty (WP7)
- D64 — Connect UX: per-field hints, retry with populated form, persistent default, pre-connect probe (WP8)
- D86 — Connect UX: agent subsets, 0-KB diagnostics, absolute paths
- D92 — Per-KB MCP entries for multi-KB servers
- D99 — Codex's
config.toml: comment markers are not enough, orphaned tables are adopted - D113 — One client status snapshot across CLI and dashboard
- D126 — Codex's
config.toml: foreign tables written inside a managed block are relocated, not lost - D127 — Codex hook adoption also matches on the decoded command value
- D137 — Declarative provider registry: two tables, owned by the packages that own the concepts
- D141 — Hermes is a supported provider that receives deliveries, not installations
- D142 —
reconnect: rebuild a client configuration, never automatically - D143 —
doctor: a separate command that diagnoses and never repairs - D146 — Existence and content are verified with different evidence
- D147 — Every reported write is observed, never intended
- D157 — Backfill managed-file hashes in place instead of rebuilding every client
- D169 — Per-provider KB binding: a user-owned preference beside a server-owned cache
- D175 — The dashboard is binding-aware, and says when it does not know
- D180 — Every typed client-config field is written by
Save - D189 — Instructions written correctly are not reported as installed until the provider reads them
- D190 — The KBs are chosen before the first write, not narrowed after it
- D194 — Support Google Antigravity in multi-provider client and provisioning
- D201 — A provider's tool identifier limit is checked at connect and sync
- D220 —
syncstates the server change; onlystatusanddoctorrecommendreconnect - D222 — sync checks the environment once, and a 401 names the variable it read
- D224 — Detection records which heuristic matched, and the evidence is labelled with it
- D225 — Crush is a provider, and the file we write is the deprecated JSON
- D253 —
cartographer setupchains the existing commands, and plans before it changes anything - D254 — Agents are told when Cartographer is out of date
- D369 — A scheduled headless doctor is a client-side opt-in, declared to the server
- D676 — GitHub Copilot CLI is a provider, with a hook file of its own
- D690 — The scheduled doctor is installed by
connect, by default - D699 — Unattended runs read the client token from a private file
- D743 — One settings view with origin, recorded by the loaders
- D747 — One settings schema in code documents both YAML files from inside
- D755 — Claude config dirs are declared, not discovered
- D898 — Hermes support is removed, with the mechanisms only it used
- D906 — Settings cleanup: one home per key, and no setting that turns a safeguard or a feature off
- D1030 — Antigravity emits canonical "url" key for MCP Streamable HTTP
- D1074 —
workspace bind codex --trustrecords the folder as trusted, on request - D1266 — Client subcommands take the positional anywhere among the flags; an extra one is a usage error
- D1269 — A Claude Code config or settings file is deleted at
{}only if Cartographer created it
Configuration, deployment and releases¶
- D21 — Configuration via environment variables
- D38 — Server configuration via YAML (
internal/config,gopkg.in/yaml.v3) - D39 — Server-side KB bootstrap from git remote (replaces the k8s init container)
- D41 — Direct release+deploy pipeline (least-privilege SA) +
install.shwithout Homebrew - D53 — Explicit KB name (
kbs[].name) + per-KB conventions for the git token (git.token_dir) and SOPS key (sops.age_key_dir) - D68 — Deploy via Flux GitOps,
kubectl applyremoved from CI - D73 — Local mode as a native service (
cartographer service), Docker out of the local deploy - D83 — Service install robustness: create the data dir, tolerate its absence, stable plist binary path
- D84 — Readiness signal and per-KB path routing
- D85 —
kb createand first-KB onboarding: a CLI command, not only the agentic skill - D95 — Upgrade transparency through version-skew hints
- D97 — Agent-driven onboarding mounts remotes through
kb clone - D112 — Reserved local endpoint defaults
- D121 — Native local upgrades repair themselves
- D134 —
kb createrequires a git remote - D156 — Service
PATH,restartafterstop, and akb createthat keeps its scaffold - D173 —
kbcommands: bounded clone, correct local target, read-only list - D174 —
service statusreports observable state, not a verdict on nothing - D176 — The multi-KB readiness path gates on the audit sink too
- D177 —
kb renameis offline, bounded, and says what it does not migrate - D192 — Onboarding and release hygiene: text that lied, hints that could not be run, paths that ended half-done
- D197 — The evaluate-then-install path: steer the agent that is actually reading
- D199 — The Cask's install steps are
postflight_steps; the next sync repairs the service - D211 — The pre-release flag is set by the release job and verified there
- D217 — On Windows the native service is a per-user Scheduled Task, driven by PowerShell
- D218 — winget is the only Windows channel, and its archive is a zip
- D221 — the Kubernetes upgrade step ends on a verified image, not on a rollout
- D223 — the published Windows zip is a documented fallback, not a second channel
- D227 — The embedded Atlas UI
- D252 — Windows installs through install.ps1, not winget
- D255 — CI runs what the change touches
- D266 — A Windows restart waits for the old process to leave its port, and /health names the process
- D268 — The generated config of a loopback service pins
auth.mode: "off", andsetupstops on a 401 beforeconnect - D280 — The Cask caveat names both the first-install and the upgrade next step
- D303 — A preview is an image built on demand, not a pushed tag
- D308 — The Atlas sends same-origin credentials so an SSO proxy can front it
- D333 — An empty usage store says since when, and stays local state
- D348 —
servebinds its port first and bootstraps the KBs behind a gate - D710 —
kb create --remoteadopts a forge's initial commit - D711 —
kb create/kb clonecan record theirkbs[]entry - D745 — The public Atlas demo is a static export of a real server, published with the docs
- D751 — The live MCP demo runs on Cloud Run behind a Cloudflare Worker
- D754 —
kb renamerewrites this machine's client bindings - D761 —
kb unmountparks the clone outside discovery, backs up the config, refuses unpushed work - D789 — The live MCP demo is authless at the edge
- D800 — The demo guestbook is a second KB, written only through an edge-moderated template
- D862 — The Atlas version opens the release history, fetched by the server on demand
- D905 — One credentials directory holds every secret file, and the audit log is always on and signed
- D956 — Releases leave on a weekly train, gated on a tested release candidate
- D989 — The freeze and the release candidate move to Saturday
- D995 — The release candidate is smoked before it is published
- D1022 — Releases carry keyless build provenance and SBOMs, and the installer never skips the manifest
- D1068 — The README film is rendered by the release candidate, and a failed render blocks the train
- D1071 —
kb createreplaces a forge's boilerplate README - D1123 — The release train merges only when the security gate is clear
- D1168 — A candidate built from the current main is kept by the Saturday run
- D1180 — Dependabot waits out the freeze; the open PRs are armed after the train
- D1192 — The train leaves on Thursday, and its release candidate ships binaries
- D1321 — upgrade-repair switches the service definition to the running binary
Repository and documentation policy¶
- D1 — Stdlib-only constraint ✅ removed
- D79 — Open source release: Apache-2.0, GitHub, release-please, GoReleaser, ghcr, Homebrew tap
- D80 — Versioning reset to 0.x: the public line starts at v0.1.0
- D81 — Agent-neutral workflow: AGENTS.md canonical, plans as GitHub issues
- D82 — Beta marking via GitHub pre-release flag, not
-betaversion suffix - D98 — Planned work lives in GitHub issues, not in the docs
- D100 — Community surfaces: Pages from
docs/, Discussions on, Wiki off - D101 — Tool names in the docs are CI-enforced
- D110 — Topic-owned decision records and GitHub-owned project state
- D111 — Repository E2E tests are deterministic and model-free
- D188 — Retired without ever being written
- D198 — No recorded demo in the README
- D202 — One file per decision, with a generated flat index
- D203 — AGENTS.md is the canonical instruction file, and a skill exists once
- D204 — The documentation gates are Go tests inside
make test - D205 — The code map is generated from the package doc comments
- D206 — D163 was a copied off-by-one, not a missing record
- D207 — A claim about a client comes from the provider matrix, and a skill is parsed the way a client parses it
- D208 — A reference is checked wherever it can live, and a decision number has three states
- D209 — The gate is one command, CI runs that command, and a budget measures what the author controls
- D213 — Every AGENTS.md gets a one-line CLAUDE.md import beside it
- D214 — AGENTS.md follows one skeleton, and a trap is fixed where it bites
- D228 — Browser-level verification of the Atlas UI
- D232 — Coordinate is the mark, Rilievo a motif
- D259 — Published text carries no private names
- D292 — A harness ledger and a re-alignment procedure, not automated version polling
- D327 — The plan-implementer subagent is a thin per-client wrapper over the implement-issue skill
- D328 — Feature PRs skip the Windows leg and the decision index; the release PR carries both
- D329 — Dependabot's patch and minor rounds merge themselves; auto-merge is on
- D330 — The README shows a recorded Atlas tour again, filmed by a test
- D672 — CI gates what it merges, and a decision takes its issue's number
- D703 — A change found by trying it lands from a live session, without a plan issue
- D785 — CI splits its slow legs across runners
- D786 — The git-backed test packages run their tests in parallel
- D790 — The README hero is re-recorded by CI on an orphan branch
- D807 — A launch film on the Atlas engine leads the README
- D812 — A test KB is a copy of a template, built once per test binary
- D856 — A pull request is shaped to be cheap to review
- D857 — Reviews converge, and supply-chain files always get a full review
- D858 — Implementation PRs are reviewed by
pr-reviewerbefore the coordinator reads them - D859 — Full-tier PRs get a separate security-reviewer pass
- D860 — A defect that escapes review becomes an eval case for the reviewers
- D865 — The release changelog is grouped by area, in a post-processing step on the release PR
- D884 — Cartographer is developed with Claude Code, Kiro, OpenCode and Copilot CLI, on Claude models, with five subagents
- D955 — Contributor and maintainer roles: the approved-plan rule is enforced in CI
- D957 — The repository's skills and agents take the
cartographer-prefix and pair by name - D987 — Only the next train's work merges, and every accepted issue has a milestone
- D992 — This repository is developed with Claude Code only
- D994 — CI path filters are a tested table, and nothing runs twice
- D996 — Forge rules are tested where they bite
- D997 — macOS is tested on a real runner when it can break
- D1020 — Security scans run in their own workflow and are not required checks
- D1058 — A PR assigned to its author claims the plan
- D1124 — A reference is also checked down to its section, its fragment and its cross-list
- D1125 — The tool table is checked against the registry
- D1126 — The environment table and variable names are CI-checked
- D1127 — A doc-owner map warns when a page is left untouched
- D1128 — Current-state docs are checked for history phrases and hand-kept counts