Skip to content

v0.10.5

Choose a tag to compare

@wdhwg001 wdhwg001 released this 04 Sep 12:01
· 23 commits to main since this release

A correction release. A reviewer pointed out that the ledger shipped with drift verdicts nobody acted on, and that its verifiers had learned to stop at an honest report. Both were true. This release fixes the four csift defects those verdicts named, corrects four statements csift printed or taught, and changes the ledger's gate so that neither can ship again.

What was wrong in csift

image joined the #N handle to the image blocks by position. A record's imagePasteIds lists the ids in the order of its image blocks, while the [Image #N] markers keep the order the operator typed them in. The two orders differ on 18 of 662 records in the reference corpus, and each of those got a silently wrong handle. The join is now by number, with the positional zip kept only for records that carry no id array.

recover replayed a Read echo that carries no text. Claude Code blanks the text of a tool result older than its retention window before persisting it, leaving the line counts intact. The reference corpus holds 320 such echoes, and four result arms never carry a text at all. A blanked echo of a complete read used to pass the whole-file test and replay as a snapshot of nothing, replacing known content. Such an echo is now counted as a blanked read with a soft annotation boundary, and nothing is replayed from it.

The status and wait pid probe ran ps with whatever locale the caller had. A German or French locale renders the start time with names no English pattern parses, and the pid-reuse guard was silently skipped on those hosts. The probe now pins LC_ALL=C and TZ=UTC on its own call, exactly as Claude Code pins its own acquisition of the same value.

Every search hit now carries refetch_uuid beside refetch. A line number is a durable address only while the transcript is append-only, and three Claude Code paths rewrite a live transcript in place. The uuid survives them.

What csift said that was not true

TaskStop resolves a teammate by its name or by name@team from Claude Code 2.1.198. The agents footer, the JSON control hint, the SKILL rows and the hook recipe all said it rejects every form, which was true on the build of the original incident and false since. A live trial at 2.1.258 confirmed the correction: the bare name stopped the teammate, the name@team form resolved it, and the aName-<hex> transcript id csift prints was the only form that missed.

The file-history checkpoint store is written by the structured file tools and by an approved in-place sed preview. The recover --list-backups banner, its help and its module doc said bash edits never land there. A live trial in default permission mode showed the preview dialog rendering the sed as a file edit, the checkpoint taken at approval, and a tool result indistinguishable from a real run.

Whether a pending AskUserQuestion reaches the transcript while its dialog is open is a timing outcome of Claude Code's write frontier, not a rule keyed on the question count, and not something that changed at 2.1.258. A comment, a user-facing note, the help and three documents said otherwise. The two measurements stand as measurements.

The registry row writer stamps procStart on every platform. The two-key procStartFt schema belongs to the .key companion file. A comment in csift's registry reader had attributed it to the row. A Windows trial read the companion: it holds a peer token, the start time as a tick count and the pid domain, and a print-mode session writes only the companion, no row.

The ledger

The gate gained three rules. A claim's latest check can no longer be drifted: the fix or the retirement has to append its own check after the drift, so a ledger whose last word on a claim is a drift cannot be released. No open leg may be an unconsumed text correction or a record of a rejected rewrite, because both mean a refuted text is still shipping. And every claim below end-to-end has to carry both attribution legs, so the derivation always runs.

The attribution set gained upstream: the producer lies outside the shipped binary by construction, on the model or API side, in the operating system, or in a native runtime binding, while the client-side treatment is traced and a specimen observed. A search that failed is never upstream.

The round that produced this release traced or reframed every claim whose producer was incomplete. The table in the README is regenerated from the ledger and checked by the gate. Where it stood before and where it stands now:

attribution before now
end-to-end 382 470
producer-only 33 33
upstream 0 14
specimen-only 105 5
partial-producer 2 0
by-elimination 0 0

Every one of the 470 carries its three hops as verbatim excerpts at byte offsets, and every one was re-read by an adversarial verifier that had to catch a planted fake first. Forty-two fakes were planted across the round and forty-two were caught.

The ledger's text now follows a prose law: no calendar dates, no csift version numbers, no narrative about the audit that produced a sentence. The commit and the release carry those. The README's verification section states what this project will never publish and why the ledger is re-verified periodically rather than for every Claude Code release.

Verification

The suite runs 1046 unit tests and 552 end-to-end tests on every commit through the pre-commit gate, which also runs the ledger gate by name. Line coverage measured 95.79 percent (889 of 21129 lines missed), holding the 0.10.4 baseline. A scoped mutation run over the eight changed files tested 363 mutants: 326 caught, 1 killed by timeout, 14 unviable and 22 survived. Five of the survivors were real gaps in code this release touched, in the image walk and in the read-event arithmetic. Two new unit tests kill them, and a targeted re-run confirms all 22 viable mutants in those two functions are now caught. The remaining seventeen sit in zones classified in earlier rounds: the prefilter widening and the base64 decoder, the buffer-disagreement threshold, the background-append arm, and the Windows and fallback bodies of the pid probe, which this host does not compile and which were exercised live on a Windows guest instead.

The ledger's own checks were written claim by claim. Every claim below end-to-end names the instrument that would close it, and the live trials this round ran on this machine closed seventeen such legs: a permission dialog held open while the registry row and the transcript were read, a NotebookEdit call, an escape recall that was never resent, a subagent that backgrounded a shell which completed while it still ran, TaskStop against a live teammate in three id forms, a scheduled task firing, an in-place sed approved through its preview, csift's own probe inside a BusyBox container, and on a Windows guest a session started under a divergent HOME, the companion key file of a running session, and the process queries by hand for a live and a missing pid.

Eight targets were built at the tag and ran the full suite on their own platform.

The four Linux lanes (glibc and musl, x86_64 and arm64) ran in the official rust:1.89 containers, 1046 unit and 552 end-to-end tests each. The two Windows lanes (arm64 native, x64 emulated) ran on a Windows 11 ARM64 guest, 1045 and 551, the missing two being the unix-only pid probe and its locale pin. The two macOS binaries were built with path remapping and smoke-tested. Every artifact was audited for machine-path strings and the Windows executables for a dynamic C runtime, all clean. The packaged documentation is byte-equal to the tag.