Skip to content

feat(core): govern lowercase units in architecture/reserved-directory-names - #409

Merged
oekazuma merged 4 commits into
mainfrom
fix/386-any-case-unit-scopes
Aug 8, 2026
Merged

oekazuma merged 4 commits into
mainfrom
fix/386-any-case-unit-scopes

Conversation

@oekazuma

@oekazuma oekazuma commented Aug 8, 2026 •

Copy link
Copy Markdown
Owner

Fixes #386.

Summary

unitScopes identifies units with isUnitDir, which requires the directory name to begin A–Z — so the children of lowercase units (.ts/.svelte.ts entries, 129 of 299 units = 43% on the measured tree) were never checked by any declaration, silently. architecture/reserved-name-placement already closed this for itself with isAnyCaseUnitDir; both design docs record "the same split would close it here" without tracking it.

Changes

  • New option map anyCaseUnitScopes (same value grammar as unitScopes, matched via the already-exported isAnyCaseUnitDir). The name follows the reserved-name-placement design's recorded rationale — the bare word "unit" must not name either map — applying its anyCase vocabulary to unitScopes' existing name.
  • Tie-break (three-way): glob specificity first via the existing moreSpecificGlob; on a byte-identical glob, scopes > unitScopes > anyCaseUnitScopes. The unit-map ordering is forced by the design's own worked convention: isUnitDir ⊂ isAnyCaseUnitDir, so the capitalised map is the narrower claim — the reverse order would make the design's partition pattern (one glob, capitalised superset + any-case subset) inexpressible and produce false positives. Pinned by three dedicated tests.
  • Collision semantics generalized: scopes × either unit map on one glob = full collision (as before); unitScopes × anyCaseUnitScopes on one glob = a legitimate partition, not a collision (the any-case entry keeps uncontested work at lowercase units). Tri-state unused-key diagnostics extended ("never a unit" vs "never a unit of either case").
  • Examined counts deliberately not added: unitScopes itself records none — the examined-counts design scopes the three sibling directory rules out. That gap is exactly issue Examined counts for the three glob-configured sibling directory rules #387, handled next (stacked on this branch).
  • 14 tests (the issue's .ts/.svelte.ts repro, unitScopes-alone silence pinned, capitalised unaffected, non-unit exclusion, partition tie-breaks, diagnostics); rule docs en/ja; configuration guide's map list updated with count-free wording ("Off until a scope map is set"); dated addenda on both design docs; changeset @svelte-vitals/core minor (default behavior unchanged — new findings only for users who declare the new map).

Known accepted edge

Dead-declaration bookkeeping is keyed by bare glob string: under the partition config on a tree with zero capitalised units, the fully-dead unitScopes copy draws no "never a unit" note (the shared string is marked used by the any-case copy). Under-reports only — consistent with the rule family's recorded direction.

Verification

pnpm -r typecheck / pnpm test (core 1317, cli 846, vite 209) / pnpm lint / pnpm -r build all green; no drift-test regen needed (new option, not a new rule).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added anyCaseUnitScopes configuration for applying reserved-directory-name checks to units regardless of capitalization.
    • Added precedence handling when multiple scope maps match the same directory.
    • Added diagnostics for unused, invalid, empty, or conflicting scope declarations.
  • Documentation

    • Updated configuration and rule documentation with usage guidance, examples, matching behavior, and restrictions.

oekazuma and others added 2 commits August 8, 2026 12:24
…-names

isUnitDir's letter test recognises only capitalised (.svelte-entry) units, so a
.ts- or .svelte.ts-entry unit's children were never governed by any unitScopes
declaration — measured at 129 of 299 units (43%) on a real tree (issue #386).

Add anyCaseUnitScopes, a string-map counterpart to unitScopes gated on
isAnyCaseUnitDir (isUnitDir without the letter test) instead of isUnitDir,
following the naming rationale architecture/reserved-name-placement records for
its own capitalisedUnitPlacements/anyCaseUnitPlacements split: the bare word
"unit" is ambiguous once both predicates exist.

An identical glob declared in both unit maps partitions rather than collides:
unitScopes's gate is a strict subset of anyCaseUnitScopes's, so unitScopes
governs at capitalised units and anyCaseUnitScopes governs alone at the
lowercase ones unitScopes never reaches — letting one glob express a
capitalised-superset / lowercase-subset convention. scopes still beats both
unit maps on a tie, unchanged. The tri-state unused-key diagnostics, examined
counts (this rule records none, matching unitScopes), and the tie-break are
covered by 14 new tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The reserved-directory-names bullet still said "off until one of the two is
set" and omitted anyCaseUnitScopes, added by the prior commit on this branch.
Reworded to name the new map and avoid hardcoding a map count that rots on
the next one (AGENTS.md's anti-hardcoding principle).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 8, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@oekazuma, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 7 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e8aaedb3-6441-4eee-b5e0-645a94251100

📥 Commits

Reviewing files that changed from the base of the PR and between 9283a02 and 62ad488.

📒 Files selected for processing (3)
  • docs/src/content/docs/ja/rules/architecture/reserved-directory-names.md
  • docs/src/content/docs/rules/architecture/reserved-directory-names.md
  • packages/core/src/rules/architecture/reserved-directory-names.ts
📝 Walkthrough

Walkthrough

The reserved-directory-names rule adds anyCaseUnitScopes for units with any capitalization. It updates precedence, matching, diagnostics, tests, English and Japanese documentation, design records, and release metadata.

Changes

Reserved directory names

Layer / File(s) Summary
Any-case matching and diagnostics
packages/core/src/rules/architecture/reserved-directory-names.ts, packages/core/test/reserved-directory-names.test.ts
The rule matches lowercase and capitalized units through three scope maps. It applies glob specificity and map priority, updates violation messages, and classifies unused or colliding declarations. Tests cover entry files, non-units, precedence, and diagnostics.
Documentation and release records
docs/src/content/docs/guides/(setup)/configuration.mdx, docs/src/content/docs/ja/guides/(setup)/configuration.mdx, docs/src/content/docs/rules/architecture/reserved-directory-names.md, docs/src/content/docs/ja/rules/architecture/reserved-directory-names.md, docs/superpowers/specs/*, .changeset/reserved-directory-names-any-case-units.md
The documentation and design records describe anyCaseUnitScopes, its precedence, restrictions, and diagnostics. The changeset records the new option and its empty default.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Configuration
  participant reserved_directory_names
  participant UnitDirectories
  participant Diagnostics
  Configuration->>reserved_directory_names: Provide scopes, unitScopes, and anyCaseUnitScopes
  reserved_directory_names->>UnitDirectories: Classify directories and match scope declarations
  UnitDirectories-->>reserved_directory_names: Return eligible units and selected declarations
  reserved_directory_names->>Diagnostics: Report reserved-name violations and unused declarations
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change: governing lowercase units in the reserved-directory-names rule.
Linked Issues check ✅ Passed The implementation, tests, diagnostics, documentation, design updates, and changeset satisfy the requirements in issue #386.
Out of Scope Changes check ✅ Passed All changes support issue #386 and remain limited to architecture/reserved-directory-names and its related documentation.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/src/content/docs/rules/architecture/reserved-directory-names.md`:
- Line 55: Replace the numeric heading in
docs/src/content/docs/rules/architecture/reserved-directory-names.md:55 with a
nonnumeric scope-map heading describing what its keys name. Apply the equivalent
synchronized Japanese heading in
docs/src/content/docs/ja/rules/architecture/reserved-directory-names.md:56,
removing “3 つのオプション” while preserving the heading’s meaning.

In `@packages/core/src/rules/architecture/reserved-directory-names.ts`:
- Around line 99-102: Correct the unit-scope predicate description across all
affected sites: in
packages/core/src/rules/architecture/reserved-directory-names.ts lines 99-102,
remove the .svelte restriction and describe the gap as missing generic any-case
unit-map declarations; in packages/core/test/reserved-directory-names.test.ts
lines 488-490, replace “any declaration” with unitScopes or unit-map
declarations; in the English documentation lines 66-70 and Japanese
documentation lines 67-71, state that anyCaseUnitScopes matches capitalized and
lowercase units, including .ts and .svelte.ts entries; and in
.changeset/reserved-directory-names-any-case-units.md lines 5-13, describe
anyCaseUnitScopes as capitalization-agnostic rather than lowercase-only.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2761ca01-6791-4192-a158-5ef44c881596

📥 Commits

Reviewing files that changed from the base of the PR and between 2c8a72b and 9283a02.

📒 Files selected for processing (9)
  • .changeset/reserved-directory-names-any-case-units.md
  • docs/src/content/docs/guides/(setup)/configuration.mdx
  • docs/src/content/docs/ja/guides/(setup)/configuration.mdx
  • docs/src/content/docs/ja/rules/architecture/reserved-directory-names.md
  • docs/src/content/docs/rules/architecture/reserved-directory-names.md
  • docs/superpowers/specs/2026-07-29-reserved-directory-names-design.md
  • docs/superpowers/specs/2026-08-06-reserved-name-placement-design.md
  • packages/core/src/rules/architecture/reserved-directory-names.ts
  • packages/core/test/reserved-directory-names.test.ts

Comment thread docs/src/content/docs/rules/architecture/reserved-directory-names.md Outdated
Comment thread packages/core/src/rules/architecture/reserved-directory-names.ts Outdated
oekazuma and others added 2 commits August 8, 2026 13:16
De-numerize the rule doc's "The three options" heading (en/ja) — it rots the
next time a scope map is added, same reasoning as the configuration.mdx fix
earlier on this branch.

Correct the rule's own JSDoc: isUnitDir's letter test doesn't require a
.svelte entry specifically (the .svelte/.ts split is the measured tree's
correlation, not the predicate), and a lowercase unit wasn't strictly never
checked by any declaration — a scopes key naming the parent directly could
still reach one. Narrowed to "no generic unit-map declaration governed it".

Comments and headings only, no behavior change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…le prose

De-numerize the JSDoc's "Three option maps" opener too, matching the doc
heading fixed earlier on this branch — same anti-count-rot reasoning.

The rule doc prose (en/ja) repeated the same two JSDoc inaccuracies fixed
previously: unitScopes's letter test doesn't require a .svelte entry
specifically (extension-agnostic predicate), and a lowercase unit's children
weren't strictly "never checked by any declaration" — a scopes key naming
the parent directly could still reach one. Narrowed to "no generic unit-map
declaration governed it" in both languages.

Comments and prose only, no behavior change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@oekazuma
oekazuma merged commit acee3c6 into main Aug 8, 2026
8 checks passed
@oekazuma
oekazuma deleted the fix/386-any-case-unit-scopes branch August 8, 2026 07:21
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.

architecture/reserved-directory-names: unitScopes never governs units whose names begin lowercase

1 participant