Starter: CLAUDE.md safari
Browse CLAUDE.md files online - good hunting grounds are GitHub code search and awesome-claude-code. Better yet, spawn a few subagents to search the internet in parallel and report back the most interesting conventions they find - yesterday’s evaluation session showed the pattern. Share your find on the Padlet.
Remember, Claude can change its own instructions. Try something like this:
When a rule, policy, or decision surfaces during work (from the user, a hook, or discovery), record it proactively: repo-wide conventions go in CLAUDE.md, design decisions go in ASSUMPTIONS.md.
In the starter kit
The starter repository (starter/) is a uv project: src/hadr_agent/ holds the runner shell, the MCP client, the two stores, and the intake/reconcile/dispatch modules. Plumbing ships working; the lessons ship as marked holes. Each store method’s docstring states its contract and edge cases, and features/ carries the acceptance scenarios as executable Gherkin with stable IDs - STORE-R* and STORE-I* (Day-1 stores), LOOP-* (agent loop), DISP-* (dispatch, stage 1), INT-* (intake: the _finalize gate is stage 1, the prompt is stage 2), REC-* (reconciliation, stage 3). The holes are: the store methods (Day-1 warm-up), the runner inner loop, intake’s _finalize gate (minimally at stage 1, fully at stage 2) and the intake prompt (stage 2), the reconciliation logic and its match thresholds (stage 3), and the dispatch prompt plus the coverage/priority state-message builder (stages 1 and 4). uv run pytest (plumbing) is green out of the box; uv run behave runs the fill-the-hole scenarios, which fail until you build them. Your PRs cite the scenario IDs they satisfy. Copy .env.example to .env and fill in your OpenCode key (OPENAI_KEY); the endpoint and model settings also live in .env and default to values that work out of the box.
Open and look around the starter kit in greater detail. In src/hadr_agent/:
| File | Role |
|---|---|
runner.py |
Outer shell: owns the MCP session, ticks the loop, calls next_tick() once per tick. Ships working; intake and reconcile are holes. |
agent.py |
The agentic tool loop, model- and task-agnostic. Every agent here is a configuration of it. |
intake.py |
One human contact in, one schema-conforming report out (cheap model). Deliberately not a loop. |
reconcile.py |
Deterministic code, no LLM: match reports + truck vision to incidents. |
dispatch.py |
Configures the loop for dispatch: state message, typed tools, the filed-incident check. |
stores/reports.py |
Append-only store of extracted evidence, one row per contact. |
stores/incidents.py |
Mutable store of the agent’s beliefs about suspected fires. |
prompts/intake_system.md |
The intake system prompt. |
prompts/dispatch_system.md |
The dispatch system prompt. |
Two files ship working and should not be changed:
engine_client.py: Connects to the game MCP and provides it to your agent.util.py: shared plumbing - token accounting, API client, prompt loading, tool schemas.
Anatomy of an agent
The dispatch agent is a claw: a small, always-on agent that is mostly files and a loop. (The name comes from OpenClaw, which has this shape.) A claw has six parts:
- Prompt/Soul: the prompts in
intake_system.mdanddispatch_system.md. - Loop: the inner tool loop (
agent.py) - feed the model context, run the tools it asks for, go round again until it yields for the tick. - Tools: actions the model can execute - read contacts, query the map, dispatch.
- Memory: what survives between ticks, kept in the report and incident stores you built yesterday morning.
- Heartbeat: what wakes it without a human - the outer runner that invokes the agent.
- Channel: where output lands so someone can act on it - commands to the simulator.
In this exercise we provide the heartbeat (runner.py) and the channel (engine_client.py); the rest you configure on top of the agentic loop you built yesterday.
In a nutshell: the heartbeat fires each tick, the channel provides input from the world, which is used to update the memory. The loop wakes, applies its prompt to pick the next action and uses tools to execute them. Nobody prompts it mid-episode.
These are the same moving parts of every agentic system, with task- and job-specific modifications.