From b29288a3e00c16427588526e1a68284f9976b8b4 Mon Sep 17 00:00:00 2001 From: shaun0927 <70629228+shaun0927@users.noreply.github.com> Date: Sat, 23 May 2026 10:57:25 +0900 Subject: [PATCH 1/2] Clarify plugin dispatch UX before implementation Constraint: Ourocode v0.1.8 has core ooo routing but not generic UserLevel plugin dispatch. Rejected: Treat superpowers as a one-off shell command | would bypass the Ouroboros plugin firewall and not generalize. Confidence: high Scope-risk: narrow Directive: Keep plugin execution routed through Ouroboros trust and firewall boundaries; do not auto-grant plugin scopes. Tested: git status; documentation-only change reviewed locally. Not-tested: Elixir test suite not run because this PR only adds design documentation. --- docs/userlevel-plugin-dispatch.md | 183 ++++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 docs/userlevel-plugin-dispatch.md diff --git a/docs/userlevel-plugin-dispatch.md b/docs/userlevel-plugin-dispatch.md new file mode 100644 index 0000000..23e764b --- /dev/null +++ b/docs/userlevel-plugin-dispatch.md @@ -0,0 +1,183 @@ +# UserLevel Plugin Dispatch in Ourocode + +Issue: https://github.com/Q00/ourocode/issues/2 + +## Goal + +`ourocode` should let users run installed Ouroboros UserLevel plugins from the +terminal UI with either direct `ooo ...` prompts or natural language. +A user should not need to leave `ourocode`, run a shell command, find generated +handoff artifacts, and then manually re-enter `ooo run`. + +The motivating example is Q00/ouroboros-plugins `superpowers`: + +```text +ooo superpowers test-driven-development --goal "Add retry behavior" +``` + +or natural language: + +```text +Use the Superpowers test-driven-development workflow to add retry behavior, then run the generated handoff. +``` + +## Current boundary + +As of `v0.1.8`, `ourocode` has the pieces needed for the first-class plugin UX, +but they are not connected end-to-end: + +- `Ourocode.Runtime.Router` recognizes core `ooo`/`ouroboros` workflow terms. +- `Ourocode.Runtime.OuroborosWorkflowInvocation` invokes seed/run style workflow + tools through the Ouroboros MCP path. +- `Ourocode.Command.Registry` can model plugin and dynamic-skill entries. +- `Ourocode.Terminal.EventLoop` can display plugin entries in discovery surfaces. +- Ouroboros owns the actual UserLevel plugin firewall, trust store, lockfile, and + fallback dispatch for `ooo ...`. + +The missing product boundary is a generic dispatch bridge from the `ourocode` +prompt loop into the installed Ouroboros plugin dispatcher. + +## Proposed architecture + +Add a `UserLevelPluginInvocation` path that is separate from core workflow +invocations. + +```text +Prompt text + -> TaskRequest / Router + -> plugin-intent resolution + -> installed plugin registry lookup + -> safe Ouroboros plugin dispatch + -> child pane output + artifact capture + -> optional continuation into ooo run +``` + +### 1. Intent detection + +Support two entry shapes: + +1. **Direct command form** + - `ooo superpowers list` + - `ooo superpowers inspect brainstorming` + - `ooo superpowers test-driven-development --goal "Add retry behavior"` +2. **Natural-language form** + - “Use superpowers TDD for this task” + - “Run the Superpowers systematic debugging workflow on this flaky test” + +Direct command form should be deterministic. Natural-language form should only +route when an installed plugin name and a known command/skill name can be +resolved confidently; otherwise it should ask for a clarification or fall back to +normal `ooo` workflow routing. + +### 2. Registry and trust resolution + +`ourocode` should not reimplement plugin trust semantics. It should ask +Ouroboros for the installed plugin state using a stable boundary, in priority +order: + +1. an Ouroboros MCP/CLI API dedicated to plugin dispatch and inspection, or +2. the existing Ouroboros CLI plugin dispatcher as a compatibility layer. + +Missing trust should render the exact remedial command reported by Ouroboros, +for example: + +```bash +ouroboros plugin trust superpowers --scope filesystem:read --scope filesystem:write +``` + +`ourocode` must not silently grant trust scopes. + +### 3. Dispatch + +Dispatch must go through the Ouroboros plugin firewall. `ourocode` should not +execute arbitrary shell strings assembled from natural language. + +The invocation result should be represented as a normal child session/pane event +stream so the user sees: + +- the selected plugin and command, +- trust/permission state, +- stdout/stderr or structured output, +- generated artifact paths, +- blocked or failed status with actionable guidance. + +### 4. Artifact capture + +Many AgentOS-style plugins prepare handoff artifacts rather than performing the +final implementation directly. `superpowers` writes artifacts under: + +```text +.omx/superpowers/runs// + invocation.json + provenance.json + handoff.md + seed.md + evidence.json + audit.jsonl +``` + +`ourocode` should detect generated `seed.md` or equivalent Seed-compatible +artifacts from the plugin result and surface the continuation: + +```text +ooo run seed_path=.omx/superpowers/runs//seed.md +``` + +### 5. Continuation policy + +The first implementation should keep continuation conservative: + +- read-only plugin commands stop after rendering output, +- handoff-generating plugin commands show the detected `ooo run` next step, +- automatic continuation into `ooo run` is allowed only when the prompt + explicitly requests it, such as “then run the generated handoff”, +- destructive plugin actions remain blocked unless a future command declaration + and trust UX explicitly allow them. + +## Example flows + +### Direct command, read-only + +```text +user: ooo superpowers inspect test-driven-development +ourocode: dispatches installed plugin via Ouroboros firewall +ourocode: renders skill metadata and permissions +``` + +### Direct command, handoff generation + +```text +user: ooo superpowers test-driven-development --goal "Add retry behavior" +ourocode: dispatches plugin +ourocode: renders generated run directory +ourocode: suggests `ooo run seed_path=.../seed.md` +``` + +### Natural language with continuation + +```text +user: Use Superpowers test-driven-development to add retry behavior, then run the generated handoff. +ourocode: resolves plugin=superpowers, command=test-driven-development +ourocode: dispatches plugin and captures seed.md +ourocode: invokes the existing `ooo run` path with the generated seed +``` + +## Acceptance tests + +A first implementation should cover: + +1. Router classification for direct `ooo ...` prompts. +2. Natural-language resolution when plugin and command names are unambiguous. +3. Trust-blocked plugin output with the exact remedial trust command. +4. Dispatch payload construction without shell-string injection. +5. Artifact detection for `.omx//runs//seed.md`. +6. Continuation policy: suggest vs auto-run. +7. A `superpowers` fixture that proves `test-driven-development` can produce a + detected handoff path. + +## Non-goals + +- Installing or trusting plugins automatically. +- Creating a plugin marketplace UI. +- Replacing Ouroboros plugin firewall semantics. +- Executing destructive plugin actions in the initial bridge. From 41cd7e941cb72a0fc3a9767a78f50ce127da8d4f Mon Sep 17 00:00:00 2001 From: shaun0927 <70629228+shaun0927@users.noreply.github.com> Date: Mon, 25 May 2026 16:55:17 +0900 Subject: [PATCH 2/2] docs(plugin-dispatch): rescope around SSOT #25 and 5-PR plan Re-anchor the userlevel plugin dispatch document on the orchestration SSOT (#25) and docs/product-vision.md, replacing the implementation phasing section with the five-PR breakdown that this document drives. Notes the existing read-only slash-command CapabilityPreflight as the sibling layer that already handles / input, and scopes this document to the ooo-prefixed dispatch path that is still missing. Records the deferred vision issues (#19, #22, #24) with their trigger conditions so they stay open without blocking implementation work. Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/userlevel-plugin-dispatch.md | 367 +++++++++++++++++------------- 1 file changed, 205 insertions(+), 162 deletions(-) diff --git a/docs/userlevel-plugin-dispatch.md b/docs/userlevel-plugin-dispatch.md index 23e764b..3f4461b 100644 --- a/docs/userlevel-plugin-dispatch.md +++ b/docs/userlevel-plugin-dispatch.md @@ -1,183 +1,226 @@ # UserLevel Plugin Dispatch in Ourocode -Issue: https://github.com/Q00/ourocode/issues/2 +Tracks the operational plan for adding `ooo ...` dispatch to +the interactive terminal. The product boundary lives in `docs/product-vision.md` +and SSOT issue +[#25](https://github.com/Q00/ourocode/issues/25); this document is one vertical +slice under that SSOT and is intentionally scoped to the UserLevel plugin +dispatch path. + +Originating request: [#2](https://github.com/Q00/ourocode/issues/2) (closed as +superseded). Umbrella vision issues #4, #6, #12, #13, and #14 restate the same +direction and are closed in favor of #25. ## Goal `ourocode` should let users run installed Ouroboros UserLevel plugins from the -terminal UI with either direct `ooo ...` prompts or natural language. -A user should not need to leave `ourocode`, run a shell command, find generated -handoff artifacts, and then manually re-enter `ooo run`. +terminal UI with direct `ooo ...` prompts. A user should not need to +leave `ourocode`, run a shell command, find generated handoff artifacts, and +then manually re-enter `ooo run`. -The motivating example is Q00/ouroboros-plugins `superpowers`: +The motivating example is `Q00/ouroboros-plugins` `superpowers`: ```text ooo superpowers test-driven-development --goal "Add retry behavior" ``` -or natural language: - -```text -Use the Superpowers test-driven-development workflow to add retry behavior, then run the generated handoff. -``` - -## Current boundary - -As of `v0.1.8`, `ourocode` has the pieces needed for the first-class plugin UX, -but they are not connected end-to-end: - -- `Ourocode.Runtime.Router` recognizes core `ooo`/`ouroboros` workflow terms. -- `Ourocode.Runtime.OuroborosWorkflowInvocation` invokes seed/run style workflow - tools through the Ouroboros MCP path. -- `Ourocode.Command.Registry` can model plugin and dynamic-skill entries. -- `Ourocode.Terminal.EventLoop` can display plugin entries in discovery surfaces. -- Ouroboros owns the actual UserLevel plugin firewall, trust store, lockfile, and - fallback dispatch for `ooo ...`. - -The missing product boundary is a generic dispatch bridge from the `ourocode` -prompt loop into the installed Ouroboros plugin dispatcher. - -## Proposed architecture - -Add a `UserLevelPluginInvocation` path that is separate from core workflow -invocations. - -```text -Prompt text - -> TaskRequest / Router - -> plugin-intent resolution - -> installed plugin registry lookup - -> safe Ouroboros plugin dispatch - -> child pane output + artifact capture - -> optional continuation into ooo run -``` - -### 1. Intent detection - -Support two entry shapes: - -1. **Direct command form** - - `ooo superpowers list` - - `ooo superpowers inspect brainstorming` - - `ooo superpowers test-driven-development --goal "Add retry behavior"` -2. **Natural-language form** - - “Use superpowers TDD for this task” - - “Run the Superpowers systematic debugging workflow on this flaky test” - -Direct command form should be deterministic. Natural-language form should only -route when an installed plugin name and a known command/skill name can be -resolved confidently; otherwise it should ask for a clarification or fall back to -normal `ooo` workflow routing. - -### 2. Registry and trust resolution - -`ourocode` should not reimplement plugin trust semantics. It should ask -Ouroboros for the installed plugin state using a stable boundary, in priority -order: - -1. an Ouroboros MCP/CLI API dedicated to plugin dispatch and inspection, or -2. the existing Ouroboros CLI plugin dispatcher as a compatibility layer. - -Missing trust should render the exact remedial command reported by Ouroboros, -for example: - -```bash -ouroboros plugin trust superpowers --scope filesystem:read --scope filesystem:write -``` - -`ourocode` must not silently grant trust scopes. - -### 3. Dispatch - -Dispatch must go through the Ouroboros plugin firewall. `ourocode` should not -execute arbitrary shell strings assembled from natural language. - -The invocation result should be represented as a normal child session/pane event -stream so the user sees: - -- the selected plugin and command, -- trust/permission state, -- stdout/stderr or structured output, -- generated artifact paths, -- blocked or failed status with actionable guidance. - -### 4. Artifact capture - -Many AgentOS-style plugins prepare handoff artifacts rather than performing the -final implementation directly. `superpowers` writes artifacts under: - -```text -.omx/superpowers/runs// - invocation.json - provenance.json - handoff.md - seed.md - evidence.json - audit.jsonl -``` - -`ourocode` should detect generated `seed.md` or equivalent Seed-compatible -artifacts from the plugin result and surface the continuation: - -```text -ooo run seed_path=.omx/superpowers/runs//seed.md -``` - -### 5. Continuation policy - -The first implementation should keep continuation conservative: - -- read-only plugin commands stop after rendering output, -- handoff-generating plugin commands show the detected `ooo run` next step, -- automatic continuation into `ooo run` is allowed only when the prompt - explicitly requests it, such as “then run the generated handoff”, -- destructive plugin actions remain blocked unless a future command declaration - and trust UX explicitly allow them. - -## Example flows - -### Direct command, read-only - -```text -user: ooo superpowers inspect test-driven-development -ourocode: dispatches installed plugin via Ouroboros firewall -ourocode: renders skill metadata and permissions -``` - -### Direct command, handoff generation +or, when the user explicitly opts into continuation: ```text -user: ooo superpowers test-driven-development --goal "Add retry behavior" -ourocode: dispatches plugin -ourocode: renders generated run directory -ourocode: suggests `ooo run seed_path=.../seed.md` +ooo superpowers test-driven-development --goal "..." then run the generated handoff ``` -### Natural language with continuation - -```text -user: Use Superpowers test-driven-development to add retry behavior, then run the generated handoff. -ourocode: resolves plugin=superpowers, command=test-driven-development -ourocode: dispatches plugin and captures seed.md -ourocode: invokes the existing `ooo run` path with the generated seed -``` - -## Acceptance tests - -A first implementation should cover: - -1. Router classification for direct `ooo ...` prompts. -2. Natural-language resolution when plugin and command names are unambiguous. -3. Trust-blocked plugin output with the exact remedial trust command. -4. Dispatch payload construction without shell-string injection. -5. Artifact detection for `.omx//runs//seed.md`. -6. Continuation policy: suggest vs auto-run. -7. A `superpowers` fixture that proves `test-driven-development` can produce a - detected handoff path. +Free-form natural-language dispatch ("Use Superpowers TDD for this change") is +deferred until the exact-match path is stable. Slash-shaped `/superpowers ...` +input continues to flow through the existing +`Ourocode.Command.CapabilityPreflight` slash-command surface; the work in this +document adds a sibling path for `ooo`-prefixed input that the slash surface +does not cover. + +## Current boundary (as of `release/bootstrap` v0.1.11) + +`ourocode` already has most of the pieces it needs and is missing the +UserLevel-specific bridge. + +In place upstream: + +- `Ourocode.Runtime.Router` classifies `ooo`/`ouroboros` shortcuts into + `interview`, `seed`, `run`, `evolve`, `ralph`, and `workflow` adapter routes. +- `Ourocode.Runtime.Dispatcher` enforces shell-injection guards + (`@forbidden_external_commands`, `@shell_commands`) for any external command + runner the adapters call. +- `Ourocode.Runtime.OuroborosWorkflowInvocation` already invokes the MCP + `ouroboros_generate_seed` and `ouroboros_start_execute_seed` tools and is the + natural continuation target for plugin-generated seeds. +- `Ourocode.Command.Registry` models a `:plugin` source with normalized + command entries, args, aliases, run_spec, and trust metadata. +- `Ourocode.Command.CapabilityPreflight` resolves slash-shaped (`/foo`) + command input read-only and projects trust state via + `CapabilityPreflight.Trust` and `CapabilityPreflight.Projection`. +- `Ourocode.Plugin.*` loads declarative plugin mappings (adapter / action / + renderer) and the CLI bootstrap now loads `.ourocode/config.json` plugin + entries during startup. + +Still missing for UserLevel plugin dispatch: + +- A discovery surface that asks Ouroboros (CLI today, MCP tomorrow) which + UserLevel plugins are installed, which commands they expose, and which + artifacts they may produce. +- An execution route for `ooo ...` that is distinct from + the existing Ouroboros workflow shortcuts and from the slash-command surface. +- A dispatch adapter that turns a preflight result into an argv invocation + through `Dispatcher.guarded_external_command_runner` and streams output into + a child pane. +- Trust-blocked rendering that surfaces the exact `ouroboros plugin trust ...` + remediation without granting trust on the user's behalf. +- Detection of plugin-generated artifacts (such as `seed.md`) and an + intent-gated continuation into `ooo run seed_path=...`. + +## Implementation plan + +The work is split into five reviewable PRs that build on each other. Each PR +keeps the SSOT primitives in #25 intact and adds exactly one new primitive. + +### PR 1 — vision normalization (this PR) + +Pure docs and issue hygiene. No code changes. + +- Re-anchor this document on #25 and the in-tree `docs/product-vision.md`. +- Close umbrella restatement issues (#4, #6, #12, #13, #14) as + superseded by #25. +- Inject the PR breakdown into the SSOT issue task list so progress is visible. + +Closes none of the implementation-shaped issues by itself; unblocks all later +PRs by giving them a single shared framing. + +### PR 2 — UserLevel plugin capability layer + +Adds the `Ourocode.Plugin.UserLevel.*` namespace. + +- `Capability` and `CommandCapability` structs that record plugin identity + (id, source, version, install scope, trust scope, manifest digest) and + per-command metadata (name, aliases, args, risk class, expected artifacts, + continuation hint). +- `Discovery` behaviour with an `OuroborosCLI` adapter that calls + `ouroboros plugin list --json` through the existing guarded external command + runner. Failure surfaces as a `:degraded` registry status rather than a + startup crash. +- `Registry` Agent that caches the latest capability list with a 60 s TTL, + invalidates on `Plugin.ConfigWatcher` signals, and exposes a manual + `/plugins refresh` slash command. +- A wiring step that publishes UserLevel capabilities into the existing + `Command.Registry` `:plugin` source so the upstream + `CapabilityPreflight` and `/preflight` surfaces immediately see them. + +Closes #5, #8, #9, #18, #27, #29. + +### PR 3 — preflight resolver and router glue + +Adds the `ooo`-prefixed resolution path that the existing slash-shaped +preflight does not cover. + +- `PreflightResult` struct mirroring the upstream slash-shaped projection but + scoped to `ooo`-shaped input. +- `Resolver` pure function that turns a `TaskRequest` into a `PreflightResult` + with kind `:unique_match`, `:ambiguous`, or `:unknown`, including trust + state and remediation text. +- A `:user_level_plugin` execution route in `Router` and `Dispatcher` + triggered only when the second token exactly matches a known plugin name. +- Tests cover unique match, ambiguous match, unknown plugin, missing trust, + and shell-injection input. + +Closes #16, #23. + +### PR 4 — dispatch adapter, trust UX, Superpowers vertical slice + +Connects the resolver to actual execution. + +- `Ourocode.Runtime.UserLevelPluginInvocation` adapter that implements + `Ourocode.Runtime.Adapter` and translates a preflight result into an argv + invocation through `Dispatcher.guarded_external_command_runner`. +- `PreflightPanel` TUI module that renders the preflight (plugin, command, + args, risk class, trust state, expected artifacts) and surfaces the exact + `ouroboros plugin trust ...` remediation when trust is missing. No silent + grants. +- A `superpowers` discovery fixture so `ooo superpowers list` can run end to + end in tests. + +Closes #15, #17 (minimal trust-blocked structured error path), #20, #21. + +### PR 5 — artifact capture, continuation policy, decision journal + +Closes the loop from dispatch to follow-up workflow. + +- `ArtifactWatcher` that scans `Capability.expected_artifacts` after the + plugin run completes, producing `%Artifact{}` records attached to the + current session. +- `Continuation` policy module: read-only commands stop, handoff-producing + commands suggest `ooo run seed_path=...`, and the suggestion runs + automatically only when the user's prompt explicitly opted in (for example, + "then run the generated handoff"). +- `DecisionJournal` appends one structured event per phase + (`:preflight`, `:dispatch`, `:artifact`, `:continuation`) into the existing + `lib/ourocode/journal/` writer. + +Closes #7, #10, #11, #26, #28. + +## Deferred (no PR yet) + +The following vision issues are valuable but premature given current usage +signal. Each is left open with a `defer:awaiting-signal` note that records the +trigger condition under which it should ship. + +- #19 — recipes: ships after a recurring user pattern emerges (same plugin + command invoked five or more times by the same user with the same shape). +- #22 — context packets: ships after a plugin declares an `accepts_context` + capability so leakage versus underuse is observable. +- #24 — durable sessions and full failure recovery: ships when long-running + (greater than 10 minute) plugin invocations or plugin-side pause/resume + hooks appear. + +## Continuation policy (PR 5 specifics) + +Continuation behavior is intentionally conservative. + +- A command whose declared risk class is `:read_only` finishes after rendering + output. No follow-up is offered. +- A command whose declared risk class is `:handoff_producing` triggers + artifact watching. If a `seed.md` or other declared artifact is found, the + continuation card shows the exact `ooo run seed_path=...` command. +- The continuation runs automatically only when the original prompt contains + an explicit opt-in token such as "then run the generated handoff" or the + Korean "이어서 실행". Otherwise it waits for user confirmation. +- A command whose declared risk class is `:destructive` requires explicit + user approval inside the preflight panel before dispatch and never + auto-continues. + +## Acceptance tests carried into PR 4 and PR 5 + +Carried forward from the original #2 acceptance criteria, rescoped to fit the +plan above. + +1. From inside `ourocode`, `ooo superpowers list` invokes the installed + `superpowers` plugin (or a discovery fixture in tests) and renders output + in a child pane. +2. From inside `ourocode`, `ooo superpowers test-driven-development --goal "..."` + surfaces the preflight, dispatches the plugin, and detects the + declared `seed.md` artifact through `Capability.expected_artifacts`. +3. When a plugin command generates a seed artifact, `ourocode` shows the + suggested `ooo run seed_path=...` continuation and only auto-runs it when + the prompt opted in. +4. Missing or untrusted plugin states render the exact + `ouroboros plugin trust ... --scope ...` remediation string and do not + grant trust silently. +5. Shell injection attempts in plugin arguments are passed through as argv + tokens; `Dispatcher.guarded_external_command_runner` guards remain green. ## Non-goals - Installing or trusting plugins automatically. -- Creating a plugin marketplace UI. -- Replacing Ouroboros plugin firewall semantics. +- Creating a plugin marketplace or catalog UI. +- Replacing Ouroboros plugin firewall semantics inside `ourocode`. - Executing destructive plugin actions in the initial bridge. +- Free-form natural-language dispatch beyond exact plugin-name plus + command-name token matching. +- Inferring plugin-internal storage paths; `ourocode` only trusts the + `expected_artifacts` glob list a capability declares.