feat(tri): refuse an unclosed day, and count every bounded fetch instead of one spelling - #3033
Merged
Conversation
…ead of one spelling `tri issues numbers --as-of 2027-01-01` printed 486 open issues -- today's count -- under the heading AS OF 2027-01-01T23:59:59Z. It looked anchored, read as history, and was a clock reading wearing next year's label. GitHub does not object: created:<=2027-01-01 composed with closed:>2027-01-01 answers 486 + 0 without complaint. Section 461 refused a MALFORMED date because a date silently becoming "today" is worse than no anchor. A future date does exactly that while parsing perfectly, so the refusal has to be about the day being CLOSED. Today is refused for the same reason as tomorrow: its end is still in the future, so the count differs from itself by evening. The comparison needs today's UTC date, so a civil calendar is transcribed rather than invented and tested on the dates that break a wrong one. The century divisor is load-bearing on exactly two days in a hundred thousand -- 1900-03-01 and 2100-03-01 -- and swapping 36_524 for 36_525 makes the calendar invent 1900-02-29. Those two dates were found by sweeping the mutant against an independent calendar. One expectation in the test was wrong when written: civil_from_days(20_699) guessed 2026-09-04 and the answer is 2026-09-03. The code was right and the test was mine. Separately: the previous change closed four `--limit` call sites and called the class closed. `--limit` is one of two spellings; the same class is written `per_page=` in a URL, and that is 22 more lines. `tri gates fetches` walks the crate and reports it: 24 fetch sites, of which 5 are complete by --paginate, 2 read the API's own total_count, 6 ask whether the page filled, 2 take one row and read no total, and 9 print what they got. None bites today -- 62 workflows against a page of 100, 35 check-runs against 100 -- and the margin that matters is still 486 against 500. Section 462 is corrected in place. The census counted itself twice. Its first rule matched its own definition, which names both needles; requiring them in the SAME string literal fixes that without naming any function as an exception. Then it counted its own test fixtures, 25 where a hand count said 24. Excluding test modules is not "everything after the first #[cfg(test)]": five files here carry real top-level functions AFTER their test module, gates.rs fifteen of them, and main.rs's forty ordinary `mod` declarations would put the walker in test mode for the rest of the file without the attribute check. What made both visible was the LIST, not the total. A census that prints only its count cannot be checked; one that prints its members can, and --excluded prints the other half. Fourteen clauses mutated, fourteen killed. Skill sections 463 and 464. Refs #2994
Contributor
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
Contributor
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.
An anchor that cannot be wrong is not an anchor
tri issues numbers --as-of 2027-01-01printed 486 open issues — today's count — under the headingAS OF 2027-01-01T23:59:59Z. It looked anchored, read as history, and was a clock reading wearing next year's label.GitHub does not object.
created:<=2027-01-01composed withclosed:>2027-01-01answers486 + 0 = 486without complaint, because every issue that exists was created before next year and none has been closed after it. The query is well-formed and its answer is worthless.§461 refused a malformed date on the grounds that a date silently becoming "today" is worse than no anchor. A future date does exactly that while parsing perfectly, so the refusal has to be about the day being CLOSED, not the string being well-shaped. Today is refused for the same reason as tomorrow: its end is still in the future, so the count differs from itself by evening.
The calendar is load-bearing on two days in a hundred thousand
The comparison needs today's UTC date, so a civil calendar is transcribed rather than invented, and tested on the dates that break a wrong one: the epoch, the day before it, a leap day, and the day after February in a century that is not a leap year. Swap
36_524for36_525and it invents1900-02-29, a date that does not exist. Exactly two inputs in a hundred thousand discriminate —1900-03-01and2100-03-01— and they were found by sweeping the mutant against an independent calendar, not by picking dates that looked interesting.One expectation in that test was wrong when written:
civil_from_days(20_699)guessed 2026-09-04, and the answer is 2026-09-03. The code was right and the test was mine. That is what an independently derived expectation is for.--limitwas one of two spellingsThe previous PR closed four
--limitcall sites and called the class closed. The same class is writtenper_page=in a URL, and that is 22 more lines.tri gates fetchesnow walks the crate and reports it:The nine are
gates unmeasured,gates dead,red nowand four inprcheck. None bites today — 62 workflows against a page of 100, 35 check-runs against 100 — and the margin that matters is still the issue one, 486 against 500. §462 is corrected in place.Grepping one spelling and calling the class closed is the same error as counting one population and calling it the subject.
The census counted itself, twice
Its first rule was "the line names
per_page=and namesrepos/", and it matched its own definition, which names both. The fix is not an exception list: both needles must live in the SAME string literal, which a rule never has and a URL always does.Then it counted its own test fixtures — 25 sites where a hand count said 24. Excluding test modules looked like one line, everything after the first
#[cfg(test)], and that was checked rather than assumed: five files in this crate carry real top-level functions AFTER their test module,gates.rsfifteen of them. The module has to be closed by a}in the first column, and the attribute has to be seen before themod— ormain.rs's forty ordinary module declarations put the walker in test mode for the rest of the file, silently dropping every fetch after the first.What made both visible was the LIST, not the total. A census that prints only its count cannot be checked; one that prints its members can.
--excludedprints the other half of the reading: 25 lines name a spelling without fetching, against 24 that fetch.cargo test -p tri— 515 passed, 0 failedRefs #2994