---
name: msg-identity-w4-delivery
description: MSG-IDENTITY W4 tests — live_agent inject-exclusion (F-033) fixture ripple + SPT_ENDPOINT_ID from-stamp leg (b2) unit+int patterns
metadata:
  type: project
---

MSG-IDENTITY W4 (branch build/msg-identity-w4-delivery) — two legs tested.

**REQ-LIVE-AGENT-NO-INJECT-DELIVERY (F-033):** `is_spt_hosted_no_relay` (spt-daemon/src/inject.rs) now returns false when `rec.state == "live_agent"` (a live agent has its own reader; controllable is attach/rc, not delivery). Ripple: EVERY test/fixture that stamped a `"live_agent"` perch and expected the inject predicate TRUE broke. Fixed BY INTENT to non-live tag `"gateway"`:
- unit homes: `cli::tests::spt_hosted_no_relay_detection` (crates/spt/src/cli.rs) + `inject::tests::shared_inject_leg_detects_spt_hosted` + its `establish_hosted` helper (spt-daemon/src/inject.rs). Positive case → `gateway`; ADDED a live_agent-excluded tail assertion (same online+controllable+relay-less shape, flip state→live_agent → false).
- **Wedge-file ripple (deterministic, NOT the flaky runtime):** `crates/spt-daemon/tests/inject_control_wedge.rs` `establish_endpoint_perch` (~L1815) + the WAN-ingress inline fixture (~L2908) stamped `live_agent`; the parked-idle test asserts `is_spt_hosted_no_relay==true` at setup (~L3069). All broke by construction (predicate false for live_agent vs assert-true). Fixed both fixture tags → `gateway` (intent = broker-driven translation-binary inject path, which STILL injects). Verified via `--test inject_control_wedge --no-run` (compile-only — do NOT run the wedge gates blind; slow + known-flaky). Other wedge fixtures at L2317/L2493 use state `"online"` (not live_agent) → unaffected.

**REQ-SEND-STAMP-AGENT-ID (leg b2):** `detect_self_id` (crates/spt/src/roster.rs) reads `SPT_ENDPOINT_ID` after SPT_AGENT_ID, accepts ONLY when the id maps to a bound perch (`info::read_info(resolve_perch_path(..))` is Some); label-only.
- unit: ONE combined test (env-mutation safety) `roster::tests::detect_self_id_endpoint_id_leg_is_label_only_and_perch_gated` under `isolated_home()` (crate::testutil — process-wide LOCK, clears OWL_SESSION_ID). Covers perch-mapped→id, perchless→None, SPT_AGENT_ID precedence. isolated_home does NOT clear SPT_ENDPOINT_ID/SPT_AGENT_ID — remove_var them at end or they leak to sibling tests. Pin fixture perch pid=0 so leg (c) ancestry can't resolve it.
- int: NEW `crates/spt/tests/send_stamp_agent_id_e2e.rs` — NO daemon needed. Shelled `spt send <inbox>` with fresh SPT_HOME spools locally (broker socket name hashes spt_home() @ endpoint.rs:25 → is_running() false in isolated home). Create relay-less bound perches, run `spt send` with/without `.env("SPT_ENDPOINT_ID","wanda")` + env_remove OWL_SESSION_ID/SPT_AGENT_ID, read back `spt_store::spool::peek_all_at(&inbox)` → row.1 (from_id) == "wanda" vs starts_with("cli"). Body is stdin-only (Send{target} has no body positional).

Verified: both unit tests + int green; clippy -p spt -p spt-daemon --all-targets -D warnings clean; traceable-reqs EXIT=0 (both REQs [OK]); spt-live --lib 65/65. Watch clippy `doc_lazy_continuation` — a prose line right after a `-` bullet list in `//!` needs a blank `//!` separator.
