Stage 1 changes the general agent loop into a fire dispatcher. The loop stays the same. A system prompt, a state message, and typed tools give the loop its task.
flowchart LR
subgraph Intake["Intake (model extraction)"]
i1["'smoke near the<br/>school on 5th'"]
i2["'building fire on Elm St,<br/>people inside'"]
i3["'fire is out at<br/>the school now'"]
end
r{"Reconciliation (Code)<br/>match to known incidents"}
subgraph Incidents["Incidents (Memory)"]
n1["1: School, 5th Ave"]
n2["2: Elm St"]
end
subgraph Dispatch["Dispatch loop (Agent)"]
plan["plan"] --> act["act"]
act --> plan
end
subgraph Trucks["Fire trucks"]
t1["truck A"]
t2["truck B"]
end
i1 --> r
i2 --> r
i3 --> r
r -- "update" --> n1
r -- "new" --> n2
n1 --> plan
n2 --> plan
act <--> t1
act <--> t2
All contacts in this stage are structured reports. Each report describes a separate incident. The dispatcher must assign the trucks to the incidents.
What is provided
The starter provides:
- the agent loop;
- the report and incident stores;
- the dispatch tools and tool runner;
- structured contact data; and
- the
DISP-*andINT-*scenarios.
What Claude implements
Claude changes only these parts:
- Claude completes the minimum
_finalizecode inintake.py. - Claude connects structured reports to incidents in
runner._process_tick. - Claude writes
_state_messageindispatch.py. - Claude completes
prompts/dispatch_system.md. - Claude runs the focused scenarios and fixes failures in this stage.
The state message must:
- rank open incidents by risk to people;
- mark each incident as
COVEREDorUNCOVERED; - mark each truck as
FREEor committed; and - give one clear allocation instruction.
What you decide and check
You decide the dispatch policy. Review these choices before Claude edits the prompt:
- How does the system rank people, severity, and uncertainty?
- When does the system hold a free truck?
- How does the system prevent duplicate coverage?
- What information must a dispatch rationale contain?
Check the final state message. Ask Claude to show why the first incident has the highest rank. Do not accept a policy that you cannot explain.
What you do not build
Do not add:
- natural-language intake;
- duplicate reconciliation;
- replanning rules; or
- a new agent loop.
Later stages add these functions.
Prompt Claude
Open the HADR repository in Claude Code. Paste this prompt:
Complete Stage 1 of the HADR dispatcher.
First, read
CLAUDE.md,dispatch.py,runner.py,intake.py, both stores, and theDISP-*andINT-*scenarios.Before you edit, show the path from one structured contact to one dispatch tool call. List the code holes on this path. Stop if a required part is outside Stage 1.
Implement only these items:
- Complete the minimum
_finalizepath for structured reports.- Connect each fire or unknown report to one incident in
runner._process_tick.- Write
_state_messageindispatch.py.- Complete
prompts/dispatch_system.md.Keep the general agent loop unchanged. Copy
contact_idandreported_locationfrom the contact envelope. Make each dispatch refer to a filed incident.In
_state_message, read truck coordinates fromposition. Permit a nullroute. Do not treat the oldincident_idon an idle truck as a current commitment.Show me the dispatch policy before you put it in the system prompt. Use this initial rule unless I change it: assign one free truck to each highest-priority uncovered incident. Do not issue a command that changes nothing. Wait for my approval.
Run
uv run behave features/dispatch.feature features/intake.feature. Inspect the recorded request when a scenario fails. Do not change code before you understand the failure.At the end, show one complete state message. Explain what code decides and what the model decides.
Check the result
Run:
uv run behave features/dispatch.feature features/intake.feature
uv run hadr-runner stage1-basic@londone
Record:
- casualties;
- buildings lost;
- dispatch rounds; and
- dispatch tokens.
Read one dispatch rationale. If both trucks go to the same fire, first check the state message and the system prompt. Do not change the model first.
Catch-up solution
If the vertical slice is still blocked after one focused repair, use the Stage 1 reference solution.
The skeleton progress checker gives a more detailed review.
Completion criteria
- A structured contact can cause a valid dispatch.
- The state message prepares the facts before the model call.
- You can explain the dispatch policy.
- You have a live baseline for the next stages.