chore(eslint): enforce kebab-case filenames, purge convention prose#1747
chore(eslint): enforce kebab-case filenames, purge convention prose#1747hercemer42 wants to merge 4 commits into
Conversation
Add unicorn/filename-case (error, kebab-case) to catch macOS/Linux import casing mismatches, plus max-params, max-lines-per-function and promise/prefer-await-to-then as warnings. Relax filename-case for the generated ANTLR parser, snake_case demo fixtures and _-grouped tests, and scope max-lines-per-function to src. Drop the now-linted and unmeasurable clean-code prose from CLAUDE.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Coverage Impact This PR will not change total coverage. 🚦 See full report on Qlty Cloud »🛟 Help
|
Count only code lines so the length smell reflects logic, not comments or spacing. Non-blocking (warn); resolves the validator's preferential note. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Claude Fable 5 (claude-fable-5) — review + scope history
Final scope: CI note: the |
Warnings CI never gates on are dormant documentation, not enforcement. Keep the one rule with teeth (kebab-case filenames, blocks macOS/Linux import-casing bugs) and drop max-params, max-lines-per-function and promise/prefer-await-to-then along with the now-unused promise plugin. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Only file naming, formatting and unused-variable checks live in ESLint; the deleted principles were removed as generic prose, not migrated. Also drop the unused-variables checklist item — the linter already errors on it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

What
Encodes the one enforceable agent-nodejs convention as an ESLint rule (from the PRD-711 conventions analysis) and drops the unmeasurable clean-code prose from
CLAUDE.md.unicorn/filename-case— error, kebab-case. Prevents a real bug class: macOS (case-insensitive) vs Linux CI (case-sensitive) import-path mismatches. Relaxed via ignore-globs for the generated ANTLR parser (can't rename), snake_casedatasource-demo-fintechfixtures, and_-grouped test files — every existing violation is covered, so CI stays green while new violations are blocked.eslint-plugin-unicorn@^48.0.1(later majors require ESLint ≥8.56).CLAUDE.md: purged DRY/KISS/YAGNI, single-responsibility, AAA, pure-functions, comments-why-not-what, descriptive-names — generic prose that carried no repo-specific information.Why cutting the prose costs the models nothing:
CLAUDE.mdis injected into every agent session, so each line spends context budget. DRY/KISS/YAGNI/AAA-style advice is the most over-represented guidance in any model's training data — models (and experienced devs) already default to it unprompted, so restating it changes zero behavior. The repo's own measurements confirm the habits hold without the prose (median 8 lines/function, 99.9% of ~46k functions ≤4 params, kebab-case at 846/849). Meanwhile every generic line dilutes the doc's real job: carrying the Forest-specific signal a model can't guess — architecture, workflows, and the conventions the linter actually enforces.What was considered and dropped
Three advisory rules (
max-params: 4,max-lines-per-function: 50,promise/prefer-await-to-then) were measured (46 / 131 / 16 existing src violations) and initially added aswarn— then removed: CI has no--max-warningsgate, so a warning nobody fails on is dormant documentation, not enforcement. They can return aserror+ bulk suppressions after the ESLint 9 upgrade (blocked today by airbnb-config deprecation, separate ticket).max-lines-per-functionis the least likely to return as-is: the length distribution is bimodal (median 8, but a legitimate tail of long-declarative route handlers and decorator wiring), so a blunt line count can't separate justified outliers from real smells — that's per-function judgment, which belongs in the conventions corpus, not lint.Notes for reviewer
@typescript-eslint/no-throw-literalerrors inagent/src/routes/.../action-authorization.ts; this is a type-resolution artifact of the unbuilt tree (CI builds before linting and is clean). Unrelated to this change.Refs PRD-759
Note
Enforce kebab-case filenames via eslint-plugin-unicorn and trim CLAUDE.md conventions
eslint-plugin-unicornand enables theunicorn/filename-caserule (kebab-case) in .eslintrc.js, with overrides disabling it for generated ANTLR parser files, demo fixture packages, and test directories.Macroscope summarized 99443ce.