lazy boot: only repopulate when the index references a missing source

_writable_store_index_needs_population compared the set of stored row
hashes against the set of index-referenced hashes symmetrically. The
store is append-only (only reconcile_index prunes), so rows orphaned by
a content change, an ad-hoc self-heal superseded by conf context, or an
uninstall accumulate legitimately - and one orphan made the comparison
unequal forever, turning every boot and every post-install reload into a
full inline repopulate and permanently defeating the freshness-token
scan skip (observed: 5 inline populates across one shed-install
integration test, 3 orphaned rows as the stable delta).

Check the direction that is actually an invariant: every source_hash the
index references must resolve to a stored row, or materialising that
tool would fail. Orphaned rows are logged at debug as prune candidates.
Measured on the same test: 5 inline populates -> 2 (cold boot + the
legitimate freshness-token change from the install itself).
This commit is contained in:
mvdbeek
2026-07-28 17:27:46 +02:00
parent e38aca1d96
commit a63f88a421
2 changed files with 45 additions and 3 deletions
+21
View File
@@ -333,6 +333,27 @@ def test_resolve_index_entry_returns_none_when_nothing_matches():
assert box._resolve_index_entry(None, None) is None
def _reconcile_box(index_hashes, store_hashes):
box = _seam_box()
box._store.read_only = False
box._store.list_all.return_value = list(store_hashes)
index = ToolIndex()
for position, source_hash in enumerate(index_hashes):
index.add_entry(_entry(id=f"tool_{position}", source_hash=source_hash))
box._store.load_index.return_value = index
return box
def test_index_reconcile_ignores_orphaned_store_rows():
box = _reconcile_box(index_hashes=["a", "b"], store_hashes=["a", "b", "orphaned"])
assert box._writable_store_index_needs_population() is False
def test_index_reconcile_repopulates_on_dangling_index_reference():
box = _reconcile_box(index_hashes=["a", "b"], store_hashes=["a"])
assert box._writable_store_index_needs_population() is True
def test_create_tool_populates_adhoc_for_existing_file(tmp_path, monkeypatch):
# Shed installs load cloned tools during metadata generation, before
# any conf is persisted — a miss for an on-disk file populates that