Three per-event costs leave the fold: every state-changing event shallow-copied
all seven retained collections, every event re-scanned the retained requests to
count turn runs, and every tool call stringified its arguments even when the
tool can never row a file op. Cloning now follows the branch's own mutation
list, the run count rides an incremental ledger (recomputed only where a trim
replaces the array), and raw arguments are kept only where they are read.
Measured over 279 real sessions (282,783 events): the fold drops 16.8% corpus
wide, ~51% on V3-shaped logs and ~57% on sessions at the retention caps, with
state output field-identical apart from the new optional `turnRuns` field and
the intended `argsRaw` omission. `stateVersion` is unchanged, so cached rows
keep parsing and stay usable.
The Windows check rode along: `path.relative` returns an ABSOLUTE path across
drives, so the old `..`-prefix test read a foreign drive's module as a child of
the plugin's own tree and degraded version detection; `!isAbsolute(rel)` closes
it.
Review follow-up on top of the original six-file change:
- an absent `timing` slot stays absent. The selective clone materialized
`timing: undefined`, which is not losslessly JSON-serializable, so
`snapshotJsonValue` rejected the whole checkpoint: every projection-cache
write for that session was skipped, and a log ending on an unpaired
`tool/result` never got a cache row at all — every reopen then paid the full
cold fold this change set aimed to cut;
- the no-`undefined`-member rule is now pinned on every intermediate fold
state, not only the last one — the gap that let the above ride through a
green suite, since reading the slot cannot tell an absent key from an
`undefined`-valued one;
- the "which tool needs its raw arguments" gate moved beside the file-op
parser (`opBearingTool` / `rawArgsNeeded`), so the fold no longer restates
the tool list.
Verified: `pnpm run lint:fix && pnpm run test && pnpm run build` green (1763
tests, per-file coverage 100%), plus a field-level diff of the fold over
282,783 real events (no divergence beyond the intended deltas), the
incremental ledger cross-checked against a full scan on every event including
both trims, and a frozen-predecessor run proving no in-place write.
Co-authored-by: Nwflower <1679659@qq.com>