Repository navigation
Keep xmd repl usable after sequential nested component calls #976
Description
Story
As an author using xmd repl, I want to call the same Markdown component more than once in an entry, including through nested workflow components, so the REPL keeps showing the correct source, bindings and completed work.
Observed failure
A real #975 workflow entry completed its Codex Architect call and saved its validated result. The REPL then displayed a failure screen instead of the entry history:
<Phase.Schema /> names a source this entry admitted more than once, so which occurrence owns it cannot be decided.
The entry used this composition, with both calls on the ordinary sequential execution path:
Architect
+-- Phase.Run
| +-- Phase.Accept -> Phase.Schema
|
+-- Phase.Context
+-- Phase.Accept -> Phase.Schema
Phase.Run validates and saves the role result through Phase.Accept. After it returns, Architect calls Phase.Context, which validates the result through Phase.Accept again. Each Phase.Accept invokes Phase.Schema. The entry also uses schema reads while preparing its assignment.
The saved event-result-saved.json records completion at 2026-10-21T18:33:26Z, with a valid phase-result.v2 result. The role returned needs_decision; that ordinary hold is distinct from the REPL history failure. No product source changed and the completed agent call was not rerun.
Observed on main revision d422daedcfad446b959ec691cb5bad5957f9c178, after deno task setup, using:
deno task xmd repl --include /private/tmp/xmd-component-sets/components \
--default-agent codex --sidekick-agent codexLocal preserved evidence from the trial:
/private/tmp/xmd-component-sets/trial-session-workspace-975/architect-entry.xmd/private/tmp/xmd-component-sets/trial-session-workspace-975/architect-1/result.json/private/tmp/xmd-component-sets/trial-session-workspace-975/architect-1/event-result-saved.json/private/tmp/xmd-component-sets/trial-session-workspace-975/first-repl-failure.json/private/tmp/xmd-component-sets/trial-session-workspace-975/first-repl-failure-screen.txt
These local files preserve the observed failure; the repair must not depend on access to them or another paid agent call.
Current gap
The history reader indexes admitted component sources by path. pathOwnerOf() accepts candidates that occurred earlier on the same coroutine or an ancestor. Two sequential calls can both qualify, and it refuses the entire reading when more than one candidate remains. A nested component import then cannot be assigned to its particular enclosing call.
See pathOwnerOf() and couldOwn() and the RS2 cases in repl-model.test.ts. The current synthetic test explicitly expects refusal when a call repeats on the same branch.
Acceptance and focused evidence
- Repeated sequential calls in a real REPL entry remain readable while running, after completion and after cold reopen. Each call shows its own nested source and bindings.
- Exercise a small nested component twice with distinct inputs and returned values; assert that each result appears under its actual call. A suggested fixture is a
Wrapperthat invokes aLeaf, called twice from one entry. This standalone fixture has not yet been run; the observed workflow above is the current reproduction. - Preserve completed effects and agent results. Reading or reopening the repaired history does not rerun them; use deterministic test effects or a fake agent rather than a paid provider.
- Keep the existing separate-branch regression from Keep
xmd replusable after repeated component calls #941 passing. Preserve refusal for genuinely missing or conflicting source ownership; selecting the latest matching path without evidence is insufficient. - Add focused coverage through the existing
packages/cli/tests/repl-model.test.tsand the relevant production REPL/component journey test. Required CI owns exhaustive runtime suites.
Relationships and scope
#941 and its repair #969 cover the earlier repeated-component failure, including calls in separate spawned branches. This issue covers sequential nested reuse exposed by the workflow on a main revision containing that repair.
The failure blocks the watchable #975 workflow trial. #975's workspace behavior and its pending product decisions remain separate; no cwd change or provider substitution is part of this repair. Preserve the failed trial and its completed Architect result for continuation after the repair.
Activity
🐛 Preserve eval source ownership through middleware copies (#976)
🐛 Carry source ownership through the scoped Context (#976)
🐛 Resolve temporary REPL fixture dependencies under Node (#976)
🐛 Read terminal test journals after entry settlement (#976)