feat: fleet governance adapter (SPEC-1b-2) — mcpDeny policy + gateway registration - #107
Merged
Merged
Conversation
…superseded vision patch
…ests (dev file: link, CI sibling job)
…reuses session settings store)
…tool precedence); PLAN spec pointer; README deferral one-liner
rz1989s
added a commit
that referenced
this pull request
Sep 3, 2026
Retire the superseded vision 0.5.2 pnpm patch (0.5.3 shipped with the lib-types fix; drops pnpm-workspace.yaml + patches/ riding the branch). Take main's @earendil-works/* ^0.84.4 alignment and the armory-gateway dev file: link from the governance adapter work.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fleet governance adapter (SPEC-1b-2)
Implements the fleet half of the armory-gateway MCP governance integration per
docs/SPEC-1b-2-fleet-governance-adapter.md(relocated intodocs/with this PR): when the (private, unpublished) gateway package is resolvable, fleet registers an MCP governance provider at session start; every MCP call through the gateway then passes fleet'smcpDenypolicy before executing. When the gateway is absent — the default for public fleet installs — registration is skipped silently and behavior is unchanged.What's in the box
@earendil-works/*deps aligned to^0.84.4(vision rider merged separately as subagent tool: failed explicit-model override returns empty output instead of a clean error #26).mcpDenysettings field (src/settings/fleet-settings.ts) — global (~/.pi/agent/fleet/settings.json) + project (<cwd>/.pi/fleet/settings.json, wins per-field); glob metacharacters in entries are rejected at parse time with an actionable warning (warn+drop, valid entries stay enforced).src/governance/mcp-policy.ts) — total function, no I/O: bareserverdenies every tool on that server;server__tooldenies one exact tool (exact-tool match takes precedence over a bare-server entry regardless of deny-list order); absent/empty list allows; malformed entries can never match (exact lookups only, no entry parsing at match time). Deny reason:denied by armory-fleet mcpDeny policy: matched "<entry>".src/governance/gateway-adapter.ts) — guarded dynamic import (the private specifier never appears in a static import, so public installs can't break at link time); identity-based provider (onlyserver/toolenter the matcher); deny list re-read fresh per call, so policy edits take effect without re-registration.src/index.ts) — registration reuses the session's ownFleetSettingsStore(cwd-correct project path), idempotent under the gateway's replace-semantics.file:../armory-gatewaydevDependency for contract tests; CI gains a sibling-clone step (token-authenticated) placed beforepnpm install --frozen-lockfile, nocontinue-on-error.docs/with the two as-built deviations folded in (glob-metachar rejection, exact-tool precedence).Acceptance (SPEC §13)
^0.84.4:pnpm typecheck && pnpm test:run(this repo's actual gate); new test files flat intest/so the glob picks them up.Symbol.forstore; absent-gateway silent skip.@getpipher/armory-gatewayanywhere in fleetsrc/— the only occurrence is the guardedimport()inside the adapter.mcpDenydocumented with examples.Verification
f16269a):pnpm typecheckclean,pnpm test:run856/856 pass, 0 fail (849 prior + 6 gateway contract tests + 1 wiring-shape test).file:../armory-gateway, skipped 0 locally) — including duplicate-instance convergence through the cache-busted second module URL.SIBLINGS_PAT, already set on the repo) required by the committedfile:devDependency under--frozen-lockfile.Deliberately deferred (named in SPEC §14–15, durable record)
ARMORY_AGENT_ID/ARMORY_TASK_IDenv emission — no reading code path exists today (pi children are in-processnoExtensionssessions; claude children never load the gateway). Revival gated on child MCP access + a concurrency-safe context mechanism.