test(comments): no plan code lands in the code again

planCodes.contract.test.ts scans every tracked text file and every new one not yet added (comments,
docstrings, test titles, lint messages alike) for an epic or roadmap code (`E28`, `E9.5`, `R14`) and
for a sprint or review round cited on its own (`(S6)`, `S3e2`, `round 4`, `deep-review`). Not
`E2E`, not a ruff rule family (`E4/E7/E9`), not a TV episode (`S2 · E5`, a test episode titled
"E1"), not `S3h` (the media-card decision docs/DESIGN.md is headed by). Markdown and the Alembic
migrations keep their history and are not scanned.

One sweep test rather than an ESLint rule plus a ruff one: the codes sat in Python, TS, CSS, shell,
TOML, YAML and lint messages, and no single linter reads all of them. Seen red on a planted
backend/app file (all three plan-code lines named, its allowed line not).

audit_metrics.py counts epic codes by the same definition (it used to miss `E9.5` and `R6`), and
CLAUDE.md's "comment the why" rule names the test.
This commit is contained in:
2026-10-05 00:19:39 +02:00
parent 4aaaaa7860
commit 4e71723a07
3 changed files with 67 additions and 4 deletions
+2 -1
View File
@@ -125,7 +125,8 @@ controls (`ui/Input`, `Checkbox`, `Slider`, …), glass surfaces (`SURFACE.*`),
"no results". Reads degrade honestly; writes are conditional (`UPDATE … WHERE status='running'`).
- **i18n parity.** HU/EN, zero key drift. Every user-facing string is translated.
- **Comment the "why", keep it current.** This codebase uses comments as its architecture doc; a stale
"why" is a liability, so update it when the behavior changes.
"why" is a liability, so update it when the behavior changes. Say the why itself, never the plan
step that produced it: no epic, sprint or review-round ids in the code (`planCodes.contract.test.ts`).
---
@@ -0,0 +1,59 @@
import { execFileSync } from "node:child_process";
import { existsSync, readFileSync } from "node:fs";
import { describe, expect, it } from "vitest";
// The code says WHY; the plan that produced it stays in the private ops repo. A comment that cites
// `E28 review J4`, `(R6 S3b)` or `deep-review round 5` names a document no reader of this repo has,
// so the citation is noise at best, and at worst a rule that only makes sense next to the plan. All
// of them were taken out at once (2026-10-04); this keeps new ones out of every tracked text file and
// every new one not yet added (comments, docstrings, test titles, lint messages alike).
//
// Not scanned: Markdown (the docs and the changelog keep a decision's date and its epic as history)
// and the Alembic migrations (each one is a dated record of what changed).
const REPO = new URL("../../../", import.meta.url);
const SKIPPED =
/\.(md|webp|png|jpe?g|ico|woff2?)$|^backend\/alembic\/versions\/|package-lock\.json$/;
// the guard itself, and the metric that counts epics by the same definition
const ALLOWED = new Set([
"frontend/src/lib/planCodes.contract.test.ts",
"scripts/audit_metrics.py",
]);
const PLAN_CODES = [
// an epic (`E28`, `E9.5`) or an older roadmap item (`R14`) — not `E2E`, not a ruff rule family
// (`E4/E7/E9`), not a TV episode (`S2 · E5`, a test show's episode titled "E1")
/(?<!S\d{1,2}\s?·?\s?)(?<![/"])\b(?:E\d{1,2}(?:\.\d+)?|R\d{1,2})\b(?![/"E])/,
// a sprint cited on its own (`(S6)`, `S3e2`) or a review round (`round 4`, `deep-review`) — not
// `S3h`, the media-card decision docs/DESIGN.md is headed by and the design lab labels
/\(S\d{1,2}[a-z]?\d?\)|\bS(?!3h\b)\d{1,2}[a-z]\d?\b|\b[Rr]ound[ -]\d|deep-review/,
];
function tracked(): string[] {
const out = execFileSync(
"git",
["ls-files", "-z", "--cached", "--others", "--exclude-standard"],
{
cwd: REPO,
encoding: "utf-8",
},
);
// a file deleted but not yet staged is still listed
return out
.split("\0")
.filter((f) => f && !SKIPPED.test(f) && !ALLOWED.has(f) && existsSync(new URL(f, REPO)));
}
describe("plan codes", () => {
it("are not cited in the code", () => {
const files = tracked();
expect(files.length).toBeGreaterThan(1000); // a scan that reads nothing is green over nothing
const hits = files.flatMap((f) =>
readFileSync(new URL(f, REPO), "utf-8")
.split("\n")
.flatMap((line, i) =>
PLAN_CODES.some((re) => re.test(line)) ? [`${f}:${i + 1}: ${line.trim()}`] : [],
),
);
expect(hits).toEqual([]);
});
});
+6 -3
View File
@@ -25,9 +25,12 @@ BE_TESTS = ROOT / "backend" / "tests"
FE_SRC = ROOT / "frontend" / "src"
BIG_FILE = 800
BE_COMPLEXITY = 10 # ruff's C901 default
FE_COMPLEXITY = 20 # the frontend's line (E32)
FE_COMPLEXITY = 20 # the frontend's line
EPIC_CODE = re.compile(r"\b(E\d{2}|R\d{1,2})(\s?S\d+)?\b")
# what planCodes.contract.test.ts holds the code to: an epic (`E28`, `E9.5`) or a roadmap item (`R14`),
# not `E2E`, not a ruff rule family (`E4/E7/E9`), not a TV episode (`S2 · E5`, an episode titled "E1")
EPIC_CODE = re.compile(r'(?<![/"])\b(E\d{1,2}(\.\d+)?|R\d{1,2})\b(?![/"E])')
EPISODE = re.compile(r"S\d{1,2}\s?·?\s?E\d+")
NARRATION = re.compile(r"\b(used to|no longer)\b", re.IGNORECASE)
@@ -111,7 +114,7 @@ def _complexity() -> dict[str, object]:
def _noise(be: list[tuple[Path, list[str]]], fe: list[tuple[Path, list[str]]]) -> dict[str, object]:
every = be + fe
epic = [(p, ln) for p, ls in every for ln in ls if EPIC_CODE.search(ln)]
epic = [(p, ln) for p, ls in every for ln in ls if EPIC_CODE.search(EPISODE.sub("", ln))]
be_c = sum(_comment_lines(ls, True) for _, ls in be)
fe_c = sum(_comment_lines(ls, False) for _, ls in fe)
return {