Implement explicit model routing and remote egress authority #75

Merged
lost-rob0t merged 63 commits from agent/issue-23-model-routing-egress into main 2026-08-22 13:50:33 +00:00
lost-rob0t commented 2026-08-22 11:36:14 +00:00 (Migrated from github.com)

Closes #23.

Summary

Implements explicit model routing and remote-provider egress without weakening Local Recall's local-first privacy boundary.

  • adds local-only, local-first, remote-explicit, and privacy-strict routing policies;
  • makes local failure non-escalating: it never creates remote permission;
  • requires immutable provider/data-class-bound EgressAuthorization before any remote route;
  • adds deterministic payload re-scan, sensitive-metadata rejection, canonical byte limits/digest, and image-denied-by-default egress approval;
  • adds OpenAI-compatible, OpenRouter, Anthropic, and Google request strategies;
  • resolves credentials through configured key-provider references immediately before request construction;
  • adds direct bounded HTTPS transport with certificate/hostname verification, no redirects, no proxy routing, fixed request/header ownership, bounded responses, and sanitized failures;
  • adds same-provider-only bounded retries and cooperative cancellation/deadline handling;
  • adds sanitized control-only audit events for remote authorization/rejection;
  • documents remote routing, egress, credential, transport, and failure semantics in docs/remote-providers.md.

Privacy and security invariants

  • Remote providers are globally and individually disabled by default.
  • local-only and privacy-strict never select remote.
  • local-first does not fall back to remote when local inference fails.
  • remote-explicit requires exact provider and data-class authorization.
  • Raw captures and secret material are never remotely eligible.
  • Images require explicit redacted-image authorization.
  • Only ApprovedEgressPayload crosses into remote-provider builders; current provider encoders deliberately accept approved redacted text only.
  • OpenRouter upstream provider fallback is explicitly disabled.
  • Retries never switch provider or privacy route.
  • Credentials, payload text, metadata values, image bytes, headers, request/response bodies, and provider prompts are excluded from audit/error/control representations.

TDD / RAGE evidence

The complete immutable RAGE record is in rage/issue-23-model-routing-egress.org.

Accepted REDs include:

  • routing contract 406a8c1833ef2ef4a756b26719b21a8c81af6a49 / CI #432: formatting, Ruff, ShellCheck, and strict Pyright passed, then unit collection failed specifically because local_recall.routing did not exist;
  • egress boundary e7c3bb1e8d95bcf7e1f43d9596539b5c8b66d257 / CI #435: hygiene/type gates passed, then unit collection failed specifically on missing egress types;
  • remote audit 1321b4a7adb806bcbb39a39736efd6c8ec71719e / CI #484: formatting, Ruff, ShellCheck, strict Pyright, and failure-propagation passed, then unit collection failed specifically because RemoteProviderAuditAdapter did not exist.

Formatting/lint/type failures encountered while constructing these tests are explicitly recorded as rejected RED evidence rather than counted as behavioral TDD proof.

Verification

Implementation head 3143ff859c5eec08b2733902c790a8f80b2ff7d5 passed CI #487 completely:

  • Ubuntu 22.04 matrix: green;
  • Ubuntu 24.04 matrix: green;
  • formatting / Ruff / ShellCheck: green;
  • strict Pyright: green;
  • unit / contract / integration / security suites: green;
  • repository security scans: green;
  • canonical ./scripts/check: green;
  • failure-propagation verification: green.

The final RAGE ledger and green-test import cleanup are committed after that implementation gate and require the same exact-head CI gate before merge.

Acceptance mapping

  • zero remote traffic in local-only/privacy-strict failure paths: routing tests;
  • no local-failure -> remote fallback: routing tests;
  • explicit provider/data-class remote authorization: routing + egress tests;
  • allowed/redacted payload only: EgressGate + ApprovedEgressPayload boundary;
  • payload filtering/size/secret scan: deterministic egress tests;
  • provider headers and request shapes: injected/mock transport tests;
  • retries/cancellation/deadlines: executor tests;
  • provider errors cannot select a less-private route: no cross-provider fallback/retry path;
  • sanitized audit: RemoteProviderAuditAdapter and client correlation tests;
  • credential references: OS-keyring provider seam and injected credential tests;
  • documentation: docs/remote-providers.md.

Nix scope

This issue changes no Nix inputs, packages, or flake outputs. The repository flake remains development-shell-only; the applicable issue merge gates are the canonical repository gate, supported Ubuntu matrices, security scans, and failure-propagation on the exact final head.

Closes #23. ## Summary Implements explicit model routing and remote-provider egress without weakening Local Recall's local-first privacy boundary. - adds `local-only`, `local-first`, `remote-explicit`, and `privacy-strict` routing policies; - makes local failure non-escalating: it never creates remote permission; - requires immutable provider/data-class-bound `EgressAuthorization` before any remote route; - adds deterministic payload re-scan, sensitive-metadata rejection, canonical byte limits/digest, and image-denied-by-default egress approval; - adds OpenAI-compatible, OpenRouter, Anthropic, and Google request strategies; - resolves credentials through configured key-provider references immediately before request construction; - adds direct bounded HTTPS transport with certificate/hostname verification, no redirects, no proxy routing, fixed request/header ownership, bounded responses, and sanitized failures; - adds same-provider-only bounded retries and cooperative cancellation/deadline handling; - adds sanitized control-only audit events for remote authorization/rejection; - documents remote routing, egress, credential, transport, and failure semantics in `docs/remote-providers.md`. ## Privacy and security invariants - Remote providers are globally and individually disabled by default. - `local-only` and `privacy-strict` never select remote. - `local-first` does not fall back to remote when local inference fails. - `remote-explicit` requires exact provider and data-class authorization. - Raw captures and secret material are never remotely eligible. - Images require explicit `redacted-image` authorization. - Only `ApprovedEgressPayload` crosses into remote-provider builders; current provider encoders deliberately accept approved redacted text only. - OpenRouter upstream provider fallback is explicitly disabled. - Retries never switch provider or privacy route. - Credentials, payload text, metadata values, image bytes, headers, request/response bodies, and provider prompts are excluded from audit/error/control representations. ## TDD / RAGE evidence The complete immutable RAGE record is in `rage/issue-23-model-routing-egress.org`. Accepted REDs include: - routing contract `406a8c1833ef2ef4a756b26719b21a8c81af6a49` / CI #432: formatting, Ruff, ShellCheck, and strict Pyright passed, then unit collection failed specifically because `local_recall.routing` did not exist; - egress boundary `e7c3bb1e8d95bcf7e1f43d9596539b5c8b66d257` / CI #435: hygiene/type gates passed, then unit collection failed specifically on missing egress types; - remote audit `1321b4a7adb806bcbb39a39736efd6c8ec71719e` / CI #484: formatting, Ruff, ShellCheck, strict Pyright, and failure-propagation passed, then unit collection failed specifically because `RemoteProviderAuditAdapter` did not exist. Formatting/lint/type failures encountered while constructing these tests are explicitly recorded as rejected RED evidence rather than counted as behavioral TDD proof. ## Verification Implementation head `3143ff859c5eec08b2733902c790a8f80b2ff7d5` passed CI #487 completely: - Ubuntu 22.04 matrix: green; - Ubuntu 24.04 matrix: green; - formatting / Ruff / ShellCheck: green; - strict Pyright: green; - unit / contract / integration / security suites: green; - repository security scans: green; - canonical `./scripts/check`: green; - failure-propagation verification: green. The final RAGE ledger and green-test import cleanup are committed after that implementation gate and require the same exact-head CI gate before merge. ## Acceptance mapping - zero remote traffic in local-only/privacy-strict failure paths: routing tests; - no local-failure -> remote fallback: routing tests; - explicit provider/data-class remote authorization: routing + egress tests; - allowed/redacted payload only: `EgressGate` + `ApprovedEgressPayload` boundary; - payload filtering/size/secret scan: deterministic egress tests; - provider headers and request shapes: injected/mock transport tests; - retries/cancellation/deadlines: executor tests; - provider errors cannot select a less-private route: no cross-provider fallback/retry path; - sanitized audit: `RemoteProviderAuditAdapter` and client correlation tests; - credential references: OS-keyring provider seam and injected credential tests; - documentation: `docs/remote-providers.md`. ## Nix scope This issue changes no Nix inputs, packages, or flake outputs. The repository flake remains development-shell-only; the applicable issue merge gates are the canonical repository gate, supported Ubuntu matrices, security scans, and failure-propagation on the exact final head.
Sign in to join this conversation.
No description provided.