Skip to content

feat(asvs): tell a re-score apart from a re-verification, and read the 28 flagged entries (BACKLOG #1328) - #882

Open
wshallwshall wants to merge 2 commits into
mainfrom
claude/asvs-rescore-1328
Open

feat(asvs): tell a re-score apart from a re-verification, and read the 28 flagged entries (BACKLOG #1328)#882
wshallwshall wants to merge 2 commits into
mainfrom
claude/asvs-rescore-1328

Conversation

@wshallwshall

Copy link
Copy Markdown
Collaborator

What this is

BACKLOG #1328's stated remainder was reading the 28 entries its 2026-09-03 run flagged. That reading is done, and the answer is three items, not 28. The item's closing act is code, and the code here is what the reading justified.

The run

The check already shipped, so nothing was rebuilt. Verified first: tests/test_asvs_rescore_handoff.py passed 29 of 29 on arrival (the row says 21; the file has grown since).

The 2026-09-03 numbers no longer reproduce, because the environment moved. The shared clone re-shallowed overnight: the graft boundary went 2026-08-04 to 2026-08-31, visible history fell to 110 commits, and the two ledger walks fell from 335 and 13 revisions to 76 and 2. Every pair in the record is dated at or before 2026-08-29, so the tool refused, correctly, deciding nothing. A screen that refuses the only environment it ships into is the exact failure this row already recorded once.

The remedy is not the owner-gated one the row assumed. git fetch --unshallow is the owner's call because it writes to an object store shared by every worktree, 3.7 GB here. A throwaway clone shares no object store, so that objection does not reach it, and --root already takes a separate history source. Measured: 35 MB in 17 seconds. Do not pass --filter=blob:none -- a blobless clone fetches one ledger revision per network round trip and did not finish in ten minutes.

Against that clone the run is strictly better than 2026-09-03's: 62 pairs over 48 items, zero undecidable pairs and zero floored dates, where the earlier run held 11 back.

The reading

35 hits over 28 distinct items, 11 open banners and 17 closed, matching the row exactly.

22 of the 28 items carried no covering grade change at all. last_verified bumps on a re-check that confirmed the grade already there, so the date comparison fires on confirmations as loudly as on real re-scores -- an instrument answering a question adjacent to the one asked (SDS-3.8). Classifying by grade movement cuts the reading burden to 6 items, and those 6 were read.

Survives reading -- three, all missing-flip direction, all closing-act: scorecard-rescore:

Item Why it survives
BACKLOG #1172 Its own banner says the row stays open only because the re-score "is explicitly not run". That re-score landed 2026-08-26, the day after. Cleanest instance this row has produced.
BACKLOG #1127 Covering grade moved to a pass 2026-08-26, after the banner. The banner's stated remainder is a durability concern written before that re-score.
BACKLOG #1184 Same shape, but its prose still describes the defect as live and high-value. The direction to fix is the Tracker's call, not an automatic flip.

Dissolved on reading: 25 of 28. Three worth naming: BACKLOG #1026 is this row's own worked negative case and behaved exactly as predicted (closing act is code, and the two records agree). BACKLOG #31 and BACKLOG #1042 are closed banners whose grade moved UP after closure, which is a strengthening.

Zero re-opens. Only two downward grade transitions exist in the entire scorecard history. BACKLOG #65's predates its banner's last touch; BACKLOG #1049's reverted and recovered inside one day, ending at the grade its closure rested on. No closed banner rests on a withdrawn premise.

Two disagreements the date rule structurally cannot see, found by reading rather than by the screen: BACKLOG #1148's grade moved to a pass on the SAME day its banner moved, and same-day is the in-sync convention every comparison here uses; BACKLOG #1143's grade has passed since 2026-08-01, before that item's banner ever moved. The screen detects ordering, not disagreement. That is a different screen and it is unfiled -- named by subject, not by a number I have not allocated.

The code

  • grade_history + classify mark each hit GRADE MOVED, GRADE MOVED DOWN or GRADE UNCHANGED. Direction only: no cell id and no grade value is ever printed.
  • classify refuses a clean UNCHANGED against a graft-floored banner date. The inequality that makes a floored date safe in evaluate runs the other way here, and reusing it unexamined inverted the answer to the reassuring side.
  • The summary counts three buckets. Counting everything not-UNCHANGED as moved reported a hit whose history could not be read as the strongest possible signal.
  • split_by_boundary also decides a pair whose item has a measured post-graft touch. Measured gain: one pair at the 2026-09-03 boundary, none at 2026-08-31 -- stated rather than implied. It is here because calling a measured date undecidable is a wrong answer.
  • GRADE_RANK is pinned against scorecard.VERDICTS, so a seventh verdict fails at import rather than rendering a downgrade as a neutral move. BACKLOG #1012 is the same drift one list earlier.

Constraints honoured

No cell-to-item map was built or proposed. No scorecard content appears in this repo -- the output is item numbers, dates and a direction. Every backlog citation uses the literal BACKLOG #N form, so none can be read as a PR number.

Checks

Check Result
ruff check . pass
ruff format --check . pass, 1241 files
mypy messagefoundry pass, 267 files
mypy scripts/asvs/rescore_handoff_check.py pass
pytest tests/test_asvs_rescore_handoff.py 43 passed (29 on arrival, 14 added)
pre-commit on all changed files pass, incl. ledger gate and bandit
scripts/docs/backlog_status_check.py pass, 664 items
Real run against the vault record exit 0, reproduced twice

/simplify ran as four review agents. Their findings are applied, including two genuine defects in code written in this PR: the floored-date inversion and the three-bucket count.

Left undone

  • The three flips are a ledger act this seat does not perform, so #1328 stays OPEN. Closing it is the Console's call once they land.
  • A measured efficiency win not taken: git cat-file --batch would cut the walk from about 54s to 2.4s, verified byte-identical. It touches both walks in this file, which is wider than this diff should be.
  • Items 246, 274, 296, 301 and 314 are referenced by the record but absent from every ledger revision walked, up from the two the row recorded.

Assumption stated

I could not reach the owner, so I read the history from a throwaway clone in the session scratchpad rather than deepening the shared store. That touches no shared state and is removed by deleting one directory. The shared object store was not modified.

🤖 Generated with Claude Code

wshallwshall and others added 2 commits September 4, 2026 18:48
…ff screen (BACKLOG #1328)

The date comparison fires whenever a cell's last_verified moves, and that bumps on
a re-check that CONFIRMED the grade already there. So the screen answered a
question adjacent to the one its own title asks (SDS-3.8).

Measured against the vault record at engine a2eef0f: 35 hits over 28 items, of
which 22 items carried no covering grade change at all after the banner moved.
Four in five prompts were confirmations, each costing a reader the full two-record
read the item demands.

grade_history reads the scorecard's own git history and classify marks each hit
GRADE MOVED, GRADE MOVED DOWN or GRADE UNCHANGED, cutting the reading burden from
28 items to 6. It prints a direction and never a grade value; cell ids and grade
values stay vaulted.

Also here:

- classify refuses a clean UNCHANGED against a graft-FLOORED banner date. The
  inequality that makes a floored date safe in evaluate runs the other way here:
  evaluate asks whether one point clears the date, classify asks what survives
  above it, so a later date deletes change points and turns a real move into a
  confident confirmation.
- The summary counts three buckets, not two. Counting everything that was not
  UNCHANGED as moved reported a hit whose history could not be read as the
  strongest possible signal.
- split_by_boundary also decides a pair whose ITEM has a measured post-graft
  touch, since the graft cannot raise a date the walk already measured. Measured
  gain is one pair at the 2026-09-03 boundary and none at 2026-08-31, stated
  rather than implied.
- The truncation refusal now names a separate throwaway clone. It shares no
  object store, so the objection that makes deepening the shared one an owner
  decision does not reach it, and --root already takes a history source.
  Measured 35 MB in 17 seconds against 3.7 GB.
- GRADE_RANK is pinned against scorecard.VERDICTS, so a seventh verdict fails at
  import instead of rendering a downgrade as a neutral move (BACKLOG #1012 is the
  same drift, one list earlier).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… (BACKLOG #1328)

The 28 flagged entries this row called "what remains" are read. Re-run against the
vault record at engine a2eef0f over a full-history clone: 62 pairs over 48
items, zero undecidable and zero floored dates, so every pair is decided against a
true last-touch date. That is strictly better than the 2026-09-03 run, which held
11 pairs back.

Surviving the read: BACKLOG #1172, BACKLOG #1127 and BACKLOG #1184, all three in
the missing-flip direction and all three carrying closing-act: scorecard-rescore.
BACKLOG #1172 is the cleanest instance this row has produced -- its own banner
says it stays open only because the re-score "is explicitly not run", and that
re-score landed the day after.

Zero re-opens. Only two downward grade transitions exist in the whole scorecard
history and neither leaves a closed banner on a withdrawn premise.

Two disagreements the date rule structurally cannot see are recorded as well:
one where the grade moved on the SAME day as the banner, and one where the grade
passed before the item was ever touched. The screen detects ordering, not
disagreement.

The row stays OPEN. The three flips are a ledger act this seat does not perform.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions github-actions Bot added the unread Green and mergeable, but not marked read. Read it, then add: reviewed label Sep 5, 2026
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown

@wshallwshall

This pull request is green and nobody has marked it read.

Every check that has reported is passing and the reviewed label is absent, so
a reviewer has read this is the only thing between it and a merge. Nothing else reports that, which is
why this comment exists (BACKLOG #1413).

To clear it, IN THIS ORDER:

  1. If the branch is behind main, update it FIRST: gh pr update-branch --repo MEFORORG/MessageFoundry 882.
    That push fires synchronize, and synchronize REMOVES the reviewed label. Labelling
    before updating throws the label away and costs a round trip.
  2. Read the diff.
  3. gh pr edit 882 --repo MEFORORG/MessageFoundry --add-label reviewed

DO NOT TRIAGE THIS FROM mergeStateStatus. It returns one value with precedence, so BEHIND,
DIRTY and UNSTABLE each mask the missing check -- the requirement is invisible until you act on
something else. This check never reads that field; see scripts/ci/check_unread_prs.py.

A seat can find every pull request in this state in one call: gh pr list --label unread.
The label is withdrawn automatically once this pull request leaves the state.

The reviewed label is a PROCESS gate. It records that a step happened. It does not
establish that an independent party looked, and nothing here should be read as saying it does.

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

Labels

unread Green and mergeable, but not marked read. Read it, then add: reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant