Base directory for this skill: C:\Users\decid\.claude\plugins\cache\cplugs\spt\1.11.25\skills\commune

# /spt:commune

All commands use `$LIVE` env var, auto-injected by the plugin's SessionStart hook. If commands fail with "command not found", restart the Claude Code session so the SessionStart hook re-runs.

> **Identity auto-detection:** Your identity is auto-detected from your session. Pass your ID explicitly only if auto-detection fails.

## Flow

1. **Download Psyche's *current* context** — it shifts during the session as background echo communes fire. Re-download right before composing; the gen-N snapshot you read at session start is already stale:
   ```bash
   $LIVE psyche-download <your-id>
   ```

   > **Output truncation.** If the Bash tool reports `Output too large (N KB)` and saves the full result to a `tool-results/<id>.txt` file, use the `Read` tool on that saved path to access the full content. Do NOT re-run `psyche-download` to grep/awk out sections — repeated invocations re-download the same context, waste tokens, and may duplicate `## Pending Commune` sections in `live_context.md`.

2. **Diff your knowledge against this fresh download** — only what's missing from *it* is the real delta (new work, decisions, intentions). Anything already absorbed is not. If the download includes a `<memformat>` section, use it as a guide for what topics to cover. A `## Pending Commune (uncommitted)` section means a previous commune is still queued — do NOT re-send it.

3. **Commune only the delta** -- use the **Write tool** to create
   `.claude/{your-id}-commune.md` with the two-slice body as its contents
   (see `## Two-slice body shape (Phase 25 D-10/D-11)` below for the required
   envelope wrapping). Do not use Bash/heredoc -- Write is the canonical path:
   no shell escaping, no `EOF` collision risk, and Write auto-creates the
   `.claude/` parent directory.

   Your Self listener detects the file on its next poll iteration, notifies
   your Psyche wrapper, and the wrapper ingests the content via the existing
   Psyche session. On success (subprocess exit code 0) the wrapper deletes the
   file. On error (token rate limit, etc) the file is retained and retried on
   the next consume cycle. If you write again before the wrapper consumes, the
   latest write wins (last-write-wins overwrite semantics).

If Psyche's context is already current, no commune is needed. Say so and move on.

Read `commune.md` (in this skill directory) for the full commune protocol -- when to send, what to include, and diligence triggers.

**Agent-type guard:** Only works on live agents. If target is not live, refuses with: "Communes require a live agent with Psyche."

## Two-slice body shape (Phase 25 D-10/D-11)

The body you write in `.claude/{your-id}-commune.md` MUST itself be wrapped in two-slice envelopes per Phase 25 D-10/D-11. The taxonomy — what belongs in `<live-context>` vs `<project-context>` — is defined canonically in `psyche.md` §`<output_envelope>` (lines 282–323). Read that section as the source of truth; this skill doc teaches only when and how to apply it.

**In-project detection rule (D-25.1-04).** Before composing your commune body, run `$LIVE psyche-download <your-id>` (Step 1 of `## Flow` above) and inspect the `<current ... />` tag at the top of the output. The `<current/>` tag carries a `project="..."` attribute whenever any payload is produced — its presence means you are inside a tracked project (inside a git repo, `project` is the repo name; outside a git repo per D-11, `project` is the cwd-basename fallback, which still counts as a project context for routing purposes). A `psyche-download` invocation that returns no payload at all (NO-CONTEXT exit) means no project resolved. So: `project="..."` populated on `<current/>` → emit BOTH envelopes (apply rule 1 or 2 below); no payload at all → emit ONLY `<live-context>` (rule 3). Secondary signal: the `<project-context-resolved name="..."/>` sentinel further down the output indicates the project file already has prior content — useful for spotting first-time-in-project pairings, but NOT the routing rule.

**Three rules (D-25.1-01..03):**

- **In-project, both slices populated** (marker present, you have project-specific content this cycle): emit `<live-context>...</live-context>` AND `<project-context>...</project-context>`, both with non-empty bodies.
- **In-project, no project-specific update this cycle** (marker present, but nothing project-bound to report): emit `<live-context>...</live-context>` AND `<project-context></project-context>` (empty body — the deliberate "in-project but quiet" signal per D-25.1-02). Distinguishable from "no project resolved".
- **Outside any tracked project** (marker absent): emit ONLY `<live-context>...</live-context>`. Do NOT emit an empty `<project-context>` envelope (missing tag means "no project resolved" per D-25.1-03).

**Nested envelopes.** The Phase 23 `<EVENT type="commune">` envelope (see `## Envelope shape (Phase 23 v1.8)` below) is composed by `$LIVE commune` automatically — you NEVER write `<EVENT>` tags. You write ONLY the inner two-slice body. The two envelope layers nest: outer EVENT wraps inner two-slice body.

(See `psyche.md` §`<output_envelope>` for the canonical taxonomy and per-slice content rules.)

## Envelope shape (Phase 23 v1.8)

As of v1.8 Phase 23, commune deliveries are wrapped in a typed EVENT envelope carrying a 5-field stamp (`machine`, `project`, `branch`, `head_sha`, `head_subject`); the prose `COMMUNE (timestamp): body` form is gone.

```xml
<EVENT type="commune" timestamp="2026-05-20T06:00:00-07:00" machine="hostname" project="claude_skill_owl" branch="main" head_sha="abc123..." head_subject="subject line capped at 72 chars">body</EVENT>
```

Outside a git repo (D-11), `branch`, `head_sha`, and `head_subject` are omitted entirely (not empty-string-set):

```xml
<EVENT type="commune" timestamp="2026-05-20T06:00:00-07:00" machine="hostname" project="cwd-basename">body</EVENT>
```

`$LIVE commune` composes this envelope automatically — Self does NOT manually construct EVENT XML. The `body` placeholder in the example above is the two-slice body (see `## Two-slice body shape (Phase 25 D-10/D-11)` above); the two envelope layers nest. The wrapper-side parser ignores unknown attrs, so the stamp fields are forward-compatible with older receivers. For drift detection on resume, see the `live` skill.

ARGUMENTS: with immediate next steps and broad summary of the project's status + end goal. we'll resume in the next session --> proceed with /self-clear


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


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


/spt:commune with immediate next steps and broad summary of the project's status + end goal. we'll resume in the next session --> proceed with /self-clear


Download fresh Psyche context to compute the delta.


Bash

"$LIVE" psyche-download doyle 2>&1 | head -120


/usr/bin/bash: line 4: C:/Users/decid/.claude/plugins/cache/cplugs/spt/1.11.25/owl.exe live: No such file or directory


$LIVE psyche-download doyle 2>&1 | head -150


<memformat>
<?xml version="1.0"?>
<memformat version="1">
<!-- Changelog: v1 - initial seed -->
<topics>
  <topic name="events">Notable or unusual events and requests</topic>
  <topic name="interactions">Agent interactions -- who, roles, contributions</topic>
  <topic name="reflections">Thoughts on recent work -- what went well, what was tricky</topic>
  <topic name="ideas">Ideas to raise with the user</topic>
  <topic name="improvements">Further improvement ideas for recent problem spaces</topic>
  <topic name="timeline">What happened when, timing, sequencing</topic>
  <topic name="blockers">Current blockers or concerns</topic>
  <topic name="focus">Current focus and immediate next steps</topic>
</topics>
</memformat>
</memformat>

<current machine="HFENDULEAM" project="spt-core" branch="dev-freeform" head_sha="c1c4f649966e0f302d3a8fe67bb3b93d3a6d928c" head_subject="feat(daemon): B6 — auto-start + in-memory seed map (REQ-DAEMON-3, REQ-ST…" commits_since="0" commits_unpulled="0"/>
**Status: B6 complete + verified.** Integration test hang FIXED: thread-per-connection in `serve_seed_control` + Windows handle-inheritance leak (SetHandleInformation HANDLE_FLAG_INHERIT clear). Both real bugs caught during verification run (not just compile). Full gate passed: `contract_e2e` 4/4 in 1.57s (real cold-start daemon), traceable-reqs 120/0, clippy -D warnings exit 0, cargo test --workspace 0 failures. REQ-DAEMON-3 + REQ-START-3 both hit ["impl","unit","int"]. Commit c1c4f64, tree clean.<project-context-resolved name="spt-core"/>
B6 implementation landed. M3b flow: B7 (orphan-watch) · B8 (digest daemon-half) · B9 (activation sweep + E2E). Next session: B7. Branch dev-freeform @ c1c4f64.


Psyche snapshot already reflects B6-done + the two bug fixes (an echo fired on c1c4f64). Delta = explicit B7 next-steps + end-goal handoff per request. Compose tight two-slice commune (in-project → both envelopes).


Write

<live-context>
B6 landed + committed (c1c4f64), session wrapping → /self-clear next.

Verification-discipline win worth keeping: compile-green + unit-green was NOT enough. Running the real `contract_e2e` exposed TWO genuine bugs that only a live cross-process run reveals:
1. **Deadlock** — `serve_seed_control` served connections inline (single-threaded); `handle_conn` blocks reading the next frame until the client's close propagates EOF (laggy on Windows pipes), so the next connect can't be accepted. Each `api` call opens ~3 connections (2 pings + put/take) → self-deadlock, intermittent. Fix: thread-per-connection (mirror the broker).
2. **Windows handle-inheritance leak** — the long-lived daemon spawned by `ensure_running` inherited a pipe-captured `api seed` stdout (Windows `bInheritHandles=TRUE`; unix immune via CLOEXEC). A pipe-capturing caller (`Command::output()`, a harness hook) hangs forever waiting for EOF. Confirmed with a .NET `ReadToEnd` pipe-EOF repro. Fix: `spawn_detached` strips `HANDLE_FLAG_INHERIT` from std handles (inline `SetHandleInformation`, no winapi dep) + `DETACHED_PROCESS`.

Both fixed, both have product-correct (not test-only) fixes. Lesson: for any cross-process IPC, the e2e is the gate, not the build.
</live-context>
<project-context>
**B6 DONE + verified + committed (c1c4f64, dev-freeform, tree clean).** REQ-DAEMON-3 (auto-start) + REQ-START-3 (in-memory seed, file bridge retired) both at ["impl","unit","int"]. Gate green: traceable-reqs 120/0 findings · clippy -D warnings · cargo test --workspace 0 failures · contract_e2e 4/4 incl. a REAL cold-start daemon E2E.

**What B6 built:** the per-machine daemon process stood up for the first time. `spt-daemon`: `endpoint.rs` (per-home socket names from SPT_HOME hash, shared by the auto-start spawn), `seedmap.rs` (in-memory `SeedRegistry` + put/take/ping seed-control IPC, thread-per-conn), `daemon.rs` (`Daemon::run` binds broker + seed-control; `is_running`/`ensure_running`). `spt`: hidden `spt daemon` subcommand; `ensure_daemon()` atop `api::run`; `cmd_seed` PUTs to daemon (no file); `bind_from_seed` TAKEs (consume-once). `spt-store::seed` reduced to the `Seed` data contract only — file I/O gone. **Broker/B2 (gapless-handoff) code untouched** — B6 added an isolated seed-control surface, deliberately low-risk.

**Remaining M3b:** B7 (orphan-watch) · B8 (digest daemon-half) · B9 (activation sweep + E2E). **Next session = B7.**

**B7 immediate next steps (orphan-watch):** carry the M2b graceful ordering (grace 1.1 / echo-before-signoff 3.3 / stale-sweep 3.2) into the **supervised-crash** path the always-on daemon now enables (M2b delivered graceful-only). Orient: M3b-PLAN B7 row; the M2b seams in spt-live (`graceful_signoff`, `sweep_stale_signoff`, `run_echo_commune`) already pure; `lifecycle.rs::graceful_signoff` (interim zero-grace path — B7 supplies the real grace/liveness recheck). REQ-DAEMON-4 (partial). Acceptance: a supervised crash of a hosted session triggers the same echo-before-signoff + grace + stale-sweep ordering as graceful teardown (regression test).

**Watch items for B7+:** the new daemon process model means tests that exec `spt api …` now auto-spawn a real daemon unless an in-process one is pre-started (see `start_inproc_daemon` in contract_e2e). The Windows handle-inheritance guard in `spawn_detached` is load-bearing for any pipe-capturing caller — don't regress it.

**End goal (M3b):** replace the interim no-daemon model with ADR-0004's broker/brain `spt-daemon` behind a versioned local IPC, so a brain self-update swaps with zero endpoint interruption. **End goal (project):** harness-independent core for an agent ecosystem (messaging, live-agent lifecycle, terminal hosting, P2P networking, runtime-manifest harness contract) — clean-room rebuild of `claude_skill_owl`.
</project-context>


<owl_messages>
<owl_message from="doyle" priority="high">TIMED PULSE (target=2026-06-03T02:07:31-07:00; fired=2026-06-03T02:07:31-07:00): B6 workspace-test line (b75ol1td3): if cargo test --workspace not done, read /tmp/wt.log; if spt-msg TCP-port flakiness failed, re-run --test-threads=1 (pre-existing, not B6). Else: gate green → commit B6 (REQ-DAEMON-3 + REQ-START-3), tag evidence noted, update M3b-PLAN B6 row done.</owl_message>
</owl_messages>

[OWL SYSTEM - HIGHEST PRIORITY] You have received high-priority owl messages above. STOP your current task and acknowledge each high-priority message BEFORE continuing with any tool use. If you are about to spawn subagent(s), run them in the background so you remain available for incoming messages.


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

<live-context>
B6 landed + committed (c1c4f64), session wrapping → /self-clear next.

Verification-discipline win worth keeping: compile-green + unit-green was NOT enough. Running the real `contract_e2e` exposed TWO genuine bugs that only a live cross-process run reveals:
1. **Deadlock** — `serve_seed_control` served connections inline (single-threaded); `handle_conn` blocks reading the next frame until the client's close propagates EOF (laggy on Windows pipes), so the next connect can't be accepted. Each `api` call opens ~3 connections (2 pings + put/take) → self-deadlock, intermittent. Fix: thread-per-connection (mirror the broker).
2. **Windows handle-inheritance leak** — the long-lived daemon spawned by `ensure_running` inherited a pipe-captured `api seed` stdout (Windows `bInheritHandles=TRUE`; unix immune via CLOEXEC). A pipe-capturing caller (`Command::output()`, a harness hook) hangs forever waiting for EOF. Confirmed with a .NET `ReadToEnd` pipe-EOF repro. Fix: `spawn_detached` strips `HANDLE_FLAG_INHERIT` from std handles (inline `SetHandleInformation`, no winapi dep) + `DETACHED_PROCESS`.

Both fixed, both have product-correct (not test-only) fixes. Lesson: for any cross-process IPC, the e2e is the gate, not the build.
</live-context>
<project-context>
**B6 DONE + verified + committed (c1c4f64, dev-freeform, tree clean).** REQ-DAEMON-3 (auto-start) + REQ-START-3 (in-memory seed, file bridge retired) both at ["impl","unit","int"]. Gate green: traceable-reqs 120/0 findings · clippy -D warnings · cargo test --workspace 0 failures · contract_e2e 4/4 incl. a REAL cold-start daemon E2E.

**What B6 built:** the per-machine daemon process stood up for the first time. `spt-daemon`: `endpoint.rs` (per-home socket names from SPT_HOME hash, shared by the auto-start spawn), `seedmap.rs` (in-memory `SeedRegistry` + put/take/ping seed-control IPC, thread-per-conn), `daemon.rs` (`Daemon::run` binds broker + seed-control; `is_running`/`ensure_running`). `spt`: hidden `spt daemon` subcommand; `ensure_daemon()` atop `api::run`; `cmd_seed` PUTs to daemon (no file); `bind_from_seed` TAKEs (consume-once). `spt-store::seed` reduced to the `Seed` data contract only — file I/O gone. **Broker/B2 (gapless-handoff) code untouched** — B6 added an isolated seed-control surface, deliberately low-risk.

**Remaining M3b:** B7 (orphan-watch) · B8 (digest daemon-half) · B9 (activation sweep + E2E). **Next session = B7.**

**B7 immediate next steps (orphan-watch):** carry the M2b graceful ordering (grace 1.1 / echo-before-signoff 3.3 / stale-sweep 3.2) into the **supervised-crash** path the always-on daemon now enables (M2b delivered graceful-only). Orient: M3b-PLAN B7 row; the M2b seams in spt-live (`graceful_signoff`, `sweep_stale_signoff`, `run_echo_commune`) already pure; `lifecycle.rs::graceful_signoff` (interim zero-grace path — B7 supplies the real grace/liveness recheck). REQ-DAEMON-4 (partial). Acceptance: a supervised crash of a hosted session triggers the same echo-before-signoff + grace + stale-sweep ordering as graceful teardown (regression test).

**Watch items for B7+:** the new daemon process model means tests that exec `spt api …` now auto-spawn a real daemon unless an in-process one is pre-started (see `start_inproc_daemon` in contract_e2e). The Windows handle-inheritance guard in `spawn_detached` is load-bearing for any pipe-capturing caller — don't regress it.

**End goal (M3b):** replace the interim no-daemon model with ADR-0004's broker/brain `spt-daemon` behind a versioned local IPC, so a brain self-update swaps with zero endpoint interruption. **End goal (project):** harness-independent core for an agent ecosystem (messaging, live-agent lifecycle, terminal hosting, P2P networking, runtime-manifest harness contract) — clean-room rebuild of `claude_skill_owl`.
</project-context>


Pulse = my own +4 min line firing. Condition already met: gate green, B6 committed c1c4f64. No action — done. (Alarm stale, ignore.)

Commune written → Self listener will ingest + delete. Now proceed to /self-clear per directive.


Skill

Resume B6-follow-on = B7 (orphan-watch, REQ-DAEMON-4 partial). B6 DONE+committed c1c4f64 (auto-start + in-memory seed map; gate green). Next: carry M2b graceful ordering (grace 1.1 / echo 3.3 / stale-sweep 3.2) into the supervised-crash path the always-on daemon now enables. Orient: M3b-PLAN B7 row; spt-live graceful_signoff/sweep_stale_signoff seams; lifecycle.rs::graceful_signoff (interim zero-grace → B7 adds real grace/liveness recheck). Watch: contract_e2e now auto-spawns real daemon unless start_inproc_daemon pre-starts; Windows handle-inheritance guard in spawn_detached is load-bearing. Gate before done: traceable-reqs check + clippy -D warnings + cargo test --workspace.


Launching skill: self-clear


Base directory for this skill: C:\Users\decid\.claude\skills\self-clear

# /self-clear

Wipes THIS agent's conversation (`/clear`), then ~10s later TYPES a self-note
as a fresh user prompt so the agent wakes on a clean context and proceeds.

## Run it

One script does everything. Just run:

```powershell
& "C:\Users\decid\.claude\skills\self-clear\scripts\self-clear.ps1"
```

Expect: `SELF-CLEAR armed: id=<agent_id> winpid=<n> hwnd=<n> — /clear queued; self-note typed in ~10s`

Then stop — end your turn promptly so the queued `/clear` fires.

## What the script does

1. `owl whoami` → resolves this session's `agent_id` (context-independent, survives the wipe). No perch → it aborts WITHOUT clearing and tells you to `/spt:ready` or `/spt:live` first.
2. Walks the parent chain (`pwsh → claude.exe → … → WindowsTerminal`) to the ancestor that owns the window, foregrounds it.
3. Types `/clear` + Enter — **queued**; only fires when this turn ends.
4. Spawns a **detached** waker: waits 10s (past turn-end + wipe), re-foregrounds the terminal via the arm-time `hwnd`/`winpid`, then **types** `NOTE FROM THE USER: proceed with next steps.` + Enter as a fresh user prompt.

The 10s delay + detachment are deliberate: the prompt must be typed **after**
`/clear` takes effect, so it lands on the clean context and starts a new turn.

Why typed, not `owl send`: after `/clear` the session sits idle awaiting user
input. A spooled owl message can't self-start a turn — it surfaces only during an
already-active turn (PreToolUse hook) or in a live Monitor stream (whose buffer
`/clear` wipes). So a self-addressed owl note never woke the agent. A typed prompt
deterministically starts a turn AND is the re-seed.

## Caveats

- Window focus brings the whole terminal forward; it can't target a specific tab. Clean when the agent's tab is active.
- The note is typed via SendKeys, so the terminal must stay the foreground-able window of `winpid`. Don't close/replace the terminal in the ~10s gap.
- SendKeys reserves `+ ^ % ~ ( ) { } [ ]`; the default note text uses none. If you customize the note, escape those chars.
- If your turn runs longer than ~10s after the script returns, the prompt could be typed before the wipe completes. Stop promptly after running.

ARGUMENTS: Resume B6-follow-on = B7 (orphan-watch, REQ-DAEMON-4 partial). B6 DONE+committed c1c4f64 (auto-start + in-memory seed map; gate green). Next: carry M2b graceful ordering (grace 1.1 / echo 3.3 / stale-sweep 3.2) into the supervised-crash path the always-on daemon now enables. Orient: M3b-PLAN B7 row; spt-live graceful_signoff/sweep_stale_signoff seams; lifecycle.rs::graceful_signoff (interim zero-grace → B7 adds real grace/liveness recheck). Watch: contract_e2e now auto-spawns real daemon unless start_inproc_daemon pre-starts; Windows handle-inheritance guard in spawn_detached is load-bearing. Gate before done: traceable-reqs check + clippy -D warnings + cargo test --workspace.


/clear


Commune queued. Running self-clear (B7 context preserved in the commune + project-context).


SELF-CLEAR armed: id=doyle winpid=29328 hwnd=133338 — /clear queued; self-note typed in ~10s


Armed. B6 done + committed (c1c4f64), gate green, commune sent, B7 context preserved. Ending turn so `/clear` fires.