Skip to content

Run and reopen a linear multi-Agent XMD REPL #783

Description

@taras

Story

As a person coordinating coding agents, I want a stateful XMD REPL that evaluates one block at a time and can be reopened after a crash, so I can work across several sessions without turning XMD into a notebook or losing committed work.

Common path

The user opens the REPL and evaluates an XMD block that creates or reconnects to an Agent session. When that block succeeds, its bindings are available to later blocks. A later block sends a <Prompt> through the referenced session and waits for the turn to settle before another block can run.

The same REPL can hold bindings for several roles and sessions. Each submitted block explicitly references the session it uses; there is no separate selected-agent state. If concurrency is needed, it is authored explicitly inside one XMD program rather than created by concurrent REPL submissions.

If the REPL crashes, reopening it replays its journal to reconstruct committed input, output, generator control state, retained effect results, and journal-restorable bindings without re-executing completed effects. An incomplete block is shown as interrupted and is not automatically resent or resumed. The user evaluates a new program to reconnect to an existing Agent session and continue.

Current gap

XMD can evaluate documents, retain effects, and interact with one Agent session through ACP, but it has no interactive terminal that keeps one evaluation scope across successive XMD blocks and presents live Agent entries through configurable Markdown components.

ACP activity is not reflected reliably in an already-open provider-native TUI, and #774 established that terminal paste cannot safely replace ACP. The REPL must therefore render updates from the ACP connection used by the executing prompt.

Contract

The REPL is linear XMD evaluation, not a notebook, background command queue, or second workflow engine. Exactly one submitted block executes at a time. A <Prompt> keeps that block active until the Agent turn settles. The next submission waits.

One long-lived Effection scope owns the live REPL instance. Each block evaluates within that scope. A successful block atomically publishes its new bindings for later blocks. A failed or cancelled block publishes no new bindings. Resource-producing syntax such as <Worktree> may keep resources alive in the REPL scope across later blocks; closing the REPL disposes that scope and its resources in the ordinary lifecycle.

Existing Agent session syntax owns creation and continuation. When evaluated for a logical session, it creates the session if absent or reconnects to that exact session if already retained. This Story adds no Session.Ensure or Session.Reconnect component and does not change <Session.Launch>.

ACP is the only REPL interaction boundary for a coding Agent. Prompts, cancellation, permission answers, and updates use the ACP session owned by the executing XMD program. Nothing is delivered through tmux, stdin injection into a native TUI, provider files, hooks, or plugins.

ACP updates are normalized into #800's immutable entries and rendered through its Markdown components. Incoming ACP transport continues to drain if rendering blocks; pending visual work coalesces to the latest snapshot. The current XMD block remains active until its prompt and renderer obligations settle. No second block begins meanwhile.

The journal retains committed XMD inputs, rendered block outputs, published journal-restorable bindings, and retained effect results. Each completed <Prompt> also retains one final normalized turn snapshot containing its settled messages, tool outcomes, permission outcomes, and status. Streaming deltas, intermediate entry snapshots, terminal frames, cursor, scroll, selection, focus, follow state, and unread state remain live-only.

Replay reconstructs completed output by rendering the final normalized snapshots and returning retained effect results; it does not reopen ACP or repeat completed prompts. A block interrupted by REPL failure is recorded and displayed as interrupted, never automatically resent, resumed, or declared equivalent to the provider's live state.

A reopened REPL does not assume that its former ACP connections, watchers, scope-owned external resources, or in-progress execution still exist. Journal-restorable values may be recovered, but no stale live handle is treated as ownership. The user starts a new linear block whose existing Session behavior creates or reconnects as appropriate. Exact provider, protocol, host, ownership, and session identity checks remain fail-closed, and a retained identity is never replaced to make reconnection succeed.

Tail is separate. xmd tail and <Session.Tail> observe provider files outside the initial REPL experience. They do not supply the REPL's live ACP view, authorize actions, or restore REPL execution.

Acceptance

  • Successive XMD blocks execute in one Effection scope, and only one submitted block is active.
  • A successful block makes its bindings available to the next block; a failed or cancelled block publishes none of its new bindings.
  • A scoped resource created by one successful block remains usable by a later block and is disposed when the REPL closes.
  • A <Prompt> prevents the next submission from starting until the turn settles.
  • Two logical Agent sessions remain distinct, and blocks explicitly reference the intended session without selected-agent state or cross-delivery.
  • Explicit concurrency authored inside one program remains possible; submitting concurrent REPL blocks is refused.
  • Existing Session behavior creates an absent logical session and reconnects to the exact retained session without a new Ensure or Reconnect component.
  • Live ACP messages, thought, tool, permission, status, failure, and completion updates render through Render Agent session entries with Markdown components #800 while transport ingestion remains independent of rendering.
  • A completed Prompt retains one final normalized turn snapshot. Replay reconstructs its presentation without opening ACP, repeating the prompt, or replaying intermediate terminal frames.
  • Reopening restores committed inputs, outputs, retained results, and journal-restorable bindings without re-executing completed effects.
  • A controlled crash during the active block leaves it visibly interrupted and causes zero automatic resend or resume.
  • A subsequent user-entered program can reconnect to the exact existing Agent session through the ordinary Session contract.
  • Reopen does not claim that a previous ACP connection, watcher, external resource, active execution, or provider state is still live.
  • Provider, protocol, capability, host, ownership, or identity disagreement refuses without allocating a substitute session or changing retained state.
  • Deterministic evidence covers linear evaluation, binding publication, scoped resource lifetime, exact reconnection, prompt settlement, replay, interruption, permission, cancellation, failure, and duplicate suppression.
  • The REPL presentation and replay journey passes through source and deno compile entrypoints without spending a model turn.

Relationships

Out of scope

  • Concurrent submitted blocks, notebook cells, or a background REPL work queue.
  • A selected-agent mode or persistent terminal UI state.
  • Automatic resend or resumption of a block interrupted by REPL failure.
  • Making ACP messages appear inside a provider-native UI.
  • Delivering prompts through tmux, provider files, or native TUI input.
  • Running Tail inside the initial REPL experience.
  • Adding REPL behavior to Workflow.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    UXUser-facing usability and interaction improvementsenhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions