# M12 candidate intake — spt-core features that unblock downstream adapters

> Status: **CANDIDATES** (not activated REQs — follow activate-don't-pre-fail).
> Surfaced 2026-06-14 during the `spt-claude-code` scoping grill (doyle).
> spt-claude-code (the v1 acceptance adapter + first casual entrypoint) DEPENDS on
> these — arrange construction promptly. Operator framed these as M12, noting
> **`spt rc`** is a core value prop (confirm what `spt rc` denotes when formalizing).
> Each needs a `REQ-*` in `traceable-reqs.toml` when M12 activates.

## Confirmed-needed by spt-claude-code

1. **Adapter strings → file-backed values.** `[strings]` entries may point to a FILE
   instead of an inline string, so a fetch can return long bodies (e.g. full skill
   instructions for UPS-injection) without bloating the adapter manifest. Requires a
   standardized per-adapter auxiliary file-storage location (verify one doesn't already
   exist). Resolution still rides the leaf-replace profile overlay. Consumer:
   spt-claude-code skill-instruction delivery + hints.

2. **Subnet create/join QR + self-elevating window.** `spt subnet create/join/show-totp`:
   - Surfaces a **QR code** of the TOTP seed for the user to store → must spawn a
     window to display it (create AND join).
   - Behavior change (per operator sketch): runs normally if env is interactive +
     elevated; ELSE re-runs self in a self-elevating window with inline stdout
     ("Elevated terminal launched. Accept the prompt and proceed there." → "You can
     close this window.", no auto-close).
   - Cross-platform elevation fallbacks: Windows = UAC self-elevate window;
     Linux+desktop = pkexec/polkit or x-terminal-emulator; Linux+TTY = inline sudo;
     headless/no-TTY = print exact command for the human (agent relays).
   - Scope elevation to only steps that need it (service-install / firewall /
     privileged-port) — subnet-create itself likely unprivileged.
   - Complementary downstream: spt-claude-code skill with create/join/show-code verbs.

3. **spt-hosted HARNESS bringup + local user PTY attach (CLI). — CONFIRMED MISSING, TOP PRIORITY.**
   Investigation 2026-06-14 (file evidence):
   - Daemon-side PTY spawn EXISTS but shells-only: `crates/spt-daemon/src/brain.rs:spawn_session_pid()`,
     `crates/spt-daemon/src/shellhost.rs:launch_shell_brokered_in()`; CLI only `spt shell spawn`.
   - NO user CLI to launch a HARNESS endpoint into a broker PTY (harnesses still
     harness-hosted: adapter launches binary → binds via `spt api listen`).
   - Local user terminal attach = DESIGN-ONLY: cross-node remote attach exists
     (`crates/spt-daemon/src/attach.rs`, M4-D5b), but no local `spt attach <id>`.
   Needed work (now full-fat M12, operator 2026-06-14):
   - **`spt endpoint run`** — the interactive bringup picker (create-new / pick-existing →
     start or attach). Full spec in `M12-ENDPOINT-RUN-PICKER.md`. Wires the existing
     spawn-session seam for harnesses.
   - **`spt rc`** — connect to an spt-hosted PTY; works **cross-node** (local attach is the
     same command, subset). Already M12-slated per operator. Wraps the existing cross-node
     attach machinery (`crates/spt-daemon/src/attach.rs`) into a user CLI.
   - spt-claude-code's `cc`/`cc <id>` = thin wrapper over `spt endpoint run` defaulted to
     `claude-spt`.
   **GATING: full-fat M12 is now a PREREQUISITE for spt-claude-code** — operator ruled v1
   acceptance = legacy parity AND cross-subnet/PTY proof, so local attach + the picker are
   MANDATORY v1. todlando builds full-fat M12 after this grill, BEFORE perri starts.

4. **Cross-adapter fallback targets `<adapter>:<profile>`.** Node-wide cross-adapter
   fallback must target a composite adapter:profile, not only a bare adapter_name — so a
   ccs profile (`claude-spt:glm`) is a valid fallback target. Reconcile CONTEXT.md wording
   (currently "ccs, its own adapter"). (Not directly verified in investigation — confirm.)

## Already EXISTS — no M12 work (investigation 2026-06-14, good news)
- **Psyche cross-machine sync = automatic** (M4-D6c, P2P over Iroh; `crates/spt-daemon/src/sync.rs`,
  `pump/sync.rs`). tracked/ replicates in-subnet by default; gh-repo `psyche-sync-setup`
  RETIRED to optional hub-mode. → spt-claude-code `/spt:setup` #8 reduces to a rare opt-in.
- **`spt endpoint fork <src> <new_id>` exists** (cross-subnet copy, same-node). Forking IS a
  first-class CLI offering. (`cli.rs:221`)
- **`spt endpoint shutdown` (graceful) + `spt endpoint stop` (soft)** exist, topology-aware
  via qualified addressing. (`cli.rs:261,273`)
- **`spt whoami` + `spt endpoint list` (self pinned `SELF:` at top)** both exist; both stay
  in the agent hot-path.

## M12 small change (revised former #5)
5. **`spt whoami` → alias for `spt endpoint list`** (operator 2026-06-14). whoami stays in the
   hot path but becomes an alias; the SELF-pin output in `endpoint list` must additionally
   include the Self endpoint's **`spt endpoint description`**. (Not obsolescence — a merge so
   the whoami-equivalent output carries the description.)

## Notes
- M10 `[digest]` extractor seam already shipped (CC-JSONL consumer = spt-claude-code) —
  listed for traceability, not an M12 item.
- Cross-reference: `../spt-claude-code/SCOPE.md` (downstream consumer ledger).
