Files
boxmaker/docs/plans/M2b/08-loopd-serve.md
kyleandClaude Fable 5.1 e156975649 Add M2b plan: ten tasks, tests, recordings and the first system prompt
The tasks build the agent loop on M2a's client: channel messages and
the usage record in proto, four config tables, the tool port and
registry with find_tool and call_tool, the baseline and replay, the
session store, the turn loop with its limits and the append-only
property test, the channel server, loopd serve, bxctl chat, and the
device checks including a four-turn conversation with a restart.

Checked against a private reference implementation: the gate passes
after every task in order, the new suites pass under CPU load, and the
reference passes make verify-device on straylight with no cache loss.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-18 17:19:02 -07:00

2.0 KiB

M2b task 08: loopd serve

Branch: m2b (run git switch m2b; git status --short must be empty, otherwise stop) Commit subject: Add the loopd serve command

Goal

The command that runs the harness: self-test, then the channel server. It refuses to start if the self-test fails.

Files

  • Copy: crates/loopd/tests/serve.rs
  • Modify: crates/loopd/src/main.rs, docs/implementer-log.md

What loopd serve --config <path> does, in order

  1. Load the config; on failure print loopd: <error> and exit 1.
  2. Work out the socket path with cfg.channel_socket(). If a socket file is already there, remove it now, before the self-test, so that a client sees "not running" rather than "connection refused" while the self-test runs.
  3. Run the self-test exactly as loopd selftest does, printing the same lines. On failure exit 1 without binding anything.
  4. Create the socket's parent directory, bind, set the socket file's mode to 0600, print loopd: serving on <path>, and call channel::serve with a Context made of the config, the client, Box::new(FakeTools::new()) and Registry::m2b().

loopd selftest --config <path> keeps working as before. Anything else prints the usage for both commands and exits 2.

Steps

  • 1. Copy. git switch m2b, then cp docs/plans/M2b/files/crates/loopd/tests/serve.rs crates/loopd/tests/
  • 2. See the test fail. cargo test -p loopd --test serve. Expected: all 3 fail, because serve is not a command yet.
  • 3. Rewrite main.rs. Keep the selftest command. Run cargo fmt --all.
  • 4. See the tests pass. cargo test -p loopd --test serve. Expected: 3 passed.
  • 5. Run the gate. make gate. Expected last line: gate: ok.
  • 6. Log and commit. git add crates/loopd docs/implementer-log.md && git commit

Done when

  • cargo test -p loopd --test serve reports 3 passed; make gate prints gate: ok.

Stop and report if

  • The socket cannot be given mode 0600 with std::fs::set_permissions.