✨ Add the ordinary run's repository provider (#643) - #695
Conversation
| } | ||
| // Without `--path-format=absolute`, which not every supported Git has: a | ||
| // linked worktree already answers absolutely, and a primary checkout answers | ||
| // `.git` relative to itself. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // `.git` relative to itself. |
| const handle = yield* until(open(temporary, "wx")); | ||
| // Registered before the write, so a halt closes the descriptor: closing is | ||
| // asynchronous, and a `finally` that suspended would not be guaranteed to | ||
| // finish. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // finish. |
| if (file === undefined) { | ||
| // Refused. There is nothing to hold open, so this task ends rather | ||
| // than suspending for the rest of the execution over a lock it never | ||
| // took. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // took. |
| // Before the index is read and long before an object is written: a host that | ||
| // cannot say who a commit is by cannot make one, and saying so first means | ||
| // nothing was staged, moved or written for a commit that was never going to | ||
| // exist. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // exist. |
| } | ||
| // One exact observation afterwards decides the outcome, never the status of | ||
| // the command: what a push left at the destination is a question about the | ||
| // destination. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // destination. |
| ); | ||
| // Admitted where a request enters, exactly as the retained provider | ||
| // admits it: the Api is public, and a caller reaching it directly is | ||
| // subject to the same boundary. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // subject to the same boundary. |
| const published = yield* livePush(host, git, checkout); | ||
| // Only after the provider has verified a performed or adopted | ||
| // publication. A refused or unreadable one leaves no entry, so nothing | ||
| // it did authorizes a pull request. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // it did authorizes a pull request. |
| repositoryName: ambient.name, | ||
| // The checkout the command was run in, whether that is the repository's | ||
| // primary one or a linked worktree somebody made by hand. Either way it is | ||
| // the repository's own checkout as far as this execution is concerned. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // the repository's own checkout as far as this execution is concerned. |
| if (inputs.number === null) { | ||
| // One open pull request for this branch pair, saying something else. An | ||
| // unnumbered request asks for one to exist, not for whatever is there to | ||
| // become this. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // become this. |
PR #695: ✨ Add the ordinary run's repository provider (#643)19 files, +5462 / -5 Scope🔴 PR has 5467 lines changed. Split into focused PRs. 🟡 5467 lines changed. PRs under 400 receive more thorough review. 🟡 New abstraction files: packages/workflow/src/deno/run-composition/provider.ts. Verify 3+ consumers. StructuralOxlint structural signals:
Slop
Static AnalysisOxlint: 10 diagnostics across 5 files (8 rules) no-array-sort (2): packages/workflow/tests/support/run-composition-tier.ts, packages/workflow/tests/support/run-composition.ts CorrectnessNo extraneous code patterns detected. |
7be4b87 to
9ebea22
Compare
| } | ||
| // Without `--path-format=absolute`, which not every supported Git has: a | ||
| // linked worktree already answers absolutely, and a primary checkout answers | ||
| // `.git` relative to itself. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // `.git` relative to itself. |
| const handle = yield* until(open(temporary, "wx")); | ||
| // Registered before the write, so a halt closes the descriptor: closing is | ||
| // asynchronous, and a `finally` that suspended would not be guaranteed to | ||
| // finish. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // finish. |
| if (file === undefined) { | ||
| // Refused. There is nothing to hold open, so this task ends rather | ||
| // than suspending for the rest of the execution over a lock it never | ||
| // took. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // took. |
| // Before the index is read and long before an object is written: a host that | ||
| // cannot say who a commit is by cannot make one, and saying so first means | ||
| // nothing was staged, moved or written for a commit that was never going to | ||
| // exist. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // exist. |
| // resolved, and a working directory reached through a symbolic link — a | ||
| // temporary directory under macOS `/var`, a home directory somebody linked | ||
| // — is the same place under another name. Comparing the two as written | ||
| // would report a document standing in its own checkout as standing in none. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // would report a document standing in its own checkout as standing in none. |
| const published = yield* livePush(host, git, checkout); | ||
| // Only after the provider has verified a performed or adopted | ||
| // publication. A refused or unreadable one leaves no entry, so nothing | ||
| // it did authorizes a pull request. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // it did authorizes a pull request. |
| repositoryName: ambient.name, | ||
| // The checkout the command was run in, whether that is the repository's | ||
| // primary one or a linked worktree somebody made by hand. Either way it is | ||
| // the repository's own checkout as far as this execution is concerned. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // the repository's own checkout as far as this execution is concerned. |
| if (pullRequestAgrees(found, inputs)) { | ||
| // Everything this invocation asks for is already true — the no-op an | ||
| // unchanged document means, and the adoption an interrupted earlier attempt | ||
| // leaves behind. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // leaves behind. |
| if (inputs.number === null) { | ||
| // One open pull request for this branch pair, saying something else. An | ||
| // unnumbered request asks for one to exist, not for whatever is there to | ||
| // become this. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // become this. |
| const handle = yield* until(open(temporary, "wx")); | ||
| // Registered before the write, so a halt closes the descriptor: closing is | ||
| // asynchronous, and a `finally` that suspended would not be guaranteed to | ||
| // finish. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // finish. |
| if (file === undefined) { | ||
| // Refused. There is nothing to hold open, so this task ends rather | ||
| // than suspending for the rest of the execution over a lock it never | ||
| // took. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // took. |
| // Before the index is read and long before an object is written: a host that | ||
| // cannot say who a commit is by cannot make one, and saying so first means | ||
| // nothing was staged, moved or written for a commit that was never going to | ||
| // exist. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // exist. |
| } | ||
| // One exact observation afterwards decides the outcome, never the status of | ||
| // the command: what a push left at the destination is a question about the | ||
| // destination. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // destination. |
| }); | ||
| // The owner's identity, because that is the repository this checkout | ||
| // belongs to; the worktree's own name and path, because that is which | ||
| // checkout of it this selection points at. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // checkout of it this selection points at. |
| repositoryName: ambient.name, | ||
| // The checkout the command was run in, whether that is the repository's | ||
| // primary one or a linked worktree somebody made by hand. Either way it is | ||
| // the repository's own checkout as far as this execution is concerned. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // the repository's own checkout as far as this execution is concerned. |
9ebea22 to
7937c35
Compare
| } | ||
| // Without `--path-format=absolute`, which not every supported Git has: a | ||
| // linked worktree already answers absolutely, and a primary checkout answers | ||
| // `.git` relative to itself. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // `.git` relative to itself. |
| const handle = yield* until(open(temporary, "wx")); | ||
| // Registered before the write, so a halt closes the descriptor: closing is | ||
| // asynchronous, and a `finally` that suspended would not be guaranteed to | ||
| // finish. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // finish. |
| if (file === undefined) { | ||
| // Refused. There is nothing to hold open, so this task ends rather | ||
| // than suspending for the rest of the execution over a lock it never | ||
| // took. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // took. |
| // Before the index is read and long before an object is written: a host that | ||
| // cannot say who a commit is by cannot make one, and saying so first means | ||
| // nothing was staged, moved or written for a commit that was never going to | ||
| // exist. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // exist. |
| } | ||
| // One exact observation afterwards decides the outcome, never the status of | ||
| // the command: what a push left at the destination is a question about the | ||
| // destination. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // destination. |
| ); | ||
| // Admitted where a request enters, exactly as the retained provider | ||
| // admits it: the Api is public, and a caller reaching it directly is | ||
| // subject to the same boundary. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // subject to the same boundary. |
| const published = yield* livePush(host, git, checkout); | ||
| // Only after the provider has verified a performed or adopted | ||
| // publication. A refused or unreadable one leaves no entry, so nothing | ||
| // it did authorizes a pull request. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // it did authorizes a pull request. |
| { | ||
| // Afresh, every execution. There is nothing to retain a read in and | ||
| // nothing that would replay one, so what a document binds is what the | ||
| // pull request holds now. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // pull request holds now. |
| if (pullRequestAgrees(found, inputs)) { | ||
| // Everything this invocation asks for is already true — the no-op an | ||
| // unchanged document means, and the adoption an interrupted earlier attempt | ||
| // leaves behind. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // leaves behind. |
| if (inputs.number === null) { | ||
| // One open pull request for this branch pair, saying something else. An | ||
| // unnumbered request asks for one to exist, not for whatever is there to | ||
| // become this. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // become this. |
The seam exists; this is the second implementation of it. A provider that works against the caller's own filesystem rather than a retained workflow run: no WorkflowRun, no Workspace, no journal, nothing to replay. What makes a checkout this execution's is an advisory lock, and what makes it the same checkout tomorrow is the sidecar beside it. It discovers the repository the execution was started inside — canonical common directory as identity, canonical checkout root as the selection, so starting in a linked worktree names the same repository as starting in the primary checkout while Git operations still act on the worktree. It places managed Repositories and Worktrees under `~/.xmd/repositories` at a digest of their whole identity, describes each with a closed version 1 sidecar written by exclusive temporary sibling plus atomic rename only after the checkout is complete, and holds each slot for one document execution with a kernel-released non-blocking advisory lock — so a second process is refused immediately rather than made to wait, and a crash releases the slot without cleanup. Nothing deletes, resets, cleans, fetches or repairs a managed checkout: what is in one is somebody's work. Local Git performs the same authored transitions the workflow performers do, directly against the authenticated checkout, under the same fixed configuration that disables hooks, signing, file-system monitors and repository-supplied helper programs. A commit records the invoking user's own effective Git identity, captured from the trusted host before the document expands; a host that can name no identity refuses `<Git.Commit>` and names the commands that fix it rather than writing the workflow identity into somebody's repository, and every other component stays usable. Push keeps the observe/adopt/fast-forward/refuse rules and stores one private evidence entry per verified publication in the provider instance's own closure. `<PullRequest>` requires the exact matching entry that instance holds: a Push for another checkout, repository, origin, destination, branch or commit is irrelevant, a later Push of the same destination supersedes the earlier entry, and missing or conflicting evidence is a local refusal before a credential is opened. Nothing crosses executions. No entrypoint installs any of this yet — the suites install it themselves through the trusted test installer, and `architecture.md` gains the terminology these structures need but no status row, because nothing on main can reach them. The certified tier suite is split by capability rather than carried whole: ambient and local Git, managed checkouts, live remotes. Every describe block is intact, all 51 cases are preserved, and shared fixtures moved to tests/support/run-composition-tier.ts.
`selectCheckout()` admitted a registered checkout as a candidate when its identity's `locatorFingerprint` equalled the authenticated contextual one. A fingerprint names where a repository came from, not which repository it is: two `<Repository>` elements naming one url under two names are two repositories, with separate slots, separate advisory leases and separate Push evidence, and every other member of their identities is equal. So a `<Dir>` into the second one, written where the first is the Repository in scope, passed selection authentication against the first and then acted in a checkout the first never selected. Under that path `<Git.Switch>` moved the second repository's branch, and `<Git.Push>` reached its origin and recorded publication evidence for it. The candidate now has to equal the contextual identity under `sameRepositoryIdentity`, so every member of `REPOSITORY_IDENTITY_MEMBERS` participates and the comparison stays in one place rather than becoming a second partial one. Nothing legitimate narrows: every checkout of a repository already carries that repository's identity, and a Worktree registers under its owner's, so longest-containing-checkout selection among a repository's own checkouts is unchanged. The regression asks for the refusal at the three surfaces that reach different things — a local mutation, a publication and a Git host — and observes the second repository's branch, head, index, working tree and remote refs rather than inferring them. It counts the authentication sessions the host opened and the credentials the Git host was asked for, so "nothing was reached" is measured. Two controls keep it from passing vacuously: the same document shape reaching every one of those boundaries when the identity does match, with the session counter non-empty there under the same fixtures, and a Worktree of the Repository in scope still operating when entered by its returned path.
7937c35 to
869593e
Compare
| const handle = yield* until(open(temporary, "wx")); | ||
| // Registered before the write, so a halt closes the descriptor: closing is | ||
| // asynchronous, and a `finally` that suspended would not be guaranteed to | ||
| // finish. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // finish. |
| if (file === undefined) { | ||
| // Refused. There is nothing to hold open, so this task ends rather | ||
| // than suspending for the rest of the execution over a lock it never | ||
| // took. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // took. |
| // Before the index is read and long before an object is written: a host that | ||
| // cannot say who a commit is by cannot make one, and saying so first means | ||
| // nothing was staged, moved or written for a commit that was never going to | ||
| // exist. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // exist. |
| } | ||
| // One exact observation afterwards decides the outcome, never the status of | ||
| // the command: what a push left at the destination is a question about the | ||
| // destination. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // destination. |
| }); | ||
| // The owner's identity, because that is the repository this checkout | ||
| // belongs to; the worktree's own name and path, because that is which | ||
| // checkout of it this selection points at. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // checkout of it this selection points at. |
| // resolved, and a working directory reached through a symbolic link — a | ||
| // temporary directory under macOS `/var`, a home directory somebody linked | ||
| // — is the same place under another name. Comparing the two as written | ||
| // would report a document standing in its own checkout as standing in none. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // would report a document standing in its own checkout as standing in none. |
| const published = yield* livePush(host, git, checkout); | ||
| // Only after the provider has verified a performed or adopted | ||
| // publication. A refused or unreadable one leaves no entry, so nothing | ||
| // it did authorizes a pull request. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // it did authorizes a pull request. |
| repositoryName: ambient.name, | ||
| // The checkout the command was run in, whether that is the repository's | ||
| // primary one or a linked worktree somebody made by hand. Either way it is | ||
| // the repository's own checkout as far as this execution is concerned. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // the repository's own checkout as far as this execution is concerned. |
Two CI-only failures, both in this tier's own tests. `refsOf` used `toSorted()`. The Node shards run `tsc --project tsconfig.node.json`, which targets ES2022, so the call does not exist there — TS2550, before a single test runs, on all five shards. Reverted to `sort()`, which is what the neighbouring helpers in this tier already do: the array being sorted is the one `map` just made, so there is nothing of anyone else's to mutate. Eleven cases then failed on `UnresolvedGitIdentityError` — ORC3, ORC4, ORC5, four in ORC14, three in ORC15 and one in ORC17. They reach `<Git.Commit>` without saying who the commit is by, so the provider fell through to its production default and read the *host's* Git configuration. That passes on a machine with `user.name` set and fails on every CI runner, which is to say the suite was asserting something about who ran it rather than about the document. `runOrdinaryDocument` now installs a fixed identity, spread first so a case that supplies its own reader still wins — which is how the ORC13 cases that are *about* identity resolution keep working, including the one that proves `<Git.Commit>` refuses when the host can say nothing. Verified by reproducing the runner rather than trusting the reading: with `user.useConfigOnly` set and no configuration file, `git var GIT_AUTHOR_IDENT` fails exactly as it does in CI, and the four suites went from 6 failed (11 steps) to 17 passed (60 steps). They also still pass with an identity present, so neither direction is assumed.
| const handle = yield* until(open(temporary, "wx")); | ||
| // Registered before the write, so a halt closes the descriptor: closing is | ||
| // asynchronous, and a `finally` that suspended would not be guaranteed to | ||
| // finish. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // finish. |
| // Before the index is read and long before an object is written: a host that | ||
| // cannot say who a commit is by cannot make one, and saying so first means | ||
| // nothing was staged, moved or written for a commit that was never going to | ||
| // exist. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // exist. |
| } | ||
| // One exact observation afterwards decides the outcome, never the status of | ||
| // the command: what a push left at the destination is a question about the | ||
| // destination. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // destination. |
| }); | ||
| // The owner's identity, because that is the repository this checkout | ||
| // belongs to; the worktree's own name and path, because that is which | ||
| // checkout of it this selection points at. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // checkout of it this selection points at. |
| const published = yield* livePush(host, git, checkout); | ||
| // Only after the provider has verified a performed or adopted | ||
| // publication. A refused or unreadable one leaves no entry, so nothing | ||
| // it did authorizes a pull request. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // it did authorizes a pull request. |
| } | ||
| // Before a credential is read and before anything is sent. What | ||
| // authorizes a pull request is this execution's own record of | ||
| // publishing the branch. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // publishing the branch. |
| repositoryName: ambient.name, | ||
| // The checkout the command was run in, whether that is the repository's | ||
| // primary one or a linked worktree somebody made by hand. Either way it is | ||
| // the repository's own checkout as far as this execution is concerned. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // the repository's own checkout as far as this execution is concerned. |
| ); | ||
| // What a runtime entrypoint installs beside the provider: `API.Files` has | ||
| // no host default, and a document that writes `<File>` must reach the | ||
| // caller's own filesystem exactly as `xmd run` leaves it. |
There was a problem hiding this comment.
Redundant comment — restates what the code does.
| // caller's own filesystem exactly as `xmd run` leaves it. |
Part of #643. Middle of a three-PR stack — depends on #694, which must merge first.
agent/issue-643-composition-seamagent/issue-643-run-provideragent/issue-643-run-profilexmd runexposureWhy
#694 gave repository composition a seam a second profile can implement. This is
that second implementation: a provider working against the caller's own
filesystem rather than a retained workflow run.
What changes
Before: the only implementation was the retained workflow provider — database,
journal, replay.
After: a second provider exists with no WorkflowRun, no Workspace, no journal and
nothing to replay. What makes a checkout this execution's is an advisory lock;
what makes it the same checkout tomorrow is the sidecar beside it.
No entrypoint installs it. Every operation of it is exercised through the
trusted test installer. Reaching it from
xmd runis PR 3.How it works
Review guide
Start with:
src/deno/run-composition/provider.tsThen review:
ambient.ts— how the repository the execution started in is discoveredcheckouts.ts+placement.ts+metadata.ts— where a managed checkout goes and what describes itleases.ts— how a slot is held for exactly one executionoperations.ts— local Git, Push evidence admissionidentity.ts— the invoking user's own Git identityLook carefully at
leases.ts. The acquiring task mustsuspend(). A taskthat completes releases what it acquired, so an earlier version dropped the
lock the moment acquisition returned. Nothing in-process caught it; a real second
process did.
What must stay true
in one is somebody's work. Checked by ORC8–ORC11.
How to verify it
second process because an in-process check cannot see a kernel lock released early.
byte-for-byte after the refusal.
that cannot name an identity writes one anyway.
authority.
deno task test packages/workflow/tests/run-composition-{ambient,managed,remote}.test.tsResults: tier suites
ok | 15 passed (51 steps) | 0 failed· seam regressionok | 42 passed (233 steps) | 0 failed·deno checkexit 0Scope
Included
Intentionally unchanged
Generated or mechanical changes
The certified 1,928-line tier suite is partitioned by capability, not rewritten:
run-composition-ambient.test.ts— ORC3, ORC4, ORC5, ORC6, ORC13run-composition-managed.test.ts— ORC8–ORC12run-composition-remote.test.ts— ORC14–ORC17support/run-composition-tier.ts— shared fixtures15 describe blocks and 51 cases before and after; the sorted set of every
describe and
ittitle is identical. No block is divided. Per-file imports weretrimmed from oxlint's report.
Risks and limitations
three suites are excluded there; the portable half arrives in PR 3.
rather than losing work.
Scope confirmation