Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Versions, seeded runs and frozen examples

Every run records the code and parameters it used. You can reuse compatible completed work while developing, or run the current code with a saved use case and inspect how its answers changed.

The tree

weft tree shows source versions and their runs. A color identifies one execution. Freeze and diff also accept an unambiguous prefix of that color. Each version records the project’s source files by content hash.

CommandEffect
weft checkpoint [label]Record the current files without building or running, and move head to that version.
weft branch <version|label|color>Restore that version’s files and move head. A color also selects that run as the next seed.
weft treeShow versions, runs and head. --json includes the version matching disk.
weft checkpoint --root / weft run --rootRecord a source version without a parent. Refuses if that version already has a parent. On run, root disables seeding.
weft prune <version>Remove the subtree and its runs after confirmation.

Head is shared per project. Checkpoint clears head’s selected run; a later seed looks for a settled run on that version or its nearest ancestor. Branch refuses to overwrite unkept edits; checkpoint them first. --discard explicitly permits replacing them.

Prune refuses when head, an activated listener, running work or a frozen example still needs the source history. Unused bakes belonging to explicitly pruned versions are removed too. Source files still referenced by a registered build or surviving history remain retained.

Running one group, or one node onward

Run builds automatically. Keep the graph intact and select the work to exercise:

weft run --from classify='{"text":"the invoice is wrong"}' --target reply --save invoice --detach
weft run --group triage='{"text":"the invoice is wrong"}' --detach
weft run --from triage='{"text":"the invoice is wrong"}' --before publish --detach
FlagMeaning
--from node='{"port":value}'Start at the node with backup inputs. A bare node supplies no backup. Repeat for several starts.
--emit node='{"port":value}'Supply that node’s outputs without executing its body, then continue downstream.
--target node-or-groupInclude this endpoint and stop propagation beyond the cut. A group or loop name includes its whole body. Repeat for several endpoints.
--before node-or-groupStop before this endpoint. A group or loop name excludes its whole body. Repeat for several endpoints.
--group group='{"port":value}'Run a whole group or loop alone, using its input ports. An included file uses its group alias.

Downstream work brings the other producers it needs. The upstream walk stops at each --from, --emit, and trigger. For A feeding C and B also feeding C, --from A includes B; --from C stops before both producers and uses C’s supplied backups or normal closed-input behaviour. Unrelated branches stay out. A cut selecting no work or output evidence is refused before building an image.

--group is a complete selection: it cannot combine with from, emit, target or before. --from group=... starts at the whole group and continues downstream instead. Cuts inside ordinary groups stay at the named node. Their _should_flow gates still apply, and a true gate dispatches only selected work. Loops are indivisible: select the whole loop or move the cut outside it. Trigger setup and infra preparation follow the same restrictions.

Supplied inputs are backups at the named starts. The runtime waits for real producers first. A real value wins, including null; a clean closure without a value permits the backup. An error or invalid real value remains an error. Inputs at arbitrary interior nodes are not part of the run parameters.

For a generator output, --emit batches='{"items":["first","second"]}' emits those items in order and closes the port. An empty array closes it without an item. An ordinary list port receives its array as one value. Read the port type before supplying it.

Preparing and firing triggers

weft bake
weft run --fire incoming='{"event":"the trigger wake payload"}' --detach
weft run --emit incoming='{"message":"the emitted output value"}' --detach

Bake runs preparation and saves the resulting trigger settings without arming listeners. A fire uses those settings and gives exactly one trigger its wake payload. An emit supplies declared outputs without executing that trigger.

The payload you type is checked against what that trigger declares it wakes with, before anything is built or started, and the check is exact: a missing field is refused, and so is a field the trigger does not declare, each named. weft run --fire prints the shape it wanted, which is the quickest way to see what a trigger takes (firesWith). The same trigger cannot use both forms. Trigger inputs are prepared through bake; a trigger cannot be a from start.

The bake must match the code and configuration being run. Bake again after changes. Closed group gates can leave triggers unprepared; inspect preparation events when fire refuses. weft bake <project-id> uses the registered build. Builds include the whole catalog by default. If using --referenced, use it for both bake and run so their code identities match.

weft activate prepares and arms listeners. Each real event starts its own run from its one trigger, using the program that prepared that listener.

Seeding: run only what changed

weft run --seed reuses eligible completed work from head’s selected run. When head names only a version, it finds a settled run there or on the nearest ancestor. To select a particular older run, branch to its color first; branch also restores its code, so checkpoint edits you want to keep.

--seed-before node permits reuse before that node. --seed-until node also permits reusing the node itself. Both require --seed. These flags bound reuse; target and before bound execution.

Changed implementations, inputs or dependencies invalidate affected work. Failed work and live handles cannot be reused. Loops are reused whole. The run reports what was inherited and what ran. A requested reuse boundary does not make incompatible results eligible; read the warning and move the cut earlier if the old values cannot supply it. A fully inherited run is valid.

--from chooses a boundary, not a forced rerun. With --seed, unchanged work inside that cut can be reused, including identical used backups. Omit --seed to run it again, or use the seed endpoints to limit reuse.

The unchanged standard library shares a finished worker image across projects. Setup prepares it, and releases publish it so a project can pull it without compiling. Project names, IDs and graph settings do not change that image. Node edits, added nodes, custom build settings, or --referenced need their own image. Building one compiles only what no earlier build on this machine already compiled: every worker build shares one compile cache, and a node whose files have not changed is taken from it. Once the standard library has been compiled once, a project with one custom node compiles that node and links. weft clean --build-cache throws that cache away.

Builds include the whole catalog by default. Adding an unchanged catalog node or editing graph configuration needs no new image. --referenced opts into compiling only the graph’s node types. Implementation edits still rebuild.

Freezing an accepted run

--save name saves starting parameters to examples/name.json. weft run name runs the current program with those parameters, whether the file contains only parameters or a frozen result.

weft run invoice --detach
weft events <color> --full
weft freeze invoice <color> --expect reply
# After changing the program:
weft run invoice --detach
weft diff <new-color> example:invoice --full
# After accepting the new result:
weft freeze invoice <new-color> --expect reply

Freeze requires a completed run. It preserves that run’s starting parameters and observed outputs. A seeded whole run preserves its original starting inputs; a carved run preserves its cut and inputs entering it. Interior reused results do not become hidden fixed inputs.

expected holds output history, including finite streams and closures. Repeat --expect node to focus review on particular outputs. Focus affects comparison, not execution. A focused output that disappeared remains visible as a difference. Stored media compares by content hash.

Run the example without seed when reviewing the current computation. Diff presents changed values for a person or AI to judge; differences do not produce a failing exit status. Inspect execution status separately. Run and diff leave the accepted file intact; freeze again only after accepting its replacement. weft examples lists saved parameters and frozen examples.

Repairing saved parameters after a graph change

Removed input ports are ignored with a warning. Missing starting nodes or cut endpoints are errors, so move the cut explicitly:

weft run invoice --clear from --from new_classifier='{"text":"the invoice is wrong"}' --target reply --detach
weft run invoice --clear group --from triage='{"text":"the invoice is wrong"}' --before publish --detach

Explicit from, target, before, group and fire flags replace their corresponding saved settings. Repeated new from flags form the replacement map. Emit flags replace the named ports while retaining other saved emit entries. --clear from|emit|target|before|group|fire clears a field before edits; repeat it for several fields. Duplicate newly supplied ports are errors. Use --save another-name to preserve revised parameters separately.

When a run waits

Frozen examples retain human questions and answers and incoming caller messages for inspection. They are not automatic replies. Compare the new question with the recorded question and answer before answering the current token. For a live connection, send messages through a new connection.

weft wake <color> <node> resolves a pure timer wait. A wait expecting a value must receive that value.

Reading the result

weft executions shows status. weft logs <color> shows failures and node logs; weft events <color> --node <id> --full shows values. Inherited history names its original run and is interpreted against its original program. Historical costs are not new charges. The editor can display the same run on its graph, including inherited work.

Completion establishes that execution finished. The output evidence tells you whether the program answered the use case.