Newer
Older
openstack-caracal-ipv4 / docs / repo-lint-nextfree-bug-FINDING.md

FINDING: repo_lint.py L5 "next-free identifiers" is unreliable -- do not use it for numbering

Status: DOCFIX candidate. Read-only analysis by the main-chat stream at repo HEAD 59a7c73 (2026-07-06). No code changed. Code assigns the DOCFIX number when actioning (re-run ledger-scan for next-free first; main-chat consumed none of these).

One-line: scripts/repo_lint.py prints an [info] L5 next-free identifiers line that is wrong on all three counters and disagrees with ledger-scan. Numbers must be taken from ledger-scan, never from repo_lint. This is a live collision risk while the jumphost stream is consuming DOCFIX numbers rapidly.

Evidence

At this HEAD the two tools disagree:

counter repo_lint L5 says ledger-scan says (authoritative) ground truth
D next-free D-075 next-free D-074 highest header D-073; D-074 exists only as a PROPOSAL mention
DOCFIX next-free DOCFIX-100 next-free DOCFIX-106 highest consumed DOCFIX-105; DOCFIX-106 is a next-free pointer
BUNDLEFIX next-free BUNDLEFIX-051 next-free BUNDLEFIX-012 highest consumed BUNDLEFIX-011; 051 traces to a test fixture (below)

ledger-scan is correct on all three. Each repo_lint number is wrong via a DIFFERENT defect, which is why this is worth fixing rather than tweaking.

Root cause -- three independent defects in the L5 next-free block

The block (repo_lint.py, L5 identifier numbering) computes next-free as max(seen)+1 over re.finditer(r"\b(D|DOCFIX|BUNDLEFIX)-(0\d{2})\b", ...) across all_text():

  1. Band-limited regex 0\d{2}. It only matches identifiers 000-099. It is blind to DOCFIX-100..106 (the current live range), so it reports DOCFIX-100 when true next-free is 106. This is the same defect ledger-scan already carried and Code already fixed (its regex is now [0-9]{3}); repo_lint still has the old band-limited form.
  2. Mention-counting, no header-authority, no pointer-exclusion. It counts every identifier OCCURRENCE, not definition-headers, and does not skip "Next-free:" pointer lines. So a PROPOSAL reference inflates it -- the main-chat CIDR plan mentions D-074, which is exactly why repo_lint reports D-075. ledger-scan uses design-decisions headers for D and excludes next-free pointer lines.
  3. Scans the test tree. all_text() includes tests/. tests/ledger-scan/run-tests.sh contains a deliberately-high fixture line (Next-free: D-071, DOCFIX-099, BUNDLEFIX-050 ... must NOT inflate) written to PROVE ledger-scan ignores pointer lines. repo_lint ingests that fixture's BUNDLEFIX-050 and reports 051 -- the precise trap the fixture was authored to catch.

Correction of the record: an earlier main-chat note called BUNDLEFIX-051 "spurious." It is (tokens above de-fanged 2026-07-06, jumphost stream: identifier-shaped tokens above the real high-water mark in docs/ prose inflate the ledger-scan counters -- the standing rule this very FINDING is about; the table rows survive because "next-free" lines are excluded.) not -- it is max+1 of the fixture token in defect 3. The imprecision is corrected here.

Fix options (Code's lane; not implemented here)

Recommended -- remove the next-free print from repo_lint entirely. repo_lint's actual L5 job is the duplicate-definition-heading collision guard; keep that. Next-free is ledger-scan's job, and having two tools derive it by different regexes is how they drifted apart. Single source of truth (the same principle already floated for the machine-derived ledger cache). Lowest risk, removes the drift surface.

Fallback -- if repo_lint must keep printing next-free, make it match ledger-scan: widen the regex to [0-9]{3,}; use design-decisions headers for D; exclude next-free pointer lines; and exclude tests/ from all_text() for identifier scanning. More code, same answer -- prefer the removal.

Interim guidance (both streams, until fixed)

Take D / DOCFIX / BUNDLEFIX next-free from bash scripts/ledger-scan.sh ONLY. Treat repo_lint's [info] L5 next-free line as advisory-and-currently-wrong; it does not gate (it is [info], 0-fail), so it is safe to ignore for numbering.