Skip to content

canonical_review.py record Has No Lock, So Two Concurrent Records Lose One Pass #1151

Description

@ptr727

scripts/canonical_review.py's record is a read-modify-write of a tracked ledger with no lock, where its sibling scripts/local_review.py guards its own receipt write with held_lock and break_stale_lock.

The shape

cmd_record reads reports/canonical-review.json through read_ledger, merges the new entries into that dict, and writes the whole file back through write_ledger, then regenerates reports/canonical-review.md from the ledger it just wrote. Two record invocations overlapping lose one of the two passes: the second read happens before the first write lands, so the second write carries only its own entry merged onto the stale copy. The write_report that follows can also render counts from a ledger state that never existed on disk.

One record per unit is the shape the local-strict-review Skill's own loop suggests, so the overlapping case is reachable rather than theoretical, most obviously where a driver fans the passes out and records each as it returns.

Why it is not urgent

It fails closed. A lost record leaves that unit uncovered, so the next check refuses the push and names it, and the remedy is another pass and another record. Nothing false is recorded, and no push goes out claiming coverage nobody produced. The cost is a wasted pass rather than a wrong verdict, which is why this is filed rather than fixed in #1148.

Two ways to close it

Either reuse local_review.py's lock helpers, which already handle the stale-lock case and are tested, or make the documented loop a single invocation, since record already takes a repeatable --unit KEY=DIGEST and one call carrying every pair has no interleaving to lose. The second is smaller and removes the shape rather than guarding it, and the two are not exclusive.

How it was found

A delegated local-strict-review diff pass over #1148, which reproduced it rather than reasoning about it.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    scriptA defect in hub tooling

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions