feat(core-domain): GT-377 AC-3 — ESLint stateless-Core *Repository guard + CI gate#147
feat(core-domain): GT-377 AC-3 — ESLint stateless-Core *Repository guard + CI gate#147beyondnetPeru wants to merge 2 commits into
Conversation
…an in ESLint + gate CI Migrate core-domain to ESLint 9 flat config (eslint.config.mjs) and add a no-restricted-syntax guard banning *Repository identifiers for product/initiative/evidence/decision — Core is a stateless Evaluation Engine, those are context not entities (ADR-0101). The rule is shared from eslint.guards.cjs (single source of truth) and covered by a 14-case negative regression test (stateless-core-repository.guard.spec.ts) proving it fires on the four banned entities and never on legit *Repository. Wire lint:boundaries into ci-cd.yml (test-core-domain); delete the dead .eslintrc.js. Root cause of the long-standing "lint:boundaries broken" note was NOT the boundaries plugin: the root global override "ajv":"8.17.1" conflicts with the workspaces' direct ajv:8.20.0 (EOVERRIDE), so npm dropped all ajv overrides and starved eslint/@eslint/eslintrc of ajv@6, throwing missingRefs/defaultMeta at load. Fixed with scoped overrides (ajv aligned to 8.20.0 + eslint/@eslint/eslintrc carved out to ajv@^6.12.6); lockfile change scoped to the eslint subtree (~82 lines, no cross-workspace drift), verified under npm ci. GT-377: AC-2 + AC-3 MET; AC-1 (schemas) still open -> stays IN-PROGRESS. Gap board + catalog updated (EN/ES). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4ea76378c7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| * if such an identifier is declared, imported, or referenced. | ||
| */ | ||
| import boundaries from 'eslint-plugin-boundaries'; | ||
| import tseslint from 'typescript-eslint'; |
There was a problem hiding this comment.
Declare the ESLint config's typescript-eslint dependency
When @evolith/core-domain is installed or linted in isolation, this new flat config imports the typescript-eslint meta-package even though packages/core-domain/package.json only declares @typescript-eslint/parser; the package is currently present only because another workspace (apps/core-api) happens to depend on it. A focused workspace install or future removal from that unrelated package will make npm run lint:boundaries --workspace @evolith/core-domain fail with ERR_MODULE_NOT_FOUND before the boundary guard can run, so core-domain should declare typescript-eslint directly or avoid importing it.
Useful? React with 👍 / 👎.
Reconciles claude/vigorous-gauss-d24b4d (GT-377 AC-3 stateless-Core *Repository guard) with main. No package.json/lockfile conflict: main already carried the byte-identical ajv-override fix from the mcp-server/core-api flat-config wave. Resolved conflicts: - ci-cd.yml: kept BOTH the core-domain boundary-guard step (GT-377) and the GT-382 build:policy step in test-core-domain. - gap board (EN/ES tracking + catalog): combined waves; with AC-1 (schemas) + AC-2 already on main, all three GT-377 ACs are MET -> GT-377 DONE. lint:boundaries green (0 errors) on the merged tree; core-domain 692/692. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
GT-377 AC-3 — ESLint stateless-Core
*Repositoryguard, enforcing + CI-gatedCloses the AC-3 acceptance criterion of GT-377: "ESLint boundary guard fails CI if a
*Repositoryfor product/initiative/evidence/decision appears."What this delivers
packages/core-domain/eslint.config.mjsbansIdentifier[name=/(Product|Initiative|Evidence|Decision)Repository/]viano-restricted-syntax. Core is a stateless Evaluation Engine — those are context, not entities (ADR-0101). Entity-scoped, so legit infra repos (AuditRepository,createRepository, …) are untouched.packages/core-domain/eslint.guards.cjs, imported by both the config and the test.src/evaluation/stateless-core-repository.guard.spec.ts— 14 cases proving the guard fires on all four banned entities (import + inline interface) and never on legit*Repository.Run core-domain architecture boundary guard (GT-377)step in.github/workflows/ci-cd.yml(test-core-domain). Before this PR,grep lint:boundaries .github/workflows= 0..eslintrc.js+--no-eslintrc(deleted the dead file);lint:boundariesscript →eslint "src/**/*.ts".Root cause of the long-standing "lint:boundaries broken" note
It was not the boundaries plugin. The root
package.jsonglobal override"ajv":"8.17.1"conflicts with the workspaces' directajv:8.20.0(EOVERRIDE), so under--legacy-peer-depsnpm silently dropped all ajv overrides and collapsedajv@8ontoeslint/@eslint/eslintrc(which needajv@6), making ESLint's loader throwmissingRefs/Cannot set properties of undefined (setting 'defaultMeta').Fix: scoped
overrides—ajvaligned to8.20.0(== direct dep, no conflict) + carve-outseslint/@eslint/eslintrc→ajv@^6.12.6.package.json(overrides) andpackage-lock.json(root).ajv@6.15.0, no cross-workspace drift), produced incrementally and verified undernpm ci.feat/core-gt377-schemas(AC-1),feat/core-gt379-blueprint-deployment,feat/core-gt382-wasm-pathif they also touched the lockfile. Recommend: merge sequentially and reconcile the lockfile at the end with the incremental method (remove only theeslint/@eslint/eslintrcentries from the lockfile +node_modules, thennpm install --legacy-peer-deps) — neverrm package-lock.json(full re-resolution drifts ~1300 lines, e.g.@types/node24→26).GT-377 status
feat/core-gt377-schemas— once it lands, GT-377 → DONE. Left asIN-PROGRESS.Verification
npm ci→npm run lint:boundaries --workspace @evolith/core-domain= 0 errors;tscbuild green; core-domain 692/692 tests; injectedProductRepositorycorrectly fails the guard,AuditRepositorydoes not.Follow-up (chip filed)
packages/mcp-serverandapps/core-apicarry the same brokenlint:boundaries(--no-eslintrc -c .eslintrc.js), ungated by CI — same migration pattern applies.🤖 Generated with Claude Code