Skip to content

chore: qualify development-repo issue references (litclock-dev#658) - #60

Merged
kapoorankush merged 1 commit into
masterfrom
chore/qualify-dev-issue-refs-658
Aug 20, 2026
Merged

chore: qualify development-repo issue references (litclock-dev#658)#60
kapoorankush merged 1 commit into
masterfrom
chore/qualify-dev-issue-refs-658

Conversation

@kapoorankush

Copy link
Copy Markdown
Owner

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 #337 correctly 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 sed

Every three-digit issue number is also a valid CSS hex colour. A previous attempt at this rewrite turned color:#555 into color:litclock-dev#555 in src/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 inline style="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

pass found why the previous pass missed it
1 1,758
2 139 the rewrite inherited the audit's lookbehind, which excludes - and / to dodge URL fragments — so the pre-/post- idiom and A/B/C chains were invisible
3 40 found by review. Seven file types nobody had looked at: .php, .conf, .json, .in, .txt, .sample, and extensionless scripts

Pass 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.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 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 #N is 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

  • Exact expected-vs-applied count on every pass, asserted in the script, not eyeballed.
  • Grep of the output for the prefix inside a colour context: clean.
  • Every changed line in every .css file confirmed to fall inside a /* */ comment.
  • Python / shellcheck / YAML syntax over every changed file.
  • Byte-level confirmation that the six CRLF files kept their line endings (CONTRIBUTING.md: 501 CRLF, 0 bare LF, before and after; same for the other five).
  • A final context-aware scan over every tracked file: zero unqualified references remaining, exactly ten colour values still bare.
  • ruff clean; 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.

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.
@kapoorankush
kapoorankush merged commit 50e9da1 into master Aug 20, 2026
5 checks passed
@kapoorankush
kapoorankush deleted the chore/qualify-dev-issue-refs-658 branch August 20, 2026 13:00
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