Repository navigation
feat: expand key controls protocol and rollback compatibility - #88
Conversation
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars.
|
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ❌ Deployment failed View logs |
multillm-proxy | b6b0e43 | Oct 20 2026, 04:46 PM |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Expansion layer; enforcement is stacked in #89.
Expand the account protocol before enabling key data controls. Existing accounts with NULL policy columns keep their current request and wire behavior. A dormant refusal fence rejects future controlled accounts with 503 before provider dispatch or delegation, including Knowledge, Realtime, media and retained evaluation work.
Every non-NULL policy activates the fence, including official_only=0 and empty preference objects. Shared admission and retained evaluation predicates use the same policy-presence test.
Shadow sampling resolves the canonical data_policy envelope produced by actual account loading, rather than inspecting omitted flat fields. Eligibility, sample construction and response capture use the shared non-NULL predicate. Capture preserves the verified policy and rechecks the source before retaining streamed content and before persistence; missing, malformed, changed and unreadable policies retain no sample. Loaded NULL, zero, empty-object, official-only and forced-policy accounts have end-to-end sampling regressions.
Legacy management lists return exactly the original account fields, including when a restricted neighbour exists. Unversioned single-account and prefix authentication refuse controlled rows, because these reads also feed deferred dispatch. Version-aware peers negotiate before receiving full policies; only an explicit unsupported-operation response permits old-peer fallback. The actual old Container modules exercise sign-in, account-list reload and management in both rollout orders. NULL accounts and administrator sign-in remain available; restricted legacy authentication and outbound work refuse without provider sends.
Additive RPC fields and both account row shapes are accepted. Readiness advertises protocol 1 without enforcement. Legacy account upserts preserve both policy columns atomically; an interleaving regression proves a concurrent policy update survives.
CI retains Git history so the same pinned compatibility modules run in clean checkouts. Pinned current-main and expansion modules exercise all old/expanded account-RPC, Container and private Knowledge pairs with a realistic D1 account migrated through 0043. Controlled-account tests cover rollback refusal and zero upstream content.
Real staging reproduced the incident in both Worker/Container mixed-version directions; matched original runtimes were healthy on 45/46 probes. The reverse rollback interrupted chat for roughly 50–55 seconds. Management regressions now sign in a controlled account and an unrestricted administrator, reload all accounts, and prove unrestricted generation continues without clearing stored restrictions. Pinned runtime probes also load their matching templates.
Preserve each media caller’s redirect mode. Pinned old/expanded transports prove that public asset redirects retain per-hop HTTPS/public-host validation and the three-hop limit, and Python video and image adapters retain explicit no-redirect behavior.
Release admission now checks the exact migration ledger, actual policy columns in both account tables, required secret names and the fully active private deployment before main upload. Tests cover missing prerequisites and deployment ordering.
Deployment now requires an explicit D1 target matching both chosen configurations; standalone remote migration reads also require an explicit target. Status labels use the chosen Worker names. Each release gets a fresh build-only image identifier; deployment captures application detail before upload and refuses success until its version/image advance and the responding Worker/Container fingerprints match. Stale list versions, no-op rollouts and mismatched stamps have regressions.
Disconnect automatic promotion in Workers Builds or switch it to versions upload. Its preflight token permissions remain untested. Keep the staging-verified Container-first rollback until the A/B matrix passes real staging. Pre-existing mixed-load disconnect failures remain outside scope. No deployment, production read or remote migration was performed for these changes.
Rollout: deploy this expansion to all three components, verify protocol 1 everywhere, then deploy the contract PR and verify enforcement before enabling restrictions. Workers Builds deploys the main Worker and Container independently of the GitHub workflow for the private Knowledge Worker. See docs/key-controls-rollout.md.
Every CI command below ran locally through blade-testlock; integration used the existing virtual environment's Python. The two skips are existing Python skips. Bundle validation uses isolated dry-run configurations and does not deploy.
python -m pip install --disable-pip-version-check --require-hashes -r requirements-ci.lock— passed.python scripts/check_static_secrets.py— passed.ruff check . --select E9,F63,F7,F82— passed.mypy --ignore-missing-imports --follow-imports=skip --disable-error-code import-untyped --disable-error-code var-annotated --disable-error-code arg-type --disable-error-code assignment --disable-error-code operator app.py routes services providers streaming— passed.bandit -q -c .bandit -r app.py config.py error_handlers.py route_helpers.py routes services providers streaming— passed.pip-audit -r requirements.lock— passed.npm ci— passed.npm audit --audit-level=high— passed.node --test tests/test_frontend_build.mjs— 2 passed.npm run test:worker— 1,984 passed.npm run cf:migrations:check— 43 migrations checked.npm run test:deploy— 19 passed.node --test tests/test_free_routes_worker.mjs— 8 passed.node --test tests/test_client_headers_worker.mjs— 13 passed.npm run test:integration— 18 passed.npm install --global pnpm@10.11.1— passed.pnpm install --frozen-lockfile— passed.pnpm run build— passed.git diff --exit-code -- static/css/style.css— passed.node --test tests/test_frontend_build.mjs— 2 passed.node scripts/key_data_preflight.mjs --check— passed.node scripts/check_worker_bundle.mjs --config wrangler.knowledge.jsonc --outdir <isolated-directory>— passed.node scripts/check_worker_bundle.mjs --config wrangler.jsonc --outdir <isolated-directory>— passed.python -m pytest -q— 5,265 passed, 955 subtests passed, two skipped.The existing main routing and authentication modules remain above 1,000 lines (main router 2,187; authentication 1,257; proxy orchestration 3,437; main Worker fixture 4,167). Changes there are limited to boundary wiring; follow-up extraction should separate Container forwarding, account persistence and provider request preparation.