A matter is not always a single straight line. Sometimes a step in one matter needs a whole separate piece of work to run to completion before it can continue: a company formation that must wait on a director’s KYC matter, a deal that branches a subsidiary set-up off to one side. Cross-matter spawn and await are the two primitives that make that branching first-class. A parent matter forks a child matter from a step, and a later step blocks the parent until that child reaches a terminal state. Both halves run through the same governed verbs and the same step engine as every other matter, so a fork-and-wait is as auditable and as bounded as a single ordinary advance.
What it does
Fork a child matter from a parent step. A SPAWN_MATTER step instantiates a child matter from a configured child template (a board id or a board key resolved in the parent’s workspace) and records a single typed relation linking parent to child, owned by the step that spawned it. The child is created through the very same matter.create instantiation path any other matter uses, so it pins the exact template version it was built from and materialises and activates its own first step immediately. The spawn step does not linger as an active step: it fires, mints the child, and completes, so the parent can move on to consider its next step.
The child is its own matter, in the parent’s workspace. A spawned child runs its own independent lifecycle: its own steps, its own status, its own audit trail. Workspace is never a spawn parameter, so a child is always born in the parent’s workspace and is intra-workspace by construction; a cross-workspace child is structurally unreachable. The link between them is a one-time copy of a title and a recorded parent-to-child relation, not a live shared state: the only thing that ever crosses the boundary later is the child’s own lifecycle status, never a fact or a document.
Block the parent until the child finishes. An AWAIT_MATTER step is the wait half. When the parent reaches it, the engine finds the child matter the step is paired with (by default the nearest prior spawn step in the same matter, or an explicitly named one) and reads that child’s status. If the child is still open or on hold, the await step parks BLOCKED and the parent’s cursor halts: the matter waits, with the single-active-step rule preserved. When the child reaches a terminal status, the parent resumes through the same progression engine.
A cancelled child is never silently a success. A child that completes resumes the parent. A child that is cancelled is terminal but not a clean completion, so the await step applies its configured onChildCancelled policy: fail the parent (the default, cancelling it), hold the parent on hold for a human to decide, or resume anyway if the configuration explicitly says a cancellation is acceptable. The default refuses to treat a cancelled child as if the work had finished.
The wait is engine-owned, so it cannot be forced past. A BLOCKED await step is resolved only by the child reaching a terminal state, never by a manual move on the parent. matter.advance refuses to advance it, and the administrative overrides (jump-to-step, activate, skip) refuse it too, so no one can resume the parent past an unfinished child. The lawful lever for a stuck wait is to resolve the child itself (complete or cancel it), which wakes the parent automatically. When the child becomes terminal, a child-driven wake re-enters the parent’s progression and re-evaluates the await condition; it is idempotent, so a duplicate terminal write finds the step already resolved and does nothing.
Bounded depth and fan-out, refused before any effect. Cross-matter spawn is fail-closed. A child can be at most three levels deep in a spawn lineage, and a single parent can spawn at most ten children. The depth and fan-out guards are checked before the child is created, so an over-limit spawn is refused with nothing written rather than half-done. A single spawn step can mint only one child lineage: a re-fired spawn from the same step is a conflict, not a duplicate. Each spawn writes a hash-chained audit event on the parent’s lineage recording the minted child, the spawning step, and the threaded depth, surfaced through the matter’s own audit feed.
How you use it
Author a fork into a template. Add a SPAWN_MATTER step to a matter template, configured with the child template to instantiate (a board id or a board key) and an optional child title. Add a later AWAIT_MATTER step where the parent should wait for that child, with an onChildCancelled policy if the default fail-the-parent behaviour is not what you want. When a matter built from that template reaches the spawn step, the child is created and linked automatically.
Spawn a child directly. When you need a branch that was not pre-authored, call the spawn verb against the parent matter and its spawn step, naming the child template. You get back the new child matter’s id, and the parent-to-child relation and audit event are written exactly as the step-driven path writes them.
Check whether a parent can move yet. Poll the await step to read its current verdict: blocked (the child is still running), resume (the child completed), or one of the cancellation outcomes. The poll is a read - it reports the verdict without applying it and without side effects - so it is safe to ask repeatedly while you wait, and it tells you which child the parent is waiting on.
Unblock a waiting parent. Do not try to force the parent’s await step. Work the child matter to completion (or cancel it deliberately) and the parent wakes on its own, resuming through the same engine that activated it.
The kernel verbs behind it
Both halves of fork-and-wait pass through the kernel’s one front door: permission-checked and audited before they run, and sharing the same single instantiation and evaluation paths as the rest of the matter engine (no second spawn engine, no second await engine).
matter.spawn- fork a child matter from a parent’s spawn step, writing the parent-to-child relation and an audit event, bounded by the fail-closed depth and fan-out guards.matter.await- poll the verdict of an await step’s cross-matter blocking condition (block, resume, or a cancellation outcome) without applying it; a side-effect-free read.matter.advance- the one step-completion path; it runs the spawn and wait side-effects when those steps come into play, and refuses to force a child-owned wait.matter.cancel- terminating a child here is what wakes a parent blocked on it (subject to the await step’s cancellation policy).matter.get- read a matter’s steps and where its cursor sits, including a parked await step.
See the full set in the matter verb reference.