From c62ac6d5c539515cc7f7b5bbdca2bfe9b8b58197 Mon Sep 17 00:00:00 2001 From: Polichinl Date: Tue, 18 Aug 2026 14:01:24 +0200 Subject: [PATCH] docs: name all three packages where the wheel is described, and check it (closes C-96) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit S1 of epic #267. Closes #268. Two live documents still said the wheel ships two packages. It has shipped three since v1.7.0. - `.github/workflows/publish_package.yml` — a comment in the workflow that ACTUALLY PUBLISHES, naming two of three. It uses no count word, so only a completeness check sees it. - `docs/guides/publishing-to-pypi.md` — "BOTH packages + their py.typed", two lines above a comment corrected earlier the same day to say "all three". That file names all three elsewhere, so only a literal check sees it. The second is why this is registered rather than just fixed. That file was corrected on 2026-08-18 and the class reported as fixed after grepping for one remembered phrasing. Fourth time this register has recorded a fix reaching the instance instead of the class, and the first time the miss was inside a file already edited. **Check 10 has two halves because neither catches the other's case.** Completeness: every package in `[tool.hatch.build.targets.wheel]` is named in each wheel-describing document. Literal: no stale count word in those documents. Scoped on purpose to documents describing the CURRENT wheel. ADRs, postmortems, this register and the CHANGELOG state counts that were true when written — ADR-017's "Two packages to maintain", C-23's "shipped in both packages" — and flagging those would make the check noise, which is how a check gets deleted. Same reasoning as check 3, which restricts itself to the constitutional ADRs. Mutation-tested five ways, all erroring: a stale count word reintroduced; a package dropped from either document; a FOURTH package added to the wheel target and left undocumented (the generalisation test); an unreadable package list. Then it caught a live regression minutes after being written. Cleaning up after the first mutation with `git checkout` discarded the still-uncommitted workflow fix; the check failed on the next run instead of the mistake reaching a commit. One thing the writing of it surfaced: the first version of the corrected comment QUOTED the old wording to explain the change, which the literal half then flagged. Reworded rather than teaching the check about quotation — the check stays dumb, which is the property that makes it survivable. What it does not catch, in its own comment rather than left to be found: a novel phrasing that omits a package in a file naming all three somewhere else. The completeness half is per-file, not per-claim. Register: 93 entries, 10 open, 83 resolved. Still 0 actionable. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/publish_package.yml | 8 +++- docs/guides/publishing-to-pypi.md | 2 +- docs/validate_docs.sh | 57 +++++++++++++++++++++++++++ reports/technical_risk_register.md | 52 +++++++++++++++++++++++- 4 files changed, 114 insertions(+), 5 deletions(-) diff --git a/.github/workflows/publish_package.yml b/.github/workflows/publish_package.yml index 8c71701..2d6bee4 100644 --- a/.github/workflows/publish_package.yml +++ b/.github/workflows/publish_package.yml @@ -9,8 +9,12 @@ name: Publish Package # Publisher: GitHub | Owner: views-platform | Repo: views-frames # Workflow: publish_package.yml | Environment: (leave blank) # -# The single `views-frames` wheel ships BOTH packages (`views_frames` + -# `views_frames_summarize`) — one PyPI project, `pip install views-frames`. +# The single `views-frames` wheel ships all three packages — `views_frames`, +# `views_frames_summarize` and `views_frames_reconcile` — as one PyPI project, so +# `pip install views-frames` makes all three importable. The authority is +# `[tool.hatch.build.targets.wheel] packages` in pyproject.toml. This comment named +# only the first two until 2026-08-18, having been written before the third package +# shipped in v1.7.0. `docs/validate_docs.sh` check 10 now keeps the two in step. on: release: diff --git a/docs/guides/publishing-to-pypi.md b/docs/guides/publishing-to-pypi.md index cfb6f5e..957c02c 100644 --- a/docs/guides/publishing-to-pypi.md +++ b/docs/guides/publishing-to-pypi.md @@ -110,7 +110,7 @@ Trusted-Publishing workflow (recommended) **or** create a new token **scoped to ```bash rm -rf dist && uv build uvx --from twine twine check dist/* # both files must say PASSED -# sanity: BOTH packages + their py.typed are in the wheel +# sanity: all three packages + their py.typed are in the wheel python3 -c "import zipfile,glob; ns=zipfile.ZipFile(glob.glob('dist/*.whl')[0]).namelist(); \ print([n for n in ns if n.endswith('py.typed')])" # expect all three packages' py.typed diff --git a/docs/validate_docs.sh b/docs/validate_docs.sh index d39a1f7..5d659d7 100755 --- a/docs/validate_docs.sh +++ b/docs/validate_docs.sh @@ -284,6 +284,63 @@ fi fi # ../src exists +# 10. The documents that describe the CURRENT wheel name every package it ships, and +# none of them claims a stale count (register: the package-count drift class). +# +# Two halves, because neither catches the other's case. `.github/workflows/ +# publish_package.yml` named two of three packages while never using a count word, +# so only the completeness half sees it; `docs/guides/publishing-to-pypi.md` said +# "BOTH packages" in one comment while naming all three elsewhere in the same file, +# so only the literal half sees it. Both were live on 2026-08-18. +# +# SCOPED ON PURPOSE to documents that describe the wheel as it is today. ADRs, +# postmortems, the register and the CHANGELOG state counts that were true when +# written — "Two packages to maintain" (ADR-017), "shipped in both packages" (a +# dated C-23 resolution) — and flagging those would make this check noise, which +# is how a check gets deleted. Same reasoning as check 3, which restricts itself +# to the constitutional ADRs. +# +# WHAT IT DOES NOT CATCH: a novel phrasing that omits a package in a file which +# names all three somewhere else. The completeness half is per-file, not per-claim. +echo "--- Checking the wheel-describing documents against pyproject.toml ---" +before=$errors +WHEEL_DOCS="../.github/workflows/publish_package.yml ../docs/guides/publishing-to-pypi.md" +if [ ! -f "../pyproject.toml" ]; then + echo " ERROR: no ../pyproject.toml; cannot read the wheel's package list" + errors=$((errors + 1)) +else + # The source of truth: [tool.hatch.build.targets.wheel] packages = ["src/a", "src/b"] + pkgs=$(grep -m1 '^packages = \[' ../pyproject.toml | grep -oE '"[^"]+"' | tr -d '"' | sed 's|.*/||') + pkg_count=$(printf '%s\n' "$pkgs" | grep -c .) + if [ "$pkg_count" -eq 0 ]; then + echo " ERROR: could not read [tool.hatch.build.targets.wheel] packages from pyproject.toml" + errors=$((errors + 1)) + fi + for doc in $WHEEL_DOCS; do + if [ ! -f "$doc" ]; then + echo " ERROR: $doc is missing; it is one of the documents that describes the wheel" + errors=$((errors + 1)) + continue + fi + # (a) completeness — every shipped package is named + for pkg in $pkgs; do + grep -qE "\b${pkg}\b" "$doc" || { + echo " ERROR: $doc does not name '$pkg', which the wheel ships" + errors=$((errors + 1)) + } + done + # (b) literal — no stale count word + stale=$(grep -niE '\b(both|two) packages\b' "$doc" || true) + if [ -n "$stale" ]; then + echo " ERROR: $doc claims a stale package count (the wheel ships $pkg_count):" + printf ' %s\n' "$stale" + errors=$((errors + 1)) + fi + done +fi +[ "$errors" -eq "$before" ] && echo " OK (wheel ships $pkg_count packages; checked $(printf '%s' "$WHEEL_DOCS" | wc -w) wheel-describing documents)" + + echo "" if [ "$errors" -gt 0 ]; then echo "=== FAILED: $errors issue(s) found ===" diff --git a/reports/technical_risk_register.md b/reports/technical_risk_register.md index fc1c586..96030db 100644 --- a/reports/technical_risk_register.md +++ b/reports/technical_risk_register.md @@ -5,9 +5,9 @@ | Project | views-frames | | Owner | VIEWS platform maintainers | | Last Updated | 2026-08-18 | -| Total Concerns | 92 | +| Total Concerns | 93 | | Open Concerns | 10 | -| Resolved Concerns | 82 | +| Resolved Concerns | 83 | | Disagreements | 12 | --- @@ -441,6 +441,54 @@ Cross-refs: C-47 (eval provenance kept out of the generic header — the precede > Resolved 2026-07-31 by **ADR-027** (Epic #208 / S1 #209) — the #113 decision. +### C-96: the wheel's package count drifted in the documents that describe it — RESOLVED + +| Field | Value | +|-------|-------| +| ID | C-96 | +| Tier | 4 | +| Resolved | 2026-08-18 | +| Resolution | Both live sites corrected, and `docs/validate_docs.sh` check 10 added so the documents that describe the wheel are held against `[tool.hatch.build.targets.wheel] packages`. | +| Source | pre-release falsification audit (2026-08-18, F3) — an unpredicted finding | +| Cross-refs | C-74 (a check that does not run), C-86 (the README tree, the same drift one document over), C-77 (the evidence discipline this entry is an instance of), ADR-023 (the release that made the count three). | + +The wheel has shipped three packages since v1.7.0. Two documents still said two: + +- `.github/workflows/publish_package.yml` — a comment in the workflow that **actually + publishes**, naming two of the three. It never used a count word, so only a completeness + check sees it. +- `docs/guides/publishing-to-pypi.md` — `# sanity: BOTH packages + their py.typed`, sitting + **two lines above** a comment corrected earlier the same day to say "all three". The file + names all three packages elsewhere, so only a literal check sees it. + +**Tier 4 — no correctness impact.** Both are comments. The reason this is registered at all is +the second one: that file was corrected on 2026-08-18 and the class was reported as fixed after +a grep for one remembered phrasing. This is the fourth time this register has recorded a fix +that reached the instance rather than the class, and the first time the miss was inside a file +the author had already edited. + +**Check 10 has two halves because neither catches the other's case** — completeness (every +package in the wheel target is named) misses the guide, literal (no stale count word) misses +the workflow. It is scoped to the documents describing the *current* wheel and excludes ADRs, +postmortems, this register and the CHANGELOG, all of which state counts that were true when +written: ADR-017's "Two packages to maintain", C-23's "shipped in both packages". Flagging +those would make the check noise, and a noisy check gets deleted. Same scoping reasoning as +check 3, which restricts itself to the constitutional ADRs. + +Mutation-tested in five directions: a stale count word reintroduced, a package dropped from +either document, a **fourth** package added to the wheel target and left undocumented (the +generalisation test), and an unreadable package list. All five error. + +It then caught a real regression within minutes of being written: a `git checkout` used to +clean up after the first mutation discarded the still-uncommitted fix to the workflow, and the +check failed on the next run rather than the mistake reaching a commit. + +**What it does not catch**, stated in the check's own comment rather than left to be found: a +novel phrasing that omits a package in a file which names all three somewhere else. The +completeness half is per-file, not per-claim. + +--- + ### C-84: the physical-architecture standard described a repository that no longer existed — RESOLVED | Field | Value |