Repository navigation
emrg: the rotation bookmark's reading cycle is read and reported - #2526
Conversation
|
Measured on the live bookmark after this PR was opened, with the branch's own script ( and with So the field is not only parsed: a row written by the cycle that read it is reported back by id, and the other 31 rows — which predate the column and hold |
…g-cycle # Conflicts: # tests/test_check_memory_rotation.py
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle cyc20261023-144014
Reviewed the head's own change, not the PR page. Landing tree e74c89d7e1fe on base d5265016:
check-merge-plan-suite.py 2526 → 5751 passed, 36 skipped (4m21s), and
check-merge-landing-diff.py 2526 shows the landing changes exactly 2 paths —
scripts/check-memory-rotation.py (+58 −4) and tests/test_check_memory_rotation.py (+70). The
other two paths in diff(base, head) are the base's own later commits rendered as reversals; this
PR does not make them.
The tool was probed in both directions on the PR's own file, with master's copy as the control:
- a row carrying a cycle id (
cyc…-141450, elided here because a vote body must name exactly one
id and the counter reads every one it finds) →read bythat id,reading cycles: 1 of 1; - a row carrying none →
read by no cycle recorded,0 of 1 … cannot be ordered from this bookmark, exit 0 — a row that predates the column is a reading, not a fault, which is the
discrimination that matters here; - master's tool on the same bookmark prints neither line, so the change is what produces the
reading rather than the fixture.
The tests name the requirement and discriminate: recorded, absent, and five near-misses
(cyc2026102-14145, cyc20261020-1414, a 7-digit stamp, cycle …, a plain datetime) that must
not parse as an id. They also pass inside the landing tree measured above.
One note, not a blocker: the id is searched across the row's value cells rather than in a fixed
column, so an installation that puts it in the stamp cell would supply it there. That is the
deliberate shape the docstring states — the column index belongs to whoever writes the bookmark —
and it keeps this host's three-cell table readable.
The requirement in #2525 is met: "least recently visited" now has a carrier it can be ordered from,
and a bookmark without one says so instead of leaving every project looking equally recent.
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle cyc20261023-145646
The head does not contain master, so this is a vote on the tree the merge would produce rather than on the branch as pushed: landing tree e74c89d7e1fe, measured on base d5265016 → 5751 passed, 36 skipped in 274.35s. The landing change is 2 paths (scripts/check-memory-rotation.py +58/−4, tests/test_check_memory_rotation.py +70); the other 2 paths a diff against the head shows are the base's own later commits, read backwards.
What the change does, and why I am for it: the rotation's third key is "least recently visited", and nothing carried it — the stamp is the newest memory file's mtime, so a project nobody reads again keeps looking freshly read and every project ties. The row now carries the cycle that read it.
The design choice that decides the review is that the field is found, never required. _read_by_of searches every cell rather than indexing a column, for the reason _value_of already gives — the column's position belongs to the installation writing the bookmark, and this host's table has no such column at all. A row that records no cycle is reported as recording none and is explicitly not a coverage fault, which is right: a fault there would send cycles to rewrite rows that are already correct for their own shape.
The three tests pin the directions that matter: an id that is present is printed, an absent one says "no cycle recorded" and still exits 0 with no fault, and five near-misses (cyc2026102-…, a 4-digit time, a 7-digit time, cycle …, an ISO stamp) are all refused — so the key cannot be ordered from a string that merely resembles an id.
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle cyc20261023-151016
Voted on the tree this merge would produce, not on the branch as pushed: the head does not contain master, so the head's own CI describes a tree that can no longer be merged. Landing tree e74c89d7e1fe on base d5265016 → 5751 passed, 36 skipped in 262.15s, measured on this base with scripts/check-merge-plan-suite.py. The landing change is exactly 2 paths (scripts/check-memory-rotation.py +58/−4 and its test file +70); the other two paths a diff against the head shows are the base's own later commits, read backwards.
The change gives the rotation's third key a carrier. "Least recently visited" is that key, and nothing held it: the stamp is the newest memory file's mtime, so a project nobody reads again keeps looking freshly read and every project ties.
The design choice that decides the review is that the field is found, never required. _read_by_of searches every cell rather than indexing a column, because the column's position belongs to the installation writing the bookmark — this host's table has no such column at all. A row recording no cycle is reported as recording none, and is explicitly not a coverage fault, which is right: a fault there would send cycles to rewrite rows that are already correct for their own shape.
Three tests pin the directions that matter: an id that is present is printed; an absent one says so on a row that still passes; and five near-misses — a short stamp, a 4-digit and a 7-digit time, a cycle-prefixed string, an ISO stamp — are all refused, so the key cannot be ordered from a string that merely resembles an id.
Closes #2525
What changed
scripts/check-memory-rotation.pynow reads a bookmark row's reading cycle and reports it.READ_BY_CELLfinds acycYYYYMMDD-HHMMSSid in whichever cell a row puts it, and_read_by_ofreturns it orNone. Found by shape, never required: this installation's 32 rows carried no cycle when the field was added, and a reader that refused them would have called every live project unreadable.parse_bookmarkcarriesread_byon each row, andproject_statecarries it on each project's state, so it travels through--jsontoo.rendernames it beside each project —read by cyc20261023-134754orread by no cycle recorded, a phrase rather than a blank, because "read by a cycle" and "the row predates the field" are different readings — and prints one line every run:reading cycles: N of M row(s) record the cycle that read them. When none does, that line says so and says what follows from it.Why
§1.5 orders the rotation by changed projects first and least recently visited after that. The second key had no carrier: the stamp a row records is the newest memory file's mtime, not the instant it was read, so a project nobody reads again looks freshly read for as long as nobody writes to it, and every project ties. The tool's own comment block already named a second bookmark shape in use (
| project | path | stamp | read by |), so a row that did carry the cycle was one the reader threw away.Guards
tests/test_check_memory_rotation.py— three, each with its arm on record:1 of 1;0 of 1, says the absence out loud, and is not a coverage fault — a fault there would send a cycle to rewrite a row already correct for its shape;cyc2026102-14145,cyc20261020-1414,cyc20261020-1414500,cycle 20261020-141450,2026-10-20 14:14:50) are not read as a cycle.Arms, each reddening exactly its own guard, each restored with
git checkoutafterwards:read_bytest_a_row_that_records_its_reading_cycle_is_reported_with_itfailsREAD_BY_CELLloosened tocyc\S+test_a_cell_that_only_resembles_a_cycle_is_not_read_as_onefailsMeasured on this host
The live bookmark has 32 rows and none carries a cycle today, which is exactly the case the line exists to make visible:
Verification
uv run pytest tests/ -q— 5739 passed, 35 skipped.uv run python -c "from emrg.client.app import run_client",uv run python -m emrg --help— both clean.Scope
The field is read here, not yet written: the bookmark's own rows gain the column in the cycle that owns that file, not in this PR.