feat(security): R-07 - wire the managed model/provider allowlist fail-closed + pin omp's provider catalog - #348
Open
alexander-blackwell wants to merge 1 commit into
Conversation
alexander-blackwell
marked this pull request as ready for review
September 4, 2026 00:09
…-closed + pin omp's provider catalog Closes #347. Core-side work for the add-on's R-07 provider-governance risk item (add-on #36, POAM R-07). The ManagedModels allowed/denied schema (ADR-0068, P-ENT.1) shipped ready-to- consume but modelAllowed() had zero live call sites: the policy was never enforced. Meanwhile omp's builtin provider registry (57 ids at the pinned 16.1.20, including qianfan / minimax-code-cn / xiaomi-token-plan-cn / zhipu-coding-plan / deepseek / zai) grows every bump with no early warning. - desktop/checker_model.ts: new pure resolveGovernedModel(locked, models, current, options) composing the ADR-0217 AskSage lockdown with modelAllowed. Lock resolves first, then the allowlist; a denied model swaps to the first option satisfying BOTH constraints; nothing qualifies means { ok:false } so callers BLOCK rather than route to a denied provider. Unmanaged + unlocked passes through unchanged. Module stays pure (policy arrives as a parameter). - desktop/acp_backend.ts: enforceAsksageLock generalized to enforceModelPolicy at its two call sites. Fresh-session sync now fires unconditionally (no-op when unmanaged); the pre-turn clamp stays the authoritative fail-closed gate and refuses the turn when policy cannot be satisfied. Post-switch it re-verifies BOTH constraints. resolveAgentRunModel routes built-agent and scheduled runs through the same resolver. accessibleModels applies the policy as a cosmetic picker filter with the existing only-narrow-if- nonempty fail-safe. - R-07 CI diff: @oh-my-pi/pi-catalog pinned 16.1.20 as a direct dependency (joins the prefix_compaction OMP_PACKAGES same-version discipline); harness/omp/provider_catalog.test.ts pins the sorted 57-id builtin provider universe and fails with review-then-re-pin instructions on any addition or removal. The pin caught real drift immediately: a newer transitive catalog carried baseten/coreweave/gitlab-duo-agent that exact-16.1.20 does not. make test: 2640 pass / 0 fail (8 resolver tests + 2 catalog tests new); desktop tsc clean.
alexander-blackwell
force-pushed
the
feat/r07-provider-allowlist
branch
from
September 4, 2026 00:19
c1ea15e to
42492b7
Compare
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.
Closes #347. Completes the core half of the add-on's R-07 provider-governance risk item (add-on #36); the add-on-side pack-to-managed-config emitter is its companion there.
The gap this closes
P-ENT.1 (ADR-0068) shipped the ManagedModels schema (allowed/denied substring lists + lock + asksageOnly) and the pure modelAllowed() helper. ADR-0217 wired fail-closed enforcement for the AskSage lockdown only. The generalized allowed/denied policy had ZERO live call sites: an org could deploy a managed models policy and nothing enforced it. Separately, omp's builtin provider catalog (57 ids at our pinned 16.1.20, including qianfan, minimax-code-cn, xiaomi-token-plan-cn/-ams/-sgp, zhipu-coding-plan, deepseek, zai, moonshot, kimi-code, qwen-portal) grows every release with no early warning: the exact R-07 risk of provider churn routing around sovereignty governance.
What changed
1. Pure resolver (desktop/checker_model.ts)
resolveGovernedModel(locked, models, current, optionValues) composes the ADR-0217 lockdown with modelAllowed: the lock resolves first (sovereignty routing), then the allowlist; when the resolved model is denied, the first option satisfying BOTH constraints wins; when nothing qualifies it returns { ok:false } so callers BLOCK the turn rather than route to a denied provider. Unmanaged + unlocked passes through unchanged. The module stays pure: policy arrives as a parameter, never read ambiently.
2. Enforcement wiring (desktop/acp_backend.ts), mirroring the ADR-0217 pattern exactly
3. CI diff against omp's provider list (harness/omp/provider_catalog.test.ts)
@oh-my-pi/pi-catalog is now a direct dependency pinned 16.1.20 and joins the prefix_compaction OMP_PACKAGES same-version discipline. The new test pins the sorted 57-id builtin provider universe; any omp bump that adds or removes a provider fails with the exact delta and instructions: review additions against the sovereignty posture (managed allowlists, the add-on's governance classification packs) and removals against any policy that names them, then re-pin. Runtime-registered providers (the AskSage gov-gateway extension, local providers) are ours and deliberately outside the pin.
Proof the pin works: it caught real drift on its first run. The transitively-resolved catalog was newer than 16.1.20 and carried baseten, coreweave, and gitlab-duo-agent; the exact pin does not. That is precisely the silent-growth failure mode this test exists to surface.
What this deliberately does not do
Evidence