Skip to content

fix(verification): bind verified.type_check records to file content - #133

Merged
alpibrupa merged 1 commit into
mainfrom
verified-content-binding
Sep 5, 2026
Merged

fix(verification): bind verified.type_check records to file content#133
alpibrupa merged 1 commit into
mainfrom
verified-content-binding

Conversation

@alpibrupa

Copy link
Copy Markdown
Contributor

Summary

  • verification.Record had no binding between a recorded pass and the content it was a pass of — only kind + target. Since the log is append-only and project-scoped (by design, per feat: auto-attestation pipeline — write trail records when verification passes #32), a passing record from an earlier session or a since-reverted edit stays in .lex/verified.jsonl forever, and task_spec.lex's old seen/seen_on only checked whether any matching record existed, never whether it still applied.
  • Reproduced live in verified.type_check has no binding to file content, so a stale pass outlives the edit that broke it #91: a stale verified.type_check record from an unrelated, older, successful run satisfied a task-spec criterion for a file whose current content failed lex check in the very same report.
  • Record gains sig :: Str — a sha256 of the target's content at the moment the record was made:
    • linter.record_verified (the write/edit implicit-check path from Write's implicit lex check never reaches the attestation trail, so a correct fix can still fail verification #90) hashes the file right after it just passed lex check — the freshest possible signal.
    • verification.harvest (the session-log path for the standalone lex_check tool, via dispatch_one_traced) hashes the target right after the turn that produced the record, since the session-log event itself never carried file content.
    • A record naming a target with no sig (legacy, or unhashable), or with a sig that no longer matches the target's current bytes, does not count as seen.
  • task_spec.lex's seen/seen_on become presence/presence_on, returning a three-state Absent | Fresh | Stale instead of a bool — a stale record now reports "a record exists but no longer matches the file's current content — re-run the check," distinct from "no record at all," so a reader knows which situation they're in.

Fixes #91

Test plan

  • lex check on all three modified files, plus a full repo sweep (lex check over every tracked src/ file)
  • lex fmt --check src/
  • lex test (4/4 passing)
  • lex doc-sync --check
  • Live repro of verified.type_check has no binding to file content, so a stale pass outlives the edit that broke it #91's exact scenario in a fresh git worktree: wrote a file via the real write tool (fresh, hash-backed record) → task spec reports SATISFIED; then edited the file out of band (bypassing write/edit, simulating a stale leftover record) → task spec now reports NOT SATISFIED with "a verified.type_check record exists for verify_target.lex but it no longer matches the file's current content — re-run the check", correctly distinguishing "stale" from "never checked"

🤖 Generated with Claude Code

verification.Record had no link between a recorded pass and the bytes
it was a pass of — only kind + target. An append-only, project-scoped
log means a passing record from an earlier session or a since-reverted
edit stays in .lex/verified.jsonl forever, and task_spec.lex's seen/
seen_on only checked whether a matching record existed anywhere, not
whether it still applied. Reproduced live in #91: a stale record from
an unrelated successful run satisfied a task-spec criterion for a file
whose current content failed lex check in the same report.

Record gains sig :: Str, a sha256 of the target's content at record
time. linter.record_verified (the #90 write/edit path) hashes the file
it just checked; verification.harvest (the session-log path for the
standalone lex_check tool) hashes the target right after the turn that
produced the record, since the session-log event itself never carried
content. A record naming a target with no sig, or a sig that no longer
matches the target's current bytes, does not count as seen.

task_spec.lex's seen/seen_on become presence_on/presence, returning a
three-state Absent | Fresh | Stale rather than a bool, so a stale
record reports "checked before, but the file has changed since" rather
than being indistinguishable from "never checked."

Fixes #91

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@alpibrupa
alpibrupa merged commit 8038d0d into main Sep 5, 2026
1 check passed
@alpibrupa
alpibrupa deleted the verified-content-binding branch September 5, 2026 13:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

verified.type_check has no binding to file content, so a stale pass outlives the edit that broke it

1 participant