{
  "summary": "Read-only Oh My Pi integration audit completed. The native hosted cut uses valid current OMP APIs and correctly makes interactive `omp` the PTY leader, but it is not yet lifecycle-complete. Highest-risk factual defects are: (1) `[session.self]`/`[session.resume]` invoke bare `omp` and bypass the repo’s own wrong-binary collision protection; (2) in-process `/resume`/session switches never rebind the SPT perch to OMP’s new session id; (3) local-only/slash prompts emit no `agent_end`, permanently wedging the native extension and timing out the RPC bridge; (4) the RPC timeout path does not abort/quarantine the old turn, so a late `agent_end` can be returned to the next sender; (5) `[update.post]` still runs the Claude/cplugs `sptc@cplugs` reconciler; (6) no OMP-native SPT brief/skill/command path is delivered, and inherited `/clear` checkpoint semantics are invalid in OMP; (7) digest/history locators ignore OMP profile/config-root relocation; and (8) the native listener has no timeout/restart/hard-exit child cleanup. The OMP extension-loading and event/API names it does use are accurate against current public docs. Detailed matrix and ranked defects are in `architecture`.",
  "files": [
    {
      "path": "adapter/strings/omp-spt.mjs",
      "description": "Native interactive integration. Valid uses of `pi.on`, `pi.sendUserMessage`, `pi.logger`, `ctx.ui`, and `ctx.sessionManager.getSessionId`; only handles `session_start`, `agent_start`, `agent_end`, and `session_shutdown`. Owns unpersisted FIFO/current state and an unmanaged `spt ready` child."
    },
    {
      "path": "adapter/omp-spt.toml",
      "description": "Active adapter manifest. Native self/resume commands are at `[session.self]` and `[session.resume]`; inherited CC hooks, translation binary, update.post, strings/briefs/skills, environment, digest/history, and psyche roles coexist with the native cut."
    },
    {
      "path": "docs/adr/0007-native-omp-tui-hosts-spt-extension.md",
      "description": "Accepted decision: native OMP owns the PTY; packaged extension must bind/listen/state/reply and serialize SPT delivery; RPC bridge remains headless-only."
    },
    {
      "path": "tools/claude-spt/src/bridge.rs",
      "description": "Headless RPC bridge. Bounded startup/turn waits and child teardown exist, but `drive_turn` waits only for `agent_end`, ignores prompt completion/error frames, and does not abort a timed-out run. `omp_bin()` contains collision protection bypassed by native manifest commands."
    },
    {
      "path": "tools/claude-spt/src/post_update.rs",
      "description": "Factual update mismatch: hardcoded Claude/ccs CLI detection, `SaberMage/cplugs`, `sptc@cplugs`, Claude registry JSON, and `/reload-plugins` notice, although invoked by omp-spt `[update.post]`."
    },
    {
      "path": "tools/claude-spt/src/digest_omp.rs",
      "description": "OMP JSONL mapper is structurally appropriate, but `sessions_root()` defaults unconditionally to `$HOME/.omp/agent/sessions`; it does not honor `PI_CONFIG_DIR`, `PI_CODING_AGENT_DIR`, or named profiles."
    },
    {
      "path": "tools/claude-spt/src/history_omp.rs",
      "description": "Shares digest_omp’s hardcoded locator, so profile-scoped session history and echo-commune input cannot be found without an unthreaded `--session-dir` override."
    },
    {
      "path": "tools/claude-spt/src/psyche_omp.rs",
      "description": "OMP-specific ephemeral Psyche shim correctly isolates continuity in a private `--session-dir` and disables extensions/skills/rules; not affected by the normal-session profile locator defect."
    },
    {
      "path": "tools/claude-spt/examples/fake-omp.rs",
      "description": "Bridge fake covers ready/get_state/prompt/agent_end and a mute timeout only; it cannot model local-only prompts, prompt failures, late completion after timeout, session switching, or extension errors."
    },
    {
      "path": "tests/omp-extension.mjs",
      "description": "Only tests body decoding, envelope draining, and assistant-text extraction; no mocked ExtensionAPI lifecycle, listener, state, shutdown, rebind, or local-command behavior."
    },
    {
      "path": "tests/manifest-shortcut.sh",
      "description": "Source-shape guard proves two native OMP commands and extension presence, but explicitly preserves inherited translation and does not behavior-test direct launch, binding, profiles, update.post, or command semantics."
    },
    {
      "path": "ci/publish/package-adapter.sh",
      "description": "Packages manifest, all strings (including the extension), and omp-spt binaries for locked Win/Linux x86_64 fleet. Comments remain Claude-lineage stale, but active binary list is omp-spt."
    },
    {
      "path": "plugin/omps",
      "description": "Claude-compatible marketplace skeleton, not a working OMP-native command surface: skills advertise `/omps:*`, expect UserPromptSubmit injection, and several bodies still activate `claude-spt`/Claude Code."
    },
    {
      "path": "adapter/strings/skills",
      "description": "Spt-core file-backed instruction bodies. They are flat `skills/*.md`, not OMP’s discoverable `skills/<name>/SKILL.md` layout, and key setup/live/checkpoint prose remains Claude-specific."
    },
    {
      "path": "README.md",
      "description": "Public onboarding still identifies the project as claude-spt/Claude Code and installs `SaberMage/claude-spt`; it does not document the actual OMP native extension, repo, launch, profile, or update behavior."
    }
  ],
  "architecture": "## Surface-by-surface evidence matrix\n\n| Surface | Classification | Public OMP contract | Current project evidence | Audit result |\n|---|---|---|---|---|\n| Extension API names | **implemented** | `omp://extensions.md` §§Extension API surfaces, Message delivery, Event surface | `adapter/strings/omp-spt.mjs::ompSpt` | The used names are current and exact: `pi.on`, `pi.sendUserMessage`, `pi.logger.error/debug`, `ctx.ui.notify/setStatus`, and `ctx.sessionManager.getSessionId`. `agent_end.messages` is consumed in the documented shape. No obsolete OMP API name was found in the active extension. |\n| Extension loading | **implemented** for hosted startup; **partial** for failure/other entry paths | `omp://extension-loading.md` §§Inputs, path resolution, failure isolation | `adapter/omp-spt.toml [session.self]/[session.resume]`; `ci/publish/package-adapter.sh`; `adapter/strings/omp-spt.mjs` | `omp --extension {adapter_dir}/strings/omp-spt.mjs` is a documented explicit-file load, default export is a factory, and `strings/` is packaged. OMP isolates a missing/import/factory error and continues, however, so a load failure can leave a normal-looking OMP TUI with no adapter-owned status/listener; there is no adapter health handshake. No equivalent is loaded in ordinary user-launched OMP. |\n| Native TUI ownership | **implemented**, with a critical executable-resolution defect | `omp://tui.md`; `omp://tui-runtime-internals.md`; `omp://extensions.md` §Interactive UI | `docs/adr/0007-native-omp-tui-hosts-spt-extension.md`; manifest `[session.self]`/`[session.resume]` | The architectural change is correct: native `omp`, not the RPC bridge, owns the broker PTY and all terminal rendering. **Defect:** both commands invoke bare `omp`. `tools/claude-spt/src/bridge.rs::omp_bin` explicitly records that PATH `omp` on Librarian is a OneCLI gateway alias and therefore resolves `OMP_SPT_OMP_BIN`/a known install path before PATH. The native cut bypasses all of that protection and its override. |\n| OMP lifecycle coverage | **partial** | `omp://extensions.md` §Event surface | `omp-spt.mjs` registrations at `session_start`, `agent_start`, `agent_end`, `session_shutdown` | Initial bind, busy, idle, reply, and normal shutdown are present. Missing: `session_before_switch/session_switch`, branch/tree events, before/after compaction and auto-compaction signals, `session_stop`, turn/message events, retry signals, and extension-error-aware recovery. These omissions become concrete defects below rather than merely unused API breadth. |\n| Session startup and startup resume | **implemented** | `omp://session-operations-export-share-fork-resume.md` operation matrix; `omp://session-switching-and-recent-listing.md` §Startup resume | Manifest `[session.self]`, `[session.resume]`; `omp-spt.mjs::session_start` | Fresh OMP mints a session id; `-r {session_id}` restores a persisted OMP session before the one startup `session_start`; extension binds the observed id to SPT. This is the correct public startup-resume shape. |\n| In-process resume/switch/branch/tree | **missing** | `omp://session-switching-and-recent-listing.md` §Runtime switch execution: switch updates `agent.sessionId` and emits `session_before_switch`/`session_switch`; `omp://extensions.md` lifecycle list | No matching handlers in `omp-spt.mjs` | `/resume` switches the running OMP session and its `sessionId`, but the perch remains bound/authenticated to the old sid. Digest/history identity and subsequent state/session-end authorization can therefore point at the departed session. Branch/tree/session transitions likewise have no adapter reconciliation. This is the OMP analogue of the already-documented inherited CC resume-rebind wedge in manifest history, but the native extension reintroduced it. |\n| Busy/idle state | **partial** | `omp://extensions.md` agent/turn/compaction/retry lifecycle | `omp-spt.mjs::agent_start`, `agent_end`; bridge main loop | Normal agent loops map busy→idle. Compaction, user bash/python, `session_stop` continuations, and lifecycle transitions are not represented. Native state calls have no deadline and a hanging `spt` subprocess can stall an OMP event handler. If `setState` fails, notification occurs but serving continues with potentially false advertised state. |\n| SPT inbound FIFO serialization | **partial** | `omp://extensions.md` §Message delivery semantics | `omp-spt.mjs::{queue,current,agentActive,dispatchNext}` | Ordinary agent-producing messages are serialized one at a time and associated with a single sender. State is only in memory, has no durable entry, and completion is defined solely as `agent_end`; local-only command execution and session transitions break the invariant. |\n| Steer/follow-up | **missing** as an explicit integration; potentially an intentional product choice | `omp://extensions.md` §Message delivery: `deliverAs: steer/followUp/nextTurn`; `omp://rpc.md` prompt/steer/follow_up commands and queue modes | Native `dispatchNext` waits for idle and calls `sendUserMessage(body)` with no `deliverAs`; bridge queues ready lines locally | Current policy is strict adapter FIFO after `agent_end`; there is no mid-turn steer or explicit follow-up. This is safe/simple if chosen, but it leaves OMP’s native steer/follow-up integration unused and should be ratified rather than accidental. |\n| Message prompt semantics | **partial**, with a high-severity command wedge and trust-boundary question | `omp://slash-command-internals.md` §§Prompt pipeline, streaming, errors; `omp://extensions.md` `sendUserMessage` | `omp-spt.mjs::dispatchNext`; bridge `drive_turn` | Peer body is injected verbatim through normal prompt expansion. A leading slash can execute extension/custom/file commands under the recipient’s project context; this is a peer-to-command trust decision. More immediately, a handled/local-only command produces no agent loop, hence no `agent_end`: native `current` never clears and all later SPT messages wedge. |\n| Native reply routing | **partial** | `omp://extensions.md` `agent_end` and message shapes | `omp-spt.mjs::extractReply`, `agent_end` handler | Normal text replies route to `completed.from`; missing assistant text gets a sentinel. Replies are passed as a command-line argument to `spt send` rather than stdin, unlike the bridge, creating Windows command-line-length and argument-shape risk for long model outputs. Sender/body/correlation are not persisted, so reload/crash/session switch loses ownership of an in-flight answer. |\n| `session_stop` finality | **missing** | `omp://extensions.md`: `session_stop` is awaited before settle and can continue up to 8 times with additional context | Native reply is sent on `agent_end` | `agent_end` is only an agent-loop notification, not necessarily final session settlement when another extension returns `session_stop {continue:true}`. The adapter can send an early reply, mark idle, and dispatch the next peer before the continued response is done. Integration must choose and observe the actual finality event/protocol. |\n| Native error and timeout recovery | **missing** | `omp://extensions.md` runtime error isolation; lifecycle/error events | `omp-spt.mjs` | There is no per-turn deadline, no no-`agent_end` recovery, no sender failure notice, no listener restart/backoff, no liveness heartbeat, and no transition to session-end when the listener dies. The headless bridge already has much of this policy, but the active native path does not. |\n| Native shutdown | **partial** | `omp://extensions.md` `session_shutdown`; OMP runtime catches handler exceptions | `omp-spt.mjs::session_shutdown` | Normal OMP shutdown sets `stopping`, kills the listener, clears status, and awaits `api session-end`. The listener kill is not awaited. More importantly, the listener is a normal child with no kill-on-parent/job-object protection: an OMP crash/hard kill can orphan `spt ready`. Listener close while OMP remains up only shows UI error and does not tear down the advertised perch. There is also a start/shutdown race: async bind can complete after `stopping=true` and still call `startListener()`. |\n| Durable extension serialization | **missing** | `omp://extensions.md` §Session and state patterns: `appendEntry`, rebuild on start/branch/tree | `omp-spt.mjs` has only closure variables | No adapter state is appended to the OMP session. Endpoint id, last bound sid, in-flight sender, and queue/correlation state cannot be reconstructed after extension reload, session navigation, or crash. Whether inbound deliveries are core-redelivered is outside the OMP contract, so exactly-once recovery is **blocked by public-contract gap** until SPT delivery acknowledgment semantics are applied. |\n| Headless RPC protocol basics | **partial** | `omp://rpc.md` startup, framing, request/response/event schemas | `bridge.rs::run_argv`, `await_frame`, `drive_turn` | Correct: `--mode rpc`, ready gate, get_state, prompt, agent_end, JSONL framing, startup/turn deadlines, FIFO of ready lines. Missing protocol rigor: no request ids, get_state matcher ignores `success`, prompt failure responses and `extension_error` are ignored, and command acceptance is conflated with turn completion. |\n| RPC local-only completion | **missing**, high severity | `omp://rpc.md` §§Request correlation and prompt payload: `data.agentInvoked:false`/`prompt_result`; local-only slash commands do not emit `agent_end` | `bridge.rs::drive_turn` recognizes only `type == agent_end` | Any local-only slash/custom command waits until `OMP_SPT_TURN_TIMEOUT_S` and returns a false timeout even though OMP completed it. `command_output`, prompt failure, same-id scheduling error, and `prompt_result` are all dropped. |\n| RPC timeout isolation | **missing**, critical reply-integrity defect | `omp://rpc.md` supports `abort`; prompt responses/events are asynchronous and correlated by id | `bridge.rs::drive_turn`; `stale_turns` handling only in outer loop | On timeout the bridge marks idle and accepts the next peer without sending `abort` or awaiting settle. A late `agent_end` from the timed-out turn arriving while the next `drive_turn` is active is accepted as the next sender’s reply. `stale_turns` only discards late ends seen by the outer loop, so it does not protect the dangerous overlap. |\n| RPC shutdown | **partial** | `omp://rpc.md`: stdin close rejects pending host requests and exits cleanly; termination conditions include stdin close/extension shutdown | `bridge.rs` teardown kills `ready_child` and `omp_child` | Job-object/backstop and SPT soft teardown are good. The bridge kills OMP rather than closing RPC stdin and waiting for its documented clean exit, so `session_shutdown` extensions and final flush behavior are not given a graceful path. |\n| RPC resume/session changes | **partial** | `omp://rpc.md` supports `switch_session`, `new_session`, state; `omp://session-switching-and-recent-listing.md` | Bridge startup `--resume`; fixed `sid` after bind | Startup `-r` works. No runtime state response/event can update fixed `sid`; if a peer prompt induces any session transition, auth and digest identity stay old. This overlaps the local-only command defect. |\n| Hooks | **intentionally inapplicable** for the native extension path, but stale/misleading artifacts are present | `omp://hooks.md`: current OMP hooks are JS/TS factories loaded through the extension runner; event names are lower-case OMP lifecycle names | Manifest `[hooks.SessionStart/UserPromptSubmit/PreToolUse/Stop/…]`; `plugin/omps/hooks`; `tools/.../hook.rs` | Native `omp --extension` never loads the Claude shell hooks. The active integration correctly uses OMP extensions instead. However the manifest still declares CC events and `strings.hook_cmd`, and the shipped marketplace skeleton still routes CC hooks. They do not supply native OMP busy/idle, brief injection, checkpoint, or poll semantics and should not be counted as implemented OMP surfaces. |\n| Delivery ownership: translator versus extension listener | **blocked by public-contract gap / design conflict requiring confirmation** | SPT manifest schema describes `[message-idle-translation-binary]` as spt-core-spawned and lifecycle-managed; OMP docs only define extension behavior | Manifest keeps `[message-idle-translation-binary] command = ... translate`; native extension independently spawns `spt ready`; ADR-0007 says extension owns listen; `tests/manifest-shortcut.sh` explicitly enforces the old translator | Two delivery mechanisms remain declared around the same hosted endpoint. The repo evidence does not establish whether the broker translator and extension `spt ready` compete, duplicate, or are mutually gated. This cannot be waved away: select one owner or cite the published SPT rule proving coexistence. Core-contract auditor should resolve this against the published harness checklist. |\n| Environment and endpoint identity | **partial** | `omp://environment-variables.md` resolution model and storage vars; `omp://config-usage.md` profiles | Manifest `[env.SPT_ENDPOINT_ID]`; extension reads `SPT_ENDPOINT_ID`, `OMP_SPT_SPT_BIN`, `OMP_SPT_SUBNET` | Broker id injection is correct and gives the extension its endpoint id. Native launch ignores the established `OMP_SPT_OMP_BIN` override and all bridge timeout/debug knobs. `OMP_SPT_SUBNET` is adapter-specific and consistently forwarded to bind/ready. |\n| OMP profiles/config-root relocation | **missing** in extractors; launch configuration is only implicit | `omp://config-usage.md` §Profiles; `omp://environment-variables.md` §Storage and config root paths | `digest_omp.rs::sessions_root`; history shares it; manifest only retains `[env.CLAUDE_CONFIG_DIR]` | Named profiles relocate sessions to `~/.omp/profiles/<name>/agent/sessions`; `PI_CODING_AGENT_DIR` and `PI_CONFIG_DIR` can relocate them further. Locator hardcodes `~/.omp/agent/sessions`, and neither manifest command supplies `--session-dir` nor `[env]` captures OMP path vars. Digest/history/echo-commune fail for those public configurations. The manifest test comment says profiles ride a bridge `-- --profile` passthrough, but native commands no longer use the bridge and expose no such path. |\n| Compaction | **missing** as an SPT lifecycle integration | `omp://compaction.md` manual `/compact`, auto compaction, idle maintenance; `omp://extensions.md` before/compacting/after and auto-compaction events | No compaction handlers in extension; inherited briefs/translator refer to CC mechanics | Native OMP compaction itself works, but adapter state stays `idle` during non-agent compaction, inbound dispatch can race it, and no SPT context/identity is added to compaction context or restored after it. There is no OMP-native pre-compact commune/checkpoint integration. |\n| Checkpoint/reset semantics | **missing/broken** | `omp://session-operations-export-share-fork-resume.md` documents `/fresh`; `omp://compaction.md` documents `/compact`; `omp://slash-command-internals.md` says unknown slash text falls through to the LLM | `translate.rs::checkpoint_clear_commands` types literal `/clear`; `strings/briefs/live-ops.md` and skills teach `/clear`; native extension ignores checkpoint JSON metadata | `/clear` is inherited Claude semantics, not an OMP built-in. In OMP it is unknown and can reach the model literally. The native listener only extracts `type/from/body`, so it does not interpret checkpoint JSON metadata either. The project needs a deliberate OMP reset primitive (`/fresh`, new session/handoff, compact, or extension command), not a token substitution. |\n| Slash commands and skills | **missing** as advertised OMP UX | `omp://skills.md`: discoverable layout is `skills/<name>/SKILL.md`, optional invocation is `/skill:<name>`; `omp://slash-command-internals.md` extension `registerCommand` and plugin command namespaces | `adapter/strings/skills/*.md` flat files; `plugin/omps/skills/*/SKILL.md`; extension registers no commands | Hosted extension does not register `/omps:*`. Adapter string skills are not OMP skill layout. Marketplace skeleton skills can be discovered only if the plugin is separately installed, but OMP exposes skills as model metadata/`/skill:<name>`, not the advertised `/omps:*`; most skeletons depend on CC UserPromptSubmit injection that never fires. `setup`/`live` bodies actively select `claude-spt`, `.claude`, CC monitors, and ccs. |\n| Agent-facing identity/actions | **missing** | `omp://extensions.md` `sendMessage`, `before_agent_start`, `context`, commands; `omp://skills.md` system-prompt exposure | Native extension only changes UI status and silently auto-replies | The OMP agent is never told it is SPT endpoint `{id}`, who sent an inbound message, how to message another agent, commune, sign off, or inspect peers. Manifest briefs are only consumed by inherited CC hook logic. Auto-reply makes reactive request/response work, but the advertised live-agent action model is absent. |\n| Marketplace/plugin extension delivery | **intentionally inapplicable** to the packaged hosted extension; **partial/broken** for skills UX | `omp://marketplace.md`: Claude-compatible catalog supported, but marketplace-installed extension modules are **not loaded**; extension modules require npm or `omp plugin link` | Extension comes from adapter.spt CLI path; `plugin/omps` is cplugs skeleton | Packaging the active extension in adapter `strings/` is the right response to OMP’s marketplace extension limitation. A marketplace plugin can still distribute skills/commands/hooks, but the current skeleton is not retargeted to OMP and update.post does not manage OMP’s registry. |\n| Adapter packaging | **implemented** for the explicitly locked fleet; other platforms **intentionally inapplicable** | OMP executable is external; SPT archive contract is audited separately | `SCOPE.md` locks Win+Linux fleet; `package-adapter.sh` packages x86_64 Windows/Linux, manifest, strings, binary | Extension is included because all `strings/` are shared at archive root. No macOS/ARM artifact, but SCOPE explicitly limits the fleet, so this is not a defect unless product scope changes. |\n| Update | **partial**, with a clear factual wrong-host post-step | OMP update surfaces: `omp plugin marketplace update`, `omp plugin upgrade`; marketplace state under `~/.omp` (`omp://marketplace.md`, `omp://plugin-manager-installer-plumbing.md`) | Manifest `[update]` points at `BigscreenVR/omp-spt`; `[update.post]` calls `omp-spt post-update`; `post_update.rs` is Claude-only | Core adapter archive update and restart notice are coherent. Post-step is wrong: it detects `claude`/`ccs`, reads Claude config roots, updates `SaberMage/cplugs`, installs/updates `sptc@cplugs`, and emits a Claude `/reload-plugins` notice. It does not update `omps`, invoke `omp plugin`, or touch OMP registries. Because the step is fail-isolated, archive update may succeed while producing irrelevant side effects/failure noise. |\n| Public docs/onboarding | **missing/stale** | OMP surfaces above | `README.md`; `docs/RELEASE-RUNBOOK.md`; plugin skill bodies; manifest comments | README still installs SaberMage/claude-spt and describes Claude Code. Release runbook and many comments use old binary/repo/plugin names. This is user-visible, not merely cosmetic: copied commands select the wrong adapter. |\n| Verification | **partial** | Observable contracts above | `tests/omp-extension.mjs`, `tests/manifest-shortcut.sh`, `tests/bridge-acceptance.sh`, fake-omp | Pure envelope/reply parsing, manifest source shape, normal RPC cycle, and mute timeout are covered. Missing tests for a mocked OMP ExtensionAPI lifecycle, in-process resume rebind, session_stop continuation, local-only prompt completion, prompt errors, late agent_end after timeout, listener death/restart, hard shutdown child cleanup, OMP profiles, actual extension loading, update.post target, and translator/listener delivery ownership. |\n\n## Ranked factual defects to grill\n\n### Critical / P0\n\n1. **Native launch can execute the known wrong `omp`.** Manifest direct commands bypass `bridge.rs::omp_bin()` and ignore `OMP_SPT_OMP_BIN`, despite the code documenting a real Librarian PATH collision.\n2. **RPC late-completion reply corruption.** After timeout, the old turn is neither aborted nor settled; its late `agent_end` can satisfy the next sender’s `drive_turn`.\n\n### High\n\n3. **In-process `/resume`/session switch leaves the perch bound to the departed OMP sid.** No `session_switch` rebind/ownership-proof logic.\n4. **Local-only/slash prompts never emit `agent_end`.** Native delivery wedges permanently; RPC delivery false-times-out. Public RPC docs explicitly require handling `agentInvoked:false`/`prompt_result`.\n5. **`[update.post]` is the Claude adapter reconciler.** It manages `sptc@cplugs`, not OMP or `omps`.\n6. **No OMP-native identity/operations injection or valid command surface.** Reactive auto-reply is present; actual agent messaging/live-agent UX is not.\n7. **Checkpoint injects nonexistent `/clear`.** OMP’s documented operations are `/fresh` and `/compact`; unknown commands fall through.\n8. **Profiles and config-root overrides break digest/history/echo-commune location.** Hardcoded default root contradicts public profile relocation.\n9. **Native listener has no timeout, liveness recovery, or hard-parent-death cleanup.** Listener death leaves a stale perch; OMP death can orphan `spt ready`.\n10. **Native turns have no deadline/failure response.** A turn that never reaches `agent_end` silently blocks every queued peer.\n11. **`session_stop` continuation can make `agent_end` an early reply boundary.** Other OMP extensions can legitimately continue the session after the adapter replies/marks idle.\n\n### Medium\n\n12. **Native state/correlation is not serialized.** No `appendEntry`/rebuild across switch/branch/tree/reload.\n13. **Compaction and non-agent busy states are invisible to SPT.** Dispatch/state can claim idle during OMP work.\n14. **RPC ignores command failures, extension errors, command output, and local completion frames.** It also omits request IDs.\n15. **RPC teardown kills rather than cleanly closes stdin.** Documented RPC graceful exit/session_shutdown path is bypassed.\n16. **Native long replies ride argv rather than stdin.** Windows size limits and option-like reply shapes are avoidable.\n17. **Extension load failures are isolated by OMP and no adapter health signal closes the loop.** A hosted TUI may exist without integration.\n18. **Startup/shutdown race can spawn listener after shutdown began.** `startListener()` does not check `stopping` after async bind/state.\n19. **Bridge and extension body decoding differ.** Native decodes SPT envelope entities/`<br>`; bridge forwards raw envelope body. Headless and TUI agents may see different prompts.\n\n## Product/design decisions requiring user input (not factual defects)\n\n1. **Delivery owner:** retain core `[message-idle-translation-binary]`, or make the OMP extension’s `spt ready` listener authoritative. The current two-owner declaration needs a published coexistence proof or a cutover.\n2. **Mid-turn policy:** strict FIFO-after-idle versus OMP-native `steer` or `followUp`. Current behavior is defensible but must be explicit.\n3. **Peer command trust:** should a peer’s leading `/...` execute recipient-side extension/file commands, or always be treated as literal attributed user text?\n4. **Reply finality:** reply on each agent loop, on `session_stop` final settlement, or via an explicit reply action/tool. This determines continuation/retry behavior.\n5. **Durability semantics:** at-most-once versus recoverable delivery across extension/OMP crash; requires matching SPT acknowledgment/redelivery public contract.\n6. **OMP reset model:** `/fresh`, new session/handoff, `/compact`, or an adapter-registered checkpoint command. `/clear` cannot be retained.\n7. **User-facing installation channel:** adapter-only hosted extension versus a real OMP marketplace/npm plugin for skills/commands. Marketplace installs cannot load extension modules, so a single OMP marketplace artifact cannot replace the current CLI-loaded extension without npm/link or configuration.\n8. **Per-endpoint OMP profile/model selection:** user default only, adapter profile overlays with explicit `--profile`, or another manifest string/env seam. The ADR says flags belong on the manifest command but no selection mechanism is currently shipped.\n9. **Agent attribution:** whether remote messages should be prefixed/persisted with sender identity rather than silently becoming ordinary user prompts.\n10. **Scope expansion beyond locked Win/Linux x86_64 fleet:** only a decision if macOS/ARM support is desired; it is not an existing-scope defect.\n\n## Recommended grill order\n\n1. Resolve **which process owns delivery** (translator vs extension listener) and **which executable launches OMP**.\n2. Specify one lifecycle state machine covering initial bind, switch/resume/branch/tree, agent loop, session_stop continuation, compaction, listener failure, and shutdown.\n3. Define prompt completion as a union: `agent_end`, local-only completion, command failure, timeout+abort settlement, and process/session transition.\n4. Define peer-command trust and steer/follow-up policy.\n5. Define OMP-native identity/skill/command delivery and reset/checkpoint semantics.\n6. Thread active OMP agent/session directory into digest/history and test named profiles plus `PI_CODING_AGENT_DIR`.\n7. Remove or retarget Claude-only post-update/plugin/docs surfaces.\n8. Add behavioral tests for the above; current tests prove parsing/source shape, not end-to-end lifecycle correctness."
}