Trace

Follow a request through every layer

Purpose of this page: show how the parts cooperate. It traces one real call — a worker claiming a task — from the shell keypress to the SQLite commit, and names the file responsible at each step.

The call we trace

A worker needs work. Its harness runs:

kanthord node claim <node-id>
Step 1 Commander parses src/cli/node/claim.ts
the program was built once by buildProgram in main.ts, with bound handlers this file holds no business logic and opens no connection itself
options handed to the shared client
Step 2 DaemonClient renders src/cli/client.ts
takes the operation's typed path tuple from http/contract/ substitutes :id parameters, builds URL and init (fetch) attaches the Bearer token of the harness actor
HTTP to the daemon's bind address
Step 3 Middleware chain src/http/server/
envelope → origin → host → preflight auth compares the token with timingSafeEqual route matches against the operation registry authorize → bodyParser → idempotency → dispatch
one matched operation, one handler
Step 4 Handler parses src/http/server/node/
validates the body with the zod schema from the contract invokes exactly one command: claimNode branches on no domain rule — that is a handler defect
the command owns everything below
Step 5 One transaction src/commands/node/claim-node.ts
storage.transact opens; the clock is read once expired leases swept · completeness checked on ancestors lease hierarchy refuses self, parent, sibling conflicts objective + task leases acquired, fenced runs opened or adopted · attempt №1 recorded ready → running, ancestors cascade lease.claimed and node.running appended
commit, or nothing happened
Step 6 Response formats handler again
success: lease, fence, run id, attempt id, heartbeat interval (TTL ÷ 3) refusal: the command threw a typed reason — lease-held, illegal-transition, … — mapped by the server to an error envelope
same path in reverse
Step 7 CLI prints worker starts its agent loop
exit code reflects the outcome (src/cli/exit-code.ts) on success the worker executes in the clone and heartbeats at the returned interval

What differs on a read

A read such as kanthord node list --state ready follows steps 1–4 and stops: the handler invokes exactly one query, which opens no transaction and writes nothing. Steps 5–7 belong to write paths only.

Why the shape is rigid

  1. The CLI cannot bypass HTTP, so the same API serves every client, and the contract stays honest.
  2. The handler cannot branch on domain rules, so behaviour has exactly one home: a command or query.
  3. The command owns one transaction, so a transition and its event are all-or-nothing.
  4. The domain imports nothing impure, so every rule is testable without a database.