claude-system
A version-controlled ~/.claude/ framework, a resource
coordinator, and an internal dashboard — the machinery behind an agentic research
setup. This page maps the framework itself: what lives where, how the parts
talk, and how a session is governed end to end.
01The two layers
The system is a framework plus the instances it scaffolds.
Only the framework lives in this repo. ~/.claude/ is not a separate
checkout — install.sh symlinks the load-bearing directories straight back
into ~/claude-system/claude/, so editing either path edits the same file and
all of it is versioned here.
@import concepts fromThis map is scoped to Layer 1. Layer 2 appears only as what the framework scaffolds and governs — the instances are documented in their own repos.
02Repo layout
| path | purpose |
|---|---|
| claude/CLAUDE.md | Durable cross-project principles (symlinked to ~/.claude/CLAUDE.md). |
| claude/settings.json | Claude Code settings — hook wiring, permissions, effort level. |
| claude/rules/ | Path-scoped rules auto-loaded by the harness (evaluation.md = HCE discipline). |
| claude/skills/ | 17 invocable slash-command skills, one SKILL.md contract each. |
| claude/hooks/ | 6 lifecycle shell hooks wired to harness events. |
| claude/templates/project/ | The instance scaffold copied by /new-project. |
| coordinator/ | Python package: state.db schema + writers/readers, hardware poller, admission policy, ccusage, CLIs. |
| dashboard/ | FastAPI + HTMX + SSE app. Reads state.db + project files. LAN-only. |
| scripts/systemd/ | systemd user units: hardware poller (+timer), dashboard. |
| install.sh | Idempotent bootstrap: symlinks, systemd units, backups. Safe to re-run. |
Runtime state — state.db, sessions/,
.env, ~/projects/* — is deliberately not tracked.
.gitignore is strict on *.db and .env.
03The claude/ tree — the ~/.claude payload
Everything the Claude Code harness loads at ~/.claude/ is one
of these six things. They are the framework's primary surface; the coordinator and
dashboard exist to serve them.
CLAUDE.md
Durable principles that apply to every project: where things live (SN850X vs OS
drive), the git-as-memory model, the experiment folder contract, end-of-task
discipline, runtime discipline (worktrees, subagents), and monitoring of
long-running ML jobs. Kept terse; instance CLAUDE.md files refine it.
settings.json
Wires the six hooks to harness events, sets permissions (incl. allowed
WebSearch/WebFetch), effort level, and theme.
rules/
Currently evaluation.md — the Hidden Consistent Evaluation (HCE)
discipline. Opt-in by project shape; respects: frontmatter on a skill
declares the dependency.
templates/project/
The canonical instance: CLAUDE.md, README.md,
budget.yaml, dvc.yaml, NOTES.md,
_meta/templates/, and the literature/ concepts/ mocs/ experiments/
raw/ journal/ docs/ skeleton.
04Skills — 17 SKILL.md contracts
Skills are the user-facing verbs. Each is a markdown contract loaded into
context on invocation. Three groups: the experiment loop, the literature
pipeline, and hygiene/ops.
subagent spawns a fresh subagent ·
HCE respects evaluation.md ·
auto-commit writes & commits without a confirmation gate.
Experiment loop — ideation → execution → iteration
| skill | role | |
|---|---|---|
| /propose | Strategic ideation from concepts + recent literature + recent experiments. Emits one proposal file. No code, no dvc. | HCE |
| /expand | Takes one proposal → N alternative implementations sharing the hypothesis. | HCE |
| /derive-experiment | Turns one literature note into an experiment proposal; back-links it into the note. | |
| /new-experiment | Scaffolds experiments/YYYY-MM-DD-<slug>/ (README, config.yaml, notes.qmd, log.md, metrics.json); copies splits if HCE. | HCE auto-commit |
| /implement | The MLE-ideator separation boundary — the only skill that spawns a subagent. Runs the experiment, captures metrics, writes Diagnostics, files the proposal under _done/ or _failed/. | subagent HCE |
| /iterate | One propose→implement cycle per call; reads the last Diagnostics, picks the strongest candidate. --chain N runs unattended. | HCE |
| /ensemble | Combines N completed experiments on the same metric into a new ensemble experiment. | HCE |
Literature pipeline — discover → fetch → ingest → graph
| skill | role | |
|---|---|---|
| /discover | Web-grounded triage on a topic → one ranked candidates file in raw/_candidates/. | auto-commit |
| /digest | Cron-friendly sweep for fresh items on active concepts since the last digest; drops candidates. Never auto-ingests. | |
| /fetch-paper | Downloads a paper/repo into immutable raw/, derives a citekey, chains into /ingest. | auto-commit |
| /ingest | Turns a raw/ file into a literature note + concept updates + index/log; proposes a 0–5 relevance score; calls /sync-imports. | auto-commit |
| /sync-imports | Appends idempotent used_by: back-references to concepts that downstream projects @import. |
Hygiene & ops
| skill | role | |
|---|---|---|
| /new-project | Scaffolds ~/projects/research/<slug> from the template; git init, dvc init, uv init, first commit. | |
| /lint | Knowledge-graph health check. Auto-detects research vs experiments mode and runs only applicable checks. HCE violations are hard failures. | HCE |
| /wrap | End-of-session discipline: appends Did/Findings/Next to NOTES.md, updates index/log, warns on placeholder rot. | auto-commit |
| /headroom | Sub-second resource snapshot — ccusage quota (5h block + reset-anchored weekly), hardware, job queue. Read-only. | |
| /plan | Asks the coordinator whether a job should start now; returns admit/defer with reason. Call before any >200k-token or GPU job. |
05Hooks — 6 scripts wired to lifecycle events
Hooks are the framework's enforcement layer — discipline that doesn't rely
on the agent remembering. Wired in settings.json.
| event | script | what it does |
|---|---|---|
| SessionStart | session-start.sh | Primes the session (context/state at startup). |
| PreCompact | pre-compact.sh | Preserves load-bearing context before the harness compacts the window. |
| Stop | token_logger.sh | Writes a token_events row to state.db per turn (usage passed as argv, not stdin). |
| PostToolUse (Write) | status_emit.sh | Emits a status signal whenever a file is written. |
| PreToolUse | pretooluse_cap.sh | Safety net: blocks further tool calls once a declared token ceiling is exceeded. Backstop, not primary control. |
| SessionEnd | session-end.sh | Writes the daily journal and commits + pushes it (scoped to journal/) in every git repo, backstops /wrap, and (opt-in via budget.yaml git.auto_push) commits + pushes the full project, retrying leftover unpushed commits. |
06Rules & CLAUDE.md — the discipline spec
Two prose layers govern agent behaviour without code.
CLAUDE.md (durable principles)
Where artifacts live, git-as-memory, the experiment folder contract, end-of-task
NOTES.md discipline, worktrees for destructive runs, subagents for
high-volume narrow work, and how to monitor multi-hour ML jobs (launch with
python -u, poll every 10–30 min, halt on a pattern of 3+ bad
epochs).
rules/evaluation.md (HCE)
Hidden Consistent Evaluation prevents the autonomous loop from overfitting its own
signal. Three hard clauses: (1) test/ is off-limits during search;
(2) two metric files per experiment — metrics.json (validation,
the search signal) vs final_metrics.json (held-out, written only at chain
end); (3) comparable experiments share one seeded split. Opt-in by project
shape; /lint is the backstop.
07Templates — the instance scaffold
The framework's output is a project. templates/project/ is the
canonical shape /new-project copies, after which a thin instance
CLAUDE.md and .claude/rules/ refine the durable principles.
templates/project/
├── CLAUDE.md # thin orientation; refines ~/.claude/CLAUDE.md
├── README.md # public-facing layout guide
├── budget.yaml # wall-time / token / disk ceilings + model roles + git.auto_push
├── dvc.yaml · params.yaml · Makefile · NOTES.md
├── _meta/ # index.md, log.md, templates/{concept,experiment,paper,post,repo}.md
├── literature/ concepts/ mocs/ # the knowledge graph
├── experiments/ # YYYY-MM-DD-<slug>/ runs (+ _proposals/)
├── raw/ # immutable sources — read-only after ingest
├── docs/decisions/ # lightweight ADRs
└── journal/ # hook-written daily session files
Two archetypes emerge from the same scaffold: literature-curation
projects (large knowledge graph, no splits.yaml; e.g. the
agentic-research hub) and ML-experiments projects (HCE on,
budget.yaml + DVC + sealed test split; e.g. dotaml-turbo).
08Coordinator — one sqlite DB as source of truth
A single ~/.claude/state.db tracks resources so skills can make
admit/defer decisions instead of guessing. The Python package wraps it with writers,
readers, a hardware poller, an admission policy, and five CLIs.
state.db tracks
| token_events | per-turn usage from the Stop hook |
| hardware_samples | CPU/RAM/disk/GPU @ 30s cadence |
| jobs | declared work + est. cost + status |
| decisions | admit/defer log for policy review |
modules
| db / init_db | connection + schema |
| writers / readers | insert events; query windows |
| poller | hardware sampler (systemd timer) |
| policy | can_start() admission logic |
| ccusage | accurate quota from projects/*.jsonl |
CLIs (console scripts in the coordinator venv)
| command | backs | does |
|---|---|---|
| claude-coordinator-status | /headroom | ccusage quota + hardware + queue snapshot |
| claude-coordinator-plan | /plan | runs policy.can_start → admit/defer |
| claude-coordinator-job | skills | declare / update a job in the queue |
| claude-coordinator-poll | systemd | one hardware sample → state.db |
| claude-coordinator-init | install | create the schema |
ccusage shells out to the community ccusage CLI to read
per-message usage. The weekly window is reset-anchored (Mon 17:00 local) and
well-calibrated; the 5h block boundary drifts, so trust the projection/burn-rate over the
headline 5h %.
09Dashboard — LAN-only window into state.db
FastAPI + HTMX + server-sent events at
http://<host>:8080. Reads state.db and project files;
auto-refreshes via SSE. Runs as a systemd user unit. A TTL cache fronts hot filesystem
scans.
| route | view |
|---|---|
| / | Live now — loop sessions, hardware gauges, quota meters, token sparkline. |
| /queue | Coordinator job queue (running + queued + recent completed). |
| /projects-hub | Discovery across all research projects. |
| /project/<name> | Per-project cycle table + Diagnostics. |
| /project/<name>/{concepts,literature,candidates} | Knowledge-graph browsing (markdown rendered). |
| /projects/<name>/dashboard/… | Serves a project's own static dashboard assets. |
| /events | SSE stream driving live refresh. |
10Session lifecycle — how the parts talk
A single session weaves skills, hooks, and the coordinator together:
- SessionStart hook primes context.
- Before a heavy job, a skill calls /plan →
policy.can_startreads hardware + quota fromstate.db→ admit / defer. - On admit, the skill optionally declares a job (visible in
/headroomand the dashboard queue). /implement spawns the subagent that runs it. - Each turn, the Stop hook logs
token_events; the PreToolUse cap halts a runaway loop past its ceiling. A systemd timer polls hardware every 30s. - The dashboard reflects all of this live over SSE.
- /wrap (backstopped by the SessionEnd hook) writes Did/Findings/Next to
NOTES.md, the journal, and — if the project opts in — commits and pushes.
Division of labour: skills = the agent's verbs · hooks = non-negotiable discipline · coordinator = the shared resource truth · dashboard = the human's read-only window.
11Install & operate
git clone git@github.com:eschmitt88/claude-system.git ~/claude-system
cd ~/claude-system && ./install.sh # idempotent: symlinks + systemd units + backups
install.sh symlinks claude/{rules,skills,hooks,templates} and
claude/{CLAUDE.md,settings.json} into ~/.claude/ (backing up
anything it replaces), then installs the systemd user units. Required env vars live in
~/.claude/.env (copied from .env.example; never overwritten).
| systemd user unit | role |
|---|---|
| claude-hw-poller.service / .timer | Samples hardware into state.db every 30s. |
| claude-dashboard.service | Runs the FastAPI dashboard on the LAN. |
Because claude/ is symlinked into ~/.claude/,
editing either path edits the same file — but always commit from
~/claude-system/ so history stays coherent.
12Conventions that hold everywhere
Git is the memory layer
Every durable fact lives in a tracked file — plain Markdown with flat YAML
frontmatter. Auto-memory is a hint, not a home. Recent skills commit directly rather
than gating on confirmation, because git revert makes it reversible.
raw/ is immutable
Snapshots of papers, repos, and web captures. The agent reads it; nothing writes to it after ingest. Re-ingest instead of editing.
Storage split
Datasets, checkpoints, venvs, HF cache → SN850X under ~/projects/.
~/.claude/ holds only config, skills, hooks, templates.
End every session with /wrap
Did / Findings / Next in NOTES.md; decisions in
docs/decisions/NNNN-*.md. Enforced by skill and SessionEnd hook —
not by asking nicely.