fabro-auth defined its own `CredentialSource` trait beside the lithos
`CredentialProvider`, with a parallel `ResolveError` and an adapter between
them, because lithos had no way to ask which providers a store can serve
right now. It does now: `credentials::readiness`, `ClientBuilder::build_ready`,
and `CredentialError::Unusable`.
- The vault, SQL vault, API-key, and extra-headers stores implement
`CredentialProvider` directly. Material that is present but unusable (an
expired token with no refresh, a wrong-typed vault entry, a header secret
that did not resolve, a store read failure) is `CredentialError::Unusable`
with the operator-facing reason; its `Display` replaces
`auth_issue_message`. `is_configured` is the cheap presence check.
- `fabro_llm::build_client` calls `build_ready`; `FabroClient::auth_issues`
carries `CredentialError`. `fabro_llm::configured_providers` replaces the
per-store `configured_providers` method.
- `CredentialSource`, `ResolvedCredentials`, `lithos_credentials`,
`ResolveError`, and `auth_issue_message` are deleted. Twenty files that
held `Arc<dyn CredentialSource>` hold `Arc<dyn CredentialProvider>`.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Workflow LLM handlers build lithos requests, bill from lithos usage and
cost, and classify failures from lithos `ErrorKind`. Model resolution and
fallback use the fabro-llm selection and catalog helpers. Validation
rules read the lithos catalog, and store fixtures use the new
`BilledModelUsage` shape.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
`EnvCredentialSource` resolved provider credentials from the process
environment. It had no production entry point of its own — it was only
ever reached as the `None` arm of an `Option<Vault>` in three places:
`build_llm_source`, `configured_providers_for_start`, and
`configured_providers_from_process_env`.
That optional vault is not a state the product can be in. Every run has a
server behind it, the server always spawns workers with `--storage-dir`
(`worker_runtime.rs`), and `SqlVaultCredentialSource` backs both the
server and the CLI. So the fallback only served to silently degrade
credential resolution to whatever the worker process happened to have in
its environment.
Make the vault required across the run path — `RunOptions`,
`StartServices`, `build_llm_source`, `tool_secrets_from_configured_sources`,
`vault_token_lookup`, and the CLI GitHub helpers — so the invariant is
enforced by types rather than assumed. A worker spawned without
`--storage-dir` now fails with a clear message instead of quietly
continuing without a vault.
`configured_providers_from_process_env` had no callers at all and is
deleted. `AgentApiBackend::new_from_env` was public but only ever called
from its own tests; it is deleted too.
Test-only credential sources move to a feature-gated
`fabro_auth::test_support`, wired through dev-dependencies so they never
link into production builds. The CLI worker tests now pass
`--storage-dir`, matching what the server actually does.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>