Skip to content

Write down how the work is actually done, and check the links it produces - #18

Merged
muellerei merged 3 commits into
mainfrom
docs/contributing-working-practices
Sep 16, 2026
Merged

muellerei merged 3 commits into
mainfrom
docs/contributing-working-practices

Conversation

@muellerei

Copy link
Copy Markdown
Owner

Spec 007. Three practices earned their place on a single day of fixes, and the
existing wording in CONTRIBUTING.md would not have prevented any of them.

What changes

A test has to be shown to fail before it is trusted. The test proving that
search-pages also matches on originalName first searched for "Alpha" --
which .lower() finds in name too. It passed while testing nothing. Only
removing the branch showed that; the fixture searches for Q&A / Support
instead, whose ampersand does not survive being slugged.

Writes to a live graph leave pages behind. They use a zz-probe-<timestamp>
prefix now and get deleted afterwards.

"Update documentation" was too soft for a rule broken twice on the day it
applied: both flags in 0.10.0 went out without their README row and AGENTS.md
entry. It is a four-item checklist now, and it names --help, which is the
source the tables are derived from.

References name symbols, not line numbers -- a comment pointing at
helpers.py:855 outlived its meaning within two commits.

scripts/check-links.py checks the relative links and heading anchors
across the Markdown files. Every one of them claims a file and a heading exist,
and nothing verified that.

The part worth reading

The first version of the checker was green and wrong in both directions, on
Markdown that is normal here. That is the new rule proving itself on its own
commit.

False positives: link syntax inside fenced blocks and inline code was read as a
link -- this project documents Markdown graphs, and CONTRIBUTING.md itself
shows link examples. Titled links, angle-bracketed targets, percent-encoded
paths and links wrapped across lines were reported broken. Repeated headings
(the CHANGELOG has ten of "Fixed") resolve as #fixed-1 on GitHub, and that
suffix was unknown here.

False negative, the one that defeated the purpose: [text][ref] links were not
matched at all, so a definition pointing at a deleted file passed silently.

One trap came out of fixing it, and it is why anchors are collected from the raw
text: ### [journal.headings]`` is a heading made entirely of inline code.
Stripping code before reading headings deleted it, and a link that works on
GitHub came back broken -- caught because that link is in docs/configuration.md.

Verification

  • Suite green after every step: 832 passed
  • python3 scripts/check-links.py . -> 5 files, 0 broken links, exit 0
  • The checker was shown to fail: a dangling file reference and a dangling anchor
    appended to README.md, both reported, exit 1, then reverted
  • Packaging unchanged -- sdist built, scripts/ is not in it

Left open, deliberately

  • Case sensitivity differs between macOS and Linux, so a local run gives no
    guarantee for CI on that one point.
  • CI does not call the script; tests.yml runs pytest only. Wiring it in is a
    separate decision and belongs with the pre-publication checklist.

Every relative link between the Markdown files claims a file and a heading
exist. Nothing verified that, so a rename broke them silently.

The anchor rule is the part worth writing down: GitHub drops punctuation
before turning spaces into hyphens, so an em dash in a heading leaves both
its surrounding spaces behind and the anchor gets two hyphens, not one. A
first version collapsed them and reported an intact link as broken.

Generated and untracked trees are skipped. An earlier version read them and
came back with a broken link inside a gitignored directory -- a failure no
contributor could reproduce, in a file they cannot see.

Run over the repository: 5 files, 0 broken links. Verified it can fail by
appending a dangling file reference and a dangling anchor to README.md:
both reported, exit 1.
…ot hold

Three practices earned their place on a single day of fixes, and the existing
text would not have prevented any of them.

A test has to be shown to fail before it is trusted. One meant to prove that
search-pages matches on originalName searched for "Alpha", which .lower() also
finds in name; it was green and tested nothing. Only removing the branch
exposed it.

Writes to a live graph leave pages behind. They use a zz-probe-<timestamp>
prefix now and get deleted afterwards.

"Update documentation" was too soft a word for a rule that was broken twice the
day it applied: both flags in 0.10.0 went out without their README row and
AGENTS.md entry. It is a checklist now, and it names --help, which is the
source the tables are derived from.

References name symbols, not line numbers -- a comment pointing at
helpers.py:855 outlived its meaning within two commits.

The link checker is mentioned where it is needed: at the end of the
documentation checklist, since that is the change that moves anchors.
Review found it wrong in both directions on input that is normal here.

False positives: link syntax shown inside fenced blocks or inline code was
read as a link, which matters because this project documents Markdown graphs
and CONTRIBUTING itself shows link examples. Titled links, angle-bracketed
targets, percent-encoded paths and links wrapped across lines were reported
broken. Repeated headings -- the CHANGELOG has ten of "Fixed" -- resolve as
#fixed-1 on GitHub, and that suffix was unknown here.

False negative, the one that defeated the purpose: [text][ref] links were not
matched at all, so a definition pointing at a deleted file passed silently.
Both the reference and a label with no definition are checked now.

An anchor is not only a heading: <a name> and id attributes make one too.

Robustness: an unreadable file is reported and the run continues instead of
ending in a traceback; a mistyped root exits 2 rather than reporting "0 files,
0 broken links" and passing.

One trap found while fixing this, and it is why anchors are collected from the
raw text: `### `[journal.headings]`` is a heading made entirely of inline code.
Stripping code before reading headings deleted it, and a link that works on
GitHub came back broken.

CHANGELOG: the script is its own Added entry now. It is a new file, and the
precedent here is examples/carried-over-todos.sh, which got one beside the
behaviour change it shipped with rather than being folded into it.

CONTRIBUTING: the search-pages example no longer says the fixture "now" uses
Q&A -- the broken version never reached a commit, so git log would have
contradicted it. What it teaches is the same; the mutation is what catches it.
@muellerei
muellerei merged commit e5aab77 into main Sep 16, 2026
4 checks passed
@muellerei
muellerei deleted the docs/contributing-working-practices branch September 16, 2026 18:13
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