Skip to content

Make repository composition available to ordinary xmd run #643

Description

@taras

Story

As an author of a repository-facing executable document, I want <Repository>,
<Worktree>, <Issue> and <PullRequest> to resolve under ordinary
xmd run, so a document can name and change the repository work it is about
without becoming a retained workflow run.

Today those words exist only inside a workflow. Every document that is not a
workflow — including this repository's own AGENTS.md role targets — has to
describe repository state in prose and let the launched Agent go find it.

Motivating case

AGENTS.md#Architect prepares an Architect session for one issue:

xmd run AGENTS.md#Architect --props-issue 638

It needs the current repository, a worktree for that issue, and the issue itself:

<Worktree name="issue-638" branch="issue-638">
   <Agent name="codex">
      <Session.Launch session="architect">
         <Issue url={issue} />
      </Session.Launch>
   </Agent>
</Worktree>

Today it fails before the role can launch:

Failed to import component Worktree: Cannot resolve component: Worktree (searched: components, .)
Failed to import component Issue: Cannot resolve component: Issue (searched: components, .)

The worktree keeps concurrent issue sessions apart. The Agent session key uses
the resolved Git root, and .git may be a file when that root is a linked
worktree. The document already has the structure needed to select the right
session, but xmd run cannot create or enter that worktree.

Current reality

Verified again on main (d1155015).

packages/workflow/src/composition/installation.ts registers Repository,
Worktree, Dir, Git.Switch, Git.Add, Git.Commit, Git.Push,
PullRequest, PullRequest.Reviews, PullRequest.Comments,
PullRequest.Checks, IssueTracker and Issue. Only workflow start/resume and
workflow-fork execution receive that installation. Ordinary xmd run receives
none of it, and xmd syntax does not list it in the run profile.

The two profiles currently have opposite halves of the motivating case:

  • xmd run has the live Agent stack and native foreground launcher, but no
    repository composition.
  • xmd workflow has repository composition, but its restricted Agent profile
    intentionally has no native foreground launcher.

Installing component names alone is not enough. The run host must also supply
the Git, filesystem, issue and pull-request providers those components call.
The existing composition providers cannot simply be installed there: their
Repository records and Git-host and Issue effect identities belong to a retained
WorkflowRun and their Deno implementations require its database.

Settled ordinary-run contract

Ordinary xmd run is a trusted, live execution. It may change local Git state
and external services using the permissions and credentials of the person who
started it. This issue does not make xmd run a sandbox and does not wait for
the least-authority work in #536.

The run profile installs the full repository composition surface:

  • Repository, Worktree and Dir;
  • Git.Switch, Git.Add, Git.Commit and Git.Push;
  • PullRequest, PullRequest.Reviews, PullRequest.Comments and
    PullRequest.Checks; and
  • IssueTracker and Issue, including issue reads and upserts.

xmd syntax reports that same surface. A repository component may still shadow
an ordinary default under the existing component-resolution rules.

The current repository is the ambient Repository

When xmd run starts inside a Git repository, the trusted run host installs
that repository as the full current Repository context. A root-level
<Worktree> therefore creates a worktree of the repository the user ran the
document from, and root-level Git.* and PullRequest use that same Repository
and the contextual checkout. The run refuses clearly when an operation requires
a Repository and the contextual working directory is not inside one.

The ambient Repository is invocation-scoped host state, not a fabricated
retained Workspace RepositoryRecord. Its identity comes from Git's canonical
repository and common-directory facts, so invoking XMD from a linked worktree
still identifies the repository that owns it while the contextual working
directory continues to select that linked checkout. A local repository needs no
origin for Worktree and local Git operations. Git.Push and PullRequest
refuse locally, before authentication or a remote request, when no authorized
origin exists.

branch remains required. name identifies the worktree and does not silently
choose a branch. A lexical <Repository> still selects another repository
explicitly through its existing name, url and optional base contract.

Managed checkouts preserve the work

A checkout created by lexical <Repository> or <Worktree> uses deterministic,
provider-owned host placement. Both primary Repository checkouts and linked
Worktrees remain after xmd run finishes normally, fails or is cancelled.
Removing one during component or process teardown would destroy work the
document or launched Agent just produced.

The provider retains enough host-owned creation metadata to distinguish the
repository, name, locator when applicable, branch, requested base and creation
commit from the mutable Git state later work produces. Reusing a managed
checkout succeeds only when those immutable creation facts agree and its live
Git identity is still compatible. A conflicting checkout, locator, branch or
base is refused instead of moved, replaced, reset or silently reused. An
interrupted partial creation is reconciled only when the provider can prove the
same compatible identity; otherwise it is refused and left for explicit
cleanup.

One ordinary run owns a selected managed checkout at a time. The provider takes
a scope-owned, non-blocking exclusive host lock before it validates or exposes
that checkout and holds it through the lexical use, including an interactive
Session.Launch. Another run selecting the same managed checkout refuses
without moving or mutating it. Different managed checkouts may proceed
concurrently. The ambient Repository the caller supplied is not provider-owned;
the caller remains responsible for concurrent use of that checkout.

Cleanup is an intentional lifecycle operation. This issue neither removes a
managed checkout automatically nor hides deletion in teardown. A later cleanup
surface must identify its exact target, refuse active use, and report dirty,
unpushed or conflicting work before anything is discarded.

A lexical Repository, Worktree or Dir installs its checkout as the contextual
working directory for its children. Session.Launch therefore launches from
the selected worktree, and the existing Agent session placement derives its key
from that Git root.

Mutations are live, not retained workflow effects

Every invocation of xmd run is a new document execution. It does not receive
a WorkflowRun ID, retained Workspace, replay, resume, history fork or effect
transaction.

The trusted host gives that document execution one opaque invocation identity.
It is not a WorkflowRun ID, creates no addressable lifecycle and grants no
continuation authority. Together with the engine-owned expansion identity it
correlates retries and external reconciliation only inside that invocation. A
later xmd run receives another identity.

--journal remains a diagnostic trace for that invocation. It may describe the
invocation identity and live outcomes, but the CLI never loads it as authority
or continuation input. If the process stops after GitHub accepted an issue,
push or pull-request change but before XMD recorded completion, the external
change may exist without a matching local result. Running the document again is
a new live request, not a resume.

Providers still observe and adopt compatible external state when their normal
contract can prove it. That can make a repeated request harmless, but ordinary
xmd run does not promise workflow-grade exactly-once recovery across process
interruption.

A successful ordinary-run Git.Push publishes verified evidence into
execution-owned state after the provider accepts the outcome. <PullRequest>
requires matching evidence for the exact Repository, checkout, branch,
destination and commit earlier in that same execution. A document, Context or
ordinary middleware cannot mint or carry that evidence into another execution.
On a new run, the document performs or adopts the Push again before it reaches
the pull request.

Authority remains host-owned

Component props and lexical contexts request a repository or remote target;
they do not grant access. The run provider validates the request against the
host's existing target ceilings before it reads credentials or contacts a
service. Missing provider configuration remains fail-closed.

This issue reuses the existing GitHub Issue and PullRequest host configuration.
It does not rename those settings. A later configuration cleanup may give them
profile-neutral names without coupling that migration to this feature.

Initial runtime support

The Deno source entrypoint and compiled binary install the operational ordinary
repository provider in the first delivery. They share the same component
declarations, provider contracts and observable behavior.

Node and Bun expose the same declarations through xmd syntax, but install no
operational repository provider in this delivery. An attempted Repository,
Worktree, Git, Issue or PullRequest operation therefore fails clearly from
provider absence before local or remote mutation. This is a runtime-provider
limit, not a different document language. Native Session.Launch retains its
existing runtime support boundary.

Non-goals

Acceptance

  • xmd syntax lists the complete ordinary-run composition surface above on
    every runtime.
  • Under the Deno source entrypoint and compiled binary, a root-level Worktree
    uses the ambient Git repository, requires branch, and refuses outside a
    repository.
  • The ambient Repository is the full Repository context: root-level Git and
    PullRequest operations use it, while remote operations refuse locally when it
    has no authorized origin.
  • Repository, Worktree and Dir children observe the selected checkout as their
    contextual working directory.
  • Session.Launch inside a Worktree launches from that checkout and therefore
    receives the worktree-specific Agent session placement.
  • A managed Repository or Worktree survives normal completion, failure and
    cancellation.
  • Compatible managed-checkout reuse succeeds; conflicting immutable creation
    identity or live Git state refuses without moving, resetting or replacing it.
  • A second process selecting an in-use managed checkout refuses without
    mutation, and releasing or cancelling the owner releases the lock without
    deleting the checkout.
  • Interrupted partial creation is adopted only when compatibility is proved;
    otherwise it remains unchanged for explicit cleanup.
  • Issue reads and upserts, Git operations, PullRequest upserts and PullRequest
    evidence reads execute under ordinary xmd run with the Deno/compiled host's
    configured providers and ceilings.
  • PullRequest upsert requires exact successful Push evidence from earlier in
    that document execution; a later invocation cannot reuse it.
  • A normal run and --journal both execute live; the latter records diagnostics
    but provides no resume or lifecycle authority.
  • Provider absence and targets outside a host ceiling fail before credentials
    are read or a remote request is sent.
  • Node and Bun resolve the same component names and refuse operational use from
    provider absence without mutation.
  • The workflow profile, retained effect identity, Workspace transactions and
    native-launch refusal remain unchanged.
  • architecture.md, specs/executable-mdx-spec.md and
    specs/workflow-workspace-spec.md describe the ordinary and retained provider
    boundaries without broadening a Workspace RepositoryRecord to mean an
    ambient host checkout.

Dependencies and related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions