Agent Platform — current state & remaining gates
Operator + reviewer note for the agent platform that shipped in PR #192 (claude/model-gateway-v2)
and the follow-up unification. What is live, what is still dark, the rollback story, and how to
validate. No changelog, no marketing — just clarity. Companion to agent-platform-boundary.md.
Update (post-launch unification): PR #192’s pre-merge readiness framing (a gateway_enabled
flag with a parallel legacy path) is obsolete. The owner ruled ONE model system before launch —
the flag and the legacy resolver were deleted from source (candado-pinned). This note reflects
the shipped reality: the gateway is the only model path, Chat v0 is live, and the internal
agents run on the same tool platform as Chat.
What’s live
Model Gateway — THE model path (one system)
- Every run (Auditor/Architect/Librarian/Chat) resolves
{base, auth}per provider, per attempt, throughbuildGatewayResolveroverProviderCredentialService.resolveAuth— server-side only, never returned by the API. There is nogateway_enabledflag and no legacy resolver (pr-hardening.guard.spec.tspins their absence). - OpenCode is one provider class inside the gateway. A workspace’s legacy subscription key
(
settings.agents.opencode_key_enc) resolves for BOTHopencodeandopencode-gothrough the credential shim, wire-identical to the pre-gateway path (buildChatRequestcandado,agentic-loop.spec.ts). provider_credentialsis the single credential store (entity registered in BOTHlibs/db/data-source.tsandapps/api/app.module.ts— the parity candadodb-entity-registration.guard.spec.tskeeps them in sync). MigrationBackfillOpencodeCredential1715200000100copies each legacy key into a real row (additive, idempotent, reversible); the legacy field + shim are retained as the rollout safety net.- Dashboard: one always-on “Model providers” section (Settings → Agents) — save/test/revoke a
credential for any of the ten provider classes, and a provider-aware model picker (OpenCode via
the models.dev catalog; every other adapter_ready provider via the live
GET /modelsprobe).
Chat v0 — live, read-only
apps/api/src/chat(module/controller/service + chat-tools),ChatThread/ChatMessageentities + migrations, thechatskill, and the dashboard wiring. A Chat assistant turn IS anagent_run(single ledger). v0 is READ-ONLY — governed writes are B4 and need a new owner ruling.
One tool platform, used everywhere
- The
DriftlessToolregistry (policy gate + observability + citations) backs Chat AND — viacognitive/agent-tools.ts(buildAgentToolExecutor) — the Auditor/Architect (SANDBOX_TOOLS) and Librarian (TOPIC_TOOLS). The canonical sets are parity-locked to the live literals so the flip is a provable no-op; the agents presentcaller:'internal_agent'and their in-loop tools are all read (the policy engine is a transparent pass-through). Their governed writes stay post-loop Action blocks.SANCTIONED_LIVE_IMPORTERSpins exactly who consumes the platform.
What is NOT live (still dark, candado-pinned)
DriftlessGatewayModel(the@ai-sdk/providerV4 adapter) — constructed by nothing live (mastra-boundary.spec.ts).- Native Anthropic/Google adapters —
adapter_ready:false+base_url:null; the resolver refuses them (provider-registry.contract.spec.ts). Reach them today via a custom OpenAI-compatible endpoint. Priority live providers: OpenAI-compatible, OpenRouter, DeepSeek, Qwen, custom OpenAI-compatible, local, and OpenCode (Zen/Go). - Mastra runtime — no
@mastra/*dependency, no import (static or dynamic). Deferred. - External-caller (MCP) write/act tool exposure — hard-denied even with the exposure flag on
(
tool-policy.spec.ts). - Chat governed writes (B4) — Chat is structurally read-only.
Rollback / no-op story
- Per workspace: revoke the offending provider credential (
DELETE /workspaces/:slug/provider-credentials/:provider_class) and/or pointsettings.agents.modelback atopencode/…refs. There is no flag to flip — the gateway is the only path. - The legacy
opencode_key_enc+ model string stay valid and authoritative through the shim; the backfill migration is reversible (down()removes only the rows it created). - The
provider_credentialstable +agent_config_events.provider_classcolumn migration is additive and reversible.
Remaining gates
- Mastra real runtime — deferred (its adoption card gates it;
@mastra/corego/no-go). - Native Anthropic/Google native-auth wire — a dedicated card, kept dark until then.
- Drop the legacy
opencode_key_encfield + the resolveAuth shim — a follow-up, only once the backfill is proven complete in staging/prod.
