# Project Research Summary

**Project:** SPT v1.7.1 Seamlessification II
**Domain:** Native Rust binary + Claude Code plugin skill UX polish
**Researched:** 2026-05-16
**Confidence:** HIGH

## Executive Summary

v1.7.1 is a pure polish iteration on an already-shipped, mature codebase (~24K LOC Rust + skill markdown). All six items are implementable within the existing stack with zero new crates, zero new hook event types, and zero schema-breaking changes. The dominant characteristic of this milestone is careful evolution of an already-complex live-agent system where multiple subsystems (pick-spec JSON contract, SessionStart hook, binary handoff lifecycle, skill frontmatter YAML) are tightly coupled and sensitive to ordering and atomicity.

The recommended approach sequences phases so that the Item 4 pick-spec bug fix lands first (it unblocks Items 3 and 5), followed by the foundational list overhaul with argument-hint audit (Items 1+2), then the dependent UX flows sharing the live/SKILL.md dispatch table (Items 3+5 together), with Item 6 changelog notification last due to its CHANGELOG.md prerequisite and SessionStart hook coupling with Item 5. This reconciles the FEATURES.md recommendation (phase Item 4 first) with the ARCHITECTURE.md Wave grouping (Wave 1 = Items 1+2+6, Wave 2 = Item 4, Wave 3 = Items 3+5). Item 4 is promoted to Phase 1 because CP-3, CP-4, and MP-3 all depend on its corrected pick-spec shape, and its test update carries the highest mechanical blast radius.

The three critical risks are: (a) the pick-spec v1 schema freeze, where the fix must introduce a new kind:all-live variant rather than reshaping existing kinds; (b) the SessionStart auto-surface (Item 5) firing inside subagent sessions, requiring an allow-list gating on source=startup plus handoff/wrapper env flags; and (c) the version-sentinel (Item 6) race against binary handoff, requiring compiled-in CARGO_PKG_VERSION only (never plugin.json at runtime), with atomic-write-then-rename. All three have concrete prevention strategies grounded in established codebase patterns.

---

## Key Findings

### Recommended Stack

No new dependencies. The existing stack (Rust 2021, clap 4.6 derive, serde_json, rusqlite, chrono, ctrlc, windows-sys, libc) is fully sufficient for every item. The single-binary, zero-runtime-deps constraint is preserved. clap ArgGroup handles --all / --offline mutual exclusion. std::env::current_dir (already imported in 13 source files) handles --here without git2. env!(CARGO_PKG_VERSION) (already used at 3 sites) handles version-sentinel. The include_str! pattern (used for psyche.md) handles changelog embedding. One prerequisite not in-tree: CHANGELOG.md at repo root must be created before Item 6 can proceed.

**Core technologies:**
- Rust 2021 / clap 4.6 derive: CLI parsing; ArgGroup covers mutually-exclusive flags; no new patterns needed
- serde / serde_json: pick-spec JSON envelope; Item 4 is an additive kind:all-live variant; schema-v1 preserved
- std::env + std::fs: --here cwd matching and version-sentinel I/O; existing helpers sufficient
- SessionStart / PreToolUse hooks: Item 5 auto-surface + Item 6 changelog prompt; same additionalContext XML pattern as Phase 28
- env!(CARGO_PKG_VERSION): compiled-in version truth for Item 6; already used at 3 call sites; never use plugin.json at runtime

### Expected Features

**Must have (table stakes) -- Item 1 list overhaul:**
- Default online-only (matches git branch, docker ps convention)
- --all includes offline; --offline is offline-only (3-state enum, not bitflags); --here filters by info.json.cwd; --all/--offline mutually exclusive; --here orthogonal
- Empty-online-list emits discovery hint: No online listeners. Pass --all to include offline perches.

**Must have (table stakes) -- Item 2 argument-hint:**
- 3 skills definitively missing argument-hint: list-ready, list-live, list-psyche (PITFALLS.md grep confirmed; FEATURES.md all-17-covered claim self-contradicted by its own audit table -- see Gaps)
- ~5 existing hints inaccurate: commune should be empty string; psyche-download should be optional id; whoami should standardize to empty string
- YAML safety: any hint with pipe, hash, colon, or braces must be quoted

**Must have (table stakes) -- Item 3 fresh-start commune:**
- Triggers: pick-spec kind:prompt-new, OR pick-spec --resolve returns no history anywhere, OR psyche-download returns NO-CONTEXT
- Non-blocking: fires AFTER $LIVE start returns; single .first-commune-sent sentinel prevents double-fire
- Suppress for cross-repo reuse, stale-but-non-empty psyche, fork, revive with on-disk psyche
- Distinguish fresh psyche from clear-psyche via cleared_at metadata

**Must have (table stakes) -- Item 4 pick-spec bug:**
- Bug at src/live/pick_spec.rs:146-151: filter excludes online agents, emptying candidates when all known agents are live
- Fix: new kind:all-live variant (additive only); online bool per candidate in kind:pick; update test pick_one_online_agent_filters_to_prompt_new which currently codifies the bug

**Must have (table stakes) -- Item 5 --auto + casual activation:**
- --auto picks most-recent offline agent + confirmation hop; SessionStart auto-surface with CP-3 allow-list
- Casual triggers to add: resume my agent, wake up my agent, resume live; reject bare keep going and resume work
- CP-4 layered detection: short prompt + no quotes + word-boundary regex + AskUserQuestion confirm before any start

**Must have (table stakes) -- Item 6 version-change changelog:**
- $SPT_HOME/last-seen-version.json sentinel; first-install = write silently, no prompt
- Multi-version skip: show version list only, not full prose; link to CHANGELOG.md

**Should have (differentiators):**
- Item 1: stderr hint when online list is empty
- Item 4: kind:auto carries also_live array for one-offline-plus-several-live case
- Item 5: confirmation hop surfaces last commune body summary
- Item 6: dismissed_versions field in sentinel (ship core first)

**Defer to v1.8+:**
- Item 5: task-level obvious-next-work auto-resume
- Item 6: dismiss-changelog skill
- Item 2: DEPLOY.ps1 frontmatter validation gate (ship as test; DEPLOY integration follow-on)

### Architecture Approach

v1.7.1 touches three architectural layers cleanly: (1) Rust binary modules (pick_spec.rs, list.rs), (2) the SessionStart hook XML injection pipeline, and (3) skill markdown YAML frontmatter. These layers are separated -- Rust changes do not touch skill markdown. The critical coupling: Items 3, 4, and 5 all share the pick-spec JSON contract and live/SKILL.md dispatch table and must be planned with Item 4 landing first. Items 5 and 6 both extend plugin-session-start and should be sequenced across separate phases to avoid file conflicts.

**Major components affected:**
1. src/live/pick_spec.rs -- Item 4 fix; schema-v1 frozen contract preserved via new kind
2. src/owl/list.rs + src/live/list.rs -- Item 1; src/live/list.rs has no flag at all currently (larger refactor than OWL side)
3. plugin-session-start hook -- Items 5 and 6 both extend; sequence them across separate phases
4. plugin/spt/skills/live/SKILL.md -- Items 3, 4, and 5 all modify dispatch table; treat as shared resource
5. plugin/spt/skills/list-ready + list-live + list-psyche SKILL.md -- Item 2 additions
6. $SPT_HOME/last-seen-version.json -- new per-user state for Item 6; sibling to owlery/, not inside it

### Critical Pitfalls

1. **CP-1 -- Version-sentinel handoff race [Item 6]:** Old and new owl.exe briefly coexist during deploy. Using plugin.json as version-of-record can cause sentinel to be written by the wrong binary. Prevention: env!(CARGO_PKG_VERSION) only; single write site at top-level SessionStart after user sees prompt; atomic_write_string (tmp + rename).

2. **CP-2 -- First-install silent-write [Item 6]:** Missing sentinel must write current version silently (no prompt). Otherwise every new user sees a spurious changelog on their first session. Gate prompt on last_seen != current_version, not on sentinel existence.

3. **CP-3 -- SessionStart auto-surface fires in subagents [Item 5]:** plugin-session-start fires in psyche-wrapper and GSD researcher sessions. Allow-list requires: source=startup AND no OWL_HANDOFF_CHILD AND no SPT_PSYCHE_WRAPPER AND parent_pid not in owlery. Reject silently (no stderr -- leaks into subagent transcripts).

4. **CP-4 -- Casual-language false-positives [Item 5]:** Pastes, quoted docs, and code containing resume/continue match naively. Layered detection required: prompt under 80 chars + no quote chars + word-boundary regex + mandatory AskUserQuestion confirm hop before any $LIVE start.

5. **MP-3 -- pick-spec v1 schema break [Item 4]:** Reshaping existing pick/prompt-new kinds breaks the frozen contract and silently mis-dispatches the SKILL. Prevention: additive new kind:all-live only; online bool as additive per-entry field in kind:pick; all existing kind-asserting tests must pass unmodified.

---

## Implications for Roadmap

Based on combined research, the recommended structure is 4 phases. The FEATURES.md vs ARCHITECTURE.md tension (Item 4 first vs Wave 1 = Items 1+2+6) is resolved by prioritizing the item with the highest downstream unblocking value and most sensitive test mutation.

### Phase 1: pick-spec Correctness (Item 4)

**Rationale:** Only actual bug fix in the milestone. Unblocks Items 3 and 5 (both depend on corrected pick-spec shape). Test pick_one_online_agent_filters_to_prompt_new currently codifies the wrong behavior -- updating it is the highest-blast-radius mechanical change and should not be deferred.

**Delivers:** kind:all-live variant; online bool per candidate in kind:pick; live/SKILL.md dispatch branch for all-live repos; updated tests

**Addresses:** Item 4 table stakes. Prerequisite for Items 3 and 5.

**Avoids:** MP-3 -- additive new kind only, existing kinds untouched

**Research flag:** Skip /gsd-research-phase -- fix location, strategy, and test update path all confirmed in research.

---

### Phase 2: list Overhaul + argument-hint Audit (Items 1 + 2)

**Rationale:** Mechanically independent from Phase 1. Items 1 and 2 are naturally coupled (new list flags require new argument-hints on list-* skills). Batching avoids a second DEPLOY cycle. src/live/list.rs currently has no flags -- scope this explicitly.

**Delivers:** 3-state list enum (--all/--offline/--here); --here cwd-filter with graceful legacy degradation; argument-hint on all 17 skills (3 added, ~5 corrected); YAML safety conventions; golden test fixture regeneration; empty-online discovery message

**Addresses:** Items 1 and 2 table stakes

**Avoids:** MP-1 (default-change breaks golden tests); MP-2 (YAML regression); MP-5 (--here cwd edge cases); MP-6 (stdin-arg confusion)

**Research flag:** Skip /gsd-research-phase. Phase plan should begin with src/live/list.rs scope audit and InfoJson.cwd universality check.

---

### Phase 3: Fresh-Start Commune + --auto / Casual Activation (Items 3 + 5)

**Rationale:** Both items modify live/SKILL.md dispatch table and both depend on Phase 1 pick-spec shape. Planning them together prevents the dispatch table being in a half-consistent state. Item 5 SessionStart extension lands here (not Phase 4) to keep the two hook extensions in separate phases.

**Delivers:** First-commune invitation flow (non-blocking, .first-commune-sent sentinel, Path A/B disambiguation, cleared_at guard); /spt:live --auto flag with confirmation hop; SessionStart pick-spec auto-surface with CP-3 allow-list; casual-language trigger phrases with CP-4 layered detection; --auto added to live skill argument-hint

**Addresses:** Items 3 and 5 table stakes and differentiators

**Avoids:** MP-4 (boot block + double-fire); CP-3 (subagent misfires); CP-4 (false-positives); MP-8 (prompt fatigue)

**Research flag:** Phase plan must include an explicit design spike section for the CP-3 allow-list predicate and a CP-4 test corpus (15+ should-fire, 15+ should-NOT-fire cases). Not a full /gsd-research-phase but these design steps are required before coding begins.

---

### Phase 4: Version-Change Changelog Notification (Item 6)

**Rationale:** Fully independent at the Rust level. Sequenced last because CHANGELOG.md prerequisite must be verified/created first; SessionStart hook extension sequences cleanly after Phase 3; sentinel design is simpler to reason about when the hook is stable.

**Delivers:** CHANGELOG.md at repo root (prerequisite, created if absent); $SPT_HOME/last-seen-version.json sentinel; owl.exe version-check subcommand; SessionStart hook version-mismatch prompt; first-install silent write; multi-version skip summary

**Addresses:** Item 6 table stakes and differentiator

**Avoids:** CP-1 (handoff race); CP-2 (first-install friction); MP-7 (version-skip text wall); MP-9 (installed_plugins.json temptation)

**Research flag:** Skip /gsd-research-phase. Phase plan must begin with CHANGELOG.md existence check and decide excerpt parsing format (H2 per version recommended).

---

### Phase Ordering Rationale

- Item 4 first: only bug fix, highest downstream unblocking value, test update has broadest blast radius
- Items 1+2 batched: mechanically independent, naturally coupled on skill frontmatter, avoids second DEPLOY cycle
- Items 3+5 batched: shared live/SKILL.md resource, both depend on Phase 1, SessionStart hook isolated from Phase 4
- Item 6 last: CHANGELOG.md prerequisite, SessionStart hook kept separate from Phase 3
- Single DEPLOY.ps1 -Bump patch at end-of-milestone (not per-phase) to avoid version-churn during in-flight binary handoffs

### Research Flags

Phases needing focused design attention:
- **Phase 3 (Items 3+5):** CP-3 allow-list classification and CP-4 test corpus are novel. Explicit pre-coding design steps required. No full /gsd-research-phase needed.
- **Phase 4 (Item 6):** Must begin with CHANGELOG.md creation if absent. Specify H2-per-version format for excerpt parsing.

Phases with standard patterns (skip /gsd-research-phase):
- **Phase 1 (Item 4):** Code location confirmed, schema strategy documented, test update path clear
- **Phase 2 (Items 1+2):** clap ArgGroup, 3-state enum, YAML audit -- all patterns documented

---

## Confidence Assessment

| Area | Confidence | Notes |
|------|------------|-------|
| Stack | HIGH | All technologies verified in-tree; zero new crates; argument-hint spec confirmed against official Claude Code docs (2026-05-16) |
| Features | HIGH | Every item grounded in specific file:line references; bug location confirmed; schema contract verified; FEATURES.md and PITFALLS.md cross-validate |
| Architecture | MEDIUM | ARCHITECTURE.md is the Phase 18 design document (2026-03-29, pre-v1.7); IPC architecture already shipped. Wave ordering superseded by current-state reconciliation |
| Pitfalls | HIGH | Grounded in codebase reads; every critical pitfall has file+line reference, named test, and prevention strategy from existing conventions |

**Overall confidence:** HIGH

### Gaps to Address

- **CHANGELOG.md existence [Phase 4 prerequisite]:** Not verified to exist at repo root. Phase 4 must begin with existence check; create from git log if absent.
- **info.json.cwd universality [Phase 2]:** STACK.md flags medium confidence that all perches carry cwd. Phase 2 plan should audit InfoJson serialization sites before implementing --here. If gaps found, add cwd backfill at start/revive in same phase.
- **argument-hint count discrepancy [Phase 2]:** STACK.md says 14/17. FEATURES.md says all 17 covered but its own audit table lists 3 as missing. PITFALLS.md grep confirms 3 missing: list-ready, list-live, list-psyche. Resolution: 3 definitively missing. Phase 2 executor should re-grep before proceeding.
- **src/live/list.rs scope [Phase 2]:** PITFALLS.md notes src/live/list.rs runs unconditional (no flag). The LIVE list refactor is larger than the OWL side. Phase 2 plan should explicitly scope this delta.

---

## Sources

### Primary (HIGH confidence)

- src/live/pick_spec.rs:146-151, :16-21, :447 (in-repo) -- bug location, schema-freeze contract, test codifying buggy behavior
- src/owl/list.rs:20, src/live/list.rs:19 (in-repo) -- current entry point signatures
- src/common/types.rs:51 (in-repo) -- InfoJson.cwd field confirmed
- plugin/spt/skills/*/SKILL.md frontmatter grep (in-repo) -- 14/17 have argument-hint; 3 missing confirmed
- plugin/spt/hooks/hooks.json (in-repo) -- SessionStart / SubagentStart hook wiring verified
- docs/DEPLOY.md (in-repo) -- Phase 18.4/18.5 handoff constraints; atomic step 8
- .planning/STATE.md (in-repo) -- schema-freeze decision 26-03; atomic_write_string convention Phase 18.8
- Cargo.toml (in-repo) -- crate versions confirmed; zero new crates
- https://code.claude.com/docs/en/slash-commands -- argument-hint stable field spec; fetched 2026-05-16
- https://github.com/anthropics/claude-code/blob/main/plugins/plugin-dev/skills/command-development/references/frontmatter-reference.md -- frontmatter contract

### Secondary (MEDIUM confidence)

- ARCHITECTURE.md (in-repo, researched 2026-03-29) -- IPC design rationale; Wave ordering superseded
- https://github.com/anthropics/claude-code/issues/31462 -- no built-in plugin update notification in Claude Code
- https://github.com/anthropics/claude-code/issues/50153 -- update notification feature request, not shipped

### Tertiary (LOW confidence)

- CHANGELOG.md at repo root -- existence unverified; Phase 4 prerequisite check required

---
*Research completed: 2026-05-16*
*Ready for roadmap: yes*
