mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-08-28 05:27:41 +00:00
Remove stale env-interpolation promises from docs
Config {{ env.NAME }} interpolation was removed workspace-wide (tokens
still parse only to fail with a migration message), but several doc
comments and the server-secrets strategy doc still presented it as a
live mechanism, including run goal file paths where the new
workflow-version validation now makes the contradiction user-visible.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
4e48d2887e
commit
14cc56b25f
5 changed files with 17 additions and 21 deletions
|
|
@ -13,7 +13,7 @@ when does it resolve** — see [Which process resolves what](#which-process-reso
|
|||
- Resolution is snapshot-based: env and file are read once at construction, then treated as immutable for the life of the process.
|
||||
- `process env` wins over `server.env` on conflicts.
|
||||
- Optional integration secrets are vault-only in the **server process**. Do not add optional server integrations to `ServerSecrets`, and do not add bespoke env fallback paths to it.
|
||||
- Not every credential is a `ServerSecrets` or vault lookup. A third mechanism exists: **settings-declared credentials** in `InterpString` fields, resolved at consumption time from `{{ env.NAME }}` or `{{ secrets.NAME }}`. See [Settings-declared credentials](#settings-declared-credentials).
|
||||
- Not every credential is a `ServerSecrets` or vault lookup. A third mechanism exists: **settings-declared credentials** in `InterpString` fields, resolved at consumption time from `{{ secrets.NAME }}`. See [Settings-declared credentials](#settings-declared-credentials).
|
||||
- `fabro server start` never generates secrets. Missing required secrets are a startup error.
|
||||
- `std::env::set_var` and `std::env::remove_var` are banned workspace-wide. Tests are not exempt. Enforced by clippy via `disallowed_methods` in `clippy.toml`; intentional exceptions must be annotated with a scoped `#[expect(clippy::disallowed_methods, reason = "...")]` at the call site.
|
||||
|
||||
|
|
@ -70,7 +70,6 @@ than saying "server runtime", which is ambiguous.
|
|||
| Bootstrap server secret | Server process, via `ServerSecrets` | Once at construction, then immutable |
|
||||
| Optional integration secret | Server process or worker, via the vault | At use |
|
||||
| `{{ vars.NAME }}` | Server process | When the run is created, from that run's variable snapshot |
|
||||
| `{{ env.NAME }}` | The process that owns the value (usually the worker) | At consumption time |
|
||||
| `{{ secrets.NAME }}` | The process that owns the value, against the server vault | At consumption time |
|
||||
|
||||
`docs/public/agents/mcp.mdx` documents the same split for MCP server configuration and is a good
|
||||
|
|
@ -80,18 +79,17 @@ worked example of the shape.
|
|||
|
||||
Some credentials are declared in settings rather than looked up by name. Those fields are
|
||||
`InterpString` (`lib/foundation/fabro-types/src/settings/interp.rs`), which supports narrow
|
||||
`{{ namespace.NAME }}` tokens with no template logic. Three namespaces resolve: `env` (process
|
||||
environment, consumption time), `secrets` (vault, consumption time), and `vars` (non-sensitive run
|
||||
variables, substituted early at run creation). A token whose namespace is unavailable in the
|
||||
resolution context fails loudly.
|
||||
`{{ namespace.NAME }}` tokens with no template logic. Two namespaces resolve: `secrets` (vault,
|
||||
consumption time) and `vars` (non-sensitive run variables, substituted early at run creation).
|
||||
`{{ env.NAME }}` tokens still parse but never resolve; they fail loudly with a migration message. A
|
||||
token whose namespace is unavailable in the resolution context also fails loudly.
|
||||
|
||||
The reference implementation is LLM provider `extra_headers`, resolved against env plus vault at
|
||||
The reference implementation is LLM provider `extra_headers`, resolved against the vault at
|
||||
`lib/foundation/fabro-auth/src/resolve.rs:376-378`:
|
||||
|
||||
```toml
|
||||
[llm.providers.example.extra_headers]
|
||||
authorization = "Bearer {{ secrets.EXAMPLE_TOKEN }}"
|
||||
x-tenant = "{{ env.EXAMPLE_TENANT }}"
|
||||
```
|
||||
|
||||
Use this mechanism when the credential belongs to an operator-configured integration declared in
|
||||
|
|
@ -149,7 +147,7 @@ First pick the mechanism. These are the only three:
|
|||
|---|---|---|
|
||||
| Bootstrap server secret | Platform env or install-written `server.env` | `state.server_secret(...)` |
|
||||
| Optional integration secret | Vault (`fabro secret set`, `fabro install`) | `state.vault_secret(...)` |
|
||||
| Settings-declared credential | `{{ secrets.* }}` or `{{ env.* }}` in an `InterpString` settings field | Resolved at consumption time by the owning process |
|
||||
| Settings-declared credential | `{{ secrets.* }}` in an `InterpString` settings field | Resolved at consumption time by the owning process |
|
||||
|
||||
Then:
|
||||
|
||||
|
|
|
|||
|
|
@ -109,8 +109,8 @@ pub(crate) fn resolve_workflow(request: ResolveWorkflowInput) -> anyhow::Result<
|
|||
|
||||
/// Resolve the `run.goal` override for a direct (non-manifest) workflow
|
||||
/// run. Reads the file from disk if the goal layer is the `file` variant.
|
||||
/// Relative paths that survived config load (e.g. env-interpolated ones)
|
||||
/// are anchored at `working_directory`.
|
||||
/// Relative paths that survived config load are anchored at
|
||||
/// `working_directory`.
|
||||
fn resolve_goal_override(
|
||||
settings: &WorkflowSettings,
|
||||
working_directory: &Path,
|
||||
|
|
|
|||
|
|
@ -78,8 +78,8 @@ pub struct LifecycleOptions {
|
|||
}
|
||||
|
||||
/// A single setup (prepare) command and the per-step environment it runs with.
|
||||
/// Both the command string and the env values are already fully resolved (their
|
||||
/// `{{ env.* }}` tokens replaced at the run boundary) by the time they reach
|
||||
/// Both the command string and the env values are already fully resolved
|
||||
/// (interpolation tokens replaced at the run boundary) by the time they reach
|
||||
/// the sandbox.
|
||||
pub struct SetupCommand {
|
||||
pub command: String,
|
||||
|
|
|
|||
|
|
@ -116,10 +116,8 @@ impl Combine for RunIntegrationsGithubLayer {
|
|||
///
|
||||
/// Relative paths inside the `file` variant are resolved against the
|
||||
/// directory of the config file that declared them at load time (see
|
||||
/// `fabro_config::resolve_goal_file_paths`). `{{ env.NAME }}` interpolation is
|
||||
/// supported inside the `file` path; env-tokenized relative paths stay
|
||||
/// unresolved until consume time and are then resolved against the run's
|
||||
/// effective working directory.
|
||||
/// `fabro_config::resolve_goal_file_paths`). Interpolation tokens are not
|
||||
/// supported inside the `file` path; a tokenized path fails to resolve.
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(untagged, deny_unknown_fields)]
|
||||
pub enum RunGoalLayer {
|
||||
|
|
|
|||
|
|
@ -61,8 +61,8 @@ pub struct ProviderCatalogSettings {
|
|||
pub api_key_url: Option<String>,
|
||||
#[serde(default)]
|
||||
pub base_url: Option<String>,
|
||||
/// Unresolved interpolation source strings (literal text, `{{ env.NAME }}`,
|
||||
/// or `{{ secrets.NAME }}` tokens), resolved at the credential boundary in
|
||||
/// Unresolved interpolation source strings (literal text or
|
||||
/// `{{ secrets.NAME }}` tokens), resolved at the credential boundary in
|
||||
/// `fabro-auth`.
|
||||
#[serde(default)]
|
||||
pub extra_headers: Option<HashMap<String, String>>,
|
||||
|
|
@ -438,8 +438,8 @@ pub struct CatalogProvider {
|
|||
pub billing_policy: BillingPolicy,
|
||||
pub api_key_url: Option<String>,
|
||||
pub base_url: Option<String>,
|
||||
/// Unresolved interpolation source strings (literal text, `{{ env.NAME }}`,
|
||||
/// or `{{ secrets.NAME }}` tokens), resolved at the credential boundary in
|
||||
/// Unresolved interpolation source strings (literal text or
|
||||
/// `{{ secrets.NAME }}` tokens), resolved at the credential boundary in
|
||||
/// `fabro-auth`.
|
||||
pub extra_headers: HashMap<String, String>,
|
||||
pub priority: i32,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue