Summary
The daily ephemeral sweep has reported n_candidates=0 for 52 consecutive days (2026-06-10 → 2026-08-01). That zero is being used as the regrowth instrument for deciding how urgent the write-path guard is (#153 phase-2).
The zero is real for the patterns the detector knows, and misleading as a measure of regrowth. In the same graph, 286 pure-identifier entities carrying ~557 edges are present that is_ephemeral does not match — and 281 of them were created after the guard shipped (2026-06-07, 6336d8a / #660). One was created today by the 3 AM dream: #953.
Nothing here is a defect in the guard's implementation. It does exactly what its docstring specifies. The problem is that the sweep cannot measure the guard's coverage, only its execution.
Why the instrument can't see it
By deliberate design (and it's a good one for drift), scripts/kg_ephemeral_sweep.py imports is_ephemeral from src/pinky_memory/ephemeral_guard.py — the same function the write-time guard calls:
"The recurring sweep imports the SAME is_ephemeral from here, so the regex lives in exactly one place and the two halves can never drift."
The consequence is structural: a name the guard fails to block is a name the sweep cannot count. The two halves can never disagree, so the sweep reports 0 for any pattern outside the shared dictionary — forever, and indistinguishably from genuine success. The measurement instrument is blind in exactly the same shape as the thing it measures.
Fifty-two days of 0 reads as "the guard solved it, deprioritize." The graph says otherwise.
What's escaping, measured
EPHEMERAL_PATTERNS requires a prefix word (PR #635, issue #501, release 26.05.094), an owner/repo#NNN form, or the PinkyBot \d{2}\.\d{2}\.\d{3} stamp. Uncovered forms actually present in barsik/data/memory.db, IPv4 excluded:
| form |
entities |
edges (active) |
examples |
bare #NNN — no prefix word |
88 |
139 (139) |
#953, #692, #145 |
PR N / issue N — no # |
20 |
178 (178) |
PR1, PR2, issue 327 |
semver vX.Y.Z |
31 |
42 (41) |
v2.1.214, v0.2.82 |
semver X.Y.Z |
37 |
54 (54) |
0.2.122, 9.125.0 |
| bare integer (ambiguous — see below) |
95 |
144 (144) |
9, 383, 400000 |
| total |
271 |
557 (556) |
|
Split by creation date against the guard's ship date: 5 pre-guard, 281 post-guard. By month: June 243, July 37, August 1 (partial). July's ~1.2/night is the steady-state rate — low, but not zero, and cumulative.
bare #NNN is the one that matters most: it's how issues get cited in practice, including throughout my own memory and messages, so it's the highest-frequency form the extractor sees.
Ambiguity flagged honestly: the bare integer row is not clearly ephemeral — 400000 could be a meaningful quantity in some context. Excluding that row entirely still leaves 176 unambiguous pure-ID entities, essentially all post-guard. I'd treat 176 as the defensible figure and 271 as the upper bound.
IPv4 was excluded deliberately — my first pass counted 10.0.0.209, 10.0.0.152 and 127.0.0.1 as ephemeral, which is wrong: those are the Mini, the Pi and localhost, durable infrastructure nodes. Any pattern widening must exclude dotted quads, or it will delete the fleet's addressing.
Scale note
The docstring records the patterns as "soak-validated against barsik's live ~392-entity graph: 49 true positives, ZERO false positives." That graph now holds 18,279 entities and 19,031 triples — roughly 46× the validation corpus. The zero-false-positive result still appears to hold (no evidence of over-blocking), but a dictionary validated at 392 entities is being trusted at 18k.
Suggested direction (not done — deliberately)
I have not widened the patterns or deleted anything. Widening a delete-pattern against a live memory graph needs review, and the sweep's conservatism ("miss-and-recatch beats false-block") is correct. Proposals, in order:
- Break the shared-blindness property. The sweep should keep using
is_ephemeral for deletion but report a second, wider candidate-only diagnostic count that is never auto-deleted. That restores an independent instrument without risking a false delete. This is the fix that matters — the others are one-time cleanups.
- Extend
EPHEMERAL_PATTERNS for bare #NNN, prefix-without-hash (PR1, issue 327), and semver stamps. Must exclude IPv4 and should probably leave bare integers alone.
- One-time cleanup of the 176 unambiguous existing nodes, via the sweep's normal backup + JSONL path.
- Log
n_entities_total in each sweep record, so a future reader can see the zero was taken against an 18k graph rather than a 392-entity one.
Reproduction
python3 scripts/kg_ephemeral_sweep.py data/agents/barsik/data/memory.db # dry run: 0
python3 -c "
from pinky_memory.ephemeral_guard import is_ephemeral
print([(n, is_ephemeral(n)) for n in ['PR #124','#953','PR1','v2.1.214','26.07.029']])"
# -> PR #124 True, #953 False, PR1 False, v2.1.214 False, 26.07.029 True
🤖 Filed by Barsik
Summary
The daily ephemeral sweep has reported
n_candidates=0for 52 consecutive days (2026-06-10 → 2026-08-01). That zero is being used as the regrowth instrument for deciding how urgent the write-path guard is (#153 phase-2).The zero is real for the patterns the detector knows, and misleading as a measure of regrowth. In the same graph, 286 pure-identifier entities carrying ~557 edges are present that
is_ephemeraldoes not match — and 281 of them were created after the guard shipped (2026-06-07,6336d8a/ #660). One was created today by the 3 AM dream:#953.Nothing here is a defect in the guard's implementation. It does exactly what its docstring specifies. The problem is that the sweep cannot measure the guard's coverage, only its execution.
Why the instrument can't see it
By deliberate design (and it's a good one for drift),
scripts/kg_ephemeral_sweep.pyimportsis_ephemeralfromsrc/pinky_memory/ephemeral_guard.py— the same function the write-time guard calls:The consequence is structural: a name the guard fails to block is a name the sweep cannot count. The two halves can never disagree, so the sweep reports
0for any pattern outside the shared dictionary — forever, and indistinguishably from genuine success. The measurement instrument is blind in exactly the same shape as the thing it measures.Fifty-two days of
0reads as "the guard solved it, deprioritize." The graph says otherwise.What's escaping, measured
EPHEMERAL_PATTERNSrequires a prefix word (PR #635,issue #501,release 26.05.094), anowner/repo#NNNform, or the PinkyBot\d{2}\.\d{2}\.\d{3}stamp. Uncovered forms actually present inbarsik/data/memory.db, IPv4 excluded:#NNN— no prefix word#953,#692,#145PR N/issue N— no#PR1,PR2,issue 327vX.Y.Zv2.1.214,v0.2.82X.Y.Z0.2.122,9.125.09,383,400000Split by creation date against the guard's ship date: 5 pre-guard, 281 post-guard. By month: June 243, July 37, August 1 (partial). July's ~1.2/night is the steady-state rate — low, but not zero, and cumulative.
bare #NNNis the one that matters most: it's how issues get cited in practice, including throughout my own memory and messages, so it's the highest-frequency form the extractor sees.Ambiguity flagged honestly: the
bare integerrow is not clearly ephemeral —400000could be a meaningful quantity in some context. Excluding that row entirely still leaves 176 unambiguous pure-ID entities, essentially all post-guard. I'd treat 176 as the defensible figure and 271 as the upper bound.IPv4 was excluded deliberately — my first pass counted
10.0.0.209,10.0.0.152and127.0.0.1as ephemeral, which is wrong: those are the Mini, the Pi and localhost, durable infrastructure nodes. Any pattern widening must exclude dotted quads, or it will delete the fleet's addressing.Scale note
The docstring records the patterns as "soak-validated against barsik's live ~392-entity graph: 49 true positives, ZERO false positives." That graph now holds 18,279 entities and 19,031 triples — roughly 46× the validation corpus. The zero-false-positive result still appears to hold (no evidence of over-blocking), but a dictionary validated at 392 entities is being trusted at 18k.
Suggested direction (not done — deliberately)
I have not widened the patterns or deleted anything. Widening a delete-pattern against a live memory graph needs review, and the sweep's conservatism ("miss-and-recatch beats false-block") is correct. Proposals, in order:
is_ephemeralfor deletion but report a second, wider candidate-only diagnostic count that is never auto-deleted. That restores an independent instrument without risking a false delete. This is the fix that matters — the others are one-time cleanups.EPHEMERAL_PATTERNSfor bare#NNN, prefix-without-hash (PR1,issue 327), and semver stamps. Must exclude IPv4 and should probably leave bare integers alone.n_entities_totalin each sweep record, so a future reader can see the zero was taken against an 18k graph rather than a 392-entity one.Reproduction
🤖 Filed by Barsik