From ff83769b30c5df4cf17963b6a24031d682488b7f Mon Sep 17 00:00:00 2001 From: Danijel Martinek Date: Tue, 12 May 2026 23:16:52 +0200 Subject: [PATCH] =?UTF-8?q?docs(work):=20story=2003.a=20=E2=80=94=20struct?= =?UTF-8?q?ural=20ESLint=20rules?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../03-a-structural-eslint-rules/_story.md | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 docs/work/conformance-system-v1/03-a-structural-eslint-rules/_story.md diff --git a/docs/work/conformance-system-v1/03-a-structural-eslint-rules/_story.md b/docs/work/conformance-system-v1/03-a-structural-eslint-rules/_story.md new file mode 100644 index 0000000..fed7233 --- /dev/null +++ b/docs/work/conformance-system-v1/03-a-structural-eslint-rules/_story.md @@ -0,0 +1,64 @@ +--- +id: 03-a-structural-eslint-rules +epic: conformance-system-v1 +title: Structural ESLint rules (feature-must-have-manifest, usecase-must-have-test-file, required-cores-installed) +type: technical-story +status: in-progress +feature: core-eslint +depends-on: [02-boot-assertions] +blocks: [03-b-ast-aware-eslint-rules] +--- + +## Goal +Stand up the custom ESLint rule plugin in `@repo/core-eslint` and ship three +structural conformance rules that don't require cross-file AST analysis. +Editor + CLI feedback fires in <1s. + +## Why +Boot-time assertion catches drift in bound use cases, but cannot catch: +- Features that exist on disk but have no manifest at all +- Use-case files lacking a sibling test file +- Manifest declaring required cores that aren't in `pnpm-workspace.yaml` + +Structural ESLint rules surface these in the editor, before code is even +saved past lint-on-save. + +## Done when +- Custom rule plugin exists at `packages/core-eslint/plugin.js` +- Three rules registered: `conformance/feature-must-have-manifest`, + `conformance/usecase-must-have-test-file`, + `conformance/required-cores-installed` +- Each rule has RuleTester tests with positive + negative cases +- `base.js` registers the plugin and enables the rules +- `pnpm lint` passes for the current monorepo state (rules tuned to today's + reality — see Out of scope) + +## In scope +- Custom rule plugin module at `packages/core-eslint/plugin.js` +- Rule modules in `packages/core-eslint/rules/*.js` +- Manifest text parser (`_manifest-source.js`) — regex-based, sufficient for + literal `as const` manifests +- Workspace.yaml reader (`_workspace.js`) +- Rule integration into `base.js` +- Tests for each rule using ESLint's RuleTester + +## Out of scope +- Cross-file AST analysis rules (`no-undeclared-event-publish`, + `no-undeclared-audit`) — milestone iii.b +- Enforcement on features that don't yet have a manifest — `feature-must-have-manifest` + ships as a WARNING today (only auth has a manifest); flips to ERROR after + blog/media/navigation/marketing-pages get manifests +- Manifest parser based on TypeScript compiler API — regex is sufficient for + literal manifests; the AST path comes in iii.b + +## Tasks +- [ ] Story 03.a scaffold +- [ ] Manifest source helper (`_manifest-source.js`) +- [ ] Workspace helper (`_workspace.js`) +- [ ] `feature-must-have-manifest` rule + tests +- [ ] `usecase-must-have-test-file` rule + tests +- [ ] `required-cores-installed` rule + tests +- [ ] Plugin module + `exports` entry in `package.json` +- [ ] Wire plugin into `base.js` +- [ ] Verify `pnpm lint` passes against the monorepo +- [ ] Final verification + story closeout