Repository navigation
feat(rollup): keep ten minutes of transaction detail by default - #407
Merged
Merged
Conversation
With the transactions page reading the read model (#406), the detail window no longer decides how far back the page can answer — the folded minute roll-ups carry that history. So the window can now be set to what the record actually needs, and the host's ruling of 2026-10-15 is that no one queries individual records at all: ten minutes. `[rollup] retain_minutes` therefore defaults to 10 instead of 43200 (30 days), and the example config follows. The deletion itself is unchanged — rows are still only deleted once they are folded *and* archived, so nothing is lost: the folded part stays answerable as minute roll-ups and the original rows stay in the JSONL archive. The transactions note no longer converts the retention boundary into days. It used to round the boundary to whole days, which was already lossy and would now be wrong in a visible way — a ten-minute window rounds to "the last 0 days". The sentence names the boundary instant instead, which is unit-free and needs no second calculation on the client (the server computes the boundary from the same expression the deletion uses). `tx_retention_gate` R1 is rewritten, because its premise was exactly what #406 removed ("the list can always only answer from the detail table"). It now has two halves: - the window must be expressible in minutes — a config that has gone back to spelling it in days turns this red, because day granularity cannot express ten minutes at all: below one day there is only 0, and 0 already means "keep no detail", a different rule; - when the window is shallower than the deepest preset the list offers, the difference can only be carried by the list no longer reading the detail table at all — the ledger is that a page answering from the raw table would silently answer less, with nothing on screen saying so. The rule is not relaxed to nothing: putting the list back on the raw table makes it apply again. Both halves were verified by mutation on the real corpus (config back to days => only R1 goes red; list back to the raw table => only R1 goes red). Tests: `cargo test` 562 passed, 0 failed. `cargo fmt --check` clean, `cargo clippy --all-targets -- -D warnings` rc=0, `cargo build` rc=0.
This was referenced Oct 15, 2026
Merged
argszero
added a commit
that referenced
this pull request
Oct 15, 2026
…409) #406 moved the transactions page onto the `tx_facts` read model, which retired the premise "the list needs per-row identity (`id`/`counterpart`), the roll-up has none, so the list can always only be answered from the detail table". #407's own commit message says its premise "was exactly what #406 removed", and `ui/README.md` calls it the premise that disappeared this round - but the two module docs that state it were never updated, so both still carry it in the present tense. - `src/tx_retention_gate.rs:6-7` opens the rule list with it, so the file argues from a premise that its own bullet, ten lines later, says is gone. - `src/usage_retention_gate.rs:4-5` reasons across files from it, and names the rule wrong as well (that rule was rewritten in #407). Both sentences now say what holds today: the window must be expressible in minutes, and the history outside it is carried by the minute roll-ups. Comments only - no behaviour, no gate rule, no config changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
Acceptance items 1 and 5 of the detail-retention rant (
2026-10-15T16:25:04). Item 2/3 (the list reading the read model) landed in #406; this PR makes the window short, which is only safe because the list no longer depends on it.The window defaults to ten minutes
[rollup] retain_minutesgoes from43200(30 days) to10, andconfig/config.example.tomlfollows. Nothing about the deletion changes: rows are still deleted only once they are folded and archived, so the folded part stays answerable as minute roll-ups and the originals stay in the JSONL archive. The default only decides how far back individual records are kept.This is the host's ruling of 2026-10-15, quoted in the rant: "the details I keep are still too many — I think ten minutes of real detail is enough. There is no need at all to query individual records [...] when the page queries detail, just give the minute roll-up as the detail." (translated from the Chinese original)
The note names the boundary instant instead of counting days
The transactions note rounded the retention boundary to whole days. That was already lossy and a ten-minute window makes it visibly wrong — it would read "kept for the last 0 days". It now names the boundary instant, which is unit-free and needs no second calculation on the client (the server derives the boundary from the same expression the deletion uses).
tx.empty.archivedchanges accordingly in both languages.tx_retention_gateR1 rewrittenIts premise was exactly what #406 removed ("the list can always only answer from the detail table"), so it now reads:
0, and0already means "keep no detail", which is a different rule;FROM transactionsno longer appears in the list endpoint's body).The rule is not relaxed to nothing. Putting the list back on the raw table makes it apply again — that is what the rule was always protecting: a page answering from the raw table answers less than the window allows, and nothing on screen would say so.
Mutation verification (acceptance item 5)
Both directions were run against the real corpus, and in each case only R1 goes red:
retain_days = 30r1=false r2=true r3=true r4=true · 窗口 None 分钟FROM transactionsr1=false r2=true r3=true r4=true · 窗口 Some(10) 分钟 · 列表读读模型 falseThe second one is the mutation the acceptance item names ("put the list back to reading the raw table"), and the positive control
the_scanner_sees_both_sidesnow also asserts the list payload is really being read, so a renamed handler cannot make the criterion silently false.Verification
cargo test— 562 passed, 0 failed.cargo fmt --checkclean;cargo clippy --all-targets -- -D warningsrc=0;cargo buildrc=0.Note on existing deployments
A deployment that already set
retain_dayskeeps that value — the legacy key is still accepted and takes precedence. The dev instance hasretain_days = 3set, so it would keep three days until that line is removed; the deploy step for this change removes it.