mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-09-14 23:22:51 +00:00
Implements the goal self-reference behavior for interpolation
unification. Independent off `main` — no dependency on the other interp
PRs (touches only the template/goal-render path).
## What changes for users
A graph `goal` is a template that interpolates `{{ inputs.* }}`
(unchanged). A node `prompt` can reference the rendered goal via `{{
goal }}` (unchanged). **New:** a goal can **no longer reference itself**
— `{{ goal }}` *inside* a goal was previously a silent passthrough (left
as the literal text `{{ goal }}`); it's now a clear error.
```
graph [goal="Refine {{ goal }}"] # error: a goal cannot reference itself
work [prompt="Work on {{ goal }}"] # fine: prompts reference the rendered goal
```
## How
- **Structural guarantee:** the goal renders with **no `goal` key in
scope** (`TemplateContext::new().with_inputs(..)` instead of the
`for_input_scan` passthrough), so a self-reference can't resolve.
- **Friendly lint:** before rendering, `resolved_goal` checks the goal
template for a top-level `goal` reference — new
`fabro_template::references_top_level_variable`, backed by MiniJinja
`undeclared_variables` — and emits a dedicated `goal_self_reference`
diagnostic (`Severity::Error`) with a clear message and fix-it, instead
of a generic "undefined variable `goal`". Fails `fabro validate` and
run-create alike.
The goal is resolved in two transform passes (FileInlining +
TemplateTransform); the diagnostic is emitted **once** (FileInlining
discards its goal-resolution diagnostics; TemplateTransform is the
canonical emitter).
## Behavior change (release notes)
A goal containing `{{ goal }}` now **errors** instead of passing through
as literal text. The error message is the migration signal.
## Tests
- `references_top_level_variable` detection
- transform-level rejection (`Severity::Error`)
- single-emission across the two passes
- end-to-end `validate` rejection
- existing goal/prompt tests still green (prompts reference goal; goal
interpolates inputs)
## Verification
- `cargo build --workspace`
- `cargo +nightly clippy --workspace --all-targets -- -D warnings`
- `cargo +nightly fmt --check`
- `cargo nextest run --workspace`: 6800 passed
Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
||
|---|---|---|
| .. | ||
| crates | ||
| packages/fabro-api-client | ||