Skip to content

feat(core): derive provider conformance matrix from registry declarations - #974

Merged
Astro-Han merged 6 commits into
mainfrom
feat/providers-phase7-conformance-matrix
Jul 14, 2026
Merged

Astro-Han merged 6 commits into
mainfrom
feat/providers-phase7-conformance-matrix

Conversation

@Astro-Han

@Astro-Han Astro-Han commented Jul 14, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Refs #860 (Phase 7: contract foundation; the issue stays open).

Provider conformance today is hand-enumerated per provider, so ready providers can silently lack coverage (anthropic, openai, google, deepseek and others have no cell in provider-conformance.test.ts) and every new provider must remember to add its own. This PR makes conformance an interpretation of the registry declarations instead:

  • A new pure module packages/core/src/provider-contract-matrix.ts derives a matrix plan from providerRegistry: 42 rows (every status === 'ready' entry with a wired runtime adapter) × 4 dimensions (discovery, exact-model-id, tool-loop, reasoning-replay). Each cell resolves to exactly one of generated (145: expectations recoverable from protocol / runtimeAdapter / modelDiscovery), override (8: provider-specific contracts owned by named hand-written tests under stable provider:dimension keys), or not-applicable (15: machine-readable reasons; fallback-discovery providers still execute a reverse assertion that /models is never requested).
  • A new runtime suite executes every generated cell against scripted local HTTP servers (openai-chat ×34, anthropic-messages ×5, google-generate ×1, cohere-v2 ×1) and fails CI when a ready provider's applicable dimension has neither a generated cell nor a registered override, naming the provider id and missing dimension. Future ready providers enter the matrix by declaration alone.

The row set is intentionally not READY_PROVIDER_TYPES: its membership is "has a readyOrder", which would silently drop github-copilot.

Per the Phase 7 constraints in #860 the change is additive only: no runtime behavior, existing suite, READY_PROVIDER_TYPES consumer, or compatibility path changes. Overlap with the hand-written provider-conformance.test.ts is intentional; consolidation belongs to Phase 8.

Verification

  • @maka/core: 968/968 pass, typecheck clean (includes the new 19-test plan-derivation suite).
  • @maka/runtime: 1691 pass / 0 fail, 7 pre-existing skips, typecheck clean (includes the new 89-test generated-conformance suite).
  • Both run after rebasing onto latest main.
  • Not run locally: Desktop E2E (deferred to the CI gate per feat(providers): support common providers from models.dev #860); no desktop surface is touched.
  • All coverage is deterministic against scripted local servers; no secrets, credentials, or raw provider responses.

Review focus

sampleModelIdFor knowingly duplicates the runtime's /^gpt-5/i Responses-routing fact (commented at the source). Lifting it into an apiProtocol declaration is deferred to a follow-up PR: the regex is an open-world pattern (a newly discovered gpt-5.x id still routes to Responses) while apiProtocol is declared per exact model id today, so a naive lift would regress routing for newly discovered models. The follow-up needs a pattern-level declaration seam; both duplication sites disappear with it.

Phase 7 of #860: derive rows from every ready registry entry and resolve
each contract dimension to generated / named-override / explicit-N/A,
as a pure function with no runtime behavior change.
Phase 7 of #860: run every generated cell against scripted local
protocol servers, assert named overrides are registered, execute
fallback reverse assertions, and fail CI on any coverage gap.
@Astro-Han
Astro-Han force-pushed the feat/providers-phase7-conformance-matrix branch from 8fc6041 to 6bb0dda Compare July 14, 2026 09:31
Review hardening for the Phase 7 matrix (#860): discovery cells now assert
the declared path, query, and credential placement before responding (public
discovery must carry no credential; array-or-data runs both fixtures);
Anthropic/Google/Cohere wire runners assert the second turn actually replays
the tool result tied to the first-turn call id, matching the OpenAI runner;
override registry entries bind to exact hand-written test titles so deleting
or renaming an owned test fails the matrix instead of drifting silently.
Every new assertion was mutation-verified red before restore.
@Astro-Han

Copy link
Copy Markdown
Contributor Author

Review hardening landed in ac8f060a (+284/−34, test-only), addressing an external review round against the matrix's own contract ("generated cell = dimension actually verified"):

  • Generated discovery cells now enforce the full derived request contract before the scripted server responds: the declared pathname, exact query equality, and credential placement. auth: 'none' cells must carry no Authorization / x-api-key / x-goog-api-key header; openai-family cells assert the Bearer credential, anthropic-family x-api-key, google the key query with no credential header, and providers without API-key auth must send no credential at all. responseShape: 'array-or-data' cells run both the data-object and bare-array fixtures.
  • The Anthropic, Google, and Cohere wire runners now parse the second-turn body and assert the tool result is actually replayed with the first-turn call id (tool_result / functionResponse / tool message respectively), matching what the OpenAI runner already asserted.
  • Override registry entries now bind to the exact hand-written test titles in provider-conformance.test.ts, checked against the source text, so deleting or renaming an owned test fails the matrix instead of drifting silently. Full executable override binding stays with the Phase 8 consolidation per the Phase 7 additivity constraint in feat(providers): support common providers from models.dev #860.

Every new assertion was mutation-verified: temporarily breaking the fetcher's path/query/auth consumption, each SDK's tool-result serialization, and one registry title each turned exactly the corresponding cells red with provider- and dimension-named messages, then restored.

One seam surfaced by lm-studio: the plan derives discovery auth default for providers whose authKind is none, while the fetcher correctly sends no credential; the executor asserts per providerAuthSupportsApiKey for now. A third derived auth state in the core plan would be the root fix — deferred as a small follow-up since it changes plan semantics.

The plan derived discovery auth 'default' for authKind 'none' providers
(lm-studio), forcing the runtime executor to second-guess the plan via
providerAuthSupportsApiKey. Derive 'none' at the plan layer instead and
drop the executor workaround: a generated 'none' cell now uniformly means
the request must carry no credential.
@Astro-Han

Copy link
Copy Markdown
Contributor Author

Follow-up: the lm-studio seam noted above is closed in 2b2e1b80 — the plan now derives discovery auth none whenever the provider has no credential to send, and the executor's providerAuthSupportsApiKey workaround is removed. A generated none cell uniformly means the request must carry no credential.

…ndings

Rereview round two on the Phase 7 matrix (#860): the GitHub Copilot
conformance test now asserts the second turn carries the exact model id,
replays the assistant tool_calls id and reasoning_content verbatim, and
links the tool result via tool_call_id; the github-copilot:discovery
override rebinds to the dedicated picker/endpoint-gating test in
model-fetcher.test.ts (bindings now name their source file); the binding
check requires an enabled test( call so test.skip/test.todo no longer
count as coverage. All new assertions mutation-verified red then restored.
@Astro-Han

Copy link
Copy Markdown
Contributor Author

Second external review round handled in 08bcdac0 (+74/−21, test-only):

  • Copilot second-turn contract (P1): the bound hand-written test now asserts turn two carries the exact model id, replays the assistant tool_calls id (call-copilot-echo) and reasoning_content verbatim, and links the tool result via tool_call_id — closing the same false-green class the generated Anthropic/Google/Cohere runners were hardened against in ac8f060a. Mutation-verified: tampering the SDK's second-turn tool_call_id, reasoning_content, and model serialization each turned the test red, then restored byte-identical.
  • github-copilot:discovery rebinds to the dedicated picker/endpoint-gating test in model-fetcher.test.ts (policy-disabled / picker-false / no-tools / unsupported-wire decoys); override bindings now name their source file instead of assuming one.
  • Binding check rejects disabled tests (P2): a bound title must appear as an enabled test( call — test.skip / test.todo no longer count as coverage, with a distinct failure message for each case.

Recorded deferral: optional_api_key (LocalAI) is folded into the with-key default case by the plan today; the keyless branch stays covered by model-fetcher.test.ts. Before Phase 8 deletes overlapping hand-written coverage, the plan must either grow per-cell credential cases or mark optional-auth discovery as an override.

E2E note: the earlier red gate was the pre-existing MiniMax catalog spec timing out in window teardown with all assertions passing — no overlap with this diff; a clean rerun is green, so it is classified as infrastructure per the #860 guardrail.

…ecks

A binding matched any test( call merely opening with the bound title, so
renaming a hand-written test by appending a suffix still counted as
coverage. Match the complete quoted title instead; the commented-out
residual stays documented for the Phase 8 executable override binding.
@Astro-Han

Copy link
Copy Markdown
Contributor Author

Third external review round returned no blockers; two P2 follow-ups, one fixed in 976aa122 (+13/−8, test-only):

  • Binding check now requires the complete quoted title: hasEnabledTestCall matched any test( call merely opening with the bound title, so renaming a hand-written test by appending a suffix still counted as coverage. It now matches test('<title>' through the closing quote (safe for the parametric Ollama binding, whose stored text is the full template literal). Mutation-verified: suffix-renaming the bound ZenMux title turned the binding test red naming zenmux:reasoning-replay, then restored. Known residual: a fully commented-out test(...) line still matches textually — documented in-source and owned by the Phase 8 executable override binding.
  • optional_api_key per-cell credential cases: identical to the deferral already recorded above (Phase 8 precondition before deleting overlapping hand-written coverage); no new action.

@Astro-Han
Astro-Han merged commit 04703d6 into main Jul 14, 2026
3 checks passed
@Astro-Han
Astro-Han deleted the feat/providers-phase7-conformance-matrix branch July 14, 2026 14:25
Astro-Han added a commit that referenced this pull request Jul 16, 2026
…#1105)

Part of #860 (Phase 8), closing the preconditions recorded in #974:

- optional_api_key discovery cells now derive auth: 'optional' and the
  generated matrix executes both credential branches (configured key
  reaches the wire; absent key sends no credential at all).
- Override cells now bind to executable runs in
  provider-contract-overrides.ts that the matrix suite executes
  directly, replacing the textual test-title source check; the bound
  hand-written tests moved out of provider-conformance.test.ts /
  model-fetcher.test.ts so each contract runs exactly once.
- The /^gpt-5/i Responses routing regex is lifted into the
  openAiAdapterApiProtocol declaration in core (ModelInfo.apiProtocol
  seam); runtime model-factory and the matrix sample-id derivation both
  consume the declaration, with a wire test locking gpt-5*->Responses
  and other ids->Chat Completions.
Astro-Han added a commit that referenced this pull request Jul 16, 2026
…ted matrix

Part of #860 (Phase 8). With the #974 preconditions landed, remove the
hand-written two-stage replay tests whose every assertion is owned by a
generated matrix cell, and strengthen the generated wire to also assert
the per-protocol request credential (Bearer / x-api-key / x-goog-api-key
keyed off the registry authKind, and no credential for authKind none) so
the deleted per-provider auth assertions stay locked.

Deleted (replaced by the named generated cells): OpenCode Go, LocalAI,
LM Studio, Cerebras, NVIDIA, SiliconFlow, MiniMax Coding Plan, xAI,
Together AI, Mistral, Tencent TokenHub, and the Xiaomi + Z.AI pair.

Kept (unique provider contracts): testConnection probes, per-model
override Responses routing (OpenCode Zen), signed reasoning_details
(ZenMux), buildProviderOptions wires (Vercel, Ollama Cloud, DeepInfra,
Groq, OpenRouter, Cloudflare, Tencent Token Plan, Volcengine Ark),
reasoning-source quirks (StepFun), full fallback-snapshot lists
(Tencent/Volcengine/StepFun plans), and Hugging Face capability mapping.

The conformance suite now shares the scripted-HTTP harness instead of
carrying its own copy.
Astro-Han added a commit that referenced this pull request Jul 16, 2026
…ted matrix (#1108)

* test(runtime): delete hand-written conformance replaced by the generated matrix

Part of #860 (Phase 8). With the #974 preconditions landed, remove the
hand-written two-stage replay tests whose every assertion is owned by a
generated matrix cell, and strengthen the generated wire to also assert
the per-protocol request credential (Bearer / x-api-key / x-goog-api-key
keyed off the registry authKind, and no credential for authKind none) so
the deleted per-provider auth assertions stay locked.

Deleted (replaced by the named generated cells): OpenCode Go, LocalAI,
LM Studio, Cerebras, NVIDIA, SiliconFlow, MiniMax Coding Plan, xAI,
Together AI, Mistral, Tencent TokenHub, and the Xiaomi + Z.AI pair.

Kept (unique provider contracts): testConnection probes, per-model
override Responses routing (OpenCode Zen), signed reasoning_details
(ZenMux), buildProviderOptions wires (Vercel, Ollama Cloud, DeepInfra,
Groq, OpenRouter, Cloudflare, Tencent Token Plan, Volcengine Ark),
reasoning-source quirks (StepFun), full fallback-snapshot lists
(Tencent/Volcengine/StepFun plans), and Hugging Face capability mapping.

The conformance suite now shares the scripted-HTTP harness instead of
carrying its own copy.

* chore: retrigger CI

* test(runtime): harden the generated wire per external review of #1108

Accepted findings from the external review:

- P1: wire runs expand optional_api_key into both credential branches
  (configured key must reach the wire; absent key must send no credential
  at all), matching the discovery-side expansion; assertWireCredential
  now also asserts every non-selected credential header (authorization,
  x-api-key, api-key, x-goog-api-key) is absent for all authKinds.
- P2: five declared edge wire samples (opencode-go kimi-k2.7-code,
  localai localai/Qwen3-8B-Instruct-GGUF:Q4_K_M, lm-studio
  lmstudio-community/Qwen3-Coder-30B-A3B-Instruct-GGUF,
  minimax-coding-plan MiniMax-M2.7-highspeed, tencent-tokenhub
  hy3-preview) run end-to-end through the same wire executor
  (exact-model-id + tool-loop) on the per-id resolved wire; the
  declaration lives in the core matrix plan (EDGE_WIRE_SAMPLE_MODEL_IDS
  -> row.edgeWireSamples) so future providers enter by declaration.
- P2: the generic OpenAI wire fixture issues an opaque tool-call id
  (D681PevKs9, no call_ prefix) and both turns assert it is replayed
  verbatim, so id canonicalization regressions cannot pass.
- P2: wire connections carry a sentinel base-URL pathname
  (/contract-base/...) and every protocol runner asserts the final
  request path equals the sentinel prefix plus the protocol suffix,
  proving the runtime preserves configured baseUrl pathnames.

Request-contract violations in wire handlers are recorded and rethrown
after the call so injected regressions fail with the contract message
instead of a destroyed-socket timeout. Each hardening was verified by
injecting the corresponding runtime regression and observing the new
assertion fail by name.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant