Deferred from the v0.9.6 release review (Tech Lead persona, P2).
Context
The v0.9.6 truncation-cleanup bug (#1112, fixed in #1113) had to be patched in two near-identical modules:
packages/opencode/src/tool/truncate.ts — Effect service (modern path)
packages/opencode/src/tool/truncation.ts — legacy module (used by bootstrap, bash, prompt)
Both compute the same mtime-based aging cutoff, both handle stat-failure the same way (fail-safe: keep the file), both were subject to the same 48-bit-ID timestamp-wrap bug because they were both computing cutoffs from decoded Identifier timestamps.
What to do
- Extract the mtime-aging cleanup into a shared helper (e.g.
packages/opencode/src/tool/cleanup-common.ts or similar), used by both modules
- Remove the duplicated stat/mtime/fail-safe logic from
truncate.ts and truncation.ts
- Ensure the regression test in
packages/opencode/test/tool/truncation.test.ts exercises the shared helper (both direct and via each module's public API)
Pre-existing duplication, not introduced by #1113 — but the #1113 fix touched both files without consolidating them. Consolidating now costs one refactor; leaving it means the next truncation-cleanup change has to be applied twice again.
Priority
P2 — no user impact, but a footgun for the next contributor working in this area.
Deferred from the v0.9.6 release review (Tech Lead persona, P2).
Context
The v0.9.6 truncation-cleanup bug (#1112, fixed in #1113) had to be patched in two near-identical modules:
packages/opencode/src/tool/truncate.ts— Effect service (modern path)packages/opencode/src/tool/truncation.ts— legacy module (used by bootstrap, bash, prompt)Both compute the same mtime-based aging cutoff, both handle stat-failure the same way (fail-safe: keep the file), both were subject to the same 48-bit-ID timestamp-wrap bug because they were both computing cutoffs from decoded Identifier timestamps.
What to do
packages/opencode/src/tool/cleanup-common.tsor similar), used by both modulestruncate.tsandtruncation.tspackages/opencode/test/tool/truncation.test.tsexercises the shared helper (both direct and via each module's public API)Pre-existing duplication, not introduced by #1113 — but the #1113 fix touched both files without consolidating them. Consolidating now costs one refactor; leaving it means the next truncation-cleanup change has to be applied twice again.
Priority
P2 — no user impact, but a footgun for the next contributor working in this area.