What happens
Three tracked files cite dev/PUNCHLIST.md as the authority for a decision, but dev/ is gitignored and PUNCHLIST.md has never been committed. No contributor working from a clone can read it.
$ grep -rn 'PUNCHLIST' --include='*.py' --include='*.toml' --include='*.md' --include='*.yml' . | grep -v .venv
pyproject.toml:187:# gate (which must stay mechanical). Items tied to dev/PUNCHLIST.md are tracked
pyproject.toml:193: "E722", # bare except: tracked as ROB-4 in dev/PUNCHLIST.md (behavioral fix)
tests/README_integration.md:41: `dev/PUNCHLIST.md`**: an efficiency/diagnostic fix must leave recovered
$ grep -n 'dev' .gitignore
55:dev/
$ git log --oneline --all -- '*PUNCHLIST*'
(no output — never committed on any branch)
$ git ls-files dev/
(no output — nothing under dev/ is tracked)
Why it matters
This is not a broken hyperlink. In two of the three places, the missing file is carrying the justification for a policy that shapes the codebase:
1. It makes the lint gate's ignore list unauditable. pyproject.toml:176-196 is unusually disciplined — every ignored rule carries a written rationale, which is exactly the right practice. But two of those rationales terminate in a document nobody else can open:
E722 (bare except) is ignored because it is "tracked as ROB-4 in dev/PUNCHLIST.md"
F841 (unused locals) is ignored partly because "several are CQ-5 dead code (tracked)"
A reviewer cannot check whether ROB-4 and CQ-5 exist, what they say, how many sites they cover, or whether they have been resolved. The ignore therefore reads as permanent to everyone except its author. The comment at line 186 makes the dependency explicit: items tied to the punchlist "are tracked and fixed there, not here" — so "there" needs to be somewhere a contributor can reach.
2. It makes a normative testing requirement unresolvable. tests/README_integration.md:38-43 defines the slow tier as "the gold-standard before/after check for the algorithm patches in dev/PUNCHLIST.md", and states the pass criteria in terms of those patches — an efficiency fix must leave recovered moments unchanged, a correctness fix must move them toward analytical truth. A contributor told to apply that standard cannot find out which patches it refers to.
3. It is the project's only issue-style debt tracker, and it is invisible. There are zero TODO/FIXME/HACK/XXX markers in pybnf/ — deliberate, and healthier than the alternative, but it means the punchlist is where that debt lives. With it untracked, the debt inventory exists only on one machine. Given the repo's contribution profile (778 of the last 12 months' commits from one author), that is a bus-factor concern rather than a cosmetic one.
Reproduction
git clone https://github.com/lanl/PyBNF && cd PyBNF
grep -rn 'PUNCHLIST' --include='*.toml' --include='*.md' . | grep -v .venv # 3 references
ls dev/PUNCHLIST.md # No such file or directory
Expected: a reference in a tracked file resolves to something a contributor can read.
Possible resolutions
Listing these because the right one is a call for the maintainer, not a code fix:
- Commit it. Move to
docs/PUNCHLIST.md (or un-ignore just that path via !dev/PUNCHLIST.md), which makes ROB-4/CQ-5 auditable and the slow-tier criterion resolvable. Most faithful to what the three references promise.
- Convert the cited items to issues and point the comments at issue numbers instead. Keeps
dev/ private; makes the tracked references resolve; puts the debt where the rest of the project's work lives.
- Drop the references. Restate the
E722/F841 rationales so they stand alone, and rewrite tests/README_integration.md:38-43 in terms of the criteria rather than the patch list. Lowest effort; loses the linkage.
Related: CONTRIBUTING.md:41 has a similar problem — it states "the project uses a populated uv.lock", which .gitignore:57 and .pre-commit-config.yaml:30-31 both contradict ("uv.lock isn't fully resolved in this repo, so syncing would fail"). Same class of defect: a tracked file describing a state of the repo that is not true. Worth sweeping together if someone takes this.
Where
pyproject.toml:187, pyproject.toml:193, tests/README_integration.md:41, against .gitignore:55.
What happens
Three tracked files cite
dev/PUNCHLIST.mdas the authority for a decision, butdev/is gitignored andPUNCHLIST.mdhas never been committed. No contributor working from a clone can read it.Why it matters
This is not a broken hyperlink. In two of the three places, the missing file is carrying the justification for a policy that shapes the codebase:
1. It makes the lint gate's ignore list unauditable.
pyproject.toml:176-196is unusually disciplined — every ignored rule carries a written rationale, which is exactly the right practice. But two of those rationales terminate in a document nobody else can open:E722(bare except) is ignored because it is "tracked as ROB-4 indev/PUNCHLIST.md"F841(unused locals) is ignored partly because "several are CQ-5 dead code (tracked)"A reviewer cannot check whether ROB-4 and CQ-5 exist, what they say, how many sites they cover, or whether they have been resolved. The ignore therefore reads as permanent to everyone except its author. The comment at line 186 makes the dependency explicit: items tied to the punchlist "are tracked and fixed there, not here" — so "there" needs to be somewhere a contributor can reach.
2. It makes a normative testing requirement unresolvable.
tests/README_integration.md:38-43defines theslowtier as "the gold-standard before/after check for the algorithm patches indev/PUNCHLIST.md", and states the pass criteria in terms of those patches — an efficiency fix must leave recovered moments unchanged, a correctness fix must move them toward analytical truth. A contributor told to apply that standard cannot find out which patches it refers to.3. It is the project's only issue-style debt tracker, and it is invisible. There are zero
TODO/FIXME/HACK/XXXmarkers inpybnf/— deliberate, and healthier than the alternative, but it means the punchlist is where that debt lives. With it untracked, the debt inventory exists only on one machine. Given the repo's contribution profile (778 of the last 12 months' commits from one author), that is a bus-factor concern rather than a cosmetic one.Reproduction
Expected: a reference in a tracked file resolves to something a contributor can read.
Possible resolutions
Listing these because the right one is a call for the maintainer, not a code fix:
docs/PUNCHLIST.md(or un-ignore just that path via!dev/PUNCHLIST.md), which makes ROB-4/CQ-5 auditable and theslow-tier criterion resolvable. Most faithful to what the three references promise.dev/private; makes the tracked references resolve; puts the debt where the rest of the project's work lives.E722/F841rationales so they stand alone, and rewritetests/README_integration.md:38-43in terms of the criteria rather than the patch list. Lowest effort; loses the linkage.Related:
CONTRIBUTING.md:41has a similar problem — it states "the project uses a populateduv.lock", which.gitignore:57and.pre-commit-config.yaml:30-31both contradict ("uv.lock isn't fully resolved in this repo, so syncing would fail"). Same class of defect: a tracked file describing a state of the repo that is not true. Worth sweeping together if someone takes this.Where
pyproject.toml:187,pyproject.toml:193,tests/README_integration.md:41, against.gitignore:55.