Skip to content

feat(mcp): select policy-approved presets without widening routes - #364

Merged
abruption merged 23 commits into
mainfrom
feat/mcp-359-presets
Nov 2, 2026
Merged

abruption merged 23 commits into
mainfrom
feat/mcp-359-presets

Conversation

@abruption

Copy link
Copy Markdown
Owner

Summary

Adds list_presets(destination) and optional preset/revision route selectors to existing MCP listing, preflight and sending. Policy v2 must explicitly grant presets and a nonempty allowlist of at most 128 approved names; existing action permissions are also required. V1/default permissions do not expand.

Preset inspection is a separate bounded, versioned allowlist projection: name, declared agent/transport and the existing dp1: route revision. It does not expose raw hosts/homes/store paths, discover sessions, probe, create/repair storage or authorize sending. Any missing/off-policy approved item refuses the whole query atomically.

Selection reads one validated snapshot through the existing secure reader, intersects exact host/agent/Codex home with policy, and rechecks effective policy before invocation. It checks route authorization before comparing the caller's revision, preventing an off-policy route-value guessing oracle. Actual sends require an explicit target and matching revision; no wake/URI/Antigravity/device/handoff/Windows or management expansion. Store mutation after expansion cannot retroactively cancel that invocation; policy is loaded at startup, not hot-reloaded from disk.

Presets are only route selectors for existing list_sessions/send_message: successful responses retain their existing native CLI schema and authorized payload, not a new mcp.preset.* projection. Only list_presets and selected preflight produce safe preset metadata. Metadata query permission alone cannot disclose native listing/send results. Native submission evidence is not replaced by a metadata-size refusal. Decode/I/O uncertainty becomes outcome_unknown, submitted=null, retryAllowed=false unless primary queued/posted/submitted facts are already known; such facts remain intact. Cancellation propagates without a second invocation.

Refs #359. Depends on #363; stacked base feat/mcp-358-diagnostics. Requires normal approval/merge of predecessors, retargeting and current-main checks before any merge. No issue closure requested.

Validation

  • macOS arm64/Python 3.13.7/MCP 1.30.0: final focused source/stdio/preflight suite 68 tests, 1 local skip; documentation 87 passed; final tool-description check passed. Generator, manifest/i18n and diff checks pass. Core secure-store and generated CLI code are unchanged by this slice.
  • Real stdio fixtures cover approved-only projection, route mismatch, stale revision, explicit policy roles, 128-name result bounds, policy revocation during resolution (invocation forbidden) and later snapshot mutation followed by exactly one owned synthetic Unix-inbox post. Existing native response/consumption distinction is preserved.
  • Real-store positive cell: creates an isolated 0700 config directory/0600 store, then tests metadata/revision → actual CLI list/preflight with zero post → exactly one synthetic inbox send. On this local external volume it is explicitly skipped, because the unchanged guard rejects a stat-verified group-writable ancestor before mount ownership inspection. No chmod of ancestors, guard mock, alternative internal temp root or fallback was used. GITHUB_ACTIONS=true does not permit guard-skipping, so supported CI cells must execute it successfully.
  • Negative real-store missing/unsafe/symlink cases preserve files/targets and create no lock or repair. Local refusal is observed at the ancestor guard; it is not claimed as independent reachability proof of later file/ACL/symlink checks. Existing secure-store tests cover those contracts separately.
  • Wrong-role/name/agent/wake/URI and missing revision refuse before store or native invocation as applicable. Schema/limits/error and optional-SDK/platform guards are covered. No live native agent, actual SSH, model, real user preset or operating installation was used. Synthetic snapshots are not filesystem acceptance evidence.

Independent review

Used independent-cli-review: Claude Code 2.1.314 requested and response-confirmed claude-opus-5-5; Codex CLI 0.166.0 isolated default model (actual ID not exposed). Both pairs ran in parallel, non-interactively, on identical immutable inputs. Claude tools/MCP/hooks disabled; Codex ephemeral/read-only/ignore-user-config. All calls completed successfully; reviewers did not run tests or edit files.

  • First whole-change/store-consumer input SHA-256: bb8ed7fcf87f83eaed7e536d21b31544f061a0ce59b45cc1c478bdd3399e866f.
  • Revised input including real-store/stdio races: 59f4eb26203f50e77d8dffb36557122a9a0f1830082c984137c19265b04a2c3d.
  • Addressed new raw-response projection concerns by removing those projections and retaining only the unchanged, already-authorized legacy surfaces; added distinct safe metadata lookup instead. Fixed decoder uncertainty, explicit selector refusal codes, Windows test guards, real stdio integration, off-policy revision oracle and the tool-description consumption warning. Final small order/reason/docstring corrections followed the second review and were checked with focused tests; no third exact-byte CLI review is claimed.

Separate translation QA: Antigravity CLI 1.4.12 requested gemini-3.8-flash-medium, medium, fresh read-only plan+sandbox calls, 127.528 s and 133.275 s, structured success. Inputs were all eight changed localized document diffs against English. Codex checked claims/flags/limits and corrected Korean particles, Chinese routing terminology and candidate scope. No material semantic/authority mismatch remained in that review; runtime/native acceptance was not delegated to the translation model.

Boundaries

Revisions describe saved name/route values, not caller/recipient identity, native generation, effective storage, permission, consumption or ACK. The default remains local-list-only. No preset/address-book management, policy mutation, global installation, native session creation, automatic resend, merge, tag, release, package publication or operational rollout.

@abruption abruption added this to the v1.4.0 milestone Nov 2, 2026
@abruption abruption self-assigned this Nov 2, 2026
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-02T02:23:00.907517Z ffaf6de PR opened
🔒 Security Review ✅ Completed 2026-11-02T02:25:40.587836Z ffaf6de PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@abruption

Copy link
Copy Markdown
Owner Author

Final source ffaf6de: all 38 available checks succeeded, including the supported MCP matrix. Separately built wheel and sdist from this exact worktree, installed each to its own isolated target, and verified both module import paths originate in the installed tree. Real stdio smoke passed for all six tool schemas, metadata diagnostics, destination inventory and pre-effect policy/store refusal without creating a preset store. SDK dependencies reused the explicitly identified Python 3.13.7/MCP 1.30.0 verification environment; this is fresh project installation, not a new fully isolated dependency resolution. No user/global installation or native session was contacted. Automatic code/security review completed at this exact head with no posted findings/threads (security finding flags are unspecified, not asserted false). Sequential dependency and final-main checks remain necessary before merge.

Base automatically changed from feat/mcp-358-diagnostics to main November 2, 2026 02:54
@abruption

Copy link
Copy Markdown
Owner Author

Sequential integration after #363: base main, head 4241929. The main squash tree equals the previously included 29858dd base; integration preserved every reviewed ffaf6de byte (tree 4aa15d723201586b00e8629ee79a7076e9d7f57e). Generator and diff checks passed. Existing completed code/security review content is unchanged, not represented as a new review run at the integration SHA. Awaiting fresh current-head/main checks and normal protections before merge.

@abruption
abruption merged commit f290973 into main Nov 2, 2026
43 checks passed
@abruption
abruption deleted the feat/mcp-359-presets branch November 2, 2026 03:04
@abruption

Copy link
Copy Markdown
Owner Author

Owner-authorized sequential merge completed through normal branch protections: #362 → e68f1c8; #363 → 7f85cb1; #364 → f290973. Each main-base integration retained the exact previously reviewed Git tree, passed all 43 current-head checks and normal strict release-gate protection, and had no unresolved review threads. #362 received a fresh manual code review at 3b76b2e; later graph-only integrations use explicitly verified identical review content, not claimed as newly run SHA-specific reviews. No admin override or protection change. Final main CI https://github.com/abruption/session-peer/actions/runs/41381070618 (all 37 jobs including release gate) and CodeQL https://github.com/abruption/session-peer/actions/runs/41381070309 both succeeded on exact final SHA f290973. Final main bytes equal the reviewed full stack ffaf6de. No version/tag/release/package publication, installation or operating-service change was included.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant