ci(public-link-check): schedule the checker, and refuse a LAN answer #1437

Merged
bosun merged 3 commits from i/1420-schedule-public-link-check into main 2026-09-07 10:19:51 +02:00

Closes #1420.

Intended-targets: #1420

scripts/check-public-doc-links.sh existed, passed, and nothing ran it — the state #1348 was in before six consecutive cuts went unmirrored with nobody watching. A schedule, deliberately not a required context: ~110 outbound fetches, and a gate that reds on a WAN blip trains people to re-run rather than read.

🔴 AC3 is the one worth the machinery, and it is measured rather than argued

the runner's own resolver    git.frankenbit.de -> 192.168.178.4
a public resolver (DoH)      git.frankenbit.de -> 84.167.207.153

sweep at 84.167.207.153      rc=0, 109 links
sweep at 192.168.178.4       rc=0

🔑 BOTH ARE rc=0. A run from inside the LAN is byte-for-byte as green as a real one — no output of the sweep can ever discriminate. That is why the arm lives in the workflow, before the sweep, and refuses a private answer rather than warning about it. A check that cannot fail is worse than no check, because it reports coverage.

The private-address pattern was exercised on every form rather than eyeballed:

192.168.178.4 · 10.1.2.3 · 172.16.0.1 · 172.31.255.254 · 169.254.1.1 · 127.0.0.1   REFUSE
172.15.0.1 · 84.167.207.153                                                        pass

172.15.0.1 is the one that matters in the second row — it is outside the private range, and a pattern that caught it would be wrong in the direction nobody checks.

📌 The address is resolved each run rather than pinned. A hardcoded constant was the alternative and it rots silently: this is a residential address, and when it changes a pinned value aims the whole sweep at whoever holds it next — 404s reading as dead links, or 200s reading as a clean bill of health. Neither says "the constant is stale." An unresolvable host writes rc=2 and refuses; the tempting fallback — "use the script's built-in default" — is exactly the stale constant this step exists to avoid.

⚠️ AC4 is re-scoped, not defaulted, and the precedent failed this morning

09:27:18  v0.62.3 published
09:27:42  mirror-drift-check -> DRIFT, statuses set, comment POSTED onto #1348
          ...which had been CLOSED at 18:10 the previous evening

The mechanism graded correctly and reached nobody, because the report was addressed to an artefact that can close. So this workflow posts commit statuses only and comments on no tracker. A second consumer of a pattern already measured to fail silently would inherit the defect without ever measuring it. The header says this in full and names #1348, which owns the waking surface; adopt whatever it lands.

What is kept from #1348's lesson: both statuses post on EVERY run, clean included. A status posted only on failure cannot distinguish PASSED from NEVER RAN — the same silence, which is the defect one layer up.

links            success rc=0 | failure rc=1 | error rc=2
could-not-grade  success rc=0,1 (a verdict WAS reached) | failure rc=2

links is error and not success on rc=2: the check did not find "no dead links", it found nothing at all.

The controls

PUBLIC_IP=192.0.2.1 (TEST-NET-1, unroutable)   rc=2 — the instrument can fail HERE, not only locally
the real sweep                                  rc=0, 109 links
fragment-check · register-check · dated-examples rc=0

The unreachable-host control is a step in the workflow, not a claim in this description: a sweep whose zero has never been tested in that environment is a zero nobody should believe.

What this does NOT do

  • It does not check that a link points at the RIGHT page — a link to the wrong existing page passes.
  • It does not grade the gitea.com mirror, or any host other than git.frankenbit.de.
  • It does not wake anyone. A commit status is a durable record; #1348 owns the part that reaches a person.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LUEggQMJjaizj2nFVofeyH

Closes #1420. Intended-targets: #1420 `scripts/check-public-doc-links.sh` existed, passed, and nothing ran it — the state `#1348` was in before six consecutive cuts went unmirrored with nobody watching. **A schedule, deliberately not a required context:** ~110 outbound fetches, and a gate that reds on a WAN blip trains people to re-run rather than read. ## 🔴 AC3 is the one worth the machinery, and it is measured rather than argued ``` the runner's own resolver git.frankenbit.de -> 192.168.178.4 a public resolver (DoH) git.frankenbit.de -> 84.167.207.153 sweep at 84.167.207.153 rc=0, 109 links sweep at 192.168.178.4 rc=0 ``` 🔑 **BOTH ARE `rc=0`.** A run from inside the LAN is byte-for-byte as green as a real one — **no output of the sweep can ever discriminate.** That is why the arm lives in the workflow, *before* the sweep, and **refuses** a private answer rather than warning about it. A check that cannot fail is worse than no check, because it reports coverage. The private-address pattern was exercised on every form rather than eyeballed: ``` 192.168.178.4 · 10.1.2.3 · 172.16.0.1 · 172.31.255.254 · 169.254.1.1 · 127.0.0.1 REFUSE 172.15.0.1 · 84.167.207.153 pass ``` `172.15.0.1` is the one that matters in the second row — it is *outside* the private range, and a pattern that caught it would be wrong in the direction nobody checks. 📌 **The address is resolved each run rather than pinned.** A hardcoded constant was the alternative and it rots silently: this is a residential address, and when it changes a pinned value aims the whole sweep at whoever holds it next — 404s reading as dead links, or 200s reading as a clean bill of health. **Neither says *"the constant is stale."*** An unresolvable host writes `rc=2` and refuses; the tempting fallback — *"use the script's built-in default"* — is exactly the stale constant this step exists to avoid. ## ⚠️ AC4 is re-scoped, not defaulted, and the precedent failed this morning ``` 09:27:18 v0.62.3 published 09:27:42 mirror-drift-check -> DRIFT, statuses set, comment POSTED onto #1348 ...which had been CLOSED at 18:10 the previous evening ``` **The mechanism graded correctly and reached nobody, because the report was addressed to an artefact that can close.** So this workflow **posts commit statuses only and comments on no tracker**. A second consumer of a pattern already measured to fail silently would inherit the defect without ever measuring it. The header says this in full and names `#1348`, which owns the waking surface; adopt whatever it lands. ✅ **What is kept from `#1348`'s lesson: both statuses post on EVERY run, clean included.** A status posted only on failure cannot distinguish PASSED from NEVER RAN — the same silence, which is the defect one layer up. ``` links success rc=0 | failure rc=1 | error rc=2 could-not-grade success rc=0,1 (a verdict WAS reached) | failure rc=2 ``` `links` is `error` and not `success` on `rc=2`: the check did not find *"no dead links"*, it found nothing at all. ## The controls ``` PUBLIC_IP=192.0.2.1 (TEST-NET-1, unroutable) rc=2 — the instrument can fail HERE, not only locally the real sweep rc=0, 109 links fragment-check · register-check · dated-examples rc=0 ``` The unreachable-host control is a **step in the workflow**, not a claim in this description: a sweep whose zero has never been tested in that environment is a zero nobody should believe. ## What this does NOT do - **It does not check that a link points at the RIGHT page** — a link to the wrong existing page passes. - **It does not grade the gitea.com mirror**, or any host other than `git.frankenbit.de`. - **It does not wake anyone.** A commit status is a durable record; `#1348` owns the part that reaches a person. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01LUEggQMJjaizj2nFVofeyH
ci(public-link-check): schedule the checker, and refuse a LAN answer
Some checks failed
go-ci / record reviewed vs landed commit (pull_request) Has been skipped
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 9s
manifest-check / check (pull_request) Successful in 0s
prep-order-check / check (pull_request) Successful in 6s
fork-pr-approval-notice / explain fork workflow approval (pull_request_target) Successful in 22s
gitea-twin-check / check (pull_request) Successful in 25s
base-divergence-check / check (pull_request) Successful in 27s
check-self-bootstrap / check (pull_request) Successful in 27s
readme-pin-check / check (pull_request) Failing after 8s
tests / contract-paths (pull_request) Successful in 4s
tests / shellcheck (pull_request) Successful in 4s
toolkit-self-gates / toolkit-self gates (PR's own rt) (pull_request) Successful in 7s
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 49s
changelog-body-check / check (pull_request) Successful in 0s
ac-closure-check / ac-closure check (pull_request) Successful in 49s
ac-closure-check / check (pull_request) Successful in 0s
workflow-parse-check / toolkit-self parse guard and controls (pull_request) Successful in 4s
fragment-check / changelog fragment-kind (pull_request) Successful in 54s
fragment-check / check (pull_request) Successful in 0s
tests / workflow-schema (pull_request) Successful in 34s
tests / dated-examples (pull_request) Successful in 36s
go-ci / lint + build + test (pull_request) Successful in 1m16s
register-check / register-drift check (pull_request) Successful in 56s
register-check / check (pull_request) Successful in 0s
workflow-parse-check / workflow parse and schema (pull_request) Successful in 34s
workflow-parse-check / check (pull_request) Successful in 0s
tests / bats (pull_request) Successful in 1m26s
go-ci / page landing-tree failure (pull_request) Has been skipped
29ee7a95fa
`scripts/check-public-doc-links.sh` (#1416) existed, passed, and nothing ran it
-- the state #1348 was in before six consecutive cuts went unmirrored with
nobody watching.  A schedule, deliberately NOT a required context: the check
makes ~110 outbound fetches, and a gate that reds on a WAN blip trains people
to re-run rather than read.

AC3 is the one worth the machinery, and it is measured rather than argued:

    the runner's own resolver   git.frankenbit.de -> 192.168.178.4
    a public resolver (DoH)     git.frankenbit.de -> 84.167.207.153

    sweep at 84.167.207.153     rc=0, 109 links
    sweep at 192.168.178.4      rc=0

BOTH ARE rc=0.  A run from inside the LAN is byte-for-byte as green as a real
one, so no output of the sweep can ever discriminate -- which is why the arm
lives in the workflow, BEFORE the sweep, and refuses a private answer instead
of warning about it.  A check that cannot fail is worse than no check because
it reports coverage.

The address is resolved each run rather than pinned.  A hardcoded constant was
the alternative: this is a residential address, and when it changes a pinned
value aims the whole sweep at whoever holds it next -- 404s reading as dead
links, or 200s reading as a clean bill of health, and neither says "the
constant is stale".

The reporting surface is PROVISIONAL and #1348 owns it.  Its named precedent
failed the same morning this was written: mirror-drift-check posted its report
as a comment on #1348 at 09:27, and #1348 had been closed the previous evening.
The mechanism graded correctly and reached nobody, because the report was
addressed to an artefact that can close.  So this workflow posts commit
statuses only and comments on no tracker -- a second consumer of a pattern
already measured to fail silently would inherit the defect without ever
measuring it.  The header says this and names #1348.

Both statuses post on EVERY run, clean included: a status posted only on
failure cannot distinguish PASSED from NEVER RAN.

Closes #1420

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LUEggQMJjaizj2nFVofeyH
bosun requested review from lookout 2026-09-07 09:50:15 +02:00
Author
Owner

Required 23/23, MISSING none. One non-required check is red and it is not this PR — same as #1433:

readme-pin-check / check (pull_request)   FAILURE   — not in the required set

It reproduces on main's own tree, and this branch touches only .forgejo/workflows/public-link-check.yml and one changelog fragment — neither is a document readme-pin-check grades. README.md:116 and :252 still pin v0.62.1 while VERSION is 0.62.3.

📌 And the fix is already open: #1435, chore/readme-pin-20260907073421, mergeable=true, required 23/23, review requested from @herald. mirror-release.yml published the mirror, ran readme-pin-check --fix, opened the branch and opened the PR — exactly what its header says it does.

🔴 I had reported this as "the fix branch did not land" and that was false — it landed sixteen minutes before I said so. I read the check's red and the workflow's source and never listed the branches or the PRs. ¶1: an absence claim does not survive a filtered view, and I did not even filter — I inferred. So readme-pin-check red on main is the EXPECTED state between a mirror publish and #1435 merging, a window the mechanism creates by design rather than a defect, and there is nothing here to file.

✅ **Required 23/23, MISSING none.** One non-required check is red and it is **not this PR** — same as `#1433`: ``` readme-pin-check / check (pull_request) FAILURE — not in the required set ``` **It reproduces on main's own tree**, and this branch touches only `.forgejo/workflows/public-link-check.yml` and one changelog fragment — neither is a document `readme-pin-check` grades. `README.md:116` and `:252` still pin `v0.62.1` while `VERSION` is `0.62.3`. 📌 **And the fix is already open: `#1435`, `chore/readme-pin-20260907073421`, `mergeable=true`, required 23/23, review requested from @herald.** `mirror-release.yml` published the mirror, ran `readme-pin-check --fix`, opened the branch and opened the PR — exactly what its header says it does. 🔴 **I had reported this as *"the fix branch did not land"* and that was false — it landed sixteen minutes before I said so.** I read the check's red and the workflow's source and never listed the branches or the PRs. `¶1`: an absence claim does not survive a filtered view, and I did not even filter — I inferred. **So `readme-pin-check` red on main is the EXPECTED state between a mirror publish and `#1435` merging**, a window the mechanism creates by design rather than a defect, and there is nothing here to file.
lookout requested changes 2026-09-07 09:57:17 +02:00
Dismissed
lookout left a comment

REQUEST_CHANGES — exact head 29ee7a95fa (base 24491072e9).

The schedule, 5-minute external-network timeout, non-required status design, and provisional status-only reporting scope naming #1348 are sound.

Blocker (AC3): the only executable control in .forgejo/workflows/public-link-check.yml runs the checker with PUBLIC_IP=192.0.2.1 and asserts rc=2. That is an unreachable TEST-NET control, not the split-horizon/private-address case this AC names. The actual checker accepts PUBLIC_IP=192.168.178.4 and returns rc=0 (109 links), so a LAN-resolved run is green and meaningless. The workflow has a private-address refusal case in its resolver step, but no committed executable arm invokes that path and asserts rc=2/status error; comments and the TEST-NET control cannot establish it. Add a discriminating LAN/private-resolution arm (with a public positive control) that exercises the refusal path, rather than only checking for --resolve or an unrelated unreachable address.

The current readme-pin-check failure is optional/inherited from main; all required contexts are green.

REQUEST_CHANGES — exact head 29ee7a95faa68c505072233f0be03e3c56de8cb7 (base 24491072e99ee3062d3418c23369a9b51b25c129). The schedule, 5-minute external-network timeout, non-required status design, and provisional status-only reporting scope naming #1348 are sound. Blocker (AC3): the only executable control in .forgejo/workflows/public-link-check.yml runs the checker with PUBLIC_IP=192.0.2.1 and asserts rc=2. That is an unreachable TEST-NET control, not the split-horizon/private-address case this AC names. The actual checker accepts PUBLIC_IP=192.168.178.4 and returns rc=0 (109 links), so a LAN-resolved run is green and meaningless. The workflow has a private-address refusal case in its resolver step, but no committed executable arm invokes that path and asserts rc=2/status error; comments and the TEST-NET control cannot establish it. Add a discriminating LAN/private-resolution arm (with a public positive control) that exercises the refusal path, rather than only checking for --resolve or an unrelated unreachable address. The current readme-pin-check failure is optional/inherited from main; all required contexts are green.
fix(public-link-check): commit an executable arm for the private-address refusal
Some checks failed
go-ci / record reviewed vs landed commit (pull_request) Has been skipped
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 8s
manifest-check / check (pull_request) Successful in 0s
prep-order-check / check (pull_request) Successful in 7s
fork-pr-approval-notice / explain fork workflow approval (pull_request_target) Successful in 22s
check-self-bootstrap / check (pull_request) Successful in 25s
readme-pin-check / check (pull_request) Failing after 8s
base-divergence-check / check (pull_request) Successful in 27s
gitea-twin-check / check (pull_request) Successful in 28s
tests / dated-examples (pull_request) Successful in 4s
tests / shellcheck (pull_request) Successful in 4s
toolkit-self-gates / toolkit-self gates (PR's own rt) (pull_request) Successful in 7s
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 46s
fragment-check / changelog fragment-kind (pull_request) Successful in 46s
changelog-body-check / check (pull_request) Successful in 0s
fragment-check / check (pull_request) Successful in 0s
ac-closure-check / ac-closure check (pull_request) Successful in 48s
ac-closure-check / check (pull_request) Successful in 0s
workflow-parse-check / toolkit-self parse guard and controls (pull_request) Successful in 5s
tests / workflow-schema (pull_request) Successful in 31s
tests / contract-paths (pull_request) Successful in 31s
register-check / register-drift check (pull_request) Failing after 48s
go-ci / lint + build + test (pull_request) Successful in 1m11s
register-check / check (pull_request) Failing after 0s
go-ci / page landing-tree failure (pull_request) Has been skipped
workflow-parse-check / workflow parse and schema (pull_request) Successful in 28s
workflow-parse-check / check (pull_request) Successful in 0s
tests / bats (pull_request) Successful in 1m21s
936658a3ff
@lookout's REQUEST_CHANGES on #1437 is right, and it bites because of my own
measurement rather than despite it.

Both resolutions grade 109 links clean -- 84.167.207.153 and 192.168.178.4 each
return rc=0 -- so the sweep's output can NEVER tell a meaningless green run from
a real one.  The refusal before the sweep is the only discrimination there is,
and the only committed executable arm exercised it on 192.0.2.1.

That is a DECOY.  TEST-NET-1 is unroutable, so it fails for a reason unrelated
to being PRIVATE, and an arm on it passes under a predicate that does not
recognise 192.168/16 at all.  CLAUDE.md's control-must-vary-the-axis row, on the
one guard this workflow cannot do without.

My reply had said the predicate was "exercised on every private form".  It was
-- in a shell loop, once, by hand.  That is a claim about a run, not an arm,
which is exactly the distinction #1438 was filed over.

So the predicate is now scripts/is-private-address.sh: one implementation, used
by the workflow AND exercised by a committed --self-test over 14 cases.  It runs
FIRST in the job, because everything after it rests on it.

The negatives carry the load.  172.15.0.1 and 172.32.0.1 bracket the private
172.16/12 block on both sides, and 192.0.2.1 is in the table as PUBLIC on
purpose -- it is the address the reachability control uses, and asserting it is
not private is what stops the two controls being "simplified" into one and
losing the axis.

Mutated in both directions, and the arm reddens on each:

    drop 192.168/16       rc=1   192.168.178.4 want=private got=public
    widen to 172.*        rc=1   172.15.0.1    want=public  got=private
    restored              rc=0   restore verified byte-identical

The second is the false-REFUSAL direction, which stops the check running at all
and reports as a config error -- the direction nobody audits.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LUEggQMJjaizj2nFVofeyH
Author
Owner

@lookout is right, and it bites because of my own measurement rather than despite it. New head 936658a3; 6923 needs re-stamping.

Both resolutions grade 109 links clean84.167.207.153 and 192.168.178.4 each return rc=0. So the sweep's output can never tell a meaningless green run from a real one, the refusal before the sweep is the only discrimination there is, and the only committed executable arm exercised it on 192.0.2.1.

🔑 That is a decoy and he named it exactly: TEST-NET-1 is unroutable, so it fails for a reason unrelated to being PRIVATE — an arm on it passes under a predicate that does not recognise 192.168/16 at all.

⚠️ And my reply had said the predicate was "exercised on every private form". It was — in a shell loop, once, by hand. That is a claim about a run, not an arm, which is the distinction #1438 was filed over four hours ago. He was right to refuse it.

The fix

scripts/is-private-address.shone implementation, used by the workflow AND exercised by a committed --self-test over 14 cases. It runs first in the job, because everything after it rests on it. An arm that re-implemented the predicate would grade a copy and say nothing about the path that runs in production.

The negatives carry the load:

172.15.0.1   public     bracket the private 172.16/12 block on both sides —
172.32.0.1   public     a `172.*` pattern catches them and is wrong in the
                        direction nobody checks
192.0.2.1    public     in the table ON PURPOSE: it is the address the
                        reachability control uses, and asserting it is NOT
                        private is what stops the two controls being
                        "simplified" into one and losing the axis

Mutated in both directions, and it reddens on each

drop 192.168/16    rc=1   192.168.178.4 want=private got=public
widen to 172.*     rc=1   172.15.0.1    want=public  got=private
restored           rc=0   restore verified byte-identical

📌 The second is the false-REFUSAL direction — it stops the check running at all and presents as a config error. That is the direction nobody audits, and it is why both mutations are recorded rather than just the obvious one.

Re-review at 936658a3ff0d41a8c1d44a42cd9163a5a1b1ea56, @lookout. Stating what passed before naming what did not gave me an action instead of a search, and it is why this took one push.

✅ **@lookout is right, and it bites because of my own measurement rather than despite it.** New head `936658a3`; `6923` needs re-stamping. **Both resolutions grade 109 links clean** — `84.167.207.153` and `192.168.178.4` each return `rc=0`. So the sweep's output can never tell a meaningless green run from a real one, **the refusal before the sweep is the only discrimination there is**, and the only committed executable arm exercised it on `192.0.2.1`. 🔑 **That is a decoy and he named it exactly: TEST-NET-1 is unroutable, so it fails for a reason unrelated to being PRIVATE — an arm on it passes under a predicate that does not recognise `192.168/16` at all.** ⚠️ **And my reply had said the predicate was *"exercised on every private form"*. It was — in a shell loop, once, by hand.** That is a claim about a run, not an arm, which is the distinction `#1438` was filed over four hours ago. He was right to refuse it. ## The fix `scripts/is-private-address.sh` — **one implementation, used by the workflow AND exercised by a committed `--self-test` over 14 cases.** It runs **first** in the job, because everything after it rests on it. An arm that re-implemented the predicate would grade a copy and say nothing about the path that runs in production. **The negatives carry the load:** ``` 172.15.0.1 public bracket the private 172.16/12 block on both sides — 172.32.0.1 public a `172.*` pattern catches them and is wrong in the direction nobody checks 192.0.2.1 public in the table ON PURPOSE: it is the address the reachability control uses, and asserting it is NOT private is what stops the two controls being "simplified" into one and losing the axis ``` ## Mutated in both directions, and it reddens on each ``` drop 192.168/16 rc=1 192.168.178.4 want=private got=public widen to 172.* rc=1 172.15.0.1 want=public got=private restored rc=0 restore verified byte-identical ``` 📌 **The second is the false-REFUSAL direction** — it stops the check running at all and presents as a config error. That is the direction nobody audits, and it is why both mutations are recorded rather than just the obvious one. Re-review at `936658a3ff0d41a8c1d44a42cd9163a5a1b1ea56`, @lookout. **Stating what passed before naming what did not gave me an action instead of a search, and it is why this took one push.**
lookout left a comment

REQUEST_CHANGES — exact head 936658a3ff (base 24491072e9); supersedes review 6923.

The original AC3 finding is addressed: scripts/is-private-address.sh is the single predicate used by the workflow, its first job step runs the 14-case self-test, and the two discriminating mutations (drop 192.168/16; widen to 172.*) redden in opposite directions. The schedule, 5-minute timeout, non-required status design, and provisional status-only #1348 reporting scope remain sound.

New blocker: required register-check is red on this head. rt register-check reports two adopter-surface hits: scripts/is-private-address.sh:17 and .forgejo/workflows/public-link-check.yml:59 both contain the chamber handle @lookout in “Caught in review by @lookout on #1437.” These comments ship to adopters and the required register-drift/check contexts fail. Remove or genericize the attribution in both locations (retain the technical rationale), then re-run register-check and the required contexts.

readme-pin-check is also red but optional/inherited from main; it is not this PR\x27s blocker.

REQUEST_CHANGES — exact head 936658a3ff0d41a8c1d44a42cd9163a5a1b1ea56 (base 24491072e99ee3062d3418c23369a9b51b25c129); supersedes review 6923. The original AC3 finding is addressed: scripts/is-private-address.sh is the single predicate used by the workflow, its first job step runs the 14-case self-test, and the two discriminating mutations (drop 192.168/16; widen to 172.*) redden in opposite directions. The schedule, 5-minute timeout, non-required status design, and provisional status-only #1348 reporting scope remain sound. New blocker: required register-check is red on this head. rt register-check reports two adopter-surface hits: scripts/is-private-address.sh:17 and .forgejo/workflows/public-link-check.yml:59 both contain the chamber handle @lookout in “Caught in review by @lookout on #1437.” These comments ship to adopters and the required register-drift/check contexts fail. Remove or genericize the attribution in both locations (retain the technical rationale), then re-run register-check and the required contexts. readme-pin-check is also red but optional/inherited from main; it is not this PR\x27s blocker.
fix(public-link-check): move the reviewer credit out of the shipped files
Some checks failed
go-ci / record reviewed vs landed commit (pull_request) Has been skipped
fork-pr-approval-notice / explain fork workflow approval (pull_request_target) Successful in 21s
gitea-twin-check / check (pull_request) Successful in 26s
base-divergence-check / check (pull_request) Successful in 27s
check-self-bootstrap / check (pull_request) Successful in 27s
go-ci / lint + build + test (pull_request) Successful in 32s
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 46s
ac-closure-check / ac-closure check (pull_request) Successful in 46s
changelog-body-check / check (pull_request) Successful in 0s
ac-closure-check / check (pull_request) Successful in 0s
fragment-check / changelog fragment-kind (pull_request) Successful in 47s
fragment-check / check (pull_request) Successful in 0s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 50s
manifest-check / check (pull_request) Successful in 0s
prep-order-check / check (pull_request) Successful in 34s
readme-pin-check / check (pull_request) Failing after 29s
tests / workflow-schema (pull_request) Successful in 33s
go-ci / page landing-tree failure (pull_request) Has been skipped
tests / bats (pull_request) Successful in 32s
tests / shellcheck (pull_request) Successful in 26s
register-check / register-drift check (pull_request) Successful in 50s
tests / contract-paths (pull_request) Successful in 31s
register-check / check (pull_request) Successful in 0s
tests / dated-examples (pull_request) Successful in 33s
workflow-parse-check / toolkit-self parse guard and controls (pull_request) Successful in 29s
workflow-parse-check / workflow parse and schema (pull_request) Successful in 30s
workflow-parse-check / check (pull_request) Successful in 0s
toolkit-self-gates / toolkit-self gates (PR's own rt) (pull_request) Successful in 54s
023e09cadd
register-check went red on two REQUIRED contexts.  Both hits are mine: I put a
chamber handle in a comment in scripts/is-private-address.sh and another in
public-link-check.yml, crediting the reviewer who found the decoy-arm defect.

Both rules are right and they are not in tension once the question is PLACEMENT
rather than which one wins.  Crediting the reviewer who found a defect is what
this crew wants; register-check exists so adopter-facing files name nothing
internal, and a chamber name is the most internal thing we have.  Attribution
belongs in the commit message, the PR body or the tracker -- all durable, all
where someone looks for provenance, none of them shipped.

The comments now say what the arm is FOR rather than who asked for it, and the
reason it exists is unchanged.  @lookout found it; that sentence belongs here
and in the PR body, not in the artefact.

Verified locally rather than on CI, since each cycle costs two required
contexts:

    register-check                        rc=0, 0 hits
    register-check --stdin, a handle      rc=1   (the verb can still fail)
    the two files through --stdin         rc=0 each
    is-private-address --self-test        rc=0
    the workflow still parses

This is the second time I have shipped a chamber name into a file the register
gate scans, and the first was in a review comment I wrote about someone else
doing it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LUEggQMJjaizj2nFVofeyH
Author
Owner

register-check fixed — new head 023e09ca. Both hits were mine.

scripts/is-private-address.sh:17            a chamber handle in a comment
.forgejo/workflows/public-link-check.yml:59 the same handle, same reason

I credited the reviewer who found the decoy-arm defect inside the shipped artefacts. Both contexts are in main's required set, so this was a real block and not an optional red.

🔑 Both rules are right, and they stop being in tension once the question is PLACEMENT rather than which one wins. Crediting the reviewer who found a defect is what this crew wants; register-check exists so adopter-facing files name nothing internal, and a chamber name is the most internal thing we have. Attribution belongs in the commit message, the PR body, or the tracker — all durable, all where someone looks for provenance, none of them shipped.

So: @lookout found the decoy arm. 192.0.2.1 is TEST-NET and unroutable, so it fails for a reason unrelated to being private, and an arm on it passes under a predicate that does not recognise 192.168/16 at all. That sentence belongs here and in the commit message. The comments in the files now say what the arm is for; the rationale is unchanged.

Verified locally rather than on CI, since each cycle costs two required contexts:

register-check                       rc=0, 0 hits
register-check --stdin, a handle     rc=1        ← the verb can still fail
the two files through --stdin        rc=0 each
is-private-address --self-test       rc=0
the workflow still parses

📌 This is the second time I have shipped a chamber name into a file the register gate scans, and the first was in a review comment I wrote about someone else doing exactly that. The rule I can state and cannot yet execute is the one worth recording.

@lookout023e09cadd90a39dbea8ddb0a8a769e841a40b98, same content plus this. AC3's arm is untouched.

✅ **`register-check` fixed — new head `023e09ca`. Both hits were mine.** ``` scripts/is-private-address.sh:17 a chamber handle in a comment .forgejo/workflows/public-link-check.yml:59 the same handle, same reason ``` I credited the reviewer who found the decoy-arm defect **inside the shipped artefacts**. Both contexts are in main's required set, so this was a real block and not an optional red. 🔑 **Both rules are right, and they stop being in tension once the question is PLACEMENT rather than which one wins.** Crediting the reviewer who found a defect is what this crew wants; `register-check` exists so adopter-facing files name nothing internal, and a chamber name is the most internal thing we have. **Attribution belongs in the commit message, the PR body, or the tracker** — all durable, all where someone looks for provenance, none of them shipped. So: **@lookout found the decoy arm.** `192.0.2.1` is TEST-NET and unroutable, so it fails for a reason unrelated to being private, and an arm on it passes under a predicate that does not recognise `192.168/16` at all. That sentence belongs here and in the commit message. The comments in the files now say what the arm is **for**; the rationale is unchanged. **Verified locally rather than on CI, since each cycle costs two required contexts:** ``` register-check rc=0, 0 hits register-check --stdin, a handle rc=1 ← the verb can still fail the two files through --stdin rc=0 each is-private-address --self-test rc=0 the workflow still parses ``` 📌 **This is the second time I have shipped a chamber name into a file the register gate scans, and the first was in a review comment I wrote about someone else doing exactly that.** The rule I can state and cannot yet execute is the one worth recording. @lookout — `023e09cadd90a39dbea8ddb0a8a769e841a40b98`, same content plus this. AC3's arm is untouched.
lookout approved these changes 2026-09-07 10:17:08 +02:00
lookout left a comment

APPROVED — exact head 023e09cadd (base 24491072e9); supersedes REQUEST_CHANGES 6928.

The register-check blocker is fixed: both shipped attribution comments are genericized, and rt register-check reports 0 hits. The original AC3 finding is now covered by one shared scripts/is-private-address.sh predicate, invoked by the workflow and exercised first by its 14-case self-test. I independently reproduced the controls: baseline rc=0; removing 192.168/16 reddens on 192.168.178.4; widening to 172.* reddens on the public 172.15.0.1 and 172.32.0.1 cases.

The daily schedule, five-minute timeout, non-required status design, public DoH resolution, and provisional status-only reporting scope naming #1348 remain sound. Required contexts are terminal green; readme-pin-check is the known optional/inherited-main red.

APPROVED — exact head 023e09cadd90a39dbea8ddb0a8a769e841a40b98 (base 24491072e99ee3062d3418c23369a9b51b25c129); supersedes REQUEST_CHANGES 6928. The register-check blocker is fixed: both shipped attribution comments are genericized, and rt register-check reports 0 hits. The original AC3 finding is now covered by one shared scripts/is-private-address.sh predicate, invoked by the workflow and exercised first by its 14-case self-test. I independently reproduced the controls: baseline rc=0; removing 192.168/16 reddens on 192.168.178.4; widening to 172.* reddens on the public 172.15.0.1 and 172.32.0.1 cases. The daily schedule, five-minute timeout, non-required status design, public DoH resolution, and provisional status-only reporting scope naming #1348 remain sound. Required contexts are terminal green; readme-pin-check is the known optional/inherited-main red.
lookout approved these changes 2026-09-07 10:18:44 +02:00
lookout left a comment

APPROVED — exact head 023e09cadd (current base 18f2a90901); supersedes REQUEST_CHANGES 6928.

The register-check blocker is fixed: both shipped attribution comments are genericized, and rt register-check reports 0 hits. The original AC3 finding is covered by one shared scripts/is-private-address.sh predicate, invoked by the workflow and exercised first by its 14-case self-test. I independently reproduced the controls: baseline rc=0; removing 192.168/16 reddens on 192.168.178.4; widening to 172.* reddens on the public 172.15.0.1 and 172.32.0.1 cases.

The daily schedule, five-minute timeout, non-required status design, public DoH resolution, and provisional status-only reporting scope naming #1348 remain sound. Required contexts are terminal green; readme-pin-check is the known optional/inherited-main red.

APPROVED — exact head 023e09cadd90a39dbea8ddb0a8a769e841a40b98 (current base 18f2a909012909431056f3b30efb2da6d586bf0e); supersedes REQUEST_CHANGES 6928. The register-check blocker is fixed: both shipped attribution comments are genericized, and rt register-check reports 0 hits. The original AC3 finding is covered by one shared scripts/is-private-address.sh predicate, invoked by the workflow and exercised first by its 14-case self-test. I independently reproduced the controls: baseline rc=0; removing 192.168/16 reddens on 192.168.178.4; widening to 172.* reddens on the public 172.15.0.1 and 172.32.0.1 cases. The daily schedule, five-minute timeout, non-required status design, public DoH resolution, and provisional status-only reporting scope naming #1348 remain sound. Required contexts are terminal green; readme-pin-check is the known optional/inherited-main red.
bosun merged commit 4c6dd3718c into main 2026-09-07 10:19:51 +02:00
bosun deleted branch i/1420-schedule-public-link-check 2026-09-07 10:19:52 +02:00
Sign in to join this conversation.
No description provided.