---
name: msg-identity-w5-f038-autostart
description: MSG-IDENTITY W5 F-038 REQ-ENDPOINT-AUTOSTART test map — config round-trip/upsert units, autostart loud-skip units, daemon-restart e2e keystone.
metadata:
  type: project
---

REQ-ENDPOINT-AUTOSTART (F-038 W5, branch build/msg-identity-w5-f038). Impl: `crates/spt-daemon/src/{config.rs,autostart.rs,daemon.rs}` + `crates/spt/src/cli.rs` (`endpoint run --save`). Daemon replays saved startup endpoints on a boot thread AFTER broker bind — best-effort, LOUD, fresh session per replay (shape (a), not a restore).

**Tests written (all GREEN):**
- `config::tests::startup_endpoints_roundtrip` [unit] — two entries (one cwd, one None) survive save→load; a legacy file with no `startup_endpoints` key back-loads as empty.
- `config::tests::upsert_startup_endpoint_appends_then_replaces_preserving_other_knobs` [unit] — under `crate::test_home::with_home` (canonical spt_home path): new id → false/append, same id → true/replace-in-place, other knobs (pulse_period/detached_subnets) survive the load→save. Also fixed pre-existing `save_load_roundtrip` (added `startup_endpoints`, was E0063).
- `autostart::tests::empty_config_is_a_pure_noop` + `unresolved_adapter_loud_skips_before_any_launch` [unit] — under `with_home`; a bogus broker socket that's never dialed (skip decided by resolve_option before launch); watchdog thread + `recv_timeout(10s)` asserts prompt no-hang/no-panic return (the "never blocks daemon start" contract). In-process stderr capture is awkward, so behavior is the gate, not the token text.
- `crates/spt/tests/endpoint_autostart_e2e.rs::saved_endpoint_replays_on_daemon_restart` [int] — models `idle_edge_drain_e2e.rs`. Isolated SPT_HOME, register `cc` mock harness, `endpoint run --adapter cc --id gwauto --start --save` → assert ENDPOINT_AUTOSTART_SAVED + daemon.json entry; reap harness; `daemon stop --force` + kill broker child + remove brain.ready; spawn daemon B; poll ≤30s. **Keystone:** `ENDPOINT_AUTOSTART:gwauto ... (startup default)` token in the SPT_HOME/logs sink (NOT the spawn-redirect file — see [[daemon-stderr-sink-supersedes-spawn-redirect]]) + the perch rebinds a FRESH session_id (distinct from run A's). Panic-safe `Reaper` guard (Mutex<Vec<u32>> taskkill on Drop). ~5s runtime (mock-session heartbeat 200ms). `--test-threads=1`.

**Anomaly found & fixed (test-only):** the committed impl @42ecada added `DaemonConfig.startup_endpoints` but did NOT update the existing `save_load_roundtrip` unit → the whole spt-daemon lib test target failed E0063. Fixed as part of test work.

**Notes:** `mock-session` fixture emits `MANIFEST_DEAD_KEY:cc` for the `[session.psyche_init]` `{psyche_dir}` cwd (retired key) — a benign register-time warning, endpoint still binds ONLINE (same manifest shape as idle_edge). Fixture prereq: `cargo build --workspace --bins` (mock-session). Verified: scoped `config::`/`autostart::` lib tests, the e2e, `cargo clippy -p spt-daemon -p spt --all-targets -D warnings`, `traceable-reqs check` exit 0 (REQ-ENDPOINT-AUTOSTART [OK] +doc+impl+unit+int).
