fix(projection): a resurrected row must enter matched to be seen
The previous commit made a stamped slug count as retired, and skipped such rows before the heuristics. That is right for a genuinely retired row and wrong for a resurrected one: `stale` is computed from `matched`, so a row that never enters `matched` is invisible — not retired, so not stale; path-matching its own file, so never reported. All six kept returning `noop`. A row whose slug carries the mark while its flag is clear now lands in `matched` under its own key, which is what makes it stale and therefore retirable. A row that is actually retired is still skipped outright: nothing to do, nothing to re-decide. This is the same mistake as the original path fallback, in the opposite direction: there a row was matched when it should not have been, here it was not matched when it had to be. 748 pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 2583210@bnt-lap001 Assistant-Session: f2bff2d5-e9b2-4338-92ca-10282a927006
This commit is contained in:
parent
95672e0c47
commit
5686b79d8c
2 changed files with 26 additions and 9 deletions
|
|
@ -732,12 +732,16 @@ async def reset_repository_projection(
|
|||
# which is then deliberately un-retired below.
|
||||
matched[key] = row
|
||||
continue
|
||||
if row.projection_retired_at is not None or RETIRED_SLUG_MARK in (row.slug or ""):
|
||||
# A stamped slug is itself evidence of a retirement, so a row
|
||||
# carrying the mark with a cleared flag is a contradiction to
|
||||
# repair rather than a live record — six rows reached that state
|
||||
# before the resurrection was fixed, and nothing else can see them:
|
||||
# they path-match their own file and report `noop` forever.
|
||||
if row.projection_retired_at is None and RETIRED_SLUG_MARK in (row.slug or ""):
|
||||
# A stamped slug with a cleared flag is a resurrected row: the mark
|
||||
# is evidence a retirement happened and the flag says it did not.
|
||||
# It must land in `matched` under its own key so it shows up as
|
||||
# stale — skipping it outright, as a genuinely retired row is
|
||||
# skipped, is what left these reporting `noop` forever.
|
||||
matched[key] = row
|
||||
continue
|
||||
if row.projection_retired_at is not None:
|
||||
# Already retired: nothing to do, and nothing to re-decide.
|
||||
#
|
||||
# Past this point only the heuristics remain, and a retired row must
|
||||
# not be matched by those. Retirement is a
|
||||
|
|
|
|||
|
|
@ -907,7 +907,7 @@ class TestRetirementIsNotUndoneByPath:
|
|||
def test_retired_rows_are_skipped_before_path_matching(self):
|
||||
import inspect
|
||||
src = inspect.getsource(fp.reset_repository_projection)
|
||||
skip_at = src.index("if row.projection_retired_at is not None or RETIRED_SLUG_MARK")
|
||||
skip_at = src.index("if row.projection_retired_at is not None:")
|
||||
path_at = src.index("if bp and _path_key(bp) in want_paths:")
|
||||
assert skip_at < path_at, "retired rows must be skipped before path matching"
|
||||
|
||||
|
|
@ -916,7 +916,7 @@ class TestRetirementIsNotUndoneByPath:
|
|||
import inspect
|
||||
src = inspect.getsource(fp.reset_repository_projection)
|
||||
assert src.index("want_by_uuid.get(str(row.id))") < src.index(
|
||||
"if row.projection_retired_at is not None or RETIRED_SLUG_MARK"
|
||||
"if row.projection_retired_at is not None:"
|
||||
)
|
||||
|
||||
def test_a_row_that_derives_again_is_not_tombstoned(self):
|
||||
|
|
@ -935,4 +935,17 @@ class TestRetirementIsNotUndoneByPath:
|
|||
"""Otherwise a resurrected row path-matches its file and reports noop forever."""
|
||||
import inspect
|
||||
src = inspect.getsource(fp.reset_repository_projection)
|
||||
assert 'projection_retired_at is not None or RETIRED_SLUG_MARK in' in src
|
||||
assert "projection_retired_at is None and RETIRED_SLUG_MARK in" in src
|
||||
|
||||
def test_a_resurrected_row_becomes_stale_rather_than_being_skipped(self):
|
||||
"""Skipping it outright is what left six rows reporting noop forever.
|
||||
|
||||
`stale` is computed from `matched`, so a row that never enters `matched`
|
||||
is invisible: not retired, so not stale; path-matching its own file, so
|
||||
never reported.
|
||||
"""
|
||||
import inspect
|
||||
src = inspect.getsource(fp.reset_repository_projection)
|
||||
zombie = src.index("projection_retired_at is None and RETIRED_SLUG_MARK in")
|
||||
tail = src[zombie:zombie + 700]
|
||||
assert "matched[key] = row" in tail, "a resurrected row must enter `matched`"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue