1	---
2	name: write-a-skill
3	description: Create new agent skills with proper structure, progressive disclosure, and bundled resources. Use when user wants to create, write, or build a new skill.
4	---
5
6	# Writing Skills
7
8	## Process
9
10	1. **Gather requirements** - ask user about:
11	   - What task/domain does the skill cover?
12	   - What specific use cases should it handle?
13	   - Does it need executable scripts or just instructions?
14	   - Any reference materials to include?
15
16	2. **Draft the skill** - create:
17	   - SKILL.md with concise instructions
18	   - Additional reference files if content exceeds 500 lines
19	   - Utility scripts if deterministic operations needed
20
21	3. **Review with user** - present draft and ask:
22	   - Does this cover your use cases?
23	   - Anything missing or unclear?
24	   - Should any section be more/less detailed?
25
26	## Skill Structure
27
28	```
29	skill-name/
30	├── SKILL.md           # Main instructions (required)
31	├── REFERENCE.md       # Detailed docs (if needed)
32	├── EXAMPLES.md        # Usage examples (if needed)
33	└── scripts/           # Utility scripts (if needed)
34	    └── helper.js
35	```
36
37	## SKILL.md Template
38
39	```md
40	---
41	name: skill-name
42	description: Brief description of capability. Use when [specific triggers].
43	---
44
45	# Skill Name
46
47	## Quick start
48
49	[Minimal working example]
50
51	## Workflows
52
53	[Step-by-step processes with checklists for complex tasks]
54
55	## Advanced features
56
57	[Link to separate files: See [REFERENCE.md](REFERENCE.md)]
58	```
59
60	## Description Requirements
61
62	The description is **the only thing your agent sees** when deciding which skill to load. It's surfaced in the system prompt alongside all other installed skills. Your agent reads these descriptions and picks the relevant skill based on the user's request.
63
64	**Goal**: Give your agent just enough info to know:
65
66	1. What capability this skill provides
67	2. When/why to trigger it (specific keywords, contexts, file types)
68
69	**Format**:
70
71	- Max 1024 chars
72	- Write in third person
73	- First sentence: what it does
74	- Second sentence: "Use when [specific triggers]"
75
76	**Good example**:
77
78	```
79	Extract text and tables from PDF files, fill forms, merge documents. Use when working with PDF files or when user mentions PDFs, forms, or document extraction.
80	```
81
82	**Bad example**:
83
84	```
85	Helps with documents.
86	```
87
88	The bad example gives your agent no way to distinguish this from other document skills.
89
90	## When to Add Scripts
91
92	Add utility scripts when:
93
94	- Operation is deterministic (validation, formatting)
95	- Same code would be generated repeatedly
96	- Errors need explicit handling
97
98	Scripts save tokens and improve reliability vs generated code.
99
100	## When to Split Files
101
102	Split into separate files when:
103
104	- SKILL.md exceeds 100 lines
105	- Content has distinct domains (finance vs sales schemas)
106	- Advanced features are rarely needed
107
108	## Review Checklist
109
110	After drafting, verify:
111
112	- [ ] Description includes triggers ("Use when...")
113	- [ ] SKILL.md under 100 lines
114	- [ ] No time-sensitive info
115	- [ ] Consistent terminology
116	- [ ] Concrete examples included
117	- [ ] References one level deep
118

---
name: write-a-skill
description: Create new agent skills with proper structure, progressive disclosure, and bundled resources. Use when user wants to create, write, or build a new skill.
---

# Writing Skills

## Process

1. **Gather requirements** - ask user about:
   - What task/domain does the skill cover?
   - What specific use cases should it handle?
   - Does it need executable scripts or just instructions?
   - Any reference materials to include?

2. **Draft the skill** - create:
   - SKILL.md with concise instructions
   - Additional reference files if content exceeds 500 lines
   - Utility scripts if deterministic operations needed

3. **Review with user** - present draft and ask:
   - Does this cover your use cases?
   - Anything missing or unclear?
   - Should any section be more/less detailed?

## Skill Structure

```
skill-name/
├── SKILL.md           # Main instructions (required)
├── REFERENCE.md       # Detailed docs (if needed)
├── EXAMPLES.md        # Usage examples (if needed)
└── scripts/           # Utility scripts (if needed)
    └── helper.js
```

## SKILL.md Template

```md
---
name: skill-name
description: Brief description of capability. Use when [specific triggers].
---

# Skill Name

## Quick start

[Minimal working example]

## Workflows

[Step-by-step processes with checklists for complex tasks]

## Advanced features

[Link to separate files: See [REFERENCE.md](REFERENCE.md)]
```

## Description Requirements

The description is **the only thing your agent sees** when deciding which skill to load. It's surfaced in the system prompt alongside all other installed skills. Your agent reads these descriptions and picks the relevant skill based on the user's request.

**Goal**: Give your agent just enough info to know:

1. What capability this skill provides
2. When/why to trigger it (specific keywords, contexts, file types)

**Format**:

- Max 1024 chars
- Write in third person
- First sentence: what it does
- Second sentence: "Use when [specific triggers]"

**Good example**:

```
Extract text and tables from PDF files, fill forms, merge documents. Use when working with PDF files or when user mentions PDFs, forms, or document extraction.
```

**Bad example**:

```
Helps with documents.
```

The bad example gives your agent no way to distinguish this from other document skills.

## When to Add Scripts

Add utility scripts when:

- Operation is deterministic (validation, formatting)
- Same code would be generated repeatedly
- Errors need explicit handling

Scripts save tokens and improve reliability vs generated code.

## When to Split Files

Split into separate files when:

- SKILL.md exceeds 100 lines
- Content has distinct domains (finance vs sales schemas)
- Advanced features are rarely needed

## Review Checklist

After drafting, verify:

- [ ] Description includes triggers ("Use when...")
- [ ] SKILL.md under 100 lines
- [ ] No time-sensitive info
- [ ] Consistent terminology
- [ ] Concrete examples included
- [ ] References one level deep


Got the principles (desc = what + "Use when"; <100 lines; concise; consistent). Sampling current non-live skeletons + the big `setup` body + a small body for style.


1	---
2	name: send
3	description: |
4	  Send a message to another SPT agent.
5	argument-hint: "<target> [--reply-to <sender>]"
6	allowed-tools: [Bash]
7	---
8
9	# /sptc:send
10
11	> **Skeleton — thin by design.** Operative instructions for this skill are delivered by the
12	> `sptc` adapter at invocation time (UserPromptSubmit injection from the adapter `[strings]`;
13	> see `docs/adr/0001-distribution-splits-by-volatility.md`). This SKILL.md stays a stub.
14	>
15	> **Operative.** The UPS hook detects `/sptc:send` and injects the body from
16	> `adapter/strings/skills/send.md` (UPS-fires-on-slash confirmed, ADR-0002; file-backed `[strings]`
17	> shipped, F-003). If injection ever no-ops (spt absent / adapter unregistered), this stub is the floor.
18
19	Delivers a message to another agent; supports reply-to and ring/ask.
20

---
name: send
description: |
  Send a message to another SPT agent.
argument-hint: "<target> [--reply-to <sender>]"
allowed-tools: [Bash]
---

# /sptc:send

> **Skeleton — thin by design.** Operative instructions for this skill are delivered by the
> `sptc` adapter at invocation time (UserPromptSubmit injection from the adapter `[strings]`;
> see `docs/adr/0001-distribution-splits-by-volatility.md`). This SKILL.md stays a stub.
>
> **Operative.** The UPS hook detects `/sptc:send` and injects the body from
> `adapter/strings/skills/send.md` (UPS-fires-on-slash confirmed, ADR-0002; file-backed `[strings]`
> shipped, F-003). If injection ever no-ops (spt absent / adapter unregistered), this stub is the floor.

Delivers a message to another agent; supports reply-to and ring/ask.


1	# /sptc:ready — operative instructions
2
3	> Delivered file-backed via the `claude-spt` adapter `[strings]`
4	> (`[strings.skills].ready = { file = "skills/ready.md" }`), resolved at injection time. The cplugs
5	> SKILL.md stays a thin skeleton (ADR-0001).
6
7	**Goal:** make this session reachable for inter-agent messages (register a perch and listen).
8
9	**Do this:**
10
11	1. If `spt` is not on `PATH`, run `/sptc:setup` first.
12	2. Read the canonical, always-current guidance: run `spt how-to ready` and follow it.
13	3. Operative summary (from that guidance):
14	   - Pick a short lowercase perch id, or reuse this session's id from `spt whoami`.
15	   - Preferred (harness hosts a long-running task): `spt ready <id>` — it **blocks** for the
16	     session's life, so run it as a **background task** and read its stdout. `READY:<id>` on stderr
17	     is the online signal; the spooled backlog drains first, then each delivery prints as it arrives.
18	   - Fallback (no long-running tasks): `spt ready <id> --once` — drains the backlog, waits for one
19	     delivery, exits. Re-run after each exit to stay reachable.
20	4. Delivery shape on stdout is the `<EVENT type="msg" from="<sender>">body</EVENT>` envelope (body
21	   HTML-escaped, newlines as `<br>`). To reply, pipe the body to `spt send --reply-to <sender>`.
22

# /sptc:ready — operative instructions

> Delivered file-backed via the `claude-spt` adapter `[strings]`
> (`[strings.skills].ready = { file = "skills/ready.md" }`), resolved at injection time. The cplugs
> SKILL.md stays a thin skeleton (ADR-0001).

**Goal:** make this session reachable for inter-agent messages (register a perch and listen).

**Do this:**

1. If `spt` is not on `PATH`, run `/sptc:setup` first.
2. Read the canonical, always-current guidance: run `spt how-to ready` and follow it.
3. Operative summary (from that guidance):
   - Pick a short lowercase perch id, or reuse this session's id from `spt whoami`.
   - Preferred (harness hosts a long-running task): `spt ready <id>` — it **blocks** for the
     session's life, so run it as a **background task** and read its stdout. `READY:<id>` on stderr
     is the online signal; the spooled backlog drains first, then each delivery prints as it arrives.
   - Fallback (no long-running tasks): `spt ready <id> --once` — drains the backlog, waits for one
     delivery, exits. Re-run after each exit to stay reachable.
4. Delivery shape on stdout is the `<EVENT type="msg" from="<sender>">body</EVENT>` envelope (body
   HTML-escaped, newlines as `<br>`). To reply, pipe the body to `spt send --reply-to <sender>`.


1	# /sptc:setup — operative instructions
2
3	> Delivered file-backed via the `claude-spt` adapter `[strings]`
4	> (`[strings.skills].setup = { file = "skills/setup.md" }`), resolved at injection time. The cplugs
5	> SKILL.md stays a thin skeleton (ADR-0001).
6
7	**Goal:** install or repair spt-core for this session **and ACTIVATE the claude-spt adapter** — the
8	mid-session installer that covers the gap when no SessionStart bootstrap has fired (a user who
9	installs the plugin mid-session). Installing the binary is only half the job: a present binary with
10	a **deregistered** adapter has no profiles/strings/hints/`[digest]`, so `/sptc:*` injection has
11	nothing to source. Setup must leave the adapter **active**.
12
13	<!-- [doc->REQ-SETUP-ACTIVATE] -->
14
15	**Do this:**
16
17	1. **Binary.** Check whether spt-core is present: `command -v spt && spt --version`.
18	   - If absent, run the published install-on-demand bootstrap (verbatim against the spt-releases
19	     contract, `harness-contract/install-on-demand.md`):
20	     - **POSIX:** `curl -fsSL https://sabermage.github.io/spt-releases/install.sh | sh`
21	     - **Windows (PowerShell):** `irm https://sabermage.github.io/spt-releases/install.ps1 | iex`
22	   - `PATH` is not reloaded in the current shell after a fresh install — verify with the absolute
23	     path for the first call: `"$HOME/.local/bin/spt" --version` (POSIX). Report the version.
24
25	2. **Adapter activation (the step a present binary still needs).** Run `spt adapter list` and look
26	   for `claude-spt`:
27	   - If `claude-spt` is listed and **not** marked `deregistered` → the adapter is **active**; report
28	     "adapter active" and go to step 4.
29	   - If `claude-spt` is **missing or `deregistered`** → **activate** it. Pick the source:
30	     - **Local dev / dogfooding from a repo checkout** (an `adapter/claude-spt.toml` is present near
31	       cwd): `spt adapter add ./adapter/claude-spt.toml` (the file-form takes any path + filename).
32	     - **End-user (plugin only, no repo checkout):** the `.spt` asset carries native binaries, so it
33	       ships **per-OS** — select the one matching this host. Detect os + arch:
34	       ```sh
35	       os=$(uname -s);  case "$os" in MINGW*|MSYS*|CYGWIN*|Windows*) os=windows;; Linux) os=linux;; Darwin) os=macos;; esac
36	       arch=$(uname -m); case "$arch" in x86_64|amd64) arch=x86_64;; arm64|aarch64) arch=aarch64;; esac
37	       ```
38	       then `spt adapter add --release SaberMage/spt-claude-code --asset adapter-$os-$arch.spt` —
39	       fetches the per-OS `adapter-<os>-<arch>.spt` release asset (a tar whose **root** holds
40	       `manifest.toml` + `strings/` + the native tool binaries) from the repo's GitHub release,
41	       extracts it to the durable adapter home, and registers it. Add `--tag <ver>` to pin a version
42	       (omit for latest). Re-running with a newer `--tag` is a manual re-acquire. `adapter add` is
43	       manifest-first (an invalid manifest registers nothing). (v1 ships **windows + linux** assets.
44	       Recommended path — straight from the monorepo, no dedicated repo. Needs the spt release that
45	       carries `--release`; the older `--github <root-manifest-repo>` is the alternative.)
46	       <!-- [doc->REQ-DIST-ADAPTER-PEROS] -->
47
48	3. **Verify activation.** Re-run `spt adapter list`: `claude-spt` must now appear **active** (no
49	   `deregistered`). Spot-check the profile resolves: `spt adapter get-string claude-spt:ccs adapter_label`
50	   (the shipped overlay — `:ccs`). Report the active state.
51
52	   Then **set the active-profile pointer** so bare resolution lands on this adapter for the `claude`
53	   host binary (the legacy-parity bare flow — `/sptc:live` and `/sptc:ready` need no `--adapter`):
54	   `spt adapter use claude-spt`. (With a single claude-hosting adapter registered this is the implicit
55	   default, but setting it is explicit + durable. There is **no `:live` profile** — base claude-spt is
56	   live-capable and the command decides ready vs live; reach for `--adapter claude-spt:ccs`
57	   only to select the ccs override profile.)
58
59	4. **Tool binaries — resolved from the install dir (REQ-INSTALL-11; no PATH copy).** The `[digest]`
60	   extractor (`claude-spt-digest`) and the Psyche runner (`claude-spt-psyche`) are invoked by **bare
61	   name**. spt-core resolves them **from the adapter install dir** — the `from …` path in
62	   `spt adapter list` (e.g. `…/adapters/_github/<safe>/`), where `--release` activation already
63	   extracted them beside the manifest. **Nothing to do here:** step 2 placed them; no PATH copy is
64	   needed. Verified on spt **v0.8.1** — session-digest and the daemon-hosted Psyche both resolve the
65	   binary straight from the install dir with nothing on PATH.
66	   - *(The legacy F-006 interim PATH-copy step is **retired**: spt-core's install-dir resolution —
67	     REQ-INSTALL-11, Feature B, landed in spt v0.8.0 — supersedes it. If session-digest or the Psyche
68	     ever fails to start, confirm the two `.exe`s are present in the install dir above; their absence
69	     is a packaging defect, not a PATH problem.)*
70
71	5. **ccs wiring (optional — SCOPE setup #7).** Detect `~/.ccs`:
72	   - **Present** → ccs is installed. The shipped **`claude-spt:ccs`** profile leaf-replaces the live
73	     session command with `ccs` (a drop-in for `claude`), so live/ready agents can run on ccs's
74	     configured backends (glm/kimi/custom from `~/.ccs/config.json`) instead of `claude`. Use it by
75	     selecting the `:ccs` composite: e.g. `/sptc:live` / `/sptc:ready` under `--adapter claude-spt:ccs`,
76	     or `spt endpoint run --adapter claude-spt:ccs`. Sanity-check `command -v ccs`; if `~/.ccs` exists
77	     but `ccs` is not on PATH, point the user at their ccs install's bin dir. (No action needed if
78	     they don't want ccs — base `claude-spt` is unaffected.)
79	   - **Absent** → ccs is an optional CLI router that lets your spt sessions drive alternate model
80	     backends (glm/kimi/custom) in place of `claude`. To enable: install ccs (see its docs), then
81	     re-run `/sptc:setup`. Skip if not wanted.
82
83	   <!-- [doc->REQ-SETUP-CCS] -->
84
85	6. **Subnet onboarding (optional — SCOPE setup #3/#4).** A **subnet** is the private group of paired
86	   machines that makes `/sptc:send`, `/sptc:ready`, and live agents work **cross-machine** (local
87	   single-machine use needs none). Check membership: `spt subnet status` (or bare `spt subnet`).
88	   - **Already in a subnet** → report it. To invite another machine: `spt subnet show-code` (prints
89	     the current 6-digit code + `otpauth://` URI + a terminal QR). On the joining machine run
90	     `spt subnet join <name> --code <code>`.
91	   - **Not in a subnet** → offer either: **create** the first one — `spt subnet create <name>` (this
92	     node becomes the seed-holder; prints code/URI/QR) — or **join** an existing one —
93	     `spt subnet join <name> --code <code>`. Skip if single-machine use is fine.
94	   - Full verb guidance (status/create/show-code/join + lifecycle) lives in **/sptc:subnet** — route
95	     there rather than re-explaining.
96	   - **Elevation:** `create`/`join`/`show-code` are **OS-elevation-gated** (seed-reveal /
97	     machine-enrollment). Run where elevation can be granted: **Windows** → an elevated (UAC) shell;
98	     **Linux desktop** → pkexec/polkit or a sudo-capable terminal; **Linux TTY** → inline `sudo`;
99	     **headless / no-TTY** → print the exact command for the user to run elevated. (Automated
100	     context-aware elevation is a deeper wave; today, surface the requirement + the exact command.)
101
102	   <!-- [doc->REQ-SETUP-SUBNET] -->
103
104	After this initial bootstrap + activation, `spt update` handles signed self-updates automatically —
105	the user does not run setup again. The whole flow is idempotent and safe to re-run.
106

# /sptc:setup — operative instructions

> Delivered file-backed via the `claude-spt` adapter `[strings]`
> (`[strings.skills].setup = { file = "skills/setup.md" }`), resolved at injection time. The cplugs
> SKILL.md stays a thin skeleton (ADR-0001).

**Goal:** install or repair spt-core for this session **and ACTIVATE the claude-spt adapter** — the
mid-session installer that covers the gap when no SessionStart bootstrap has fired (a user who
installs the plugin mid-session). Installing the binary is only half the job: a present binary with
a **deregistered** adapter has no profiles/strings/hints/`[digest]`, so `/sptc:*` injection has
nothing to source. Setup must leave the adapter **active**.

<!-- [doc->REQ-SETUP-ACTIVATE] -->

**Do this:**

1. **Binary.** Check whether spt-core is present: `command -v spt && spt --version`.
   - If absent, run the published install-on-demand bootstrap (verbatim against the spt-releases
     contract, `harness-contract/install-on-demand.md`):
     - **POSIX:** `curl -fsSL https://sabermage.github.io/spt-releases/install.sh | sh`
     - **Windows (PowerShell):** `irm https://sabermage.github.io/spt-releases/install.ps1 | iex`
   - `PATH` is not reloaded in the current shell after a fresh install — verify with the absolute
     path for the first call: `"$HOME/.local/bin/spt" --version` (POSIX). Report the version.

2. **Adapter activation (the step a present binary still needs).** Run `spt adapter list` and look
   for `claude-spt`:
   - If `claude-spt` is listed and **not** marked `deregistered` → the adapter is **active**; report
     "adapter active" and go to step 4.
   - If `claude-spt` is **missing or `deregistered`** → **activate** it. Pick the source:
     - **Local dev / dogfooding from a repo checkout** (an `adapter/claude-spt.toml` is present near
       cwd): `spt adapter add ./adapter/claude-spt.toml` (the file-form takes any path + filename).
     - **End-user (plugin only, no repo checkout):** the `.spt` asset carries native binaries, so it
       ships **per-OS** — select the one matching this host. Detect os + arch:
       ```sh
       os=$(uname -s);  case "$os" in MINGW*|MSYS*|CYGWIN*|Windows*) os=windows;; Linux) os=linux;; Darwin) os=macos;; esac
       arch=$(uname -m); case "$arch" in x86_64|amd64) arch=x86_64;; arm64|aarch64) arch=aarch64;; esac
       ```
       then `spt adapter add --release SaberMage/spt-claude-code --asset adapter-$os-$arch.spt` —
       fetches the per-OS `adapter-<os>-<arch>.spt` release asset (a tar whose **root** holds
       `manifest.toml` + `strings/` + the native tool binaries) from the repo's GitHub release,
       extracts it to the durable adapter home, and registers it. Add `--tag <ver>` to pin a version
       (omit for latest). Re-running with a newer `--tag` is a manual re-acquire. `adapter add` is
       manifest-first (an invalid manifest registers nothing). (v1 ships **windows + linux** assets.
       Recommended path — straight from the monorepo, no dedicated repo. Needs the spt release that
       carries `--release`; the older `--github <root-manifest-repo>` is the alternative.)
       <!-- [doc->REQ-DIST-ADAPTER-PEROS] -->

3. **Verify activation.** Re-run `spt adapter list`: `claude-spt` must now appear **active** (no
   `deregistered`). Spot-check the profile resolves: `spt adapter get-string claude-spt:ccs adapter_label`
   (the shipped overlay — `:ccs`). Report the active state.

   Then **set the active-profile pointer** so bare resolution lands on this adapter for the `claude`
   host binary (the legacy-parity bare flow — `/sptc:live` and `/sptc:ready` need no `--adapter`):
   `spt adapter use claude-spt`. (With a single claude-hosting adapter registered this is the implicit
   default, but setting it is explicit + durable. There is **no `:live` profile** — base claude-spt is
   live-capable and the command decides ready vs live; reach for `--adapter claude-spt:ccs`
   only to select the ccs override profile.)

4. **Tool binaries — resolved from the install dir (REQ-INSTALL-11; no PATH copy).** The `[digest]`
   extractor (`claude-spt-digest`) and the Psyche runner (`claude-spt-psyche`) are invoked by **bare
   name**. spt-core resolves them **from the adapter install dir** — the `from …` path in
   `spt adapter list` (e.g. `…/adapters/_github/<safe>/`), where `--release` activation already
   extracted them beside the manifest. **Nothing to do here:** step 2 placed them; no PATH copy is
   needed. Verified on spt **v0.8.1** — session-digest and the daemon-hosted Psyche both resolve the
   binary straight from the install dir with nothing on PATH.
   - *(The legacy F-006 interim PATH-copy step is **retired**: spt-core's install-dir resolution —
     REQ-INSTALL-11, Feature B, landed in spt v0.8.0 — supersedes it. If session-digest or the Psyche
     ever fails to start, confirm the two `.exe`s are present in the install dir above; their absence
     is a packaging defect, not a PATH problem.)*

5. **ccs wiring (optional — SCOPE setup #7).** Detect `~/.ccs`:
   - **Present** → ccs is installed. The shipped **`claude-spt:ccs`** profile leaf-replaces the live
     session command with `ccs` (a drop-in for `claude`), so live/ready agents can run on ccs's
     configured backends (glm/kimi/custom from `~/.ccs/config.json`) instead of `claude`. Use it by
     selecting the `:ccs` composite: e.g. `/sptc:live` / `/sptc:ready` under `--adapter claude-spt:ccs`,
     or `spt endpoint run --adapter claude-spt:ccs`. Sanity-check `command -v ccs`; if `~/.ccs` exists
     but `ccs` is not on PATH, point the user at their ccs install's bin dir. (No action needed if
     they don't want ccs — base `claude-spt` is unaffected.)
   - **Absent** → ccs is an optional CLI router that lets your spt sessions drive alternate model
     backends (glm/kimi/custom) in place of `claude`. To enable: install ccs (see its docs), then
     re-run `/sptc:setup`. Skip if not wanted.

   <!-- [doc->REQ-SETUP-CCS] -->

6. **Subnet onboarding (optional — SCOPE setup #3/#4).** A **subnet** is the private group of paired
   machines that makes `/sptc:send`, `/sptc:ready`, and live agents work **cross-machine** (local
   single-machine use needs none). Check membership: `spt subnet status` (or bare `spt subnet`).
   - **Already in a subnet** → report it. To invite another machine: `spt subnet show-code` (prints
     the current 6-digit code + `otpauth://` URI + a terminal QR). On the joining machine run
     `spt subnet join <name> --code <code>`.
   - **Not in a subnet** → offer either: **create** the first one — `spt subnet create <name>` (this
     node becomes the seed-holder; prints code/URI/QR) — or **join** an existing one —
     `spt subnet join <name> --code <code>`. Skip if single-machine use is fine.
   - Full verb guidance (status/create/show-code/join + lifecycle) lives in **/sptc:subnet** — route
     there rather than re-explaining.
   - **Elevation:** `create`/`join`/`show-code` are **OS-elevation-gated** (seed-reveal /
     machine-enrollment). Run where elevation can be granted: **Windows** → an elevated (UAC) shell;
     **Linux desktop** → pkexec/polkit or a sudo-capable terminal; **Linux TTY** → inline `sudo`;
     **headless / no-TTY** → print the exact command for the user to run elevated. (Automated
     context-aware elevation is a deeper wave; today, surface the requirement + the exact command.)

   <!-- [doc->REQ-SETUP-SUBNET] -->

After this initial bootstrap + activation, `spt update` handles signed self-updates automatically —
the user does not run setup again. The whole flow is idempotent and safe to re-run.


/grill-with-docs i noticed that the skills here are not well written. they're bloated with too much inessential information. please rewrite them all using the following references: -reference /write-a…


Update Claude-spt adapter configuration and flags


Clear picture now. Current state:
- **Plugin skeletons**: verbose note w/ ADR-0001/0002/F-003 citations in the body; your hand-edited `live` dropped those for a clean 2-line note. → standardize all on your `live` note.
- **Adapter bodies**: every one opens with a "Delivered file-backed via the adapter `[strings]`…" meta-blockquote; some (`ready`) still redirect to `spt how-to X` instead of being self-contained (your `live.md` killed that redirect).
- **`setup`** (105 lines) is the special self-contained floor; **`version`** is trivial.

Most decisions are answerable from your two reference files + the legacy basis. Four genuine forks remain — batching them so I don't round-trip six times:


AskUserQuestion

Question: In skill `description` routing phrases, which command prefix?

Choices:
Use /sptc: everywhere (the actual shipped plugin name — what users type today). Correct now; the succession flip to /spt: is the documented s/sptc/spt/ seam done later.
Match your hand-edited live/SKILL.md (which kept legacy `/spt:live`) + the eventual succession name. Risk: wrong for the plugin as currently shipped.

Question: The meta-blockquote atop every adapter body ("Delivered file-backed via the adapter [strings]…")?

Choices:
The injected body should be pure operative instructions — the receiving agent doesn't need to know its own delivery mechanism. Tightest; best matches 'no bloat'. (Traceability <!-- [doc->REQ-*] --> tags stay.)
Keep a single terse provenance line (your live.md kept ~3 lines). Slightly more context, slightly more bloat.

Question: How to treat `setup` (the self-contained floor that must work when spt is absent)?

Choices:
setup's plugin SKILL.md stays self-contained (NOT a thin stub, since injection can no-op pre-install); only tighten its prose. Adapter setup.md tightened but keeps all operative content. version + the other 8 go fully thin.
Make setup a thin stub too. Risk: breaks the pre-install floor — if spt isn't there, injection no-ops and the stub has no instructions.

Question: Capture the two-surface skill-authoring convention in a doc?

Choices:
Add a short 'Skill authoring' section to docs/DOCS-STRATEGY.md: the two surfaces, their shapes, the standard skeleton note, self-contained bodies. So future skills follow it.
Standalone docs/SKILL-AUTHORING.md with the templates + checklist.
Just do the rewrite; don't write a convention doc.


Your questions have been answered: "In skill `description` routing phrases, which command prefix?"="/sptc:", "The meta-blockquote atop every adapter body ("Delivered file-backed via the adapter [strings]…")?"="Cut entirely", "How to treat `setup` (the self-contained floor that must work when spt is absent)?"="Exempt + tighten", "Capture the two-surface skill-authoring convention in a doc?"="new SKILL-AUTHORING.md + a ref to it within DOCS-STRATEGY.md". You can now continue with these answers in mind.

Question: In skill `description` routing phrases, which command prefix?

Choices:
Use /sptc: everywhere (the actual shipped plugin name — what users type today). Correct now; the succession flip to /spt: is the documented s/sptc/spt/ seam done later.
Match your hand-edited live/SKILL.md (which kept legacy `/spt:live`) + the eventual succession name. Risk: wrong for the plugin as currently shipped.

Question: The meta-blockquote atop every adapter body ("Delivered file-backed via the adapter [strings]…")?

Choices:
The injected body should be pure operative instructions — the receiving agent doesn't need to know its own delivery mechanism. Tightest; best matches 'no bloat'. (Traceability <!-- [doc->REQ-*] --> tags stay.)
Keep a single terse provenance line (your live.md kept ~3 lines). Slightly more context, slightly more bloat.

Question: How to treat `setup` (the self-contained floor that must work when spt is absent)?

Choices:
setup's plugin SKILL.md stays self-contained (NOT a thin stub, since injection can no-op pre-install); only tighten its prose. Adapter setup.md tightened but keeps all operative content. version + the other 8 go fully thin.
Make setup a thin stub too. Risk: breaks the pre-install floor — if spt isn't there, injection no-ops and the stub has no instructions.

Question: Capture the two-surface skill-authoring convention in a doc?

Choices:
Add a short 'Skill authoring' section to docs/DOCS-STRATEGY.md: the two surfaces, their shapes, the standard skeleton note, self-contained bodies. So future skills follow it.
Standalone docs/SKILL-AUTHORING.md with the templates + checklist.
Just do the rewrite; don't write a convention doc.

new SKILL-AUTHORING.md + a ref to it within DOCS-STRATEGY.md


All four locked: `/sptc:` prefix · cut adapter-body preamble (keep REQ tags) · `setup` exempt+tightened, rest thin · new `docs/SKILL-AUTHORING.md` + DOCS-STRATEGY ref.

I'll write the spec doc first (it doubles as the rewrite contract), then partition the work. Reading the rest of my own skills' files + legacy descriptions.


1	---
2	name: setup
3	description: |
4	  Install or repair spt-core AND activate the claude-spt adapter for this Claude Code session
5	  (mid-session installer + post-install activation).
6	allowed-tools: [Bash]
7	---
8
9	# /sptc:setup
10
11	> **Self-contained by necessity.** Unlike other `/sptc:*` skills, `setup` cannot rely on
12	> UPS-injection of its body: it runs precisely when spt-core may be **absent**, so
13	> `spt adapter get-string` (the injection source) is unavailable. The operative steps therefore live
14	> in this SKILL.md (the floor); the file-backed `[strings.skills].setup` body mirrors them for the
15	> spt-present repair path. See `docs/adr/0001-distribution-splits-by-volatility.md`.
16
17	Covers the mid-session install + activation gap (ADR-0001): a user who installs the plugin mid-session
18	has not had a SessionStart bootstrap fire, so `/sptc:setup` runs the same invisible-installer
19	bootstrap to fetch + verify spt-core on demand **and then activates the claude-spt adapter**. A
20	present binary is not enough: an unregistered/`deregistered` adapter has no profiles/strings/hints/
21	`[digest]`, so the `/sptc:*` surface is inert until activation.
22
23	**Do this:**
24
25	1. **Binary.** If spt-core is absent (`command -v spt && spt --version` reports nothing), run the
26	   published install-on-demand bootstrap (spt-releases `harness-contract/install-on-demand.md`):
27	   - **POSIX:** `curl -fsSL https://sabermage.github.io/spt-releases/install.sh | sh`
28	   - **Windows (PowerShell):** `irm https://sabermage.github.io/spt-releases/install.ps1 | iex`
29
30	   `PATH` is not reloaded in this shell after a fresh install — verify with the absolute path:
31	   `"$HOME/.local/bin/spt" --version`. After this, `spt update` handles signed self-updates.
32
33	2. **Activate the adapter.** Run `spt adapter list` and find `claude-spt`:
34	   - Listed and **not** `deregistered` → already active; report it and skip to step 3.
35	   - Missing or `deregistered` → activate it:
36	     - **Local dev / dogfooding a repo checkout** (an `adapter/claude-spt.toml` is present near cwd):
37	       `spt adapter add ./adapter/claude-spt.toml` (the file-form accepts any path + filename).
38	     - **End-user (plugin only):** the `.spt` carries native binaries, so it ships **per-OS** —
39	       pick the host's. Detect: `os=$(uname -s)` → MINGW*/MSYS*/CYGWIN*=windows, Linux=linux,
40	       Darwin=macos; `arch=$(uname -m)` → x86_64/amd64=x86_64, arm64/aarch64=aarch64. Then
41	       `spt adapter add --release SaberMage/spt-claude-code --asset adapter-$os-$arch.spt` — fetches
42	       the per-OS `adapter-<os>-<arch>.spt` asset (tar root = `manifest.toml` + `strings/` + native
43	       tool binaries), extracts to the durable home, registers. `--tag <ver>` pins a version. v1
44	       ships windows + linux. Recommended (from the monorepo, no dedicated repo); needs the spt
45	       release carrying `--release`.
46
47	3. **Verify activation.** Re-run `spt adapter list` — `claude-spt` must read **active**
48	   (no `deregistered`). The `[digest]`/`[session]` templates invoke `claude-spt-digest` +
49	   `claude-spt-psyche` by **bare name**, and spt-core resolves them **from the adapter install dir**
50	   (the `from …/adapters/_github/<safe>/` path in `spt adapter list`), where `--release` activation
51	   already extracted them beside the manifest. **No PATH copy needed** (REQ-INSTALL-11, spt v0.8.0
52	   Feature B; verified live on v0.8.1 — digest + daemon-hosted Psyche both resolve from the install
53	   dir). If either ever fails to start, confirm both `.exe`s are present in that install dir — their
54	   absence is a packaging defect, not a PATH problem. *(Legacy F-006 interim PATH-copy: retired.)*
55
56	4. **ccs wiring (optional — SCOPE setup #7).** Detect `~/.ccs`:
57	   - Present → ccs is installed. The shipped `claude-spt:ccs` profile leaf-replaces the session
58	     command with `ccs` (drop-in for `claude`) → run live/ready agents on ccs backends
59	     (glm/kimi/custom) via `--adapter claude-spt:ccs` (e.g. `/sptc:live`, `/sptc:ready`,
60	     `spt endpoint run --adapter claude-spt:ccs`). Check `command -v ccs`; if `~/.ccs` exists but `ccs`
61	     isn't on PATH, point the user at their ccs bin dir. No action needed if unwanted (base
62	     `claude-spt` is unaffected).
63	   - Absent → ccs is an optional CLI router for driving alternate model backends (glm/kimi/custom) in
64	     place of `claude`. To enable: install ccs (its docs), then re-run `/sptc:setup`. Skip if unwanted.
65
66	5. **Subnet onboarding (optional — SCOPE setup #3/#4).** A subnet is the private group of paired
67	   machines that makes `/sptc:send`, `/sptc:ready`, and live agents work cross-machine (local use
68	   needs none). Check: `spt subnet status`.
69	   - In a subnet → to invite a machine: `spt subnet show-code` (6-digit code + URI + QR); on the
70	     joiner: `spt subnet join <name> --code <code>`.
71	   - Not in one → offer create (`spt subnet create <name>` — seed-holder; prints code/URI/QR) or join
72	     (`spt subnet join <name> --code <code>`). Skip if single-machine.
73	   - Full verb guidance → **/sptc:subnet**. **Elevation:** create/join/show-code are
74	     OS-elevation-gated — Windows: elevated (UAC) shell; Linux desktop: pkexec/polkit or sudo
75	     terminal; Linux TTY: inline sudo; headless: print the command for the user to run elevated.
76
77	Idempotent and safe to re-run — the same bootstrap + activation the SessionStart hook performs.
78

---
name: setup
description: |
  Install or repair spt-core AND activate the claude-spt adapter for this Claude Code session
  (mid-session installer + post-install activation).
allowed-tools: [Bash]
---

# /sptc:setup

> **Self-contained by necessity.** Unlike other `/sptc:*` skills, `setup` cannot rely on
> UPS-injection of its body: it runs precisely when spt-core may be **absent**, so
> `spt adapter get-string` (the injection source) is unavailable. The operative steps therefore live
> in this SKILL.md (the floor); the file-backed `[strings.skills].setup` body mirrors them for the
> spt-present repair path. See `docs/adr/0001-distribution-splits-by-volatility.md`.

Covers the mid-session install + activation gap (ADR-0001): a user who installs the plugin mid-session
has not had a SessionStart bootstrap fire, so `/sptc:setup` runs the same invisible-installer
bootstrap to fetch + verify spt-core on demand **and then activates the claude-spt adapter**. A
present binary is not enough: an unregistered/`deregistered` adapter has no profiles/strings/hints/
`[digest]`, so the `/sptc:*` surface is inert until activation.

**Do this:**

1. **Binary.** If spt-core is absent (`command -v spt && spt --version` reports nothing), run the
   published install-on-demand bootstrap (spt-releases `harness-contract/install-on-demand.md`):
   - **POSIX:** `curl -fsSL https://sabermage.github.io/spt-releases/install.sh | sh`
   - **Windows (PowerShell):** `irm https://sabermage.github.io/spt-releases/install.ps1 | iex`

   `PATH` is not reloaded in this shell after a fresh install — verify with the absolute path:
   `"$HOME/.local/bin/spt" --version`. After this, `spt update` handles signed self-updates.

2. **Activate the adapter.** Run `spt adapter list` and find `claude-spt`:
   - Listed and **not** `deregistered` → already active; report it and skip to step 3.
   - Missing or `deregistered` → activate it:
     - **Local dev / dogfooding a repo checkout** (an `adapter/claude-spt.toml` is present near cwd):
       `spt adapter add ./adapter/claude-spt.toml` (the file-form accepts any path + filename).
     - **End-user (plugin only):** the `.spt` carries native binaries, so it ships **per-OS** —
       pick the host's. Detect: `os=$(uname -s)` → MINGW*/MSYS*/CYGWIN*=windows, Linux=linux,
       Darwin=macos; `arch=$(uname -m)` → x86_64/amd64=x86_64, arm64/aarch64=aarch64. Then
       `spt adapter add --release SaberMage/spt-claude-code --asset adapter-$os-$arch.spt` — fetches
       the per-OS `adapter-<os>-<arch>.spt` asset (tar root = `manifest.toml` + `strings/` + native
       tool binaries), extracts to the durable home, registers. `--tag <ver>` pins a version. v1
       ships windows + linux. Recommended (from the monorepo, no dedicated repo); needs the spt
       release carrying `--release`.

3. **Verify activation.** Re-run `spt adapter list` — `claude-spt` must read **active**
   (no `deregistered`). The `[digest]`/`[session]` templates invoke `claude-spt-digest` +
   `claude-spt-psyche` by **bare name**, and spt-core resolves them **from the adapter install dir**
   (the `from …/adapters/_github/<safe>/` path in `spt adapter list`), where `--release` activation
   already extracted them beside the manifest. **No PATH copy needed** (REQ-INSTALL-11, spt v0.8.0
   Feature B; verified live on v0.8.1 — digest + daemon-hosted Psyche both resolve from the install
   dir). If either ever fails to start, confirm both `.exe`s are present in that install dir — their
   absence is a packaging defect, not a PATH problem. *(Legacy F-006 interim PATH-copy: retired.)*

4. **ccs wiring (optional — SCOPE setup #7).** Detect `~/.ccs`:
   - Present → ccs is installed. The shipped `claude-spt:ccs` profile leaf-replaces the session
     command with `ccs` (drop-in for `claude`) → run live/ready agents on ccs backends
     (glm/kimi/custom) via `--adapter claude-spt:ccs` (e.g. `/sptc:live`, `/sptc:ready`,
     `spt endpoint run --adapter claude-spt:ccs`). Check `command -v ccs`; if `~/.ccs` exists but `ccs`
     isn't on PATH, point the user at their ccs bin dir. No action needed if unwanted (base
     `claude-spt` is unaffected).
   - Absent → ccs is an optional CLI router for driving alternate model backends (glm/kimi/custom) in
     place of `claude`. To enable: install ccs (its docs), then re-run `/sptc:setup`. Skip if unwanted.

5. **Subnet onboarding (optional — SCOPE setup #3/#4).** A subnet is the private group of paired
   machines that makes `/sptc:send`, `/sptc:ready`, and live agents work cross-machine (local use
   needs none). Check: `spt subnet status`.
   - In a subnet → to invite a machine: `spt subnet show-code` (6-digit code + URI + QR); on the
     joiner: `spt subnet join <name> --code <code>`.
   - Not in one → offer create (`spt subnet create <name>` — seed-holder; prints code/URI/QR) or join
     (`spt subnet join <name> --code <code>`). Skip if single-machine.
   - Full verb guidance → **/sptc:subnet**. **Elevation:** create/join/show-code are
     OS-elevation-gated — Windows: elevated (UAC) shell; Linux desktop: pkexec/polkit or sudo
     terminal; Linux TTY: inline sudo; headless: print the command for the user to run elevated.

Idempotent and safe to re-run — the same bootstrap + activation the SessionStart hook performs.


1	---
2	name: version
3	description: |
4	  Report the spt-core-tracked adapter manifest/binary version.
5	allowed-tools: [Bash]
6	---
7
8	# /sptc:version
9
10	> **Skeleton — thin by design.** Operative instructions for this skill are delivered by the
11	> `sptc` adapter at invocation time (UserPromptSubmit injection from the adapter `[strings]`;
12	> see `docs/adr/0001-distribution-splits-by-volatility.md`). This SKILL.md stays a stub.
13	>
14	> **Operative.** The UPS hook detects `/sptc:version` and injects the body from
15	> `adapter/strings/skills/version.md` (UPS-fires-on-slash confirmed, ADR-0002; file-backed `[strings]`
16	> shipped, F-003). If injection ever no-ops (spt absent / adapter unregistered), this stub is the floor.
17
18	Reports the version-of-truth (adapter manifest/binary tracked by spt-core), not the marketplace skeleton version.
19

---
name: version
description: |
  Report the spt-core-tracked adapter manifest/binary version.
allowed-tools: [Bash]
---

# /sptc:version

> **Skeleton — thin by design.** Operative instructions for this skill are delivered by the
> `sptc` adapter at invocation time (UserPromptSubmit injection from the adapter `[strings]`;
> see `docs/adr/0001-distribution-splits-by-volatility.md`). This SKILL.md stays a stub.
>
> **Operative.** The UPS hook detects `/sptc:version` and injects the body from
> `adapter/strings/skills/version.md` (UPS-fires-on-slash confirmed, ADR-0002; file-backed `[strings]`
> shipped, F-003). If injection ever no-ops (spt absent / adapter unregistered), this stub is the floor.

Reports the version-of-truth (adapter manifest/binary tracked by spt-core), not the marketplace skeleton version.


1	# /sptc:version — operative instructions
2
3	> Delivered file-backed via the `claude-spt` adapter `[strings]`
4	> (`[strings.skills].version = { file = "skills/version.md" }`), resolved at injection time. The
5	> cplugs SKILL.md stays a thin skeleton (ADR-0001).
6
7	**Goal:** report the **version-of-truth** — the spt-core-tracked binary + adapter-manifest version,
8	NOT the marketplace skeleton's `plugin.json` version (ADR-0001: the thin skeleton sits static across
9	many binary/manifest updates, so its version is not authoritative).
10
11	**Do this:**
12
13	1. If `spt` is not on `PATH`, run `/sptc:setup` first.
14	2. Report the spt-core binary version: `spt --version`.
15	3. Report the registered adapter (the conducted layer's version-of-truth): `spt adapter list` — find
16	   the `claude-spt` entry and its active profile(s). This is what actually drives the session.
17	4. State plainly that the cplugs plugin version (`plugin.json`) is intentionally NOT the
18	   version-of-truth; the binary + adapter manifest above are.
19

# /sptc:version — operative instructions

> Delivered file-backed via the `claude-spt` adapter `[strings]`
> (`[strings.skills].version = { file = "skills/version.md" }`), resolved at injection time. The
> cplugs SKILL.md stays a thin skeleton (ADR-0001).

**Goal:** report the **version-of-truth** — the spt-core-tracked binary + adapter-manifest version,
NOT the marketplace skeleton's `plugin.json` version (ADR-0001: the thin skeleton sits static across
many binary/manifest updates, so its version is not authoritative).

**Do this:**

1. If `spt` is not on `PATH`, run `/sptc:setup` first.
2. Report the spt-core binary version: `spt --version`.
3. Report the registered adapter (the conducted layer's version-of-truth): `spt adapter list` — find
   the `claude-spt` entry and its active profile(s). This is what actually drives the session.
4. State plainly that the cplugs plugin version (`plugin.json`) is intentionally NOT the
   version-of-truth; the binary + adapter manifest above are.


1	# /sptc:subnet — operative instructions
2
3	> Delivered file-backed via the `claude-spt` adapter `[strings]`
4	> (`[strings.skills].subnet = { file = "skills/subnet.md" }`), resolved at injection time. The
5	> cplugs SKILL.md stays a thin skeleton (ADR-0001).
6
7	**Goal:** manage this machine's **subnet** membership — the private group of paired machines whose
8	agents can reach each other across every member node. A subnet is what makes `/sptc:send`,
9	`/sptc:ready`, and live agents work *cross-machine* (not just locally). Covers the three primary
10	user intents — **create** a new subnet, **show-code** to invite another machine, **join** an
11	existing one — plus the **status** view.
12
13	**Do this:**
14
15	1. If `spt` is not on `PATH`, run `/sptc:setup` first (a subnet needs the running daemon).
16	2. The canonical, always-current verb list is `spt subnet --help` (there is no `spt how-to subnet`
17	   topic — the `--help` output is the source of truth). Match the user's intent to a verb:
18	   - **See where I stand:** `spt subnet` (bare) or `spt subnet status` — name, paired nodes,
19	     endpoints. Start here when unsure.
20	   - **Start a new subnet** (this machine becomes the first node): `spt subnet create` — mints a
21	     fresh subnet and prints its joining material (a 6-digit pairing code + URI + QR).
22	   - **Invite another machine to mine:** `spt subnet show-code` — re-displays the current subnet's
23	     pairing code (+ URI + QR) to hand to the machine that will join.
24	   - **Pair THIS machine into an existing subnet:** `spt subnet join` — guided; needs the pairing
25	     code from the subnet's existing member (their `create`/`show-code` output).
26	3. **Pairing flow (two machines):** on machine A run `spt subnet create` (or `show-code` if it
27	   already has one) → read off the 6-digit code → on machine B run `spt subnet join` and supply
28	   that code. Confirm with `spt subnet status` on both (each should list the other as a paired node).
29	4. **Lifecycle verbs** (mention only if asked): `leave` (drop this node's membership),
30	   `detach`/`attach` (stop/resume serving a held subnet without leaving), `revoke`/`prune`
31	   (fleet-wide node removal + seed rotation), `notify` (subnet-wide user notification).
32	5. Confirm to the user what changed (subnet name, the code to share, or the newly paired node).
33	   Pairing codes are sensitive joining material — share them only with machines that should join.
34	<!-- [doc->REQ-SKILL-SUBNET] -->
35

# /sptc:subnet — operative instructions

> Delivered file-backed via the `claude-spt` adapter `[strings]`
> (`[strings.skills].subnet = { file = "skills/subnet.md" }`), resolved at injection time. The
> cplugs SKILL.md stays a thin skeleton (ADR-0001).

**Goal:** manage this machine's **subnet** membership — the private group of paired machines whose
agents can reach each other across every member node. A subnet is what makes `/sptc:send`,
`/sptc:ready`, and live agents work *cross-machine* (not just locally). Covers the three primary
user intents — **create** a new subnet, **show-code** to invite another machine, **join** an
existing one — plus the **status** view.

**Do this:**

1. If `spt` is not on `PATH`, run `/sptc:setup` first (a subnet needs the running daemon).
2. The canonical, always-current verb list is `spt subnet --help` (there is no `spt how-to subnet`
   topic — the `--help` output is the source of truth). Match the user's intent to a verb:
   - **See where I stand:** `spt subnet` (bare) or `spt subnet status` — name, paired nodes,
     endpoints. Start here when unsure.
   - **Start a new subnet** (this machine becomes the first node): `spt subnet create` — mints a
     fresh subnet and prints its joining material (a 6-digit pairing code + URI + QR).
   - **Invite another machine to mine:** `spt subnet show-code` — re-displays the current subnet's
     pairing code (+ URI + QR) to hand to the machine that will join.
   - **Pair THIS machine into an existing subnet:** `spt subnet join` — guided; needs the pairing
     code from the subnet's existing member (their `create`/`show-code` output).
3. **Pairing flow (two machines):** on machine A run `spt subnet create` (or `show-code` if it
   already has one) → read off the 6-digit code → on machine B run `spt subnet join` and supply
   that code. Confirm with `spt subnet status` on both (each should list the other as a paired node).
4. **Lifecycle verbs** (mention only if asked): `leave` (drop this node's membership),
   `detach`/`attach` (stop/resume serving a held subnet without leaving), `revoke`/`prune`
   (fleet-wide node removal + seed rotation), `notify` (subnet-wide user notification).
5. Confirm to the user what changed (subnet name, the code to share, or the newly paired node).
   Pairing codes are sensitive joining material — share them only with machines that should join.
<!-- [doc->REQ-SKILL-SUBNET] -->


1	---
2	name: subnet
3	description: |
4	  Manage subnet membership — create, show a pairing code, or join, so agents reach each other across machines.
5	argument-hint: "[status|create|show-code|join]"
6	allowed-tools: [Bash]
7	---
8
9	# /sptc:subnet
10
11	> **Skeleton — thin by design.** Operative instructions for this skill are delivered by the
12	> `sptc` adapter at invocation time (UserPromptSubmit injection from the adapter `[strings]`;
13	> see `docs/adr/0001-distribution-splits-by-volatility.md`). This SKILL.md stays a stub.
14	>
15	> **Operative.** The UPS hook detects `/sptc:subnet` and injects the body from
16	> `adapter/strings/skills/subnet.md` (UPS-fires-on-slash confirmed, ADR-0002; file-backed
17	> `[strings]` shipped, F-003). If injection ever no-ops (spt absent / adapter unregistered), this
18	> stub is the floor.
19
20	Manages this machine's **subnet** — the private group of paired machines whose agents reach each
21	other across nodes. Wraps `spt subnet {status,create,show-code,join,…}`: create a subnet, show a
22	pairing code to invite a machine, or join an existing one. Cross-machine `/sptc:send` + live agents
23	depend on it.
24

---
name: subnet
description: |
  Manage subnet membership — create, show a pairing code, or join, so agents reach each other across machines.
argument-hint: "[status|create|show-code|join]"
allowed-tools: [Bash]
---

# /sptc:subnet

> **Skeleton — thin by design.** Operative instructions for this skill are delivered by the
> `sptc` adapter at invocation time (UserPromptSubmit injection from the adapter `[strings]`;
> see `docs/adr/0001-distribution-splits-by-volatility.md`). This SKILL.md stays a stub.
>
> **Operative.** The UPS hook detects `/sptc:subnet` and injects the body from
> `adapter/strings/skills/subnet.md` (UPS-fires-on-slash confirmed, ADR-0002; file-backed
> `[strings]` shipped, F-003). If injection ever no-ops (spt absent / adapter unregistered), this
> stub is the floor.

Manages this machine's **subnet** — the private group of paired machines whose agents reach each
other across nodes. Wraps `spt subnet {status,create,show-code,join,…}`: create a subnet, show a
pairing code to invite a machine, or join an existing one. Cross-machine `/sptc:send` + live agents
depend on it.


Full picture in hand. Pulling legacy `description` blocks to enrich the "Use when" triggers (current sptc descriptions lack them), then writing the spec doc.


Bash

for s in ready send signoff commune force-stop list-agents live; do echo "=== legacy $s ==="; awk '/^description:/,/^[a-z-]+:/' "C:/Users/decid/.claude/plugins/cache/cplugs/spt/1.11.25/skills/$s/SKILL.md" 2>/dev/null | sed '/^argument-hint:/d;/^allowed-tools:/d' | head -20; done

Extract legacy frontmatter descriptions for basis


=== legacy ready ===
description: |
=== legacy send ===
description: |
=== legacy signoff ===
description: |
=== legacy commune ===
description: |
=== legacy force-stop ===
description: |
=== legacy list-agents ===
description: |
=== legacy live ===
description: |


for s in ready send signoff commune force-stop list-agents; do echo "=== legacy $s (frontmatter) ==="; sed -n '1,30p' "C:/Users/decid/.claude/plugins/cache/cplugs/spt/1.11.25/skills/$s/SKILL.md" 2>/dev/null | sed -n '/^description:/,/^---/p'; done

Read legacy description frontmatter blocks


=== legacy ready (frontmatter) ===
description: |
  Enable inter-agent messaging for the current session.
  Use when the user says "listen as", "ready as", or wants to receive inter-agent messages.
argument-hint: "<id> [--reboot] [--block] [--once]"
allowed-tools: [Bash, Read, Monitor]
---
=== legacy send (frontmatter) ===
description: |
  Send a message to another SPT agent. Use when the user says "send to",
  "message", "tell <agent>", or wants to communicate with another agent.
argument-hint: "<target> [--block]"
allowed-tools: [Bash, Read]
---
=== legacy signoff (frontmatter) ===
description: |
  Graceful live agent shutdown with final context summary. Use when the user
  says "sign off", "graceful stop", or wants to cleanly end a live session.
argument-hint: ""
allowed-tools: [Bash, Write]
---
=== legacy commune (frontmatter) ===
description: |
  Send a communal update to your Psyche. Use when the user says "commune",
  "update psyche", or wants to sync context with their Psyche companion.
argument-hint: ""
allowed-tools: [Bash, Read, Write]
---
=== legacy force-stop (frontmatter) ===
description: |
  Force-stop an SPT agent -- ready agent or live agent (with its
  Psyche). Use when the user says "stop listening", "stop owl", "kill live
  agent", "force stop", "tear down perch", or "immediately terminate".
  Session-aware: a live session (or a target with `live:true` in info.json)
  routes through `$LIVE stop` (3-step kill including Psyche teardown); a
  ready agent routes through `$OWL stop`.
argument-hint: "[<id>] | --all"
allowed-tools: [Bash]
---
=== legacy list-agents (frontmatter) ===
description: |
  Unified listing for SPT agents -- ready agents, live agents, and Psyche
  processes. Use when the user says "list agents", "who's live", "who's
  listening", "show psyches", "show active listeners", or wants a roster of
  active perches. Session-aware: defaults to live agents in a live session,
  ready agents otherwise. Pass `--psyches` to list Psyche processes
  instead.
argument-hint: "[--all] [--offline] [--here] [--psyches]"
allowed-tools: [Bash]
---


Now I have legacy "Use when" triggers to adapt (dropping `$LIVE`/`$OWL`/info.json internals). I have everything. Writing the spec doc first — it's the rewrite contract.


Write

# Skill authoring

> How `/sptc:*` skills are written in this repo. Skills live on **two surfaces** (ADR-0001's
> thin-skeleton split). Keep both lean: the plugin file is a stub, the adapter file is the operative
> instructions. Bloat — provenance notes, requirement ids, ADR/finding citations, rationale the
> running agent doesn't need — does not belong in either.

## The two surfaces

| Surface | File | Role | Audience |
|---|---|---|---|
| **Plugin skeleton** | `plugin/sptc/skills/<name>/SKILL.md` | Thin stub shipped on cplugs. Frontmatter `description` is the routing surface; body is a fixed note. | The model deciding *which* skill to load. |
| **Adapter body** | `adapter/strings/skills/<name>.md` | The operative instructions, UPS-injected at invocation from the adapter `[strings]`. | The agent *running* the skill. |

The plugin skeleton carries **no operative steps** — those are injected from the adapter body at call
time. The two never duplicate instructions.

## Plugin SKILL.md template

```md
---
name: <name>
description: |
  <One sentence: what it does.> Use when the user says "<trigger>", "<trigger>", or
  wants to <intent>.
argument-hint: "<args>"        # omit if none
allowed-tools: [Bash]          # the minimum the skill needs (Bash/Read/Write/Monitor)
---

# /sptc:<name>

> **Skeleton — thin by design.** Operative instructions for this skill are delivered by the
> `sptc` adapter at invocation time. Look out for the UserPromptSubmit additionalContext.
>
> **Operative.** If injection ever no-ops (spt absent / adapter unregistered), check
> SPT's installation status using the skill `sptc:setup`. Otherwise, avoid additional steps.

<One line naming what the skill does.>
```

The skeleton note above is **verbatim and identical** across every skill (except `setup` — see
below). Do not re-add ADR/finding/requirement citations to it.

## Adapter body template

```md
# /sptc:<name> — operative instructions

**Goal:** <one line — the outcome the agent is producing>.

**Do this:**

1. <step>
2. <step>
<!-- [doc->REQ-<…>] -->   # keep the traceability tag if this body is doc evidence
```

Rules for the body:

- **No provenance preamble.** Do not open with "Delivered file-backed via the adapter `[strings]`…"
  — the running agent does not need to know its own delivery mechanism.
- **Self-contained.** Inline the operative steps; do **not** redirect to `spt how-to <topic>`. (A
  verb's own `spt <verb> --help` is fine to cite as the live source of truth where the surface is
  large, e.g. `subnet`.)
- **Concise.** Commands, the must-do sequence, the reply/output shape — nothing else. Cut rationale,
  repeated warnings, and history.
- **Keep `<!-- [doc->REQ-*] -->` tags** — they are traceability evidence; place them on/above the
  real evidence.

## `description` rules (from write-a-skill)

The `description` is the only thing the model sees when choosing a skill. Per
`write-a-skill`: third person, **what it does** then **"Use when [triggers]"**, ≤1024 chars, no
time-sensitive info, consistent terms. Route phrases reference **`/sptc:`** (the shipped plugin
name; the `s/sptc/spt/` succession flip renames them later). The legacy `claude_skill_owl`
descriptions are the basis for the trigger phrasing — adapt them, dropping legacy internals
(`$OWL`/`$LIVE`/`info.json`).

## The `setup` exception

`setup` is **self-contained on both surfaces**: it runs precisely when spt-core may be **absent**,
so UPS-injection (which needs `spt adapter get-string`) can no-op. Its plugin SKILL.md therefore
keeps the operative steps as the floor, and the adapter body mirrors them for the spt-present repair
path. Tighten `setup` for concision, but do **not** reduce it to a stub.

## Checklist

- [ ] `description` is third-person, has "Use when …" triggers, routes via `/sptc:`.
- [ ] Plugin SKILL.md uses the verbatim skeleton note + one what-it-does line (except `setup`).
- [ ] Adapter body has no provenance preamble, is self-contained, ≤ ~40 lines (large surfaces aside).
- [ ] `allowed-tools` is the minimum the skill needs.
- [ ] Traceability `[doc->REQ-*]` tags preserved.


File created successfully at: C:\Users\decid\Documents\projects\spt-claude-code\docs\SKILL-AUTHORING.md (file state is current in your context — no need to Read it back)

# Skill authoring

> How `/sptc:*` skills are written in this repo. Skills live on **two surfaces** (ADR-0001's
> thin-skeleton split). Keep both lean: the plugin file is a stub, the adapter file is the operative
> instructions. Bloat — provenance notes, requirement ids, ADR/finding citations, rationale the
> running agent doesn't need — does not belong in either.

## The two surfaces

| Surface | File | Role | Audience |
|---|---|---|---|
| **Plugin skeleton** | `plugin/sptc/skills/<name>/SKILL.md` | Thin stub shipped on cplugs. Frontmatter `description` is the routing surface; body is a fixed note. | The model deciding *which* skill to load. |
| **Adapter body** | `adapter/strings/skills/<name>.md` | The operative instructions, UPS-injected at invocation from the adapter `[strings]`. | The agent *running* the skill. |

The plugin skeleton carries **no operative steps** — those are injected from the adapter body at call
time. The two never duplicate instructions.

## Plugin SKILL.md template

```md
---
name: <name>
description: |
  <One sentence: what it does.> Use when the user says "<trigger>", "<trigger>", or
  wants to <intent>.
argument-hint: "<args>"        # omit if none
allowed-tools: [Bash]          # the minimum the skill needs (Bash/Read/Write/Monitor)
---

# /sptc:<name>

> **Skeleton — thin by design.** Operative instructions for this skill are delivered by the
> `sptc` adapter at invocation time. Look out for the UserPromptSubmit additionalContext.
>
> **Operative.** If injection ever no-ops (spt absent / adapter unregistered), check
> SPT's installation status using the skill `sptc:setup`. Otherwise, avoid additional steps.

<One line naming what the skill does.>
```

The skeleton note above is **verbatim and identical** across every skill (except `setup` — see
below). Do not re-add ADR/finding/requirement citations to it.

## Adapter body template

```md
# /sptc:<name> — operative instructions

**Goal:** <one line — the outcome the agent is producing>.

**Do this:**

1. <step>
2. <step>
<!-- [doc->REQ-<…>] -->   # keep the traceability tag if this body is doc evidence
```

Rules for the body:

- **No provenance preamble.** Do not open with "Delivered file-backed via the adapter `[strings]`…"
  — the running agent does not need to know its own delivery mechanism.
- **Self-contained.** Inline the operative steps; do **not** redirect to `spt how-to <topic>`. (A
  verb's own `spt <verb> --help` is fine to cite as the live source of truth where the surface is
  large, e.g. `subnet`.)
- **Concise.** Commands, the must-do sequence, the reply/output shape — nothing else. Cut rationale,
  repeated warnings, and history.
- **Keep `<!-- [doc->REQ-*] -->` tags** — they are traceability evidence; place them on/above the
  real evidence.

## `description` rules (from write-a-skill)

The `description` is the only thing the model sees when choosing a skill. Per
`write-a-skill`: third person, **what it does** then **"Use when [triggers]"**, ≤1024 chars, no
time-sensitive info, consistent terms. Route phrases reference **`/sptc:`** (the shipped plugin
name; the `s/sptc/spt/` succession flip renames them later). The legacy `claude_skill_owl`
descriptions are the basis for the trigger phrasing — adapt them, dropping legacy internals
(`$OWL`/`$LIVE`/`info.json`).

## The `setup` exception

`setup` is **self-contained on both surfaces**: it runs precisely when spt-core may be **absent**,
so UPS-injection (which needs `spt adapter get-string`) can no-op. Its plugin SKILL.md therefore
keeps the operative steps as the floor, and the adapter body mirrors them for the spt-present repair
path. Tighten `setup` for concision, but do **not** reduce it to a stub.

## Checklist

- [ ] `description` is third-person, has "Use when …" triggers, routes via `/sptc:`.
- [ ] Plugin SKILL.md uses the verbatim skeleton note + one what-it-does line (except `setup`).
- [ ] Adapter body has no provenance preamble, is self-contained, ≤ ~40 lines (large surfaces aside).
- [ ] `allowed-tools` is the minimum the skill needs.
- [ ] Traceability `[doc->REQ-*]` tags preserved.


Spec doc written. Adding the DOCS-STRATEGY reference.


1:# Documentation strategy
13:## The defining constraint: a dual audience
21:## Principles (top techniques, prioritized)
49:## Information architecture — by capability vertical
54:**The `/spt:*` skills · `/spt:setup` · the `cc` launcher · ccs profiles · subnet setup · the
62:## Killer quickstart targets
69:## Agent-consumable docs
83:## Site generator: mdBook + custom theme CSS
91:## CI commitments
97:## Anti-patterns to design against (most-cited failures)


49	## Information architecture — by capability vertical
50
51	Organize by capability, each vertical carrying the same four Diátaxis modes internally (the
52	Cloudflare pattern):
53
54	**The `/spt:*` skills · `/spt:setup` · the `cc` launcher · ccs profiles · subnet setup · the
55	`[digest]` extractor.**
56
57	Global sequence (Rust Book logic): early runnable project → dependency-ordered concepts →
58	capstone last. Per-vertical internal template (Django labels × Cloudflare ordering):
59	`Overview (why + diagram) · Quickstart/Tutorial · How-to guides · Reference (generated) ·
60	llms.txt`.

## Information architecture — by capability vertical

Organize by capability, each vertical carrying the same four Diátaxis modes internally (the
Cloudflare pattern):

**The `/spt:*` skills · `/spt:setup` · the `cc` launcher · ccs profiles · subnet setup · the
`[digest]` extractor.**

Global sequence (Rust Book logic): early runnable project → dependency-ordered concepts →
capstone last. Per-vertical internal template (Django labels × Cloudflare ordering):
`Overview (why + diagram) · Quickstart/Tutorial · How-to guides · Reference (generated) ·
llms.txt`.


Edit

**The `/spt:*` skills · `/spt:setup` · the `cc` launcher · ccs profiles · subnet setup · the
`[digest]` extractor.**

**The `/spt:*` skills · `/spt:setup` · the `cc` launcher · ccs profiles · subnet setup · the
`[digest]` extractor.**

> **Authoring the `/sptc:*` skills themselves** — the two-surface shape (thin plugin skeleton +
> UPS-injected adapter body), templates, and the lean-by-default rules — lives in
> [`SKILL-AUTHORING.md`](SKILL-AUTHORING.md).


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

**The `/spt:*` skills · `/spt:setup` · the `cc` launcher · ccs profiles · subnet setup · the
`[digest]` extractor.**

> **Authoring the `/sptc:*` skills themselves** — the two-surface shape (thin plugin skeleton +
> UPS-injected adapter body), templates, and the lean-by-default rules — lives in
> [`SKILL-AUTHORING.md`](SKILL-AUTHORING.md).

# Documentation strategy

> A **designed-in commitment**, not an afterthought — grounded in research on
> critically-acclaimed developer docs (Stripe, Twilio, the Rust Book, FastAPI, Cloudflare,
> Anthropic, Diátaxis, `llms.txt`, the Google developer style guide). Governs the **shipped
> product docs** (authored as code lands). The planning docs (CONTEXT / ADRs / design docs) are
> internal and separate.
>
> **Where the docs live (the reframe):** docs live in **this same repo** under `docs-site/`.
> CI builds them with **mdBook** and **publishes to GitHub Pages from this repo**, gated against
> drift. (No separate releases/publish repo — source of truth and published site are one repo.)

## The defining constraint: a dual audience

These docs serve **two readers at once** — human developers *and* the **AI dev-agents that
build on or integrate with this project**. This is the design constraint: every artifact is
authored **once in clean markdown** and served in **two depths** (human-rendered + agent-export).
The agent layer is **first-class, not optional** — make it so good that a dev-agent integrates
correctly on the first try.

## Principles (top techniques, prioritized)

1. **Sub-10-minute killer quickstart** — runnable, deterministic, whole-working-thing-first, no
   placeholders. Time-to-first-hello-world is the single most-cited conversion lever.
2. **Diátaxis four-mode separation** — tutorial / how-to / reference / explanation, never mixed
   (mixing is the most-cited cause of confusing docs).
3. **Deterministic, real, copy-pasteable examples everywhere** — no `<YOUR_VALUE_HERE>`
   placeholders; real values that run. Serves humans *and* agents.
4. **Dual-depth agent exports** — `llms.txt` (slim curated index) + `llms-full.txt` (full
   concatenated export), auto-generated in CI, plus markdown content negotiation (a `.md` suffix
   alongside each `.html`, or `Accept: text/markdown`) which cuts agent token use ~90% vs HTML.
5. **One canonical way to do X** — explicitly mark deprecated / alternate paths. Non-determinism
   is fatal for agents.
6. **Complete reference, auto-generated, all error variants** — generate API reference from the
   code for your public surface, plus any machine-readable contract/schema. Generic placeholders
   in reference are a failure mode.
7. **Consistent conversational voice** — adopt the Google developer style guide: second person
   ("you"), active voice, knowledgeable-friend tone.
8. **Explain *why*, not just *what*** — conceptual docs + diagrams for the project's core model
   and state machines.
9. **Stable, never-renamed anchors / URLs** — agents cache links.
10. **Docs-as-product, gated in CI** — generation (API reference, `llms.txt`, schema, CLI help)
    is part of the build so docs can never drift from code. Drift is the #1 most-cited docs
    failure; this kills it structurally.
    <!-- [doc->REQ-DOCS-DRIFT] The drift gate (ci/docs/check-docs.sh) regenerates llms.txt
         deterministically and fails the build on any diff vs the committed file; the book must
         also build. This is the structural anti-drift commitment, enforced in run-gates. -->

## Information architecture — by capability vertical

Organize by capability, each vertical carrying the same four Diátaxis modes internally (the
Cloudflare pattern):

**The `/spt:*` skills · `/spt:setup` · the `cc` launcher · ccs profiles · subnet setup · the
`[digest]` extractor.**

Global sequence (Rust Book logic): early runnable project → dependency-ordered concepts →
capstone last. Per-vertical internal template (Django labels × Cloudflare ordering):
`Overview (why + diagram) · Quickstart/Tutorial · How-to guides · Reference (generated) ·
llms.txt`.

## Killer quickstart targets

Define one per audience — e.g. a **human dev** quickstart (the core primitive end-to-end in one
command + minimal config, < 10 min, whole-thing-first then decomposed) and, if you have
integrators, a **dev-agent integrator** quickstart (the minimal "build against this" hello-world
for `<your integration surface>`). Zero placeholders; every value runs.

## Agent-consumable docs

- **`llms.txt` / `llms-full.txt`** — auto-emitted in CI; the slim index answers quick questions,
  the full export feeds deep ingestion. Two-level (Cloudflare pattern): a curated root index that
  fans out to per-vertical `llms.txt`; `llms-full.txt` is CI-concatenated page bodies
  (generation-only, never hand-authored).
- **Markdown content negotiation** + deterministic include/exclude tags so agent exports carry
  the canonical path and drop human-only narrative.
- **Machine-readable contract/schema** (e.g. JSON Schema) at a stable, discoverable path, if your
  project has one — the schema *is* documentation.
- **CLI help as first-class agent docs**, if you ship a CLI — `<cmd> --help` complete, exampled,
  and ideally machine-readable (a `--json` / structured help mode). The CLI surface is a
  documentation surface.

## Site generator: mdBook + custom theme CSS

**mdBook** is the generator. The **shared theme** lives in `docs-site/theme/` (a
Starlight-inspired skin reused across consumer projects — re-point the accent to rebrand);
**Astro Starlight is the styling north star** (copy its look / feel in the theme CSS, not its
toolchain). Raw `.md` is published alongside each rendered page (`/x.html` ↔ `/x.md`) for the
agent-export convention; `llms.txt` / `llms-full.txt` / any schema are static assets at site root.

## CI commitments

Generated reference, the schema, `llms.txt` / `llms-full.txt`, and CLI help exports are
**generated and checked in CI** — a doc-drift gate. The mdBook build + GitHub Pages publish run
in the same pipeline. Doc quality lives on the same footing as tests.

## Anti-patterns to design against (most-cited failures)

Doc / code drift (#1 — solved by CI gating); *what* without *why*; too much setup before first
success; generic placeholders in reference; mixed Diátaxis modes; poor search / navigation;
multiple non-canonical ways to do X (fatal for agents).

+> **Authoring the `/sptc:*` skills themselves** — the two-surface shape (thin plugin skeleton +

+> UPS-injected adapter body), templates, and the lean-by-default rules — lives in


Spec + DOCS-STRATEGY done. Now the rewrites. Starting with the 8 thin plugin skeletons (standard note + enriched `/sptc:` descriptions with "Use when" triggers).


Write

---
name: ready
description: |
  Make this Claude Code session reachable for inter-agent messages (register a perch and
  listen). Use when the user says "listen as", "ready as", or wants to receive messages from
  other agents.
argument-hint: "<id>"
allowed-tools: [Bash, Read, Monitor]
---

# /sptc:ready

> **Skeleton — thin by design.** Operative instructions for this skill are delivered by the
> `sptc` adapter at invocation time. Look out for the UserPromptSubmit additionalContext.
>
> **Operative.** If injection ever no-ops (spt absent / adapter unregistered), check
> SPT's installation status using the skill `sptc:setup`. Otherwise, avoid additional steps.

Registers a perch and listens, so other agents can reach this session.


<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.


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

# /sptc:send

> **Skeleton — thin by design.** Operative instructions for this skill are delivered by the
> `sptc` adapter at invocation time. Look out for the UserPromptSubmit additionalContext.
>
> **Operative.** If injection ever no-ops (spt absent / adapter unregistered), check
> SPT's installation status using the skill `sptc:setup`. Otherwise, avoid additional steps.

Delivers a message to another agent; supports reply-to.


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 wants to reach another agent.
argument-hint: "<target> [--reply-to <sender>]"
allowed-tools: [Bash]
---

# /sptc:send

> **Skeleton — thin by design.** Operative instructions for this skill are delivered by the
> `sptc` adapter at invocation time. Look out for the UserPromptSubmit additionalContext.
>
> **Operative.** If injection ever no-ops (spt absent / adapter unregistered), check
> SPT's installation status using the skill `sptc:setup`. Otherwise, avoid additional steps.

Delivers a message to another agent; supports reply-to.

+  Send a message to another SPT agent. Use when the user says "send to", "message",

+  "tell <agent>", or wants to reach another agent.

-> `sptc` adapter at invocation time (UserPromptSubmit injection from the adapter `[strings]`;

-> see `docs/adr/0001-distribution-splits-by-volatility.md`). This SKILL.md stays a stub.

+> `sptc` adapter at invocation time. Look out for the UserPromptSubmit additionalContext.

-> **Operative.** The UPS hook detects `/sptc:send` and injects the body from

-> `adapter/strings/skills/send.md` (UPS-fires-on-slash confirmed, ADR-0002; file-backed `[strings]`

-> shipped, F-003). If injection ever no-ops (spt absent / adapter unregistered), this stub is the floor.

+> **Operative.** If injection ever no-ops (spt absent / adapter unregistered), check

+> SPT's installation status using the skill `sptc:setup`. Otherwise, avoid additional steps.

-Delivers a message to another agent; supports reply-to and ring/ask.

+Delivers a message to another agent; supports reply-to.

---
name: send
description: |
  Send a message to another SPT agent.
argument-hint: "<target> [--reply-to <sender>]"
allowed-tools: [Bash]
---

# /sptc:send

> **Skeleton — thin by design.** Operative instructions for this skill are delivered by the
> `sptc` adapter at invocation time (UserPromptSubmit injection from the adapter `[strings]`;
> see `docs/adr/0001-distribution-splits-by-volatility.md`). This SKILL.md stays a stub.
>
> **Operative.** The UPS hook detects `/sptc:send` and injects the body from
> `adapter/strings/skills/send.md` (UPS-fires-on-slash confirmed, ADR-0002; file-backed `[strings]`
> shipped, F-003). If injection ever no-ops (spt absent / adapter unregistered), this stub is the floor.

Delivers a message to another agent; supports reply-to and ring/ask.


Need to Read before Write. Batch-reading the remaining plugin skeletons + adapter bodies I'll rewrite.


1	---
2	name: ready
3	description: |
4	  Enable inter-agent messaging for the current session.
5	argument-hint: "[<id>]"
6	allowed-tools: [Bash]
7	---
8
9	# /sptc:ready
10
11	> **Skeleton — thin by design.** Operative instructions for this skill are delivered by the
12	> `sptc` adapter at invocation time (UserPromptSubmit injection from the adapter `[strings]`;
13	> see `docs/adr/0001-distribution-splits-by-volatility.md`). This SKILL.md stays a stub.
14	>
15	> **Operative.** The UPS hook detects `/sptc:ready` and injects the body from
16	> `adapter/strings/skills/ready.md` (UPS-fires-on-slash confirmed, ADR-0002; file-backed `[strings]`
17	> shipped, F-003). If injection ever no-ops (spt absent / adapter unregistered), this stub is the floor.
18
19	Registers a perch so this session can receive inter-agent messages.
20

---
name: ready
description: |
  Enable inter-agent messaging for the current session.
argument-hint: "[<id>]"
allowed-tools: [Bash]
---

# /sptc:ready

> **Skeleton — thin by design.** Operative instructions for this skill are delivered by the
> `sptc` adapter at invocation time (UserPromptSubmit injection from the adapter `[strings]`;
> see `docs/adr/0001-distribution-splits-by-volatility.md`). This SKILL.md stays a stub.
>
> **Operative.** The UPS hook detects `/sptc:ready` and injects the body from
> `adapter/strings/skills/ready.md` (UPS-fires-on-slash confirmed, ADR-0002; file-backed `[strings]`
> shipped, F-003). If injection ever no-ops (spt absent / adapter unregistered), this stub is the floor.

Registers a perch so this session can receive inter-agent messages.


1	---
2	name: signoff
3	description: |
4	  Graceful live-agent shutdown with a final context summary.
5	allowed-tools: [Bash]
6	---
7
8	# /sptc:signoff
9
10	> **Skeleton — thin by design.** Operative instructions for this skill are delivered by the
11	> `sptc` adapter at invocation time (UserPromptSubmit injection from the adapter `[strings]`;
12	> see `docs/adr/0001-distribution-splits-by-volatility.md`). This SKILL.md stays a stub.
13	>
14	> **Operative.** The UPS hook detects `/sptc:signoff` and injects the body from
15	> `adapter/strings/skills/signoff.md` (UPS-fires-on-slash confirmed, ADR-0002; file-backed `[strings]`
16	> shipped, F-003). If injection ever no-ops (spt absent / adapter unregistered), this stub is the floor.
17
18	Cleanly ends a live session, writing a final summary consumed at teardown.
19

---
name: signoff
description: |
  Graceful live-agent shutdown with a final context summary.
allowed-tools: [Bash]
---

# /sptc:signoff

> **Skeleton — thin by design.** Operative instructions for this skill are delivered by the
> `sptc` adapter at invocation time (UserPromptSubmit injection from the adapter `[strings]`;
> see `docs/adr/0001-distribution-splits-by-volatility.md`). This SKILL.md stays a stub.
>
> **Operative.** The UPS hook detects `/sptc:signoff` and injects the body from
> `adapter/strings/skills/signoff.md` (UPS-fires-on-slash confirmed, ADR-0002; file-backed `[strings]`
> shipped, F-003). If injection ever no-ops (spt absent / adapter unregistered), this stub is the floor.

Cleanly ends a live session, writing a final summary consumed at teardown.


1	---
2	name: list-agents
3	description: |
4	  List SPT agents — ready, live, and Psyche processes.
5	allowed-tools: [Bash]
6	---
7
8	# /sptc:list-agents
9
10	> **Skeleton — thin by design.** Operative instructions for this skill are delivered by the
11	> `sptc` adapter at invocation time (UserPromptSubmit injection from the adapter `[strings]`;
12	> see `docs/adr/0001-distribution-splits-by-volatility.md`). This SKILL.md stays a stub.
13	>
14	> **Operative.** The UPS hook detects `/sptc:list-agents` and injects the body from
15	> `adapter/strings/skills/list-agents.md` (UPS-fires-on-slash confirmed, ADR-0002; file-backed
16	> `[strings]` shipped, F-003). If injection ever no-ops (spt absent / adapter unregistered), this
17	> stub is the floor. (Core roster only — the legacy `--psyches` live-layer view is not in core spt.)
18
19	Lists agents/endpoints. Maps to `spt endpoint list`.
20

---
name: list-agents
description: |
  List SPT agents — ready, live, and Psyche processes.
allowed-tools: [Bash]
---

# /sptc:list-agents

> **Skeleton — thin by design.** Operative instructions for this skill are delivered by the
> `sptc` adapter at invocation time (UserPromptSubmit injection from the adapter `[strings]`;
> see `docs/adr/0001-distribution-splits-by-volatility.md`). This SKILL.md stays a stub.
>
> **Operative.** The UPS hook detects `/sptc:list-agents` and injects the body from
> `adapter/strings/skills/list-agents.md` (UPS-fires-on-slash confirmed, ADR-0002; file-backed
> `[strings]` shipped, F-003). If injection ever no-ops (spt absent / adapter unregistered), this
> stub is the floor. (Core roster only — the legacy `--psyches` live-layer view is not in core spt.)

Lists agents/endpoints. Maps to `spt endpoint list`.


1	---
2	name: commune
3	description: |
4	  Send a communal context update to your Psyche.
5	argument-hint: "<<stdin>>"
6	allowed-tools: [Bash]
7	---
8
9	# /sptc:commune
10
11	> **Skeleton — thin by design.** Operative instructions for this skill are delivered by the
12	> `sptc` adapter at invocation time (UserPromptSubmit injection from the adapter `[strings]`;
13	> see `docs/adr/0001-distribution-splits-by-volatility.md`). This SKILL.md stays a stub.
14	>
15	> **Operative.** The UPS hook detects `/sptc:commune` and injects the body from
16	> `adapter/strings/skills/commune.md` (UPS-fires-on-slash confirmed, ADR-0002; file-backed
17	> `[strings]` shipped, F-003). If injection ever no-ops (spt absent / adapter unregistered), this
18	> stub is the floor.
19
20	Pushes a context delta to the Psyche via a file-drop (`<id>-commune.md` into the adapter's
21	`[session].commune_dir`); the daemon ingests it. Live agents only (a Psyche must exist).
22

---
name: commune
description: |
  Send a communal context update to your Psyche.
argument-hint: "<<stdin>>"
allowed-tools: [Bash]
---

# /sptc:commune

> **Skeleton — thin by design.** Operative instructions for this skill are delivered by the
> `sptc` adapter at invocation time (UserPromptSubmit injection from the adapter `[strings]`;
> see `docs/adr/0001-distribution-splits-by-volatility.md`). This SKILL.md stays a stub.
>
> **Operative.** The UPS hook detects `/sptc:commune` and injects the body from
> `adapter/strings/skills/commune.md` (UPS-fires-on-slash confirmed, ADR-0002; file-backed
> `[strings]` shipped, F-003). If injection ever no-ops (spt absent / adapter unregistered), this
> stub is the floor.

Pushes a context delta to the Psyche via a file-drop (`<id>-commune.md` into the adapter's
`[session].commune_dir`); the daemon ingests it. Live agents only (a Psyche must exist).


1	---
2	name: force-stop
3	description: |
4	  Force-stop an SPT agent — ready or live (with its Psyche).
5	argument-hint: "<id>"
6	allowed-tools: [Bash]
7	---
8
9	# /sptc:force-stop
10
11	> **Skeleton — thin by design.** Operative instructions for this skill are delivered by the
12	> `sptc` adapter at invocation time (UserPromptSubmit injection from the adapter `[strings]`;
13	> see `docs/adr/0001-distribution-splits-by-volatility.md`). This SKILL.md stays a stub.
14	>
15	> **Operative.** The UPS hook detects `/sptc:force-stop` and injects the body from
16	> `adapter/strings/skills/force-stop.md` (UPS-fires-on-slash confirmed, ADR-0002; file-backed
17	> `[strings]` shipped, F-003). If injection ever no-ops (spt absent / adapter unregistered), this
18	> stub is the floor.
19
20	Tears down an agent's endpoint: graceful `spt endpoint shutdown` (final save + Psyche teardown) or
21	soft `spt endpoint stop`. No hard/no-grace path in core spt (tracked gap).
22

---
name: force-stop
description: |
  Force-stop an SPT agent — ready or live (with its Psyche).
argument-hint: "<id>"
allowed-tools: [Bash]
---

# /sptc:force-stop

> **Skeleton — thin by design.** Operative instructions for this skill are delivered by the
> `sptc` adapter at invocation time (UserPromptSubmit injection from the adapter `[strings]`;
> see `docs/adr/0001-distribution-splits-by-volatility.md`). This SKILL.md stays a stub.
>
> **Operative.** The UPS hook detects `/sptc:force-stop` and injects the body from
> `adapter/strings/skills/force-stop.md` (UPS-fires-on-slash confirmed, ADR-0002; file-backed
> `[strings]` shipped, F-003). If injection ever no-ops (spt absent / adapter unregistered), this
> stub is the floor.

Tears down an agent's endpoint: graceful `spt endpoint shutdown` (final save + Psyche teardown) or
soft `spt endpoint stop`. No hard/no-grace path in core spt (tracked gap).


1	# /sptc:send — operative instructions
2
3	> Delivered file-backed via the `claude-spt` adapter `[strings]`
4	> (`[strings.skills].send = { file = "skills/send.md" }`), resolved at injection time. The cplugs
5	> SKILL.md stays a thin skeleton (ADR-0001).
6
7	**Goal:** deliver a message to another spt agent.
8
9	**Do this:**
10
11	1. If `spt` is not on `PATH`, run `/sptc:setup` first.
12	2. Read the canonical, always-current guidance: run `spt how-to send` and follow it.
13	3. Operative summary (from that guidance) — the message **body is read from stdin**:
14	   - Fire-and-forget: `printf '%s' "<body>" | spt send <target>`.
15	     - `SENT:<target>` = delivered live. `QUEUED:<target>` = target not listening; spooled, drains
16	       on its next `spt ready`. **QUEUED is success — do not retry.**
17	   - Reply to a received message: `... | spt send --reply-to <sender>` (`<sender>` = the envelope's
18	     `from` attribute; prints `REPLIED:<sender>`).
19	   - Send and block for a reply: `... | spt ring <target> --timeout 60` (reply body prints to
20	     stdout; `TIMEOUT` is exit 0 — the message still landed, the reply arrives on your listener).
21	4. Your own sender id is auto-detected in most sessions; `--from <id>` overrides. To receive replies
22	   on your own listener, run `/sptc:ready` first.
23

# /sptc:send — operative instructions

> Delivered file-backed via the `claude-spt` adapter `[strings]`
> (`[strings.skills].send = { file = "skills/send.md" }`), resolved at injection time. The cplugs
> SKILL.md stays a thin skeleton (ADR-0001).

**Goal:** deliver a message to another spt agent.

**Do this:**

1. If `spt` is not on `PATH`, run `/sptc:setup` first.
2. Read the canonical, always-current guidance: run `spt how-to send` and follow it.
3. Operative summary (from that guidance) — the message **body is read from stdin**:
   - Fire-and-forget: `printf '%s' "<body>" | spt send <target>`.
     - `SENT:<target>` = delivered live. `QUEUED:<target>` = target not listening; spooled, drains
       on its next `spt ready`. **QUEUED is success — do not retry.**
   - Reply to a received message: `... | spt send --reply-to <sender>` (`<sender>` = the envelope's
     `from` attribute; prints `REPLIED:<sender>`).
   - Send and block for a reply: `... | spt ring <target> --timeout 60` (reply body prints to
     stdout; `TIMEOUT` is exit 0 — the message still landed, the reply arrives on your listener).
4. Your own sender id is auto-detected in most sessions; `--from <id>` overrides. To receive replies
   on your own listener, run `/sptc:ready` first.


1	# /sptc:signoff — operative instructions
2
3	> Delivered file-backed via the `claude-spt` adapter `[strings]`
4	> (`[strings.skills].signoff = { file = "skills/signoff.md" }`), resolved at injection time. The
5	> cplugs SKILL.md stays a thin skeleton (ADR-0001).
6
7	**Goal:** gracefully shut down this session's own endpoint, with the final context save.
8
9	**Do this:**
10
11	1. If `spt` is not on `PATH`, there is no endpoint to sign off — nothing to do.
12	2. (Optional) Write a brief closing summary of the session's state first, so the saved context is
13	   useful on resume.
14	3. Run `spt endpoint shutdown` (defaults to this session's own perch). It soft-stops the listener,
15	   then takes the suspend edge — **the final context save fires** and persistent shells cascade
16	   offline with it.
17	4. Confirm the shutdown to the user. After signoff this session is no longer reachable for
18	   inter-agent messages; `/sptc:ready` (or a fresh `spt endpoint run`) brings it back.
19
20	To stop the perch WITHOUT the full suspend/save (spool preserved, lighter), use `spt endpoint stop
21	<id>` instead — but signoff is the graceful, context-saving path.
22

# /sptc:signoff — operative instructions

> Delivered file-backed via the `claude-spt` adapter `[strings]`
> (`[strings.skills].signoff = { file = "skills/signoff.md" }`), resolved at injection time. The
> cplugs SKILL.md stays a thin skeleton (ADR-0001).

**Goal:** gracefully shut down this session's own endpoint, with the final context save.

**Do this:**

1. If `spt` is not on `PATH`, there is no endpoint to sign off — nothing to do.
2. (Optional) Write a brief closing summary of the session's state first, so the saved context is
   useful on resume.
3. Run `spt endpoint shutdown` (defaults to this session's own perch). It soft-stops the listener,
   then takes the suspend edge — **the final context save fires** and persistent shells cascade
   offline with it.
4. Confirm the shutdown to the user. After signoff this session is no longer reachable for
   inter-agent messages; `/sptc:ready` (or a fresh `spt endpoint run`) brings it back.

To stop the perch WITHOUT the full suspend/save (spool preserved, lighter), use `spt endpoint stop
<id>` instead — but signoff is the graceful, context-saving path.


1	# /sptc:list-agents — operative instructions
2
3	> Delivered file-backed via the `claude-spt` adapter `[strings]`
4	> (`[strings.skills].list-agents = { file = "skills/list-agents.md" }`), resolved at injection time.
5	> The cplugs SKILL.md stays a thin skeleton (ADR-0001).
6
7	**Goal:** show the roster of spt endpoints/agents reachable from this node.
8
9	**Do this:**
10
11	1. If `spt` is not on `PATH`, run `/sptc:setup` first.
12	2. Run `spt endpoint list` (equivalently, bare `spt endpoint`). It renders the merged listing —
13	   every member subnet's endpoints grouped by subnet, with **this session's own endpoint pinned
14	   distinctly at the top**.
15	3. Summarize for the user: who is online, their ids, and which is this session. To message one, use
16	   `/sptc:send <id>`; to become reachable yourself, `/sptc:ready`.
17

# /sptc:list-agents — operative instructions

> Delivered file-backed via the `claude-spt` adapter `[strings]`
> (`[strings.skills].list-agents = { file = "skills/list-agents.md" }`), resolved at injection time.
> The cplugs SKILL.md stays a thin skeleton (ADR-0001).

**Goal:** show the roster of spt endpoints/agents reachable from this node.

**Do this:**

1. If `spt` is not on `PATH`, run `/sptc:setup` first.
2. Run `spt endpoint list` (equivalently, bare `spt endpoint`). It renders the merged listing —
   every member subnet's endpoints grouped by subnet, with **this session's own endpoint pinned
   distinctly at the top**.
3. Summarize for the user: who is online, their ids, and which is this session. To message one, use
   `/sptc:send <id>`; to become reachable yourself, `/sptc:ready`.


1	# /sptc:commune — operative instructions
2
3	> Delivered file-backed via the `claude-spt` adapter `[strings]`
4	> (`[strings.skills].commune = { file = "skills/commune.md" }`), resolved at injection time. The
5	> cplugs SKILL.md stays a thin skeleton (ADR-0001).
6
7	**Goal:** push a context DELTA to this endpoint's Psyche so it can brief a resume across a session
8	boundary (a `/clear` or compact). Only meaningful for a **live agent** — a ReadyAgent has no Psyche.
9
10	**This is a FILE-DROP, not a command** — there is deliberately no `spt commune`. spt-core's daemon
11	watches the adapter's commune dir (`[session].commune_dir` = `.claude`), ingests any
12	`<endpoint_id>-commune.md` it finds into the endpoint's tracked mind, then deletes it (the daemon is
13	the single writer).
14
15	**Do this:**
16
17	1. If `spt` is not on `PATH`, there is no Psyche to commune with — nothing to do.
18	2. Resolve this session's endpoint id with `spt whoami` (empty ⇒ no perch — run `/sptc:live` first;
19	   commune needs a Psyche, i.e. a live agent). Call it `<id>`.
20	3. Compose a concise DELTA — not the whole history: current task + status, decisions made since the
21	   last commune, immediate next steps, and anything the Psyche needs to brief a resume.
22	4. Write it to `.claude/<id>-commune.md` (the watched dir, relative to this project). Use a single
23	   atomic write of the full markdown body.
24	5. Confirm to the user. **The file disappearing is the success signal** (the daemon ingested it). If
25	   it lingers, the watcher isn't running — verify `spt` is live and this endpoint is a LiveAgent.
26

# /sptc:commune — operative instructions

> Delivered file-backed via the `claude-spt` adapter `[strings]`
> (`[strings.skills].commune = { file = "skills/commune.md" }`), resolved at injection time. The
> cplugs SKILL.md stays a thin skeleton (ADR-0001).

**Goal:** push a context DELTA to this endpoint's Psyche so it can brief a resume across a session
boundary (a `/clear` or compact). Only meaningful for a **live agent** — a ReadyAgent has no Psyche.

**This is a FILE-DROP, not a command** — there is deliberately no `spt commune`. spt-core's daemon
watches the adapter's commune dir (`[session].commune_dir` = `.claude`), ingests any
`<endpoint_id>-commune.md` it finds into the endpoint's tracked mind, then deletes it (the daemon is
the single writer).

**Do this:**

1. If `spt` is not on `PATH`, there is no Psyche to commune with — nothing to do.
2. Resolve this session's endpoint id with `spt whoami` (empty ⇒ no perch — run `/sptc:live` first;
   commune needs a Psyche, i.e. a live agent). Call it `<id>`.
3. Compose a concise DELTA — not the whole history: current task + status, decisions made since the
   last commune, immediate next steps, and anything the Psyche needs to brief a resume.
4. Write it to `.claude/<id>-commune.md` (the watched dir, relative to this project). Use a single
   atomic write of the full markdown body.
5. Confirm to the user. **The file disappearing is the success signal** (the daemon ingested it). If
   it lingers, the watcher isn't running — verify `spt` is live and this endpoint is a LiveAgent.