chore: qualify development-repo issue references (litclock-dev#658) - #60
Merged
Merged
Conversation
Most of this codebase was written in the development repo, where a bare
three-digit reference correctly meant a development issue. Ported here the same
text renders as a link to THIS repo's issue of that number, and GitHub draws a
wrong link exactly like a right one -- so nothing looks broken. None of them
resolved to anything yet, but this repo's numbering only climbs, and at audit
time the nearest collision was 23 issues away.
1,937 references across 205 files now carry the `litclock-dev` prefix.
THE TEN THAT LOOK IDENTICAL AND MUST NOT BE TOUCHED ARE STILL BARE. Every
three-digit issue number is also a valid CSS hex colour, and an earlier attempt
at this rewrite prefixed colour values in setup_server.py's inline styles and
shipped invalid CSS to every first-boot owner -- because the verification
normalised BOTH sides by stripping the prefix before diffing, so a mangled
colour and a real reference both round-tripped to the original. A check that
applies the inverse of the transformation under test cannot detect
over-application of it.
So classification here is per-OCCURRENCE and context-aware, never a blind
regex. Excluded: colour values (`color:` / `background:` / a custom property,
with a quote counting as a token boundary so an inline `style="color:..."`
does not slip past), HTML entities, and lettered sub-references, which do not
autolink and so cannot mis-resolve anyway.
IT TOOK THREE PASSES, AND THE SECOND AND THIRD ARE THE INTERESTING ONES.
* Pass 1 rewrote the plain form over the file types the audit's own scan
command named.
* Pass 2: a completeness scan deliberately WIDER than the rewrite found 139
references still bare -- the `pre-#337` / `post-#209` idiom and `A/B/C`
chains -- because the rewrite had inherited the audit's lookbehind, which
excludes `-` and `/` to dodge URL fragments. Each shape got its own narrow
pattern rather than one widened one; all 22 chain sites were read by eye to
confirm a reference list rather than a URL.
* Pass 3: /review found 40 more in seven file types nobody had looked at --
.php, .conf, .json, .in, .txt, .sample and extensionless scripts. The fix
is not an eighth extension: the scan and the guard now walk every tracked
text file, because an allowlist of file types is a list of the places you
remembered.
REFERENCES AT OR BELOW THIS REPO'S OWN NUMBERING WERE LEFT ALONE AND TRIAGED BY
HAND -- 29 occurrences, 17 distinct. All 29 are correct as they stand: most are
genuine references to this repo, and several are not issue references at all
but numbered items in a review or a test plan.
Verified by checks that do NOT invert the rewrite: an exact expected-vs-applied
count on every pass (asserted, not eyeballed); a grep of the OUTPUT for the
prefix inside a colour context; confirmation that every changed line in every
CSS file falls inside a comment; python/shellcheck/YAML syntax over every
changed file; and byte-level confirmation that the six CRLF files kept their
line endings (CONTRIBUTING.md 501 CRLF / 0 bare LF before and after, and the
same for the other five). A final context-aware scan over every tracked file
reports zero unqualified references remaining and exactly the ten colour values
still bare. The full suite passes unchanged.
tests/test_issue_ref_namespace.py fails on a new bare reference above the
ceiling. That is the part that makes it stay fixed: two hand passes had already
been run and neither stuck, because requalification only ever happened on the
porting path and anything authored directly here skipped it. The ceiling is a
constant a human bumps deliberately rather than a live API call, because
raising it asserts a judgement a regex cannot make.
The guard proved itself three times during this change: it rejected the first
draft of the CHANGELOG entry, which quoted bare references as examples; it
flagged its own fixtures until given a narrow one-path self-exemption; and
after being widened it catches a reintroduced reference in each of the seven
file types the first version was blind to.
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.
Tracked as litclock-dev#658. 206 files, 1,937 references. No behaviour changes — text only, plus one new test.
The problem
Most of this codebase was written in the development repo, where a bare
#337correctly meant development issue 337. Ported here the same text renders as a link to this repo's issue 337 — and GitHub draws a wrong link exactly like a right one, so nothing looks broken.None of them resolve to anything yet. But this repo's numbering only climbs, and at audit time the nearest collision was 23 issues away. A dead link is visibly broken; a wrong link that looks right is not.
The trap, and why this is not a
sedEvery three-digit issue number is also a valid CSS hex colour. A previous attempt at this rewrite turned
color:#555intocolor:litclock-dev#555insrc/setup_server.py's inline styles and shipped invalid CSS to every first-boot owner. It got through because the verification normalised both sides by stripping the prefix before diffing — so a mangled colour and a genuine reference both round-tripped to the original. A check that applies the inverse of the transformation under test cannot detect over-application of it.So classification here is per-occurrence and context-aware. Excluded: colour values (
color:/background:/ a custom property — with a quote counting as a token boundary, or an inlinestyle="color:..."slips past), HTML entities, and lettered sub-references like#431b, which do not autolink and so cannot mis-resolve anyway.Ten references are deliberately still bare — the colour values in
setup_server.py. They are the exact sites that were corrupted last time.It took three passes, and the last two are the interesting ones
-and/to dodge URL fragments — so thepre-/post-idiom andA/B/Cchains were invisible.php,.conf,.json,.in,.txt,.sample, and extensionless scriptsPass 2 came from running a completeness scan deliberately wider than the rewrite and asking what it saw that the rewrite had not touched. Each shape got its own narrow pattern rather than one widened one, and all 22 chain sites were read by eye to confirm a reference list rather than a URL.
Pass 3's fix is not an eighth extension. The scan and the guard now walk every tracked text file, because an allowlist of file types is a list of the places you remembered.
References at or below this repo's own numbering were left alone, and triaged by hand
29 occurrences, 17 distinct. All 29 are correct as they stand. Most are genuine references to this repo. Several are not issue references at all — they are numbered items in a review or a test plan.
The guard
tests/test_issue_ref_namespace.pyfails on a new bare reference above the ceiling. That is the part that makes it stay fixed: two hand passes had already been run before this and neither stuck, because requalification only ever happened on the porting path and anything authored directly here skipped it.The ceiling is a constant a human bumps deliberately rather than a live API call. Raising it to N asserts "this repo now has an issue N, so a bare
#Nis ambiguous and I have checked the ones in the tree" — a judgement a regex cannot make.It proved itself three times during this change: it rejected the first draft of the CHANGELOG entry, which quoted bare references as examples; it flagged its own fixtures until given a narrow one-path self-exemption; and after being widened it catches a reintroduced reference in each of the seven file types the first version was blind to.
Verification — none of it inverts the rewrite
.cssfile confirmed to fall inside a/* */comment.CONTRIBUTING.md: 501 CRLF, 0 bare LF, before and after; same for the other five).ruffclean;pytest tests/— 3459 passed, 62 skipped (3455 before, plus the 4 new guard tests).Twelve lines crossed the 120-character limit once the prefix was added; those were re-wrapped.