Plan M4a: gatewayd in 15 tasks, with skeletons and given tests

Each task's tests were run against a reference at its end state; the end states were replayed
from master in order with the gate at each step (650 to 762 tests); each skeleton compiles
against its tests and fails them. The reference is kept off this machine. Lessons T27 (every
wait in a test has a limit) and T28 (mutate the reference before hand-over) come from this work.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-23 19:05:44 -07:00
co-authored by Claude Opus 5.5
parent f38dc8d474
commit 0339dc13b2
69 changed files with 7790 additions and 3 deletions
+57
View File
@@ -0,0 +1,57 @@
# M4a task 15: `gatewayd serve --config <path>`
**Branch:** `m4a` (run `git switch m4a`; `git status --short` must be empty, otherwise stop)
**Commit subject:** `gatewayd: main, serve --config with its start checks`
## Goal
The program. `gatewayd serve --config <path>` loads the configuration and the token, prepares its
directory, and runs the serve loop (task 14) until it must stop, then exits 1. Anything else on the
command line prints `usage: gatewayd serve --config <path>` and exits 2. Every failure at start
prints one line and its runbook pointer and exits 1, **before** anything is created on disk and
before any connection:
| Failure | Output |
|---|---|
| the config cannot be read, parsed or checked | `gatewayd: <error>` then `see docs/runbook.md#gatewayd-start-failed` |
| the token's source is wrong | `gatewayd: <path>: <why>` then the same pointer |
| the token cannot be loaded | `gatewayd: secret mattermost_token: <why>` then `see docs/runbook.md#secret-unavailable` (the error's own `Display`) |
| `<home>/gateway` cannot be created | `gatewayd: cannot prepare <dir>: <error>` then the start-failed pointer |
A token read from a file prints task 04's warning, and `gatewayd` goes on. The token itself is
never printed: the last test runs the real program and looks for it in everything it wrote.
## Files
- Copy: `crates/gatewayd/tests/main.rs`, and the skeleton `crates/gatewayd/src/main.rs` (replaces
the placeholder that printed "not implemented")
- Modify: `docs/implementer-log.md`
## The skeleton
Written: `main`, which parses the arguments like `loopd`'s. To fill: `serve(path)`, whose steps
are above its `todo!()`. The directory is `config.state_path()`'s parent, created with
`std::fs::DirBuilder`, `recursive(true)` and `mode(0o700)` (`std::os::unix::fs::DirBuilderExt`).
## Steps
- [ ] **1. Copy.** `git switch m4a`, then
`cp docs/plans/M4a/files/crates/gatewayd/tests/main.rs crates/gatewayd/tests/ && cp docs/plans/M4a/files/crates/gatewayd/src/main.rs crates/gatewayd/src/`
- [ ] **2. See it fail.** `cargo test -p gatewayd --test main`. Expected: it compiles; 4 fail and 1
passes (`usage`, since `main` is given).
- [ ] **3. Fill `serve`.** `cargo check -p gatewayd`.
- [ ] **4. See it pass.** `cargo test -p gatewayd --test main`. Expected: 5 passed.
- [ ] **5. Run everything.** `cargo test -p gatewayd`. Expected: every suite passes.
- [ ] **6. Run the gate.** `cargo fmt --all`, then `make gate`. Expected last line: `gate: ok`,
with about 762 tests.
- [ ] **7. Log and commit.** `git add crates/gatewayd docs/implementer-log.md Cargo.lock && git commit`
This is the last task of M4a. Stop after the commit.
## Done when
- `cargo test -p gatewayd` passes; `make gate` prints `gate: ok`.
## Stop and report if
- A test's output contains the token.