Skip to content

Ask whether the release record still says what the release lists say [#225] - #226

Merged
iderex merged 3 commits into
mainfrom
ci/nothing-re-takes-the-release-record
Sep 1, 2026
Merged

Ask whether the release record still says what the release lists say [#225]#226
iderex merged 3 commits into
mainfrom
ci/nothing-re-takes-the-release-record

Conversation

@iderex

@iderex iderex commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

What was wrong

data/releases.json is what the landing table and every plugin page compute the
shipping state from. It is taken by hand and nothing runs the verb that takes
it:

grep -rln 'releases' .github/workflows/; echo "exit=$?"
exit=1

so the file aged with nothing reading it, while the landing page stated the day
it was taken as though a reader could rely on it:

jq -r '.taken' data/releases.json
2026-08-26
go run . build > /dev/null
grep -o -E '[^<>]*read on [^<>]*' dist/index.html
12 rows, read from the roster this repository carries. What each plugin has published was read on 2026-08-26, and the state below is computed from that rather than declared: a row says what is true before anything is published, and a finished release raises it.

Both run 2026-09-01 at acf49ee. The three neighbouring verbs that read
something published elsewhere each have a route that asks for them and this one
had none:

for v in pins tokens roster releases; do
  printf '%-9s %s\n' "$v" "$(ls .github/workflows/$v.yml 2>/dev/null || echo 'no workflow')"
done
pins      .github/workflows/pins.yml
tokens    .github/workflows/tokens.yml
roster    .github/workflows/roster.yml
releases  no workflow

Run 2026-09-01 at acf49ee. The record was six days out of date when this
branch started, and the two entries that had moved are in the third commit's
message.

What this does

go run . releases check asks the same question of the same repositories as the
writing mode, compares what came back against the record, names every repository
the two disagree about with what it moved from and to, writes nothing, and
refuses while any of them disagree. The reporting loop is shared with the
writing mode, so a red schedule and the change that repairs it describe the same
difference in the same words. A record that could not be read is refused rather
than reported and carried on from, which is the opposite of what the writing
mode does with the same failure and is the same reason in both directions: that
one is about to replace the file, and this one would be reporting no difference
having compared nothing.

The request that reads a release list carries a token where the environment
holds one. Twelve repositories from a shared address exhaust the anonymous rate,
measured rather than supposed: a run taken on 2026-09-01 answered 403 for the
fifth repository it asked about. No token is not an error, and the metadata
beside a release carries none, because it is fetched from whichever host that
release names.

The workflow asks on the weekly cadence the other three comparisons use, grants
contents: read, and proves after every run, red or green, that the tree it
checked out is unchanged.

The record is re-taken in the last commit so this lands green over a file that
reproduces what is published, rather than red over one nothing had re-taken.

Closes

Closes #225.

What was run

go run . ci
gate: 7 legs, in order: format, vet, test, build, links, sitemap, invariants
  needs-network was not asked for. Asking costs a request to the public name from whatever machine runs it, and a verdict that moves when somebody else's service does rather than when this tree changes. Ask with: go run ./harness/needs-network
  format: ok, 74 file(s)
  vet: ok
  test: ok, 37 test file(s)
  build: ok, 22 file(s)
  links: every reference that stays inside this site resolves to a file the build wrote
  sitemap: every page the build wrote is listed once, and every entry has a page behind it
  invariants: ok, 39 rule(s) decided, 2 owed and not decided
7 of 7 legs ran. None was skipped.

The needs-network set was not asked for and is named above by the run itself.
No test was skipped, and nothing here needs a display or elevation.

go run . hygiene origin/main HEAD | tail -1
3 commit(s) judged, none refused.

The new verb, against the record as this branch leaves it:

go run . releases check | tail -2
releases: 12 repository(s) compared against data/releases.json, taken on 2026-09-01, 0 entry(s) moved, nothing written

and against the record before the re-take, which is what the schedule would have
found:

go run . releases check | grep MOVED
  Flowfin/jellyfin-plugin-requests: MOVED, was 1 finished, 0 prerelease(s), for 10.11, now 2 finished, 0 prerelease(s), for 10.11
  Flowfin/jellyfin-plugin-sso: MOVED, was 29 finished, 53 prerelease(s), for 10.11, 4 stating no generation, now 37 finished, 61 prerelease(s), for 10.11, 4 stating no generation
releases: 2 entry(s) in data/releases.json no longer say what the release lists say, and the pages render that file; re-take it with `go run . releases`

All run 2026-09-01.

What the guards were shown to bite on

The refusal, disabled at its own condition:

go test ./internal/releases -run TestTheComparisonBites -count=1
--- FAIL: TestTheComparisonBitesOnAnEditAndPassesWithoutIt (0.01s)
    releases_test.go:387: the comparison passed a record that no longer says what was published

The token, with the header no longer set:

go test ./internal/releases/github -run TestTheTokenReaches -count=1
--- FAIL: TestTheTokenReachesTheReleaseListAndNothingElse (0.00s)
    github_test.go:180: the request carries the authorisation ""

Both run 2026-09-01, and both restored before the commits above. The green half
and the red half of the comparison case are the same bytes apart from one edited
count, so neither half proves only that the other is reachable.

The means

Go, as a mode of the verb that already asks these repositories the same
question, and YAML for the workflow, which is the format the route is declared
in and is forced by where it runs. The comparison is a refusable property with a
fixture that reddens when it is disabled, the counts it reports carry the run
that produced them, and the package already holds the fetcher, the record shape
and a suite that reaches no network. Nothing here adds a language, a runtime or
a dependency: the module graph is still empty.

Who read it

Nobody but me. The ruleset requires no approving review, so this is merged by
whoever opened it, and the commands above stand in place of a second reader.

data/releases.json is what the landing table and every plugin page compute the
shipping state from, and it is taken by hand: `go run . releases` writes it and
nothing runs that verb. So the record aged with nothing reading it, while the
landing page went on stating the day it was taken as though a reader could rely
on it. A repository publishing its first finished release turns a `shell` row
into a shipping one, and nothing here would have said so.

The verb gains one argument. `go run . releases check` asks the same question of
the same repositories, compares what came back against the record, names every
repository the two disagree about with what it moved from and to, writes
nothing, and refuses while any of them disagree. The reporting loop is shared
with the writing mode, so a red schedule and the change that repairs it describe
the same difference in the same words.

A record that could not be read is refused rather than reported and carried on
from, which is the opposite of what the writing mode does with the same failure:
that one is about to replace the file, and this one would be reporting no
difference having compared nothing.

The workflow beside it asks on the weekly cadence the other three comparisons
against something published elsewhere use, and proves after every run, red or
green, that the tree it checked out is unchanged.

Signed-off-by: Nils Lehnen <30603423+iderex@users.noreply.github.com>
The comparison asks about twelve repositories in one run, and an anonymous
caller from a shared address does not get that far: a run taken on 2026-09-01
answered 403 for the fifth repository it asked about. A run that could not ask
says nothing about the record, which is the opposite of what a scheduled
comparison is for.

So the request that reads a release list carries a token where one is in the
environment, under the name a workflow already puts it, and the workflow hands
it the read-only one. No token is not an error: a contributor asking once is
inside the anonymous rate and should not have to hold a credential to run a
verb, and the refusal that matters is the one the request itself answers with.

The metadata beside a release carries no token. It is fetched from wherever
that release names, which is not this interface and is not a host this
repository chose, and a credential sent there is one handed to a third party.
The case beside the header proves both directions.

Signed-off-by: Nils Lehnen <30603423+iderex@users.noreply.github.com>
The record the pages compute the shipping state from was taken on 2026-08-26,
and the landing page states that day to a reader as the moment the data was
read. Two entries had moved under it since: `requests` published a second
finished release and `sso` published eight more and eight more prereleases.

Nothing had said so, which is what the comparison landing beside this exists to
end. It is re-taken here rather than left for the schedule to report, so that
the route lands green over a record that reproduces what is published rather
than red over one nothing had re-taken.

    go run . releases | tail -1
    releases: 12 repository(s) recorded as taken on 2026-09-01, 2 entry(s) moved, written to data/releases.json

Neither move changes a state word any page prints. The move that would is the
one nothing would have reported either.

Signed-off-by: Nils Lehnen <30603423+iderex@users.noreply.github.com>
@iderex
iderex merged commit 6541274 into main Sep 1, 2026
17 checks passed
@iderex
iderex deleted the ci/nothing-re-takes-the-release-record branch September 1, 2026 18:22
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.

Nothing re-takes the release record, and the page states its date as though it were current

1 participant