Skip to content

馃悰 Keep REPL source ownership across sequential nested calls - #977

Merged
taras merged 5 commits into
mainfrom
agent/issue-976-sequential-nested
Oct 22, 2026
Merged

taras merged 5 commits into
mainfrom
agent/issue-976-sequential-nested

Conversation

@taras

@taras taras commented Oct 21, 2026 •

Copy link
Copy Markdown
Owner

Why

Sequential calls to the same nested Markdown component can execute successfully while xmd repl refuses to display their retained history. Two Wrapper/Leaf calls producing first/second need distinct invocation ownership even when they share an authored site and coroutine.

Closes #976.

What changes

Each attributed operation retains the exact prior successful import coordinate that owns its source. The REPL can inspect both nested calls, continue interrupted work, and reopen completed work without repeating completed effects.

How it works

Core binds the existing import DurablePosition in the internal scoped SourceOwner Context (executablemd.source-owner). Component bodies use their own import; projected caller Content restores its captured caller binding. Attribution writers capture that binding before handing work to another owned task. Elicit and Prompt retain their original props-only APIs; ownership-only invocation and expansion arguments are removed.

The additive journal description field contains { coroutineId, index }, where index is the existing zero-based per-coroutine yield index within the entry. Projection validates the exact prior import, source and ancestry. Existing unique legacy histories retain inference; ambiguous legacy histories and invalid explicit references refuse without rewriting or re-executing history.

Review guide

Start with SO1鈥揝O7 in packages/cli/tests/repl-model.test.ts, then source admission/Context binding in execute.ts and expand.ts, attribution writers, and exact-reference validation in packages/cli/src/repl/model.ts.

Final signed head: 0f165fb2da28710dc548cbb19c17ffc5c2df2fd9. Base: d422daedcfad446b959ec691cb5bad5957f9c178, targeting main with no stacked dependency. ROOT reviewed the final scope and finite correction; this does not claim two independent reviewer agents.

How to verify it

The six frozen rows cover sequential nested ownership at every serialized prefix, repeated loop sites and caller projection, real terminal inspection, separate-process completed reopen with an unchanged journal/provider counter, interrupted current/legacy continuation, and malformed/invalid explicit references plus RS1/RS2 regressions. SO7 additionally proves ordinary code-block middleware copies preserve ownership.

Focused receipts for the Context correction: ownership/model/generated suites pass (13 suites, 95 steps); affected boundary suites pass (32 suites, 218 steps); Deno terminal journey passes (1 suite, 1 step).

The temporary fixture declares its module type and links prepared project dependencies using the existing CLI test convention. Its journal reader waits for the existing Ready state before parsing the settled file, avoiding reads during an append while preserving strict validation. Both complete terminal journeys (include selection and #976 ownership/reopen) pass under Node and Deno:

pnpm exec tsx --tsconfig tsconfig.node.json --test --test-concurrency=1 packages/cli/tests/repl-include-pty.test.ts
deno task test packages/cli/tests/repl-include-pty.test.ts

Changed-file oxlint and formatting, diff checks and normal commit signature verification pass. Required CI on the final head is the delivery gate; the exhaustive runtime suites run there.

Risks and limitations

Terminal evidence uses the production source CLI and a counted fake Elicitation provider; no paid Agent call is made. The original ambiguous #975 journal remains untouched and cannot gain ownership metadata retroactively; its completed Architect result remains preserved.

Scope confirmation

  • Every changed file supports retained source ownership and its regression evidence.
  • No dependency, lockfile, generated artifact, permission, model or provider changes.
  • Existing effect identities, ordering, generated-fragment attribution and public component APIs are preserved.

@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

PR #977: 馃悰 Keep REPL source ownership across sequential nested calls

20 files, +779 / -102

Scope

馃敶 PR has 881 lines changed. Split into focused PRs.

馃煛 881 lines changed. PRs under 400 receive more thorough review.

Structural

Oxlint structural signals:

  • no-unused-vars 脳18: packages/core/src/generated-xmd.ts, packages/core/src/execute.ts, packages/core/src/expand.ts
  • no-unnecessary-type-assertion 脳10: packages/core/src/eval-handler.ts, packages/core/src/expand.ts, packages/core/src/execute.ts (+1)
  • no-empty-function 脳1: packages/core/src/execute.ts

Slop

Oxlint slop signals:

  • no-inferrable-types 脳2: packages/core/src/expand.ts

Static Analysis

Oxlint: 92 diagnostics across 7 files (19 rules)
Density: 0.118 violations/added-line

no-unused-vars (18): packages/core/src/generated-xmd.ts, packages/core/src/execute.ts, packages/core/src/expand.ts
no-shadow (14): packages/core/src/agent/journal.ts, packages/core/src/generated-xmd.ts, packages/core/src/execute.ts (+1)
no-unsafe-type-assertion (11): packages/core/src/eval-handler.ts, packages/core/src/expand.ts, packages/core/src/execute.ts
unbound-method (11): packages/core/src/expand.ts, packages/core/src/execute.ts
no-unnecessary-type-assertion (10): packages/core/src/eval-handler.ts, packages/core/src/expand.ts, packages/core/src/execute.ts (+1)
no-base-to-string (7): packages/core/src/eval-handler.ts, packages/cli/tests/fixtures/repl/source-ownership.ts, packages/core/src/expand.ts
no-underscore-dangle (4): packages/core/src/eval-handler.ts, packages/core/src/expand.ts
no-array-sort (2): packages/core/src/execute.ts, packages/cli/src/repl/model.ts
no-inferrable-types (2): packages/core/src/expand.ts
no-unnecessary-type-conversion (2): packages/core/src/eval-handler.ts, packages/cli/src/repl/model.ts
consistent-return (2): packages/core/src/execute.ts
no-duplicate-type-constituents (2): packages/core/src/execute.ts
no-empty-function (1): packages/core/src/execute.ts
consistent-function-scoping (1): packages/core/src/execute.ts
no-useless-fallback-in-spread (1): packages/core/src/expand.ts
restrict-template-expressions (1): packages/core/src/expand.ts
no-unnecessary-template-expression (1): packages/cli/src/repl/model.ts
no-implied-eval (1): packages/core/src/expand.ts
no-floating-promises (1): packages/core/src/execute.ts

Correctness

No extraneous code patterns detected.

@taras
taras marked this pull request as ready for review October 21, 2026 22:47
@taras
taras marked this pull request as draft October 21, 2026 23:48
@taras
taras marked this pull request as ready for review October 22, 2026 00:13
@taras
taras merged commit 00f05aa into main Oct 22, 2026
44 checks passed
@taras
taras deleted the agent/issue-976-sequential-nested branch October 22, 2026 00:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Keep xmd repl usable after sequential nested component calls

1 participant