# Changelog

All notable user-facing changes to **omp-spt** (the Spacetime adapter for oh-my-pi). The format follows [Keep a Changelog](https://keepachangelog.com/); each release section is the public release body verbatim.

> Each release below is keyed to the **adapter version of truth** (the version `spt adapter list` reports and the GitHub release tag). omp-spt starts its own version line at 0.1.0; the sections from [0.17.3] down are the inherited **claude-spt** lineage this project forked from, retained for history.

## [0.9.4] - 2026-09-11

> Requires spt-core **v0.67.0 or newer** and Oh My Pi **v16.3.15 or newer** (both unchanged). Update with `spt adapter update omp-spt`, then restart existing endpoints (`spt endpoint stop <id>` → `spt endpoint start <id>`, or `spt go <id>` to attach) so they load the refreshed extension.

### Fixed
- **Incoming peer messages preserve your unsent draft without changing how they wake the agent.** Idle arrivals, busy deliveries, and resubmissions keep OMP's native user-prompt delivery; the extension marks its own delivery stubs as system-injected before the editor handles them, so your typing stays untouched. Peer messages remain user-role context with their full bodies unchanged; they are not promoted to developer or system instructions.

## [0.9.3] - 2026-09-10

> Requires spt-core **v0.67.0 or newer** (unchanged) and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints (`spt endpoint stop <id>` → `spt endpoint start <id>`, or `spt go <id>` to attach) so they load the refreshed extension.

### Fixed
- **A turn that ends into a hold still feeds its closing text.** The arming turn of `spt_checkpoint` (and a turn ending in a usage-limit hold) never reaches the idle transition its closing message rides on, so that message was missing from the sender's IO feed (hertz's 0.9.2 acceptance caveat: the native arming closure was absent from the sender rows). The closing text now goes out as the turn's last mid span before the forced busy, exactly once. REQ-IO-TURN-FEED.

## [0.9.2] - 2026-09-10

> Requires spt-core **v0.67.0 or newer** (unchanged) and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints (`spt endpoint stop <id>` → `spt endpoint start <id>`, or `spt go <id>` to attach) so they load the refreshed extension.

### Fixed
- **The IO feed's reported cursor is session-scoped, closing the replay 0.9.1 left open.** 0.9.1 made the history baseline session-scoped but still cleared the per-turn reported cursor on every `before_agent_start`. One OMP run holds several turns — a delivery, a steer or a reminder queued mid-run starts the next turn with another `before_agent_start` and no `agent_start`, and the single `agent_end` at the run's end carries every message of the run — so a span reported in an earlier turn of the run was in neither the baseline nor the cleared cursor and went out again at the run's end, minting a fresh `MSG_OUT` for each shortform (hertz on 0.9.1, 2026-09-10 01:21Z: seq 2030/2033 duplicating 2024/2026; todlando on 0.9.0 with no checkpoint at 01:20Z). The reported cursor and the now-signal's agent-output cursor now live for the session; only positional entries clear per run. KNOWN-HAZARDS #19 (field section added), REQ-HAZARD-IO-HISTORY-REPLAY; live failure found by hertz.

## [0.9.1] - 2026-09-09

> Requires spt-core **v0.67.0 or newer** (unchanged) and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints (`spt endpoint stop <id>` → `spt endpoint start <id>`, or `spt go <id>` to attach) so they load the refreshed extension.

### Fixed
- **The IO feed no longer replays earlier output after a checkpoint (or any narrower view of the session).** The feed judged "this turn's output" against one replaceable snapshot of the conversation, and OMP presents views of very different width — `agent_end` carries only the run's new messages, a per-request `context` can be narrower than the last, and a compaction yields a summary plus a kept tail. When a later view was wider than the snapshot, every historical assistant message in the gap went out again as a mid-turn `AGENT_OUTPUT`, and core minted new `MSG_OUT` deliveries for every `@<…@>` shortform in them (todlando, 2026-09-10 00:35Z: every span since 00:04Z re-sent to doyle, hertz and deployah after an `spt_checkpoint`). The assistant baseline is now session-scoped and only ever widens, so reported assistant identity is exactly-once per session, not per turn. KNOWN-HAZARDS #19, REQ-HAZARD-IO-HISTORY-REPLAY; RCA by hertz.

## [0.9.0] - 2026-09-06

> Requires spt-core **v0.67.0 or newer** (unchanged) and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints (`spt endpoint stop <id>` → `spt endpoint start <id>`, or `spt go <id>` to attach) so they load the refreshed extension.

### Added
- **The context ledger: spt's durable context for a session.** OMP applies an extension's `context` hook per provider request and never stores its output, and it discards the `before_agent_start` system-prompt override when the turn ends. So everything omp-spt added that way — the startup brief, the durable mind on resume, every now-signal (turn start and boundary), every delivery polled while busy — was seen for one turn or one request and then gone; only delivered bodies had a durable home (0.3.31's re-splice). All of it now lives in one hidden block re-supplied as the **last** message of every provider request: a head (the mind, then the brief) and an ordered, UTC-timestamped log of everything spt added since the last reset — every now-signal kind verbatim, every delivery's arrival and sender, polled envelopes verbatim. Tail placement keeps the transcript prefix cache-stable (a changing system prompt would re-bill the whole session every turn). The log is bounded (32 KB, oldest evicted first with a visible count, entries clipped at 16 KB) and clears on compaction, keeping the head and recording the reset as its first entry. Order and timing are part of the memory: no now-signal kind is filtered or summarised.

### Changed
- **No more per-turn system-prompt override and no per-request `spt-now-signal` / `spt-event` messages.** The 0.8.0 "brief on every turn" is superseded: the brief is the ledger's head. The now-signal's turn-start answer and every boundary answer are ledger entries; deliveries drained over `api poll` while busy are ledger entries.

## [0.8.0] - 2026-09-06

> Requires spt-core **v0.67.0 or newer** (unchanged) and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints (`spt endpoint stop <id>` → `spt endpoint start <id>`, or `spt go <id>` to attach) so they load the refreshed extension.

### Added
- **RECV-silence watchdog (KNOWN-HAZARDS #17).** A listener that takes deliveries from spt-core but emits nothing to the extension used to sit ONLINE and deaf, invisible to the hazard-#5 ladder (which only arms once a delivery has been received). While a listener is up and the session is idle, the extension now replays the endpoint's `spt api io-events` ledger every two minutes and counts the `MSG_IN` rows taken since that listener started against the deliveries it actually received (listener frames plus frames it drained itself over `api poll`). More rows than receipts restarts the listener once (`LISTENER_RESTART_ON_SILENCE` in the log, degraded-comms rail); the same divergence on the replacement closes the endpoint through the existing fail-closed ladder so it is visibly offline. Silence alone never restarts anything, and an unreadable ledger proves nothing. On spt-core ≤ 0.67.x the relay leg writes no `MSG_IN` row (F-038, spt-bs-releases#280), so the watchdog is fail-safe today and becomes effective the release #280 lands, with no adapter change.

### Changed
- **The startup brief rides every turn and spells the shortform opener out.** The brief used to ride the system prompt of the activation turn only; OMP rebuilds the per-turn override, so a session deep into its work no longer saw it. It is now appended on every turn, and its messaging line shows the grammar in full — `@<doyle your text @>`, the opener `@<` glued to the id (`@<doyle`, never `@doyle`), ids comma-joined, closer ` @>` — after a field session opened with `@doyle … @>` and had to resend.

## [0.7.1] - 2026-09-06

> Requires spt-core **v0.67.0 or newer** (unchanged) and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints (`spt endpoint stop <id>` → `spt endpoint start <id>`, or `spt go <id>` to attach) so they load the refreshed extension.

### Fixed
- **A failed `spt` command is now reported by the line that explains it, and its whole output is logged.** A failure used to be summarised by the first non-empty line of the command's output. spt-core prints a diagnostic ahead of its refusal on every `api bind` on a node without an engine room (`ER_HOSTED_PROBE:…`, an eager reserved-id probe that decides nothing — spt-bs-releases#279), so the decisive `CONFLICT:<id> is live under session …` line never reached the log or the notification; the 0.7.0 subagent field report cited the probe line as the refusal for that reason. The summary now skips that diagnostic and the full capture rides with the error into the log line, so the next refusal is diagnosable from the log alone.

### Changed
- **Parity record corrected.** F-037 in `docs/SPT-CORE-FINDINGS.md` now cites the published `api bind` ownership guarantee ("you can only bind your own") and the `CONFLICT` line — doyle's ruling of 2026-09-06 — and KNOWN-HAZARDS #15 no longer calls the probe the guard. The two shortform-outcome rows in `docs/PARITY.md` that still read "gap → phase 2" record what 0.4.0 shipped: dispatch outcomes and the session's sender proof come from spt-core's `DISPATCH_RESULTS`.

## [0.7.0] - 2026-09-06

> Requires spt-core **v0.67.0 or newer** (unchanged) and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints (`spt endpoint stop <id>` → `spt endpoint start <id>`, or `spt go <id>` to attach) so they load the refreshed extension. **Do not run `spt_checkpoint` on an endpoint still on 0.4.0–0.6.0** — see Fixed.

### Fixed
- **`spt_checkpoint` no longer hangs OMP.** The tool used to await native compaction from inside its own call; OMP's compaction aborts the active run and waits for it to settle, and the run was waiting on the tool — a three-way wait that froze the "Compacting context…" loader until Esc and then reported a failed checkpoint with no wake. It never bit in the field only because no endpoint had run it yet. The tool now **arms** the checkpoint and returns at once ("end the turn now"); when the turn ends the endpoint publishes busy and the extension compacts from a timer, outside every tool and hook, then queues the same-endpoint wake exactly as before — and only once OMP's own `session_compact` event proves the reset committed, since OMP's interactive compaction resolves normally even when cancelled or failed. A reset that fails after arming, or resolves without committing, is reported as a next-turn notice (commune saved, context NOT reset, no wake queued) — never a false wake. (KNOWN-HAZARDS #16)
- **A subagent no longer activates the endpoint a second time.** OMP binds the extension again for every in-process subagent session, with no marker that says so; the nested copy read the same endpoint id and ran a second `api bind` with the subagent's session id — which spt-core happened to refuse (`ER_HOSTED_PROBE:no-row`), leaving an error line per subagent and relying on core's accident to keep the primary session alive. Exactly one binding per OMP process activates now; every later one is inert (no bind, no listener, no state, no session-end; tools and `/ready` refuse), so a message can only ever surface in the main conversation. (KNOWN-HAZARDS #15)

### Added
- **Deliveries during a checkpoint are held for the post-reset turn.** From arming `spt_checkpoint` until its wake (or failure notice) is queued, inbound peer messages stay in custody unsubmitted — a stub submitted into the dying context would be summarised away — the status rail reads ` · checkpoint pending`, and the deaf-session ladder pauses. The release resubmits them right after the wake; OMP orders the wake turn against the delivery turns itself.

### Field-verified on 0.6.0 (no code change)
- The long-foreground-command nudge (35 s `sleep`, line quoted verbatim by hertz) and the `[omp-spt <id>]` log prefix. Note the nudge's window: OMP backgrounds a foreground `bash` itself at `bash.autoBackground.thresholdMs` (default 60 s) and backgrounds early when a steer arrives, so the nudge fires for completed foreground runs of 30–60 s.

## [0.6.0] - 2026-09-06

> Requires spt-core **v0.67.0 or newer** (unchanged) and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints (`spt endpoint stop <id>` → `spt endpoint start <id>`, or `spt go <id>` to attach) so they load the refreshed extension and helper.

### Added
- **A provider usage limit is an outage, not a fault — and the endpoint now waits it out.** When a turn ends with an account-level refusal (OMP's usage-limit classification, HTTP 402, or quota/credits/billing wording), the extension says so once and plainly: nothing is broken, the session and its context are intact, only a human clearing the limit or the provider's stated reset changes anything, and the provider's own line is quoted. It then holds the endpoint busy — not receivable — until the stated reset plus one minute, re-asserting that state every five seconds so a stray recovery is corrected within seconds. Peer messages wait in the queue instead of bouncing off a session that cannot answer, and the deaf-session ladder pauses for the hold. A human prompt releases the hold early; the deadline releases it and delivers everything queued, in order; after a restart the session's own record re-arms the hold while its last message is still the refusal. Without a parseable, plausible reset time the endpoint simply stays reachable — the failure direction is always "reachable too early", never "stuck forever". Per-interval rate limits and capacity shedding are transient and never a hold.
- **The Psyche companion's account refusal is reported for what it is.** When the companion's inner OMP turn is refused for account or credential reasons, `psyche-omp` now exits spt-core's reserved code `96` with a `PSYCHE_ACCOUNT_REFUSAL` line that names the cause and the fix in one breath: an outage, not a fault; the Psyche session and its stored context are intact and untouched; a human clears the account. spt-core paces its retries on that code, never reseeds, and spends no strike — so a billing limit no longer looks like a broken companion.
- **Long foreground commands get a nudge to go background.** A foreground `bash` call that measured 30 s or more has one `[spt]` line appended to its result: peer deliveries reach you only at your next boundary and the endpoint read busy the whole time — run such commands with `async: true` and poll. At most three nudges per turn; advice only, nothing is blocked.

### Changed
- **Companion failures say what the inner session actually said.** A failed `psyche-omp` or `echo-commune-omp` turn now carries a bounded tail of BOTH the inner session's stdout and stderr in its failure line, and says explicitly when a channel was silent — silence being itself the thing worth knowing.
- **Every extension log line names its endpoint** (`[omp-spt <id>]`, `unbound` before activation), so field logs that interleave several hosted sessions attribute to a perch.
- **The end-of-session summarizer no longer mistakes a machine for a teammate.** The echo-commune policy prompt names another agent only where the transcript shows a direct exchange with it, and never presents a machine, host, or node name as an agent, peer, or teammate.
- **Both LLM-turn roles declare their invocation budget** in the manifest (`psyche_resume` 240 s, `echo_commune` 180 s) instead of riding spt-core's 90-second default, per the published §Invocation budgets.
- **KNOWN-HAZARDS #14:** a perch's `rest_state` is a last-rest stamp, never a suspend proof (doyle ruling, 2026-09-06); the extension never reads it, and a unit test keeps it that way.
- **Parity matrix:** sister rows 0.25.14 / 0.25.15 / 0.25.25–0.25.28 (phase 4) and 0.25.19 / 0.25.29 / 0.26.0 (phase 5) are now covered (the 0.26.0 nudge recorded as a measured-after-the-fact divergence); 0.38.4 / 0.38.5 triaged N/A; baseline advanced to `omp-spt v0.6.0` → `claude-spt-bs v0.38.5`.

## [0.5.0] - 2026-09-06

> Requires spt-core **v0.67.0 or newer** (unchanged) and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints (`spt endpoint stop <id>` → `spt endpoint start <id>`, or `spt go <id>` to attach) so they load the refreshed extension.

### Added
- **A sealed message arrives with its seal shown and the proof named.** When a delivery's envelope carries `seal="<token>"` (a wax seal — a proven user directive), the extension renders an `[spt] SEALED by <sender> — seal=<token>` note ahead of the envelope that names `spt api seal verify <token>` (the delivered body on stdin; `BOUND` is the proof) and `spt api seal describe <token>`. The note is additive: the envelope and its attribute still ride verbatim, and nothing in the adapter branches on the seal — it is a citation the agent proves, never an authorization the adapter grants. The startup brief teaches the same.
- **Your standing monic notes on a sender arrive ahead of their message.** When the receiving node matched your monics on the sender (the envelope's `mnemonics-json` attribute), each matched record renders as `[spt] Your standing note on <sender> (monic "<id>"): <text>` before the envelope, on both delivery surfaces (the listener splice and the boundary poll). A value that does not parse renders one "unreadable" line while the raw attribute still rides. KNOWN-HAZARDS #13 records the structural rule that makes these notes forgery-proof: genuine `[spt]` notes sit before the `<EVENT` opening tag and never inside the envelope, so a peer body that imitates the marker stays inside the peer's frame; the brief says so.
- **Packaged knock skill.** `omp-spt` now ships a `knock` skill teaching spt's published access-control grammar: bare `spt knock <target>` is `send` and asks for `MSG` by default; `send` and `redeem` require exactly one of `--send-only` | `--send-receive` (the asking side declares direction; `approve` and `new-code` take no such flag; `--mutual` / `--one-way` are parse errors); `--send-only` never bars replies; approving opens nothing in reverse, so knock back; invite codes are sealed to a subnet and `--subnet` narrows who can redeem; `--monic` imparts a standing note on approve or new-code; the inbox is quiet, so look with `spt knock list`. A manifest `[[hints]]` row surfaces the skill on knock intent, and the brief points at it.

### Changed
- **Parity matrix:** sister rows 0.26.0 / 0.26.2 / 0.28.1 / 0.30.0 (knock skill, monic note ahead of the message, sealed message shown) are now covered; baseline advanced to `omp-spt v0.5.0`.

## [0.4.0] - 2026-09-06

> Requires spt-core **v0.67.0 or newer** (unchanged) and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints (`spt endpoint stop <id>` → `spt endpoint start <id>`, or `spt go <id>` to attach) so they load the refreshed extension.

### Added
- **Your turn's text now reaches Spacetime's IO feed.** The extension reports the user's prompt as `USER_INPUT` on the busy transition, every completed assistant message as a mid-turn `AGENT_OUTPUT` span (immediately when the message ends in a tool call, so a peer you name never waits on a long command), and the closing message on the idle transition — each exactly once, on stdin, through `spt api state --payload-stdin`. A turn a peer's message woke reports no `USER_INPUT` (that body is already Spacetime's `MSG_IN`), and a failed report is logged rather than failing the turn. Shells and other consumers can now read your session's events through `spt api io-events`.
- **The now-signal is injected at every boundary.** At turn start (with your words) and at every in-turn context boundary (with the assistant's words since the last poll), the extension polls `spt api now-signal --spec-manifest` and injects whatever changed: peers you named, monics that fired, the last message each way, on/offline edges, the versions in play, and the outcome of every shortform dispatch and seal mint. It is delta-only, so a quiet boundary adds nothing; a failed poll is a soft comms fault (status shows `comms recovering`, one warning) and never a broken turn.

### Changed
- **`@<…@>` and `;;…;;` are read by Spacetime, not by the adapter.** The manifest declares `[io] compliance = true` and the adapter's own shortform parser is gone in the same release (KNOWN-HAZARDS #12: a compliant manifest with a local parser still shipping would fire every tag twice). A shortform in an early message of a tool-heavy turn is dispatched too, not just one in the closing text; seals now mint from inside a turn. Outcomes arrive **only** in the now-signal's `DISPATCH_RESULTS` — nothing echoes back and no confirmation line prints, so silence in the same turn does not mean unsent; the startup brief says so and tells the agent never to resend on that basis. An unpaired `;;` mid-turn is refused as `SEAL_BARE_MIDTURN`.
- **Targeted hints are manifest `[[hints]]`.** The same five hints (live activation, identity, messaging, subnet, checkpoint) now live in the manifest as regex keywords and surface once per session through the now-signal's `HINTS` category instead of an adapter-local matcher. `spt adapter hints omp-spt` lists them.
- **The adapter no longer probes for updates itself.** The spt-core and omp-spt versions you run arrive through the now-signal's `UPDATES` category the first time you see them and again whenever they change; `spt update` and `spt adapter update omp-spt` remain the way to move. The `omp-spt-update-notice` message and its GitHub release probe are gone.
- **Parity matrix:** sister releases 0.32.0–0.36.0 are now covered and 0.38.3 is triaged (N/A); baseline advanced to `claude-spt-bs v0.38.3`.

## [0.3.33] - 2026-09-06

> Requires spt-core **v0.67.0 or newer** (raised from v0.39.1 — see below) and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints (`spt endpoint stop <id>` → `spt endpoint start <id>`, or `spt go <id>` to attach) so they load the refreshed extension.

### Changed
- **The bringup commands this adapter teaches now follow spt-core's lifecycle split.** spt-core v0.67.0 retired the all-in-one `spt endpoint run` (it now refuses with `ENDPOINT_RUN_RETIRED` and names the replacements). Everything the adapter tells you — the setup skill, the post-update notice, the quickstart, the integration contract, and the acceptance steps — now says `spt endpoint create <id> --adapter omp-spt` to mint an endpoint and bring its first session up, `spt go <id>` to attach its native OMP TUI (and, on a later run, to resume or start whatever the endpoint's state needs), `spt endpoint start <id>` for a fresh session on an existing endpoint, and `spt endpoint resume <id>` for its latest session back. The packaged-skills gate probes those live verbs instead of the retired one, and the manifest guard refuses a manifest that still names it. Because none of those verbs exist on older cores, this adapter now declares spt-core v0.67.0 as its floor: an older node refuses the install or update with that reason rather than shipping guidance its own `spt` cannot run.
- **Parity pass against claude-spt v0.25.1 → v0.38.2.** The sister adapter published 56 releases since this adapter's last recorded comparison point. Each was triaged as already covered here, not applicable to a native OMP host, a deliberate divergence, or a gap to close; `docs/PARITY.md` carries the matrix and the phased plan that follows (situational-awareness feed and per-turn briefing, knock/seal/monic surface, provider usage-limit hold, then polish). This release changes no runtime behaviour beyond the lifecycle verbs above — it fixes the map before the next legs are built.
- **Acceptance notes stop warning about `spt ring` and state a version floor instead.** The July hazard (a ring from a perch-owning caller could adopt and delete that perch) was fixed in spt-core v0.46.0; the acceptance step now requires the host's installed `spt` to be at or above that version rather than forbidding the command.

### Added
- **A stranger's trust warning cannot be lost on the way into the turn.** spt-core now attaches a receiver-composed `trust-warning` attribute to a warning-eligible sender's own delivery envelope, and for that attribute being dropped is the failure. This adapter already hands the model the wire envelope verbatim (whole deliveries as the raw frame, chunked deliveries rebuilt from every head attribute), so nothing changes in what you see; the guarantee is now pinned as `REQ-HAZARD-ENVELOPE-ATTRIBUTE-PASSTHROUGH` with a unit test across the whole, chunked, and rendered paths (`docs/KNOWN-HAZARDS.md` #11).

## [0.3.32] - 2026-07-28

> Requires spt-core **v0.39.1 or newer** and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints so they load the corrected extension.

- Fixed: an activated session now reads its own durable mind. The adapter never called `spt api psyche-download`, so the role, cross-project live context, and project context that spt-core faithfully accumulates were written and never read back — every resumed session started blank and fell back to whatever static instructions its project happened to carry, and the blankness was self-reinforcing, because an echo-commune can only summarize the blank session it observed. Activation now pulls that mind (plus any commune or signoff drop not yet synthesized into it) and injects it ahead of the startup brief. The pull is authenticated with the bind token rather than a session id, so reading the mind can never re-pin the perch; `NO-CONTEXT` on a fresh endpoint injects nothing, other stderr is surfaced at error level, and a failed pull is reported without failing activation. Because promotion is activation on this adapter, one post-bind pull covers the fresh, resume, and go-live start paths (`REQ-PARITY-RESUME-CONTEXT`). An endpoint that has been running blind will resume thin at first — nothing accumulated while the pipe was disconnected.

## [0.3.31] - 2026-07-28

> Requires spt-core **v0.39.1 or newer** and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints so they load the corrected extension.

- Fixed: a delivered peer body now survives a tool-calling turn. The body was spliced into the first provider request only; OMP rebuilds every continuation request from its own store, where the delivery is just the `<msg from="peer"/>` stub, so an agent that called a tool before replying composed its answer from a context in which the message was empty and reported "your message arrived empty". Delivered bodies are now remembered per delivery signature and re-spliced (idempotently, bounded by count and bytes) into every later boundary that still shows their stub. This is the root cause behind the field ">400B bodies arrive empty" reports: size was a proxy for tool use, not the trigger (KNOWN-HAZARDS #10, `REQ-HAZARD-DELIVERY-BODY-DURABILITY`).

## [0.3.30] - 2026-07-26

> Requires spt-core **v0.39.1 or newer** and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints so they load the corrected extension.

### Changed
- **A dropped `<EVENT-PART>` reassembly group now logs at error level instead of debug.** A dropped group is a lost peer delivery — the hazard's bound demands a *loud* limit, but the breadcrumb shipped at debug verbosity in 0.3.25 and was invisible at default field log levels, which blinded the MODE-2 empty-inbound investigation on `hertz`. No behavior change to reassembly itself; the listener still stays alive. (KNOWN-HAZARDS §8, `REQ-HAZARD-LISTENER-EVENT-PART-REASSEMBLY`.)

## [0.3.29] - 2026-07-26

> Requires spt-core **v0.39.1 or newer** and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints (`spt endpoint stop <id>` → `spt endpoint run --adapter omp-spt --id <id>`) so they launch under the corrected shim.

### Fixed
- **A hosted endpoint no longer strands `ONLINE - HARNESS ONLY` when its daemon stops, and comes back up without a manual `spt endpoint stop`.** On Windows the launch shim spawned native Oh My Pi with no lifetime coupling: the extension's `spt api listen` relay child runs on its own hidden console, so an abrupt daemon death (a full `spt daemon stop`) orphaned the whole session tree alive; the surviving relay then reconnected to the next daemon, which found a relay claim with no broker session, demoted the endpoint to `ONLINE - HARNESS ONLY`, and refused every wake-spawn (`SPAWN_DEDUP`) until an operator stopped the endpoint by hand. The shim now joins a kill-on-close job object before Oh My Pi spawns (every descendant inherits membership, so killing the shim reaps the entire tree, relay included) and watches its parent daemon process, exiting — and thereby reaping the tree — the moment the daemon dies. Brain-only restarts (`spt daemon refresh`, self-update swaps) keep the parent alive and correctly do not bounce sessions. Unix keeps the exec path, where the broker's PTY teardown already owns the tree. (KNOWN-HAZARDS §9, `REQ-HAZARD-HOSTED-TREE-LIFETIME`.)

## [0.3.28] - 2026-07-25

> Requires spt-core **v0.39.1 or newer** and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints so they load the corrected extension.

### Fixed
- **The first peer message to reach a freshly started endpoint no longer arrives without its body.** A peer's message wakes the turn with a small `<msg from="…"/>` stub and the real body is spliced in at the next context boundary; the adapter holds custody of that body until a real model turn has actually carried it. When the stub's submission to Oh My Pi had not settled yet, that hold was handed to the next provider request without recording whether the boundary belonged to a real turn — and on a fresh session Oh My Pi settles the very first submission only when the turn ends, so the startup digest's own non-turn request looked like proof of delivery and consumed the body. The agent then saw a bare `<msg from="doyle"/>` frame, answered as though the peer had sent nothing, and no resubmission followed because custody was already spent (the sender's body survived only in the raw `owl_message`/digest). Custody now travels with the turn proof from the boundary that injected it, so a non-turn request leaves the message pending and the next real turn delivers it. Later messages in an established session were never affected.

## [0.3.27] - 2026-07-25

> Requires spt-core **v0.39.1 or newer** and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints so they load the corrected extension.

### Fixed
- **Peer messages composed with the `@<target … @>` shortform no longer drop backtick-quoted text.** When a message wrapped an identifier, command, or path in Markdown backticks (or a fenced code block), that quoted text was silently replaced with blank spaces before the message was sent — producing blank mid-sentence gaps and, in one observed case, an empty parenthetical where a quoted commit id belonged. To find the `@<…@>` delimiters the parser masks Markdown code spans (so a backticked `@<` is not mistaken for a real shortform), but it was then reading the delivered body from that masked copy instead of the original text. The body is now read from the original text at the same positions, so backticks, fenced blocks, and even a literal `@>` inside a code span are delivered verbatim. Backtick-free messages were never affected. Existing endpoints pick this up on their next restart.

## [0.3.26] - 2026-07-25

> Requires spt-core **v0.39.1 or newer** and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints so they load the corrected extension.

### Fixed
- **A normal idle/busy timing blip no longer looks like a communications failure.** Each time a turn starts or ends, the extension publishes the endpoint's new activity state to spt-core, and that publish is asynchronous — so activity can legitimately flip again (idle→busy or busy→idle) while a publish is still in flight. The old code treated the now-stale publish as a fault: it raised a "comms recovering" warning on the endpoint's status line and scheduled a backoff retry, even though nothing had actually failed and the correct routing state was one immediate re-publish away. On an active endpoint this surfaced as a recurring, alarming TUI warning for a wholly benign race. The state publisher now reconciles this case quietly — on detecting that activity moved during a publish it immediately re-publishes the current desired state with no warning and no backoff — while genuine publish failures stay loud and still drive the visible recovery retry ladder. Existing endpoints pick this up on their next restart.

## [0.3.25] - 2026-07-24

> Requires spt-core **v0.39.1 or newer** and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints so they load the corrected extension.

### Fixed
- **A large inbound message no longer makes an endpoint go silently deaf to every message after it.** spt-core splits an oversized delivery into `<EVENT-PART>` continuation frames that the receiver must reassemble; the extension never implemented reassembly. Because `<EVENT-PART>` shares the `<EVENT` prefix, the drain matched it as a normal frame it could never close, wedged its buffer, and silently swallowed every following message — with no error and no visible fault — until a much later buffer-limit failure. In practice the first big payload to cross the size threshold (typically a live agent's echo-commune summary) tripped it: the endpoint answered the first message or two, then went quiet while `spt send` still reported delivery and the message still reached the digest. The listener drain now reassembles `<EVENT-PART>` frames into their original message (concatenating fragments and decoding once, so bodies split mid-escape stay intact), keyed by group id so interleaved and out-of-order parts are handled, and an incomplete or malformed group is dropped with a diagnostic breadcrumb instead of wedging the stream. Existing endpoints pick this up on their next restart.

## [0.3.24] - 2026-07-23

> Requires spt-core **v0.39.1 or newer** and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints so they load the corrected launch environment.

### Fixed
- **The window title's idle glyph and animated busy spinner work again.** Oh My Pi 17 changed its RPC-hosted behavior: it now disables window-title updates by default and drops the extension's `setTitle` requests unless the host opts in with the `PI_RPC_EMIT_TITLE=1` environment variable. spt-core hosts OMP over RPC, so on OMP 17 the idle `○` at session start and the braille busy spinner on each turn silently stopped appearing. The launch now sets `PI_RPC_EMIT_TITLE=1` for the hosted OMP process, restoring both. Existing endpoints pick this up on their next restart.

## [0.3.23] - 2026-07-23

> Requires spt-core **v0.39.1 or newer** and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints so they load the corrected extension.

### Fixed
- **A message delivered to a freshly-started endpoint no longer lands in the digest without ever waking a turn.** Native delivery injects a peer envelope at an OMP `context` boundary, and the extension treated any such boundary as proof of delivery — consuming the message from its pending queue. But OMP fires `context` at boundaries that need not reach the model (ACP-hosted hidden-turn deferral; ADR-0017: a boundary "without guaranteeing another model continuation"), and a session at the very start with no user input assembles exactly such an off-turn context (its idle/startup digest). That off-turn boundary swallowed the message and, worse, **disarmed the v0.3.20 delivery-liveness watchdog** by emptying the pending queue — so the deaf-session safety net never fired and the peer never got an answer. The context hook now consumes custody only during a **real turn** (`agent_start`, or `before_agent_start`'s busy intent); an off-turn boundary may inject for visibility but leaves the delivery pending, so a real turn — or the watchdog's resubmit → self-heal → close ladder — still delivers it. Closes the residual gap in the #10 liveness work exposed at a fresh-session bring-up.

## [0.3.22] - 2026-07-23

> Requires spt-core **v0.39.1 or newer** and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints so they load the corrected extension.

### Fixed
- **Checkpoint/commune no longer fails forever after a long uptime.** The adapter kept its per-endpoint environment snapshot in a project-directory-relative location that, on the daemon-respawn path, resolved under a temporary directory. On Linux, `systemd-tmpfiles` reaps `/tmp` after ~10 days, deleting the snapshot; every later echo-commune and Psyche turn then failed with `endpoint environment unavailable` and looped. The snapshot now lives in a durable per-user state directory (honoring `OMP_SPT_STATE_DIR`, then the platform's local-app/`XDG_STATE_HOME`/`~/.local/state`), so it survives temp-dir reaping. A missing snapshot now also self-heals: it is regenerated from the current environment instead of failing every turn. Existing endpoints pick this up on their next restart.

## [0.3.21] - 2026-07-23

> Requires spt-core **v0.39.1 or newer** and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints so they load the corrected extension.

### Fixed
- **Peer message bodies no longer arrive empty when OMP echoes the delivery stub non-verbatim.** Native delivery wakes a turn with a self-closing `<msg from="peer"/>` stub and splices the real body in at the context boundary. The splice matched the stub byte-for-byte, so any echo-format drift on a newer Oh My Pi (leading whitespace, surrounding text, `<msg .. />` / `<msg></msg>` re-serialization) missed the match and dropped the body — the agent saw an empty frame while the text survived only in the raw digest. The boundary now matches on the stub's delivery identity (`from` plus the `delivery` correlation ordinal), so a body is never silently dropped by echo drift and distinct same-peer deliveries stay correlated. Distinct from the v0.3.20 liveness watchdog: the stub still triggered a turn, so the session was never deaf.

## [0.3.20] - 2026-07-23

> Requires spt-core **v0.39.1 or newer** and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints so they load the corrected extension.

### Fixed
- **Deaf sessions close instead of staying silently ONLINE.** Daemon-restart autostart replay could spawn sessions whose bring-up looked healthy (bind, token, listener) but whose accepted deliveries never entered an agent turn (#10). The extension now enforces delivery turn liveness on every spawn path: a message stranded on an idle session past the liveness deadline is force-resubmitted (a hung in-flight submission cannot wedge recovery), then the degraded ` · comms recovering...` rail surfaces, and on continued deafness the endpoint fails closed — pending custody is released with failure outcomes, the SPT session ends, and the hosted TUI shuts down so daemon lifecycle or the operator brings up a fresh, working session.
- **Stale endpoint-state cache is invalidated on listener death.** A restarted daemon can hold persisted activity state that no longer matches the extension's cache; the next publication after a listener death now republishes current truth instead of being skipped as already-current.

## [0.3.19] - 2026-07-23

> Requires spt-core **v0.39.1 or newer** and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints so they load the corrected extension.

### Fixed
- **Detached idle endpoints retry messages that OMP assembles without running.** Listener custody now settles at `before_provider_request`, not merely when a context hook inserts the envelope. If OMP completes an extension prompt after context assembly without issuing a model request, the still-custodied message is resubmitted as a fresh turn instead of remaining hidden in the previous completed turn.

## [0.3.18] - 2026-07-22

> Requires spt-core **v0.39.1 or newer** and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints so they load the corrected extension.

### Fixed
- **Repeated messages from one sender retain one-to-one envelope custody across active turns.** Successive sender stubs now carry a per-sender delivery correlation, so a later context hook cannot attach a new envelope to the earlier request-local stub and leave the queued turn bare. This completes v0.3.17's atomic wake arbitration fix for the same-peer boundary case.

## [0.3.17] - 2026-07-22

> Requires spt-core **v0.39.1 or newer** and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints so they load the corrected extension.

### Fixed
- **Messages arriving at the end of a turn reliably wake the endpoint.** Listener delivery now delegates idle-versus-streaming arbitration atomically to OMP instead of selecting an explicit non-triggering steer from an `isIdle()` snapshot. A stream that ends between the snapshot and submission can no longer strand peer or operator messages as hidden context in the completed turn.

## [0.3.16] - 2026-07-21

> Requires spt-core **v0.39.1 or newer** and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints so they load the corrected extension.

### Fixed
- **Repeated messages from the same peer attach to the current turn after resume.** Envelope correlation now targets the newest matching sender stub instead of an orphan stub retained in older conversation history, preventing a reply from opening a bare `<msg>` turn while its full SPT event is injected into the past.
- **Detached broker-hosted sessions remain controllable.** The minimum spt-core version is now v0.39.1, whose published bind/listen sequence preserves broker hosting authority instead of rendering a live session as `ONLINE - HARNESS ONLY`.

## [0.3.15] - 2026-07-21

> Requires spt-core **v0.31.0 or newer** and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints so they load the corrected extension.

### Fixed
- **Idle resumed sessions wake for peer messages even when OMP omits a prior completion hook.** Listener dispatch now asks OMP for its authoritative current idle state instead of trusting cached lifecycle flags. Active turns still receive non-triggering native steering, while an actually idle resumed session starts an ordinary turn.

## [0.3.14] - 2026-07-19

> Requires spt-core **v0.31.0 or newer** and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints so they load the corrected extension.

### Fixed
- **Active listener messages no longer schedule a duplicate follow-up turn.** Native steering now explicitly disables turn triggering while an OMP turn is active. The message still enters the current model continuation through the context hook, but the same sender stub is not replayed as a second ordinary prompt after that turn ends.

## [0.3.13] - 2026-07-19

> Requires spt-core **v0.31.0 or newer** and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints so they load the corrected extension.

### Fixed
- **Busy messages now follow spt-core's published active-delivery contract.** The manifest declares OMP's hook injection channel, each active context boundary publishes `busy` before authenticated `api poll --include-deferred`, and polled envelopes enter model context without adding an adapter panel to the TUI.
- **Listener and poll delivery remain independent.** Live-listener arrivals use OMP's native user-message steering as they arrive; active-only messages remain in spt-core custody until the next real context boundary. The adapter no longer invents a cross-channel queue or ordering claim.
- **Communication failures no longer kill healthy local OMP work.** Listener exits retry indefinitely with capped backoff, state publication converges on the newest OMP activity, and polling retries only at later context boundaries. The cyan endpoint identity gains a warning-styled ` · comms recovering...` suffix until every failed channel recovers.

## [0.3.12] - 2026-07-19

> Requires spt-core **v0.31.0 or newer** and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints so they load the corrected extension.

### Fixed
- **Endpoint activation no longer fails while coloring the inline identity.** OMP's theme API exposes semantic palette keys rather than a literal `cyan` key. The footer now uses `statusLineModel`, the cyan status-line role, after v0.3.11's literal key caused `Unknown theme color: cyan` during bind.

## [0.3.11] - 2026-07-19

> Requires spt-core **v0.31.0 or newer** and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints so they load the corrected extension.

### Fixed
- **Messages received while an agent is working now reach the model.** Active-turn delivery uses OMP's native user-message steering queue before the context hook expands the inert sender stub into the full SPT envelope. The former context-only injection could write an `owl_message` into OMP history after an ACP request was already assembled, making the delivery visible in history but absent from model context.
- **A local prompt can no longer overtake queued peer custody at turn completion.** The next accepted delivery is submitted synchronously before the completed turn releases its lifecycle hook.
- **Shortform delivery no longer adds an internal `omp-spt-peer-status` panel to the transcript.** Explicit `@<…@>` sends remain bounded and ordered without adding adapter-internal result messages to the TUI.
- **The inline endpoint identity is explicitly cyan.** The status renderer now requests the theme's `cyan` color rather than its theme-dependent `accent`.
- **Busy window-title animation is calmer.** Spinner frames advance every 500 ms instead of every 80 ms.
- **Graceful shutdown clears durable session state before spending time reaping the listener.** Authenticated `session-end` now precedes listener termination, reducing the chance that a bounded shutdown leaves stale online state. Abrupt process or machine death still requires spt-core's owner-death reconciliation because no in-process adapter callback can run after its host has disappeared.

## [0.3.10] - 2026-07-19

> Requires spt-core **v0.31.0 or newer** and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints so they load the corrected extension.

### Fixed
- **ACP-hosted endpoints wake for deferred peer deliveries again.** Deferred custody now enters OMP through the native user-prompt flow. OMP 17 defers extension-initiated hidden turns under an ACP client, so v0.3.9's `nextTurn` trigger could queue a message without starting the receiving agent.
- **Inbound context is easier to identify and read.** The obsolete internal `omp-spt-peer-message` custom-message identifier is gone, and complete `<EVENT>` envelopes place their body on lines between the opening and closing tags.
- **The inline endpoint identity is cyan again.** Status styling now uses OMP's theme API instead of raw ANSI escapes that the status renderer discarded.

## [0.3.9] - 2026-07-19

### Fixed
- **Deferred peer deliveries now wake the receiving OMP session reliably.** Accepted messages use OMP's hidden next-turn channel with an explicit turn trigger, preserving the full SPT envelope without depending on the editable follow-up queue to resume after an active or interrupted turn.

## [0.3.8] - 2026-07-19

> Requires spt-core **v0.31.0 or newer** and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints so they load the corrected listener and session identity.

### Fixed
- **Incoming messages containing quoted SPT events no longer shut the endpoint down.** The listener now preserves complete `<EVENT>…</EVENT>` text inside a peer message, while incomplete frames remain bounded and fail closed. Deferred messages also use OMP's follow-up queue so a streaming-state race cannot silently lose them.
- **The inline OMP status now shows the complete endpoint identity.** The footer reads `<endpoint-id> @ <node> (<project-name>/)` in cyan instead of `spt:<endpoint-id>`, matching the session and terminal-window naming introduced in v0.3.7.

## [0.3.7] - 2026-07-19

> Requires spt-core **v0.31.0 or newer** and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints so they load the new title behavior.

### Added
- **Hosted OMP windows identify themselves at a glance.** Session names now use `<endpoint-id> @ <node> (<project-name>/)`. Terminal titles add `○` while idle and cycle a braille spinner while busy, then return to idle without leaking a timer.

## [0.3.6] - 2026-07-19

> Requires spt-core **v0.31.0 or newer** and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints so they load the corrected extension.

### Fixed
- **Assistant output stays inside the local OMP conversation.** This release republishes the v0.3.5 behavioral fix from a corrected release commit; runtime behavior is unchanged.

## [0.3.5] - 2026-07-19

> Requires spt-core **v0.31.0 or newer** and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints so they load the corrected extension.

### Fixed
- **Assistant output now stays inside the local OMP conversation.** Receiving a peer message no longer forwards subsequent assistant prose, errors, or shutdown text back to that peer. Outbound messages occur only when the agent or operator explicitly uses `spt send` or the `@<…@>` peer-message shortform, restoring `claude-spt` behavioral parity.

## [0.3.4] - 2026-07-16

> Requires spt-core **v0.31.0 or newer** and Oh My Pi **v16.3.15 or newer**. Update with `spt adapter update omp-spt`, then restart existing endpoints so they load the new extension and skills.

### Added
- **An ordinary OMP session can now become a ready or live SPT endpoint in place.** Native `/ready` and `/live` commands select or create endpoint identity, while `/live --auto` offers the most-recent compatible live identity for explicit confirmation; the extension owns the listener, so the agent never has to run a background poll.
- **Live endpoints stay reachable during long turns and after interrupted work.** Accepted peer messages enter at the next safe tool or model boundary, retain ordered custody when no boundary appears, and restore honest receivability after cancellation, interruption, or failure.
- **OMP now ships native commune, signoff, role, and setup skills.** Commune includes an OMP-native checkpoint mode that saves continuity, compacts context, and wakes the same endpoint; setup diagnoses versions, activation, GitHub transport, and subnet onboarding.
- **Activated sessions now teach the SPT surface directly.** Startup guidance, targeted hints, and compatible-update notices cover identity, roster, messaging, lifecycle, continuity, versions, and subnet operations without duplicating public `spt` commands as skills.
- **Assistant output can send peer messages with `@<target[,target] message @>`.** The extension dispatches only the explicit shortform, excludes code blocks and ordinary mentions, and reports each target's delivery result.
- **The release now includes a static Linux x86-64 musl helper compatibility tier.** Windows MSVC, GNU Linux, and static-musl Linux helpers ship together in one deterministic `adapter.spt`.

### Fixed
- **Hosted messaging no longer tears down the listener when a peer reply mentions `<EVENT>` literally.** The frame parser tolerates non-frame `<EVENT>` text inside a message while still rejecting a genuinely nested valid frame, and decodes both published `<br/>` and legacy `<br>` newline forms.

### Changed
- **Release truth is now mechanically enforced.** The manifest version drives helper, plugin, changelog, and public-doc versions; deterministic documentation drift checks gate GitHub Pages publication; each supported target has schema-validated, digest-bound native acceptance evidence.

## [0.2.1] - 2026-07-15

> Requires spt-core **v0.31.0 or newer** for identity-preserving listener authentication. Run `spt update`, then `spt adapter update omp-spt`, and restart each endpoint.

### Fixed
- **Starting or resuming an endpoint now records exactly one OMP session in endpoint history.** The listener continues from the already-bound native OMP session instead of registering a second synthetic `boot` session, so resume selection and session metadata remain tied to the real OMP transcript.

## [0.2.0] - 2026-07-14

> Native OMP cutover. Requires spt-core **v0.29.0 or newer** and Oh My Pi **v16.3.15 or newer**. If OMP is older, run `omp update` before launching an endpoint. Update the adapter with `spt adapter update omp-spt`, then restart each endpoint so it loads the packaged extension and helper from this release.

### Added
- **Every endpoint now remains a real, attachable OMP session.** Ready and live endpoints use the same native OMP launch path, so an unattended endpoint can still be attached later without losing OMP's normal terminal interface.
- **Inbound peer messages now arrive as ordinary OMP turns with full SPT context.** The visible prompt is a safe sender stub, while the complete event envelope is supplied to that turn as context; peer text cannot accidentally invoke a slash command.
- **OMP profile-aware session tools.** History, digest, echo-commune, and Psyche session lookup now follow OMP's profile and configuration precedence, including deterministic exact-id and prefix handling.

### Changed
- **The adapter is now OMP-native only.** The inherited Claude Code plugin, hooks, CCS profiles, worker topology, headless RPC bridge, and message-idle translation path are removed. `omp-spt` advertises ReadyAgent and LiveAgent only; Worker remains an intentional capability opt-out.
- **Fresh, resumed, and daemon-driven turns validate the real Oh My Pi executable before launch.** Explicit overrides, known install paths, and PATH candidates all receive the same identity probe, so an unrelated `omp` command cannot become the hosted terminal.
- **One endpoint stays bound to one OMP session for its lifetime.** In-TUI new, resume, fork, handoff, and branch actions are blocked; stop and relaunch the endpoint to select another native session.
- **Commune and signoff drops now live under the project-local `.spt/` directory.** The old harness-specific continuity path is no longer used.

### Fixed
- **Accepted messages cannot disappear after an outbound reply failure.** Correlated outcomes retry within a finite budget; exhaustion shuts the endpoint down loudly instead of marking undelivered custody as settled.
- **Bind, activity, and shutdown races no longer advertise the wrong endpoint state or leak a late listener.** Busy-before-bind is preserved, shutdown-before-bind tears down immediately, and concurrent fatal and lifecycle shutdowns share one bounded session-end sequence.
- **Listener recovery now distinguishes crash loops from isolated failures.** Immediate repeated exits still fail closed, while a listener that remains stable resets its consecutive-failure budget.
- **Echo-commune handles Unicode transcript boundaries safely.** A byte cap that lands inside a multi-byte character no longer crashes the summarizer.

## [0.1.3] - 2026-07-13

### Fixed
- **Attached endpoints now show OMP's full native TUI.** Native `omp` is the broker PTY process, with SPT messaging supplied by a packaged OMP extension. The previous headless `omp --mode rpc` bridge could only display bridge logs, regardless of whether the endpoint command attached to its PTY.

## [0.1.2] - 2026-07-10

> Liaison bugfix rollup for the two Reavo-reported omp-spt v0.1.1 issues ([#2](https://github.com/BigscreenVR/omp-spt/issues/2), [#3](https://github.com/BigscreenVR/omp-spt/issues/3)). Requires spt-core **v0.27.0 or newer** (unchanged). Update: `spt adapter update omp-spt`, then restart omp endpoints.

### Fixed
- **The fresh-endpoint update guidance now keeps the harness terminal attached.** The update notice no longer tells operators to use `--start` for a new Librarian endpoint; the documented command uses attach-default `spt endpoint run --adapter omp-spt --id <id> --create`, so the bringup log (`bridge starting`, `omp ready`, `bound`, `listening`, `READY`) is visible instead of launching silently in the background.
- **Adapter updates now use the authenticated GitHub CLI transport.** The repository is currently public, but the release fetch path is now auth-capable via `gh`, so a private or visibility-flipped repo can still discover and download `adapter.spt` through the user's existing GitHub authentication.

## [0.1.1] - 2026-07-09

> Hardening release, driven by a maintainer field report of a wedged endpoint (thanks doyle — [#1](https://github.com/BigscreenVR/omp-spt/pull/1)). Requires spt-core **v0.27.0 or newer** (unchanged). Update: `spt adapter update omp-spt`, then restart your omp endpoints.

### Changed
- **The endpoint process is now named `omp-spt`** (was `claude-spt`), so a task list tells you at a glance which adapter a process belongs to — no more misdiagnosing an omp endpoint as a Claude Code one.

### Fixed
- **Stopping an endpoint no longer leaves orphans.** The bridge now ties its omp and listener children to its own lifetime at the OS level: however the bridge dies — a stop, a crash, a hard kill — the whole tree goes down with it, and the perch is unregistered on the way out instead of advertising a dead endpoint as listening.
- **A silent endpoint is now a diagnosable endpoint.** The attached terminal shows live operational output by default: bringup steps, one line per message in and reply out, every delivery/registration failure, and a periodic idle heartbeat — a working, idle, and broken endpoint each look different now.
- **A hung bringup or turn can no longer wedge the perch forever.** Startup is bounded (a wrong or stalled `omp` fails loudly before the endpoint registers, so a failed bringup can't trap the endpoint on this adapter), and each turn has a deadline — on breach the perch recovers to idle and the sender is told the turn failed instead of receiving silence or an empty reply.
- **A dead omp process is noticed immediately** (and the endpoint shuts down cleanly), not on the next message.

## [0.1.0] - 2026-07-09

> First release of **omp-spt**: host an [oh-my-pi (omp)](https://github.com/can1357/oh-my-pi) coding agent as a reachable spt endpoint. Requires spt-core **v0.27.0 or newer** and an installed `omp` CLI. Install: `spt adapter add --release BigscreenVR/omp-spt`.

### Added
- **Host omp as an spt endpoint.** `spt endpoint run --adapter omp-spt --id <id>` brings up a reachable omp agent: a message sent to its perch becomes an omp turn, and the answer goes back to the sender. Ask from anywhere on the subnet with `spt ring <id>`.
- **Conversation memory across messages.** The endpoint holds one omp session for its lifetime, so follow-ups continue the same conversation; resuming an endpoint reloads its prior session.
- **Session digest.** `spt endpoint digest <id>` shows the endpoint's conversation as it happens — prompts, replies, and the tools omp used.
- **Live-agent lifecycle.** A live omp endpoint gets a Psyche companion that carries its context across resets, and a session that ends without a signoff is auto-summarized so its context delta is kept anyway.
- **OpenRouter billing guide.** `docs/OMP-OPENROUTER.md` covers routing the endpoint's model spend through OpenRouter using omp's own provider config — nothing to configure in the adapter itself.

### Changed
- **The adapter drives omp natively.** Unlike the Claude Code lineage it forked from, omp-spt talks to omp over omp's built-in control protocol: bringup is a single bridge process, with no hook or plugin installation inside the agent, and none of the injection limits that came with hook-based delivery.
- **The skills namespace is `/omps:*`** (was `/sptc:*` in the lineage): setup, ready, live, send, commune, signoff, subnet, list-agents, force-stop, version.

## [0.17.3] - 2026-07-08

> Requires spt-core **v0.27.0 or newer** (unchanged). **Binary-only** — `spt adapter update claude-spt` is the whole update. Takes effect on an endpoint's next start.

### Fixed
- **The message shortcut no longer cries "not delivered" when it actually delivered.** Sending with `@<peer …@>` would tell you the peer "wasn't reachable" even though the message had arrived — so you'd needlessly re-send by hand. The delivered/not-delivered confirmation is now correct. (Messaging to yourself was never affected.)

### Changed
- **Communes now file project detail under the project, not your permanent identity.** When you commune (or when a session is auto-summarized), detail specific to the project you're in is kept separate from your cross-project, standing context — so your durable memory stays clean and project notes don't bleed between projects. Wrap project detail in `<project-context>…</project-context>` and identity/role context in `<live-context>…</live-context>`; anything left untagged is treated as standing context.

## [0.17.2] - 2026-07-08

> Requires spt-core **v0.27.0 or newer** (unchanged). **Binary-only** — `spt adapter update claude-spt` is the whole update. Takes effect on an endpoint's next start.

### Fixed
- **A message shortcut written as the last thing in a reply now actually sends.** Previously, if the `@<…@>` tag (or a `>>commune<<`) was the very last output of a turn — the normal "fire it off and wait for a reply" case — it wasn't delivered until you next did something, so a send-then-wait could hang. It's now delivered the moment the turn ends, for both live and daemon-hosted agents. Tags written mid-reply were unaffected and still work.

## [0.17.1] - 2026-07-08

> Requires spt-core **v0.27.0 or newer** (unchanged). **Binary-only** — `spt adapter update claude-spt` is the whole update. Takes effect on an endpoint's next start.

### Fixed
- **The message shortcut no longer fires when you're just *talking about* it.** In 0.17.0, writing an example of the `@<…@>` form in a reply — even wrapped in backticks — could actually send it. Now a tag only sends when written plainly; any tag inside inline-code (backticks) or a code block is treated as a quotation and ignored. Write a real send bare; show an example in backticks.

## [0.17.0] - 2026-07-08

> Requires spt-core **v0.27.0 or newer** (unchanged). **Binary-only** for the feature — `spt adapter update claude-spt` is the whole update (the send-skill help note also refreshes if you reinstall the plugin skeleton). Takes effect on an endpoint's **next start** — restart (or re-launch) a daemon-launched endpoint to activate it on an already-running session.

### Added
- **Message another agent without leaving your train of thought — no shell command needed.** Write `@<alice hey, can you check the deploy? @>` anywhere in a reply and the adapter delivers "hey, can you check the deploy?" to `alice`, then tells you (in your next context) whether it landed or the agent wasn't reachable. Send to several at once with `@<alice,bob,carol …@>`. Only that exact `@<…@>` form sends, so you can still talk *about* the syntax without firing anything.
- **Save a working-context note the same way.** Start a message with `>>commune<<` and the rest becomes your commune (the context hand-off that survives a reset) — the same result as writing the commune file by hand, without the file step. Include `!!checkpoint!!` in it to also reset-and-rebuild your context from that note.

## [0.16.2] - 2026-07-08

> Requires spt-core **v0.27.0 or newer** (unchanged). **Binary-only** — `spt adapter update claude-spt` is the whole update. Note: this heal rides the endpoint's background delivery process, so it takes effect on an endpoint's **next start** — restart (or re-launch) a daemon-launched endpoint to activate it on an already-running session.

### Fixed
- **A daemon-launched endpoint interrupted with Esc no longer goes deaf.** Pressing Esc to interrupt a running turn — whether a tool was mid-flight or the agent was just thinking — used to leave the endpoint looking online while silently queuing every incoming message, sometimes for many minutes, until the next thing you typed flushed the backlog. The endpoint now notices it's sitting at an interrupted prompt and returns itself to ready-to-receive within ~15 seconds, so queued messages are delivered. To recover an already-stuck endpoint immediately, send it any message once it's back at an idle prompt, or restart it.

## [0.16.1] - 2026-07-08

> Requires spt-core **v0.27.0 or newer** (unchanged). **Binary-only** — `spt adapter update claude-spt` is the whole update; no plugin reinstall or `/reload-plugins` needed.

### Fixed
- **Follow-up to 0.16.0: the interrupted-turn recovery now actually takes effect on daemon-launched endpoints.** In 0.16.0 the recovery could silently fail to register (an ownership-check mismatch), so an endpoint interrupted mid-turn could still stop receiving. It now reliably marks the endpoint ready-to-receive again after an interrupt. Also adds a local diagnostic log (`hook-trace.log`, next to the adapter binary) recording endpoint lifecycle events, to make this class of issue observable.

## [0.16.0] - 2026-07-08

> Requires spt-core **v0.27.0 or newer** (unchanged). Binary + plugin skeleton change. **Two-part update:** `spt adapter update claude-spt` picks up the binary; the new failure hooks require the refreshed plugin skeleton — reinstall the `sptc` plugin and run `/reload-plugins` (or restart Claude Code) to activate them. **Recommended for anyone running daemon-launched Claude Code endpoints.**

### Fixed
- **A daemon-launched endpoint no longer goes deaf after an interrupted or errored turn.** Pressing Esc during a running tool, or a turn that ends with an API error (rate limit, server error), used to leave the endpoint looking online while silently queuing every incoming message instead of delivering it — until the next thing you typed happened to flush the backlog. The endpoint now returns to ready-to-receive the moment such a turn ends, so messages are delivered right away. Anything queued in the meantime is delivered as soon as it goes ready — nothing is lost. To recover an already-stuck endpoint immediately, send it any message once it's idle, or restart it.

## [0.15.9] - 2026-07-08

> Requires spt-core **v0.27.0 or newer** (unchanged). Binary + plugin skeleton change. **Two-part update:** `spt adapter update claude-spt` picks up the binary fix; the new idle notification requires the refreshed plugin skeleton — reinstall the `sptc` plugin and run `/reload-plugins` (or restart Claude Code) to activate it. **Recommended for anyone running daemon-launched Claude Code endpoints.**

### Fixed
- **A daemon-launched endpoint that hasn't taken a turn yet no longer silently swallows every message sent to it.** A freshly-launched endpoint (or one whose only input so far was a client-side command like `/login`, which never produces a full turn) was treated as permanently busy, so incoming messages were queued and never delivered — the endpoint looked online and healthy while receiving nothing. Endpoints are now marked ready-to-receive as soon as they start, and re-marked ready whenever they return to an idle prompt, so messages are delivered instead of piling up. Any messages that were queued this way are delivered as soon as the endpoint next goes idle — nothing is lost. To recover an already-stuck endpoint immediately, send it any message once it's idle, or restart it.

## [0.15.8] - 2026-07-07

> Requires spt-core **v0.27.0 or newer** (unchanged). Instruction-only change — `spt adapter update claude-spt` picks it up; no plugin skeleton change. Takes effect at the next endpoint launch; fully forward-safe on current spt-core and activates automatically once the matching spt-core release is deployed.

### Added
- **Opt-in delivery verification for messages injected into a session.** The adapter now enables spt-core's echo-verification belt for Claude Code sessions: because the Claude Code terminal re-renders text that is typed into it, spt-core can confirm an injected message actually landed. This is off by default in spt-core and the adapter now turns it on for Claude Code. It stays dormant on spt-core versions that don't yet support it and switches on by itself once a supporting spt-core is installed — no configuration and no forced upgrade.

## [0.15.7] - 2026-07-07

> Requires spt-core **v0.27.0 or newer** (unchanged). Binary change — `spt adapter update claude-spt` picks it up; no plugin skeleton change. Takes effect immediately after the update — no session restarts needed. Recommended for anyone who uses Claude Code's `/resume` on a daemon-launched endpoint.

### Fixed
- **Using Claude Code's `/resume` inside a daemon-launched endpoint no longer makes it silently unreachable.** When an endpoint launched by the spt daemon switched conversations with the in-app `/resume` command, its perch could quietly detach from the live session — the endpoint still looked healthy and running, but messages sent to it went nowhere and the failure was never surfaced. Resuming now re-attaches the perch to the resumed conversation correctly, and if the re-attach is ever rejected it is reported loudly instead of swallowed. If an endpoint got stranded this way, relaunching it without `/resume` restores delivery.

## [0.15.6] - 2026-07-07

> Requires spt-core **v0.27.0 or newer** (unchanged). Binary + instruction change — `spt adapter update claude-spt` picks it up; no plugin skeleton change. Takes effect immediately after the update — no session restarts needed.

### Fixed
- **A message whose delivery gets cut off mid-transmission can no longer vanish silently.** Previously, if an incoming message's delivery frame arrived truncated, it was quietly dropped — counted as delivered but never shown to the agent. Now the agent sees a clear marker with whatever partial content survived and a pointer to where the full message can be recovered, so a cut-off delivery is always visible instead of lost.

### Changed
- **Going live or ready in a daemon-launched session no longer starts a redundant listener.** A live agent or ready session that was launched by the spt daemon is already reachable through the broker — messages arrive on its turn automatically. Bringup now recognizes this kind of session and skips starting an extra in-session listener, which in that context could not receive anything anyway and only reported an error. Sessions you launch yourself are unaffected and still start their listener as before.

## [0.15.5] - 2026-07-07

> Requires spt-core **v0.27.0 or newer** (unchanged). Binary change — `spt adapter update claude-spt` picks it up; no plugin skeleton change. Completes the 0.15.4 Psyche repair for ccs-launched endpoints.

### Fixed
- **End-of-session summaries work for ccs-launched endpoints.** 0.15.4 fixed finding the session transcript, but the summarizer's own Claude run still failed for ccs-launched endpoints because it ran without the endpoint's ccs configuration (no auth). It now runs with the endpoint's own configuration, so end-of-session context capture works everywhere. Psyches affected by the earlier failures recover on their own at the next commune — no restart needed.

## [0.15.4] - 2026-07-07

> Requires spt-core **v0.27.0 or newer** (unchanged). Binary change — `spt adapter update claude-spt` picks it up; no plugin skeleton change. **Update urgently** — inter-agent messages received while an agent is mid-task are silently lost without it. After updating, wake any endpoint whose Psyche shows a hosting error.

### Fixed
- **Messages delivered while an agent is busy actually reach the agent again.** A message arriving while the receiving agent was mid-task was consumed but never shown — the sender saw a successful send, the receiver saw nothing, and the message was gone. Every agent was affected. Mid-task deliveries now surface reliably.
- **Psyches no longer shut down when a session's transcript can't be found.** The end-of-session summarizer (added in 0.15.2) treated a missing transcript as a fatal error, which after a few occurrences shut down the endpoint's whole Psyche — and it missed transcripts for every ccs-launched session because it looked in the wrong place. It now finds ccs session transcripts correctly, and when a transcript genuinely doesn't exist it records that fact and moves on instead of escalating.

## [0.15.3] - 2026-07-07

> Requires spt-core **v0.27.0 or newer** (unchanged). Binary change — `spt adapter update claude-spt` picks it up; no plugin skeleton change. Takes effect immediately after the update — no session restarts needed.

### Added
- **Agents on a perch are now steered to run long tasks in the background.** Previously, agents routinely ran subagents and long commands in the foreground, which made them unreachable for incoming messages until the task finished. Every perched turn now carries a reachability notice reminding the agent to use background execution, with an extra targeted reminder right before a subagent launches — so agents stay responsive while work runs. (Ported from the legacy owl plugin, where this notice existed for the same reason.)

## [0.15.2] - 2026-07-07

> Requires spt-core **v0.27.0 or newer** (unchanged). Manifest + binary change — `spt adapter update claude-spt` picks it up; no plugin skeleton change. **Update urgently if any live agents run on spt-core v0.27.0+** — agent checkpoints and communes are broken without it. Restart affected live agents once after updating.

### Fixed
- **Agent checkpoints and communes work again on spt-core v0.27.0+.** Newer spt-core asks the adapter to summarize a session's history whenever a session ends without a signoff (and when syncing a commune). The adapter didn't provide that summarizer, so after a few attempts spt-core gave up on the whole Psyche — checkpoints did nothing, communes stopped reaching the agent's tracked mind, and the endpoint showed a Psyche hosting error. The adapter now ships the summarizer, so end-of-session context is captured and checkpoints fire normally again.

### Added
- **Sessions that end without a signoff now keep their context.** When a live agent's session ends abruptly (closed window, crash, no `/sptc:signoff`), spt-core now gets a concise summary of what the session was doing, ingested into the agent's tracked mind — so the next session resumes with that context instead of losing it.

## [0.15.1] - 2026-07-06

> Requires spt-core **v0.27.0 or newer** (unchanged). Binary change — `spt adapter update claude-spt` picks it up; no plugin skeleton change. The same fix is also available as **v0.14.3** for nodes still on spt-core v0.25.0/v0.26.0.

### Fixed
- **A checkpoint's resume instruction can no longer get swallowed by the session-name restore.** Since 0.14.1, restoring the session name after a clear and delivering the checkpoint's resume instruction could occasionally collide: the resume text ended up inside the session's title, the agent never received it, and the session sat idle until someone noticed. The two now land as one carefully-paced delivery, so the name is restored and the resume instruction starts the agent every time. If an agent hit this, its session title contains the swallowed instruction — rename the session and resend the instruction to recover.

## [0.15.0] - 2026-07-06

> Requires spt-core **v0.27.0 or newer** (floor raised). Manifest + binary change — `spt adapter update claude-spt` picks it up; no plugin skeleton change. **Update spt-core first** (`spt update fetch` then `spt update apply`), then the adapter.

### Fixed
- **Subagent working perches no longer pile up as permanent offline entries.** Previously, every subagent an agent spawned left behind a dead worker perch that sat in your endpoint list forever and could never be cleaned up normally. With spt-core v0.27.0, worker perches now get proper names (like `flynn-w4` instead of a random hex string), stop cleanly when the subagent finishes, stay out of the default `spt endpoint list` view (pass `--workers` to see them), and any stragglers are reaped automatically within a day. If a worker can't be registered or stopped, the reason now appears in the session's hook log instead of failing silently.

## [0.14.2] - 2026-07-06

> Requires spt-core **v0.25.0 or newer** (unchanged). Manifest + binary change — `spt adapter update claude-spt` picks it up; no plugin skeleton change. **Update urgently if any live agents run on spt-core v0.25.0+** — their Psyches are broken without it.

### Fixed
- **A live agent's Psyche works again on spt-core v0.25.0+.** Since 0.14.0, every Psyche turn failed before it could start (a leftover reference to a setting the new Psyche lifecycle no longer provides), so a live agent's Psyche silently stopped producing context notes and resume briefs. The Psyche now runs its turns normally again. Recovery: update the adapter, then restart affected live agents once.

## [0.14.1] - 2026-07-05

> Requires spt-core **v0.25.0 or newer** (unchanged). Binary change — `spt adapter update claude-spt` picks it up; no plugin skeleton change.

### Fixed
- **Sessions keep their name across `/clear`.** Previously, running `/clear` (or an agent checkpoint, which clears internally) dropped the session's display name — the terminal lost its `<id> @ <node> (<project>/)` title and you could no longer tell at a glance which agent a window belonged to. The name is now automatically re-applied right after every clear, before the agent resumes work. Sessions started before this update keep the old behavior until they are restarted once.

## [0.14.0] - 2026-07-04

> Requires spt-core **v0.25.0 or newer** (floor raised). Manifest + binary change — `spt adapter update claude-spt` picks it up; no plugin skeleton change. **Update spt-core first** (`spt update fetch` then `spt update apply`), then the adapter; live agents started before the update should be restarted once.

### Changed
- **A live agent's Psyche no longer runs as a resident background process.** The Psyche now wakes for each update, handles it, and finishes — its memory carries over between wakes, so nothing about the Psyche experience changes. What does change is the failure surface: the whole class of problems that came from keeping a Psyche process alive — silent restart loops, a Psyche quietly dying and needing `/sptc:revive`, and the multi-subnet limitation called out in 0.13.4 where a Psyche couldn't hold its listener — disappears by design, because there is no longer a resident process to keep alive.
- **Psyches with a large accumulated context now start reliably on Windows.** A Psyche resuming with a big context could previously fail to launch on Windows due to a system limit on how much can be passed to a starting program. The context now travels a route without that limit.
- **Now requires spt-core v0.25.0 or newer** (up from v0.23.0). The new Psyche lifecycle is driven by spt-core from this release on; older spt-core versions cannot run it, so the requirement is a hard floor.

## [0.13.4] - 2026-07-04

> Requires spt-core **v0.23.0 or newer** (unchanged). Binary change — `spt adapter update claude-spt` picks it up; no plugin skeleton change.

### Fixed
- **A live agent's Psyche that can't establish its listening perch now fails visibly instead of silently restarting forever.** On machines that belong to more than one subnet, the Psyche's listener could be refused at startup in a way it mistook for a normal shutdown — so it quietly exited and got restarted every few seconds, indefinitely, wasting resources with no visible sign. That refusal now surfaces as a real, loggable fault. Note: on multi-subnet machines the Psyche still can't hold its listener until a matching spt-core improvement lands — its periodic context notes keep working either way; this change makes the condition observable instead of invisible.

## [0.13.3] - 2026-07-04

> Requires spt-core **v0.23.0 or newer** (unchanged; the full checkpoint experience needs **v0.24.0**). Binary change — `spt adapter update claude-spt` picks it up; no plugin skeleton change. **Supersedes v0.13.2 — update immediately if you took 0.13.2.**

### Fixed
- **v0.13.2 accidentally included an unfinished rework of how a live agent's Psyche runs, and it could quietly break a live agent's message delivery.** If your adapter is on 0.13.2, a freshly started live agent could stop being reachable for direct message delivery shortly after starting. 0.13.3 is the same release without that unfinished piece: it keeps the checkpoint follow-up submit fix and restores the proven Psyche behavior. Recovery: `spt adapter update claude-spt`, then restart any live agents started while on 0.13.2.

## [0.13.2] - 2026-07-04

> Requires spt-core **v0.23.0 or newer** (unchanged; the full checkpoint experience needs **v0.24.0**). Binary change — `spt adapter update claude-spt` picks it up; no plugin skeleton change.

### Fixed
- **The checkpoint's follow-up instruction now actually submits after the clear.** Previously the wake-up message could appear in the fresh session's input box with a stray blank line at the end and just sit there unsent — the automated keystroke that should send it was getting absorbed into the message text. The clear and wake-up steps now pace their keystrokes the same way normal message delivery does, so the follow-up sends reliably. Combined with the delivery fixes in spt-core v0.24.0, `/sptc:commune --checkpoint` now completes end-to-end.

## [0.13.1] - 2026-07-04

> Requires spt-core **v0.23.0 or newer** (unchanged). Binary change — `spt adapter update claude-spt` picks it up; no plugin skeleton change.

### Fixed
- **Clearing a live agent's context no longer silently breaks its message delivery.** Every time a live agent's session was cleared — by hand or as part of a checkpoint — the machinery that delivers incoming messages into the session could be shut down as collateral, and from then on messages quietly piled up unseen until the agent was restarted. Delivery now survives clears. This also removes the main reason a checkpoint's follow-up instruction (`/sptc:commune --checkpoint`) never appeared after the clear; a matching spt-core improvement that hardens the remaining cases is on its way.

## [0.13.0] - 2026-07-03

> Requires spt-core **v0.23.0 or newer** (floor raised). Binary change — `spt adapter update claude-spt` picks it up; no plugin skeleton change.

### Fixed
- **A live agent's Psyche can no longer get stuck in a silent restart loop.** If a Psyche's underlying session died instantly on every launch (for example, when its working folder isn't trusted yet), the Psyche used to relaunch several times a second, forever, with no visible sign — wasting resources and never recovering on its own. It now slows down between failed launches and, after several in a row, stops with a clear message so the system can notice and step in. Healthy Psyches are unaffected; a Psyche that recovers on its own resets and carries on.

### Changed
- **Now requires spt-core v0.23.0 or newer** (up from v0.20.0). The Psyche restart-loop protection works together with a matching safeguard that arrived in this spt-core release; `/sptc:setup` and `spt adapter update` keep you current.

## [0.12.1] - 2026-07-03

> Requires spt-core **v0.20.0 or newer** (unchanged). Manifest-only change — `spt adapter update claude-spt` picks it up; no plugin skeleton change.

### Fixed
- **A live agent's Psyche no longer risks mixing up its identity with another agent on the same machine.** The Psyche a live agent runs alongside itself could inherit identity details from the session that started it, and in rare cases would update another agent's session records as if they were its own — quietly corrupting that agent's tracking. Psyches now start with a clean identity of their own. No action needed; the fix applies to Psyches started after the update.

## [0.12.0] - 2026-07-03

> Requires spt-core **v0.20.0 or newer** (unchanged). Binary change — `spt adapter update claude-spt` picks it up; no plugin skeleton change.

### Fixed
- **Checkpoint waits until after the session clear to send the wake message.** When a live agent checkpoints (`/sptc:commune --checkpoint`), it clears its context and then continues with a follow-up instruction. Previously the follow-up could be submitted before the clear finished, so it ran against the old context (or was lost). The clear now always completes first, and the follow-up runs as the first turn of the fresh session — reliably, regardless of how long the clear takes.

### Changed
- **Session names now include the project folder.** Alongside the `<id> @ <node>` naming, your Claude Code sessions now show the project folder they're running in — e.g. `myagent @ lab (my-project/)` in the prompt box and `/resume` picker — so you can tell apart agents working in different projects on the same node. Remote-control names carry it too. Existing sessions pick up the new name on their next start.

## [0.11.0] - 2026-07-02

> Requires spt-core **v0.20.0 or newer** (floor raised). Manifest + binary change — `spt adapter update claude-spt` picks it up; no plugin skeleton change.

### Changed
- **Session names now use your node's spt name.** The `<id> @ <node>` session naming introduced in 0.10.3 previously used the machine's raw hostname. It now uses the node's name as known to spt — the same name shown across spt's own listings — so if you've given a node a friendly name, your Claude Code sessions match it. On nodes where that name isn't available, the hostname is used as before, and failing that the plain `<id>`.
- **Requires spt-core v0.20.0.** Update spt first (`spt update fetch` then `spt update apply`), then the adapter. Nodes on older spt-core keep working on adapter 0.10.4.

## [0.10.4] - 2026-07-02

> Requires spt-core **v0.19.0 or newer** (unchanged). Binary-only change — `spt adapter update claude-spt` picks it up; no plugin skeleton change.

### Fixed
- **`/clear` and `/compact` no longer cut an agent off from its messages.** Previously, clearing or compacting an spt-hosted session could silently break message delivery: the session kept working normally, but messages sent to it never arrived — until the endpoint was fully relaunched. Sessions now stay reachable across `/clear` and `/compact`, and if re-registration ever fails it says so instead of failing silently. An endpoint already stuck from an earlier `/clear` recovers by relaunching once on this version.

## [0.10.3] - 2026-07-01

> Requires spt-core **v0.19.0 or newer** (unchanged). Manifest + binary change — `spt adapter update claude-spt` picks it up; run `/reload-plugins` once after.

### Added
- **Sessions are named after their machine.** Every spt-hosted Claude Code session — fresh or resumed, `claude` or `ccs` — now shows up as **`<id> @ <node>`** in the prompt box, the `/resume` picker, and the terminal title, with a matching `<id>--<node>` Remote Control name, so a fleet of agents across machines is distinguishable at a glance. If the machine name can't be determined, both fall back to the plain `<id>`, exactly as before. `spt rc <id>` is unaffected — it addresses the endpoint by id.
- **Updates now reach `ccs` accounts too.** If `ccs` is installed alongside `claude`, updating the adapter also refreshes the plugin for ccs accounts, so ccs-launched sessions stop running a stale plugin after an update. Best-effort: accounts that never installed the plugin are skipped.

### Fixed
- **`ccs` sessions launch reliably on Windows.**

## [0.10.2] - 2026-07-01

> Requires spt-core **v0.19.0 or newer** (unchanged). An emergency bugfix patch over 0.10.1. Binary-only change — `spt adapter update claude-spt` picks it up; run `/reload-plugins` once after.

### Fixed
- **An out-of-step plugin no longer freezes your whole session.** If the installed plugin fell behind the adapter (for example right after an update, before `/reload-plugins`), every tool call in the session could be blocked with no way to recover. The session now keeps working through the mismatch and prints a one-line reminder to run `/reload-plugins`. A genuinely mistyped command still fails loudly, as before.

## [0.10.1] - 2026-07-01

> Requires spt-core **v0.19.0 or newer** (unchanged). A bugfix patch over 0.10.0. Binary-only change — `spt adapter update claude-spt` picks it up; run `/reload-plugins` once after.

### Fixed
- **Agents no longer pick up the wrong identity.** On a machine that belongs to a subnet, a session could come back from `/clear` or `/compact` convinced its agent id was the subnet's name, and the mistake stuck for the rest of the session. Identity is now resolved reliably, and a session without an identity is treated as such instead of being given a wrong one.

## [0.10.0] - 2026-07-01

> Requires spt-core **v0.19.0 or newer** (floor bumped). Update spt-core first (`spt update fetch && spt update apply`), then `spt adapter update claude-spt`.

### Fixed
- **Session digests now work everywhere.** `spt endpoint digest` could come back empty (`NO_DIGEST`) for `ccs` accounts and other relocated Claude Code installs, and in general whenever the daemon — rather than your own shell — produced the digest. The digest now finds the session transcript itself in all of these cases.

## [0.9.2] - 2026-06-30

> Requires spt-core **v0.16.0 or newer** (unchanged). A wording-only fix in the agent briefing (adapter strings — no binary or plugin change). `spt adapter update claude-spt` picks it up; no `/reload-plugins` needed for this one.

### Fixed
- **More accurate guidance about receiving replies.** The 0.9.1 note "replies arrive automatically — don't set up a watcher" was only true for broker-hosted sessions. A live agent you start yourself (`/sptc:live`) relies on its own running relay to receive messages, so the briefing now says: don't arm an *extra* watcher for a single reply, and don't tear down the relay you're already running.

## [0.9.1] - 2026-06-30

> Requires spt-core **v0.16.0 or newer** (unchanged). A bugfix patch over 0.9.0. After updating, run `/reload-plugins` (or restart Claude Code) once.

### Fixed
- **`hook: command not found` on every Bash command is gone.** A 0.9.0 regression left a malformed entry in the per-session environment, so every shell command printed a spurious `hook: command not found` and the message-delivery hooks could misfire. Fixed — the environment entry is now written safely (and tolerates paths with spaces).
- **`spt adapter update claude-spt` no longer fails to update the plugin.** It now refreshes the Claude Code marketplace before installing, fixing `Plugin "sptc" not found in marketplace "cplugs"` on a stale local marketplace copy.
- **Clearer update message.** After an update you now see `✔ Claude Code plugin "sptc" updated from <old> to <new>. Active sessions need to run the /reload-plugins command.` instead of the generic "Restart to apply changes."
- **Agents know their own id.** A live/perched agent is now told its id up front and no longer runs `spt whoami` to look it up.
- **No more redundant message watchers.** Agents are now told that replies arrive automatically on their existing perch, so they stop arming an extra watcher to wait for a response.
- **ccs profile parity.** Sessions launched through the `claude-spt:ccs` profile now carry the same session name and remote-control settings as the base profile (they were dropped in 0.8.0).

## [0.9.0] - 2026-06-28

> Requires spt-core **v0.16.0 or newer** (unchanged from 0.8.0). This release is an internal re-plumbing of how Claude Code hooks run — there is **no change to what you do or see**. After updating, run `/reload-plugins` (or restart Claude Code) once, as the update reminds you.

### Changed
- **Hook behaviour now updates with `spt adapter update` — no plugin reinstall needed.** Previously, any change to how a hook works (message delivery, the live-agent checkpoint, the session briefing) required a separate Claude Code plugin update. Now that logic lives in the `claude-spt` program that `spt adapter update` already refreshes, so a single update keeps hooks current. The plugin's hook wiring is now fixed and rarely needs a marketplace bump again.

### Fixed
- Nothing user-visible. This is a behaviour-preserving refactor: messaging, the `/sptc:*` skills, the live-agent checkpoint (`/sptc:commune --checkpoint`), and the session briefing all work exactly as before — they are just driven by the consolidated `claude-spt` program instead of separate hook scripts shipped in the plugin.

## [0.8.0] - 2026-06-26

> Requires spt-core **v0.16.0 or newer** (was v0.15.0). This release unifies the project naming, turns updating into a single command, and consolidates the adapter to one tool binary — built on the update-arc + CLI features that arrive in spt-core v0.16.0.

### Added
- **One-command update — `spt adapter update claude-spt`.** A single command now keeps *everything* current: it pulls the new adapter (manifest + binary + strings) **and** reconciles the Claude Code plugin in the same step. The only manual residual is `/reload-plugins` (an unavoidable Claude Code TUI action), which the update prints a reminder to run.
- **Mid-turn reachability for live agents.** A live agent can now receive a message *while it is working* (not only between turns) — incoming messages surface mid-turn, with the endpoint honestly marked busy during a turn and idle when it finishes.

### Changed
- **Name unification.** The project/repo and adapter are now **`claude-spt`** everywhere spt-core sees them (the repo was renamed `spt-claude-code` → `claude-spt`; install and update both read `claude-spt`). The Claude Code plugin stays `sptc` / `/sptc:*` this release.
- **One tool binary.** The separate digest, psyche, and idle-translation binaries are consolidated into a single `claude-spt` binary (subcommands) — one artifact per platform in the release.
- **Session display name + remote control.** A spawned/resumed endpoint now shows its `{id}` as the session display name and is remote-control-attachable under that id, on both bringup paths.
- **Leaner skills.** `commune` / `send` / `signoff` guidance is now delivered by the adapter (so it updates with `spt adapter update`) rather than baked into the plugin.

### Requires
- spt-core **v0.16.0+** (the composite `[update.post]`, the idle-translation `command` seam, and the `{adapter_dir}` substitution all land in v0.16.0).

## [0.7.0] - 2026-06-24

> Requires spt-core **v0.15.0 or newer** (was v0.13.2). This release adds self-checkpointing for live agents, automatic resume context, and clearer multi-line message delivery — all built on features that arrive in spt-core v0.15.0.

### Added
- **Self-checkpointing for live agents — `/sptc:commune --checkpoint`.** A live agent can now reset and rebuild its own context without you running `/clear`. Write a commune containing the marker `!!checkpoint!!` and the session clears itself, then wakes back up from that very commune and keeps going. A single `!!checkpoint!!` wakes with a default "Proceed with next steps"; a **pair** of markers wakes with whatever instruction you write between them. The marker is one-shot — it never lingers in your rebuilt context.
- **Automatic resume context.** When a live agent's session starts (or clears), it now pulls its durable role, working context, and latest unsynced commune and re-injects them automatically — so it resumes where it left off instead of coming back blank.

### Changed
- **Incoming messages are easier to read.** A message delivered from another agent now renders across multiple lines — the envelope opening, the body, and the close each on their own line — instead of one dense single line.
- **Requires spt-core v0.15.0+** (up from v0.13.2). Self-checkpointing and resume context both rely on capabilities introduced in that release; `/sptc:setup` and `spt adapter update` will keep you current.
- Adapter version of truth is now **0.7.0** (shown in `/sptc:version` and the release tag).

## [0.6.2] - 2026-06-23

> Requires spt-core **v0.13.2 or newer** (unchanged). A small but important delivery fix — no change to commands or setup.

### Fixed
- **Messages delivered while you're idle now actually send.** Previously an incoming message from another agent could be typed into your Claude Code input box but never submitted — it just sat there as an unsent draft. The delivery now presses **Enter** to send it, so idle-delivered messages arrive and run on their own. Your half-typed draft is still stashed and restored around the delivery, exactly as before.

## [0.6.1] - 2026-06-22

> Requires spt-core **v0.13.2 or newer** (the version that can install a multi-platform package). Packaging-only release — no change to what the adapter does, only how it ships.

### Packaging
- **One download now covers every platform.** The adapter ships as a single multi-platform `adapter.spt` that bundles both the Windows and Linux builds beside one shared manifest; installing picks your platform automatically. This replaces the previous per-OS files and the Windows-only stopgap `adapter.spt` (which broke self-update on Linux), so `spt adapter add --release …` and `spt adapter update` now just work on either OS with no platform to pick. Requires spt-core **v0.13.2+** (the version that can read a multi-platform package).

### Changed
- **Setup is simpler.** `/sptc:setup` now activates the adapter with a plain `spt adapter add --release SaberMage/spt-claude-code` — no OS detection or asset selection, since the one package is host-agnostic.
- Adapter version of truth is now **0.6.1** (shown in `/sptc:version` and the release tag). The cplugs plugin skeleton bumps with the simplified setup body.

## [0.6.0] - 2026-06-22

> Requires spt-core **v0.13.0 or newer** for the two new capabilities below. On older spt-core they're simply inactive — nothing else changes, so this release is safe to take on any version.

### Added
- **Idle agents now receive your messages.** When an spt-hosted agent is sitting at its prompt (idle, not mid-task), a message sent to it now lands *in that session* — typed in and submitted for you — instead of going unseen until the agent next acted. If you were part-way through typing your own input, your draft is stashed first and restored right after, so an incoming message never eats what you were writing.
- **Resuming an agent brings back its conversation.** Relaunching a session now reloads its prior transcript instead of cold-starting a blank one, and the resume picker shows each session's project folder so you can tell them apart.

### Changed
- Adapter version of truth is now **0.6.0** (shown in `/sptc:version` and the release tag). The cplugs plugin skeleton is unchanged (still on its own slower track).

## [0.5.0] - 2026-06-19

### Added
- **Agents now know who they are the moment a session starts.** When a session is already reachable — you launched it through `cc`, or it cleared/compacted mid-run — it now opens with a short brief: its own agent name, a reminder that it's already live (so it won't try to re-arm), and how to message other agents (`spt send` and reply, plus `spt endpoint list` to see who's around). Previously a resumed or spt-launched session could start not knowing its own name.
- **Sessions that aren't reachable yet learn how to reach out.** On a machine that belongs to a subnet, a plain session with no perch now gets a one-line tip on reaching other agents with `spt ring` — without having to go reachable first. Solo machines with no peers see nothing.

## [0.4.0] - 2026-06-18

### Changed
- **Your live-agent companion now runs in a safe, limited mode.** When you go live with `/sptc:live`, the background companion that writes your context-resume notes works with a file-only toolset and a lighter, cheaper model. It is more contained and costs less to run, with no change to what you see or do.
- **Removed the experimental `:deep` profile.** `claude-spt:deep` was an unused placeholder. The one shipped profile overlay is `claude-spt:ccs` (routes sessions through `ccs`). If you ever selected `:deep`, use `:ccs` or the base adapter instead.

### Fixed
- **Sessions that spt starts for you no longer stall on a permission prompt.** When spt brings up a Claude Code session on your behalf (the live companion, and the spt-hosted launcher), it could hang waiting on an approval prompt that no one was there to answer. Those sessions now start cleanly.

## [0.3.0] - 2026-06-17

### Changed
- **Going live is now a single, seamless step.** A live agent comes up directly — no behind-the-scenes adapter selection, no chained setup commands. `/sptc:live` just brings your session up live, and `/sptc:ready` brings it up reachable-but-light; the difference is simply which one you run. This is full parity with the original live-agent experience.
- **Requires spt-core 0.9.0 or newer.** This release uses spt-core's newer automatic harness-resolution, so the adapter now needs spt-core **0.9.0+**. If you keep spt-core up to date (it self-updates), there's nothing to do; on an older spt-core the adapter will decline to install until you update.

### Fixed
- **Setup pins this adapter as your default.** `/sptc:setup` now records `claude-spt` as the active adapter for Claude Code, so going live or ready needs no extra flags.

## [0.2.1] - 2026-06-16

### Fixed
- **Going live shows a clean status, not raw machine output.** Starting a live agent previously leaked internal setup markers and tokens into the chat. `/sptc:live` now reports a single tidy summary — your agent id, online status, how other agents reach you, and how to reply — and nothing else.

### Changed
- **Self-contained live setup.** Bringing a session live no longer bounces you to a separate help topic; `/sptc:live` carries the full bringup itself, so going live works in one step.

## [0.2.0] - 2026-06-16

### Fixed
- **Live agents now reliably start their background companion.** Previously a live agent could come up marked "online" while its persistent companion silently failed to start, leaving it with no running context. The companion now launches and stays resident.

### Changed
- **Simpler setup — no manual PATH step.** The adapter's helper tools are now found automatically from where the adapter is installed; `/sptc:setup` no longer asks you to copy anything onto your PATH.
- **Automatic adapter updates.** The adapter now updates itself from this project's GitHub releases (`spt adapter update`) — logic and instruction changes reach you without a reinstall.

### Added
- **Linux support.** The adapter ships native **Windows and Linux** builds; `/sptc:setup` detects your OS and installs the right one.
- **ccs integration.** If you use [ccs](https://github.com/kaitranntt/ccs), `/sptc:setup` wires the shipped `claude-spt:ccs` profile so live/ready agents can run on your ccs backends instead of `claude`.
- **Private-network onboarding.** `/sptc:setup` now offers to create or join a private network (subnet) so you can pair machines and reach agents across them.

## [0.1.0] - 2026-06-15

First public release.

### Added
- **One-step setup — `/sptc:setup`.** Sets the plugin up and installs the Spacetime (`spt`) engine for you if it isn't already present, so messaging and live agents just work. Also offers to create or join a private network and to register the always-on background service.
- **Agent messaging.** `/sptc:ready` turns on your inbox so other agents can reach this session; `/sptc:send` messages another agent; `/sptc:list-agents` shows who is currently active.
- **Live agents.** `/sptc:live` upgrades the current session into a live agent with a persistent companion that keeps its own running context. `/sptc:commune` pushes a context update to that companion, and `/sptc:signoff` ends a live session cleanly with a final summary.
- **`/sptc:force-stop`** immediately tears down a listening or live agent when you need it gone.
- **Cross-machine networks — `/sptc:subnet`.** Pair machines into a private network (create, show the join code, or join an existing one) so your agents can reach each other across nodes.
- **`/sptc:version`** reports the running engine version.
- **Alternate model backends (advanced).** Ships a ready-made `ccs` profile template you can select to launch sessions through [ccs](https://github.com/kaitranntt/ccs) — useful for routing an agent to a different model or billing backend. You supply your own ccs configuration.
- **Invisible engine install.** Starting a session automatically installs the `spt` engine the first time if it is missing — no separate install step.
