Life of a Molecule
Last verified against code: 2026-03-17
Summary
A molecule starts as a*.formula.toml file, becomes active through formula
layer resolution, is instantiated by the configured beads backend, gets routed
to an agent or pool, and eventually closes and ages out through wisp GC.
The crucial current-state detail is that Gas City resolves formula files, but
the store backend performs runtime formula instantiation.
Phase 1: Definition
Formulas live on disk as*.formula.toml files in city, pack, or rig formula
directories.
Example:
Phase 2: Resolution
ComputeFormulaLayers() in internal/config/pack.go builds ordered formula
layers for the city and each rig. ResolveFormulas() in
cmd/gc/formula_resolve.go then:
- scans all layers for
*.formula.toml - keeps the highest-priority file for each filename
- stages winners into
.beads/formulas/as symlinks - removes stale formula symlinks
bd.
Phase 3: Instantiation
Molecule creation goes through thebeads.Store interface:
Store.MolCook(formula, title, vars)Store.MolCookOn(formula, beadID, title, vars)
BdStoreusesbd mol wispandbd mol bondexec.Storedelegatesmol-cookandmol-cook-onto a scriptMemStoreandFileStorecreate simplified molecule roots for tests and tutorials
BdStore is the normal path.
Phase 4: Routing
After instantiation,gc sling or order dispatch routes the molecule root:
cmd/gc/cmd_sling.gohandles explicit user dispatchcmd/gc/order_dispatch.gohandles formula-backed scheduled work
Phase 5: Execution
The agent picks up the molecule through the bead store and works through the resulting tasks. In production,bd owns the detailed step-bead materialization
and dependency handling. Gas City does not currently provide a separate
in-process formula executor for the main runtime path.
At this layer, the important contributor rule is simple:
- molecule creation is a store concern
- routing is a
cmd/gc/concern - step execution is an agent plus backend concern
Phase 6: Completion
Once the work represented by the molecule is done, the relevant beads are closed. The root molecule bead then transitions toclosed as well.
That closed root still matters because it is:
- visible for history and audit
- eligible for TTL-based cleanup if it is a wisp
- useful to order cooldown tracking when created by automation
Phase 7: Garbage Collection
cmd/gc/wisp_gc.go periodically purges closed molecules older than
[daemon].wisp_ttl, on the cadence set by [daemon].wisp_gc_interval.
This cleanup is intentionally conservative:
- only closed molecules are eligible
- TTL must have elapsed
- cleanup is skipped entirely when the daemon settings are unset
Function Reference
| Phase | Function | File |
|---|---|---|
| Layer computation | ComputeFormulaLayers() | internal/config/pack.go |
| Symlink staging | ResolveFormulas() | cmd/gc/formula_resolve.go |
| Wisp creation | Store.MolCook() | internal/beads/beads.go |
| Attached molecule creation | Store.MolCookOn() | internal/beads/beads.go |
| Production backend cook | BdStore.MolCook() / BdStore.MolCookOn() | internal/beads/bdstore.go |
| Script backend cook | exec.Store.MolCook() / exec.Store.MolCookOn() | internal/beads/exec/exec.go |
| User dispatch | doSling() | cmd/gc/cmd_sling.go |
| Order dispatch | dispatchWisp() | cmd/gc/order_dispatch.go |
| GC creation | newWispGC() | cmd/gc/wisp_gc.go |
| GC execution | memoryWispGC.runGC() | cmd/gc/wisp_gc.go |
See Also
- Formulas & Molecules for the subsystem overview
- Dispatch for sling routing
- Orders for formula-backed automation
- Bead Store for the store boundary that owns instantiation
