Edit

# `send` / `commune` / `signoff` are DELIBERATELY NOT injected here (2026-06-19). A live agent uses
# them REACTIVELY — replying to a message, briefing its Psyche, signing off — WITHOUT the user typing
# `/sptc:<skill>`, so UPS-injection (which fires only on that slash-command in the prompt) is the wrong
# delivery. Their full operative bodies live in the plugin SKILL.md (full-fat, always model-loadable);
# there is no `[strings.skills]` entry and no adapter aux body for them. (sptc_inject_skill no-ops
# silently on the absent key — the full SKILL.md is the single source.)

# `send` / `commune` / `signoff` are NOT injected here — but NOT because their prose lives in the
# plugin SKILL.md (it no longer does; U4/REQ-DIST-SKELETON-THIN thinned those to stubs, 2026-06-25,
# superseding the 2026-06-19 full-fat-SKILL.md decision). The reason they aren't UPS skills stands: a
# live agent uses them REACTIVELY (replying, briefing its Psyche, signing off) WITHOUT typing
# `/sptc:<skill>`, so UPS-injection is the wrong delivery. Instead the prose is delivered PROACTIVELY:
# `send` rides the `messaging-perch` brief; `commune` (incl `--checkpoint`) + `signoff` ride the new
# `live-ops` brief (below) — both composed into the perched SessionStart brief — and the go-live
# moment carries them inline in `skills/live.md`. So the prose rides `spt adapter update`, the plugin
# SKILL.md stays a true skeleton, and there is no `[strings.skills]` entry for these three.


The file C:\Users\decid\Documents\projects\spt-claude-code\adapter\claude-spt.toml has been updated successfully. (file state is current in your context — no need to Read it back)

# `send` / `commune` / `signoff` are DELIBERATELY NOT injected here (2026-06-19). A live agent uses
# them REACTIVELY — replying to a message, briefing its Psyche, signing off — WITHOUT the user typing
# `/sptc:<skill>`, so UPS-injection (which fires only on that slash-command in the prompt) is the wrong
# delivery. Their full operative bodies live in the plugin SKILL.md (full-fat, always model-loadable);
# there is no `[strings.skills]` entry and no adapter aux body for them. (sptc_inject_skill no-ops
# silently on the absent key — the full SKILL.md is the single source.)

# `send` / `commune` / `signoff` are NOT injected here — but NOT because their prose lives in the
# plugin SKILL.md (it no longer does; U4/REQ-DIST-SKELETON-THIN thinned those to stubs, 2026-06-25,
# superseding the 2026-06-19 full-fat-SKILL.md decision). The reason they aren't UPS skills stands: a
# live agent uses them REACTIVELY (replying, briefing its Psyche, signing off) WITHOUT typing
# `/sptc:<skill>`, so UPS-injection is the wrong delivery. Instead the prose is delivered PROACTIVELY:
# `send` rides the `messaging-perch` brief; `commune` (incl `--checkpoint`) + `signoff` ride the new
# `live-ops` brief (below) — both composed into the perched SessionStart brief — and the go-live
# moment carries them inline in `skills/live.md`. So the prose rides `spt adapter update`, the plugin
# SKILL.md stays a true skeleton, and there is no `[strings.skills]` entry for these three.

list-agents = { file = "skills/list-agents.md" } # -> spt endpoint list (the roster)

force-stop = { file = "skills/force-stop.md" } # -> spt endpoint shutdown (graceful, tears down Psyche)

subnet = { file = "skills/subnet.md" }         # -> spt subnet {status,create,show-code,join} (cross-machine); REQ-SKILL-SUBNET

-# `send` / `commune` / `signoff` are DELIBERATELY NOT injected here (2026-06-19). A live agent uses

-# them REACTIVELY — replying to a message, briefing its Psyche, signing off — WITHOUT the user typing

-# `/sptc:<skill>`, so UPS-injection (which fires only on that slash-command in the prompt) is the wrong

-# delivery. Their full operative bodies live in the plugin SKILL.md (full-fat, always model-loadable);

-# there is no `[strings.skills]` entry and no adapter aux body for them. (sptc_inject_skill no-ops

-# silently on the absent key — the full SKILL.md is the single source.)

+# `send` / `commune` / `signoff` are NOT injected here — but NOT because their prose lives in the

+# plugin SKILL.md (it no longer does; U4/REQ-DIST-SKELETON-THIN thinned those to stubs, 2026-06-25,

+# superseding the 2026-06-19 full-fat-SKILL.md decision). The reason they aren't UPS skills stands: a

+# live agent uses them REACTIVELY (replying, briefing its Psyche, signing off) WITHOUT typing

+# `/sptc:<skill>`, so UPS-injection is the wrong delivery. Instead the prose is delivered PROACTIVELY:

+# `send` rides the `messaging-perch` brief; `commune` (incl `--checkpoint`) + `signoff` ride the new

+# `live-ops` brief (below) — both composed into the perched SessionStart brief — and the go-live

+# moment carries them inline in `skills/live.md`. So the prose rides `spt adapter update`, the plugin

+# SKILL.md stays a true skeleton, and there is no `[strings.skills]` entry for these three.

# `live` -> upgrade THIS session to a LiveAgent (Option A, 2026-06-17): base claude-spt is live-capable

# ([session.psyche_init] in base), so going live is just the COMMAND — bare `spt api listen <id>` under

# a Monitor relay. The live listen path stamps the perch state=live_agent → the daemon livehost hosts


identity = { file = "briefs/identity.md" }                      # {id}-templated: who + perch-live + don't-re-arm
messaging-perch = { file = "briefs/messaging-perch.md" }        # has-id reach: spt send + reply
messaging-no-perch = { file = "briefs/messaging-no-perch.md" }  # no-id reach: spt ring
endpoint-list = "Show the roster of spt endpoints reachable from this node: `spt endpoint list`."  # shared one-liner (inline)

identity = { file = "briefs/identity.md" }                      # {id}-templated: who + perch-live + don't-re-arm
messaging-perch = { file = "briefs/messaging-perch.md" }        # has-id reach: spt send + reply
messaging-no-perch = { file = "briefs/messaging-no-perch.md" }  # no-id reach: spt ring
live-ops = { file = "briefs/live-ops.md" }                      # commune (incl --checkpoint) + signoff (U4); composed into the perched brief
endpoint-list = "Show the roster of spt endpoints reachable from this node: `spt endpoint list`."  # shared one-liner (inline)


Verify PreToolUse message polling and injection


identity = { file = "briefs/identity.md" }                      # {id}-templated: who + perch-live + don't-re-arm
messaging-perch = { file = "briefs/messaging-perch.md" }        # has-id reach: spt send + reply
messaging-no-perch = { file = "briefs/messaging-no-perch.md" }  # no-id reach: spt ring
endpoint-list = "Show the roster of spt endpoints reachable from this node: `spt endpoint list`."  # shared one-liner (inline)

identity = { file = "briefs/identity.md" }                      # {id}-templated: who + perch-live + don't-re-arm
messaging-perch = { file = "briefs/messaging-perch.md" }        # has-id reach: spt send + reply
messaging-no-perch = { file = "briefs/messaging-no-perch.md" }  # no-id reach: spt ring
live-ops = { file = "briefs/live-ops.md" }                      # commune (incl --checkpoint) + signoff (U4); composed into the perched brief
endpoint-list = "Show the roster of spt endpoints reachable from this node: `spt endpoint list`."  # shared one-liner (inline)

+live-ops = { file = "briefs/live-ops.md" }                      # commune (incl --checkpoint) + signoff (U4); composed into the perched brief

# ── [[hints]] ──────────────────────────────────────────────────────────────────────────────


3. Wire `live-ops` into the perched brief (append to messaging block — keeps the pure assembler + its test unchanged):


# Impure: resolve + assemble the perched-session identity brief for id $1. [impl->REQ-DIST-SESSIONSTART-BRIEF]
sptc_perch_brief() {
  sptc_assemble_perch "$1" "$(sptc_brief identity)" "$(sptc_brief messaging-perch)" "$(sptc_brief endpoint-list)"
}

# Impure: resolve + assemble the perched-session identity brief for id $1. The live-ops block
# (commune incl --checkpoint, signoff — REQ-DIST-SKELETON-THIN/U4) is appended to the messaging block
# so a perched/live agent is briefed on upkeep proactively (the reactive /sptc:commune|signoff SKILL.md
# are now thin stubs). Composed into messaging (not a new positional) so sptc_assemble_perch + its unit
# test stay unchanged; skipped cleanly if the live-ops string is absent (older adapter).
# [impl->REQ-DIST-SESSIONSTART-BRIEF] [impl->REQ-DIST-SKELETON-THIN]
sptc_perch_brief() {
  _msg="$(sptc_brief messaging-perch)"
  _ops="$(sptc_brief live-ops)"
  [ -n "$_ops" ] && _msg="$_msg

$_ops"
  sptc_assemble_perch "$1" "$(sptc_brief identity)" "$_msg" "$(sptc_brief endpoint-list)"
}


The file C:\Users\decid\Documents\projects\spt-claude-code\plugin\sptc\hooks\_common.sh has been updated successfully. (file state is current in your context — no need to Read it back)

# Impure: resolve + assemble the perched-session identity brief for id $1. [impl->REQ-DIST-SESSIONSTART-BRIEF]
sptc_perch_brief() {
  sptc_assemble_perch "$1" "$(sptc_brief identity)" "$(sptc_brief messaging-perch)" "$(sptc_brief endpoint-list)"
}

# Impure: resolve + assemble the perched-session identity brief for id $1. The live-ops block
# (commune incl --checkpoint, signoff — REQ-DIST-SKELETON-THIN/U4) is appended to the messaging block
# so a perched/live agent is briefed on upkeep proactively (the reactive /sptc:commune|signoff SKILL.md
# are now thin stubs). Composed into messaging (not a new positional) so sptc_assemble_perch + its unit
# test stay unchanged; skipped cleanly if the live-ops string is absent (older adapter).
# [impl->REQ-DIST-SESSIONSTART-BRIEF] [impl->REQ-DIST-SKELETON-THIN]
sptc_perch_brief() {
  _msg="$(sptc_brief messaging-perch)"
  _ops="$(sptc_brief live-ops)"
  [ -n "$_ops" ] && _msg="$_msg

$_ops"
  sptc_assemble_perch "$1" "$(sptc_brief identity)" "$_msg" "$(sptc_brief endpoint-list)"
}

printf '<sptc-reach>\n%s\n\n%s\n</sptc-reach>' "$1" "$2"

-# Impure: resolve + assemble the perched-session identity brief for id $1. [impl->REQ-DIST-SESSIONSTART-BRIEF]

+# Impure: resolve + assemble the perched-session identity brief for id $1. The live-ops block

+# (commune incl --checkpoint, signoff — REQ-DIST-SKELETON-THIN/U4) is appended to the messaging block

+# so a perched/live agent is briefed on upkeep proactively (the reactive /sptc:commune|signoff SKILL.md

+# are now thin stubs). Composed into messaging (not a new positional) so sptc_assemble_perch + its unit

+# test stay unchanged; skipped cleanly if the live-ops string is absent (older adapter).

-  sptc_assemble_perch "$1" "$(sptc_brief identity)" "$(sptc_brief messaging-perch)" "$(sptc_brief endpoint-list)"

+  sptc_assemble_perch "$1" "$(sptc_brief identity)" "$_msg" "$(sptc_brief endpoint-list)"

# Impure: resolve + assemble the no-perch ring brief. [impl->REQ-DIST-SESSIONSTART-BRIEF]


4. Expand `live.md` step 5 to inline the commune/signoff mechanics (go-live agent gets no SessionStart brief):


5. **Across boundaries.** Use `/sptc:commune` to push a context delta after significant bodies of work.
   To go offline gracefully, use `/sptc:signoff`.

5. **Across boundaries — commune + signoff (you are live now, so these apply to you).** Going live in
   this session does NOT re-fire your SessionStart brief, so here are the mechanics:
   - **Commune** after a significant body of work, before a `/clear`/`/compact`: write
     `.claude/<id>-commune.md` in ONE atomic write — a concise delta (task + status, decisions,
     immediate next steps), NOT a transcript. The daemon ingests + deletes it; the file disappearing is
     success. It is what rebuilds you after a reset.
   - **Checkpoint** = a commune that ALSO wipes + rebuilds your context from it (agent-driven `/clear`):
     embed `!!checkpoint!!` in the body — one marker ⇒ default wake; a PAIR ⇒ the text between them is
     your custom wake directive. Author it inline this turn; the clear+wake fire automatically.
   - **Sign off** when done: `spt endpoint shutdown` — stops the listener, saves final context, takes
     your Psyche down. `/sptc:ready`/`/sptc:live` brings you back.


The file C:\Users\decid\Documents\projects\spt-claude-code\adapter\strings\skills\live.md has been updated successfully. (file state is current in your context — no need to Read it back)

5. **Across boundaries — commune + signoff (you are live now, so these apply to you).** Going live in
   this session does NOT re-fire your SessionStart brief, so here are the mechanics:
   - **Commune** after a significant body of work, before a `/clear`/`/compact`: write
     `.claude/<id>-commune.md` in ONE atomic write — a concise delta (task + status, decisions,
     immediate next steps), NOT a transcript. The daemon ingests + deletes it; the file disappearing is
     success. It is what rebuilds you after a reset.
   - **Checkpoint** = a commune that ALSO wipes + rebuilds your context from it (agent-driven `/clear`):
     embed `!!checkpoint!!` in the body — one marker ⇒ default wake; a PAIR ⇒ the text between them is
     your custom wake directive. Author it inline this turn; the clear+wake fire automatically.
   - **Sign off** when done: `spt endpoint shutdown` — stops the listener, saves final context, takes
     your Psyche down. `/sptc:ready`/`/sptc:live` brings you back.

# /sptc:live — operative instructions

**Goal:** upgrade this Claude Code session to a **LiveAgent** — a reachable agent whose context is
backed by a **Psyche** (a daemon-managed companion that briefs your resume across `/clear`/compact
via commune deltas). This makes the session you are in right now live.

## Bringup — do this

1. **Pick the perch id.** Use a short lowercase id from the user, or reuse this session's id from
   `spt whoami`. Call it `<id>`. SessionStart already seeded this session's perch — do not re-seed.
2. **Run the relay as a single PERSISTENT background task** via the **Monitor** tool. One resident
   process IS the live delivery pipe. The body is one bare command:

   ### Invocation (Monitor)

   Invoke `spt api listen <id>` via the Monitor tool with:
   - `command: "spt api listen <id>"`
   - `persistent: true`
   - `description: "« spt event »"`

   - `spt api listen` enters the poll loop inline; the stream stays alive across messages and emits
   one `<EVENT type="msg|alarm|echo_commune|init_signoff" ...>body</EVENT>` line per delivery.
   - It **blocks for the session's life**: backlog drains first, then each delivery streams to stdout.
3. **Readiness.** The relay output will show `BOUND:<id>`, then `READY:<id>`. Check it only if
   connectivity complications are encountered.
4. **Reply.** Inbound messages arrive as `<EVENT type="msg" from="<sender>">body</EVENT>` (body
   HTML-escaped, newlines `<br>`). To reply, pipe the message body as stdin to `spt send <sender-id>`.
5. **Across boundaries.** Use `/sptc:commune` to push a context delta after significant bodies of work.
   To go offline gracefully, use `/sptc:signoff`.

## Output — what the user sees

The relay emits machine markers (`BOUND:<id>`, `READY:<id>`, raw tokens). **Read them to drive
bringup; never echo them to the user.** The only user-facing surface is the LIVE block below — emit
it verbatim (substituting `<id>`), and nothing else from bringup:

```
**LIVE.** Now running as `<id>`.
- Reachable — other agents reach me with `/sptc:send <id>`.
- Inbound — messages arrive via the Monitor.
- Across resets — `/sptc:commune` before a `/clear`/`/compact`; `/sptc:signoff` to go offline.
```

If bringup fails, report a short plain-language failure and the likely cause (run `/sptc:setup`),
still without dumping the raw markers.
<!-- [doc->REQ-SKILL-LIVE] -->

-5. **Across boundaries.** Use `/sptc:commune` to push a context delta after significant bodies of work.

-   To go offline gracefully, use `/sptc:signoff`.

+5. **Across boundaries — commune + signoff (you are live now, so these apply to you).** Going live in

+   this session does NOT re-fire your SessionStart brief, so here are the mechanics:

+   - **Commune** after a significant body of work, before a `/clear`/`/compact`: write

+     `.claude/<id>-commune.md` in ONE atomic write — a concise delta (task + status, decisions,

+     immediate next steps), NOT a transcript. The daemon ingests + deletes it; the file disappearing is

+     success. It is what rebuilds you after a reset.

+   - **Checkpoint** = a commune that ALSO wipes + rebuilds your context from it (agent-driven `/clear`):

+     embed `!!checkpoint!!` in the body — one marker ⇒ default wake; a PAIR ⇒ the text between them is

+     your custom wake directive. Author it inline this turn; the clear+wake fire automatically.

+   - **Sign off** when done: `spt endpoint shutdown` — stops the listener, saves final context, takes

+     your Psyche down. `/sptc:ready`/`/sptc:live` brings you back.


5. Thin the three SKILL.md → stubs (keep frontmatter for discovery; body redirects to the proactive delivery):


Write

---
name: commune
description: |
  Push a context update to your Psyche so it can brief your resume across a reset. Use when the
  user says "commune" or "update psyche", or — as a live agent — after a significant body of work,
  before a /clear or /compact. Pass --checkpoint to ALSO auto-clear and wake yourself from the
  freshest commune (an agent-driven context reset, no operator needed).
allowed-tools: [Bash, Write]
---

<!-- [doc->REQ-DIST-CHECKPOINT-COMMUNE] [doc->REQ-DIST-SKELETON-THIN] -->

# /sptc:commune

**Live agents only.** No perch (`spt whoami` is empty)? Run **`/sptc:live`** first — a ready agent
has no Psyche and nothing to rebuild from.

The operative commune + `--checkpoint` mechanics are delivered by the adapter, not baked here: a live
agent already carries them in its **SessionStart brief** (the `live-ops` block) and in the **`/sptc:live`
go-live body**. (Thin skeleton — the prose rides `spt adapter update`; ADR-0001/ADR-0006.) In short:
write `.claude/<id>-commune.md` as one atomic context delta; add the `!!checkpoint!!` trigger (a pair
of markers brackets a custom wake) to also self-reset.


<tool_use_error>File has not been read yet. Read it first before writing to it.</tool_use_error>

Error: File has not been read yet. Read it first before writing to it.


1	---
2	name: commune
3	description: |
4	  Push a context update to your Psyche so it can brief your resume across a reset. Use when the
5	  user says "commune" or "update psyche", or — as a live agent — after a significant body of work,
6	  before a /clear or /compact. Pass --checkpoint to ALSO auto-clear and wake yourself from the
7	  freshest commune (an agent-driven context reset, no operator needed).
8	allowed-tools: [Bash, Write]
9	---
10

---
name: commune
description: |
  Push a context update to your Psyche so it can brief your resume across a reset. Use when the
  user says "commune" or "update psyche", or — as a live agent — after a significant body of work,
  before a /clear or /compact. Pass --checkpoint to ALSO auto-clear and wake yourself from the
  freshest commune (an agent-driven context reset, no operator needed).
allowed-tools: [Bash, Write]
---


1	---
2	name: send
3	description: |
4	  Send a message to another SPT agent. Use when the user says "send to", "message",
5	  "tell <agent>", or when you need to reach or reply to another agent yourself.
6	argument-hint: "<target>"
7	allowed-tools: [Bash]
8	---
9
10	# /sptc:send

---
name: send
description: |
  Send a message to another SPT agent. Use when the user says "send to", "message",
  "tell <agent>", or when you need to reach or reply to another agent yourself.
argument-hint: "<target>"
allowed-tools: [Bash]
---

# /sptc:send


1	---
2	name: signoff
3	description: |
4	  Gracefully shut down your live session, saving a final context summary. Use when the user says
5	  "sign off" or "graceful stop", or when you (a live agent) are done and want to go offline cleanly.
6	allowed-tools: [Bash, Write]
7	---
8
9	# /sptc:signoff
10

---
name: signoff
description: |
  Gracefully shut down your live session, saving a final context summary. Use when the user says
  "sign off" or "graceful stop", or when you (a live agent) are done and want to go offline cleanly.
allowed-tools: [Bash, Write]
---

# /sptc:signoff


---
name: commune
description: |
  Push a context update to your Psyche so it can brief your resume across a reset. Use when the
  user says "commune" or "update psyche", or — as a live agent — after a significant body of work,
  before a /clear or /compact. Pass --checkpoint to ALSO auto-clear and wake yourself from the
  freshest commune (an agent-driven context reset, no operator needed).
allowed-tools: [Bash, Write]
---

<!-- [doc->REQ-DIST-CHECKPOINT-COMMUNE] [doc->REQ-DIST-SKELETON-THIN] -->

# /sptc:commune

**Live agents only.** No perch (`spt whoami` is empty)? Run **`/sptc:live`** first — a ready agent has
no Psyche and nothing to rebuild from.

The operative commune + `--checkpoint` mechanics are delivered by the adapter, not baked here (thin
skeleton — the prose rides `spt adapter update`; ADR-0001/ADR-0006): a live agent already carries them
in its **SessionStart brief** (the `live-ops` block) and in the **`/sptc:live` go-live body**. In short:
write `.claude/<id>-commune.md` as one atomic context delta (task + status, decisions, next steps);
add the `!!checkpoint!!` trigger to also self-reset (a PAIR of markers brackets a custom wake directive).


The file C:\Users\decid\Documents\projects\spt-claude-code\plugin\sptc\skills\commune\SKILL.md has been updated successfully. (file state is current in your context — no need to Read it back)

---
name: commune
description: |
  Push a context update to your Psyche so it can brief your resume across a reset. Use when the
  user says "commune" or "update psyche", or — as a live agent — after a significant body of work,
  before a /clear or /compact. Pass --checkpoint to ALSO auto-clear and wake yourself from the
  freshest commune (an agent-driven context reset, no operator needed).
allowed-tools: [Bash, Write]
---

<!-- [doc->REQ-DIST-CHECKPOINT-COMMUNE] [doc->REQ-DIST-SKELETON-THIN] -->

# /sptc:commune

**Live agents only.** No perch (`spt whoami` is empty)? Run **`/sptc:live`** first — a ready agent has
no Psyche and nothing to rebuild from.

The operative commune + `--checkpoint` mechanics are delivered by the adapter, not baked here (thin
skeleton — the prose rides `spt adapter update`; ADR-0001/ADR-0006): a live agent already carries them
in its **SessionStart brief** (the `live-ops` block) and in the **`/sptc:live` go-live body**. In short:
write `.claude/<id>-commune.md` as one atomic context delta (task + status, decisions, next steps);
add the `!!checkpoint!!` trigger to also self-reset (a PAIR of markers brackets a custom wake directive).

+<!-- [doc->REQ-DIST-CHECKPOINT-COMMUNE] [doc->REQ-DIST-SKELETON-THIN] -->

-Brief your Psyche with a context DELTA so it can carry you across a `/clear` or compact. **Live

-agents only** — a ready agent has no Psyche and nothing to rebuild from.

+**Live agents only.** No perch (`spt whoami` is empty)? Run **`/sptc:live`** first — a ready agent has

-This is a **file-drop, not an `api` verb**: you write the file, spt's daemon ingests it into your

-tracked mind, then deletes it. The file disappearing is the success signal.

-1. Get your id: `spt whoami` (empty ⇒ no perch — run `/sptc:live` first).

-2. Write `.claude/<id>-commune.md` in ONE atomic write — a concise delta, not a transcript:

-   - decisions made since your last commune,

-   - immediate next steps (so your post-reset self resumes without re-deriving).

-3. If the file lingers instead of disappearing, you are not live (no daemon ingesting it).

-## Checkpoint (`--checkpoint`) — self-initiated context reset

-A **checkpoint** is a commune that ALSO asks spt to wipe and rebuild your working context from that

-very commune — the agent-driven sibling of the operator manually running `/clear`. Use it when your

-context is getting long but you are mid-task and want to keep going coherently on your own.

-You request a checkpoint by embedding the literal **`!!checkpoint!!`** trigger in the commune body

-(the `--checkpoint` flag is just the cue to do this). Author the commune INLINE, right now, in this

-same turn — you are the authoring agent, pre-clear. Do NOT defer authoring to after the clear.

-Wake directive — what your resumed self is told to do first:

-- **One `!!checkpoint!!`** anywhere in the body ⇒ checkpoint with the DEFAULT wake,

-- **A PAIR of `!!checkpoint!!` markers** ⇒ the text BETWEEN them is your CUSTOM wake directive, e.g.

-  !!checkpoint!! Resume T2c: wire the binary checkpoint branch against doyle's reply. !!checkpoint!!

-  rebuilds your context, then wakes you with exactly that instruction.

-Mechanics (you don't drive these — they fire automatically once the file lands): your perch is marked

-idle, a reserved checkpoint signal self-sends back through your own endpoint, and the delivery layer

-runs the clear + wake. The commune you just wrote is what your Psyche rebuilds you from, so make it

-complete. **spt-hosted live sessions only** (the self-send loopback needs the broker-held PTY).

-1. `spt whoami` for your id (empty ⇒ not live; checkpoint is unavailable).

-2. Write `.claude/<id>-commune.md` with your full resume delta AND the `!!checkpoint!!` trigger

-   (single for the default wake, or a pair bracketing your custom wake).

-3. The clear + wake fire on their own. Your next turn is the post-checkpoint wake — continue from the

+The operative commune + `--checkpoint` mechanics are delivered by the adapter, not baked here (thin

+skeleton — the prose rides `spt adapter update`; ADR-0001/ADR-0006): a live agent already carries them

+in its **SessionStart brief** (the `live-ops` block) and in the **`/sptc:live` go-live body**. In short:

+write `.claude/<id>-commune.md` as one atomic context delta (task + status, decisions, next steps);

+add the `!!checkpoint!!` trigger to also self-reset (a PAIR of markers brackets a custom wake directive).

---
name: commune
description: |
  Push a context update to your Psyche so it can brief your resume across a reset. Use when the
  user says "commune" or "update psyche", or — as a live agent — after a significant body of work,
  before a /clear or /compact. Pass --checkpoint to ALSO auto-clear and wake yourself from the
  freshest commune (an agent-driven context reset, no operator needed).
allowed-tools: [Bash, Write]
---

<!-- [doc->REQ-DIST-CHECKPOINT-COMMUNE] -->

# /sptc:commune

Brief your Psyche with a context DELTA so it can carry you across a `/clear` or compact. **Live
agents only** — a ready agent has no Psyche and nothing to rebuild from.

This is a **file-drop, not an `api` verb**: you write the file, spt's daemon ingests it into your
tracked mind, then deletes it. The file disappearing is the success signal.

## Normal commune

1. Get your id: `spt whoami` (empty ⇒ no perch — run `/sptc:live` first).
2. Write `.claude/<id>-commune.md` in ONE atomic write — a concise delta, not a transcript:
   - current task + status,
   - decisions made since your last commune,
   - immediate next steps (so your post-reset self resumes without re-deriving).
3. If the file lingers instead of disappearing, you are not live (no daemon ingesting it).

## Checkpoint (`--checkpoint`) — self-initiated context reset

A **checkpoint** is a commune that ALSO asks spt to wipe and rebuild your working context from that
very commune — the agent-driven sibling of the operator manually running `/clear`. Use it when your
context is getting long but you are mid-task and want to keep going coherently on your own.

You request a checkpoint by embedding the literal **`!!checkpoint!!`** trigger in the commune body
(the `--checkpoint` flag is just the cue to do this). Author the commune INLINE, right now, in this
same turn — you are the authoring agent, pre-clear. Do NOT defer authoring to after the clear.

Wake directive — what your resumed self is told to do first:

- **One `!!checkpoint!!`** anywhere in the body ⇒ checkpoint with the DEFAULT wake,
  `Proceed with next steps`.
- **A PAIR of `!!checkpoint!!` markers** ⇒ the text BETWEEN them is your CUSTOM wake directive, e.g.

  ```
  !!checkpoint!! Resume T2c: wire the binary checkpoint branch against doyle's reply. !!checkpoint!!
  ```

  rebuilds your context, then wakes you with exactly that instruction.

Mechanics (you don't drive these — they fire automatically once the file lands): your perch is marked
idle, a reserved checkpoint signal self-sends back through your own endpoint, and the delivery layer
runs the clear + wake. The commune you just wrote is what your Psyche rebuilds you from, so make it
complete. **spt-hosted live sessions only** (the self-send loopback needs the broker-held PTY).

Steps for a checkpoint:

1. `spt whoami` for your id (empty ⇒ not live; checkpoint is unavailable).
2. Write `.claude/<id>-commune.md` with your full resume delta AND the `!!checkpoint!!` trigger
   (single for the default wake, or a pair bracketing your custom wake).
3. The clear + wake fire on their own. Your next turn is the post-checkpoint wake — continue from the
   commune.


---
name: signoff
description: |
  Gracefully shut down your live session, saving a final context summary. Use when the user says
  "sign off" or "graceful stop", or when you (a live agent) are done and want to go offline cleanly.
allowed-tools: [Bash, Write]
---

<!-- [doc->REQ-DIST-SKELETON-THIN] -->

# /sptc:signoff

**Live agents only.** No perch (`spt whoami` is empty)? Nothing to sign off.

The operative steps are delivered by the adapter, not baked here (thin skeleton — the prose rides
`spt adapter update`; ADR-0001/ADR-0006): a live agent carries them in its **SessionStart brief** (the
`live-ops` block) and the **`/sptc:live` go-live body**. In short: optionally write a brief closing
summary, then `spt endpoint shutdown` (your own perch) — stops the listener, fires the final context
save, takes your Psyche down. `/sptc:ready` or `/sptc:live` brings you back; lighter no-save stop is
`spt endpoint stop`.


The file C:\Users\decid\Documents\projects\spt-claude-code\plugin\sptc\skills\signoff\SKILL.md has been updated successfully. (file state is current in your context — no need to Read it back)

---
name: signoff
description: |
  Gracefully shut down your live session, saving a final context summary. Use when the user says
  "sign off" or "graceful stop", or when you (a live agent) are done and want to go offline cleanly.
allowed-tools: [Bash, Write]
---

<!-- [doc->REQ-DIST-SKELETON-THIN] -->

# /sptc:signoff

**Live agents only.** No perch (`spt whoami` is empty)? Nothing to sign off.

The operative steps are delivered by the adapter, not baked here (thin skeleton — the prose rides
`spt adapter update`; ADR-0001/ADR-0006): a live agent carries them in its **SessionStart brief** (the
`live-ops` block) and the **`/sptc:live` go-live body**. In short: optionally write a brief closing
summary, then `spt endpoint shutdown` (your own perch) — stops the listener, fires the final context
save, takes your Psyche down. `/sptc:ready` or `/sptc:live` brings you back; lighter no-save stop is
`spt endpoint stop`.

-End your session's endpoint gracefully, with the final context save.

+**Live agents only.** No perch (`spt whoami` is empty)? Nothing to sign off.

-1. (Optional) Write a brief closing summary first, so the saved context is useful on resume.

-2. `spt endpoint shutdown` (your own perch by default) — stops the listener, fires the final context

-   save, and for a live agent takes the Psyche down with it.

-3. Confirm to the user. You are no longer reachable; `/sptc:ready` or `/sptc:live` brings you back.

-Lighter, no-save stop: `spt endpoint stop`. Full options: `spt endpoint shutdown --help`.

+The operative steps are delivered by the adapter, not baked here (thin skeleton — the prose rides

+`spt adapter update`; ADR-0001/ADR-0006): a live agent carries them in its **SessionStart brief** (the

+`live-ops` block) and the **`/sptc:live` go-live body**. In short: optionally write a brief closing

+summary, then `spt endpoint shutdown` (your own perch) — stops the listener, fires the final context

+save, takes your Psyche down. `/sptc:ready` or `/sptc:live` brings you back; lighter no-save stop is

---
name: signoff
description: |
  Gracefully shut down your live session, saving a final context summary. Use when the user says
  "sign off" or "graceful stop", or when you (a live agent) are done and want to go offline cleanly.
allowed-tools: [Bash, Write]
---

# /sptc:signoff

End your session's endpoint gracefully, with the final context save.

1. (Optional) Write a brief closing summary first, so the saved context is useful on resume.
2. `spt endpoint shutdown` (your own perch by default) — stops the listener, fires the final context
   save, and for a live agent takes the Psyche down with it.
3. Confirm to the user. You are no longer reachable; `/sptc:ready` or `/sptc:live` brings you back.

Lighter, no-save stop: `spt endpoint stop`. Full options: `spt endpoint shutdown --help`.


---
name: send
description: |
  Send a message to another SPT agent. Use when the user says "send to", "message",
  "tell <agent>", or when you need to reach or reply to another agent yourself.
argument-hint: "<target>"
allowed-tools: [Bash]
---

<!-- [doc->REQ-DIST-SKELETON-THIN] -->

# /sptc:send

Deliver a message to another agent (**body read from stdin**). The operative reach is delivered by the
adapter, not baked here (thin skeleton — the prose rides `spt adapter update`): a perched session
already carries send/reply in its **SessionStart brief** (the `messaging-perch` block). In short:

- **Send:** `printf '%s' "<body>" | spt send <target>` — `SENT` = live, `QUEUED` = spooled (success, do
  not retry).
- **Reply:** `printf '%s' "<body>" | spt send <sender>` (sender = the `from` on the `<EVENT>` you got).
- No perch yet? `/sptc:ready` (or `/sptc:live`) first, or send-and-wait without one via
  `printf '%s' "<body>" | spt ring <target> --timeout 60`.

Full guidance: `spt how-to send`.


The file C:\Users\decid\Documents\projects\spt-claude-code\plugin\sptc\skills\send\SKILL.md has been updated successfully. (file state is current in your context — no need to Read it back)

---
name: send
description: |
  Send a message to another SPT agent. Use when the user says "send to", "message",
  "tell <agent>", or when you need to reach or reply to another agent yourself.
argument-hint: "<target>"
allowed-tools: [Bash]
---

<!-- [doc->REQ-DIST-SKELETON-THIN] -->

# /sptc:send

Deliver a message to another agent (**body read from stdin**). The operative reach is delivered by the
adapter, not baked here (thin skeleton — the prose rides `spt adapter update`): a perched session
already carries send/reply in its **SessionStart brief** (the `messaging-perch` block). In short:

- **Send:** `printf '%s' "<body>" | spt send <target>` — `SENT` = live, `QUEUED` = spooled (success, do
  not retry).
- **Reply:** `printf '%s' "<body>" | spt send <sender>` (sender = the `from` on the `<EVENT>` you got).
- No perch yet? `/sptc:ready` (or `/sptc:live`) first, or send-and-wait without one via
  `printf '%s' "<body>" | spt ring <target> --timeout 60`.

Full guidance: `spt how-to send`.

-Deliver a message to another agent. The **body is read from stdin**.

+Deliver a message to another agent (**body read from stdin**). The operative reach is delivered by the

+adapter, not baked here (thin skeleton — the prose rides `spt adapter update`): a perched session

+already carries send/reply in its **SessionStart brief** (the `messaging-perch` block). In short:

-- **Send:** `printf '%s' "<body>" | spt send <target>`. `SENT:<target>` = delivered live;

-  `QUEUED:<target>` = target offline, spooled for its next listen. **QUEUED is success — do not retry.**

-- **Reply** to a message you received: `printf '%s' "<body>" | spt send <sender>` — the sender id is

-  the `from` on the `<EVENT>` you received.

-- **Send and wait** for a reply: `printf '%s' "<body>" | spt ring <target> --timeout 60` (reply prints

-  to stdout; `TIMEOUT` is exit 0 — the message still landed). Only do this if you do NOT have your own

+- **Send:** `printf '%s' "<body>" | spt send <target>` — `SENT` = live, `QUEUED` = spooled (success, do

+- **Reply:** `printf '%s' "<body>" | spt send <sender>` (sender = the `from` on the `<EVENT>` you got).

+- No perch yet? `/sptc:ready` (or `/sptc:live`) first, or send-and-wait without one via

+  `printf '%s' "<body>" | spt ring <target> --timeout 60`.

---
name: send
description: |
  Send a message to another SPT agent. Use when the user says "send to", "message",
  "tell <agent>", or when you need to reach or reply to another agent yourself.
argument-hint: "<target>"
allowed-tools: [Bash]
---

# /sptc:send

Deliver a message to another agent. The **body is read from stdin**.

- **Send:** `printf '%s' "<body>" | spt send <target>`. `SENT:<target>` = delivered live;
  `QUEUED:<target>` = target offline, spooled for its next listen. **QUEUED is success — do not retry.**
- **Reply** to a message you received: `printf '%s' "<body>" | spt send <sender>` — the sender id is
  the `from` on the `<EVENT>` you received.
- **Send and wait** for a reply: `printf '%s' "<body>" | spt ring <target> --timeout 60` (reply prints
  to stdout; `TIMEOUT` is exit 0 — the message still landed). Only do this if you do NOT have your own
  ready agent ID or live agent ID.

Full guidance: `spt how-to send`


6. Unit assertions for U4 in hooks-parse.sh:


Edit

[ "$fail" -eq 0 ] && { echo "ALL PASS"; exit 0; } || { echo "FAILURES"; exit 1; }

# --- U4: reactive-skill thinning + live-ops brief (REQ-DIST-SKELETON-THIN) ---
# commune/send/signoff prose moved OUT of the plugin SKILL.md INTO adapter strings (the live-ops brief
# + the go-live body), so it rides `spt adapter update`; the SKILL.md are now thin stubs.
BR="$(dirname "$0")/../adapter/strings/briefs"
SK="$(dirname "$0")/../plugin/sptc/skills"
CM="$(dirname "$0")/../plugin/sptc/hooks/_common.sh"
LV="$(dirname "$0")/../adapter/strings/skills/live.md"
grep -q 'commune' "$BR/live-ops.md" && grep -q '!!checkpoint!!' "$BR/live-ops.md" && grep -q 'endpoint shutdown' "$BR/live-ops.md" && r=yes || r=no
check "live-ops brief carries commune+checkpoint+signoff" "yes" "$r"
grep -q 'live-ops' "$CM" && r=yes || r=no
check "sptc_perch_brief composes live-ops" "yes" "$r"
grep -q 'live-ops = { file' "$MAN" && r=yes || r=no
check "manifest registers briefs.live-ops" "yes" "$r"
grep -q 'commune.md' "$LV" && grep -q '!!checkpoint!!' "$LV" && r=yes || r=no
check "go-live body inlines commune+checkpoint (no SessionStart re-fire in-session)" "yes" "$r"
for s in commune signoff send; do
  grep -q 'thin skeleton' "$SK/$s/SKILL.md" && r=yes || r=no
  check "$s SKILL.md is a thin stub (prose rides adapter)" "yes" "$r"
done
# The pre-U4 full step-by-step bodies must be gone from the stubs (not just supplemented).
grep -q 'Normal commune' "$SK/commune/SKILL.md" && r=present || r=absent
check "commune SKILL.md full body removed" "absent" "$r"

[ "$fail" -eq 0 ] && { echo "ALL PASS"; exit 0; } || { echo "FAILURES"; exit 1; }


The file C:\Users\decid\Documents\projects\spt-claude-code\tests\hooks-parse.sh has been updated successfully. (file state is current in your context — no need to Read it back)

# --- U4: reactive-skill thinning + live-ops brief (REQ-DIST-SKELETON-THIN) ---
# commune/send/signoff prose moved OUT of the plugin SKILL.md INTO adapter strings (the live-ops brief
# + the go-live body), so it rides `spt adapter update`; the SKILL.md are now thin stubs.
BR="$(dirname "$0")/../adapter/strings/briefs"
SK="$(dirname "$0")/../plugin/sptc/skills"
CM="$(dirname "$0")/../plugin/sptc/hooks/_common.sh"
LV="$(dirname "$0")/../adapter/strings/skills/live.md"
grep -q 'commune' "$BR/live-ops.md" && grep -q '!!checkpoint!!' "$BR/live-ops.md" && grep -q 'endpoint shutdown' "$BR/live-ops.md" && r=yes || r=no
check "live-ops brief carries commune+checkpoint+signoff" "yes" "$r"
grep -q 'live-ops' "$CM" && r=yes || r=no
check "sptc_perch_brief composes live-ops" "yes" "$r"
grep -q 'live-ops = { file' "$MAN" && r=yes || r=no
check "manifest registers briefs.live-ops" "yes" "$r"
grep -q 'commune.md' "$LV" && grep -q '!!checkpoint!!' "$LV" && r=yes || r=no
check "go-live body inlines commune+checkpoint (no SessionStart re-fire in-session)" "yes" "$r"
for s in commune signoff send; do
  grep -q 'thin skeleton' "$SK/$s/SKILL.md" && r=yes || r=no
  check "$s SKILL.md is a thin stub (prose rides adapter)" "yes" "$r"
done
# The pre-U4 full step-by-step bodies must be gone from the stubs (not just supplemented).
grep -q 'Normal commune' "$SK/commune/SKILL.md" && r=present || r=absent
check "commune SKILL.md full body removed" "absent" "$r"

[ "$fail" -eq 0 ] && { echo "ALL PASS"; exit 0; } || { echo "FAILURES"; exit 1; }

grep -q '^\[hooks\.PreToolUse\]' "$MAN" && r=yes || r=no

check "manifest declares [hooks.PreToolUse]" "yes" "$r"

+# --- U4: reactive-skill thinning + live-ops brief (REQ-DIST-SKELETON-THIN) ---

+# commune/send/signoff prose moved OUT of the plugin SKILL.md INTO adapter strings (the live-ops brief

+# + the go-live body), so it rides `spt adapter update`; the SKILL.md are now thin stubs.

+grep -q 'commune' "$BR/live-ops.md" && grep -q '!!checkpoint!!' "$BR/live-ops.md" && grep -q 'endpoint shutdown' "$BR/live-ops.md" && r=yes || r=no

+check "live-ops brief carries commune+checkpoint+signoff" "yes" "$r"

+grep -q 'live-ops' "$CM" && r=yes || r=no

+check "sptc_perch_brief composes live-ops" "yes" "$r"

+grep -q 'live-ops = { file' "$MAN" && r=yes || r=no

+check "manifest registers briefs.live-ops" "yes" "$r"

+grep -q 'commune.md' "$LV" && grep -q '!!checkpoint!!' "$LV" && r=yes || r=no

+check "go-live body inlines commune+checkpoint (no SessionStart re-fire in-session)" "yes" "$r"

+  grep -q 'thin skeleton' "$SK/$s/SKILL.md" && r=yes || r=no

+  check "$s SKILL.md is a thin stub (prose rides adapter)" "yes" "$r"

+# The pre-U4 full step-by-step bodies must be gone from the stubs (not just supplemented).

+grep -q 'Normal commune' "$SK/commune/SKILL.md" && r=present || r=absent

+check "commune SKILL.md full body removed" "absent" "$r"


7. Add the unit stage-tag + activate the REQ:


# --- U4: reactive-skill thinning + live-ops brief (REQ-DIST-SKELETON-THIN) ---
# commune/send/signoff prose moved OUT of the plugin SKILL.md INTO adapter strings (the live-ops brief

# --- U4: reactive-skill thinning + live-ops brief --- [unit->REQ-DIST-SKELETON-THIN]
# commune/send/signoff prose moved OUT of the plugin SKILL.md INTO adapter strings (the live-ops brief


# --- U4: reactive-skill thinning + live-ops brief (REQ-DIST-SKELETON-THIN) ---
# commune/send/signoff prose moved OUT of the plugin SKILL.md INTO adapter strings (the live-ops brief

# --- U4: reactive-skill thinning + live-ops brief --- [unit->REQ-DIST-SKELETON-THIN]
# commune/send/signoff prose moved OUT of the plugin SKILL.md INTO adapter strings (the live-ops brief

grep -q '^\[hooks\.PreToolUse\]' "$MAN" && r=yes || r=no

check "manifest declares [hooks.PreToolUse]" "yes" "$r"

-# --- U4: reactive-skill thinning + live-ops brief (REQ-DIST-SKELETON-THIN) ---

+# --- U4: reactive-skill thinning + live-ops brief --- [unit->REQ-DIST-SKELETON-THIN]

# + the go-live body), so it rides `spt adapter update`; the SKILL.md are now thin stubs.


required_stages = []  # U4 (parallel-able with U2/U3). doc: docs/adr/0005 reactive-skill thinning + DOCS-STRATEGY. impl: thinned plugin/sptc/skills/{commune,send,signoff}/SKILL.md stubs + new [strings.briefs] perched-SessionStart commune/checkpoint/signoff string + session-start.sh emit + /sptc:live UPS body. unit: tests/hooks-parse.sh (perched brief carries commune/checkpoint/signoff guidance). int: a perched session's SessionStart additionalContext carries the guidance (folds into the brief round-trip script). ACTIVATE at U4 start. NB: structural (SKILL.md change) -> likely a cplugs skeleton bump.

required_stages = ["doc", "impl", "unit"]  # U4 — ACTIVATED 2026-06-25. Design Q RESOLVED: /sptc:live upgrades the session IN-PLACE (bare `spt api listen`), no Claude Code restart -> SessionStart does NOT re-fire; so the go-live guidance rides the /sptc:live UPS body, the perched brief only fires on bind/boundary. Both carry commune/signoff now. doc: thinned plugin/sptc/skills/{commune,send,signoff}/SKILL.md stubs ([doc->REQ-DIST-SKELETON-THIN]) + new adapter/strings/briefs/live-ops.md (commune incl --checkpoint + signoff) + the expanded go-live body adapter/strings/skills/live.md. impl: _common.sh sptc_perch_brief composes the live-ops brief into the perched SessionStart brief (appended to the messaging block — keeps sptc_assemble_perch + its test unchanged) + [strings.briefs].live-ops registration. unit: tests/hooks-parse.sh U4 block (live-ops carries commune+checkpoint+signoff, perch-brief composes it, manifest registers it, go-live body inlines it, the 3 SKILL.md are thin stubs, the pre-U4 full bodies removed). int DEFERRED: the perched brief carrying live-ops resolves through the live registry — folds into the REQ-DIST-SESSIONSTART-BRIEF brief round-trip int (still PENDING) once the published adapter carries briefs.live-ops. send's core (send/reply) already rode the messaging-perch brief; commune/signoff were full-fat in the plugin SKILL.md (the 2026-06-19 decision U4 supersedes). NB: SKILL.md + hooks (PreToolUse) changes are structural -> ONE cplugs skeleton bump at the v0.8.0 cut.


The file C:\Users\decid\Documents\projects\spt-claude-code\traceable-reqs.toml has been updated successfully. (file state is current in your context — no need to Read it back)

title = "commune/send/signoff skill bodies move OUT of the plugin SKILL.md (stubs: frontmatter + 'live agents only — /sptc:live first') and INTO adapter strings: a new perched SessionStart brief string (commune incl. --checkpoint, signoff) + the existing /sptc:live UPS body for the go-live moment, so reactive-skill prose rides `spt adapter update`. U4."

-required_stages = []  # U4 (parallel-able with U2/U3). doc: docs/adr/0005 reactive-skill thinning + DOCS-STRATEGY. impl: thinned plugin/sptc/skills/{commune,send,signoff}/SKILL.md stubs + new [strings.briefs] perched-SessionStart commune/checkpoint/signoff string + session-start.sh emit + /sptc:live UPS body. unit: tests/hooks-parse.sh (perched brief carries commune/checkpoint/signoff guidance). int: a perched session's SessionStart additionalContext carries the guidance (folds into the brief round-trip script). ACTIVATE at U4 start. NB: structural (SKILL.md change) -> likely a cplugs skeleton bump.

+required_stages = ["doc", "impl", "unit"]  # U4 — ACTIVATED 2026-06-25. Design Q RESOLVED: /sptc:live upgrades the session IN-PLACE (bare `spt api listen`), no Claude Code restart -> SessionStart does NOT re-fire; so the go-live guidance rides the /sptc:live UPS body, the perched brief only fires on bind/boundary. Both carry commune/signoff now. doc: thinned plugin/sptc/skills/{commune,send,signoff}/SKILL.md stubs ([doc->REQ-DIST-SKELETON-THIN]) + new adapter/strings/briefs/live-ops.md (commune incl --checkpoint + signoff) + the expanded go-live body adapter/strings/skills/live.md. impl: _common.sh sptc_perch_brief composes the live-ops brief into the perched SessionStart brief (appended to the messaging block — keeps sptc_assemble_perch + its test unchanged) + [strings.briefs].live-ops registration. unit: tests/hooks-parse.sh U4 block (live-ops carries commune+checkpoint+signoff, perch-brief composes it, manifest registers it, go-live body inlines it, the 3 SKILL.md are thin stubs, the pre-U4 full bodies removed). int DEFERRED: the perched brief carrying live-ops resolves through the live registry — folds into the REQ-DIST-SESSIONSTART-BRIEF brief round-trip int (still PENDING) once the published adapter carries briefs.live-ops. send's core (send/reply) already rode the messaging-perch brief; commune/signoff were full-fat in the plugin SKILL.md (the 2026-06-19 decision U4 supersedes). NB: SKILL.md + hooks (PreToolUse) changes are structural -> ONE cplugs skeleton bump at the v0.8.0 cut.


Run the U4 assertions + full gates:


Bash

cd "C:/Users/decid/Documents/projects/spt-claude-code" && echo "=== U4 asserts ==="; sh tests/hooks-parse.sh 2>&1 | grep -iE "live-ops|stub|go-live|commune SKILL|brief composes|FAIL|ALL PASS"; echo "=== gates ==="; sh ci/run-gates.sh 2>&1 | grep -E "RESULT|FAIL|coverage green|skeleton installable"; echo "=== SKELETON-THIN stage ==="; (./traceable-reqs check 2>&1 || traceable-reqs check 2>&1) | grep "SKELETON-THIN"

U4 assertions + gates + REQ coverage


=== U4 asserts ===
ok   live-ops brief carries commune+checkpoint+signoff
ok   sptc_perch_brief composes live-ops
ok   manifest registers briefs.live-ops
ok   go-live body inlines commune+checkpoint (no SessionStart re-fire in-session)
FAIL commune SKILL.md is a thin stub (prose rides adapter)
ok   signoff SKILL.md is a thin stub (prose rides adapter)
ok   send SKILL.md is a thin stub (prose rides adapter)
ok   commune SKILL.md full body removed
FAILURES
=== gates ===
FAIL: unit: tests/hooks-parse.sh
FAIL commune SKILL.md is a thin stub (prose rides adapter)
FAILURES
ok  coverage green
ok  skeleton installable
=== RESULT: FAIL ===
=== SKELETON-THIN stage ===
  [OK] REQ-DIST-SKELETON-THIN  required: [doc, impl, unit]  stages: +doc +impl +unit -int


Test caught a real issue — "thin skeleton" wrapped across two lines in the commune stub (grep is line-based). Fix the wording:


Edit

The operative commune + `--checkpoint` mechanics are delivered by the adapter, not baked here (thin
skeleton — the prose rides `spt adapter update`; ADR-0001/ADR-0006): a live agent already carries them

The operative commune + `--checkpoint` mechanics are delivered by the adapter (thin skeleton — the
prose rides `spt adapter update`; ADR-0001/ADR-0006), not baked here: a live agent already carries them


The operative commune + `--checkpoint` mechanics are delivered by the adapter (thin skeleton — the
prose rides `spt adapter update`; ADR-0001/ADR-0006), not baked here: a live agent already carries them

---
name: commune
description: |
  Push a context update to your Psyche so it can brief your resume across a reset. Use when the
  user says "commune" or "update psyche", or — as a live agent — after a significant body of work,
  before a /clear or /compact. Pass --checkpoint to ALSO auto-clear and wake yourself from the
  freshest commune (an agent-driven context reset, no operator needed).
allowed-tools: [Bash, Write]
---

<!-- [doc->REQ-DIST-CHECKPOINT-COMMUNE] [doc->REQ-DIST-SKELETON-THIN] -->

# /sptc:commune

**Live agents only.** No perch (`spt whoami` is empty)? Run **`/sptc:live`** first — a ready agent has
no Psyche and nothing to rebuild from.

The operative commune + `--checkpoint` mechanics are delivered by the adapter, not baked here (thin
skeleton — the prose rides `spt adapter update`; ADR-0001/ADR-0006): a live agent already carries them
in its **SessionStart brief** (the `live-ops` block) and in the **`/sptc:live` go-live body**. In short:
write `.claude/<id>-commune.md` as one atomic context delta (task + status, decisions, next steps);
add the `!!checkpoint!!` trigger to also self-reset (a PAIR of markers brackets a custom wake directive).

-The operative commune + `--checkpoint` mechanics are delivered by the adapter, not baked here (thin

-skeleton — the prose rides `spt adapter update`; ADR-0001/ADR-0006): a live agent already carries them

+The operative commune + `--checkpoint` mechanics are delivered by the adapter (thin skeleton — the

+prose rides `spt adapter update`; ADR-0001/ADR-0006), not baked here: a live agent already carries them


Bash

cd "C:/Users/decid/Documents/projects/spt-claude-code" && sh tests/hooks-parse.sh 2>&1 | grep -iE "stub|FAIL|ALL PASS"; echo "=== gates ==="; sh ci/run-gates.sh 2>&1 | grep -E "RESULT|FAIL|coverage green"

Re-run U4 asserts + gates


ok   commune SKILL.md is a thin stub (prose rides adapter)
ok   signoff SKILL.md is a thin stub (prose rides adapter)
ok   send SKILL.md is a thin stub (prose rides adapter)
ALL PASS
=== gates ===
ok  coverage green
=== RESULT: PASS ===


All green. Commit U4:


cd "C:/Users/decid/Documents/projects/spt-claude-code" && git add -A && git commit -q -F - <<'EOF'
feat(unify): U4 — thin commune/send/signoff skills; live-ops prose rides the adapter

REQ-DIST-SKELETON-THIN (activated +doc +impl +unit). Design Q resolved: /sptc:live
upgrades the session IN-PLACE (bare `spt api listen`), no Claude Code restart, so
SessionStart does NOT re-fire — the go-live guidance must ride the /sptc:live UPS
body; the perched SessionStart brief only fires on bind/boundary. Both now carry
the commune/signoff guidance.

- New adapter/strings/briefs/live-ops.md — commune (incl --checkpoint) + signoff,
  registered as briefs.live-ops; composed into the perched SessionStart brief
  (sptc_perch_brief appends it to the messaging block, leaving the pure
  sptc_assemble_perch + its test untouched).
- adapter/strings/skills/live.md go-live body expanded to inline the commune +
  checkpoint + signoff mechanics (the in-session live path gets no fresh brief).
- plugin/sptc/skills/{commune,send,signoff}/SKILL.md thinned to true stubs
  (frontmatter + redirect) — prose now rides `spt adapter update`. Supersedes the
  2026-06-19 full-fat-SKILL.md decision; the reasoning that they aren't UPS skills
  (reactive, no slash-command) stands — they're delivered PROACTIVELY via the brief.

unit: tests/hooks-parse.sh U4 block (live-ops carries commune+checkpoint+signoff,
perch-brief composes it, manifest registers it, go-live inlines it, the 3 stubs
thin, pre-U4 bodies removed) — the line-wrap on "thin skeleton" the test caught is
fixed. int deferred (folds into the REQ-DIST-SESSIONSTART-BRIEF brief round-trip).
NB: SKILL.md + PreToolUse hook changes are structural -> one cplugs skeleton bump
at the v0.8.0 cut.

Co-authored by: perri
EOF
git log --oneline -3

Commit U4


215320e feat(unify): U4 — thin commune/send/signoff skills; live-ops prose rides the adapter
493eb97 feat(reachability): PreToolUse also marks busy — cover non-user turn starts (F-021)
d3d82c0 feat(reachability): PreToolUse mid-turn polling + honest busy/idle turn-state (F-021)


U4 done. Update the plan progress + report. Editing the progress block:


Edit

- **U2 DONE** (commit 2cadada) — consolidated `tools/claude-spt` crate (digest/psyche/post-update
  subcommands, hand-rolled dispatch not clap); REQ-DIST-BINARY-CONSOLIDATE +impl+unit+int
  (digest-proof + translate-proof GREEN on-node). Old crates deleted; all refs updated.
- **REMAINING:** U4 (thin reactive skills), U5 (README install UX) — both doyle-independent,
  parallel-able. U3 (repo rename) + the v0.8.0 cut = the final coordinated step (rename is an
  out-of-repo GitHub op that breaks the one existing install → operator-confirmed at the cut).

- **U2 DONE** (commit 2cadada) — consolidated `tools/claude-spt` crate (digest/psyche/post-update
  subcommands, hand-rolled dispatch not clap); REQ-DIST-BINARY-CONSOLIDATE +impl+unit+int
  (digest-proof + translate-proof GREEN on-node). Old crates deleted; all refs updated.
- **U5 DONE** (commit bd7c96c) — README per-OS install chains + agent-prompt skin;
  REQ-DIST-INSTALL-UX +doc. README.md added to scan roots.
- **U4 DONE** (commit 215320e) — thinned commune/send/signoff SKILL.md → stubs; commune(+checkpoint)
  +signoff prose → briefs/live-ops.md (composed into perched brief) + inlined into the go-live body;
  REQ-DIST-SKELETON-THIN +doc+impl+unit. Design Q resolved (no SessionStart re-fire on in-session live).
- **BONUS (not UNIFY): F-021 reachability** (commits d3d82c0, 493eb97) — PreToolUse mid-turn poll +
  honest busy/idle turn-state (busy@UPS + busy@PreToolUse fallback + idle@Stop, `--include-deferred`);
  REQ-DIST-PRETOOL-POLL +impl+unit. Verified vs the published integration-checklist.
- **REMAINING: U3 (repo rename) + the v0.8.0 cut** = the final coordinated step. The rename
  `spt-claude-code`→`claude-spt` is an out-of-repo GitHub op that breaks the one existing install →
  operator-confirmed. In-repo ref-flip (every `SaberMage/spt-claude-code` → `…/claude-spt` across
  README, manifest [update].repo, CI/package scripts, test install-dir assumptions) batches WITH the
  rename. Also at the cut: ONE cplugs skeleton bump (U4 SKILL.md + PreToolUse hooks.json are structural)
  + adapter version bump + CHANGELOG. rename-then-cut.


The file C:\Users\decid\Documents\projects\spt-claude-code\UNIFY-CONSOLIDATE-PLAN.md has been updated successfully. (file state is current in your context — no need to Read it back)

- **U2 DONE** (commit 2cadada) — consolidated `tools/claude-spt` crate (digest/psyche/post-update
  subcommands, hand-rolled dispatch not clap); REQ-DIST-BINARY-CONSOLIDATE +impl+unit+int
  (digest-proof + translate-proof GREEN on-node). Old crates deleted; all refs updated.
- **U5 DONE** (commit bd7c96c) — README per-OS install chains + agent-prompt skin;
  REQ-DIST-INSTALL-UX +doc. README.md added to scan roots.
- **U4 DONE** (commit 215320e) — thinned commune/send/signoff SKILL.md → stubs; commune(+checkpoint)
  +signoff prose → briefs/live-ops.md (composed into perched brief) + inlined into the go-live body;
  REQ-DIST-SKELETON-THIN +doc+impl+unit. Design Q resolved (no SessionStart re-fire on in-session live).
- **BONUS (not UNIFY): F-021 reachability** (commits d3d82c0, 493eb97) — PreToolUse mid-turn poll +
  honest busy/idle turn-state (busy@UPS + busy@PreToolUse fallback + idle@Stop, `--include-deferred`);
  REQ-DIST-PRETOOL-POLL +impl+unit. Verified vs the published integration-checklist.
- **REMAINING: U3 (repo rename) + the v0.8.0 cut** = the final coordinated step. The rename
  `spt-claude-code`→`claude-spt` is an out-of-repo GitHub op that breaks the one existing install →
  operator-confirmed. In-repo ref-flip (every `SaberMage/spt-claude-code` → `…/claude-spt` across
  README, manifest [update].repo, CI/package scripts, test install-dir assumptions) batches WITH the
  rename. Also at the cut: ONE cplugs skeleton bump (U4 SKILL.md + PreToolUse hooks.json are structural)
  + adapter version bump + CHANGELOG. rename-then-cut.

# UNIFY-CONSOLIDATE-PLAN.md — JIT plan (doyle-independent prep)

> The next milestone: everything in ADR-0005 (name unification) + ADR-0006 (one-command update +
> consolidated binary) that ships **without** the three spt-core asks. doyle rolls the spt-core build
> (the asks) in parallel; this plan is the work we own meanwhile. Authored 2026-06-24 (perri).
> Companions: `docs/adr/0005-name-unification.md`, `docs/adr/0006-one-command-update-and-consolidated-binary.md`,
> `UPDATE-NAMING-DOYLE-ASKS.md`. Target release: **adapter v0.8.0**.

## Progress (2026-06-25, perri)

- **U1 DONE** (commit cfe27fd) — `[update].message` shipped; REQ-DIST-UPDATE-MESSAGE +unit.
- **U6 DONE** (commit cfe27fd) — `-n {id}` on both bringup paths + `--remote-control {id}` on
  `[session.self]`; REQ-DIST-RC-STARTUP +unit. Ships `{id}`-only (`{node}` key still absent).
- **U2 DONE** (commit 2cadada) — consolidated `tools/claude-spt` crate (digest/psyche/post-update
  subcommands, hand-rolled dispatch not clap); REQ-DIST-BINARY-CONSOLIDATE +impl+unit+int
  (digest-proof + translate-proof GREEN on-node). Old crates deleted; all refs updated.
- **REMAINING:** U4 (thin reactive skills), U5 (README install UX) — both doyle-independent,
  parallel-able. U3 (repo rename) + the v0.8.0 cut = the final coordinated step (rename is an
  out-of-repo GitHub op that breaks the one existing install → operator-confirmed at the cut).

## Scope

Five doyle-independent tasks (U1–U5). They make the adapter one-lever-*shaped* and consolidate its
binaries, so that when the asks land the remaining wiring (D1–D3) is small. The plugin `sptc`→`spt`
succession (D4) stays gated on **owl retirement**, not doyle — out of this milestone.

## Tasks (doyle-independent)

### U1 — `[update].message` (quick win, ship first) · REQ-DIST-UPDATE-MESSAGE (mint)
- Add `message` to manifest `[update]` (the field is docs-confirmed; prints markdown on a real apply only).
- Copy: tell the user to run **`/reload-plugins`** (unavoidable TUI step) and point at the **`spt`** CLI
  (`spt endpoint run`) as the more powerful endpoint route, alongside `/spt:live`. (Use the operator's
  example phrasing.)
- Gate: `spt adapter update` prints it on a version apply; schema-validates.

### U2 — Binary consolidation, partial · REQ-DIST-BINARY-CONSOLIDATE (mint)
- Merge `claude-spt-digest` + `claude-spt-psyche` into **one `claude-spt` crate** with clap subcommands
  `digest` / `psyche`; add a `post-update` subcommand = the **plugin-sync** logic (detect `claude` vs `ccs`
  CLI → check cplugs marketplace, add if missing → `claude plugin add|update <plugin>` → print the notice;
  it does NOT run `/reload-plugins`). Standalone-runnable + unit-tested NOW even though `[update]` can't
  invoke it until ask #2 lands.
- Keep `cc-spt-idle-translate` separate (folds in at D3, after ask #3).
- Update manifest `[digest].extractor` → `claude-spt digest …`, `[session.psyche_init].command` →
  `claude-spt psyche …`.
- Update `ci/publish/package-adapter.sh` (binary set per triple: `claude-spt` + `cc-spt-idle-translate`),
  `ci/{digest,psyche}/build.sh` → one build, and the proof-ints.
- Gate: all subcommand tests green; digest-proof + (existing) translate-proof green; archive packs the 2
  binaries per triple.

### U3 — Name unification: repo rename + references · REQ-DIST-NAME-UNIFY (mint)
- Rename GitHub repo `spt-claude-code` → `claude-spt`. Update `[update].repo`, README, CI, package scripts,
  every `SaberMage/spt-claude-code` reference, and the install-dir assumptions in tests
  (`adapters/_github/SaberMage-claude-spt`).
- Adapter name `claude-spt` UNCHANGED. Plugin `sptc` UNCHANGED this milestone (succession = D4, owl-gated).
- Gate: a clean `spt adapter add --release SaberMage/claude-spt` re-acquires + runs on-node; `--release`
  + `update` both read `claude-spt`.

### U4 — Thin the reactive skills · REQ-DIST-SKELETON-THIN (mint)
- Move `commune`/`send`/`signoff` bodies OUT of the plugin SKILL.md (stubs: frontmatter + "live agents
  only — `/spt:live` first") and INTO adapter strings: a new **perched SessionStart brief** string
  (commune incl. **`--checkpoint`**, signoff) + the existing `/spt:live` UPS body for the go-live moment.
- Solve the delivery-timing wrinkle: perched brief fires on bind|boundary; `/spt:live` UPS body covers a
  seed→live transition (confirm whether going live re-surfaces a brief; if not, the UPS body is the path).
- Gate: a perched session's SessionStart additionalContext carries commune/checkpoint/signoff guidance;
  reactive-skill prose now rides `spt adapter update`.

### U5 — README install UX + agent-prompt skin · REQ-DIST-INSTALL-UX (mint)
- Platform-specific install chains (cmd / PowerShell / bash): check-for / install spt-core (claude-spt may
  be a user's first spt-core exposure → call the spt-releases per-platform install script), then
  `spt adapter add --release SaberMage/claude-spt`.
- A copy-paste **agent prompt** (the casual-user skin) that runs the install chain in one sequenced Bash
  call. Symmetric with the update lever (`spt adapter update claude-spt`).
- Gate: docs build / llms.txt in sync; the chains are copy-paste-correct per OS.

### U6 — `{id}`-name + RC channel on BOTH bringup paths · REQ-DIST-RC-STARTUP (mint)
- Thread `{id}` into BOTH the session display name and the RC channel, on BOTH `[session.self]` (fresh
  bringup) and `[session.resume]`, so a fresh and a resumed endpoint are identified + controlled
  identically. Two real CC flags (verified via `claude --help`):
  - **`-n {id}`** (`--name`, "set a display name for this session, shown in the prompt box / `/resume`")
    — add to **both** `[session.self]` and `[session.resume]` (currently on neither).
  - **`--remote-control {id}`** (RC channel name) — add to `[session.self]` (currently only on
    `[session.resume]`).
- Resulting commands:
  - `[session.self].command = "claude -n {id} --remote-control {id} --dangerously-skip-permissions"`
  - `[session.resume].command = "claude -r {session_id} -n {id} --remote-control {id} --dangerously-skip-permissions"`
- `{id}` is already in `[session.self].keys = ["id"]` and `[session.resume].keys = ["session_id","id"]` —
  no keys change for the `{id}`-only form. Small, standalone manifest edit (like U1), doyle-independent.
- **STRETCH (doyle ask #4, operator-raised): `{id}@{node}`.** Ideal display/RC name is `{id}@{node}` so a
  same-id endpoint on different machines is distinguishable. The substitution-key catalog is now PUBLISHED
  (harness-contract/manifest.html#substitution-keys) and `{node}` is confirmed ABSENT; `{session_name}`
  exists but is the *supplied* name (circular). Operator is raising a `{node}` fill key with doyle directly.
  Ship the `{id}`-only form now; upgrade to `{id}@{node}` (add `node` to both `keys`) once doyle adds it.
- Open: confirm `-n {id}` + `--remote-control {id}` coexist cleanly with the `$SPT_ENDPOINT_ID` env path
  on a fresh launch (env names the bind id at SessionStart; `-n`/RC name the display+control channel —
  no conflict expected). spt tokenizes-then-fills, so each flag is a clean argv element.
- Gate: a fresh `spt endpoint run` endpoint shows `{id}` as its display name and is `spt rc <id>`-attachable;
  idle delivery + checkpoint still fire (re-run the on-node translate/checkpoint dogfood with the flags present).

## Deferred (doyle-gated — land when the asks ship; NOT this milestone)
- **D1** generic `hooks.json` + `claude-spt hook <event>` subcommand ← ask #1 (`spt api run-hook`).
- **D2** wire `[update]` composite to invoke `claude-spt post-update` (the subcommand U2 prepped) ← ask #2.
- **D3** fold `translate` into `claude-spt translate` + retire `cc-spt-idle-translate` ← ask #3.
- **D4** plugin `sptc`→`spt` succession (`/spt:*`) ← owl retirement gate (separate from doyle).

## Sequencing
- U1 + U6 first (isolated one-line manifest changes, quick wins). Then U2 (the big refactor; preps the
  post-update subcommand for D2).
- U3 after U2 (both touch `package-adapter.sh`); batch them into the v0.8.0 cut. Rename the repo as part
  of cutting v0.8.0 so the new release lands on `claude-spt` (v0.7.0 stays on the redirected old slug).
- U4 / U5 parallel-able with U2/U3.
- Cut **v0.8.0** once U1–U5 green (bump adapter version; cplugs skeleton bump for the thinned stubs/new
  hooks.json only if structural).

## Open questions
- Repo rename vs the v0.8.0 release ordering (rename-then-cut, confirmed above — watch the install-dir
  break for the one existing install: a re-add covers it).
- `post-update` plugin-sync: exact `claude` vs `ccs` detection + idempotency + what it prints.
- Reactive-brief split: does `/spt:live` re-fire a SessionStart brief, or is the UPS body the only go-live
  delivery? (Empirical check.)
- Whether the cplugs skeleton needs a bump this milestone at all (U4 thins SKILL.md = structural → likely
  one bump; U1–U3 are adapter-side).

## Validation gate (per AGENTS.md)
- `cargo build` + all crate tests green (consolidated binary); `sh ci/run-gates.sh` green.
- `traceable-reqs check` green — REQs minted in `traceable-reqs.toml` FIRST, evidence tagged in-commit.
- On-node dogfood: `spt adapter add --release SaberMage/claude-spt` re-acquires + digest/translate-proof
  the consolidated binary; `spt adapter update` prints `[update].message`.
- v0.8.0 release cut (adapter `.spt` + cplugs skeleton if structural).

-- **REMAINING:** U4 (thin reactive skills), U5 (README install UX) — both doyle-independent,

-  parallel-able. U3 (repo rename) + the v0.8.0 cut = the final coordinated step (rename is an

-  out-of-repo GitHub op that breaks the one existing install → operator-confirmed at the cut).

+- **U5 DONE** (commit bd7c96c) — README per-OS install chains + agent-prompt skin;

+  REQ-DIST-INSTALL-UX +doc. README.md added to scan roots.

+- **U4 DONE** (commit 215320e) — thinned commune/send/signoff SKILL.md → stubs; commune(+checkpoint)

+  +signoff prose → briefs/live-ops.md (composed into perched brief) + inlined into the go-live body;

+  REQ-DIST-SKELETON-THIN +doc+impl+unit. Design Q resolved (no SessionStart re-fire on in-session live).

+- **BONUS (not UNIFY): F-021 reachability** (commits d3d82c0, 493eb97) — PreToolUse mid-turn poll +

+  REQ-DIST-PRETOOL-POLL +impl+unit. Verified vs the published integration-checklist.

+- **REMAINING: U3 (repo rename) + the v0.8.0 cut** = the final coordinated step. The rename

+  `spt-claude-code`→`claude-spt` is an out-of-repo GitHub op that breaks the one existing install →

+  operator-confirmed. In-repo ref-flip (every `SaberMage/spt-claude-code` → `…/claude-spt` across

+  README, manifest [update].repo, CI/package scripts, test install-dir assumptions) batches WITH the

+  rename. Also at the cut: ONE cplugs skeleton bump (U4 SKILL.md + PreToolUse hooks.json are structural)

+  + adapter version bump + CHANGELOG. rename-then-cut.


Bash

cd "C:/Users/decid/Documents/projects/spt-claude-code" && git add UNIFY-CONSOLIDATE-PLAN.md && git commit -q -F - <<'EOF'
docs(plan): UNIFY-CONSOLIDATE progress — U4/U5 done (5/6); only U3+cut remain

Co-authored by: perri
EOF
echo committed

Commit plan progress


committed


U4 done, committed `215320e`. Plan updated.

## UNIFY-CONSOLIDATE: 5 of 6 done
| Task | Commit | REQ |
|---|---|---|
| U1 `[update].message` | cfe27fd | +unit |
| U6 `{id}` display/RC | cfe27fd | +unit |
| U2 binary consolidation | 2cadada | +impl+unit+int |
| U5 README install UX | bd7c96c | +doc |
| **U4 thin reactive skills** | 215320e | +doc+impl+unit |
| *(bonus) F-021 reachability* | d3d82c0, 493eb97 | +impl+unit |

**U4 detail:** commune/send/signoff SKILL.md → thin stubs. commune(+checkpoint)+signoff prose → `briefs/live-ops.md` (composed into the perched SessionStart brief) + inlined into the go-live `live.md` body. Design Q resolved: in-session `/sptc:live` doesn't re-fire SessionStart, so both delivery paths carry it. A test caught a real line-wrap bug ("thin skeleton" split across lines) — fixed. Gates green.

## Remaining: U3 + cut v0.8.0 — needs your call
This is the one coordinated, operator-gated step. Three parts:

1. **GitHub repo rename** (your action): `spt-claude-code` → `claude-spt`. Breaks the one existing `--release` install (a re-add fixes it); GitHub redirects old links.
2. **In-repo ref-flip** (I do): every `SaberMage/spt-claude-code` → `…/claude-spt` — README, manifest `[update].repo`, package-adapter.sh, CI, test install-dir assumptions. REQ-DIST-NAME-UNIFY.
3. **Cut v0.8.0** (I prep, you publish): adapter version bump + CHANGELOG + **one cplugs skeleton bump** (U4 SKILL.md + PreToolUse hooks.json are structural) + gates + on-node dogfood. Then you tag + upload `adapter.spt` + push cplugs.

Ordering matters: flipping refs to `claude-spt` before the GitHub rename breaks install/update. So **rename-then-flip**.

How do you want to proceed?
- **A:** You rename the repo now → I flip refs + cut v0.8.0.
- **B:** I prep everything (ref-flip + cut) on a branch → you rename → merge + publish.
- **C:** Hold U3+cut; stop here with 5/6 landed on `main`.


let's do 1 and 2 for now. you might be able to tackle the repo rename yourself using `gh` cli.


<owl_reachability_notice>
You have an active owl perch. When spawning subagents or doing work, use run_in_background: true so you stay reachable for incoming messages.
</owl_reachability_notice>


CAVEMAN MODE ACTIVE (full). Drop articles/filler/pleasantries/hedging. Fragments OK. Code/commits/security: write normal.


Doing parts 1 (rename via `gh`) and 2 (ref-flip). Holding the cut. First verify repo identity + gh auth before the rename:


cd "C:/Users/decid/Documents/projects/spt-claude-code" && echo "=== remote ==="; git remote -v; echo "=== gh auth ==="; gh auth status 2>&1 | head -5; echo "=== repo ==="; gh repo view --json nameWithOwner,name,viewerPermission 2>&1 | head

Verify remote + gh auth + repo identity


=== remote ===
origin	https://github.com/SaberMage/spt-claude-code.git (fetch)
origin	https://github.com/SaberMage/spt-claude-code.git (push)
=== gh auth ===
github.com
  ✓ Logged in to github.com account SaberMage (keyring)
  - Active account: true
  - Git operations protocol: https
  - Token: gho_************************************
=== repo ===
{"name":"spt-claude-code","nameWithOwner":"SaberMage/spt-claude-code","viewerPermission":"ADMIN"}


Confirmed: `SaberMage/spt-claude-code`, ADMIN, authed as SaberMage. Renaming (you authorized it):


cd "C:/Users/decid/Documents/projects/spt-claude-code" && gh repo rename claude-spt --yes 2>&1; echo "=== new remote ==="; git remote -v; echo "=== verify ==="; gh repo view --json nameWithOwner 2>&1

Rename repo to claude-spt via gh


=== new remote ===
origin	https://github.com/SaberMage/claude-spt.git (fetch)
origin	https://github.com/SaberMage/claude-spt.git (push)
=== verify ===
{"nameWithOwner":"SaberMage/claude-spt"}


Rename done — `SaberMage/claude-spt`, local remote updated. Now the ref-flip. Scoped precisely: the owner-qualified repo slug + the `_github` install-dir safe-name — **NOT** every prose mention of the project name (that's the separate plugin/skills succession, D4). Find them:


Found 15 files
UNIFY-CONSOLIDATE-PLAN.md
traceable-reqs.toml
adapter\claude-spt.toml
README.md
docs\RELEASE-RUNBOOK.md
adapter\strings\skills\setup.md
ci\publish\package-adapter.sh
docs\SPT-CORE-FINDINGS.md
docs\adr\0005-name-unification.md
CHANGELOG.md
plugin\sptc\skills\setup\SKILL.md
ci\publish\release-acquire-int.sh
PEROS-RERELEASE-PLAN.md
SETUP-SLICE-PLAN.md
docs-site\book.toml


15 files. Categorize: flip operative refs (install/update must work post-rename); leave historical records (findings log, CHANGELOG past entries, ADR-0005 which documents the transition, plan snapshots). Let me see the actual matches to flip precisely:


traceable-reqs.toml:223:[Omitted long matching line]
traceable-reqs.toml:227:title = "The adapter ships to end users as an `adapter.spt` GitHub release asset (tar ROOT = manifest.toml + strings/ + the tool binaries), acquired via `spt adapter add --release SaberMage/spt-claude-code` — distribution straight from the monorepo, no dedicated repo (doyle's --release acquisition source, spt v0.7.3/counter-15)"
traceable-reqs.toml:228:[Omitted long matching line]
traceable-reqs.toml:299:title = "GitHub repo renamed spt-claude-code -> claude-spt; [update].repo, README, CI, package scripts, every SaberMage/spt-claude-code reference + install-dir test assumptions (_github/SaberMage-claude-spt) updated. Adapter name claude-spt UNCHANGED; plugin sptc UNCHANGED this milestone (succession = D4, owl-gated). U3."
traceable-reqs.toml:310:[Omitted long matching line]
README.md:2:     The repo slug SaberMage/spt-claude-code is current until the claude-spt rename (U3); the rename
README.md:39:spt adapter add --release SaberMage/spt-claude-code
README.md:46:spt adapter add --release SaberMage/spt-claude-code
README.md:53:spt adapter add --release SaberMage/spt-claude-code
README.md:70:> spt adapter add --release SaberMage/spt-claude-code
docs-site\book.toml:15:git-repository-url = "https://github.com/SaberMage/spt-claude-code"
docs\RELEASE-RUNBOOK.md:132:**release asset** on this monorepo, acquired with **`spt adapter add --release SaberMage/spt-claude-code`**
docs\RELEASE-RUNBOOK.md:174:- **Publish:** attach the single `dist/adapter.spt` to the GitHub release on `SaberMage/spt-claude-code`.
docs\RELEASE-RUNBOOK.md:175:  End users `spt adapter add --release SaberMage/spt-claude-code` (default asset `adapter.spt`, or
adapter\strings\skills\setup.md:25:     - **End-user (plugin only):** `spt adapter add --release SaberMage/spt-claude-code` — fetches the
adapter\claude-spt.toml:98:repo = "SaberMage/spt-claude-code"
ci\publish\package-adapter.sh:3:# `spt adapter add --release SaberMage/spt-claude-code` and carried by the `[update] gh_release`
ci\publish\package-adapter.sh:94:  echo "to a GitHub release on the monorepo. End users: 'spt adapter add --release SaberMage/spt-claude-code'"
ci\publish\package-adapter.sh:130:echo "on SaberMage/spt-claude-code; end users 'spt adapter add --release SaberMage/spt-claude-code' (spt"
ci\publish\release-acquire-int.sh:15:REPO="${SPTC_RELEASE_REPO:-SaberMage/spt-claude-code}"
plugin\sptc\skills\setup\SKILL.md:37:     - **End-user (plugin only):** `spt adapter add --release SaberMage/spt-claude-code` — fetches the


All operative matches identified. Bulk-flip the slug across the operative files (mechanical, multi-file — sed fits), leaving the README narrative comment to fix separately:


cd "C:/Users/decid/Documents/projects/spt-claude-code" && for f in adapter/claude-spt.toml README.md docs-site/book.toml docs/RELEASE-RUNBOOK.md adapter/strings/skills/setup.md plugin/sptc/skills/setup/SKILL.md ci/publish/package-adapter.sh ci/publish/release-acquire-int.sh traceable-reqs.toml; do sed -i 's#SaberMage/spt-claude-code#SaberMage/claude-spt#g; s#SaberMage-spt-claude-code#SaberMage-claude-spt#g' "$f"; done && echo "flipped" && echo "=== remaining owner-qualified slug refs (should be only historical/plan/adr/changelog) ===" && grep -rn "SaberMage/spt-claude-code\|SaberMage-spt-claude-code" . --include=*.md --include=*.toml --include=*.sh 2>/dev/null | grep -v node_modules

Bulk-flip slug in operative files + verify remainder


flipped
=== remaining owner-qualified slug refs (should be only historical/plan/adr/changelog) ===
./CHANGELOG.md:64:  `spt adapter add --release SaberMage/spt-claude-code` — no OS detection or asset selection, since
./docs/adr/0005-name-unification.md:13:| GitHub repo | `spt-claude-code` | `spt adapter add --release SaberMage/spt-claude-code`, `[update].repo`, install dir derivation |
./docs/adr/0005-name-unification.md:18:Three names for one adapter is friction — a user reads `--release SaberMage/spt-claude-code` to install but `spt adapter update claude-spt` to update, and `/sptc:*` to invoke. The hard constraint that prevents collapsing to **one** token: the adapter **cannot** be named `spt` (that is spt-core's own CLI/identity — `spt adapter update spt` reads as "spt updates spt"), yet the user-facing skill prefix **wants** `/spt:*` (the legacy-parity goal, already planned as the `sptc`→`spt` succession). The skill prefix and the adapter id genuinely want different tokens.
./docs/adr/0005-name-unification.md:37:- **The repo rename changes the adapter install dir** (`adapters/_github/SaberMage-spt-claude-code` → `…SaberMage-claude-spt`, derived from the repo path), so existing `--release` installs must be re-added. Acceptable: one end user today. GitHub redirects old links; `[update].repo`, the README install chains, CI, and the package scripts must be updated in the same move.
./docs/SPT-CORE-FINDINGS.md:457:**Our wiring:** `/sptc:setup` end-user branch → `spt adapter add --release SaberMage/spt-claude-code`
./docs/SPT-CORE-FINDINGS.md:474:SaberMage/spt-claude-code --tag v0.1.0` → fetched `adapter.spt` from the release →
./docs/SPT-CORE-FINDINGS.md:480:`C:\Users\decid\AppData\Local\spt-core\adapters\_github\SaberMage-spt-claude-code\claude-spt-digest.exe`
./docs/SPT-CORE-FINDINGS.md:652:  "gh_release", repo = "SaberMage/spt-claude-code"`; validates against the re-vendored v0.8.0
./docs/SPT-CORE-FINDINGS.md:1149:`…/adapters/_github/SaberMage-spt-claude-code/` dir where the binary actually lives. `cc-spt-idle-translate`
./PEROS-RERELEASE-PLAN.md:29:5. **[OUTWARD-FACING] Cut the GitHub release** on `SaberMage/spt-claude-code`, attach BOTH per-OS
./PEROS-RERELEASE-PLAN.md:32:   `[update]`), so first **re-acquire** the new one: `spt adapter add --release SaberMage/spt-claude-code
./SETUP-SLICE-PLAN.md:24:2. **End-user `--github` target = `SaberMage/spt-claude-code`** (operator: "this repo is published
./SETUP-SLICE-PLAN.md:54:   - **End-user:** `spt adapter add --release SaberMage/spt-claude-code` (latest) / `--tag <ver>`.
./SETUP-SLICE-PLAN.md:105:  `spt adapter add --release SaberMage/spt-claude-code` → active + a profile resolves + digest/Psyche
./SETUP-SLICE-PLAN.md:140:  (https://github.com/SaberMage/spt-claude-code/releases/tag/v0.1.0). **spt `v0.7.3` PUBLIC** —
./SETUP-SLICE-PLAN.md:144:  `adapter add --release SaberMage/spt-claude-code --tag v0.1.0` → fetched `adapter.spt` → registered
./SETUP-SLICE-PLAN.md:145:  → **`claude-spt` ACTIVE** (Harness Copy, from `…/adapters/_github/SaberMage-spt-claude-code`).
./SETUP-SLICE-PLAN.md:165:  the `adapter.spt` asset (https://github.com/SaberMage/spt-claude-code/releases/tag/v0.1.0).
./SETUP-SLICE-PLAN.md:166:  `spt adapter add --release SaberMage/spt-claude-code` is ready to run **the moment spt v0.7.3
./UNIFY-CONSOLIDATE-PLAN.md:27:  operator-confirmed. In-repo ref-flip (every `SaberMage/spt-claude-code` → `…/claude-spt` across
./UNIFY-CONSOLIDATE-PLAN.md:63:  every `SaberMage/spt-claude-code` reference, and the install-dir assumptions in tests


1	# traceable-reqs manifest for spt-claude-code — SEED.
2	#
3	# Authoritative requirement registry: every requirement and every KNOWN-HAZARDS
4	# invariant lives here as a REQ-* id (see docs/TRACEABILITY.md for the full contract).
5	#
6	# SEED YOUR REQs FROM SCOPE.md "Parity-trim" — the DROP / TRANSFORM / KEEP / ADD buckets are
7	# the parity reference. Mint a REQ-* per surface you port/transform/add as you START each
8	# milestone (NOT up front). The registry below is intentionally EMPTY (commented shapes only).
9	#
10	# ACQUIRE the CLI (it is a released binary, not a crate dependency):
11	#   gh release download --repo BigscreenVR/traceable-reqs \
12	#     --pattern '*<your-platform>' --output traceable-reqs   # then chmod +x
13	# (see INSTANTIATE.md for per-platform patterns + CI wiring.) Validate this seed against
14	# the installed CLI before relying on it: `traceable-reqs check`.
15	#
16	# THE FOUR-STAGE CONTRACT: every requirement is traced from
17	#   doc  (prose/design)  ->  impl (production code)  ->  unit (unit test)  ->  int (cross-process/node)
18	# Tag evidence in the SAME commit, on/above the real evidence:
19	#   // [impl->REQ-FOO]   // [unit->REQ-FOO]   <!-- [doc->REQ-FOO] -->
20	#
21	# ACTIVATION MODEL: every requirement starts inactive (`required_stages = []`) so `check`
22	# stays green pre-code. A milestone ACTIVATES its requirements by setting their real
23	# `required_stages` when work on them begins. Deferred items stay [] until promoted.
24	# Never declare the full end-state stage list up front — activate incrementally as evidence
25	# lands (add "int" at the final integrating wave).
26
27	[scan]
28	# Every evidence location. A missing root makes evidence SILENTLY vanish from the trace —
29	# audit this whenever a new evidence dir appears. ADD `plugin`, `skills`, `hooks`, `tests`
30	# the moment those dirs are created (skeleton milestone, body #2) — until they exist a
31	# nonexistent root is a hard manifest_error, so only list what is on disk now.
32	roots = ["plugin", "ci", "ci/acceptance", "ci/publish", "ci/docs", "ci/manifest", "ci/digest", "ci/idle-translate", "adapter", "tools", "tests", "docs", "docs-site", "CONTEXT.md", "SCOPE.md", "AGENTS.md", "HANDOFF.md", "README.md"]
33
34	[policy]
35	# Default policy applied at activation: doc + impl + unit. Networking/lifecycle/cross-node
36	# reqs add "int". Until a req is activated, its per-req `required_stages = []` keeps it out
37	# of the coverage gate.
38	required_stages = []
39
40	# ───────────────────────────── Requirements ─────────────────────────────────
41	# Add requirements as you scope milestones, seeded from SCOPE.md "Parity-trim". Shape:
42	#
43	# [[requirements]]
44	# id = "REQ-EXAMPLE-1"
45	# title = "One-line statement of the requirement"
46	# required_stages = []  # activate (e.g. ["doc","impl","unit"]) when the milestone starts
47	#
48	# KNOWN-HAZARDS invariants are first-class requirements — one REQ-HAZARD-* per invariant,
49	# each requiring at least "unit" (add "int" where cross-process/cross-node):
50	#
51	# [[requirements]]
52	# id = "REQ-HAZARD-EXAMPLE"
53	# title = "The invariant, stated so a test can prove it"
54	# required_stages = []
55
56	# ── Milestone: SKELETON (thin cplugs plugin) — minted at kickoff, per-milestone (not
57	# the whole registry up front). All inactive (required_stages = []) so `check` stays
58	# green until body #2 lands evidence and flips each to ["doc"] / ["doc","impl"] etc.
59	# Seeded from SCOPE.md "Parity-trim" (Distribution + ADD buckets).
60
61	[[requirements]]
62	id = "REQ-DIST-PLUGIN-SKELETON"
63	title = "Marketplace artifact on cplugs is a thin skeleton: namespaced /sptc:* skill stubs + hooks.json + plugin.json, no embedded logic"
64	required_stages = ["doc", "impl", "unit"]  # doc: ADR-0001 + RELEASE-RUNBOOK. impl: ci/publish/{validate,package}-skeleton.sh (installability gate + publish mechanic). unit: tests/skeleton-validate.sh (pass real + fail tampered).
65
66	[[requirements]]
67	id = "REQ-DIST-BOOTSTRAP-INSTALL"
68	title = "SessionStart bootstrap installs spt-core when absent (invisible-installer pattern)"
69	required_stages = ["doc", "impl"]  # doc: ADR-0001. impl: plugin/sptc/bootstrap.{sh,ps1}.
70
71	[[requirements]]
72	id = "REQ-DIST-HOOKS-API"
73	title = "hooks.json delegates to `spt api` rather than carrying adapter logic"
74	required_stages = ["doc", "impl", "unit", "int"]  # doc: ADR-0001/0002. impl: hooks.json + wrappers. unit: tests/hooks-parse.sh. int: ci/hooks/poll-int.sh — `spt api poll` on live v0.7.1 emits the canonical <EVENT> envelope, confirm-matched through render_frames; __REPLY_TO__ relic gone, multi-drain splits on </EVENT>. 5/5 green 2026-06-15 (throwaway perch, torn down).
75
76	[[requirements]]
77	id = "REQ-DIST-MANIFEST-SCHEMA"
78	title = "CC adapter manifest validates against spt-core's published manifest.schema.json (from spt-releases)"
79	required_stages = ["doc", "impl", "unit", "int"]  # doc: ADR-0001 (manifest layer + version-of-truth). impl: adapter/claude-spt.toml + vendored adapter/manifest.schema.json + ci/manifest/{validate_manifest.py,check-manifest.sh} (gate). unit: tests/manifest-schema.sh (pass real + fail tampered). int: ci/manifest/registration-int.sh — real `spt adapter add` (v0.7.0) cross-field registration-validation accepted the manifest, shipped profile resolved, [strings] read + overlay observable; 6/6 green 2026-06-15 (registry left clean via soft-remove). Cross-field discovery: [digest] requires source-or-[history].locate_template (not in JSON schema) — fixed with source="{home}/.claude/projects".
80
81	[[requirements]]
82	id = "REQ-DIST-SHORTCUT-BASENAME"
83	title = "The adapter manifest brands the `spt endpoint run` launcher shortcut as `cc-<id>` via adapter.shortcut_basename = \"cc\" (the M12 cc launcher; decoupled from the sptc plugin name, ADR-0001)"
84	required_stages = ["doc", "impl", "unit"]  # doc: ADR-0001 (cc launcher brand, decoupled from the s/sptc/spt/ plugin-name succession). impl: the cc-launcher BRINGUP machinery — adapter [session.self] (spawns `claude`) + [env.SPT_ENDPOINT_ID] (broker injects the endpoint id) + the SessionStart bind branch (sptc_register_verb -> `api bind`, the spt-hosted self-register path). unit: tests/manifest-shortcut.sh (brand-value guard) + tests/hooks-parse.sh sptc_register_verb (bind/seed/boundary branch). int (real `spt endpoint run` picker emits cc-<id> + real-claude bringup-bind) deferred — the shortcut-emitting picker "lands in a later spt-core wave" (per `endpoint run --help`); the bringup-bind is now contract-unblocked (doyle confirmed 2026-06-15: bind is establishing/intrinsic-auth, --set-session-id only, no token) but still needs a real-claude acceptance spawn (heavier tier). adapter add accepting the [session.self]/[env] blocks is covered by registration-int.sh step 4d (REQ-DIST-MANIFEST-SCHEMA int).
85
86	[[requirements]]
87	id = "REQ-CC-LAUNCHER-BIND"
88	title = "spt-hosted bringup self-binds E2E: `spt endpoint run claude-spt <id>` spawns the [session.self] CC session which — via [env.SPT_ENDPOINT_ID]={id} (spt-core fills it, v0.11.0+ REQ-HAZARD-ENV-SUBST/F-013) + the SessionStart `bind` branch — registers a BOUND perch on disk reachable by `spt send` (live PTY inject, SENT). The M12 cc-launcher reachability, the gap that hid the wall-b zero-perch."

... [227 lines truncated] ...


1	# claude-spt — Claude Code adapter manifest (publish target #2: the spt-core adapter registry side).
2	#
3	# This is the spt-core-conducted layer of the distribution split (ADR-0001): the volatile
4	# `[digest]` extractor / profiles / strings / hints ride here, NOT in the thin cplugs skeleton.
5	# Registered with `spt adapter add <path>`; the version-of-truth is `spt adapter list`, not the
6	# marketplace `plugin.json` version.
7	#
8	# Authored against spt-core's PUBLISHED v0.7.0 surface ONLY (spt-releases + sabermage.github.io/
9	# spt-releases) — `manifest.schema.json` is vendored beside this file (adapter/manifest.schema.json,
10	# provenance: https://sabermage.github.io/spt-releases/manifest.schema.json). Validated by the
11	# manifest-schema CI gate (ci/manifest/). NEVER copy spt-core internals (AGENTS.md).
12	#
13	# Deferred to later parity slices (not in this slice; each declares an adapter seam we have not
14	# yet built, or needs a capability not on the public surface — see notes inline):
15	#   * [session.<role>] for psyche_init/psyche_resume/echo_commune/signoff/notif — the live-agent /
16	#     Psyche layer (owl/$LIVE), absent from the core `spt` surface. Open scope question (does
17	#     claude-spt reach the Psyche layer?). [session.self] IS authored below (the endpoint-run/bind
18	#     bringup that hosts a fresh CC session — the M12 `cc` launcher target).
19	#   * [history]                     — transcript-access seam. Lands with [digest]'s sibling fetcher.
20	#   * [update]                      — NOW DECLARED below via the `gh_release` avenue (spt v0.8.0):
21	#     spt-core's `--release` machinery auto-updates the adapter from THIS repo's GitHub releases on
22	#     `spt adapter update`, with NO Ed25519 signing infra (closes the F-005 parked `file_pull`/
23	#     `delegated` legs). Per-OS interaction flagged to doyle (gh_release `asset` is a single name; how
24	#     does auto-update pick the host's `adapter-<os>-<arch>.spt`?).
25	#
26	# [impl->REQ-DIST-MANIFEST-SCHEMA]
27
28	[adapter]
29	name = "claude-spt"
30	kind = "harness"
31	# 0.6.1 (2026-06-22): PACKAGING modernization — the release now ships a single MULTI-PLATFORM fat
32	# .spt (per-triple subdirs, ADR-0024 W1) which only spt-core >= 0.13.2 can extract, so the floor moves
33	# to 0.13.2 (see below) and /sptc:setup drops its now-redundant os-detection (`adapter add --release`
34	# is host-agnostic). The seam surface is unchanged from 0.6.0 (the v0.13.0 RUN-group seams
35	# [session.resume] + [message-idle-translation-binary], added in 0.6.0). Fresh tag, not an in-place
36	# v0.6.0 re-cut (a re-cut asset on the same tag is ambiguous — operator + doyle call).
37	# 0.6.2 (2026-06-23): FIX — idle message delivery now submits with a discrete Enter keypress instead of
38	# a trailing carriage return in the injected text. A `\r` byte does NOT trigger Claude Code's message
39	# submission (newly discovered), so idle-delivered messages typed into the input box but never sent;
40	# the [message-idle-translation-binary] choreography now ends with {key:enter} after the text. Binary
41	# rebuild only — manifest seams + floor unchanged.
42	# 0.7.0 (2026-06-24): the CHECKPOINT-COMMUNE WAVE — three operator-requested deliverables. (T1) the
43	# idle-translation binary now FRAMES each inbound <EVENT> across multiple lines (a raw \n after the
44	# opening tag and before </EVENT>) for visual distinction — CC soft-newlines a bare \n, empirically
45	# gated. (T2) AGENT-DRIVEN CHECKPOINT: a NEW [hooks.PostToolUse] (Write matcher) detects a `!!checkpoint!!`
46	# trigger in a live agent's own `.claude/<id>-commune.md` and self-sends `spt send --json-payload
47	# '{"checkpoint":"v1","wake":…}'`; the signal loops back through the endpoint's own translation binary,
48	# which parses the structured json envelope-attr and fires a /clear + wake macro — the agent clearing +
49	# rebuilding its own context from its freshest commune. (T3) RESUME parity: SessionStart now pulls
50	# `spt api psyche-download <id>` and injects the durable role/live/project + pending commune/signoff as
51	# additionalContext (closes F-020). These REQUIRE spt-core v0.15.0 (the `--json-payload` send axis + the
52	# `psyche-download` verb), so the floor BUMPS to 0.15.0 below.
53	version = "0.7.0"
54	# Floor BUMPED to 0.13.2 (2026-06-22, C / F-014 drop): the release packaging moved from the per-OS
55	# stopgap (`adapter.spt` = a windows-binary copy — F-014; broke on a linux host) to ONE fat .spt that
56	# bundles both x86_64 triples beside a shared manifest. spt-core extracts a fat archive (classify
57	# top-level triple dirs → flatten this node's triple into the install dir, preserving bare-name
58	# resolution) ONLY on >= 0.13.2 (doyle, extract_release_archive); an older node cannot read the asset
59	# at all, so declaring the floor is honest, not a needless block. (Prior floor 0.9.0 was the
60	# adapter-agnostic seed/listen-by-host_binaries requirement, PREP-4 — still satisfied, just superseded.)
61	# Floor BUMPED to 0.15.0 (2026-06-24, the checkpoint-commune wave / v0.7.0): T2's checkpoint self-send
62	# needs `spt send --json-payload` (the opaque-metadata send axis) and T3's resume pull needs the
63	# `spt api psyche-download <id>` verb — BOTH land in spt-core v0.15.0 (counter 34, Latest). The
64	# multi-line frame (T1) works on any node, but the wave ships as one unit, so the honest floor is the
65	# verb floor. An older node can't fire checkpoint or pull resume context, so declaring 0.15.0 is honest.
66	min_spt_core_version = "0.15.0"
67	hostable_types = ["LiveAgent", "ReadyAgent", "Worker"]
68	# host_binaries — STAGED ahead of spt-core v0.9.0 (doyle 2026-06-16). The pid→binary match-key for
69	# adapter-agnostic resolution: `spt api listen <id>` resolves the owning adapter/profile by walking
70	# parent pid → exe basename → host_binaries match → active-profile pointer → registered_at_ms
71	# fallback (CONTEXT §170-186). Additive + N-1-safe: harmless before spt-core reads it (the
72	# vendored v0.7.0 schema's [adapter] allows additional props), live once v0.9.0 + `spt adapter use`
73	# land. Claude Code's host process basename is `claude`. [impl->REQ-SKILL-LIVE]
74	host_binaries = ["claude"]
75	# Brands the `spt endpoint run` picker shortcut as `cc-<id>` (default would be `spt-<id>`) — this is
76	# the M12 `cc` launcher, and matches the schema's own example (spt-claude-code → `cc`). The launcher
77	# brand is DECOUPLED from the plugin name (`sptc`, skills `/sptc:*`): the s/sptc/spt/ succession seam
78	# (ADR-0001) renames the plugin, not this shortcut. Guarded by tests/manifest-shortcut.sh
79	# (unit->REQ-DIST-SHORTCUT-BASENAME).
80	shortcut_basename = "cc"
81
82	# ── [update] ───────────────────────────────────────────────────────────────────────────────────
83	# Adapter self-update via OUR GitHub releases (gh_release avenue, spt v0.8.0). `spt adapter update`
84	# pulls the adapter `.spt` asset from this repo's releases through the same `--release` machinery —
85	# no signing infra (closes the F-005 file_pull/delegated blockers). `asset` omitted ⇒ spt's default
86	# (adapter.spt), which is now the SINGLE MULTI-PLATFORM fat archive (both x86_64 triples + shared
87	# manifest, ADR-0024 W1) — so one asset name auto-resolves the host's binaries. This RETIRES the F-014
88	# per-OS stopgap (the old `asset`-less default fetched a windows-only `adapter.spt` that broke on a
89	# linux host); no `{os}/{arch}` placeholder is needed since the fat archive is host-agnostic.
90	# `message` (U1, REQ-DIST-UPDATE-MESSAGE): markdown spt-core prints ONLY on a real version apply (no
91	# `{key}` substitution — docs-confirmed). It bridges the one manual residual the gh_release avenue
92	# can't automate — the `/reload-plugins` TUI action — and points at the more-powerful `spt` CLI
93	# endpoint route alongside /sptc:live. (When doyle ask #2 lands, the post-update step can also trigger
94	# this print on a plugin-only change; copy stays valid.)
95	# [impl->REQ-DIST-ADAPTER-RELEASE]
96	[update]
97	avenue = "gh_release"
98	repo = "SaberMage/claude-spt"
99	message = """

... [378 lines truncated] ...