Status: STARTED - second 2.0 pillar to start (after 1.x step 1 lands, since local-quality judgments need trustworthy instruments). ROADMAP anchors: Active Queue #18; "Local Inference Mode" (Considered for Later); existing provider abstraction (v1.22-1.24).
A run should be cost-tunable from sub-$1 cloud down to $0 API local, and should eventually be able to use official agent hosts when both sanctioned tooling and trustworthy billing provenance or explicit operator acknowledgment are available, without changing the pipeline. Local is a moving default candidate, not a permanent discount tier: as desk-side AI hardware improves, more stages should graduate to $0 API local execution when eval proves the quality bar holds. The provider abstraction, role-based routing, and the Ollama provider already exist; what's missing is (a) stages declaring what they need rather than which model they want, (b) eval-validated direct/local/hybrid recipes, and (c) a bounded host runner seam that does not mistake authentication type for billing proof.
ProviderABC + xAI/Gemini/OpenAI/Anthropic/Ollama providers; per-model usage and cache accounting; finite HTTP timeouts everywhere (v1.30.0)pick_model_for_roleroutes UTILITY/WRITING/REASONING by key availability with hardcoded preference chainsModelCircuitBreaker+call_with_failoverlive at all production call sites (v1.30.0) - quota events already fail over across providers- Local eval judging (Ollama) and named local model lists exist in the eval harness
- Agent-host integrations exist as MCP/skill surfaces that let compatible
agent hosts operate primr. The first in-run host-agent pilot is an
unpromoted
fast.source_relevanceadapter through the official Codex CLI. A single-company experimental route is exposed only with--inference hybrid --acknowledge-host-agent-may-billbecause Primr cannot determine whether Codex authentication is plan-backed or API-key billed. It records potentially metered billing and pending-eval status, not plan usage. ai/host_agent_runner.pynow defines the transport-free runner contract: bounded stage packet, host billing policy, normalized result metadata, and evidence fencing.ai/host_agent_cli.pyprovides the first concrete Codex CLI transport for the source-relevance pilot; additional official runners and stages are still planned.- The complementary host-native, keyless path is shipped:
primr prepcollects a versioned evidence bundle with model calls disabled, and the portable.agents/skills/primr-zeroskill lets the surrounding host research and synthesize from its existing plan allowance after the host billing basis is verified. This is an artifact handoff, not an internal backend or a claim that the host produced the measured full Primr pipeline. ai/capability_routing.pynow defines the pure StageRequirements router: backend capability rows, cloud/agent/hybrid/local profiles, billing-mode guards, ordered route plans, and explicit rejection reason codes. It has no provider calls; production execution now consumes it first forfast.scrape_summary,fast.source_relevance, andfast.hiring_signals.ai/provider_availability.pynow defines the pure quota/availability contract: normalized quota windows, binding headroom, elapsed-reset handling, stale last-known-good snapshots, and deterministic provider ranking. It has no provider calls and is the seam live quota collectors should feed.ai/provider_availability_collectors.pyadds the first generic collector layer: non-secret cloud provider configuration snapshots and local OpenAI-compatible service probes using the user's configured endpoint. It does not store API key values, raw endpoint URLs, account ids, or installed model names.ai/capability_routing.pycan now apply provider availability snapshots to backend capability rows with sanitized metadata. This is the deterministic bridge between generic collectors androute_stage().primr doctornow surfaces the same generic provider availability view without paid cloud probes, raw endpoint URLs, installed local model names, API key material, account ids, or raw exception payloads.core/stage_inventory.pynow declares the production-stage capability inventory for fast-mode and premium deep-research execution. Each row records the stage id, module, role, reasoning and trust requirements, context and token estimates, egress/deep-research/structured-output needs, accepted backend families, budget checkpoints, current backend ownership, promotion gate, and emitted artifacts.ai/stage_routing.pyis the first production runtime bridge from the stage inventory toroute_stage().fast.scrape_summary,fast.source_relevance, andfast.hiring_signalsnow resolve their legacy utility models through the capability router behind--inference cloud|hybrid, log safe route metadata, append capped body-freestage_routesentries to_run_state.json, include measured token/cache/cost deltas when provider counters expose them, and execute through existing provider seams with today's role defaults preserved as fallback.fast.source_relevancehas an explicit, single-company experimental Codex CLI adapter; other agent/local stage execution remains planned until each stage has a dedicated adapter and eval evidence. If tests or evals select the internal agent profile before those adapters exist,fast.scrape_summaryandfast.hiring_signalsnow record body-freeagent_profile_unavailablefallbacks and use deterministic source-excerpt or posting-metadata output instead of silently falling back to cloud APIs.- First production local slice shipped (1.x, calibration judge):
ai/local_inference.pydetects any OpenAI-compatible server via the generic/v1/modelsendpoint (fail-open, cached, env-chain base URL) and picks a judge model from whatever is installed by family preference;primr calibrate --judge auto|localruns the traceability judge locally at $0 with fail-closed local-call behavior, sidecar provenance stamping, and a--judge-comparecloud-vs-local agreement measurement. These detection, fail-closed, and agreement-validation patterns are the template the utility-tier routing below should reuse. - Provider-specific xAI browse/search behavior and Gemini terminal quota
guidance now live in provider-owned seams. The xAI surrogate is owned by
XAIProviderand exposed through the legacygrok_browse_and_summarize()wrapper; Gemini quota copy is owned byGeminiProviderand rendered by the legacy Geminillm()path. - Cost estimates now expose live input, cached input, cached-input cost, and long-context surcharge fields. Historical cached-token averages are included when available, but pre-run estimates assume zero speculative cache hits.
Reviewed 2026-06-30:
- OpenTelemetry's GenAI semantic conventions have moved to the dedicated GenAI conventions surface. Backend-freedom telemetry should preserve provider, model, operation, token, and usage concepts so stage route records can map to those conventions when runtime spans are wired. See OpenTelemetry GenAI semantic conventions.
- OpenAI prompt caching is automatic for recent models and depends on exact prompt-prefix reuse, with cached-token counts exposed in usage metadata and discounted cached input pricing. Stage requirements and estimates therefore need room for stable-prefix and cached-token accounting. See OpenAI Prompt caching.
- OpenAI's current API pricing page labels GPT-5-family standard pricing as applying under 270K context. Estimates therefore model the >270K long-context tier explicitly where the registered context window can cross that boundary. See OpenAI API pricing.
- Anthropic prompt caching changed to workspace-level isolation on the Claude API, Claude Platform on AWS, and Microsoft Foundry as of February 5, 2026, while requiring exact prompt segment matches. Provider-specific cache semantics must stay provider-owned, not hardcoded in a generic stage. See Anthropic Prompt caching.
- Gemini's current API docs describe implicit caching, explicit caching on the generateContent API, context-cache token reporting, Gemini 3 long-context support, and current Interactions API limitations. Long-context estimates need provider-specific cache and API-surface fields before routes can be compared honestly. See Gemini context caching, Gemini generateContent caching, and Gemini 3 developer guide.
The three cheap utility-stage pilots now prove the runtime bridge:
fast.scrape_summary, fast.source_relevance, and fast.hiring_signals
record route metadata in _run_state.json: backend id/kind, billing mode,
route/fallback reason, expected stage token budget, latency, input/output item
counts, failure class, and measured token/cache/cost deltas when provider
counters expose them. Body-free route comparison artifacts now aggregate those
records by stage/backend/profile, and scorecards can join those route rows with
explicit quality evidence to mark candidates for human review. The CLI can now
write those artifacts through primr --eval --eval-stage-scorecard from route
ledgers plus explicit quality evidence JSON, and MCP clients can inspect the
compact scorecard summary at primr://eval/stage_scorecard/{eval_id} without
raw prompt, report, source, or run-state content. The website-summary local
stage eval now writes website_summary_stage_quality_evidence.json as
structured scorecard input, and same-command scorecard generation can consume
it when no manual quality-evidence path is supplied. The same local stage eval
can now add --eval-local-stage-semantic-judge to produce body-free semantic
quality evidence from a local OpenAI-compatible judge or comma-separated local
judge panel and feed that evidence to the same-command scorecard. Panel runs
record score-spread agreement metadata. This is still review-only: calibrated
samples and human-reviewed acceptance criteria are required before any host or
local candidate can be promoted.
The first official host-agent transport is an unpromoted
fast.source_relevance Codex adapter. Primr builds a fixed stage packet and
invokes official codex exec with a read-only sandbox, disabled web search and
shell tools, no approvals, no persisted history, a JSON-array output schema,
and bounded time/output limits. If no runner qualifies under the internal agent
profile, Primr records agent_profile_unavailable and keeps all sources rather
than spending cloud API dollars silently. The public CLI remains
--inference cloud|hybrid; an installed Codex runner becomes eligible only for
a single-company command that also supplies
--acknowledge-host-agent-may-bill. Primr records that route as potentially
metered and experimental with its promotion eval pending. Unknown host charges
are outside Primr's estimate and budget, and batch fan-out is rejected.
Promotion still requires calibrated eval evidence plus billing provenance or
the explicit billing acknowledgment.
Source-relevance fixture evals can now produce the first review-only quality
evidence for that pilot: --eval-source-relevance-fixture accepts labeled
source-number keep lists and candidate keep lists, then writes body-free
precision, recall, F1, exact-match, and scorecard quality evidence for
fast.source_relevance. It measures selection behavior without inspecting
prose or copying source URLs/text into scorecards.
The canonical inventory lives in src/primr/core/stage_inventory.py.
| Stage ID | Role | Trust | Accepted non-cloud candidates | Budget checkpoint |
|---|---|---|---|---|
fast.scrape_summary |
utility | medium | host, local | no |
fast.source_relevance |
utility | medium | host, local | no |
fast.hiring_signals |
utility | medium | host, local | no |
fast.research_deepening |
reasoning | high | none yet | yes |
fast.analysis_workbook |
reasoning | high | none yet | no |
fast.report_sections |
writing | high | none yet | no |
fast.cross_validation |
reasoning | high | none yet | yes |
fast.trust_polish |
writing | high | none yet | no |
fast.label_honesty |
utility | high | none yet | optional |
fast.strategy_generation |
writing | high | none yet | yes |
premium.deep_research |
reasoning | high | none yet | no |
Only the first three fast-mode utility stages are declared as local or host pilot candidates. Every high-trust stage remains cloud/gateway-only until the standing eval corpus proves a candidate backend preserves trust, citation, reasoning, and utility behavior.
Each pipeline stage declares a StageRequirements (frozen dataclass):
minimum reasoning depth (enum value, calibrated from eval data, not vibes),
required capabilities (web_search, structured_output, long_context >= N
tokens), trust sensitivity, accepted backend families, and acceptable latency
class. The shipped pure router solves for the cheapest compatible backend from
the supplied capability rows:
- Inputs:
StageRequirements,ModelConfigcapability/pricing metadata (extend with capability flags +tier_threshold_tokensfor the long-input surcharge models), available backend rows, operator routing policy, and later circuit-breaker health - Output: a fallback chain (ordered candidates), which
call_with_failoveralready consumes once production wiring is added - The requirements themselves come from observed eval cost/quality per role. Until a stage has eval evidence, it inherits today's role-based default - the migration is incremental, stage by stage
The public CLI exposes --inference cloud|hybrid. Internal router profiles also
represent agent and local candidates for tests and evals, but they are not
supported configuration. Today the production default is the direct-cloud path
because it is the validated full-report recipe. The 2.0 target for an unflagged
run is the best validated route by incremental spend and quality: local capacity
first where it passes the stage bar, a host runner only when its billing basis is
proven or explicitly acknowledged, otherwise the best sub-dollar API recipe,
with premium routes explicit.
clouduses direct provider APIs and remains the reproducible baseline and fallback.- The internal
agentprofile represents an official host runner for compatible stages through a sanctioned automation, local CLI, or connector surface. It is structured and bounded and cannot own the pipeline loop, egress policy, disk writes, or completion decision. It remains eval-only until quality and billing gates both pass. hybridis the public promotion surface for stage candidates that pass their requirements and evals. Host candidates also require billing provenance or explicit operator acknowledgment. Direct cloud remains in place for reasoning/trust-critical stages until eval data says otherwise.localrequires local for all compatible stages and skips stages with no local equivalent (Deep Research) with clear logging. No silent fallback to paid cloud. Its quality class is per hardware/model profile and should be re-measured as local capacity improves.
The cost estimator reports dollars for direct API stages and $0 API plus runtime for local stages. A future host route may report "host plan usage" only when the billing basis is proven; otherwise it must report unknown or potentially metered billing and require acknowledgment. Progress display names the backend per stage.
The local boundary is OpenAI-compatible HTTP, not one runtime brand. An
operator-installed MAX Serve, Ollama, llama.cpp, vLLM, LM Studio, LocalAI, or
other compatible server can be evaluated through LOCAL_LLM_BASE_URL without
adding a new provider abstraction or embedding its implementation language.
Runtime comparisons use the same model, quantization, hardware, prompts, and
quality corpus where possible. Record report and stage quality, success rate,
time to first token, throughput, p95 latency, peak VRAM, cold start, busy and
out-of-memory behavior, and total Primr run duration. The existing
available/busy/unavailable contract, bounded retry guidance, and hard-zero
no-paid-fallback rule remain authoritative regardless of runtime.
Primr does not embed Mojo or MAX through FFI and does not install, start,
reserve, or terminate the operator's model server. Bundling any runtime requires
a separate platform, distribution, security, and license review. See
runtime-language-boundaries.md.
primr prep serves users who have no provider key or GPU but do have a capable
agent host. Primr retains deterministic collection, URL safety, DNS, hiring
signals, local PDF text, source indexing, trace artifacts, and content fencing.
It writes primr.host-evidence-bundle v1.0 plus a bounded research packet. The
host then owns external research, synthesis, and review through the portable
primr-zero skill.
The collection context disables model calls even when keys are configured, and
the manifest records zero model calls and $0.00 incremental API spend. This
path must remain distinct from the internal Codex adapter: Primr does not invoke
or authenticate the host, and the output is labeled host-assisted. It is the
supported plan-native path while in-pipeline host routes remain unpromoted
until their stage eval clears.
Zero total incremental spend is promised only after the host is verified not to
bill API usage or overages.
Provider and host-account availability must be a deterministic routing input,
not ad hoc UI text or provider-specific exception handling. Collectors return
ProviderQuotaSnapshot rows. Generic collectors can report configuration and
local-service availability immediately; official live quota collectors should
add zero-token quota/status windows wherever supported and fall back to stale
last-known-good snapshots when a quota endpoint is temporarily unavailable.
The normalized contract is intentionally small:
QuotaWindowrepresents one provider bucket, such as requests per day, tokens per minute, weekly host-account usage, or local runtime capacity.binding_window()selects the most constrained window, so one exhausted bucket can prevent an otherwise healthy provider from being ranked first.- Elapsed reset times are treated as fresh quota because stale provider data should not keep a model marked exhausted after its reset boundary.
- Stale snapshots preserve useful routing information, but
provider_with_most_headroom()prefers fresh snapshots before stale ones. - Generic collectors must meet users where they are: read only their runtime environment and configured local OpenAI-compatible endpoint, never repo-owned credentials, personal account ids, raw endpoint URLs, or provider-specific private surfaces.
- Local capacity has three explicit states:
available,busy, andunavailable. A 429/503 response or probe timeout isbusy; connection failure, an invalid endpoint, or no usable chat model isunavailable. - A busy result carries body-free
retry_after_secondsandretry_atmetadata. ServerRetry-Afterhints are bounded to 30 seconds through six hours. When no hint exists, caller-supplied attempt numbers select 30 minutes, two hours, then six hours. - The same contract applies after actual local chat execution exhausts its
short in-call retries. A structured
LocalCapacityBusyErrorcarries the safe retry metadata; large server hints are not converted into hidden in-process sleeps. - Retry metadata is guidance, not an in-process scheduler. Primr does not poll, sleep until capacity frees, or become a daemon. The CLI, MCP host, or external scheduler may submit a later single job after re-checking capacity.
- An explicit local profile is a hard zero-API boundary. If no local backend qualifies, the stage returns an unavailable route and uses its deterministic no-model fallback. It never returns the paid legacy model silently. Route metadata distinguishes busy, unavailable, and unknown capacity from an available endpoint that lacks an executable stage adapter.
Next production wiring: official cloud collectors translate supported
quota/status metadata into this shape, then the existing availability-to-backend
adapter carries the resulting decision into route_stage(). ModelCircuitBreaker
continues to handle runtime failures and quota exceptions observed mid-call.
The host runner is not a generic provider API. It is a Level-2 decision point: primr hands a fixed stage packet to an official agent host and receives a schema-constrained response.
Stage packet fields: role, model capability requirements, evidence bundle, prompt, output schema, timeout, budget/plan policy, and provenance labels.
Required properties:
- Uses only official auth surfaces and local/automation commands. No browser scraping, unofficial proxies, or private endpoints.
- For the Codex pilot, the only transport is official
codex execwith a read-only sandbox, disabled web search/shell-tool config, no approvals, no persisted history, and schema-constrained output. - Remains unpromoted. Single-company hybrid experiments require an explicit potentially metered billing acknowledgment, and route metadata records that the quality eval is still pending.
- Fails open to other configured profiles when the host runner is unavailable, except when an eval harness deliberately selects the internal agent profile.
- Records runner provenance in sidecars and usage records.
- Treats route billing metadata as a declared policy category, not proof of the authenticated host session's actual billing basis.
- Runs through the same semantic calibration/eval path as API-keyed recipes before promotion.
The standard primr doctor availability section now distinguishes a reachable
local endpoint from transiently busy capacity and an unavailable endpoint. Busy
capacity includes the bounded retry time. A future focused local fit check can
add model-specific VRAM sufficiency without making vendor-specific GPU APIs part
of the generic OpenAI-compatible probe.
- Stage-requirements schema + router as a pure function over existing
ModelConfig- DONE inai/capability_routing.pywith fake-backend tests and no production behavior change while every stage still carries the legacy default. - Provider availability schema + pure headroom helpers - DONE in
ai/provider_availability.pywith no live provider calls. - Generic availability collectors - DONE in
ai/provider_availability_collectors.py: non-secret cloud configuration status plus local OpenAI-compatible probe snapshots. Next is official zero-token quota/status metadata where providers expose it. - Availability-to-backend bridge - DONE in
ai/capability_routing.py: provider snapshots mark backend rows unavailable and attach sanitized routing metadata before the pure router ranks candidates. - Doctor availability visibility - DONE in
core/cli_doctor.py: sanitized generic snapshots are visible to operators without paid cloud probes or local endpoint leakage. - Production stage capability inventory - DONE in
core/stage_inventory.py: fast-mode and premium deep-research stages now declare router-ready capability rows and promotion gates without changing runtime behavior. - Move xAI browse/search surrogate into providers - DONE in
ai/providers/xai.py:XAIProviderowns the Responses API browse/search call andgrok_browse_and_summarize()is compatibility glue. - Move Gemini quota UI/fallback messaging into provider-owned seams - DONE in
ai/providers/gemini.py:GeminiProviderowns terminal quota guidance andllm()renders it generically. - Long-context surcharge and cache-token modeling in estimates - DONE:
CostEstimatenow exposes live input, cached input, cached-input cost, and long-context surcharge fields without assuming unobserved cache savings. - First routed utility stage - DONE in
ai/stage_routing.pyandcore/source_relevance.py:fast.source_relevanceconsumesroute_stage()behind--inference cloud|hybridwhile preserving the legacy utility model as fallback. - Route usage metadata - DONE in
ai/stage_routing.pyandcore/source_relevance.py: routedfast.source_relevancecalls append capped body-freestage_routesrecords to_run_state.jsonwith backend, profile, billing, route reason, fallback reason, expected token budget, latency, source counts, and failure class. - Second routed utility stage - DONE in
ai/summarize.py: routedfast.scrape_summarycalls pass the selected model through the existing summarizerllm()seam and append capped body-freestage_routesrecords with backend, profile, billing, route reason, fallback reason, expected token budget, input page count, output summary count, duration, and failure class. - Third routed utility stage - DONE in
data/hiring_signals.py: routedfast.hiring_signalscalls pass the selected model through the existing hiring triage/extraction seams and append capped body-freestage_routesrecords with backend, profile, billing, route reason, fallback reason, expected token budget, discovered role count, extracted role count, duration, and failure class. - Route comparison artifacts - DONE in
core/stage_route_comparison.py: route records aggregate by stage/backend/profile into body-free JSON and Markdown with attempts, selected/fallback/failure counts, latency, and measured token/cache/cost deltas. These artifacts are eval inputs, not promotion decisions. - Stage eval scorecards - DONE in
core/stage_eval_scorecard.pyandcore/stage_eval_scorecard_cli.py: explicit quality evidence joins with route comparison rows to classify candidates as human-review-ready, needing quality eval, below quality bar, or needing reliability review.primr --eval --eval-stage-scorecardwrites JSON/Markdown artifacts from route ledgers and a supplied quality evidence JSON file. Scorecards never auto-promote a backend. - Stage scorecard MCP readback - DONE in
mcp_server/stage_scorecard_summary.py:primr://eval/stage_scorecard/{eval_id}returns compact route, quality-score, status, and blocker fields from the CLI-generated JSON artifact without arbitrary file paths, prompt bodies, report bodies, quality-source bodies, or raw run-state content. - Generated stage quality evidence - DONE in
core/local_stage_eval.pyandcore/cli_local_stage_eval.py: website-summary local-stage evals write scorecard-ready quality evidence from existing completeness metrics, and--eval-local-stage website-summary --eval-stage-scorecardcan consume the generated evidence in the same command. This remains scorecard input only, not a promotion gate. - Semantic local stage evidence - DONE in
core/local_stage_eval.pyandcore/cli_local_stage_eval.py:--eval-local-stage-semantic-judgeruns a local OpenAI-compatible judge or comma-separated local judge panel over baseline and candidate website summaries, stores body-free score rows, agreement metadata, and semantic quality evidence, and lets same-command scorecards use that semantic evidence when requested. This is a review signal, not a promotion gate. - First official host-runner transport - DONE as an internal/eval-only pilot
in
ai/host_agent_cli.py,ai/stage_routing.py, andcore/source_relevance.py: evals can routefast.source_relevancethrough the official Codex CLI runner, record body-free host route metadata, and refuse silent cloud API fallback when the internal agent profile has no qualifying runner. It is not a public CLI profile. - Source-relevance fixture evidence - DONE in
core/source_relevance_eval.pyandcore/cli_local_stage_eval.py:--eval-source-relevance-fixtureturns labeled keep-list fixtures into body-free quality evidence for review-onlyfast.source_relevancescorecards. - Agent-profile fail-closed safety for remaining routed utility stages - DONE
in
ai/summarize.pyanddata/hiring_signals.py: internal agent-profile unavailability forfast.scrape_summaryandfast.hiring_signalsrecords body-free route fallbacks and uses deterministic local output instead of invoking cloud LLMs before a stage-specific host adapter exists. - Keyless host-native handoff - DONE in
core/cli_prep.py,core/evidence_bundle.py,utils/model_policy.py, and the portable.agents/skills/primr-zeropackage: deterministic collection emits a versioned, bounded, fenced packet and fails closed against model egress. - Hybrid profile - IN PROGRESS. The first billing-honesty slice is shipped
for
fast.source_relevance: an explicitly acknowledged, potentially metered Codex route is available only for single-company experimental runs, with estimate, budget, route-ledger, selected-host failure, and batch-fan-out guards. It is markedexperimental_eval_pending, not promoted. Next, curate the representative source-relevance corpus and eval host vs cloud on the same labeled cases. Then route additional cheap utility stages local or through billing-proven or explicitly acknowledged hosts only after their own gates. - Full local profile +
doctor --local; eval again; document the quality band honestly - "local quality unacceptable for stage X on this hardware" is a valid, publishable outcome, and a prompt to re-test when local capacity improves - Per-stage requirement tuning from accumulated eval data
Steps 1-4 are free to build with fakes. The host-native prep path is covered by
zero-network unit fixtures plus hard no-model-call contract tests. Live runner
validation can use official host-plan allocation only after that billing basis
is verified; otherwise the operator must acknowledge potentially metered API
use. Direct cloud comparison should
stay under the existing ~$4-5 corpus pass. Local validation is $0 API plus GPU
time. A 4090-class workstation should start with the focused
4090-report-race local stage eval against the current sub-dollar API
baseline before spending time on the full local matrix. Promotion criteria pre-registered: trust-gate pass rate,
decision-utility within band of cloud baseline, billing/plan behavior
documented, runtime documented, and default class assigned (zero-incremental,
sub-dollar API, fallback, or premium-only).
- Any stage can be answered by any backend that meets its declared requirements; chains come from the router, not hardcoded preference lists
- A public host-runner profile ships only after at least one official runner has a published eval and either trustworthy billing provenance or an explicit potentially metered billing acknowledgment. Until then, the Codex adapter is an explicitly gated, single-company experiment with pending-eval metadata, not a supported or default backend. Additional hosts remain candidates until they meet the official invocation, structured-output, provenance, bounded-runtime, and billing-honesty requirements.
--inference hybridships as a supported mode with a published eval--inference localeither ships with a published eval or is documented as not-yet-meeting-bar per stage (also a valid exit)
- No new orchestration framework - the router returns a chain; execution stays in the existing failover seam
- No fine-tuning and no bundled model server; local execution points at the user's OpenAI-compatible endpoint
- No silent quality degradation: profile changes are explicit operator choices, surfaced in the run banner and usage records
- Backend freedom is model-execution freedom, not a mandate to rewrite Primr in another programming language