Verify the validator-side half of the tokenless-sim REJECT root cause
against current source (first link of the bf-34lwt split):
- mothership/cmd/mothership/main.go:4494 — SetTokenValidator(...) is a
bare statement with no env/build guard; provSrv is created
unconditionally at :4492. 'validator configured?' is always YES.
- mothership/internal/ingestion/server.go:513 — tokenOK :=
hello.Token != "" && validator(hello.MAC, hello.Token) depends
solely on the deserialized hello JSON body field (message.go:22),
not any HTTP header. No X-Spaxel-Token read exists on this path.
Conclusion: validator always configured; accept/reject hinges entirely
on hello.Token.
Co-Authored-By: Claude <noreply@anthropic.com>
Definitive root-cause for the bf-4iewr split's first child. Confirms
against current source (with file:line citations) that:
- The token validator is wired UNCONDITIONALLY (main.go:4494)
- It reads hello.Token only (server.go:513); the sim never populates it
- The sim sends its token only as the X-Spaxel-Token header (cmd/sim
main.go:633/scenario.go:318), and the mothership never reads that
header (HandleNodeWS upgrades unconditionally at server.go:469) -> the
token-supply path is currently DEAD
- The default 24h migration window (config.go:139) is the only thing
accepting sim nodes -> current 'no reject' is a window MASK, not a fix
- REJECT fires only when the window closes (SPAXEL_MIGRATION_WINDOW_HOURS=0
or uptime > 24h)
Corroborated by the e2e harness comment (tests/e2e/e2e_test.go:86-94)
which pins the window open and documents exactly this.
Co-Authored-By: Claude <noreply@anthropic.com>
Appendix A to ci-test-sim-reference-map.md: line-by-line path inventory
of the spaxel-build WorkflowTemplate. Every Go step runs with cwd=mothership,
so ./cmd/sim (L385), ./cmd/mothership (L392), and ./test/acceptance/ (L400)
all resolve under the mothership module. Confirms the template references
none of: root cmd/sim, root test/acceptance, tests/e2e/run.sh, or
mothership/tests/e2e/e2e_test.go (the latter only transitively compile-
covered by go test ./...).
Co-Authored-By: Claude <noreply@anthropic.com>
Decision spike for the firmware/test/ host harness (split of bf-4ne).
Records why the ESP-IDF --target linux / Unity-host path was rejected:
csi.c is blocked by esp_wifi.h and provision.c by driver/uart.h, and
firmware/main builds as one component whose REQUIRES line names
esp_wifi/bt/driver — none of which have a linux build. Falls back to a
plain gcc harness under firmware/test/ that does not link main/*.c.
Reason must be carried into bf-4ne's test-runner header comment.
Co-Authored-By: Claude <noreply@anthropic.com>
Add optional mothership IP override to the provisioning flow so nodes
on networks where mDNS is blocked (enterprise WiFi, mesh, VLANs) can
connect on first boot without manual intervention.
- Add ms_ip field to provisioning Payload and request structs
- Firmware writes ms_ip to both NVS_KEY_MS_IP and NVS_KEY_MS_IP_PROV
- Discovery prefers provisioned IP on first attempt, falls back to
mDNS, then cached IP
- Web Serial wizard adds Mothership IP field in Network Troubleshooting
- Auto-populates IP when browser accesses dashboard by IP address
- Document when/how to use the override in docs/notes/mdns-override.md
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>