✨ Give an ordinary xmd run the repository vocabulary, and make <Dir> create its target (#643) - #696
Conversation
| // any of them. This runtime has no kernel-released advisory lock to hold a | ||
| // managed checkout with, so a Repository, Worktree, Git, Issue or PullRequest | ||
| // operation reports an absent provider before a local or remote change could | ||
| // happen. `xmd syntax` still describes one language everywhere. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // happen. `xmd syntax` still describes one language everywhere. |
| // Registering it installs no provider, discovers no repository, acquires no | ||
| // lock and reaches no network: what a name *does* is decided by whichever | ||
| // provider the command installed, and a runtime that installs none still | ||
| // resolves every one of these. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // resolves every one of these. |
| // published. `xmd run` and an approved `xmd plan --run` supply the live one; | ||
| // `xmd test` and every runtime without an operational provider supply the one | ||
| // that installs nothing, and every repository operation then reports an | ||
| // absent provider before touching anything. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // absent provider before touching anything. |
| // installs no repository provider for its own document — still gives one to | ||
| // a child that asked to be a run. Passed rather than inherited because a | ||
| // child runs in an isolated scope and needs a fresh instance: its own | ||
| // invocation identity, its own leases and its own Push evidence. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // invocation identity, its own leases and its own Push evidence. |
| installService, | ||
| // An approved plan's second execution is an ordinary run, so it gets | ||
| // the ordinary provider — a fresh one, since the authorship profile's | ||
| // scope is already gone. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // scope is already gone. |
| // Read here, on the last line that is still inside this invocation. The | ||
| // isolated scope below does not descend from the document's, so this is the | ||
| // only place a `<Dir>` or `<TempDir>` around the `<Execution>` is still | ||
| // observable — one statement later it is the process directory. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // observable — one statement later it is the process directory. |
| return { | ||
| PATH: Deno.env.get("PATH") ?? "", | ||
| // The managed root follows `HOME`, so this smoke never reaches the real | ||
| // `~/.xmd/repositories` and never needs an option that does not exist. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // `~/.xmd/repositories` and never needs an option that does not exist. |
| // command inside it, and a gate the document holds itself open on. The | ||
| // command writes where it is standing to a file rather than to its own | ||
| // output, so what this script reads is the checkout Git resolved rather | ||
| // than a line it had to parse out of a rendered document. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // than a line it had to parse out of a rendered document. |
| fail(`the holding run exited ${first.code}`); | ||
| } | ||
|
|
||
| // Where the command inside the Worktree was actually standing. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // Where the command inside the Worktree was actually standing. |
| // Where the command inside the Worktree was actually standing. | ||
| const slot = (yield* readTextFile(marker)).trim(); | ||
|
|
||
| // The worktree the run made is still there, and it is a real linked one. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // The worktree the run made is still there, and it is a real linked one. |
|
Warning This PR changes release configuration (.github/workflows/publish-packages.yml) without touching PR #696: ✨ Give an ordinary xmd run the repository vocabulary, and make create its target (#643)51 files, +4206 / -347 Scope🔴 PR has 4553 lines changed. Split into focused PRs. 🟡 4553 lines changed. PRs under 400 receive more thorough review. 🟡 51 files changed. Are all changes related? 🟡 Changes span 14 directories. 🟡 PR mixes config and source changes. Structural🟡 Type declarations with no consumers: FilesOperation.
🟡 1 console statements. Oxlint structural signals:
Slop
Oxlint slop signals:
Static AnalysisOxlint: 30 diagnostics across 10 files (12 rules) no-shadow (6): packages/workflow/src/composition/components/Dir.ts, packages/testing/src/execution-host.ts, packages/testing/src/execution-harness.ts CorrectnessNo extraneous code patterns detected. |
| // any of them. This runtime has no kernel-released advisory lock to hold a | ||
| // managed checkout with, so a Repository, Worktree, Git, Issue or PullRequest | ||
| // operation reports an absent provider before a local or remote change could | ||
| // happen. `xmd syntax` still describes one language everywhere. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // happen. `xmd syntax` still describes one language everywhere. |
| // Registering it installs no provider, discovers no repository, acquires no | ||
| // lock and reaches no network: what a name *does* is decided by whichever | ||
| // provider the command installed, and a runtime that installs none still | ||
| // resolves every one of these. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // resolves every one of these. |
| // published. `xmd run` and an approved `xmd plan --run` supply the live one; | ||
| // `xmd test` and every runtime without an operational provider supply the one | ||
| // that installs nothing, and every repository operation then reports an | ||
| // absent provider before touching anything. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // absent provider before touching anything. |
| // installs no repository provider for its own document — still gives one to | ||
| // a child that asked to be a run. Passed rather than inherited because a | ||
| // child runs in an isolated scope and needs a fresh instance: its own | ||
| // invocation identity, its own leases and its own Push evidence. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // invocation identity, its own leases and its own Push evidence. |
| installService, | ||
| // An approved plan's second execution is an ordinary run, so it gets | ||
| // the ordinary provider — a fresh one, since the authorship profile's | ||
| // scope is already gone. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // scope is already gone. |
| // and the two GitHub configurations this deployment authorizes. It is | ||
| // parameterized by the same credential-helper assembly the workflow host | ||
| // uses, because the program that is running is what knows how to re-invoke | ||
| // itself as one. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // itself as one. |
| // any of them. This runtime has no kernel-released advisory lock to hold a | ||
| // managed checkout with, so a Repository, Worktree, Git, Issue or PullRequest | ||
| // operation reports an absent provider before a local or remote change could | ||
| // happen. `xmd syntax` still describes one language everywhere. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // happen. `xmd syntax` still describes one language everywhere. |
| // Read here, on the last line that is still inside this invocation. The | ||
| // isolated scope below does not descend from the document's, so this is the | ||
| // only place a `<Dir>` or `<TempDir>` around the `<Execution>` is still | ||
| // observable — one statement later it is the process directory. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // observable — one statement later it is the process directory. |
|
|
||
| // Observed while the child is still waiting for a file this script has not | ||
| // written yet, so the slot is genuinely held when the second binary asks for | ||
| // it. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // it. |
|
|
||
| // 4. The slot is free again, and the next run finds the same checkout. The | ||
| // marker is removed first, so what it holds afterwards is that run's own | ||
| // answer rather than the first one's. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // answer rather than the first one's. |
4fed8c1 to
b00eeb1
Compare
| // before the root document is imported. | ||
| useWorkflowServiceDenial, | ||
| // A workflow run's repositories are the retained ones its Workspace | ||
| // attachment installs, so this path installs none of its own. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // attachment installs, so this path installs none of its own. |
| // `<Worktree>`, the Git operations, `<Issue>` and `<PullRequest>`. Deno and | ||
| // the compiled binary supply the live provider; Node and Bun supply the one | ||
| // that installs nothing, so those runtimes describe the same vocabulary and | ||
| // operate none of it. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // operate none of it. |
| // Read here, on the last line that is still inside this invocation. The | ||
| // isolated scope below does not descend from the document's, so this is the | ||
| // only place a `<Dir>` or `<TempDir>` around the `<Execution>` is still | ||
| // observable — one statement later it is the process directory. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // observable — one statement later it is the process directory. |
| return { | ||
| PATH: Deno.env.get("PATH") ?? "", | ||
| // The managed root follows `HOME`, so this smoke never reaches the real | ||
| // `~/.xmd/repositories` and never needs an option that does not exist. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // `~/.xmd/repositories` and never needs an option that does not exist. |
| }, | ||
| }), | ||
| // This harness runs Markdown tiers, not repository work: a child that | ||
| // asked for a checkout is told there is no provider. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // asked for a checkout is told there is no provider. |
| ...WEB_REGISTRATIONS, | ||
| // The repository-composition vocabulary. Registering it is all that happens | ||
| // here: catalog construction installs no provider, discovers no ambient | ||
| // repository, acquires no lock, spawns no Git and reads no credential. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // repository, acquires no lock, spawns no Git and reads no credential. |
| // A bound Workspace path is already logical and absolute, and `<Dir>` | ||
| // uses one as written. Every other operation refuses an absolute path, | ||
| // so the resolution is chosen here rather than by relaxing the shared | ||
| // rule that keeps authored paths inside the working directory. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // rule that keeps authored paths inside the working directory. |
| fail(`the holding run exited ${first.code}`); | ||
| } | ||
|
|
||
| // Where the command inside the Worktree was actually standing. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // Where the command inside the Worktree was actually standing. |
b00eeb1 to
ff6a9c6
Compare
| // before the root document is imported. | ||
| useWorkflowServiceDenial, | ||
| // A workflow run's repositories are the retained ones its Workspace | ||
| // attachment installs, so this path installs none of its own. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // attachment installs, so this path installs none of its own. |
| // `<Worktree>`, the Git operations, `<Issue>` and `<PullRequest>`. Deno and | ||
| // the compiled binary supply the live provider; Node and Bun supply the one | ||
| // that installs nothing, so those runtimes describe the same vocabulary and | ||
| // operate none of it. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // operate none of it. |
| }, | ||
| }), | ||
| // This harness runs Markdown tiers, not repository work: a child that | ||
| // asked for a checkout is told there is no provider. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // asked for a checkout is told there is no provider. |
| // Read here, on the last line that is still inside this invocation. The | ||
| // isolated scope below does not descend from the document's, so this is the | ||
| // only place a `<Dir>` or `<TempDir>` around the `<Execution>` is still | ||
| // observable — one statement later it is the process directory. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // observable — one statement later it is the process directory. |
| // The directory act, which the compiled binary must carry like the rest. A | ||
| // relative target creates every missing parent; an absolute one names that | ||
| // exact location and is used as written, which is the one place this contract | ||
| // admits an absolute path at all. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // admits an absolute path at all. |
| return { | ||
| PATH: Deno.env.get("PATH") ?? "", | ||
| // The managed root follows `HOME`, so this smoke never reaches the real | ||
| // `~/.xmd/repositories` and never needs an option that does not exist. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // `~/.xmd/repositories` and never needs an option that does not exist. |
ff6a9c6 to
9f63f29
Compare
| // any of them. This runtime has no kernel-released advisory lock to hold a | ||
| // managed checkout with, so a Repository, Worktree, Git, Issue or PullRequest | ||
| // operation reports an absent provider before a local or remote change could | ||
| // happen. `xmd syntax` still describes one language everywhere. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // happen. `xmd syntax` still describes one language everywhere. |
| // Registering it installs no provider, discovers no repository, acquires no | ||
| // lock and reaches no network: what a name *does* is decided by whichever | ||
| // provider the command installed, and a runtime that installs none still | ||
| // resolves every one of these. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // resolves every one of these. |
| // published. `xmd run` and an approved `xmd plan --run` supply the live one; | ||
| // `xmd test` and every runtime without an operational provider supply the one | ||
| // that installs nothing, and every repository operation then reports an | ||
| // absent provider before touching anything. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // absent provider before touching anything. |
| installService, | ||
| // An approved plan's second execution is an ordinary run, so it gets | ||
| // the ordinary provider — a fresh one, since the authorship profile's | ||
| // scope is already gone. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // scope is already gone. |
| // The outer `xmd test` command installs no operational repository | ||
| // provider. A test that needs the production behavior exercises an | ||
| // explicit `<Execution host="run">` child, which is an ordinary run and | ||
| // is handed the entrypoint's own installer below. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // is handed the entrypoint's own installer below. |
| // The directory this execution starts in, which is where the ambient | ||
| // repository is discovered from. Read through the contextual Api rather | ||
| // than from the process, so a nested execution that composed its own | ||
| // working directory is discovered from that one. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // working directory is discovered from that one. |
| }, | ||
| }), | ||
| // This harness runs Markdown tiers, not repository work: a child that | ||
| // asked for a checkout is told there is no provider. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // asked for a checkout is told there is no provider. |
| // Read here, on the last line that is still inside this invocation. The | ||
| // isolated scope below does not descend from the document's, so this is the | ||
| // only place a `<Dir>` or `<TempDir>` around the `<Execution>` is still | ||
| // observable — one statement later it is the process directory. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // observable — one statement later it is the process directory. |
| // A bound Workspace path is already logical and absolute, and `<Dir>` | ||
| // uses one as written. Every other operation refuses an absolute path, | ||
| // so the resolution is chosen here rather than by relaxing the shared | ||
| // rule that keeps authored paths inside the working directory. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // rule that keeps authored paths inside the working directory. |
| return { | ||
| PATH: Deno.env.get("PATH") ?? "", | ||
| // The managed root follows `HOME`, so this smoke never reaches the real | ||
| // `~/.xmd/repositories` and never needs an option that does not exist. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // `~/.xmd/repositories` and never needs an option that does not exist. |
The provider exists; this is what reaches it. The Deno source entrypoint and the compiled binary install it for `xmd run` and for an approved `xmd plan --run`, parameterized by the same credential-helper assembly the workflow host uses and by the two existing host configurations, both read and validated before a document expands rather than in the middle of one. Node and Bun register the same thirteen declarations and install no operational provider, so `xmd syntax` describes one language everywhere and every repository operation on those runtimes reaches a clear provider-absence error before a lock, a credential, a subprocess or a request exists. That is the whole implementation of the portable half: one array, declared once, with three consumers — the workflow attachment, `xmd syntax` and `xmd plan`, and an ordinary document execution. `run-repositories.ts` names the managed root and the unsupported installer and is on the shared command path; `deno-repositories.ts` assembles the live provider and is imported only by the two Deno entrypoints. The split is load bearing rather than tidy: the adapter's module graph reaches `node:sqlite`, which Bun has no built-in for, so a static import from shared code would stop `xmd` loading on Bun entirely instead of refusing one operation. A nested `<Execution host="run">` child installs no provider here. Giving a child a live one is inseparable from placing it in the document's contextual repository — a child that had authority but discovered the process directory would operate on a checkout nobody named — so both land together, later, as one change. At this level `xmd test`, a nested child and a workflow execution all reach provider absence. The public specifications describe the ordinary profile, the compiled smoke proves the provider and its kernel-released lock survive `deno compile`, and CI carries the smoke as its own step.
…#643) The provider exists; this is everything that reaches it. The Deno source entrypoint and the compiled binary install it for `xmd run` and for an approved `xmd plan --run`, parameterized by the same credential-helper assembly the workflow host uses and by the two existing host configurations, both read and validated before a document expands rather than in the middle of one. Node and Bun register the same thirteen declarations and install no operational provider, so `xmd syntax` describes one language everywhere and every repository operation there reaches a clear provider-absence error before a lock, a credential, a subprocess or a request exists. One array, declared once, with three consumers: the workflow attachment, `xmd syntax` and `xmd plan`, and an ordinary document execution. `run-repositories.ts` names the managed root and the unsupported installer and sits on the shared command path; `deno-repositories.ts` assembles the live provider and is imported only by the two Deno entrypoints. That split is load bearing rather than tidy: the adapter's module graph reaches `node:sqlite`, which Bun has no built-in for, so a static import from shared code would stop `xmd` loading on Bun entirely instead of refusing one operation. A nested `<Execution host="run">` child is an ordinary run whatever command hosts it, and gets what one gets: a provider instance of its own — its own invocation identity, leases and Push evidence — and the working directory the `<Execution>` was written in. Those two are one thing. A child is a root execution in a scope that does not descend from the document's, so it inherits no `API.Env` handler and would otherwise stand in the *process* directory: a `<Dir>` would scope every component inside it except the child, and the child's own provider would discover its ambient Git from whatever checkout the process happened to be launched in. Authority without placement is worse than neither, so the contextual directory is captured on the last line still inside the invocation, carried privately on `ChildInvocation`, and installed ahead of the root, the provider and the execution. Evidence: ORC1–ORC19 and ORC21, the retained workflow regression, the compiled smoke, and portable parity under Node and Bun.
`<Dir path>` installed a working directory and created nothing, so a document
that named a directory which was not there ran its content somewhere that did
not exist. It now performs one provider-neutral directory act before it installs
cwd and before any content expands.
`API.Files` gains a mandatory `ensureDirectory`. It recursively creates a
missing target, succeeds for an existing directory without replacing it or
clearing its contents, and refuses a file or another non-directory at the target
or on the way to it. Success carries nothing at all — no path, no handle, and no
word on whether this call is what created it — for the same reason `deleteFile`
carries nothing: a document that asked for a directory to exist has been
answered by its existence, and a caller that could tell the two apart would be
branching on a race.
The host provider creates directly and persistently. There is no rollback and no
teardown removal: a later failure of the content running inside a directory says
nothing about whether the directory should exist. It is also the one operation
here that accepts an absolute path, which is `<Dir>`'s established exception, so
it resolves its own destination rather than inheriting the rule that refuses one.
The workflow provider publishes one `workspace_file` effect. The recursive
creation runs inside its savepoint, so a refusal after a partial creation leaves
neither the parent nor a rolled-back transaction — the effect that follows still
commits. An absolute path there is a logical Workspace path used as written, and
names nothing on the host.
Shared `<Dir>` calls only `API.Files.ensureDirectory`, through core's door that
turns an illegal provider throw into a fenced failure. It reaches no `API.Fs`,
no `@effectionx/fs`, no runtime API and no Repository composition, and it
changes no Repository selection or identity member.
`allow={["write"]}` now authorizes persistent recursive creation, so the pinned
paired identity is versioned to
`@executablemd/workflow/composition/dir-v2#Dir`. A continuation retaining the
former identity — which authorized placement that created nothing — refuses
before generated execution and before any mutation.
The thirteen composition components take their accepted descriptions.
Evidence: HF15b, HF24–HF28, FF2, the compiled contract probe, WF23–WF26,
WGAC17, ORC6–ORC6i, runtime parity under Deno, Node and Bun, and ORC20.
Seven corrections to the previous feedback commit. The production contract, the public `ensureDirectory` export, the versioned `dir-v2#Dir` identity and the thirteen accepted descriptions are unchanged. `Dir.ts` said "It creates nothing", which the change had made false. Its module documentation now describes what it does: ensure or create the target, then expand content there, restore the enclosing directory on the way out, and delete nothing when it does. FF2's shipped-component half searched the escaping error for content markers. That could not tell "the content never expanded" from "the content expanded and its text is not in this message". Sentinel components record whether they ran, so the assertion is about expansion rather than about a string. HF26 and ORC6b covered regular files only. Both now cover the frozen matrix: a regular file and a supported special entry, each at the target and each as an intermediate. The special entry is a symbolic link to a file — a link to a directory is a directory to enter, which is the parity decision both providers make, so using one would have tested the opposite claim. ORC6 inferred ordering from a nested `<File>` landing, which proves nothing because a write creates its own parents. A probe now runs first inside the region and records that the directory already exists and that the contextual working directory is the ensured target. ORC6c inferred cwd restoration after cancellation from where a later run's files landed, but a fresh execution is handed its cwd explicitly. It now reads the contextual directory from inside the region and again from the enclosing scope after the halt. WGAC17 gains the current-admission control as committed evidence: it resumes, completes, and publishes no further effect or root. Root invariance is described as what it is — no published mutation — rather than as a call count, which it is not: an ensure that found the directory already there would publish no root either. The call count is WF26's, which decorates `mkdir` and counts it. Four documentation blocks had been orphaned from their declarations by code inserted between them, WF23's comment still described the ordering proof it no longer used, and `logicalTarget` was a generator that never yielded.
…orts (#643) Comment and evidence corrections. No production behavior changes. WGAC17's shared setup now reads the retained ordered `workspace_file` effects and requires an `ensure-directory` for `/generated` ahead of the nested write to `/generated/inside.md`. That is what says the generated `<Dir>` actually ran under the current admission — the fragment's text says what was asked for, and only the committed order says what happened. Pointing it at a target the run never ensures fails both cases, since the setup guards each. The comments now claim only what their observables support. This test proves the generated Dir effect occurred and that resuming publishes no further effect or root. WF26 proves a completed `<Dir>` replay makes no second low-level `mkdir` call. Root invariance proves neither: an ensure finding the directory already there would publish no root either. The former-identity case no longer claims anything about a second creation — it establishes refusal before generated execution or publication, which is its whole subject. The control's name said "does not create again", which is WF26's claim rather than this one's; it now names what it proves. Two stale comments removed: ORC6's header still said the nested `<File>` landing observes ordering, which the probe beneath it contradicts, and HF26 carried its pre-revision two-case explanation above the corrected four-case one.
9f63f29 to
72dca80
Compare
| // any of them. This runtime has no kernel-released advisory lock to hold a | ||
| // managed checkout with, so a Repository, Worktree, Git, Issue or PullRequest | ||
| // operation reports an absent provider before a local or remote change could | ||
| // happen. `xmd syntax` still describes one language everywhere. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // happen. `xmd syntax` still describes one language everywhere. |
| // Registering it installs no provider, discovers no repository, acquires no | ||
| // lock and reaches no network: what a name *does* is decided by whichever | ||
| // provider the command installed, and a runtime that installs none still | ||
| // resolves every one of these. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // resolves every one of these. |
| // before the root document is imported. | ||
| useWorkflowServiceDenial, | ||
| // A workflow run's repositories are the retained ones its Workspace | ||
| // attachment installs, so this path installs none of its own. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // attachment installs, so this path installs none of its own. |
| }, | ||
| }), | ||
| // This harness runs Markdown tiers, not repository work: a child that | ||
| // asked for a checkout is told there is no provider. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // asked for a checkout is told there is no provider. |
| // Read here, on the last line that is still inside this invocation. The | ||
| // isolated scope below does not descend from the document's, so this is the | ||
| // only place a `<Dir>` or `<TempDir>` around the `<Execution>` is still | ||
| // observable — one statement later it is the process directory. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // observable — one statement later it is the process directory. |
| // command inside it, and a gate the document holds itself open on. The | ||
| // command writes where it is standing to a file rather than to its own | ||
| // output, so what this script reads is the checkout Git resolved rather | ||
| // than a line it had to parse out of a rendered document. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // than a line it had to parse out of a rendered document. |
|
|
||
| // Observed while the child is still waiting for a file this script has not | ||
| // written yet, so the slot is genuinely held when the second binary asks for | ||
| // it. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // it. |
|
|
||
| // 4. The slot is free again, and the next run finds the same checkout. The | ||
| // marker is removed first, so what it holds afterwards is that run's own | ||
| // answer rather than the first one's. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // answer rather than the first one's. |
#643) `packages/testing/src/execution-harness.ts` imports `cwd` from `@executablemd/runtime`, so `packages/testing/package.json` gained `@executablemd/runtime` — but the workflow generated from those manifests was not regenerated with it. The generated graph is what orders publication, so the stale copy had `testing` waiting only on `core` and `durable-streams`. It could therefore publish before the `runtime` package it now depends on. CI checks this in every `test-deno` shard by regenerating and diffing, which is why all nine failed together and in under a minute, before any test ran.
| // any of them. This runtime has no kernel-released advisory lock to hold a | ||
| // managed checkout with, so a Repository, Worktree, Git, Issue or PullRequest | ||
| // operation reports an absent provider before a local or remote change could | ||
| // happen. `xmd syntax` still describes one language everywhere. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // happen. `xmd syntax` still describes one language everywhere. |
| // Registering it installs no provider, discovers no repository, acquires no | ||
| // lock and reaches no network: what a name *does* is decided by whichever | ||
| // provider the command installed, and a runtime that installs none still | ||
| // resolves every one of these. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // resolves every one of these. |
| // published. `xmd run` and an approved `xmd plan --run` supply the live one; | ||
| // `xmd test` and every runtime without an operational provider supply the one | ||
| // that installs nothing, and every repository operation then reports an | ||
| // absent provider before touching anything. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // absent provider before touching anything. |
| // before the root document is imported. | ||
| useWorkflowServiceDenial, | ||
| // A workflow run's repositories are the retained ones its Workspace | ||
| // attachment installs, so this path installs none of its own. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // attachment installs, so this path installs none of its own. |
| // `<Worktree>`, the Git operations, `<Issue>` and `<PullRequest>`. Deno and | ||
| // the compiled binary supply the live provider; Node and Bun supply the one | ||
| // that installs nothing, so those runtimes describe the same vocabulary and | ||
| // operate none of it. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // operate none of it. |
| // The directory this execution starts in, which is where the ambient | ||
| // repository is discovered from. Read through the contextual Api rather | ||
| // than from the process, so a nested execution that composed its own | ||
| // working directory is discovered from that one. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // working directory is discovered from that one. |
| // Read here, on the last line that is still inside this invocation. The | ||
| // isolated scope below does not descend from the document's, so this is the | ||
| // only place a `<Dir>` or `<TempDir>` around the `<Execution>` is still | ||
| // observable — one statement later it is the process directory. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // observable — one statement later it is the process directory. |
|
|
||
| // Observed while the child is still waiting for a file this script has not | ||
| // written yet, so the slot is genuinely held when the second binary asks for | ||
| // it. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // it. |
|
|
||
| // 4. The slot is free again, and the next run finds the same checkout. The | ||
| // marker is removed first, so what it holds afterwards is that run's own | ||
| // answer rather than the first one's. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // answer rather than the first one's. |
…ntity (#643) Two failures, both revealed rather than caused by the previous commit: the stale publish workflow had been killing all nine `test-deno` shards before a test ran, so nothing underneath it had been reported yet. ## The catalog was truncated when stdout was a pipe `process.stdout` is synchronous for a file or a terminal and asynchronous for a pipe, and the `syntax` case handed its whole document to `write` without waiting. The run then ended and the process exited with most of the document still in a buffer, so `xmd syntax --json > file` was whole at 89252 bytes while `xmd syntax --json | …` stopped at 65394 — inside a token, which is why the reader saw "Unexpected end of JSON input" rather than a short catalog. This became visible now because this branch registers the repository vocabulary in the catalog, which is what first pushed it past the buffer. The write now waits for the callback, so it finishes before anything can exit. Only that one write is changed. The other large writes in this file stream in chunks rather than handing over a single document, and none of them is near the buffer. ## The CLI tier read the host's Git identity `runOrdinary` installed the provider without saying who a commit is by, so it fell through to the production default — the caller's own `git config`. ORC18 and ORC15 therefore asserted something about who ran them: green on a machine with `user.name` set, `UnresolvedGitIdentityError` on every runner. It now states a fixture identity, the same correction the workflow tier already carries. ORC19 was never affected: it commits inside a subprocess whose environment it builds itself. Verified against a reproduced runner rather than a reading — with `user.useConfigOnly` set and no configuration file, the four CLI suites pass 11/33, and the npm-bin suite passes 1/2 with a rebuilt package.
| // any of them. This runtime has no kernel-released advisory lock to hold a | ||
| // managed checkout with, so a Repository, Worktree, Git, Issue or PullRequest | ||
| // operation reports an absent provider before a local or remote change could | ||
| // happen. `xmd syntax` still describes one language everywhere. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // happen. `xmd syntax` still describes one language everywhere. |
| // Registering it installs no provider, discovers no repository, acquires no | ||
| // lock and reaches no network: what a name *does* is decided by whichever | ||
| // provider the command installed, and a runtime that installs none still | ||
| // resolves every one of these. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // resolves every one of these. |
| // published. `xmd run` and an approved `xmd plan --run` supply the live one; | ||
| // `xmd test` and every runtime without an operational provider supply the one | ||
| // that installs nothing, and every repository operation then reports an | ||
| // absent provider before touching anything. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // absent provider before touching anything. |
| // installs no repository provider for its own document — still gives one to | ||
| // a child that asked to be a run. Passed rather than inherited because a | ||
| // child runs in an isolated scope and needs a fresh instance: its own | ||
| // invocation identity, its own leases and its own Push evidence. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // invocation identity, its own leases and its own Push evidence. |
| installService, | ||
| // An approved plan's second execution is an ordinary run, so it gets | ||
| // the ordinary provider — a fresh one, since the authorship profile's | ||
| // scope is already gone. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // scope is already gone. |
| }, | ||
| }), | ||
| // This harness runs Markdown tiers, not repository work: a child that | ||
| // asked for a checkout is told there is no provider. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // asked for a checkout is told there is no provider. |
| // Read here, on the last line that is still inside this invocation. The | ||
| // isolated scope below does not descend from the document's, so this is the | ||
| // only place a `<Dir>` or `<TempDir>` around the `<Execution>` is still | ||
| // observable — one statement later it is the process directory. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // observable — one statement later it is the process directory. |
| return { | ||
| PATH: Deno.env.get("PATH") ?? "", | ||
| // The managed root follows `HOME`, so this smoke never reaches the real | ||
| // `~/.xmd/repositories` and never needs an option that does not exist. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // `~/.xmd/repositories` and never needs an option that does not exist. |
|
|
||
| // Observed while the child is still waiting for a file this script has not | ||
| // written yet, so the slot is genuinely held when the second binary asks for | ||
| // it. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // it. |
|
|
||
| // 4. The slot is free again, and the next run finds the same checkout. The | ||
| // marker is removed first, so what it holds afterwards is that run's own | ||
| // answer rather than the first one's. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // answer rather than the first one's. |
Closes #643. Top of a three-PR stack — depends on #695, which depends on #694. Merge bottom-up.
agent/issue-643-composition-seamagent/issue-643-run-provideragent/issue-643-run-profilexmd runexposure, and the<Dir>correctionWhy
#695 built the provider; nothing could reach it. This is everything that reaches
it, for a root
xmd runand for a nested<Execution host="run">child alike.It also corrects
<Dir>.<Dir path>installed a working directory and creatednothing, so a document that named a directory which was not there ran its
content somewhere that did not exist.
What changes
Before: the repository vocabulary resolved only under
xmd workflow. Node and Bundid not describe the names at all.
<Dir>was placement-only.After: an ordinary
xmd rununder Deno or the compiled binary operates the fullvocabulary against the caller's own filesystem, with the Git checkout the command
was run in as the ambient Repository. Node and Bun register the same thirteen
declarations — so
xmd syntaxdescribes one language everywhere — and everyrepository operation reaches a clear provider-absence error before anything is
touched.
<Dir>now ensures or creates its target before content begins, on bothprofiles.
How it works
Review guide
Start with:
packages/cli/src/run-repositories.tsanddeno-repositories.ts, thenpackages/workflow/src/composition/components/Dir.ts.Then review:
cli.ts— installer assembly, andchildRepositoriesthreadingtesting-host.ts+packages/testing/src/execution-{host,harness}.ts—ChildInvocation.cwdpackages/runtime/files.ts—ensureDirectoryon the shared contractpackages/runtime/host-files.tsandpackages/workflow/src/deno/workspace/files.ts— the two providersspecs/,architecture.mdLook carefully at the split between
run-repositories.tsanddeno-repositories.ts. It is load bearing, not tidy: the adapter's module graphreaches
node:sqlite, which Bun has no built-in for, so a static import from theshared command path stops
xmdloading on Bun entirely rather than refusingone operation. Found by running ORC2 under Bun, not by reading.
And at the child's working directory. A child is a root execution in a scope
that does not descend from the document's, so it inherits no
API.Envhandler andwould otherwise stand in the process directory. Authority without placement is
worse than neither, which is why both land here together.
And at
useHostFiles's forwarding list.Files.around()accepts a partialhandler by design, so an operation omitted from that list is well-typed and every
caller falls through to the fail-closed terminal. That defect shipped in an early
revision of this branch and was caught by the compiled contract probe, not by the
type checker. HF15b now covers all seven operations through the installed provider.
What must stay true
xmd rungets: its own provider and the document'sdirectory — ORC19.
deno compile— ORC21.<Dir>ensures before content, uses an existing directory without changing it,refuses a non-directory, and never deletes what it created — ORC6–ORC6e, HF24–HF28.
How to verify it
xmd runin a subprocess whose process directory is not aGit checkout, so a regression in cwd propagation refuses for want of a
repository instead of operating on the tree the suite runs from.
<Dir>that records the targetalready exists and that cwd is the ensured target — a nested
<File>provesnothing, because a write creates its own parents.
following effect still commits, which is what distinguishes savepoint rollback
from transaction rollback.
the resume refuses before any effect or root is published.
Results: exposure evidence 26 suites
ok | 90 passed (481 steps) | 0 failed·<Dir>evidence 29 suitesok | 115 passed (680 steps) | 0 failed·check/lint/check:jsrexit 0 ·build+ smoke ok · Node and Bun parity exit 0 ·verify:cleanexit 0, nine of nine · files-contract probe 28 claims.Scope
Included
Session placement, the compiled smoke and its CI step, the public
specifications, the complete nested-child integration.
API.Files.ensureDirectoryon the shared contract and in both providers;<Dir>reordered to ensure → install cwd → expand content.@executablemd/workflow/composition/dir-v2#Dir, becauseallow={["write"]}nowauthorizes persistent recursive creation. A continuation retaining the former
@executablemd/workflow/composition#Dirrefuses before generated execution.Intentionally unchanged
disabled in ordinary runs.
New abstractions
API.Files.ensureDirectoryexists because<Dir>must perform a directory actwithout knowing which filesystem answers. Consumers:
<Dir>, both providers.Unit-shaped for the same reasondeleteFileis — a document that asked for adirectory has been answered by its existence.
New dependencies
@executablemd/runtime(workspace:*) added to@executablemd/testing,for reading the contextual working directory when a nested execution is handed to
its host. No cycle —
runtimedepends on no first-party package.ensureDirectoryis exported from@executablemd/core.<Dir>lives in@executablemd/workflow, and core owns the call that converts anillegal provider throw into a fenced failure; importing
Files.operationsdirectlywould bypass that boundary. No raw handler or Api is exposed.
Generated or mechanical changes
packages/cli/tests/run-composition-deno.test.tsis split into root-provider casesand
run-composition-nested.test.ts; the nested block is the certified text verbatim.Risks and limitations
vocabulary and operate none of it.
<Dir>is the exception — it needs only thehost
API.Filesprovider, which all four entrypoints install, so it staysoperational everywhere.
through later content failure and cancellation, with no rollback and no teardown
deletion.
Scope confirmation