Workflow Runner
Phase 6 adds FreshForge’s first workflow execution surface: a serial local runner for provider-owned nodes. Phase 7 adds optional run namespaces and compact run summaries so repeated local runs can be compared without artifact collisions.
The runner keeps FreshForge generic. FreshForge validates the workflow, creates
the deterministic run plan, resolves relative artifact paths against a run
working directory, and calls provider run_node hooks in plan order. Domain
packages still own the actual work.
Command Line
Use freshforge run with a workflow spec:
freshforge run examples/stand_treatment_workflow.yaml --json
Plan-only providers fail with a clear diagnostic instead of pretending to run:
node.execution.unsupported
Executable provider packages may implement run_node(node, node_type,
context=...) and return a ProviderRunResult. The run result is serialized
as deterministic JSON and includes workflow status, per-node status, provider
outputs, artifact paths, and diagnostics.
Working Directory
Relative artifact paths are resolved against the selected work directory:
freshforge run path/to/workflow.yaml --workdir /path/to/project --json
The default work directory is the current directory. Providers can use
context.resolve_path(...) to resolve workflow-declared paths.
Run Namespaces
Use --namespace to isolate relative artifacts for repeated local runs:
freshforge run path/to/workflow.yaml --workdir tmp/runs --namespace strategy/output-columns --json
With that command, a workflow artifact declared as reports/out.json resolves
under tmp/runs/strategy/output-columns/reports/out.json. Absolute artifact
paths remain absolute. Namespaces must be non-empty relative paths and may not
contain ...
Run Summaries
JSON run output includes both the full run record and a compact
summary record:
{
"ok": true,
"run": {"workflow_id": "demo"},
"summary": {"workflow_id": "demo", "node_count": 3}
}
The summary includes the workflow id, optional namespace, status, node counts, diagnostic counts, artifact count, and per-node compact summaries. Full outputs, artifacts, diagnostics, and provider data remain available in the full run record.
For downstream tools that only need the compact record, use --summary:
freshforge run examples/stand_treatment_workflow.yaml --summary
This emits the same deterministic summary object that appears under
summary in --json output, without the full run record.
Boundaries
The Phase 7 runner is intentionally small. It does not add caching, checkpointing, parallel execution, remotes, retries, shell-command nodes, or domain-package imports in FreshForge core. Phase 8 builds on the runner with generic repeated-run matrices; see Run Matrices.