Skip to content

feat(tri): --as-of for the issue counts, and say when a read is a page rather than a total - #3032

Merged
gHashTag merged 1 commit into
masterfrom
loop/issues-as-of
Sep 3, 2026
Merged

feat(tri): --as-of for the issue counts, and say when a read is a page rather than a total#3032
gHashTag merged 1 commit into
masterfrom
loop/issues-as-of

Conversation

@gHashTag

@gHashTag gHashTag commented Sep 3, 2026

Copy link
Copy Markdown
Owner

tri issues numbers printed 486 open issues. That is not a fact about this repository; it is a fact about the moment it was asked. Read as of a date one month back, the same query answers 140 — a 3.5× move in 33 days, and nothing in the old output said which month it belonged to.

--as-of YYYY-MM-DD fixes the population, not the phrasing

OPEN ISSUES THAT STATE A COUNT IN THE TITLE, AS OF 2026-08-01T23:59:59Z

  This reading is ANCHORED: the population is the set of issues created
  at or before 2026-08-01T23:59:59Z and not closed by then, which does not move.

  issues read from gh           1482   (fewer than the --limit of 4000, so the read is COMPLETE)
  open issues read              140
  POPULATION                    75

It drops --state open — an issue open THEN may be closed NOW, and that filter removes exactly the rows that make the two readings differ — reads --state all with createdAt/closedAt, and keeps:

open_at(created, closed, t) = created <= t && (closed.is_empty() || closed > t)

The two boundaries point opposite ways, and that is the whole rule: created AT the instant counts as existing, closed AT the instant counts as closed, so an issue opened and closed in the same second is not open. A row with no creation time is not counted rather than defaulted to open — guessing would put it in the population in silence, which is the failure this command exists to expose.

The END of the UTC day, not the start, because GitHub's own search reads a bare date in created:<=2026-08-01 as covering that whole day. Two tools answering the same question must mean the same thing by the same date, or the second reader gets a different number and blames the first.

Three independent routes agree on 140: GitHub search as two queries (created:<=T state:open → 43, plus created:<=T closed:>T → 97); a full walk of all 1482 issues computing open-at-T from timestamps; and this command. The first two were run by separate readers before the command existed.

A malformed date is refused, not defaulted--as-of 2026-8-1 errors out, because a date silently becoming "today" under a heading that says the reading is anchored is worse than no anchor at all. The shape check is skillnum::is_iso_date, the rule already mutation-proved for §459's recovered anchors, not a second copy of the same ten conjuncts.

Without the flag the command now says so in its own first line: this reading is NOT anchored.

And one level down: a page presented as a total

gh returns at most --limit rows and says nothing about what it left behind, so a full page is a lower bound and only a short page is a total. Nothing here checked that.

Measured 2026-09-03T16:35Z: 486 open issues against a default --limit of 500. Fourteen issues from every figure this command prints becoming a page, in silence, with no line of output different.

pub fn read_is_complete(returned: usize, limit: usize) -> bool { returned < limit }

At exactly limit rows there may or may not be more, and the honest answer is that this cannot tell — so it reports incomplete. Mutating < to <= kills a test whose fixture is the live boundary, (486, 500) and (500, 500).

The class was four call sites, not one. Grepping "--limit" across cli/tri/src/ found numbers, dated, stale and gates prs — the last carrying a hardcoded 50 with no flag at all (10 open PRs at the time of measuring, so it does not bite yet, and when it does it will bite in silence). Each was then run at its own boundary:

command --limit 486 --limit 487
issues numbers LOWER BOUND COMPLETE
issues dated LOWER BOUND COMPLETE
issues stale LOWER BOUND COMPLETE
gates prs 10 of 50 → COMPLETE

This is §457 one level down. There the population was a query and the figure went stale; here the tool does not know whether it saw all of the population. An anchor on an incomplete read is worse than none — it says this number can be taken again about a number that was never the whole thing.

  • eight clauses mutated, eight killed
  • cargo test -p tri501 passed, 0 failed
  • skill §461, §462

Refs #2994

…e rather than a total

`tri issues numbers` printed 486 open issues. That is not a fact about
this repository; it is a fact about the moment it was asked. Read as of a
date one month back the same query answers 140 -- a 3.5x move in 33 days,
and nothing in the old output said which month it belonged to.

`--as-of YYYY-MM-DD` fixes the population instead of the phrasing. It
drops `--state open` (an issue open THEN may be closed NOW, and that
filter removes exactly the rows that make the two readings differ), reads
`--state all` with createdAt/closedAt, and keeps what was open at the end
of that UTC day:

  open_at(created, closed, t) = created <= t && (closed empty || closed > t)

The two boundaries point opposite ways and that is the whole rule:
created AT the instant counts as existing, closed AT the instant counts
as closed, so an issue opened and closed in the same second is not open.
A row with no creation time is not counted rather than defaulted to open.

The END of the day, not the start, because GitHub's own search reads a
bare date in `created:<=2026-08-01` as covering that whole day. Two tools
answering the same question must mean the same thing by the same date.

Three independent routes agree on 140: GitHub search as two queries
(43 + 97), a full walk of all 1482 issues computing open-at-T from
timestamps, and this command. The first two were run by separate readers
before the command existed.

A malformed date is refused, not defaulted: `--as-of 2026-8-1` errors,
because a date silently becoming "today" under a heading that says the
reading is anchored is worse than no anchor at all. The shape check is
`skillnum::is_iso_date`, the rule already mutation-proved for section
459, rather than a second copy of the same ten conjuncts.

Separately, and one level down: `gh` returns at most --limit rows and
says nothing about what it left behind, so a full page is a LOWER BOUND
and only a short page is a total. Nothing here checked that. Measured
2026-09-03T16:35Z: 486 open against a default limit of 500 -- fourteen
issues from every printed figure becoming a page, in silence.

  read_is_complete(returned, limit) = returned < limit

The class was four call sites, not one: `numbers`, `dated`, `stale`, and
`gates prs`, the last with a hardcoded 50 and no flag. Each was run at
its own boundary -- --limit 486 prints LOWER BOUND, --limit 487 prints
COMPLETE.

Eight clauses mutated, eight killed.

Skill sections 461 and 462.

Refs #2994
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

📓 NotebookLM Notebook linked to this PR

This notebook contains session context, decisions, and artifacts for this work.

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-09-03 17:01:15 UTC

Summary

Status Count
Total Open PRs 11
PRs with Failing Checks 10
PRs with All Checks Green 1
READY 0
FAILING 10
PENDING 0

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=9b8875f1c9d4 != manifest seal=87e5cbd3ad94.
    The committed NMSE numbers were certified against an older compiler.rs.
    Run scripts/reseal-check.sh locally for the two-step reseal command (advisory; not a merge gate).

@gHashTag
gHashTag merged commit e1dcad1 into master Sep 3, 2026
36 checks passed
@gHashTag
gHashTag deleted the loop/issues-as-of branch September 3, 2026 17:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant