docs: record the LDE promotion, and what closing its main gap taught - #89
Merged
Merged
Conversation
Second half of this revision. The ttl-editor edits already in the working tree covered that repository's production run, its mirror divergence and the CI-skip finding; this adds what Linked Data Explorer did on the same day, and updates the claims about it that those edits left standing. Verified head moves afb182e -> 36c4246. ── Build provenance: two of three, not one ── The section read "still wired and unexercised in the other two". Linked Data Explorer ran its production workflow hours later, promoting acc to main and publishing nineteen changelog entries — ten weeks, 1.9.9 to 2026.09.2 — and its production changelog now reads `build 007b350 · #39`, confirmed by eye. Two things that run adds to ttl-editor's: the SHA is the promotion's merge commit while the run number is what a redeploy would change, which is the whole argument for carrying both; and reading the changelog is the check, because the workflow succeeds identically whether the env: block reached the artifact or not. Only ronl-business-api is now wired-and-unexercised. ── The ruleset question, asked of the second repository ── The ttl-editor edits ended on "the same question is worth asking of the other two: a ruleset naming one branch says nothing about any other." Asked here, the answer was worse: linked-data-explorer's main had no ruleset at all, not even the pull request ttl-editor's main requires. Anyone could have pushed to it, or squashed a promotion and orphaned every SHA cited across seventy-five changelog entries. Closed before the promotion, with three findings worth more than the fix: - A required check must actually reach the branch. Requiring `audit` on main works only because zizmor.yml triggers on a bare pull_request: with no branch filter — a fix that landed in the same release. Before it, this would have deadlocked the promotion permanently. - Omitting a ruleset parameter is not setting it false. The create call left require_extra_approval_for_unattributed_changes out; GitHub stored it as true. With 206 commits, zero required approvals and no second maintainer, that would have blocked the pull request the ruleset existed to protect. Found by reading the stored ruleset back rather than trusting the write. - The promotion pull request is itself the proof, and costs nothing: it reported BLOCKED on the pending audit. Do not test a branch ruleset by pushing to the branch — if it is misconfigured the push succeeds, and the test was the promotion. ── Two corrections to what production actually does ── A protected environment protects the jobs that declare it. Of three production workflows here, only the backend names `environment: production`; frontend and ropa-site ship unattended. Confirmed on the promotion — the backend paused and recorded an approval while the other two deployed straight through. The asymmetry is deliberate, but "production requires reviewers" describes one third of what deploys. And a workflow that names its own file in its paths: filter fires when only that file changed. ropa-site was predicted not to deploy — no packages/ropa-site/** content differed — and deployed twice. Its filter's second entry is itself, and the supply-chain work had changed it by 21 lines. A repository-wide pass over workflow files rearms every such filter at once. ── Mirror: behind is not diverged ── ttl-editor's mirror needed tree comparison, an archive branch and a force-with-lease. This one needed one push per branch: gitlab was 114 and 253 commits behind and zero ahead, so both were strict ancestors. `git merge-base --is-ancestor` is the one command that separates the two cases before anything is pushed; commit counts do not, because "253 behind" and "18 ahead and 306 behind" both read as stale. Also recorded: push the remote-tracking ref, not the local branch. Local main was still a four-month-old merge node origin/main had never contained, and `git push gitlab main` would have sent that tree to the mirror. ── Open work ── Closed for this repository: the unexercised build id, the unprotected main, and the stale mirror. ttl-editor's own main row survives — closing a gap in one repository says nothing about another, which is why the rows are per repository. Two new rows, both noticed while doing something else: #80 sets engines.node to >=24.20.0 while pinning 24.19.0 in all four workflows, and changelog entry 1.9.12 still carries the legacy "Latest" status, now rendering that badge on a July entry below 2026.09.2 in production. The closing checklist gains three items: enumerate the branches a ruleset does not name, read a ruleset back after writing it, and predict deploys from the whole paths: list.
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.
Second half of this revision. The ttl-editor edits already in the tree covered
that repository's production run, its mirror divergence and the CI-skip finding;
this adds what Linked Data Explorer did on the same day, and updates the claims
about it those edits left standing.
Verified head moves
afb182e→36c4246.Build provenance — two of three, not one
The section read "still wired and unexercised in the other two". Linked Data
Explorer ran its production workflow hours later, promoting
acctomainandpublishing nineteen changelog entries — ten weeks,
1.9.9→2026.09.2.Its production changelog now reads
build 007b350 · #39, confirmed by eye.Two things that run adds to ttl-editor's:
007b350is the promotion's mergecommit;
#39is the run that built it. A redeploy of that same commit gives#40— the whole argument for carrying both.whether the
env:block reached the artifact or not.Only
ronl-business-apiis now wired-and-unexercised.The ruleset question, asked of the second repository
The ttl-editor edits ended on "the same question is worth asking of the other
two: a ruleset naming one branch says nothing about any other."
Asked here, the answer was worse:
mainhad no ruleset at all — not even thepull request ttl-editor's
mainrequires. Anyone could have pushed to itdirectly, or squashed a promotion and orphaned every SHA cited across all
seventy-five changelog entries.
Closed before the promotion. Three findings worth more than the fix:
auditonmainworks only becausezizmor.ymltriggers on a barepull_request:with no branch filter — a fix that landed in the same release. Before it, this
would have deadlocked the promotion permanently.
require_extra_approval_for_unattributed_changesout; GitHub stored it astrue. With 206 commits, zero required approvals and no second maintainer,that would have blocked the very pull request the ruleset existed to protect.
Found by reading the stored ruleset back rather than trusting the write.
reported
BLOCKEDon the pendingaudit. Do not test a branch ruleset bypushing to the branch: if it is misconfigured the push succeeds, and the test
was the promotion.
Two corrections to what production actually does
A protected environment protects the jobs that declare it. Of three
production workflows here, only the backend names
environment: production;frontend and ropa-site ship unattended. Confirmed on the promotion — the backend
paused and recorded an approval while the other two deployed straight through.
The asymmetry is deliberate, but "production requires reviewers" describes one
third of what deploys.
A workflow that names its own file in its
paths:filter is a trigger.ropa-site was predicted not to deploy — no
packages/ropa-site/**contentdiffered — and deployed twice. Its filter's second entry is itself, and the
supply-chain work had changed it by 21 lines. A repository-wide pass over
workflow files rearms every such filter at once.
Mirror — behind is not diverged
ttl-editor's mirror needed tree comparison, an archive branch and a
--force-with-lease. This one needed one push per branch: GitLab was 114 and 253commits behind and zero ahead, so both were strict ancestors.
git merge-base --is-ancestoris the one command separating the two cases beforeanything is pushed. Commit counts do not — "253 behind" and "18 ahead and 306
behind" both read as stale.
Also recorded: push the remote-tracking ref, not the local branch. Local
mainwas still a four-month-old merge nodeorigin/mainhad never contained;git push gitlab mainwould have sent that tree to the mirror.Open work
Closed for this repository: the unexercised build id, the unprotected
main, andthe stale mirror. ttl-editor's own
mainrow survives — closing a gap in onerepository says nothing about another, which is why the rows are per repository.
Two new rows, both noticed while doing something else:
engines.node >=24.20.0while pinning24.19.0in all fourworkflows
1.9.12still carries the legacyLateststatus, nowrendering that badge on a July entry below
2026.09.2in productionThe closing checklist gains three items: enumerate the branches a ruleset does
not name, read a ruleset back after writing it, and predict deploys from the
whole
paths:list.Scope
Documentation only — one file, +350/−25. No workflow, config or source change.
Prettier-clean.