Skip to content

fix(runtime-host): one linked-child rule for every conversation copy - #5757

Merged
jackwener merged 6 commits into
apache:mainfrom
Astro-Han:fix/5333-branch-linked-children
Sep 27, 2026
Merged

jackwener merged 6 commits into
apache:mainfrom
Astro-Han:fix/5333-branch-linked-children

Conversation

@Astro-Han

@Astro-Han Astro-Han commented Sep 27, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Branching from a turn that retained a linked child Session always failed in the Host with Ordinary branches cannot share linked child Session ownership with their source, and Desktop showed only the generic "Operation failed, try again later" toast. The same code path also made edit-and-resend always fail once an ordinary (non-Graph) subagent had run, again with the generic toast.

Root cause

Conversation copies (branch, side conversation, revision) chose how to handle linked children based on the kind of copy. Branches rejected. Side conversations made snapshots. Revisions shared Agent Graph children and rejected everything else. On top of that, a separate gate rejected owned references inside archived tool results, but only for branches and revisions, while side conversations wrote those archives inline. So each kind of copy failed on its own subset of sessions.

All of these cases come down to one invariant: a copy may share a child only when the copy's own lifecycle keeps that child alive. Agent Graph children retire together with their root's revision family (session-retirement-coordinator), so a revision can share them. An ordinary subagent is an independent Session that can be removed on its own. Branches and side conversations have their own lifecycle. So every other retained child has to be copied as a snapshot of its terminal result.

Change

  • @maka/runtime conversation-copy: the reference map now has one shape, sharedChildren. Removed the three reject / snapshot / preserve_validated modes, the preserve_external variant (no production code used it), the mode discriminant, and archivedToolResultContainsLinkedChildReferences.
  • Archived tool results: every archive transition, including a legacy (rewriteVersion 1) Artifact-backed one, is rebuilt as a ledger archive of the copied event, the path v2 archives already took. The copied event already holds the snapshot, so the archive carries no source child ids and needs no Artifact. This replaces inlining archived bodies into the copy, which had no aggregate size bound (a copied Turn could exceed the transcript reader's 16 MiB limit) and, for the v1 transitions that builds between refactor(runtime): unify durable model-context projection authority #4350 and feat(runtime): archive tool results through durable ledger refs #4987 wrote, rolled the copy back with missing Artifact because the inlined archive was excluded from the Artifact copy. No shipped build persisted a v1 placeholder inside a RuntimeEvent result (pruning was replay-only before refactor(runtime): unify durable model-context projection authority #4350), so the inlining served no real data. Removed with it: the archive preflight, archived-result reference discovery, archivedToolResultContainsConversationOwnedReferences, and the storage excludeArtifactIds copy option.
  • Runtime Host: prepareLinkedChildCopyReferences validates every retained child the same way and returns shared (only a revision's Graph children) and snapshots (all other children). The coordinator applies these the same way for every kind of copy, and the archived-tool-result gate is gone. Copy kinds now differ only in slice boundary, source-active admission, labels/intent, revision-family metadata and Todo inheritance.
  • Desktop is unchanged. When the Host still refuses a copy (session_busy, or operation_unavailable for unsupported content), Desktop shows the generic toast as before. Showing the reason needs logic in app-shell-turn-actions.ts / app-shell-revision-actions.ts, but the renderer architecture ledger freezes those files as root debt and assigns them to features/conversation. That migration is tracked in Desktop shows a generic failure when the Host refuses a Branch or edit-and-resend #5762.

Behavior change

  • Branches from turns with linked children, and revisions of sessions with ordinary subagents, now succeed. In the copy, those child results keep their summary and Artifacts (copied into the copy), but no longer link to the source's child Session. A revision still links its Agent Graph children.
  • A copy of a session with legacy archived tool results keeps them archived, now as ledger archives of the copied events. Branches and revisions no longer refuse them, and side conversations no longer expand them inline, so a copy's context is never larger than the source's.

Fixes #5333
Refs #5762

Verification

  • session-revision-two-client-uds.test.ts (real Host over UDS; fails on main, passes here):
    • The branch of the Agent Graph source commits.
    • The seed now also has an ordinary subagent with a terminal result. On main, the revision fails with Session revision requires a terminal result for every retained Agent Graph child. Here it commits.
    • The archived-owned source now seeds a v1 archive the way refactor(runtime): unify durable model-context projection authority #4350–feat(runtime): archive tool results through durable ledger refs #4987 builds wrote it (projection transition + Artifact). On the previous head its branch rolled back with Conversation copy is missing Artifact archived-owned-result. Here it commits.
    • After Host restarts, the side conversation, branch and revision ledgers all have the ordinary subagent result as a snapshot (no childSessionId / runId, Artifact readable inside the copy). The revision still shares its Graph child. In both the branch and the side conversation, the archived result's copied transition is a rewriteVersion 2 ledger archive of the copied event, with no Artifact id and a body digest that matches the copied snapshot.
  • session-revision-graph-references.test.ts: a new test covers that only a revision shares Graph children and that every other kind / child pair is a snapshot. conversation-copy.test.ts was migrated to the single map shape and covers snapshots, validation of shared-child ids, and legacy archive transitions rebuilt over the copied event (chained and rival roots).
  • Full workspace suites:
    • @maka/runtime-host: 2143 pass. 2 failures: sandbox Bash, which also fails on the root main build, and the real-model implementation child patch test, which timed out under suite concurrency and passes when run alone.
    • @maka/runtime: 3619 pass. 7 failures, all in filesystem-worker-smoke, which also fails on the root main build. Both sandbox failures are environmental (macOS sandbox inside the agent shell).
    • @maka/storage: 1457 pass.
  • @maka/storage / @maka/runtime / @maka/runtime-host typecheck, npm run format, npm run lint, knip for storage/runtime/runtime-host: no new findings. check-renderer-architecture passes against the base.
  • Not run: E2E (left to CI) and a live Desktop run against a real Session with subagents.

AI use

Select exactly one:

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Tool(s) and scope: Devin wrote the diagnosis, implementation, tests and verification.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

A branch from any turn that retained a linked child Session always failed
with "Ordinary branches cannot share linked child Session ownership with
their source". The invariant is right: a branch has its own lifecycle, so
it must not hold child Run/Artifact identities owned by the source
revision family. But rejecting was not the only way to keep it.

Side conversations already solve the same problem: they validate that
every retained child is terminal, copy the child Artifacts into the new
Session, and drop childSessionId/runId from the copied results. Branches
now take that same snapshot path; only revisions keep sharing child
ownership. The archived-tool-result gate for branches is unchanged.

Refs apache#5333

Generated-by: Devin
When the Host refused a branch (session_busy or operation_unavailable),
the IPC handler rethrew the RuntimeHostOperationError. Electron IPC drops
the error class and code, so the renderer could only show "Operation
failed, try again later" -- misleading for a refusal that retrying will
not fix.

Side conversations already got a structured { ok: false, reason } result
for these two codes. Ordinary branches now use the same result, so the
branchFromTurn bridge has one return shape instead of two overloads, and
the turn footer action shows a branch-specific title and a reason for
each code.

Refs apache#5333

Generated-by: Devin
@github-actions github-actions Bot added the effort/M Under 500 readable lines label Sep 27, 2026
…copy

The copy code chose linked-child handling by copy kind: branches rejected
(until the previous commit), side conversations snapshotted, revisions
shared Graph children and rejected everything else, and a separate gate
rejected owned references inside archived tool results for branches and
revisions only. Each kind therefore failed on its own subset of sessions;
edit-and-resend still always failed once an ordinary subagent had run.

The invariant behind all of it is a single one: a copy may share a child
only when the copy's own lifecycle keeps that child alive. Agent Graph
children retire with their root's revision family, so a revision shares
them. Ordinary subagents are independent Sessions that can be removed on
their own, and branches and side conversations have their own lifecycle,
so every other retained child is copied as a terminal snapshot.

- conversation-copy: the reference map is one shape with sharedChildren
  and inlinedArchives; reject / snapshot / preserve_validated modes and
  the production-unused preserve_external variant are gone.
- prepareLinkedChildCopyReferences returns shared and snapshot children;
  revision no longer rejects ordinary subagents.
- The archived-tool-result gate is gone: every copy inlines archives that
  hold references it cannot share, as side conversations already did.

Behavior change: revisions of sessions with ordinary subagents now succeed
with those results as snapshots, and branches/revisions whose archived
tool results hold owned references now inline them instead of failing.

Refs apache#5333

Generated-by: Devin
Edit-and-resend still rethrew Host refusals, which Electron IPC reduces
to a message the renderer can only show as "Operation failed, try again
later". Branch and revision now return the same structured copy result
from one preload invoker, and both actions show the reason from one copy
table (copyFailures) under their own title. Refusals are expected
outcomes, so they use an info toast instead of the error toast.

Refs apache#5333

Generated-by: Devin
@Astro-Han Astro-Han changed the title fix: let branches snapshot linked child results and explain refusals fix: one linked-child rule for every conversation copy Sep 27, 2026
…migration

Reverts 6228364 and 2182242. Showing the reason for a refused branch or
edit-and-resend needs logic in app-shell-turn-actions.ts and
app-shell-revision-actions.ts, which the renderer architecture ledger
freezes as root debt (token, import and bridge counts may only shrink).
The ledger already assigns both files to features/conversation; doing that
move properly needs a conversation session-copy port, new homes for the
legacy helpers they import, and render-prop wiring for the revision draft
in AppShell. That migration is tracked separately so this change stays the
Host fix.

Refs apache#5333

Generated-by: Devin
@Astro-Han Astro-Han changed the title fix: one linked-child rule for every conversation copy fix(runtime-host): one linked-child rule for every conversation copy Sep 27, 2026
@Astro-Han
Astro-Han marked this pull request as ready for review September 27, 2026 13:48
@github-actions github-actions Bot added effort/L Under 1000 readable lines and removed effort/M Under 500 readable lines labels Sep 27, 2026

@hqhq1025 hqhq1025 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed exact head e9c7d10a0768d6b3a0a4df14e1f3fdb52f61ce4a (6 files, +403/-585). The change replaces copy-kind-specific linked-child modes with one validated split: revision copies share terminal Agent Graph children; branches, side conversations, and ordinary subagents copy terminal result snapshots. It also lets branch/revision copies inline legacy archived tool results instead of refusing them. I found one P2 capacity boundary in that new inlining path (inline comment). Please bound the aggregate expanded turn or preserve a target-owned archive representation before merging.

I traced the full production diff, admission/terminal and Artifact checks, revision-family retirement, copy rollback, legacy archive rewriting, and the focused/UDS tests. The shared Graph child remains in the revision family that retirement removes together; snapshot child IDs are removed and available Artifacts are copied under the target. The tests cover these ordinary cases, but not multiple large archived results or retirement after a copy. No remaining production use of the removed preserve_external mode was found. No schema or protocol migration is introduced.

Current-head hosted test and label succeed; a fresh-main (592d2d4d) merge-tree and git diff --check are clean. GitHub reports MERGEABLE/BLOCKED. I did not run local suites (Node 18, no dependencies), a live Desktop/Host session, or a large-archive reproduction; the capacity finding follows the cited code path and fixed limits. This is a COMMENTED review, not approval.

Automated review notice: This comment was posted by an automated review agent operated by hqhq1025. It is not an independent human review and does not replace one.

input.sourceSessionId,
linkedReferences.shared,
),
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Bound the aggregate size of legacy archived results before inlining them into one copied Turn. This filter can admit multiple v1 archived linked-child bodies independently: #readArchivedToolResults verifies each body against its own originalBytes (:652-671), while rewriteArchivedSnapshot expands each into a full function_response (conversation-copy.ts:1945-1962) and the copy commits them. A source Turn with two valid ~9 MiB archived subagent summaries is readable as small placeholders, but a branch/revision now embeds >18 MiB of results in its copied Turn. session-transcript-reader.ts:617-621,562-571 rejects any Turn above 16 MiB, so the committed copy cannot be paged/opened. The new UDS test uses only tiny archive bodies. Please enforce a combined presentation bound or keep oversized snapshots in a target-owned archive; I have not run this large-body scenario locally.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, the capacity path was real: nothing bounded the combined inlined bodies, and the copy committed before anything read the Turn back. Rather than add a bound, c3c8465 removes the inlining. No shipped build persisted a v1 placeholder inside a RuntimeEvent result (pruning was replay-only before #4350), so the only durable v1 archives are the projection transitions that #4350–#4987 builds wrote, and their events still hold the full result. For those, inlining was also broken on its own: the archive Artifact was excluded from the copy while the transition clone still rewrote its id, so the copy rolled back with missing Artifact (reproduced in the UDS test on e9c7d10). Every archive transition is now rebuilt as a ledger archive of the copied event, the path v2 archives already took, so the copy keeps the result archived, carries no source child ids, and is never larger than the source. The archive preflight, inlinedArchives, archived-result reference discovery and the storage excludeArtifactIds option are gone.

@zhiiw zhiiw left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bound to e9c7d10a0768d6b3a0a4df14e1f3fdb52f61ce4a (re-checked against GitHub immediately before posting, unmoved). Not draft; CI label + test green on this head. Real Windows machine, Node 24.18.1.

No P0–P2, no P3, no inline comments. The one-rule shape ("only revision-Graph children share; everything else snapshots") is pinned from both directions I could ablate on this machine.

Suites on this head (Windows) and attribution

  • runtime-host session-revision-graph-references + session-revision-two-client-uds: 14 pass / 0 fail / 1 skipped — the UDS test is win32-skipped (skip: 'Windows SQLite shutdown lifecycle'). I force-ran it (scratch-patched skip, restored after): the two-client flow executes over named pipe for ~10.5s with no socket error and dies only at teardown on EBUSY: resource busy or locked, unlink runtime.sqlite — exactly the lifecycle the skip names. So on Windows it is runnable but not completable; neither its green nor an ablation red is observable here.
  • runtime conversation-copy: 16 pass / 13 fail, all 13 the same EBUSY unlink of a temp runtime.sqlite at teardown — the same Windows SQLite file-lock class as above. Zero assertion failures; the copy-logic assertions in those tests are not what fails. Environment, not this PR.

Ablations (each restored, rebuilt, re-verified green)

  1. Revision-shared Graph children made to snapshot too (session-revision-graph-references.ts:221, dropped the revision && parent.graph condition) → exactly the two revision-sharing pins go red: Agent Graph revision references preserve only exact terminal provenance and only a revision shares Graph children; every other retained child is a snapshot. The ten Side Conversation / validation siblings stay green, so the pin is scoped to the sharing rule, not the validation machinery around it.
  2. Snapshot reverted to reject (a non-shared retained child now returns operation_unavailable) → exactly only a revision shares Graph children; every other retained child is a snapshot goes red, plus Side Conversation validates the retained Graph instead of a newer live Graph (same cause — the snapshot path it exercises is now a refusal). The UDS test would catch this too (its previously-rejected branches now assert committed), but per above that red is not observable on Windows.

Read, no finding

  • The collapse of the reference map (exact/preserve_external/reject/snapshot/preserve_validated → sharedChildren + inlinedArchives) removes the two mode fields rather than adding a third branch, and the coordinator's copy path got shorter with it — the deleted refusal of owned references inside archived results is exactly the behavior the UDS test now asserts as committed, so the relaxation is test-driven, not silent.
  • rewriteConversationCopyMessage no longer gates assistant rewriting on mode === 'exact' — with only one mode left, the condition was dead weight; the rewrite still targets artifactIds the same way.
  • The two desktop presentation commits net out to zero (the second reverts the first, leaving refusal presentation to the conversation migration).

Not checked

UDS ablation evidence on this OS (skip is justified — see above), e2e, full repo suite.

UTC 2026-09-27 14:04.

Conversation copies expanded every legacy (rewriteVersion 1) archived tool
result that held conversation-owned references inline into the copied Turn.
Nothing bounded the combined size, and the transcript reader refuses a Turn
above 16 MiB, so a copy could commit a Session that cannot be opened.

That inlining never served a real archive. No shipped build persisted a v1
placeholder inside a RuntimeEvent result: before apache#4350 pruning was replay
only, and from apache#4350 to apache#4987 it wrote a projection transition whose event
keeps the full result. For those transitions the inlined archive was also
excluded from the Artifact copy while the transition clone still rewrote its
Artifact id, so the copy rolled back with "missing Artifact".

Every archive transition is now rebuilt as a ledger archive of the copied
event, the path v2 archives already take. The copied event holds the
snapshotted result, so the archive carries no source child identifiers and
needs no Artifact. This removes the archive preflight, inlined archives,
archived-result reference discovery and the Artifact copy exclude list.

Generated-by: Devin

@hqhq1025 hqhq1025 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-review of exact head c3c8465. The previous P2 expansion path is gone: legacy v1 projection transitions now become v2 ledger transitions over the rewritten RuntimeEvent (packages/runtime/src/conversation-copy.ts:1253-1305), rather than inlining archive bodies into copied messages. Also, the original P2 scenario was not established for shipped v1 writers: at #4350 the v1 placeholder was written in a model-projection transition, while the durable RuntimeEvent retained the full result; before that, stale pruning was request-only. I retract the prior claim that multiple shipped v1 placeholders could inflate a copied transcript Turn. The actual old failure was the excluded archive Artifact being required by transition cloning; the new v2 rebuild avoids that missing-map rollback.

The copied snapshot result is rewritten before the new archive digest is calculated (packages/runtime/src/conversation-copy.ts:558-578,1253-1270). Non-shared child identifiers are stripped by rewriteToolResultContent at :1793-1805; graph-shared child identifiers remain intentionally external. The v2 replacement names the target RuntimeEvent and has no source Artifact ID. Source-owned file/context and linked child Artifacts are still selected and mapped; one low-priority over-copy/failure case remains in the inline finding.

Validation: inspected the eight-file follow-up diff, the historical #4350 and #4987 writer paths, runtime copy and rollback flow, and current tests. No local suite or actual Host/Desktop run (Node 18 and no dependencies). Current-head windows_recovery succeeded; test was still in progress at publication. PR base merge-tree and diff-check were clean; current main advanced and a fresh-main local fetch failed, so I did not claim a fresh-main merge check. This is COMMENTED, not merge approval.

Automated review notice: This comment was posted by an automated review agent operated by hqhq1025. It is not an independent human review and does not replace one.

record.sessionId === input.sourceSessionId &&
turnIds.has(record.turnId) &&
!excludedArtifactIds.has(record.id),
(record) => record.sessionId === input.sourceSessionId && turnIds.has(record.turnId),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: The new v2 transition no longer needs its old v1 archive Artifact, but the turn-wide selection now copies every tool_result_archive record. For a retained v1 result whose archive metadata survives but payload is missing/corrupt, the raw RuntimeEvent is still available to rebuild v2, yet prepareRecordRead fails and the coordinator rolls back the whole branch/revision. A healthy source also duplicates the obsolete archive bytes in every copy. Repro: retain a v1 transition and raw result, remove only that archive payload, then branch the Turn. Please avoid making an unreferenced legacy archive a required copy input (while preserving any Artifact that historical content actually references), and cover this recovery case.

@zhiiw zhiiw left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bound to c3c846541cdc56407b5101e1f4b3cd7e10f6bcb9 (re-checked against GitHub immediately before posting, unmoved). Not draft; CI test + windows_recovery green on this head. Real Windows machine, Node 24.18.1.

No P0–P2, no P3, no inline comments. The inline→ledger-archive rebuild is pinned, and I got that pin to go red on a Windows-runnable test.

Suites on this head (Windows) and attribution

  • runtime-host session-revision-graph-references: 14/14 green.
  • runtime conversation-copy: 14/27 — all 13 failures are the teardown class: EBUSY: resource busy or locked, unlink <tmp>\runtime.sqlite(.-shm) in the test finally. Zero assertion failures at baseline; environment, not this PR (same class as the UDS skip).
  • The UDS two-client test remains win32-skipped. This round I went one step further than last: force-running it with the teardown made non-fatal (scratch, reverted) shows the flow then dies at a shutdown-lifecycle assertion — the host process exits SIGTERM where the test expects a clean code 0 — before the rewriteVersion: 2 / storage: ledger assertions. So the skip is precisely justified, and the UDS assertion phase is not reachable on this OS.

Ablation (restored, rebuilt, re-verified)

Reverting the rebuild to "keep the legacy placeholder verbatim" (conversation-copy.ts, the buildLedgerArchivedToolResultPlaceholder call in cloneModelProjectionTransition) → the Windows-runnable substitute test conversation copy retains archive reference closure and checkpoints (inspect: false) and (inspect: true) both go red with AssertionError (the rewriteVersion === 2 / bodySha-inequality assertions), with the teardown scratch-tolerated so nothing masks them. On the restored PR code the same two tests fail only with the teardown EBUSY — i.e. their v2 assertions pass. That is the same guarantee the UDS test's new rewriteVersion: 2 / storage: 'ledger' / artifactId: undefined block asserts, proven red-able on this machine.

Note for honesty: my first ablation attempt was invalid — a type-unsafe scratch edit blocked tsc emit, so the test silently ran the previous build. I caught it because the run was indistinguishable from baseline, redid the edit type-safely, and re-verified that the reported red is the assertion, not teardown.

Read, no finding

  • The commit's own justification for dropping inlining checks out in code: nothing shipped persists a v1 placeholder inside a RuntimeEvent result, and the inlining path had no size bound against the transcript reader's 16 MiB Turn limit. The rebuild reuses the exact v2 path (buildLedgerArchivedToolResultPlaceholder over the cloned event, digest re-derived from the clone), and an unmapped predecessor throws instead of silently rooting a successor — the failure direction stays loud.
  • Deletion completeness: the preflight, the Artifact exclusion list, and the inlinedArchives map are gone from the coordinator and the reference map together; artifact-store.ts sheds the exclusion hook. The corresponding test deletions (-235 in conversation-copy.test.ts, -30 in artifact-store.test.ts) are exactly the guards of the removed mechanism.

Not checked

UDS assertion phase on this OS (unreachable — see above), e2e, full repo suite.

UTC 2026-09-27 14:42.

@jackwener jackwener left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving at c3c846541cdc56407b5101e1f4b3cd7e10f6bcb9. No open P0–P2.

  • One linked-child rule: only a revision shares its Agent Graph children, which retire with the revision family; every other retained terminal child becomes a snapshot (source child id removed, surviving Artifacts copied under the target). Live children are refused. No production caller of the removed preserve_external mode remains.
  • The earlier aggregate-size P2 on inlined v1 archives is withdrawn: no shipped writer persisted a v1 placeholder inside a RuntimeEvent result (#4350–#4987 wrote projection transitions over full events; pre-#4350 pruning was request-only). c3c846541 rebuilds every archive transition as a v2 ledger archive over the copied event, which also closes the old reachable missing Artifact rollback.
  • Ablation: keeping the snapshot as reject, or letting revisions snapshot Graph children, reddens exactly the matching graph-references cases; keeping the legacy placeholder instead of rebuilding reddens the rewriteVersion === 2 assertions in conversation-copy.test.ts. On Windows the conversation-copy failures are all teardown EBUSY unlink runtime.sqlite (no assertion failures) and the UDS test is win32-skipped for the same SQLite lifecycle reason.
  • CI test and windows_recovery green.

Open P3 (non-blocking, inline 4115738504): the copy still duplicates legacy archive Artifacts that no v2 archive references. If such a payload is missing or corrupt, the whole branch/revision rolls back even though the copied RuntimeEvent is enough to rebuild the archive; when healthy it only costs disk and copy I/O. Worth excluding those Artifacts in a follow-up.

Not run: live Desktop/Host session, large-archive reproduction.

Reviews: #5757 (review) , #5757 (review)

@jackwener
jackwener merged commit 077f154 into apache:main Sep 27, 2026
2 checks passed
@Astro-Han
Astro-Han deleted the fix/5333-branch-linked-children branch September 27, 2026 15:11
sunrioa added a commit to sunrioa/maka that referenced this pull request Sep 28, 2026
Resolve the import conflict in session-revision-coordinator.ts: main
(apache#5757) dropped the unused RuntimeEvent import, and this branch adds the
session-name and ExecutionBoundary imports its branch-title code uses.
Keep both sides. The branch's net change against main is unchanged.

The staged protocol-epoch hook compares the merge with the old branch
tip and flags protocol files that arrived from main; the CI-mode check
against main is run on the merge commit instead.

Generated-by: Claude Code
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/L Under 1000 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Branching a session with linked child sessions consistently fails

4 participants