Skip to content

fix(runtime): re-authenticate a copied paging Read with its dispatch - #5466

Open
ggbdpq wants to merge 1 commit into
apache:mainfrom
ggbdpq:fix/revision-copy-canonical-hash
Open

ggbdpq wants to merge 1 commit into
apache:mainfrom
ggbdpq:fix/revision-copy-canonical-hash

Conversation

@ggbdpq

@ggbdpq ggbdpq commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #5329

Editing an earlier message fails with canonical_args_hash_conflict whenever the model paged a truncated tool result: the ledger clone rewrites a copied Read/ArchiveRead call's args to name the copied tool result, but the paired tool_dispatch event was copied verbatim and kept the hash of the source's args. The copy then fails its own T1 re-scan (importConversationCopyRuntimeEventsscanToolLedger), and every revision retry is refused as a corrupt ledger — while the source Session's ledger is, in fact, fine.

The fix lives where the rewrite happens: during the identity-rewrite pass, the clone records the rewritten args per (invocation, tool call) and re-authenticates the paired dispatch's canonicalArgsHash, so the copied ledger authenticates the args it actually carries. Dispatches without a recorded hash keep their shape. The existing copy tests never caught this because their Read calls had no paired tool_dispatch event, leaving the scanner nothing to compare.

Verification

Check Result
New regression test (clones a ledger whose paging Read is paired with a dispatch that authenticated the source args) fails with the issue's exact canonical_args_hash_conflict before the fix; passes after, with the dispatch hash equal to the rewritten args
Full conversation-copy suite 15/15 pass on this branch; the 13 failures seen locally fail identically on clean upstream/main in this environment (Windows sqlite-cleanup EBUSY in test cleanup, one per failing test) — CI is expected to run them clean
biome check on both touched files clean

AI use

Implemented with GLM-5.3-Flash (ZCode); the reproduction, fix, and tests were verified locally as described above.

Checklist

  • The patch targets the shared clone path, not one caller's symptom
  • A regression test pins the issue's exact failure mode (paired dispatch present)
  • No new dependencies; one helper import from the existing @maka/core/tool-args-identity
  • Local environment caveats disclosed above (13 EBUSY cleanup failures pre-exist on clean upstream locally)

Editing an earlier message fails with canonical_args_hash_conflict
whenever the model paged a truncated tool result. The ledger clone
rewrites a copied Read/ArchiveRead call's args to name the copied tool
result, but the paired tool_dispatch event was copied verbatim and kept
the hash of the source's args — so the copy failed its own T1 re-scan
and every revision retry was refused as a corrupt ledger.

Record the rewritten args per (invocation, tool call) during the
identity-rewrite pass and re-authenticate the paired dispatch's
canonicalArgsHash, so the copied ledger authenticates the args it
actually carries. Dispatches without a recorded hash keep their shape.

The new regression test clones a ledger whose Read points at a copied
tool result and whose dispatch authenticated the source args: it fails
with the issue's exact canonical_args_hash_conflict before the fix and
passes after, with the dispatch hash equal to the rewritten args.

Fixes apache#5329

Generated-by: GLM-5.3-Flash (ZCode)
@github-actions github-actions Bot added the effort/M Under 500 readable lines label Sep 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/M Under 500 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Revise before turn fails with canonical_args_hash_conflict after the model paged a tool result

1 participant