cokecoder handbook wiki

Sessions

Technical chapter.sessions raw

The word "session" names three different things in this stack, and most confusion about the daemon comes from blurring them. This chapter separates them, shows where each one lives on disk, and names the commands that answer the questions you will actually ask. The detail — every verb, every record shape, every refusal — lives in the installed ccc-base skill (load /ccc-base in a Claude seat); this page is the map, not the manual.

The three things called a session

  1. A harness session. One running agent process — Claude Code, Codex — with a UUID. Its transcript is <uuid>.jsonl plus a sibling <uuid>/ directory under $UCC_HOME/shared/projects/<project-slug>/. This is what your terminal pane is.
  2. A daemon client. The same process, as ccc-statusd sees it: an entry in the daemon's session cache and, while its socket is open, in the connection register. ccc-statusd session list reads the register; ccc-statusd status prints the count.
  3. A session record. A directory in the sessions root, year=YYYY/month=MM/DD-HH-<slug>/, holding an INTENT.md. This is the shared workspace of a piece of work: its board, its roster, its results. Many harness sessions join one session record.

The first two are ephemeral and belong to a process; the third is durable and belongs to the work. The daemon ties them together through your card.

From a running seat to its card and its session

flowchart LR
  P["your seat: a process with a uuid"] -->|first prompt| C["your card: agents/short-id/short-id.md"]
  C -->|seat:| R
  C -->|owner:| T
  subgraph S["sessions root: year=YYYY/month=MM/DD-HH-slug/"]
    I["INTENT.md"]
    R["rosters/role-slug.md"]
    T["tasks/slug.md"]
  end
  • The short id. The daemon addresses every seat by an 8-hex handle derived from its UUID. For a UUIDv4 (Claude Code, Kimi) it is the first 8 hex. For a UUIDv7 (Codex, Grok) it is the last 8 hex, because a v7 UUID opens with a timestamp and two Codex seats born in the same minute would otherwise share a handle. Every session send, session read, check-health and card path uses this handle. In a Codex seat, take the last 8 hex of the session id, never the first.
  • The card. On your first prompt the daemon births agents/<short-id>/<short-id>.md in the sessions root. Its frontmatter carries role, session, seat, host, claude-session-id, spawned-by; you own manifest (what you exist to do), status (what you are doing now), exit (your own-exit claim) and the body sections Memo, Todo, Notes, Handoff. A card whose seat: is empty reads as vacant even while the process runs. The first UserPromptSubmit banner — joined <session> as agent <short-id> — is the proof that hooks are live and the card exists; no banner, no hooks, no card.
  • The seat. seat: on your card points at a roster file, rosters/<role>-<slug>.md, inside a session record. The roster is the charter of that seat: purpose, scope, who it reports to, its exit shape. A spawner seeds session: and seat: at birth; a seat you take yourself is one properties write on your own card.
  • The session record. Birthing INTENT.md at year=YYYY/month=MM/DD-HH-<slug>/ is session birth; there is no scaffold. Subdirectories appear when something is first born in them: tasks/ (the board), rosters/ (who), results/ (payload worth keeping), decisions/, inbox/, code/. One owner per fact: the card carries now, the roster carries who, the task carries what.

The board

tasks/<slug>.md files are the cards of a pull board — teammates read the board, not each other's messages. Each card has status in one of seven columns (Backlog, Todo, In Progress, Waiting for others, Done, Canceled, Duplicate) and an owner of the form [[<short-id>]]. Claiming is a properties write of owner and status; moving is a properties write of status; a card that moved under you refuses with fingerprint_mismatch rather than losing the update. The owner never closes a card as Done — a reviewer does. The MCP sql tool over the sessions root lists a board in one query; the ccc-base skill has the query.

Agent home, memos, and the work folder

  • agents/<short-id>/ is your agent home: the card, memos/, and later leases/. It is flat — one directory per seat, under the root, not under a session.
  • A memo is one finding worth keeping past this conversation — a gotcha, a failed approach, a user correction — as one file at agents/<short-id>/memos/<slug>.md with type: memo and a memo/<kind> tag. Compound reads memos by their session: stamp and graduates them into the wiki; a memo written outside the record door has no stamp and is invisible to it.
  • Your work folder is outside the tree: <work>/<short-id>/, by default $UCC_HOME/work/<short-id>/. Checkouts, builds, captures, git worktrees go there, never into the sessions root. When your process is gone the daily tick packs that folder into agents/<short-id>/leases/<timestamp>.tar.zst and removes it — so anything that must outlive you is promoted into the tree (a result into results/, a finding into a memo) while you live.

What you never do in the sessions root

A sessions root is a git repository, and it is committed by exactly one actor: bin/sweep, run by the daemon every ten minutes for every bound root. One cycle stages everything, commits, fetches and merges the canonical remote's main, pushes, copies annexed bytes to the special remote, and drops cold ones; its log is <root>/.ccc/sweep.log. Agents never git add, git commit, git push or git stash there. Stash in particular is the trap: the tree is dirty by design with other seats' live work, and a stash reverts all of it silently while leaving the checkout looking clean. Records are born and changed through the MCP put tool (Meridian tools, folded under What you have); reads through read and sql.

The commands you will ask questions with

Every one of these prints its own contract with --help; the daemon binary is the authority, never a remembered flag.

  • ccc-statusd status — is the daemon up, how many sessions are connected.
  • ccc-statusd session list --location global — every connected seat on this host with role, model, token fill, status and liveness. A bare list is scoped to the current directory. The register is reborn empty at every daemon start (the header says register since daemon start …), so a young register is weak evidence that a seat is gone; -a includes cached disconnected ones.
  • ccc-statusd session check-health <short-id> — healthy (exit 0), unreachable (exit 1, process dead), unknown (exit 2, not in the registry).
  • ccc-statusd session read <short-id> — a seat's transcript as an outline: one line per message, tool runs folded, the position of any API error. It never wakes the seat. --index 5,12-24 reads messages in full; --usage prints token usage only.
  • ccc-statusd session send <short-id> 'text' — delivers over the daemon socket in an XML envelope naming the sender. The Sent tick means a non-empty body was accepted for delivery, not that it was read. --needs-reply marks that you expect an answer; !@path inlines a file at send time.
  • ccc-statusd session schedule <id> --in 10m 'text' — an absolute-time alarm delivered as a message; schedule list|get|delete manage them.
  • ccc-statusd session killme --delay 2 — ends the calling seat; a spawned pane closes itself. restart relaunches in place with history; forkme splits a parallel pane that inherits the parent's history.
  • ccc-statusd session auq list|answer|resend — the relay for a seat's pending AskUserQuestion dialog, so a person or another seat can answer it from outside the pane.
  • ccc-agent list --table — live agents by pane and role; liveness is computed from the process, never read from a file.

Waking a seat that has been idle past the prompt cache's lifetime (about an hour) re-creates its whole context at full price — read it instead, and kill it from outside with the CLAUDE_CODE_SESSION_ID=<uuid> override on killme.

Where the detail lives

  • ccc-base — boot, the card, the board, memos, messaging, running and seating other agents, continuity. Reference files inside it: session-dir.md (the INTENT.md template and layout), orchestration.md (seating), worker-continuity.md (a worker's wrap-up), hooks-reference.md (the sensors that tell you to rotate).
  • ccc-sessions-root — where each byte goes, the storage doors and their refusals, bin/init, bin/check, bin/sweep.
  • ccc-meridian — read, put, sql, guarded writes, the refusal vocabulary.
  • ccc-work, ccc-leader, ccc-advisor — the role you play once seated.

Wiki

Technical chapter.wiki raw

The wiki is a git repository of markdown that is also an Obsidian vault. It holds maintained knowledge for future work: what your agents learned in earlier sessions, kept in one place and organized so the next session reads it instead of rediscovering it. Agents operate it through the llm-wiki skill and the Meridian engine — the mrd command, or the same operations as MCP tools inside Claude Code. A person opens the same directory in Obsidian and reads the computed views in bases/.

It sits at both ends of a session. At the start it is a context source: mrd run LLM_WIKI.md load prints the wiki's identity, its companions and any structure findings. At the end it is a knowledge sink: the compound stage of the ccc chain writes what the session learned back into it.

The step that builds yours is Step 5 of Start here — it fetches the skeleton archive and walks the five setup steps. This chapter explains what that step builds and how agents use it afterwards.

The flow

flowchart LR
  I["inbox/"] --> G["ingest"] --> P["pages"] --> C["check"]
  1. inbox/ — evidence lands here as a raw capture: a clipped web page, a scraped repo, a curated session digest, a note you dropped by hand. A capture is immutable once dropped; it keeps its origin (source: or source-uri:) and its capture time (created:).
  2. ingest — an agent with the llm-wiki skill loaded works the capture into knowledge (the skill's CAPTURE cluster): find the page that already covers the subject, preserve the evidence once, update the explanation readers already use, connect it, pin the claims that depend on a specific passage, validate. Not every capture needs a page in every layer.
  3. pages — the maintained tiers: sources/ explains one piece of evidence, domains/ holds the current understanding of a subject, synthesis/ reasons across subjects, effects/ describes reusable artifacts.
  4. check — mrd run LLM_WIKI.md check says whether the tree still conforms; exit 1 on findings.

Layers — one folder per layer

The folder declares the layer. The set is mandated: every wiki under the shared contract carries the same folders, so a shipped Base's folder filter is identical everywhere.

Folder Layer Mutability What a page there is
inbox/ raw immutable after drop a capture, in one of six inbox folders: _unstaged/ (the default drop; Obsidian's new-note folder), clipper/, scraped/, filed/, curated-sessions/, refresh/
sources/<bucket>/ source immutable from the commit that introduces it a dated interpretation of one input, linked to its capture; each bucket has an uppercase master page
domains/<cluster>/<domain>/ domain evolving one home page per domain; pins the source sections it interprets
synthesis/ synthesis evolving cross-topic reasoning; pins domain and source sections
effects/<kind>/<group>/ effect content immutable a descriptor of a reusable artifact — skill, agent, prompt, site, document, tool — with a git version record
decisions/ decision append YYYY-MM-DD-<slug>.md, status: pending, decided, rejected or superseded
logs/ exhaust append run logs
bases/ views computed Obsidian .base files that render inventories from frontmatter — never a hand-kept list
bin/ wrappers byte-identical across wikis the scripts the contract names
review/ board generated, gitignored the pin-state board bin/wang regenerates; never committed, never hand-edited

A cluster under domains/ is a pure container: a page goes inside a domain, never directly inside a cluster. Every tracked folder carries an uppercase blurb page (inbox/INBOX.md, sources/SOURCES.md, domains/DOMAINS.md, …) with a ^check block; those blurbs are what check runs.

Files the tools need

File What it is
LLM_WIKI.md the entry page — type: llm-wiki-root, wiki: name, optional sessions-root: and repos-root:, and the declared load and check tasks
SCHEMA.md the local overlay: contract version, sessions root, scope ledger, default owner — at most 60 lines, no absolute path
CONTRACT.md the shared contract, byte-identical to the llm-wiki skill's references/contract-v5.md
MERIDIAN.md the root's self-declaration (type: meridian-root, name:), written by mrd init
bases/DOMAINS.base, bases/REVIEW.base the two Bases every wiki must carry; the rest are optional
bin/ wang, why, repin, pin-law.sh, bases-identity.sh, contract-identity.sh, commit-gate.sh and the others the contract lists
.wikiignore the committed exception list for the gates (SCHEMA.md's scope-ledger: names it); a finished wiki has it empty
rules/, meridian/ optional armed middleware, and the engine's reserved runtime home — never hand-edited

MERIDIAN.md in the repo names the root; ~/MERIDIAN.md on a machine binds that name to a path. Binding is what makes <wiki-name>:LLM_WIKI.md resolve from anywhere and makes the MCP tools list the wiki as a root. Local CLI work in the checkout needs no binding.

How agents read it

  • mrd run LLM_WIKI.md --list — the tasks the entry page declares; load and check are the two the entry template declares.
  • mrd run LLM_WIKI.md load — the context an agent pulls at session entry.
  • mrd read <page> — a page's section map, then the sections you name; read the map before a large page.
  • mrd sql — SQL over the corpus's frontmatter, links, tags and sections; the way to find a subject's home.
  • mrd resolve '<wiki-name>:LLM_WIKI.md' — where a named root lands on this machine.

Inside Claude Code the ccc-statusd MCP tools read, sql, resolve, run and walk do the same work with the same names; the ccc-meridian skill teaches both faces.

How agents write it

  • A write is a guarded put. The engine takes a fingerprint from your read and refuses the write if the page moved under you — a refusal names what is missing; re-read and re-plan, never resend the same bytes.
  • Link versus pin. A link means "see also". A pin means "this claim depends on that passage": mrd pin <page> '<target>#<Heading path>', one per claim, the narrowest heading that supports it, with a twin line under an ## Inputs section at the end of the page. When the pinned passage changes the pin goes red on the review board; bin/why shows the pair, you read both, and bin/repin settles it — never re-pin unread text to make a check green.
  • Ingest by the skill's steps, not by hand: prefer improving the page readers already use over adding another; keep each fact in one maintained home and link to it from elsewhere; remove obsolete guidance instead of stacking correction banners.
  • Provenance is untouchable. A tidy never rewrites a capture's created:, source: or source-uri:, and never backfills updated: or reviewed:; reviewed: records a review act, not a cleanup.
  • Never a live secret in a page, never another wiki's people, content or absolute paths.
  • Compound writes for you. At the close of a ccc chain session the compound stage ingests the session's memos into the wiki bound under the root name home-wiki — bind yours under that name (step 5 does) or compound writes nothing into it.

Checks, cheapest first

  1. mrd run LLM_WIKI.md check — structure, blurb presence, the closed set of inbox folders. Silent when clean; exit 1 with a finding line per problem.
  2. mrd check --json — pin state against the engine's baseline.
  3. bin/wang --gate — regenerates review/ and applies the hard tier of the board.

A status glance is not a verdict; check is. An empty pin walk means no pins, not verified truth.

Obsidian

Open the wiki directory as a vault. Bases is a core Obsidian feature — no community plugin is required for the views to render. The skeleton carries no .obsidian/ settings: in Obsidian's Files and links settings, point new notes and attachments at inbox/_unstaged/, so a note you write by hand lands in a declared inbox folder.

The five setup steps

Named here so this chapter reads on its own; Step 5 of Start here runs them.

  1. Choose the directory and the wiki name — a git repository, since pins anchor on git objects.
  2. Adapt the entry template into LLM_WIKI.md.
  3. Add SCHEMA.md and CONTRACT.md, with the layout, Bases and wrappers the contract requires.
  4. Declare the Meridian root with mrd init . --name home-wiki and bind it in ~/MERIDIAN.md under that name — the compound stage writes only into the root bound as home-wiki.
  5. Verify: mrd resolve LLM_WIKI.md, mrd run LLM_WIKI.md --list, mrd run LLM_WIKI.md load, mrd run LLM_WIKI.md check.

The skeleton tarball carries steps 2 and 3 already done — entry page, contract, schema, the mandated folders with their blurb pages, the two required Bases and the wrappers — so the step is: extract, mrd init, verify.

Skills that carry the detail

  • llm-wiki — selecting a wiki, its entry pages, the verb clusters (CAPTURE, BUILD, SEEK, EVOLVE, HARVEST, UPDATE), page design, provenance and pins. Load it for any wiki work.
  • ccc-meridian — the engine: addressing, section maps, guarded writes, pin proof, the refusal vocabulary, SQL over a root.
  • ccc-compound — the chain stage that graduates a session's memos into the wiki.