mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-08-28 05:27:41 +00:00
Third reducing PR of the interpolation unification (**D11 resolution
(c)**): the control plane never interpolates. `InterpString` is now
strictly the user-facing workflow config language; server identity,
storage, listen, object-store, and GitHub App identifiers are plain
`String`, consumed where needed with no resolution point.
## Demoted to `String` (was `InterpString`)
Both the layer and resolved types:
- `server.listen.unix.path`, `server.api.url`, `server.web.url`
- `server.storage.root`, `server.artifacts.prefix`,
`server.slatedb.prefix`
- object store: `Local.root`, S3 `bucket` / `region` / `endpoint`
(shared by artifacts + slatedb)
- `github.app_id` / `client_id` / `slug`
**Kept `InterpString`:** `slack.default_channel` (run-time consumption —
the one server-defined survivor). `server.listen.tcp.address` stays the
`SocketAddr` `parsed_value` special case.
## Native `FABRO_WEB_URL` read
Deployment-time late binding now goes through a native env read instead
of a `{{ env.* }}` token: `FABRO_WEB_URL` overrides `server.web.url`
(**env override > settings literal > default**), applied in
`canonical_origin` and reused by the JWT issuer, cookie-secure check,
and system-info. `docker/split-web` no longer ferries the value through
a settings token (compose still sets the env var). `canonical_origin`'s
error message now advertises a knob that is actually true for everyone.
## Behavior change (release notes)
- `{{ env.* }}` / `{{ vars.* }}` tokens in the demoted server fields are
now **literal text**, not interpolated. The resolve layer emits
`warn_if_demoted_template` for every demoted field, so operators with
tokens still in server config **fail loud** rather than silently
treating the token as a literal.
- Operators who relied on env-based storage location should use the
existing native `FABRO_STORAGE_DIR` (`--storage-dir`) override.
`FABRO_STORAGE_ROOT` promotion is intentionally deferred (not a proven
need).
## Cleanup
`fabro-server`'s `crate::interp` shrinks to just the process-env lookup
facade; `resolve_interp` / `_path` / `_with` and the
`AppState::resolve_interp` seam are deleted (nothing resolves
server-scope `InterpString` anymore).
## Verification
- `cargo build --workspace` ✅
- `cargo +nightly clippy --workspace --all-targets -- -D warnings` ✅
(incl. the `as_source` gate)
- `cargo +nightly fmt --check --all` ✅
- `cargo nextest run --workspace`: 6305 passed; added two tests covering
the `FABRO_WEB_URL` override precedence (env-wins and settings-literal
fallback).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
||
|---|---|---|
| .. | ||
| build-support | ||
| fabro-acp | ||
| fabro-agent | ||
| fabro-api | ||
| fabro-auth | ||
| fabro-automation | ||
| fabro-checkpoint | ||
| fabro-cli | ||
| fabro-client | ||
| fabro-config | ||
| fabro-core | ||
| fabro-dev | ||
| fabro-dump | ||
| fabro-environment | ||
| fabro-github | ||
| fabro-graphviz | ||
| fabro-hooks | ||
| fabro-http | ||
| fabro-install | ||
| fabro-interview | ||
| fabro-llm | ||
| fabro-macros | ||
| fabro-manifest | ||
| fabro-mcp | ||
| fabro-mcp-server | ||
| fabro-model | ||
| fabro-oauth | ||
| fabro-options-metadata | ||
| fabro-proc | ||
| fabro-redact | ||
| fabro-sandbox | ||
| fabro-server | ||
| fabro-slack | ||
| fabro-spa | ||
| fabro-static | ||
| fabro-store | ||
| fabro-telemetry | ||
| fabro-template | ||
| fabro-test | ||
| fabro-tool | ||
| fabro-tracker | ||
| fabro-types | ||
| fabro-util | ||
| fabro-validate | ||
| fabro-variable | ||
| fabro-vault | ||
| fabro-workflow | ||