Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

225 changes: 167 additions & 58 deletions docs/SmokeTests.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ execution.
- `session_execute`, `session_execute_file`, and `session_batch_execute` return
a bounded human-readable summary plus references, never an unbounded raw
payload.
- Tool response body budget: 8 KB maximum serialized response payload per
- Tool response body budget: 32 KB maximum serialized response payload per
`session_*` call.
- Large execution/fetch/file artifacts are stored locally and referenced by
artifact or corpus ID.
Expand Down Expand Up @@ -238,7 +238,9 @@ enforcement-hook rewrite.
- `session_fetch_and_index`
- `session_stats`
- `session_doctor`
2. Every request schema must require `root_session_id`.
2. Superseded by later runtime contract changes: public request schemas no
longer accept `root_session_id`; canonical root-session identity is resolved
implicitly from runtime context.
3. Every response schema must include `status` and enough metadata to attribute
results later in hooks.
4. Add a runtime module in `src/services/session-mcp-runtime.ts` that:
Expand Down Expand Up @@ -278,11 +280,11 @@ Write failing tests first in `src/services/session-mcp-runtime.test.ts` and
`src/index.test.ts` covering:

- runtime registers exactly the 8 `session_*` tools
- each tool schema rejects calls without `root_session_id`
- each tool schema rejects caller-supplied `root_session_id`
- initial stub handlers return minimal valid responses for all 8 registered
tools
- response payloads are capped to the exact 8 KB response budget
- at least one large-output case crossing the 8 KB boundary falls back to local
- response payloads are capped to the exact 32 KB response budget
- at least one large-output case crossing the 32 KB boundary falls back to local
artifact storage/reference instead of returning an oversized inline payload
- `session_batch_execute` executes sequentially in request order
- `src/index.ts` wires runtime initialization and teardown in-process
Expand Down Expand Up @@ -481,12 +483,13 @@ shared across parent/child sessions.
### 7.3 Implementation requirements

1. Reuse `SessionManager` as the only canonical lineage authority.
2. `tool.execute.before` must inject `root_session_id` into every `session_*`
call using canonical resolution from `src/session.ts`.
3. The `session_*` runtime must reject mismatched or missing `root_session_id`
after schema validation; it must not invent a second lineage model.
4. All corpus/artifact/stats writes must use `root_session_id`, never the raw
child session ID.
2. `tool.execute.before` must preserve canonical root-session context for every
`session_*` call using canonical resolution from `src/session.ts`.
3. The `session_*` runtime must resolve canonical root-session identity from
runtime context; callers must not supply `root_session_id`, and the runtime
must not invent a second lineage model.
4. All corpus/artifact/stats writes must use the canonical root session ID,
never the raw child session ID.
5. Parent and child sessions must read from the same root corpus namespace.
6. Temporary-root sessions must remain supported until later migration work in
Task 6.
Expand All @@ -498,10 +501,11 @@ Write failing tests first in `src/session.test.ts`,
covering:

- parent and child `session_*` calls share one root corpus namespace
- `tool.execute.before` injects `root_session_id` on `session_*` calls
- `tool.execute.before` keeps `session_*` calls rooted in canonical session
context without mutating public args
- native tool calls do not receive `root_session_id`
- the runtime rejects `session_*` calls when `root_session_id` is absent or
mismatched
- the runtime rejects caller-supplied `root_session_id` and resolves canonical
root identity from context

### 7.5 Verification commands

Expand Down Expand Up @@ -623,7 +627,8 @@ model toward `session_*` tools and attributes outcomes cleanly.
### 9.3 Implementation requirements

1. Keep `session_*` calls simple in `tool.execute.before`:
- inject canonical `root_session_id`
- preserve canonical root-session context without injecting public
`root_session_id` args
- allow the call to proceed
2. Rewrite native-tool policy so it is explicitly secondary:
- `WebFetch` -> deny with direct guidance to `session_fetch_and_index`
Expand All @@ -643,7 +648,8 @@ model toward `session_*` tools and attributes outcomes cleanly.

Write failing tests first in the existing hook/routing test files covering:

- `session_*` calls are allowed with injected `root_session_id`
- `session_*` calls are allowed with canonical root-session context and without
caller-supplied `root_session_id`
- `WebFetch` is denied toward `session_fetch_and_index`
- data-heavy `Bash` is routed toward `session_execute`
- `Task` prompt rewriting adds MCP-first routing guidance
Expand Down Expand Up @@ -839,7 +845,7 @@ This cleanup is mandatory and not optional follow-up polish.
enforcement layer only.
2. Retain `src/handlers/tool-before.ts` and `src/handlers/tool-after.ts`, but
narrow them to:
- `root_session_id` injection for `session_*`
- canonical root-session context handling for `session_*`
- native fallback enforcement
- routing attribution metadata
3. Retain `src/session.ts` as lineage authority and extend it for corpus/state
Expand Down
56 changes: 30 additions & 26 deletions docs/superpowers/plans/2026-03-20-context-mode-mcp-first.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,16 +209,16 @@ in this repository.

### 5.1 Tool suite and exact role

| Tool | Role | Primary inputs | Primary outputs | Notes |
| ------------------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------ | ------------------------------------------------------------ | ----------------------------------------------------- |
| `session_execute` | Run one bounded sandbox execution task | command/script, runtime, intent, timeout, `root_session_id` | bounded result, summary, optional artifact/index handle | primary replacement for raw data-heavy Bash workflows |
| `session_execute_file` | Run one bounded sandbox file-processing task | path(s), processing intent, runtime/handler, `root_session_id` | findings, summary, optional artifact/index handle | primary replacement for raw file-dump analysis |
| `session_batch_execute` | Combine multiple execute/search sub-operations into one call | list of execute/search/file subrequests, `root_session_id` | bounded multi-result response + handles | sequential in v1; no hidden parallelism |
| `session_index` | Normalize and locally index supplied content into the hot-tier corpus | content or pre-normalized text, source metadata, `root_session_id` | corpus id, chunk count, query hints | local-only indexing; no Graphiti involvement |
| `session_search` | Query the local indexed corpus for the canonical root session | query or query list, optional corpus filters, `root_session_id` | ranked bounded snippets + corpus/chunk refs | searches only local session-scoped indexed data |
| `session_fetch_and_index` | Fetch a URL in sandbox, normalize it, then index it locally | url, fetch options, content-type hint, `root_session_id` | corpus id, summary, query hints | primary replacement for native `WebFetch` |
| `session_stats` | Show local context-savings and tool/index activity for the root session | optional scope, `root_session_id` | counters, byte ratios, corpus counts, queue depth | in scope |
| `session_doctor` | Diagnose MCP/plugin/hot-tier health | optional checks, `root_session_id` | health report for Redis, hooks, cache, Graphiti connectivity | in scope |
| Tool | Role | Primary inputs | Primary outputs | Notes |
| ------------------------- | ----------------------------------------------------------------------- | ----------------------------------------------- | ------------------------------------------------------------ | --------------------------------------------------------------------------- |
| `session_execute` | Run one bounded sandbox execution task | command/script, runtime, intent, timeout | bounded result, summary, optional artifact/index handle | canonical root session resolves implicitly from runtime context |
| `session_execute_file` | Run one bounded sandbox file-processing task | path(s), processing intent, runtime/handler | findings, summary, optional artifact/index handle | canonical root session resolves implicitly from runtime context |
| `session_batch_execute` | Combine multiple execute/search sub-operations into one call | list of execute/search/file subrequests | bounded multi-result response + handles | sequential in v1; no hidden parallelism; canonical root resolves implicitly |
| `session_index` | Normalize and locally index supplied content into the hot-tier corpus | content or pre-normalized text, source metadata | corpus id, chunk count, query hints | local-only indexing; no Graphiti involvement |
| `session_search` | Query the local indexed corpus for the canonical root session | query or query list, optional corpus filters | ranked bounded snippets + corpus/chunk refs | searches only local session-scoped indexed data |
| `session_fetch_and_index` | Fetch a URL in sandbox, normalize it, then index it locally | url, fetch options, content-type hint | corpus id, summary, query hints | primary replacement for native `WebFetch` |
| `session_stats` | Show local context-savings and tool/index activity for the root session | optional scope | counters, byte ratios, corpus counts, queue depth | in scope |
| `session_doctor` | Diagnose MCP/plugin/hot-tier health | optional checks | health report for Redis, hooks, cache, Graphiti connectivity | in scope |

### 5.2 Scope decision for `session_upgrade`

Expand All @@ -240,10 +240,12 @@ replacement milestone, the validation bar, or the migration work.
The following defaults are mandatory unless later superseded by a narrower
implementation plan:

1. Every `session_*` tool must accept `root_session_id`.
2. In OpenCode, the plugin must populate `root_session_id` in
`tool.execute.before` for every `session_*` call using canonical root-session
resolution from `src/session.ts`.
1. Every public `session_*` tool request resolves the canonical root session
implicitly from runtime context; callers must not pass `root_session_id`.
2. In OpenCode, the plugin/runtime must preserve canonical root-session context
for every `session_*` call using canonical root-session resolution from
`src/session.ts`, without mutating the public request contract to require
`root_session_id`.
3. `session_*` tools are session-scoped by default; they do not create
indefinite project-wide local corpora.
4. If a full result exceeds the bounded response budget, the tool must
Expand Down Expand Up @@ -523,14 +525,14 @@ architecture” to “enforcement + continuity around the MCP-first runtime.”

### 7.1 Hook responsibilities

| Hook | Required role in the new model |
| -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `tool.execute.before` | populate canonical `root_session_id` on `session_*` calls; enforce fallback from risky native tools toward `session_*`; never become the main execution engine |
| `tool.execute.after` | capture bounded tool events, context-savings stats, artifact refs, and routing outcomes; never rewrite large raw output after the fact as the primary mechanism |
| `chat.message` | assemble local `<session_memory>` from events, snapshot, and cached persistent memory; schedule async refresh decisions only |
| `experimental.chat.messages.transform` | prepend the prepared `<session_memory>` envelope to the last user message |
| `experimental.session.compacting` | inject the same prepared local continuity envelope into compaction |
| `event` | capture user/assistant/session lifecycle events, maintain canonical root-session lineage state, schedule snapshot rebuilds and async Graphiti drain |
| Hook | Required role in the new model |
| -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `tool.execute.before` | preserve canonical root-session context for `session_*` calls and enforce fallback from risky native tools toward `session_*`; never become the main execution engine |
| `tool.execute.after` | capture bounded tool events, context-savings stats, artifact refs, and routing outcomes; never rewrite large raw output after the fact as the primary mechanism |
| `chat.message` | assemble local `<session_memory>` from events, snapshot, and cached persistent memory; schedule async refresh decisions only |
| `experimental.chat.messages.transform` | prepend the prepared `<session_memory>` envelope to the last user message |
| `experimental.session.compacting` | inject the same prepared local continuity envelope into compaction |
| `event` | capture user/assistant/session lifecycle events, maintain canonical root-session lineage state, schedule snapshot rebuilds and async Graphiti drain |

### 7.2 Hook interaction sequence

Expand All @@ -544,7 +546,7 @@ architecture” to “enforcement + continuity around the MCP-first runtime.”

3. tool call selected by the model
a. tool.execute.before
- if tool is session_*: inject canonical root_session_id and allow
- if tool is session_*: route using canonical session context and allow
- if tool is risky native fallback: redirect/deny toward session_*
- if tool is safe bounded native fallback: allow
b. tool runs
Expand Down Expand Up @@ -582,7 +584,9 @@ continuity concept. The new architecture must reuse that logic.
Rule:

- the plugin is authoritative for canonical root-session identity in OpenCode
- `tool.execute.before` must add `root_session_id` to all `session_*` tool calls
- `tool.execute.before` / runtime wiring must preserve canonical root-session
context for all `session_*` tool calls without exposing `root_session_id` as a
required public request field
- `tool.execute.after` and `event` must attribute all resulting continuity
events, stats, corpora, and artifacts to that same canonical root session

Expand Down Expand Up @@ -929,8 +933,8 @@ The implementation/tasks must explicitly prevent these drift modes.
3. **Child-session split brain**\
Symptom: child `session_*` calls create separate corpora or stats outside the
root session.\
Prevention: plugin-injected `root_session_id` is mandatory for all
`session_*` calls; no alternative local-session namespace is allowed.
Prevention: canonical root resolution from runtime context is mandatory for
all `session_*` calls; no alternative local-session namespace is allowed.

4. **Temporary-root orphaning**\
Symptom: artifacts indexed before lineage resolution remain under obsolete
Expand Down
Loading
Loading