fix(skills): warn when blob GC is skipped over a malformed ledger line
gc_blobs() aborts the sweep on a json.JSONDecodeError (tools/skill_ledger.py:351-352) but did so silently, while the sibling read-failure abort a few lines above logs "ledger unreadable (...); blob GC skipped". `hermes curator ledger --compact` therefore printed "0 blobs removed" as if the sweep had run and found nothing. Emit the same warning family so the operator learns the ledger needs repair before blobs can be GC'd. Test: `malformed-json` param on the kept invariant test — (0, 0), blobs intact, and "blob GC skipped" in caplog. RED with the warning removed (assert 'blob GC skipped' in ''), GREEN at head.
This commit is contained in:
@@ -94,7 +94,7 @@ def test_gc_blobs_removes_only_unreferenced(ledger_home):
|
||||
assert skill_ledger.gc_blobs() == (0, 0)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("failure", ["unreadable", "missing", "invalid-encoding"])
|
||||
@pytest.mark.parametrize("failure", ["unreadable", "missing", "invalid-encoding", "malformed-json"])
|
||||
def test_gc_keeps_rollback_blobs_when_the_ledger_cannot_be_read(ledger_home, monkeypatch, caplog, failure):
|
||||
from tools import skill_ledger
|
||||
|
||||
@@ -119,6 +119,8 @@ def test_gc_keeps_rollback_blobs_when_the_ledger_cannot_be_read(ledger_home, mon
|
||||
patch.setattr(Path, "read_text", read_text)
|
||||
elif failure == "missing":
|
||||
ledger.unlink()
|
||||
elif failure == "malformed-json":
|
||||
ledger.write_bytes(saved + b"{broken\n")
|
||||
else:
|
||||
ledger.write_bytes(b"\xff")
|
||||
assert skill_ledger.gc_blobs() == (0, 0)
|
||||
|
||||
@@ -349,6 +349,7 @@ def gc_blobs() -> Tuple[int, int]:
|
||||
try:
|
||||
row = json.loads(line)
|
||||
except json.JSONDecodeError:
|
||||
logger.warning("skill_ledger: malformed ledger line; blob GC skipped")
|
||||
return 0, 0
|
||||
for item in (row.get("before") or []) + (row.get("after") or []):
|
||||
referenced.add(str(item.get("sha256", "")))
|
||||
|
||||
Reference in New Issue
Block a user