You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<Output> currently makes failures visible by collecting them as rendered error
segments and continuing. That is a dangerous default for operational documents:
a failed preview can still reach a later <Elicit> or destructive publish step.
PR #308 exposed the consequence. The npm-bootstrap workflow had to build a
fail-closed protocol from sentinel files, cat, and production uses of testing
assertions merely to express:
Show the operator what this stage produced, but stop the document if it
failed.
The language already has an explicit collection boundary. Continuing after an
error should be requested there, not silently selected by every <Output>.
Product decision
<Output> is fail-fast by default.
It renders the output produced before a failure.
The document completes with a failure.
Later siblings, later output regions, elicitations, and other effects do not
run.
Continuing after ordinary failures is explicit and scope-local:
<Output>
<CaptureErrors>
... work whose errors should render without aborting ...
</CaptureErrors>
</Output>
Rename the paired public vocabulary as part of the same breaking change:
<CollectFailures> becomes <CaptureErrors>.
collectFailures(fn) becomes captureErrors(fn).
The old tag and export are removed rather than retained as aliases.
<CaptureErrors> otherwise preserves the existing collection contract: it
accepts no props, converts ordinary function-component failures into one
structured error segment, renders/observes each error once, and permits later
work to continue. Fatal durability, replay, schema, and already-selected
documentation failures remain outside that recovery contract exactly as they
are today.
This is a breaking language and API change; its PR title uses the 💥 gitmoji.
Dependency
#307 lands first. A non-zero command must be recognized as a failure even when
it wrote stdout. This issue then governs what <Output> does with that failure
and ensures the stdout remains observable.
Required behavior
<Output>
A failure after visible text or command stdout preserves everything produced
before the failure and then fails the execution.
The failure is reported only after the failing invocation has completed
teardown.
Error identity, type, cause, aggregation, and one-observation behavior are
preserved.
No later sibling or region begins after the failure.
A successful root <Output> retains its existing single buffered emission.
A failing root <Output> emits the partial selected output before its
completion Result reports failure.
Component-owned <Output> follows the same policy as root <Output>.
Documentation remains hidden and fail-fast.
A root or component with no <Output> retains its separately documented
behavior; do not broaden this issue into a redesign of text roots.
<CaptureErrors> / captureErrors(fn)
Both install the same explicit, scope-local recovery policy as their current CollectFailures counterparts.
Nested capture boundaries do not duplicate diagnostics.
Failures outside the boundary remain fail-fast.
A captured failure inside <Output> renders once and allows later content to
run.
The structural name is reserved and receives the existing placement, prop,
source-position, projection, and observation guarantees.
Acceptance coverage
Root <Output>: output before failure is emitted, completion is failed, and a
later sibling with an observable side effect does not run.
Component <Output>: the same three assertions through a real invocation.
Multiple output regions: failure in an earlier region prevents later regions
and documentation from running while preserving earlier selected output.
Explicit <CaptureErrors> inside <Output> renders the diagnostic once and
permits a following marker to render.
Without <CaptureErrors>, the same fixture fails and the marker does not
render; demonstrate this discriminating mutation before keeping the test.
Nested <CaptureErrors> and captureErrors(fn) preserve existing collection,
teardown, identity/cause, and one-observation behavior.
Successful <Output> selection, <Content> projection, as capture, empty
regions, and root/component parity remain covered.
Durable replay produces the same visible partial output and failure without
replaying suppressed later effects.
Migration and documentation
Rename the structural dispatch, reservation entry, diagnostics, conformance
rows, tests, smoke documents, README examples, and current specifications.
Rename every production and test import/call of collectFailures to captureErrors.
Audit every remaining CollectFailures / collectFailures occurrence into
removed or explicitly historical text; current authoring and API references
use only the new vocabulary.
Update specs/executable-mdx-spec.md in the same PR, including the current
statements that <Output> selects the collecting policy and that buffered
output is discarded on later failure.
Before commit, run the repository's complete required gates with the CI-pinned
runtimes, including deno task fmt, lint, check, test, check:jsr, Node
typecheck/tests, Bun tests, compiled-binary smoke, git diff --check, and the packages/cli/src/node.ts mode check. No red gate is waived as baseline.
Motivation
<Output>currently makes failures visible by collecting them as rendered errorsegments and continuing. That is a dangerous default for operational documents:
a failed preview can still reach a later
<Elicit>or destructive publish step.PR #308 exposed the consequence. The npm-bootstrap workflow had to build a
fail-closed protocol from sentinel files,
cat, and production uses of testingassertions merely to express:
The language already has an explicit collection boundary. Continuing after an
error should be requested there, not silently selected by every
<Output>.Product decision
<Output>is fail-fast by default.run.
capture behavior remain unchanged.
Continuing after ordinary failures is explicit and scope-local:
Rename the paired public vocabulary as part of the same breaking change:
<CollectFailures>becomes<CaptureErrors>.collectFailures(fn)becomescaptureErrors(fn).<CaptureErrors>otherwise preserves the existing collection contract: itaccepts no props, converts ordinary function-component failures into one
structured error segment, renders/observes each error once, and permits later
work to continue. Fatal durability, replay, schema, and already-selected
documentation failures remain outside that recovery contract exactly as they
are today.
This is a breaking language and API change; its PR title uses the 💥 gitmoji.
Dependency
#307 lands first. A non-zero command must be recognized as a failure even when
it wrote stdout. This issue then governs what
<Output>does with that failureand ensures the stdout remains observable.
Required behavior
<Output>before the failure and then fails the execution.
teardown.
cause, aggregation, and one-observation behavior arepreserved.
<Output>retains its existing single buffered emission.<Output>emits the partial selected output before itscompletion
Resultreports failure.<Output>follows the same policy as root<Output>.<Output>retains its separately documentedbehavior; do not broaden this issue into a redesign of text roots.
<CaptureErrors>/captureErrors(fn)CollectFailurescounterparts.<Output>renders once and allows later content torun.
source-position, projection, and observation guarantees.
Acceptance coverage
<Output>: output before failure is emitted, completion is failed, and alater sibling with an observable side effect does not run.
<Output>: the same three assertions through a real invocation.<Elicit>/process probe does not run. This is the integration pin with A non-zero code block that printed to stdout raises no failure #307.and documentation from running while preserving earlier selected output.
<CaptureErrors>inside<Output>renders the diagnostic once andpermits a following marker to render.
<CaptureErrors>, the same fixture fails and the marker does notrender; demonstrate this discriminating mutation before keeping the test.
<CaptureErrors>andcaptureErrors(fn)preserve existing collection,teardown, identity/cause, and one-observation behavior.
<Output>selection,<Content>projection,ascapture, emptyregions, and root/component parity remain covered.
replaying suppressed later effects.
Migration and documentation
rows, tests, smoke documents, README examples, and current specifications.
collectFailurestocaptureErrors.CollectFailures/collectFailuresoccurrence intoremoved or explicitly historical text; current authoring and API references
use only the new vocabulary.
specs/executable-mdx-spec.mdin the same PR, including the currentstatements that
<Output>selects the collecting policy and that bufferedoutput is discarded on later failure.
xmd run: elicit the OTP #308's plan after this lands: the verdict files and productionassertions disappear, and ordinary npm stages rely on fail-fast
<Output>.Verification
Before commit, run the repository's complete required gates with the CI-pinned
runtimes, including
deno task fmt, lint, check, test,check:jsr, Nodetypecheck/tests, Bun tests, compiled-binary smoke,
git diff --check, and thepackages/cli/src/node.tsmode check. No red gate is waived as baseline.