Line

You are reading the unreleased docs (next). See latest (v0.9)

Internals

Context Envelope and pipeline

Chain generator steps with machine-readable state.

A Context Envelope is the plain-JSON state handed between generator steps, so a script (or a model) driving a multi-step build never has to re-derive what already exists. Each step reads the envelope from the previous step and returns an updated one.

The schema of record is schemas/envelope.v1.json. packages/engine/envelope.mjs builds and structurally validates envelopes (createEnvelope, validateEnvelope); a test reads the schema's own required list so the two cannot drift.

Shape#

Field Meaning
version Always 1. A breaking change ships as a new schema file, not a mutation of v1.
feature The feature (features/<feature>/...) this envelope tracks.
status pending on the way in; committed or aborted on the way out.
layers Map of layer name to the project-relative files that layer owns so far.
unboundSlots Interactive props found on an ingested page that have no handler wired yet.
events XState event types exposed by the feature's workflow.
diagnostics Violations found when the step's output was validated.
steps Input only: [{ layer, name }] generator steps to run. Cleared on output.

Running a pipeline#

construct pipeline run reads an envelope from standard input, renders every requested step, stages all files in one transaction and validates the combined result with the same enforcers construct validate uses. Either every file lands or none do: there is no half-applied run. The resulting envelope is printed as JSON.

echo '{"version":1,"feature":"billing","status":"pending","layers":{},
       "steps":[{"layer":"domain","name":"Invoice"},{"layer":"service","name":"fetchInvoice"}]}' \
  | construct pipeline run --dir my-app

Real output:

{
  "version": 1,
  "feature": "billing",
  "status": "committed",
  "layers": {
    "domain": ["features/billing/domain/Invoice.tsx"],
    "service": ["features/billing/services/FetchInvoice.tsx"]
  },
  "unboundSlots": [],
  "events": [],
  "diagnostics": []
}

If validation fails, nothing is written, status is aborted, diagnostics lists why, and the process exits non-zero (1 for rule violations). Malformed input exits with 2.

Where the pieces are#

Piece File
Runner packages/engine/pipeline.mjs (runPipeline)
Atomic writes packages/engine/transactionalWriter.mjs (createTransaction)
Envelope helpers packages/engine/envelope.mjs
Page ingestion, workflow generation, controller binding packages/engine/pageTransformer.mjs, workflowGenerator.mjs, controllerBinder.mjs

Each of the zero-LLM generators can feed the envelope: ingest a page and record its unbound slots, generate a workflow from a state descriptor, then bind the controller. The envelope carries what one step learned to the next as a concrete example rather than a specification to re-interpret.