Cartographer · the map itself
Thirty-four nouns. Five of them are ghosts.
This is a real map of a real runtime: a three-box home-lab fleet, aliased, nothing staged. The constellation is the first walk (nine nouns); the full 34-card catalog and two unedited cards are below. Click a star. Read its card. Stop. That last part is the whole product.
Why a map and not a README
A cold reader (usually a model with no memory) was going to load this whole tree to change one thing. One session did exactly that: it edited a frozen locks file that looked live, and the nightly sync made the mistake permanent on two more boxes.
The map fixes the loading, not the reader. The catalog is small on purpose. Each card says what the thing is, what else moves if you touch it (Hits), and the obvious neighbour that is the wrong one (Does not hit). Ghost cards list the wiring the cartographer looked for and did not find. A name on a file is never evidence of life.
One rule: load the catalog, then one card. Never the whole cards folder, never the source tree.
The full map · verbatim from the public repo
Thirty-four cards. Five ghosts. One collision.
The constellation above is the first walk (08-16). The full pass (08-29) is below: every line is a real card in
map/, checked by verify-map.mjs (34 examined, 0 findings). Names and paths are aliased; the wiring is real.
| noun | status | one line | card |
|---|---|---|---|
| lane-store | live | lanes.json, sole writer lanes.mjs CLI | cards/lane-store.md |
| worker-queues | live* | 30+ comms/<id>/inbox dirs; consumers vary | cards/worker-queues.md |
| outputs-shelf | live | 2,831 dated deliverable dirs; not a queue | cards/outputs-shelf.md |
| vault | live | long memory; writers = nightly archiver + indexer | cards/vault.md |
| skills-shelf | live | 133 entries; two LaunchAgents run from inside it | cards/skills-shelf.md |
| reference-shelf | live | canon + hourly GENERATED STATE.md | cards/reference-shelf.md |
| shadow-tree/ | leftover | retired tree, 4 LIVE services still inside | cards/shadow-tree.md |
| session-inbox-executor | live | flat comms/inbox, 300s, the one verified consumer | cards/session-inbox-executor.md |
| steer-listener | live | 30s poll of a steer file → dispatcher queue | cards/steer-listener.md |
| dispatch-watcher | ghost | self-disabled 08-15, re-struck 08-23; dispatcher deaf | cards/dispatch-watcher.md |
| notify-relay | ghost | :8793 dead; publish gates stage-only | cards/notify-relay.md |
| session-relay | ghost | broker not running; helpers write to nothing | cards/session-relay.md |
| remote-dispatch-watch | live | 20-min read-only check of one box-B dispatch | cards/remote-dispatch-watch.md |
| sync-legs | live | 3 legs, box B→A leg absent by gap | cards/sync-legs.md |
| edge-tunnel | live | boundary: box A → edge provider, inbound HTTP only | cards/edge-tunnel.md |
| local-servers | live | :8790 review + :3121/:3122 boards, loopback | cards/local-servers.md |
| speech-server | live | speech-to-text on the mesh address :8990 | cards/speech-server.md |
| local-model-host | live | boundary: model server :11434; no proxy running | cards/local-model-host.md |
| agent-observer | live | subagent transcript sidecars; fork-cap | cards/agent-observer.md |
| stall-watchdog | live | 120s idle-transcript notifier | cards/stall-watchdog.md |
| closeout-hooks | live | per-session deliverable ledger via tool hooks | cards/closeout-hooks.md |
| session-archive | live | 02:17 nightly transcript → vault notes | cards/session-archive.md |
| checkpoint-daemon | ghost | last checkpoint 04-09; ops doc still names it | cards/checkpoint-daemon.md |
| overnight-council | live | local-model nightly audit; 08-29 round FAILED | cards/overnight-council.md |
| news-digest | live | twice-daily digest; send half failing 08-29 | cards/news-digest.md |
| screen-audit | live | 5s capture loop; PAUSED marker present 08-29 | cards/screen-audit.md |
| mailer-guard | live | 300s mailer pass, 12-strike self-disable | cards/mailer-guard.md |
| mail-watch | live | 60s inbound-mail lure scan (via legacy root alias) | cards/mail-watch.md |
| community-capture | ghost | exits without a session marker; loaded, not running | cards/community-capture.md |
| write-guard | live | manifest write enforcement, all box-A sessions | cards/write-guard.md |
| output-gate | live | de-secret pass before anything leaves the org | cards/output-gate.md |
| proof-gate | live | DONE-claim evidence gate, exit 0/1/2 | cards/proof-gate.md |
| index-router | live | recall-before-search; 371 descriptors | cards/index-router.md |
| collision-root | live | "the root" = runtime root vs legacy alias symlink | cards/collision-root.md |
| staged plists | leftover | 3 plists in ops/launchagents never loaded on box A | (not carded; one is the box B→A leg, see sync-legs) |
| retired residue | leftover | inert retired-product residue, staged removal | (not carded; see LEGACY-RETIREMENT.md) |
live* = live with a caveat on the card. Two nouns are leftover residue and deliberately not carded — the catalog says so instead of pretending.
Two cards, unedited
What a ghost looks like. What a collision looks like.
# dispatch-watcher status: ghost source: Library/LaunchAgents/com.fleet.dispatch-watcher.plist ; ops/scripts/dispatch-inbox-watcher.sh what: Polled comms/dispatch/inbox every 300s and pushed messenger-app notifications — the dispatcher's doorbell on box A. Self-disabled 2026-08-15T01:41Z after 3 consecutive messenger send failures (designed 3-strike breaker; see the SELF-DISABLED note of 2026-08-15 in comms/outputs/). looked-for: launchctl list (not loaded, verified 08-16 and again 08-29); the disable note names the reload command. Someone reloaded it between: its log shows a 4th strike and a second SELF-DISABLED line on 08-23 — the relay was still dead, exactly as the caution below predicts. hits: nothing at runtime — that is the danger. 633 items sit unconsumed in comms/dispatch/inbox (08-29), including fresh dispatches; "queued to the dispatcher" currently means "parked indefinitely". does-not-hit: comms/inbox (flat) — its executor is a DIFFERENT service (session-inbox-executor) and still runs; do not conclude "inbox processing works" from it. caution: root cause is likely notify-relay (see that card) — reload the watcher only AFTER a test send succeeds, or it strikes out again in 15 minutes.open on GitHub
# collision-root status: live source: the runtime root vs the legacy root alias (a symlink at the home dir, created 07-12, pointing at the runtime root) what: Collision card. "The root" means two paths. Meaning 1: the runtime root — the flat tree write-guard enforces, what every card here cites. Meaning 2: the legacy root alias — a symlink with the old name that several loops still default to: session-inbox-executor, reference-shelf's state-probe, dual-host-sync, mail-watch's plist. moves: none — but every script that reads the root env var falls back to one of the two. hits: removing the symlink kills the four loops above silently (they resolve a path that no longer exists and their LaunchAgents keep reporting exit 0 or restart forever). does-not-hit: write-guard scope — the guard keys on the runtime root only; a write through the alias resolves to the same inode and is guarded the same way.open on GitHub
A ghost card lists the wiring that was looked for and not found, and names the loop that will strike out again if you "re-enable" it. A collision card exists because one word meant two paths and four loops depended on the wrong one.