Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 92 additions & 2 deletions architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@ Existing documents and code get aligned to this section retroactively.
| middleware | applied by the lexical structure, used by runtime execution |
| workflow run | a workflow being carried out with its progress and outcome recorded durably; document executions perform its work, while ongoing effects remain scoped to the document execution in which they run |
| document execution | one evaluation of a root document initiated through `execute()`, producing one output stream and one completion result while reading and appending a durable journal; its ongoing effects belong to the Effection scope in which the evaluation runs |
| workflow definition | what a workflow run is a run of: a versioned descriptor naming an immutable object — its format and object ID — together with the repository-relative path of the root document inside it. A repository locator is not part of it, and it is distinct from every Repository created inside the run's Workspace |
| workflow definition | what a workflow run is a run of: a versioned descriptor naming an immutable object — its format and object ID — together with the repository-relative path of the root document inside it, and the exact canonical document target when one is selected. A repository locator is not part of it, and it is distinct from every Repository created inside the run's Workspace |
| retrieval metadata | replaceable, credential-free information about where a workflow definition can be fetched from now; it takes no part in run identity and is reauthorized by the host before use |
| stop reason | why a workflow run or a document execution stopped: a categorical host code, or a reference to an already-filtered journal event |
| run ID | an opaque stable public identifier generated by the host or selected by an authorized caller; it associates the run's durable records and effects, remains unchanged for the life of the run, and has no semantics beyond equality and lifecycle addressing |
| definition base | the Git revision supplied to choose a workflow definition's pinned commit |
| Repository base | the optional Git revision from which one named Workspace Repository initializes its primary checkout |
| pinned commit | the commit obtained by resolving a base once; it remains the workflow run's starting repository state even as the run creates descendant commits |
| document target | an addressable static heading in a root document's own Markdown flow, named by the canonical path of heading labels that reaches it; selecting one executes the preamble, each ancestor's own content, and that heading's complete subtree |
| expansion | one logical evaluation of an authored executable element within a document execution |
| expansion ID | a deterministic identifier for one logical expansion; restoring or retrying that expansion preserves the ID, while a distinct evaluation requested by the document receives another |
| Git capability | the contextual interface through which workflow infrastructure queries the Git repository associated with the current working directory |
Expand Down Expand Up @@ -603,6 +604,81 @@ interpreter; graceful Worker shutdown alone is insufficient. Worker Shell
exposes no native executable or host PATH and is not described as POSIX or
native Bash.

## Document targets

A root document addresses its own sections. The outline is discovered from the
document's static Markdown alone: only headings in the root flow are targets,
and a heading is addressable only when its text is statically rendered — a
heading generated inside a component, or one carrying an interpolation, has no
stable address, and neither does anything beneath it. Discovery therefore
parses a copy in which the scanner's top-level component spans are blanked,
because a Markdown parser reading raw XMD cannot tell a component's children
from the root flow.

A document's preamble is what precedes its outline — the source before the first
root-flow heading, whatever its depth. A document may open at a deeper level than
the one supplying its title, and an earlier section is a target in its own right
rather than preamble every other target carries.

Selection resolves exactly once, before the document expands and before any
authored effect runs. A selector may glob, but it must name exactly one catalog
entry: naming none and naming several are both failures, and two sections that
canonicalize to the same path stay two entries so the ambiguity is reported
rather than resolved arbitrarily.

The selector and the target it resolves to are different things, and only one of
them is identity.

**The exact canonical target is definition identity.** It is what ran, so it is
what a document execution records durably, what a targeted workflow definition
carries, and what a resumed run is checked against.

**A caller's glob is non-authoritative invocation metadata.** It describes what
a caller asked for — two callers may spell one request differently — and it
never substitutes for the exact target: it does not occupy the recorded
exact-target field, it never enters a workflow definition, and it is never
re-resolved against a newer checkout to decide what a resumed run means. A glob
is retained in exactly one place, a failed selection's structural record, and
only so that an ordinary failed execution can be reproduced.

A resumed run re-resolves the current selector against the *recorded* content
and refuses to continue unless the outcome is the one recorded. A failed
selection is an outcome too, and is recorded and compared as one — otherwise a
journal left by a selector that matched nothing would answer a later request for
a section that does exist.

Validating that identity is **execution-owned**. Replay guards are composable
policy — a handler installed further out may decline to delegate — so identity,
which must not be negotiable, is not decided there. The execution owns the
journal it replays through and validates the recorded selection inside the read
itself, ahead of public guard policy, of a retained terminal result being
reused, of authored work, and of any append. The retained history it owns covers
every event that takes part in that decision, a recorded completion included, so
no event can present one identity to the validation and another to the run.

Three views of that history stay distinct. The **authoritative** one is what
admission validated and replay consumes, and it is immutable to policy.
Replaceable public policy reads an **isolated observation** of it, so a handler
composes freely without acquiring the authority the gate exists to withhold.
What a document receives is a **fresh mutable copy**, because a resumed binding
is ordinary data its own continuation writes to. Reusing a terminal result also
requires exactly one recognizable root import belonging to the coroutine whose
result is being reused.

Every public path validates in one order: parse the source, resolve the target,
compile schemas, then build the projected definition. A caller who named a
section the document does not offer hears that, rather than a complaint about a
schema they never reached.

A recorded selection is a closed protocol, and a record that does not satisfy it
is refused rather than delegated. "This event is not the root import" and "the
root import, malformed" are different answers: one continues, the other fails
before the recorded terminal result can be reused, without executing authored
work or appending history. The record carries the content it was taken from, so
the selection is verified against that content rather than merely parsed, and
reading it is total — every way journal-controlled data can refuse to be read is
the same refusal, carrying nothing the record supplied.

## Expansion identity

Core describes the executable element currently being expanded:
Expand Down Expand Up @@ -639,6 +715,14 @@ JavaScript object identity.
document execution receives expansion identity without installing workflow
middleware.

Selecting a document target does not disturb any of this. Projection retains
the original source ranges and scans each one under its own origin, so a
retained element keeps the offset and line it was authored at, and with them
its expansion ID. Two runs of the same document under different targets
therefore agree on the ID of every element they both retain, and may share IDs
without sharing effects — run identity and workflow-definition identity are
what tell those runs apart.

## Two layers

Error handling has two layers:
Expand Down Expand Up @@ -935,7 +1019,12 @@ It qualifies only while every one of these holds:
it;
- establishment and transfer occur only through the canonical module's
`establishJournalProvenance()` and `preserveJournalProvenance()`, one fresh
witness per stream, with duplicate establishment refused; and
witness per stream, with duplicate establishment refused;
- transfer happens only at a trusted wrapping site — one installed before any
code the journal's content could influence, delegating to the exact stream it
was handed. A document execution's journal passes through two: the secret
filter and the execution-owned target-admission wrapper. Each transfers only
what its source already had, so an unproven journal stays unproven; and
- it retains no execution, lifecycle, journal content or provider state.

The exception exists because the exact-object, anti-forgery and loaded-copy
Expand Down Expand Up @@ -992,6 +1081,7 @@ Status is measured against main.
| `<PrintErrors>` / `printErrors(fn)` | prints failures | built on main |
| `<Output>` region `output` mode | an undecided error fails the document execution | built on main |
| `Expansion` / `getExpansion()` | describes the current logical element expansion | built on main |
| document targets | catalogs a root document's addressable static headings, resolves one selector to one exact target, and projects the document to it before expansion | built on the #412 stack; `xmd targets`, targeted `xmd run`, and the targeted workflow definition are unbuilt |
| `useWorkflow()` / `getWorkflowRun()` | associates one document execution with a workflow run | built on main |
| `Git.revParse()` | verifies and resolves one Git revision expression contextually | built on main |
| workflow run storage | creates or compatibly finds one run by public run ID, retains its identity, state, document executions and filtered journal, and validates immutable Workspace roots through one provider-owned connection entry | built on the #365 stack; public workflow execution is unbuilt |
Expand Down
21 changes: 19 additions & 2 deletions packages/core/mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,25 @@ export type {
ExecutionApi,
DocumentExecution,
} from "./src/execute.ts";
export { INLINE_SOURCE_PATH, inlineSource, rootSourcePath } from "./src/root-source.ts";
export type { InlineRootDocument, RootDocumentSource } from "./src/root-source.ts";
export {
fileSource,
formatDocumentReference,
INLINE_SOURCE_PATH,
inlineSource,
rootSourcePath,
} from "./src/root-source.ts";
export type {
FileRootDocument,
InlineRootDocument,
RootDocumentSource,
} from "./src/root-source.ts";
export {
asDocumentTargetError,
DocumentTargetError,
isDocumentTargetError,
parseDocumentTargetFailure,
} from "./src/document-targets.ts";
export type { DocumentTargetErrorKind, DocumentTargetFailure } from "./src/document-targets.ts";
export { inspectComponent, inspectDocument } from "./src/inspect.ts";
export type {
ComponentInfo,
Expand Down
Loading
Loading