Skip to content

fix(scripts): refuse layer names that share a mermaid id, and mark the count-word tripwire a BUG invariant - #484

Merged
Vivswan merged 1 commit into
mainfrom
fix/scripts-arch-id-count-word
Oct 6, 2026
Merged

Vivswan merged 1 commit into
mainfrom
fix/scripts-arch-id-count-word

Conversation

@Vivswan

@Vivswan Vivswan commented Oct 6, 2026

Copy link
Copy Markdown
Owner

Before

$ renderArchitectureMermaid() over a layers map holding plain-data and plain_data
graph TD
  plain_data["src/plain-data.ts"]
  plain_data["src/plain_data.ts"]

Mermaid draws those two lines as one node. Nothing refused the declaration.

After

$ parseArchitecture() over the same declaration
architecture.yml: layers "plain-data" and "plain_data" share the mermaid id plain_data, which would draw them as one node of the module map; rename all but one

$ countWord(21)
Error: BUG: extend COUNT_WORDS (.github/scripts/lib/count-word.ts): no word for count 21

How

  • One id mapping: mermaidId() serves both the renderer and the refusal, so the two cannot drift apart.
  • Refused at the owner: parseArchitecture() groups layer names by that id and returns one problem per shared id, beside the other declaration problems.
  • A BUG: invariant: countWord() keeps its throw with a BUG: prefix, and its header states that every caller counts a code-derived list.
  • Caller census: on main no caller feeds countWord() a number read from a page (the section registry's length, MAX_RETRIES, closed.length).

Proof

  • Tests: test/architecture/architecture.test.ts and test/scripts/count-word.test.ts, 27 green (1 new case), both changed cases seen red before the fix.
  • Gates: typecheck, biome, knip, lint:arch on the committed architecture.yml, and build:docs idempotent.
Technical details
  • Follow-up after build(scripts): seal generated regions behind a parse-render round trip #483 lands: on build/markdown-regions, roundTrip() calls render(parse(body)), so a page whose count sentence lists 21 code spans reaches countWord(21) through the parse path.
  • That follow-up's fix: parseCountSentence() in gen-action-docs.ts refuses a count past the word table with a Result naming the line, before rendering reaches the throw.
  • Positive control: the committed architecture.yml holds no layer name with _, so no pair collides and readArchitecture(ROOT) still parses.
  • Three or more colliding names: the layers join with "and" and the fix reads "rename all but one".
  • Lines: +45 / -14 across 4 files, of which arch-lint.ts +26 / -8 (the two helpers and their use in the renderer), count-word.ts +4 / -3, tests +15 / -3.
  • Files: .github/scripts/{arch-lint.ts,lib/count-word.ts}, test/{architecture/architecture.test.ts,scripts/count-word.test.ts}.

Copilot AI balanced review requested due to automatic review settings October 6, 2026 07:18
@github-actions

github-actions Bot commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

File size check

0 over a hard cap (fails), 1 warning(s).

File Size Tier Cap
test/e2e/generators.ts 2641 lines warn 2560

Split the file, wrap the line, shorten or exempt the comment, or list the path in .file-size-allow.local with a # reason.

5 managed file(s) skipped; repo-platform owns them.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

The validation is centralized, deterministic, and covered by focused tests.

Review effort: Balanced
Findings: None

What changed in this PR

Prevents Mermaid node-ID collisions during architecture parsing and clarifies countWord() overflow as a programming invariant.

Changes:

  • Rejects layer names that normalize to the same Mermaid ID.
  • Reuses one ID-normalization helper for validation and rendering.
  • Prefixes count-word overflow errors with BUG: and updates tests.
File Description
.github/​scripts/​arch-lint.ts Adds Mermaid ID collision validation and shared normalization.
.github/​scripts/​lib/​count-word.ts Marks unsupported counts as BUG invariants.
test/​architecture/​architecture.test.ts Tests colliding layer-name rejection.
test/​scripts/​count-word.test.ts Updates invariant error expectations.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@Vivswan
Vivswan marked this pull request as ready for review October 6, 2026 07:32
@Vivswan
Vivswan merged commit 949dffa into main Oct 6, 2026
30 checks passed
@Vivswan
Vivswan deleted the fix/scripts-arch-id-count-word branch October 6, 2026 08:01
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.

2 participants