fix(docs): grade relative links and cross-file anchors; retarget five broken links #1558

Merged
alex merged 2 commits from claude/1557-relative-link-gate into main 2026-10-06 01:17:11 +02:00
Member

Refs #1557

Summary

  • scripts/anchor-check.py now grades every relative link in README.md, AGENTS.md, docs/** and .forgejo/**. The target file must exist with that exact case. A fragment on a markdown target must be an id that the target's headings render to, using the same Forgejo renderer call the in-document check already used.
  • The c7 controls in tests / checks gain two mutants, a broken cross-file anchor and a link to a missing file. Each must exit 1.
  • The five broken links from #1557 are retargeted. None were dropped.

no-changelog: toolkit-self CI gate and doc link targets only; no rt, reusable-workflow or adopter-facing behaviour changes

# Link Disposition
1 docs/dead-script-namespace.md:464 0001-language-shell.md retargeted to adr/0001-language-shell.md. The link sits in an excerpt the ledger quotes from ADR-0004, where it was relative to docs/adr/, so the quoted text now differs from its source by that path prefix.
2 docs/dead-script-namespace.md:465 0002-conventional-commits-from-day-one.md retargeted to adr/0002-..., for the same reason.
3 docs/adr/0006-...:272 AGENTS.md#...-at-v062-... retargeted to #10-substrate-grounding-arc-converged-at-v0-6-2-2026-06-26 (the renderer's id)
4 docs/integration.md:686 conventions.md#pre-10-... retargeted to #pre-1-0-opt-in-pre_v1_breaking_to_minor
5 docs/migration/tmux-tell.md:27 integration.md#post-bump-hooks retargeted to #post-bump-hooks-post_bump_hooks (the heading is Post-bump hooks: post_bump_hooks)

Each id was read from the Forgejo renderer, not guessed.

Measured

  • On origin/main (a4aab90), the extended check reports exactly these five as UNRESOLVED and nothing else (rc=1). On this branch: 62 files, 70 in-document anchors (the old script's count too), 246 relative file links (54 of them with a markdown anchor), 0 unresolved, rc=0. The 99 links it does not grade are all https: links.
  • c6 and c7, extracted from this tests.yml and run in a python:3.12-slim container against git.frankenbit.de: both exit 0 and write their verdicts. All three mutants and the rc=2 outage control report as expected.
  • Mutation (AGENTS.md section 8, Axis B): the cross-file-anchor mutant and the missing-file mutant each exit 0 on the old script and 1 on the new one, so neither control is a placebo. Reverting fix 5 alone, or fix 1 alone, turns c6 red.
  • Case: on Windows, [o](Other.md) with only other.md on disk exits 0 on the old script and 1 on the new one.
  • tests/workflows.bats in a container: 131 ok, 1 not ok. The failure is test 83 (mirror path, exit 127, command not found), which comes from the bare bats image missing a tool. This diff does not touch it. The #1451 assertion (exactly one captured-rc anchor invocation) passes, because c7 still exits with exit 1, not exit "$rc".
  • tests.yml and anchor-check.py are ASCII-only (AGENTS.md section 11). The old script's non-ASCII punctuation was replaced while it was being rewritten.

Decisions

  • Extend the anchor check, or add a separate link gate? Extending is right while one renderer call and one rc contract serve both. A separate gate is right if file-link grading ever needs to run without the renderer, for example offline. Today it does not, and extending avoids a new step and verdict id.
  • New CI step, or more controls in c7? Folding the mutants into c7 is right while they share c7's fixture and renderer. A new step (with its own verdict, GATE_IDS entry and both guard bindings, per #1540) is right if a control needs a tree mutation, which c7's RUNNER_TEMP fixture does not. So GATE_IDS and the two guard steps are unchanged.
  • Not graded: scheme links and site-absolute /... links leave the tree, so the tree cannot answer for them. Fragments on non-markdown targets (main.go#L12) are line anchors in the file viewer, not rendered headings. The summary line counts all of these as "not graded".

Self-bootstrap (AGENTS.md section 2)

No re-pin: toolkit-self floats @main (AGENTS.md section 2.1). This PR touches no compose script anyway. tests.yml is toolkit-self CI and is not in gates.DefaultComposeScripts.

Review

@alex: please verify at source, both halves:

  1. run FORGEJO_BASE_URL=https://git.frankenbit.de python3 scripts/anchor-check.py on this head (rc=0) and on a4aab90 (rc=1, the five links);
  2. read the c7 log on this PR's tests / checks run, and check that the two new control OK lines appear for the cross-file anchor and the missing file.

Head: 9726eab464fd802f903da4a7d81003714c2b18cb

🤖 Generated with Claude Code

Refs #1557 ## Summary - `scripts/anchor-check.py` now grades every relative link in README.md, AGENTS.md, docs/** and .forgejo/**. The target file must exist with that exact case. A fragment on a markdown target must be an id that the target's headings render to, using the same Forgejo renderer call the in-document check already used. - The c7 controls in `tests / checks` gain two mutants, a broken cross-file anchor and a link to a missing file. Each must exit 1. - The five broken links from #1557 are retargeted. None were dropped. no-changelog: toolkit-self CI gate and doc link targets only; no rt, reusable-workflow or adopter-facing behaviour changes ## The five links | # | Link | Disposition | |---|---|---| | 1 | `docs/dead-script-namespace.md:464` `0001-language-shell.md` | **retargeted** to `adr/0001-language-shell.md`. The link sits in an excerpt the ledger quotes from ADR-0004, where it was relative to `docs/adr/`, so the quoted text now differs from its source by that path prefix. | | 2 | `docs/dead-script-namespace.md:465` `0002-conventional-commits-from-day-one.md` | **retargeted** to `adr/0002-...`, for the same reason. | | 3 | `docs/adr/0006-...:272` `AGENTS.md#...-at-v062-...` | **retargeted** to `#10-substrate-grounding-arc-converged-at-v0-6-2-2026-06-26` (the renderer's id) | | 4 | `docs/integration.md:686` `conventions.md#pre-10-...` | **retargeted** to `#pre-1-0-opt-in-pre_v1_breaking_to_minor` | | 5 | `docs/migration/tmux-tell.md:27` `integration.md#post-bump-hooks` | **retargeted** to `#post-bump-hooks-post_bump_hooks` (the heading is `Post-bump hooks: post_bump_hooks`) | Each id was read from the Forgejo renderer, not guessed. ## Measured - On `origin/main` (`a4aab90`), the extended check reports exactly these five as UNRESOLVED and nothing else (rc=1). On this branch: 62 files, 70 in-document anchors (the old script's count too), 246 relative file links (54 of them with a markdown anchor), 0 unresolved, rc=0. The 99 links it does not grade are all `https:` links. - c6 and c7, extracted from this `tests.yml` and run in a `python:3.12-slim` container against git.frankenbit.de: both exit 0 and write their verdicts. All three mutants and the rc=2 outage control report as expected. - Mutation (AGENTS.md section 8, Axis B): the cross-file-anchor mutant and the missing-file mutant each exit **0 on the old script** and **1 on the new one**, so neither control is a placebo. Reverting fix 5 alone, or fix 1 alone, turns c6 red. - Case: on Windows, `[o](Other.md)` with only `other.md` on disk exits 0 on the old script and 1 on the new one. - `tests/workflows.bats` in a container: 131 ok, 1 not ok. The failure is test 83 (mirror path, exit 127, command not found), which comes from the bare bats image missing a tool. This diff does not touch it. The #1451 assertion (exactly one captured-rc anchor invocation) passes, because c7 still exits with `exit 1`, not `exit "$rc"`. - `tests.yml` and `anchor-check.py` are ASCII-only (AGENTS.md section 11). The old script's non-ASCII punctuation was replaced while it was being rewritten. ## Decisions - **Extend the anchor check, or add a separate link gate?** Extending is right while one renderer call and one rc contract serve both. A separate gate is right if file-link grading ever needs to run without the renderer, for example offline. Today it does not, and extending avoids a new step and verdict id. - **New CI step, or more controls in c7?** Folding the mutants into c7 is right while they share c7's fixture and renderer. A new step (with its own verdict, GATE_IDS entry and both guard bindings, per #1540) is right if a control needs a tree mutation, which c7's RUNNER_TEMP fixture does not. So GATE_IDS and the two guard steps are unchanged. - **Not graded**: scheme links and site-absolute `/...` links leave the tree, so the tree cannot answer for them. Fragments on non-markdown targets (`main.go#L12`) are line anchors in the file viewer, not rendered headings. The summary line counts all of these as "not graded". ## Self-bootstrap (AGENTS.md section 2) No re-pin: toolkit-self floats `@main` (AGENTS.md section 2.1). This PR touches no compose script anyway. `tests.yml` is toolkit-self CI and is not in `gates.DefaultComposeScripts`. ## Review @alex: please verify at source, both halves: 1. run `FORGEJO_BASE_URL=https://git.frankenbit.de python3 scripts/anchor-check.py` on this head (rc=0) and on `a4aab90` (rc=1, the five links); 2. read the c7 log on this PR's `tests / checks` run, and check that the two new `control OK` lines appear for the cross-file anchor and the missing file. Head: `9726eab464fd802f903da4a7d81003714c2b18cb` 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix(docs): grade relative links and cross-file anchors; retarget five broken links
All checks were successful
fork-pr-approval-notice / explain fork workflow approval (pull_request_target) Successful in 4s
base-divergence-check / check (pull_request) Successful in 6s
go-ci / lint + build + test (pull_request) Successful in 33s
go-ci / record reviewed vs landed commit (pull_request) Has been skipped
pr / plan, and run every gate when combined (pull_request) Successful in 9s
readme-pin-check / mirror (pull_request) Successful in 7s
tests / bats (pull_request) Successful in 38s
tests / checks (pull_request) Successful in 8s
toolkit-self-gates / toolkit-self gates (PR's own rt) (pull_request) Successful in 8s
go-ci / page landing-tree failure (pull_request) Has been skipped
pr / manifest (pull_request) Has been skipped
pr / fragments (pull_request) Has been skipped
pr / changelog_body (pull_request) Has been skipped
pr / register (pull_request) Has been skipped
pr / ac_closure (pull_request) Has been skipped
pr / workflow_parse (pull_request) Has been skipped
pr / split result (pull_request) Has been skipped
pr / gates (pull_request) Successful in 0s
9726eab464
scripts/anchor-check.py graded only in-document anchors. A link to a
missing file and an anchor into another markdown file were never read,
so five broken links sat on main with the gate green. The check now
resolves every relative link against the linking file's directory
(case-exact) and, for a markdown target with a fragment, renders that
file's headings through the same Forgejo renderer call. ~~~ fences are
now skipped like ``` fences.

The c7 controls gain two mutants, a broken cross-file anchor and a link
to a missing file, each required to exit 1. Both exit 0 against the old
script. No new step, so GATE_IDS and the two guard steps are unchanged.

Retargeted: two ADR links in dead-script-namespace.md (now adr/...),
and three anchors whose renderer ids differ from the hand-written slug.

Refs #1557

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude requested review from alex 2026-10-06 01:05:18 +02:00
claude left a comment

Verdict: APPROVE at 9726eab464fd802f903da4a7d81003714c2b18cb. This is posted as COMMENT because the forge identity is claude, the PR's author, so @alex has to click Approve.

Refs #1557

Verified at source

  • Both halves of the requested check:
    • On this head, anchor-check.py (live renderer) gives: 62 files, 70 in-document anchors, 246 relative file links (54 with a markdown anchor), 99 not graded, 0 unresolved, rc=0.
    • On a4aab90's docs/ with the new script: rc=1, exactly the five links from #1557, and nothing else.
  • c7 log of run 19928, job 1 (the log itself, not the status): all five control OK lines are there. That covers the clean fixture, the in-document mutant, the cross-file anchor mutant, the missing-file mutant, and the renderer outage staying rc=2.
  • c6 and c7 extracted from this tests.yml and run in a Linux container against git.frankenbit.de: every control reports as expected.
  • Mutation (section 8, Axis B): I ran the cross-file-anchor fixture and the missing-file fixture against the old script. Both exit 0. Against the new script, both exit 1. Neither control is a placebo.
  • Other checks:
    • tests/workflows.bats -f anchor: the #1451 single-invocation test passes.
    • Both changed code files are ASCII-only (section 11).
    • All 18 commit statuses on the head are success.
    • Base is live main a4aab90.
  • Coverage of the tree: I compared every ]( in the selected markdown against what INLINE captures. Only one is missed: dead-script-namespace.md:251, a truncated ](ht... inside a quoted excerpt, which is not a real link. No reference-style definitions exist in the tree today.
  • The five retargets: each new id matches what the renderer emits. The edited ADR-0004 excerpt in the ledger now differs from its source by the adr/ prefix. The body discloses this, and the ledger quotes are not read by any gate (the only reference to the file is a link from operations.md). That is acceptable.

Non-blocking nits (fine as a follow-up or not at all)

  1. REFDEF also matches footnote definitions. [^1]: See the note. extracts See as a relative file link, so the first footnote anyone adds goes red with no file docs/See. Forgejo renders footnotes. Suggested fix: skip labels that start with ^.
  2. Links with valid CommonMark titles disappear silently. [a](other.md 'title') and [a](other.md (title)) extract nothing. They are neither graded nor counted in "not graded", so the summary's not-graded count undercounts. None are in the tree today, so this fails open without biting.
  3. A query string is graded as part of the path. [a](other.md?plain=1) reports no file other.md?plain=1, which is a false red. None are in the tree.
  4. An OSError from reading a file inside the grading loop is mislabelled. It is reported as "renderer stopped answering mid-run". It still fails closed (rc=2), so only the label is wrong.

None of these affects today's tree or the ACs.

Verdict: APPROVE at `9726eab464fd802f903da4a7d81003714c2b18cb`. This is posted as COMMENT because the forge identity is `claude`, the PR's author, so @alex has to click Approve. Refs #1557 ## Verified at source - **Both halves of the requested check:** - On this head, `anchor-check.py` (live renderer) gives: 62 files, 70 in-document anchors, 246 relative file links (54 with a markdown anchor), 99 not graded, **0 unresolved, rc=0**. - On `a4aab90`'s `docs/` with the new script: **rc=1, exactly the five links** from #1557, and nothing else. - **c7 log of run 19928, job 1** (the log itself, not the status): all five `control OK` lines are there. That covers the clean fixture, the in-document mutant, the cross-file anchor mutant, the missing-file mutant, and the renderer outage staying rc=2. - **c6 and c7 extracted from this `tests.yml` and run in a Linux container against git.frankenbit.de:** every control reports as expected. - **Mutation (section 8, Axis B):** I ran the cross-file-anchor fixture and the missing-file fixture against the **old** script. Both exit 0. Against the new script, both exit 1. Neither control is a placebo. - **Other checks:** - `tests/workflows.bats -f anchor`: the #1451 single-invocation test passes. - Both changed code files are ASCII-only (section 11). - All 18 commit statuses on the head are success. - Base is live main `a4aab90`. - **Coverage of the tree:** I compared every `](` in the selected markdown against what `INLINE` captures. Only one is missed: `dead-script-namespace.md:251`, a truncated `](ht...` inside a quoted excerpt, which is not a real link. No reference-style definitions exist in the tree today. - **The five retargets:** each new id matches what the renderer emits. The edited ADR-0004 excerpt in the ledger now differs from its source by the `adr/` prefix. The body discloses this, and the ledger quotes are not read by any gate (the only reference to the file is a link from `operations.md`). That is acceptable. ## Non-blocking nits (fine as a follow-up or not at all) 1. **`REFDEF` also matches footnote definitions.** `[^1]: See the note.` extracts `See` as a relative file link, so the first footnote anyone adds goes red with `no file docs/See`. Forgejo renders footnotes. Suggested fix: skip labels that start with `^`. 2. **Links with valid CommonMark titles disappear silently.** `[a](other.md 'title')` and `[a](other.md (title))` extract nothing. They are neither graded nor counted in "not graded", so the summary's not-graded count undercounts. None are in the tree today, so this fails open without biting. 3. **A query string is graded as part of the path.** `[a](other.md?plain=1)` reports `no file other.md?plain=1`, which is a false red. None are in the tree. 4. **An `OSError` from reading a file inside the grading loop is mislabelled.** It is reported as "renderer stopped answering mid-run". It still fails closed (rc=2), so only the label is wrong. None of these affects today's tree or the ACs.
Author
Member

HOLD: fixing the four nits from review 7267 (footnote definitions, titled links, query strings, OSError label) as a new commit on this branch. Reviewed head stays 9726eab; I will post the new full head SHA when it is pushed.

HOLD: fixing the four nits from review 7267 (footnote definitions, titled links, query strings, OSError label) as a new commit on this branch. Reviewed head stays 9726eab; I will post the new full head SHA when it is pushed.
fix(docs): anchor-check skips footnotes and query strings, grades titled links
All checks were successful
base-divergence-check / check (pull_request) Successful in 6s
go-ci / lint + build + test (pull_request) Successful in 32s
go-ci / record reviewed vs landed commit (pull_request) Has been skipped
pr / plan, and run every gate when combined (pull_request) Successful in 9s
readme-pin-check / mirror (pull_request) Successful in 7s
tests / bats (pull_request) Successful in 38s
tests / checks (pull_request) Successful in 8s
toolkit-self-gates / toolkit-self gates (PR's own rt) (pull_request) Successful in 8s
go-ci / page landing-tree failure (pull_request) Has been skipped
pr / manifest (pull_request) Has been skipped
pr / fragments (pull_request) Has been skipped
pr / changelog_body (pull_request) Has been skipped
pr / register (pull_request) Has been skipped
pr / ac_closure (pull_request) Has been skipped
pr / workflow_parse (pull_request) Has been skipped
pr / split result (pull_request) Has been skipped
pr / gates (pull_request) Successful in 0s
check-self-bootstrap / check (push) Successful in 5s
gitea-twin-check / check (push) Successful in 4s
go-ci / lint + build + test (push) Successful in 33s
go-ci / record reviewed vs landed commit (push) Successful in 2s
prepared-uncut-check / toolkit-self prepared-uncut controls (push) Successful in 5s
prepared-uncut-check / prepared-but-uncut release (push) Successful in 7s
prepared-uncut-check / check (push) Successful in 0s
release / decide + act (push) Successful in 8s
release / release (push) Successful in 0s
tests / bats (push) Successful in 37s
tests / checks (push) Successful in 8s
go-ci / page landing-tree failure (push) Has been skipped
release / fire-cut (push) Has been skipped
11aba7f75c
Review 7267's four nits on the link gate:

- a footnote definition (`[^1]: text`) was read as a reference-style
  link, so its first word was graded as a missing file;
- links with a 'single' or (paren) title matched nothing and were
  neither graded nor counted;
- a query string (`other.md?plain=1`) was graded as part of the path;
- an unreadable file was reported as "renderer stopped answering".
  It is now "could not read <file>", still rc=2.

The c7 baseline fixture now carries a footnote, all three title forms
and a query string, and a new mutant points a titled link at a missing
file. Against the previous script the baseline exits 1 and the titled
mutant exits 0.

Refs #1557

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Author
Member

Pushed. New head: 11aba7f75c9daf987f0dc018cff292f135039e47 (one new commit on top of the reviewed 9726eab, no amend, no force-push). The HOLD is lifted.

All four nits from review 7267 are addressed:

# Nit Before (9726eab) After
1 footnote definition [^1]: See the other file. rc=1, no file .../See rc=0, REFDEF skips labels starting with ^
2 titled links [a](absent.md 't'), [a](absent.md (t)) rc=0, not extracted rc=1, all three CommonMark title forms extracted
3 [a](other.md?plain=1) rc=1, no file other.md?plain=1 rc=0, the query is dropped before the path resolves
4 unreadable file (a directory named dir.md) labelled as a renderer failure COULD-NOT-GRADE - could not read <file>, still rc=2

The c7 baseline fixture now carries a footnote, all three title forms and a query string. A fifth mutant points a 'sq title' link at a missing file. Run in a Linux container against git.frankenbit.de:

  • c6: rc=0, the same counts as before.
  • c7: rc=0, and all six control OK lines appear.
  • c7 against the 9726eab script: the baseline exits 1 on the footnote and the query string.
  • The titled mutant exits 0 on 9726eab and 1 on this head.

Both files stay ASCII-only. c7 still ends in exit 1, so the #1451 single-invocation bats assertion is unaffected.

Delta to review: 9726eab..11aba7f.

Pushed. New head: `11aba7f75c9daf987f0dc018cff292f135039e47` (one new commit on top of the reviewed `9726eab`, no amend, no force-push). The HOLD is lifted. All four nits from review 7267 are addressed: | # | Nit | Before (9726eab) | After | |---|---|---|---| | 1 | footnote definition `[^1]: See the other file.` | rc=1, `no file .../See` | rc=0, `REFDEF` skips labels starting with `^` | | 2 | titled links `[a](absent.md 't')`, `[a](absent.md (t))` | rc=0, not extracted | rc=1, all three CommonMark title forms extracted | | 3 | `[a](other.md?plain=1)` | rc=1, `no file other.md?plain=1` | rc=0, the query is dropped before the path resolves | | 4 | unreadable file (a directory named `dir.md`) | labelled as a renderer failure | `COULD-NOT-GRADE - could not read <file>`, still rc=2 | The c7 baseline fixture now carries a footnote, all three title forms and a query string. A fifth mutant points a `'sq title'` link at a missing file. Run in a Linux container against git.frankenbit.de: - c6: rc=0, the same counts as before. - c7: rc=0, and all six `control OK` lines appear. - c7 against the 9726eab script: the baseline exits 1 on the footnote and the query string. - The titled mutant exits 0 on 9726eab and 1 on this head. Both files stay ASCII-only. c7 still ends in `exit 1`, so the #1451 single-invocation bats assertion is unaffected. Delta to review: `9726eab..11aba7f`.
claude left a comment

Verdict: APPROVE at 11aba7f75c9daf987f0dc018cff292f135039e47. This replaces review 7267, which was at 9726eab. It is posted as COMMENT because the forge identity is claude, the PR's author, so @alex has to click Approve.

Refs #1557

Delta 9726eab..11aba7f, verified at source

  • History is intact: 9726eab is an ancestor of 11aba7f, so nothing was rewritten. The delta touches only scripts/anchor-check.py and tests.yml (c7).
  • Whole tree on the head (live renderer): 62 files, 70 in-document anchors, 246 relative links (54 with an anchor), 99 not graded, 0 unresolved, rc=0. The counts match 9726eab.
  • The new c7 baseline fixture, run directly:
    • On the 9726eab script: rc=1, with exactly two UNRESOLVED: See (the footnote) and other.md?plain=1 (the query string).
    • On 11aba7f: rc=0.
  • Titled links, each isolated in a one-link fixture pointing at a missing file:
    • 'sq' and (pt) titles: rc=0 on 9726eab, rc=1 on 11aba7f. The new mutant is not a placebo.
    • "dq" title: rc=1 on both, because it was already graded.
  • Unreadable file (a directory named dir.md): both versions return rc=2. The label is now could not read fx\dir.md: ... instead of renderer stopped answering mid-run.
  • c6 and c7 extracted from this tests.yml and run in a Linux container against git.frankenbit.de: both exit 0 and write pass. All six controls report OK.
  • c7 log of run 19935, job 1 (the log itself, not the status): six control OK lines, including the new 's/(other.md 'sq title')/(absent-titled.md 'sq title')/' is reported as rc=1.
  • Other checks:
    • tests/workflows.bats -f anchor: the #1451 single-invocation test passes. c7 still ends in exit 1, not exit "$rc".
    • Both changed files have 0 non-ASCII bytes (section 11).
    • All 18 commit statuses on the head are success.

Optional, non-blocking

  • At anchor-check.py:184, dest =pathlib.Path( is missing a space after =. This is cosmetic only.
  • A .md file that is not UTF-8 raises UnicodeDecodeError. That is a ValueError, not an OSError, so it escapes both handlers, and Python's traceback exits 1, which c6 labels "NOT MERGE-READY". This was already the case before this PR and nothing in the tree triggers it. If you want it fail-closed as rc=2, add UnicodeDecodeError to the could-not-read handler.

All four nits from review 7267 are addressed.

Verdict: APPROVE at `11aba7f75c9daf987f0dc018cff292f135039e47`. This replaces review 7267, which was at `9726eab`. It is posted as COMMENT because the forge identity is `claude`, the PR's author, so @alex has to click Approve. Refs #1557 ## Delta `9726eab..11aba7f`, verified at source - **History is intact:** `9726eab` is an ancestor of `11aba7f`, so nothing was rewritten. The delta touches only `scripts/anchor-check.py` and `tests.yml` (c7). - **Whole tree on the head (live renderer):** 62 files, 70 in-document anchors, 246 relative links (54 with an anchor), 99 not graded, **0 unresolved, rc=0**. The counts match `9726eab`. - **The new c7 baseline fixture, run directly:** - On the `9726eab` script: **rc=1**, with exactly two UNRESOLVED: `See` (the footnote) and `other.md?plain=1` (the query string). - On `11aba7f`: rc=0. - **Titled links, each isolated in a one-link fixture pointing at a missing file:** - `'sq'` and `(pt)` titles: rc=0 on `9726eab`, rc=1 on `11aba7f`. The new mutant is not a placebo. - `"dq"` title: rc=1 on both, because it was already graded. - **Unreadable file (a directory named `dir.md`):** both versions return rc=2. The label is now `could not read fx\dir.md: ...` instead of `renderer stopped answering mid-run`. - **c6 and c7 extracted from this `tests.yml` and run in a Linux container against git.frankenbit.de:** both exit 0 and write `pass`. All six controls report OK. - **c7 log of run 19935, job 1** (the log itself, not the status): **six `control OK` lines**, including the new `'s/(other.md 'sq title')/(absent-titled.md 'sq title')/' is reported as rc=1`. - **Other checks:** - `tests/workflows.bats -f anchor`: the #1451 single-invocation test passes. c7 still ends in `exit 1`, not `exit "$rc"`. - Both changed files have 0 non-ASCII bytes (section 11). - All 18 commit statuses on the head are success. ## Optional, non-blocking - At `anchor-check.py:184`, `dest =pathlib.Path(` is missing a space after `=`. This is cosmetic only. - A `.md` file that is not UTF-8 raises `UnicodeDecodeError`. That is a `ValueError`, not an `OSError`, so it escapes both handlers, and Python's traceback exits 1, which c6 labels "NOT MERGE-READY". This was already the case before this PR and nothing in the tree triggers it. If you want it fail-closed as rc=2, add `UnicodeDecodeError` to the could-not-read handler. All four nits from review 7267 are addressed.
alex approved these changes 2026-10-06 01:16:57 +02:00
alex merged commit 11aba7f75c into main 2026-10-06 01:17:11 +02:00
alex deleted branch claude/1557-relative-link-gate 2026-10-06 01:17:11 +02:00

Landing identity record

  • PR: #1558
  • landed commit (server merge_commit_sha): 11aba7f75c9daf987f0dc018cff292f135039e47
  • effective official approval(s):
    • @alex, review #7269, stamped commit: 11aba7f75c9daf987f0dc018cff292f135039e47
  • replay comparison: no identity change (stamped SHA equals landed SHA)

This is a post-merge identity record. It does not retroactively review the landed object; it records whether the server landed the object that an official approval named.

<!-- release-toolkit:landing-review-record-v1 landed=11aba7f75c9daf987f0dc018cff292f135039e47 --> ## Landing identity record - PR: #1558 - landed commit (server merge_commit_sha): `11aba7f75c9daf987f0dc018cff292f135039e47` - effective official approval(s): - @alex, review #7269, stamped commit: `11aba7f75c9daf987f0dc018cff292f135039e47` - replay comparison: no identity change (stamped SHA equals landed SHA) This is a post-merge identity record. It does not retroactively review the landed object; it records whether the server landed the object that an official approval named.
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
3 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
frankenbit/release-toolkit!1558
No description provided.