Program integration: M03 OpenAI-compatible gateway + execution coordinator (#88) and M08 interface guardrails + remote bridge client (#93) #104

Merged
adrian.tkacz merged 11 commits from program/m03-m08-parallel into develop 2026-09-20 09:43:24 +00:00
Member

Summary

Two parallel, independently reviewed workstreams, integrated into one feature branch for owner review. Baseline PROGRAM_BASE_SHA = e4391dfcfcd82e3463624f132ccf26d73e1a5051 (canonical develop at wave start, including merged #103 / D-047). Nothing is merged to develop by this PR; it is left open for human review.

Workstream A — #88 / M03: OpenAI-compatible gateway and execution coordinator (full implementation)

  • Approved HEAD: e03d3cc6106fb2ef4e9028ba7a91c4bd414e5d5a on m03/gateway-coordinator (6 commits). Review iterations: 2 (round 1 CHANGES_REQUESTED with 3 blockers — chunkless-stream client hang, dead limits=None safe default, one D-045 doc contradiction; all remediated in e03d3cc; round 2 APPROVE with no findings).
  • New modules beside the application layer (D-041): gateway_validation.py, gateway_contracts.py (execution surface v1, D-045; GatewayLimits safe defaults, D-044; closed OpenAI-style error vocabulary; SHA-256 client-key directory), gateway_audit.py (exact D-043 audit field set, content-free, count+age bounded, AuditSink seam), gateway_adapters.py (ExecutionAdapter dispatch seam + typed permanent/ambiguous/timeout failures for future M04/M05/M06), gateway_openai.py (strict closed-allowlist chat/completions parsing, capability inference, fail-closed), gateway_coordinator.py (admission via M02 route_request/admit_pinned_target exactly once, bounded concurrency reservation, single dispatch with no cross-target reroute or blind retry, disconnect cancellation, deadline, honest multi-call usage accounting), gateway_server.py (distinct authenticated execution server, python -m scarcity_router.gateway_server, default loopback:8787; bearer auth vs hashed keys file, refuses unconfigured start, TLS required off-loopback, router-loop X-Scarcity-Router-Gateway rejection, SSE with chunkless-stream synthesis).
  • Exact-target discipline: sr-pin:<resource>/<provider>/<model>/<variant>[@decision] → PinnedTarget → admit_pinned_target; no variant reconstruction, pinned_model_not_bound is a typed rejection, model field resolves only via routing-profile alias (existing requirement model, D-042 — no second scoring system).
  • server.py (frozen loopback REST v1) byte-identical to baseline. No persistence introduced — in-memory state + AuditSink seam (D-041 in-memory allowance; SQLite-class store deferred to M09 if needed).
  • Contract doc: docs/execution-surface.md (additive execution-surface v1 contract). README gateway paragraph refreshed.
  • Deliberate deferrals: /v1/responses; n>1, logprobs/logit_bias, multimodal content parts; real adapters (M04/M05/M06 — the shipped registry starts empty and answers honestly); administrator key-issuance/rotation UX + durable store (M09); execution-resource collector wiring (M04/M09); representative OpenAI-SDK/IDE client acceptance and dated backend capability-matrix evidence (explicit #88 evidence items, owned by M10).

Workstream B — #93 / M08: MCP, REST, CLI compatibility; optional remote mode (full implementation)

  • Approved HEAD: 521f961670a93acc901cbd558c4e246ac2630998 on m08/interfaces-compat (3 commits). Review iterations: 1 (APPROVE, no blockers).
  • tests/test_interfaces_guardrails.py (40 tests): the consolidated guardrail suite locking frozen v1 semantics — exact REST route set (execution paths 404 on the loopback adapter), exact 3 MCP tools, loopback-only non-configurable binding, liveness-only /healthz, envelope/schema-version separation (machine-interface 1 / capacity 3 / eligibility 1), closed error vocabulary with frozen status mapping, strict JSON parsing, missing-vs-null semantics, requirement-source XOR, freshness semantics, and four-way direct == CLI == REST == MCP parity extended to gateway-era D-039 eligibility fields. Runnable standalone via the new make guardrails gate.
  • scarcity_router/remote.py (+ typed RemoteBridgeError in errors.py): the optional remote-mode bridge client — explicit configuration, explicit failure, zero silent local fallback (client structurally holds no collectors/artifacts/policy); verified TLS for every non-loopback origin with no bypass option, plain HTTP only for explicit loopback origins, redirects never followed, bearer key header-only/never logged/redacted repr, machine-interface v1 envelopes end-to-end.
  • Seam expectation documented for M03/M09 reconciliation (additive docs/architecture.md section): authenticated control endpoints GET /v1/status, POST /v1/select, POST /v1/simulate + Bearer client identity. Reconciliation is confined to three endpoint constants + envelope validation + the test stub.
  • All frozen surfaces byte-identical: server.py, machine_api.py, mcp.py, cli.py.

Integration

  • Integration HEAD: e278cb1 — two --no-ff merge commits preserving logical task history. Zero conflicts; zero manual resolution (branches were file-disjoint); the integration auditor proved both task file sets are byte-identical to their approved heads in the merge result, so no task re-review was required.
  • Cross-workstream integration audit: PASS (fresh independent auditor; 12-point contract: no competing servers — control :8765 vs execution :8787, disjoint path sets; frozen v1 intact; execution ingress separately versioned; no M08 bypass of M03/M02 admission (sole execution path is gateway ingress → admission); no per-interface compat logic in M03; exact PinnedTarget variant survives every boundary verbatim; no hidden rerouting/fallback anywhere; no M04/M05/M06 adapter leaked (registry ships empty); ZCode closed per D-047; Z.ai deferred to M04; security postures coherent (same TLS rule from both sides); docs tell one story).
  • Combined validation on e278cb1 (run by integrator and independently re-run by the auditor): uv sync --only-dev ✅ · make check ✅ 1318 tests OK (1183 baseline + 95 M03 + 40 M08) · uv run basedpyright ✅ 0 errors / 0 warnings / 0 notes · git diff --check ✅ · make package-check ✅ · make guardrails ✅ 40/40. No test depends on live inference, provider credentials, personal subscriptions, private infrastructure or paid services — all fixtures are synthetic.

Explicit confirmations

  • Nothing was merged to develop; main untouched; no tags or releases.
  • M04 was not implemented; M05 was not implemented; M06 Stage 2 was not implemented.
  • ZCode execution remains cancelled per D-047 (no adapter, no IPC/wrapper, no planned-backend docs).
  • No new decision was recorded in docs/decisions.md — none was needed (no conflict arose).

Refs: #88, #93 (program root #85).

## Summary Two parallel, independently reviewed workstreams, integrated into one feature branch for owner review. Baseline `PROGRAM_BASE_SHA` = `e4391dfcfcd82e3463624f132ccf26d73e1a5051` (canonical `develop` at wave start, including merged #103 / D-047). **Nothing is merged to `develop` by this PR; it is left open for human review.** ### Workstream A — #88 / M03: OpenAI-compatible gateway and execution coordinator (full implementation) - **Approved HEAD:** `e03d3cc6106fb2ef4e9028ba7a91c4bd414e5d5a` on `m03/gateway-coordinator` (6 commits). **Review iterations: 2** (round 1 `CHANGES_REQUESTED` with 3 blockers — chunkless-stream client hang, dead `limits=None` safe default, one D-045 doc contradiction; all remediated in `e03d3cc`; round 2 `APPROVE` with no findings). - New modules beside the application layer (D-041): `gateway_validation.py`, `gateway_contracts.py` (execution surface v1, D-045; `GatewayLimits` safe defaults, D-044; closed OpenAI-style error vocabulary; SHA-256 client-key directory), `gateway_audit.py` (exact D-043 audit field set, content-free, count+age bounded, `AuditSink` seam), `gateway_adapters.py` (`ExecutionAdapter` dispatch seam + typed permanent/ambiguous/timeout failures for future M04/M05/M06), `gateway_openai.py` (strict closed-allowlist chat/completions parsing, capability inference, fail-closed), `gateway_coordinator.py` (admission via M02 `route_request`/`admit_pinned_target` exactly once, bounded concurrency reservation, single dispatch with no cross-target reroute or blind retry, disconnect cancellation, deadline, honest multi-call usage accounting), `gateway_server.py` (distinct authenticated execution server, `python -m scarcity_router.gateway_server`, default loopback:8787; bearer auth vs hashed keys file, refuses unconfigured start, TLS required off-loopback, router-loop `X-Scarcity-Router-Gateway` rejection, SSE with chunkless-stream synthesis). - Exact-target discipline: `sr-pin:<resource>/<provider>/<model>/<variant>[@decision]` → `PinnedTarget` → `admit_pinned_target`; no variant reconstruction, `pinned_model_not_bound` is a typed rejection, `model` field resolves only via routing-profile alias (existing requirement model, D-042 — no second scoring system). - `server.py` (frozen loopback REST v1) byte-identical to baseline. **No persistence introduced** — in-memory state + `AuditSink` seam (D-041 in-memory allowance; SQLite-class store deferred to M09 if needed). - Contract doc: `docs/execution-surface.md` (additive execution-surface v1 contract). README gateway paragraph refreshed. - **Deliberate deferrals:** `/v1/responses`; `n>1`, `logprobs`/`logit_bias`, multimodal content parts; real adapters (M04/M05/M06 — the shipped registry starts empty and answers honestly); administrator key-issuance/rotation UX + durable store (M09); execution-resource collector wiring (M04/M09); representative OpenAI-SDK/IDE client acceptance and dated backend capability-matrix evidence (explicit #88 evidence items, owned by M10). ### Workstream B — #93 / M08: MCP, REST, CLI compatibility; optional remote mode (full implementation) - **Approved HEAD:** `521f961670a93acc901cbd558c4e246ac2630998` on `m08/interfaces-compat` (3 commits). **Review iterations: 1** (`APPROVE`, no blockers). - `tests/test_interfaces_guardrails.py` (40 tests): the consolidated guardrail suite locking frozen v1 semantics — exact REST route set (execution paths 404 on the loopback adapter), exact 3 MCP tools, loopback-only non-configurable binding, liveness-only `/healthz`, envelope/schema-version separation (machine-interface 1 / capacity 3 / eligibility 1), closed error vocabulary with frozen status mapping, strict JSON parsing, missing-vs-`null` semantics, requirement-source XOR, freshness semantics, and four-way `direct == CLI == REST == MCP` parity extended to gateway-era D-039 eligibility fields. Runnable standalone via the new `make guardrails` gate. - `scarcity_router/remote.py` (+ typed `RemoteBridgeError` in `errors.py`): the optional remote-mode bridge **client** — explicit configuration, explicit failure, zero silent local fallback (client structurally holds no collectors/artifacts/policy); verified TLS for every non-loopback origin with no bypass option, plain HTTP only for explicit loopback origins, redirects never followed, bearer key header-only/never logged/redacted repr, machine-interface v1 envelopes end-to-end. - Seam expectation documented for M03/M09 reconciliation (additive `docs/architecture.md` section): authenticated control endpoints `GET /v1/status`, `POST /v1/select`, `POST /v1/simulate` + Bearer client identity. Reconciliation is confined to three endpoint constants + envelope validation + the test stub. - All frozen surfaces byte-identical: `server.py`, `machine_api.py`, `mcp.py`, `cli.py`. ### Integration - Integration HEAD: `e278cb1` — two `--no-ff` merge commits preserving logical task history. **Zero conflicts; zero manual resolution** (branches were file-disjoint); the integration auditor proved both task file sets are byte-identical to their approved heads in the merge result, so no task re-review was required. - **Cross-workstream integration audit: PASS** (fresh independent auditor; 12-point contract: no competing servers — control :8765 vs execution :8787, disjoint path sets; frozen v1 intact; execution ingress separately versioned; no M08 bypass of M03/M02 admission (sole execution path is gateway ingress → admission); no per-interface compat logic in M03; exact `PinnedTarget` variant survives every boundary verbatim; no hidden rerouting/fallback anywhere; no M04/M05/M06 adapter leaked (registry ships empty); ZCode closed per D-047; Z.ai deferred to M04; security postures coherent (same TLS rule from both sides); docs tell one story). - **Combined validation on `e278cb1`** (run by integrator and independently re-run by the auditor): `uv sync --only-dev` ✅ · `make check` ✅ **1318 tests OK** (1183 baseline + 95 M03 + 40 M08) · `uv run basedpyright` ✅ 0 errors / 0 warnings / 0 notes · `git diff --check` ✅ · `make package-check` ✅ · `make guardrails` ✅ 40/40. No test depends on live inference, provider credentials, personal subscriptions, private infrastructure or paid services — all fixtures are synthetic. ### Explicit confirmations - Nothing was merged to `develop`; `main` untouched; no tags or releases. - M04 was **not** implemented; M05 was **not** implemented; M06 Stage 2 was **not** implemented. - ZCode execution remains cancelled per D-047 (no adapter, no IPC/wrapper, no planned-backend docs). - No new decision was recorded in `docs/decisions.md` — none was needed (no conflict arose). Refs: #88, #93 (program root #85).
kilo added 11 commits 2026-09-20 04:45:18 +00:00
Add scarcity_router/remote.py: the CLIENT side of the optional remote
recommendation bridge (D-045 topology 4), for the central authenticated
Scarcity Router server whose control API is owned by M03/M09.

- RemoteServerConfig: explicit origin + client api_key; HTTPS required
  off loopback (verified TLS via ssl.create_default_context(), no bypass
  option), bare origin only, credential never in URLs and redacted from
  repr; bounded timeout.
- RemoteScarcityClient: status/select/simulate returning the frozen
  machine-interface v1 envelopes; requests validated through the shared
  machine_api parsers (no second parser); responses parsed strictly and
  envelope-validated.
- Explicit failure everywhere: unreachable, auth failure, redirect,
  unexpected status, malformed or contract-violating responses raise
  the new typed RemoteBridgeError; the client holds no collectors,
  artifacts or policy, so silent local fallback is structurally
  impossible.
- Smallest interface-side seam expectation documented in the module for
  M03/M09 integration: GET /v1/status, POST /v1/select,
  POST /v1/simulate, Authorization: Bearer <client key>, v1 envelopes.

MCP, REST v1 and CLI surfaces are unchanged; the bridge recommends and
reports only and never executes inference or reserves capacity.
Add tests/test_interfaces_guardrails.py, the continuous per-module
regression gate of the gateway program (make guardrails):

- Frozen surface: exactly the four REST v1 operations (execution paths
  /v1/models and /v1/chat/completions are never served by the loopback
  adapter), exactly the three MCP recommendation tools, loopback-only
  non-configurable binding, liveness-only /healthz.
- Envelope discipline: outer schema_version 1 never collapsed with the
  nested capacity v3 / eligibility v1 domain versions; closed
  invalid_request/internal_error vocabulary with safe structural
  messages; strict parsing (duplicate keys, NaN/Infinity), frozen
  missing-vs-null field semantics, requirement-source XOR, simulation
  override tri-state.
- Frozen semantics across CLI/REST/MCP: no-solution stays a valid
  success, unknown profile is invalid_request, provider degradation
  stays domain data, freshness stays fresh-per-request with one shared
  observation timestamp and no cache.
- Parity extended to gateway-era additive fields (D-039): status
  envelope eligibility identical REST == MCP == direct while the CLI
  keeps its released snapshot-array shape; execution-stage exclusions
  carry execution_eligibility identically through all four surfaces;
  four-way parity for profile, explicit-requirement, tightened-profile
  and simulation scenarios.
- Remote bridge (D-045 topology 4): parity of remote vs local envelopes
  against a synthetic authenticated control server implementing the
  documented seam; explicit failure on unreachability, authentication
  failure (with zero local collector calls), redirects (never
  followed), server errors and contract-violating responses; structural
  request violations fail client-side through the shared parser; no
  TLS-verification bypass exists.
- No-execution and no-IDE-mutation guardrails: MCP source stays local
  stdio with no network/subprocess/execution surface; an AST scan plus
  an isolated-environment behavior test pin every product filesystem
  write to the D-036 selector-policy provisioning.

Deterministic: synthetic collectors, fixed clock, repository artifacts;
never live provider quota.
Add the 'Remote bridge client (M08, #93)' subsection to the A0
execution-gateway architecture: endpoints, envelopes, authentication,
transport and explicit-failure rules the configured client expects from
the server-side authenticated control API, plus the reconciliation
boundary (scarcity_router/remote.py and its synthetic-server tests).
New gateway-family modules beside the existing application layer (D-041):

- gateway_validation: shared restricted-grammar validators (one typing
  discipline for the gateway family; no rule of its own).
- gateway_contracts: EXECUTION_SURFACE_VERSION (separately versioned
  execution surface, D-045), administrator-configurable admission limits
  with safe defaults (D-044), the OpenAI-compatible typed error vocabulary
  (never the machine-interface invalid_request/internal_error codes), the
  SHA-256-hash client-key directory (inference-client identity, D-044) and
  honest usage accounting types (provider-reported vs estimated stay
  distinguishable, D-043).
- gateway_audit: the minimal frozen D-043 audit record (request id,
  decision id, client/profile identity, routing-policy version, state
  snapshot identity/version, selected/executed target, adapter
  identity/version, start/end, result status, usage, call count) with no
  content-bearing field, plus the thread-safe bounded in-memory trail and
  the injectable AuditSink seam (in-memory per D-041; durable store is
  M09 scope if ever needed).
- gateway_adapters: the dispatch seam for M04/M05/M06 (ExecutionAdapter
  protocol, AdapterCall on the exact admitted target, ExecutionContext
  with deadline/cancel-event/stream emitter, AdapterResult with per-call
  observations for honest multi-call fan-out, normalized stream chunks,
  and the permanent/ambiguous/timeout typed failure vocabulary).

No production adapter is included; the deterministic synthetic adapter
used by tests lives with the tests.
- gateway_openai: strict chat/completions request parsing (closed key
  allowlist; unknown or unimplemented parameters rejected, never
  silently ignored), capability inference from request structure
  (tools/tool results/roles history/structured output/streaming/reasoning
  controls as compatibility requirements, never ranking inputs), the
  conservative context-floor estimate and the chat.completion /
  chat.completion.chunk rendering with the x_scarcity_router extension.
- gateway_coordinator: one execution lifecycle per request (D-043) --
  admission via route_request or admit_pinned_target exactly once
  (recommendation-to-execution binding, D-042), bounded concurrency
  reservation acquired post-admission with immediate 429 exhaustion,
  dispatch to the exact selected target with NO cross-target reroute and
  NO blind retries (ambiguous state fails closed), client-disconnect
  cancellation propagation, deadline-bounded execution, honest multi-call
  usage aggregation and a complete audit record for every outcome.
  Model-field resolution: configured routing-profile alias or the exact
  sr-pin:<resource>/<provider>/<model>/<variant>[@decision] reference;
  pinned_model_not_bound is an explicit typed rejection, never a
  substitution. Supplemental roles_history/tool_results admission gates
  reuse the M02 matrix lookup; missing or UNKNOWN/UNSUPPORTED fails
  closed before inference.
The NEW, distinct server component (python -m scarcity_router.server's
loopback REST v1 adapter stays byte-identical and frozen, D-030/D-045):

- GET /v1/models and POST /v1/chat/completions (SSE) on an ephemeral or
  configured port; default bind 127.0.0.1:8787; non-loopback binds
  require explicit TLS and are refused otherwise (no plaintext
  non-loopback mode, no verify=false, D-044).
- Bearer-key authentication against the hash-only client-key directory
  (constant-time comparison); the server refuses to start without an
  explicitly configured owner-only keys file -- no default credential
  exists. Keys authorize inference only; there is no administration
  surface.
- Exactly-one-Host discipline on loopback binds; no CORS headers ever;
  no bearer secrets in URLs; oversized bodies drained boundedly and
  rejected 413; transfer-encoding, duplicate JSON keys and unread-body
  cases close the connection so pipelined bytes can never be misread.
- Router-loop protection: ingress refuses requests carrying the
  X-Scarcity-Router-Gateway marker with router_loop_detected (D-044).
- Lazy SSE framing (pre-dispatch failures stay clean HTTP errors),
  EOF-based client-disconnect detection feeding the coordinator's
  cancellation, and in-band error frames only after the stream started.
- build_default_application starts empty and answers honestly (empty
  model list, explicit no-target errors) until administrator
  configuration (M09) and real adapters (M04/M05/M06) land.
All tests are synthetic and self-contained: no live providers, no
network beyond the ephemeral loopback listener, no wall clock (injected),
no secrets (only conspicuous fake key material).

- tests/gateway_fixtures: the deterministic ScriptedAdapter/BlockingAdapter
  fixtures implementing the adapter seam (echo, streaming, tool calls,
  multi-call fan-out, permanent/ambiguous/timeout failures, cancellation)
  plus the fully injected catalog/registry/matrix-cell/capacity world and
  the GatewayApplication assembly helper.
- tests/test_gateway_contracts: limits, OpenAI-compatible error
  vocabulary (never machine-interface codes), hash-only client-key
  directory, honest usage accounting, D-043 audit record shape and
  bounded retention, alias/pin resolution and the strict request parser
  with capability inference.
- tests/test_gateway_coordinator: non-streaming round trip, pinned exact
  target execution (pinned_model_not_bound, pin_target_not_found, stale
  resource), streaming lifecycle, disconnect cancellation, dispatch
  failure without cross-target reroute, ambiguous-state safety, timeout,
  concurrency exhaustion and reservation release, fail-closed
  compatibility (UNKNOWN/UNSUPPORTED including the supplemental
  roles_history/tool_results gates), the multi-turn tool round-trip,
  honest multi-call usage, audit completeness and audit content-freedom.
- tests/test_gateway_server: HTTP ingress -- authentication, disjoint
  surface routes, non-streaming and SSE round-trips (role/usage/[DONE]
  framing), transport rejections (413/400), Host and router-loop
  boundaries, no-CORS, client-disconnect cancellation, key-file
  permission discipline and the non-loopback TLS refusal.
- docs/execution-surface.md: the authoritative contract for the
  OpenAI-compatible ingress -- versioning/coexistence rules (D-045),
  the D-044 security boundary, model-field resolution (alias or exact
  sr-pin reference), the request allowlist and capability-inference
  table, the frozen execution-lifecycle rules, SSE framing, honest
  usage/usage_source semantics, the OpenAI-compatible error vocabulary
  with its code mapping, the D-043 audit contract and the explicit
  deferred sub-scopes (/v1/responses, n>1, logprobs, multimodal parts,
  key-issuance UX, real adapters).
- README: refresh the gateway paragraph to the now-implemented ingress
  (entry point + contract link); recommendation-only behavior is stated
  as unchanged. Strictly additive/factual; no frozen section touched.
Address the three blocking findings of independent review 1 (HEAD
8ff9a4d):

B1 -- a completed result for stream:true that never emitted a chunk left
the client with no status line and no body (silent-failure mode on the
request path, contradicting the contract's own synthesis promise).
_run_streaming now captures the outcome and _StreamState.finish renders
the promised synthesized sequence -- headers, shared-created role chunk,
content/tool-call deltas from the outcome message, the finish chunk, the
usage chunk when requested and available, then [DONE]. A failed
execution with an unstarted stream still stays unstarted, so
pre-dispatch failures remain clean HTTP errors. Pinned by
chunkless_behavior in the fixtures and
test_chunkless_completed_stream_is_synthesized_never_silent.

B2 -- GatewayApplication validated limits with v_instance BEFORE the
None handling, so the advertised safe-default path raised instead of
selecting GatewayLimits() (D-044). Validation now runs only for an
explicit value. Pinned by ApplicationDefaultsTests, which constructs the
application without limits and executes one request under the defaults.

B3 -- docs/execution-surface.md said one listener process never serves
both contracts, contradicting the frozen D-045 coexistence rule (the
disjoint path sets are precisely what ALLOW one listener to serve both
in server deployments). Reworded to: one listener MAY serve both; the
contracts' versions, error vocabularies and security boundaries never
mix.
adrian.tkacz deleted branch program/m03-m08-parallel 2026-09-20 09:43:24 +00:00
Sign in to join this conversation.
No description provided.