Commit graph

5 commits

Author SHA1 Message Date
Scott Werner
a49478c1e7 Unify the workflow graph reference walkers
The manifest bundler and workflow-version validation each maintained
their own walk over the graph reference vocabulary (goal files, inline
goal/prompt templates, imports, child workflows, @-file attributes), so
a new reference-bearing attribute had to be added twice or the two
would drift. Add fabro_template::visit_graph_references as the single
per-graph walker — it validates that file references are template-free
and emits typed events — and rewrite both consumers on top of it,
keeping their own IO, resolution, and recursion.

Same for dockerfiles: SettingsLayer::image_layers[_mut] is now the one
definition of where images live in a settings layer, replacing the
three hand-rolled traversals in the run compiler, manifest bundler, and
workflow-version validation.

Behavior note: the manifest bundler now also follows
stack.child_dotfile (already in the shared vocabulary and treated as a
child-workflow reference by workflow-version validation); nothing in
the engine emits or reads that attribute today.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-13 13:46:10 -04:00
Scott Werner
7bf40373f9 Split workflow version wire type from semantic validation
Move the WorkflowVersion wire type and its structural invariants (file
count and size limits, entrypoint presence, unique keys, path
collisions, canonical form) into fabro-types, so fabro-api replaces the
generated schema type without pulling graph parsing or the template
engine into every API consumer. The wire shape is unchanged.

fabro-workflow-version keeps the expensive graph/config/template
validation behind a ValidatedWorkflowVersion newtype and now owns
WorkflowVersionStore: put only accepts validated versions and get still
re-validates blobs read from shared storage. fabro-store goes back to
being domain-agnostic persistence.

Move the static-reference attribute vocabulary (ReferenceKind,
AttributeScope, reference_kind_for_attribute) to fabro_types::graph and
template-syntax validation to fabro-template, so fabro-graphviz no
longer depends on the template engine.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-13 13:46:10 -04:00
Release Repro
b04684aec4
fix(workflow): harden script value interpolation 2026-07-28 17:21:35 -04:00
Bryan Helmkamp
6bcd730284
feat(workflow): interpolate goal, inputs, and vars in command scripts
Command node `script` attributes were literal text: a `{{ inputs.x }}`
reached bash verbatim, and the only signal was a `detemplated_attribute`
warning. Scripts now substitute `{{ goal }}`, `{{ inputs.NAME }}`, and
`{{ vars.NAME }}` at run creation, alongside goals and prompts.

Scripts use `InterpString` token substitution rather than the MiniJinja
pass that renders prompts. Shell source is full of brace syntax that must
survive untouched — jq filters, awk programs, Go templates, brace
expansion — and `InterpString` claims only the narrow token forms,
leaving everything else literal.

`env` and `secrets` are deliberately not wired and now fail loudly
instead of passing through as text. A script reads the environment with
`$NAME`, which needs no interpolation, and a resolved secret would be
baked into the `CommandStarted` event that records the script verbatim.
The error points at `[environments.<slug>.env]` for the secret case.

`ResolveCtx` gains opt-in `with_inputs` and `with_goal`. Namespace
availability stays scope-determined per call site, so every existing
config-layer context leaves both unwired and keeps its current behavior.
`goal` names a single value rather than a namespace of them, so it has
no dotted form: only the exact body `goal` produces a token and
`{{ goal.title }}` stays literal.

Values substitute verbatim without shell quoting, matching
`[[run.prepare.steps]].script` where the snippet is the author's to
quote. Substituted text is never rescanned.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-27 19:56:50 -04:00
Scott Werner
47bc772f7b refactor: organize crates into three layers 2026-07-23 17:59:34 -04:00