Skip to content

feat(nx-plugin): enforce module boundaries on new arch#16803

Merged
lewisd5 merged 6 commits intodevelopfrom
ci/nx-enforce-module-boundaries-new-arch
Apr 30, 2026
Merged

feat(nx-plugin): enforce module boundaries on new arch#16803
lewisd5 merged 6 commits intodevelopfrom
ci/nx-enforce-module-boundaries-new-arch

Conversation

@ysitbon
Copy link
Copy Markdown
Contributor

@ysitbon ysitbon commented Apr 24, 2026

✅ Checklist

  • npx changeset was attached.
  • Covered by automatic tests. 23 node --test assertions (8 project-tags + 15 boundary validator). End-to-end run on current tree is green with no pre-existing violations, so CI can land as blocking from day one.
  • Impact of the changes:
    • New enforce-boundaries job in .github/workflows/build-and-test-pr.yml calling the dedicated .github/workflows/test-boundaries-reusable.yml reusable workflow, gated on PRs touching domain/, shared/, or features/ — fails the PR on any boundary violation.
    • New pnpm lint:boundaries script for local verification.
    • Zero runtime behavior change for any published package. Adds scope:domain, scope:shared, type:domain-entity, type:domain-api tags to new-arch packages via the existing tools/nx-plugins/project-tags/plugin.js.

📝 Description

Locks the dependency graph of the new architecture (domain/, shared/, features/) before it drifts. Implements LIVE-29780 — the Jira description carries the full plan and the first comment on the ticket carries the research notes.

Tag taxonomy — inferred dynamically from the folder layout. No manual project.json tags.

Folder Tags
domain/entity/* scope:domain, type:domain-entity
domain/api/* scope:domain, type:domain-api
shared/* scope:shared
features/* scope:features (unchanged)

Dependency constraints:

```
scope:shared → [scope:shared] (leaf)
scope:domain → [scope:domain, scope:shared]
scope:features → [scope:features, scope:domain, scope:shared]
type:domain-entity → [type:domain-entity, scope:shared] (entities can't import APIs)
type:domain-api → [type:domain-entity, type:domain-api, scope:shared]
```

Legacy libs/, apps/, e2e/, tools/ stay unconstrained during migration — rules only fire when a project carries a matching source tag.

Enforcement — a Node validator at tools/nx-plugins/enforce-boundaries/validate.js walks the Nx project graph via @nx/devkit's createProjectGraphAsync and checks every workspace→workspace edge against DEP_CONSTRAINTS. Wired as a cacheable Nx target on the dedicated enforce-boundaries project at tools/nx-plugins/enforce-boundaries/. CI calls pnpm exec nx run enforce-boundaries:lint:boundaries from the dedicated enforce-boundaries job in build-and-test-pr.yml (which uses test-boundaries-reusable.yml). No ESLint involvement — stays aligned with the oxlint migration (143 of 149 packages with a lint script are already on oxlint).

Forward compatibilityDEP_CONSTRAINTS shape (sourceTag / onlyDependOnLibsWithTags) mirrors @nx/enforce-module-boundaries so the array ports verbatim to .oxlintrc.json when nrwl/nx-labs#441 publishes and oxlint's user-plugin loader stabilizes. Migration at that point: delete tools/nx-plugins/enforce-boundaries/ and .github/workflows/test-boundaries-reusable.yml, add .oxlintrc.json, swap the enforce-boundaries job to @nx/oxlint:lint. One commit.

Why not ESLint / oxlint-labs today — summarized above; full research (four alternatives, with rejection rationale and verification steps) is in the Jira comment on LIVE-29780.

❓ Context

  • JIRA or GitHub link: LIVE-29780
  • ADR link (if any): n/a — plan and research live in the Jira ticket description and first comment.

Copilot AI review requested due to automatic review settings April 24, 2026 15:20
@ysitbon ysitbon requested review from a team as code owners April 24, 2026 15:20
@live-github-bot live-github-bot Bot added tools Has changes in tools automation CI/CD stuff labels Apr 24, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 24, 2026

❌ Action Required: Monitored Files Changed

The following files in monitored folders have been modified:

  • .github/workflows/build-and-test-pr.yml
  • .github/workflows/test-libs-reusable.yml

Action Required: Please rebase your branch against develop to ensure consistency:

git rebase origin/develop

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Enforces module-boundary rules for the “new architecture” packages (domain/, shared/, features/) by inferring Nx project tags from folder layout and validating workspace-to-workspace dependencies in CI.

Changes:

  • Extend the existing Nx project-tags plugin to infer scope:domain, scope:shared, type:domain-entity, type:domain-api from folder layout (with node:test coverage).
  • Add a Node-based Nx project-graph validator (tools/nx-plugins/enforce-boundaries) and wire it as a cacheable root Nx target lint:boundaries.
  • Add a CI step to run the new boundaries target, plus a local pnpm lint:boundaries script and an explanatory note in AGENTS.md.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tools/nx-plugins/project-tags/plugin.js Adds tag inference for domain/ + shared/ packages.
tools/nx-plugins/project-tags/plugin.test.js Node unit tests covering new tag inference + regressions.
tools/nx-plugins/enforce-boundaries/constraints.js Defines the dependency-constraint ruleset (Nx-like depConstraints shape).
tools/nx-plugins/enforce-boundaries/validate.js Walks Nx project graph and reports boundary violations (CLI + exported findViolations).
tools/nx-plugins/enforce-boundaries/validate.test.js Node unit tests covering allowed/forbidden dependency edges.
project.json Adds root Nx target lint:boundaries to run the validator.
package.json Adds lint:boundaries convenience script.
.github/workflows/test-libs-reusable.yml Adds CI step to enforce module boundaries (blocking).
AGENTS.md Documents the new boundaries rule and where tags/constraints live.
.changeset/nx-enforce-module-boundaries-new-arch.md Changeset describing the new enforcement behavior.

Comment thread tools/nx-plugins/enforce-boundaries/project.json
Comment thread .github/workflows/test-libs-reusable.yml Outdated
Comment thread AGENTS.md Outdated
Extends the project-tags plugin so every package under domain/, shared/,
and features/ carries the tags that LIVE-29780's upcoming module-boundary
validator will rely on:

- domain/entity/*  -> scope:domain + type:domain-entity
- domain/api/*     -> scope:domain + type:domain-api
- shared/*         -> scope:shared
- features/*       -> scope:features (unchanged)

Legacy libs/, apps/, e2e/, and tools/ inference is untouched. 8 node:test
assertions lock both the new branches and the legacy regression paths.

Refs: LIVE-29780
@ysitbon ysitbon force-pushed the ci/nx-enforce-module-boundaries-new-arch branch from db34aa9 to 059afc9 Compare April 29, 2026 13:35
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 29, 2026

⚠️ E2E tests are required

Changes detected require e2e testing before merge (even before asking for any review).

🖥️ Desktop

-> Run Desktop E2E

  • Select "Run workflow"
  • Branch: ci/nx-enforce-module-boundaries-new-arch
  • Device: nanoSP or stax

📱 Mobile

-> Run Mobile E2E

  • Select "Run workflow"
  • Branch: ci/nx-enforce-module-boundaries-new-arch
  • Device: nanoX

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 29, 2026

Web Tools Build Status

Build Status Deployment
Web Tools Build ✅ Deployed https://web-tools-oamjk6wu3-ledger-hq-prd.vercel.app
Native Storybook Build ✅ Deployed https://native-ui-storybook-346emh730-ledger-hq-prd.vercel.app
React Storybook Build ✅ Deployed https://react-ui-storybook-rdtzmkiaf-ledger-hq-prd.vercel.app

ysitbon added a commit that referenced this pull request Apr 29, 2026
Per @gre-ledger feedback on PR #16803: the section is too verbose for
AGENTS.md and the "Legacy libs/apps/..." line risks confusing agents
working in those folders during the migration. Boundary rules already
live in the LIVE-29780 ticket description and in
tools/nx-plugins/enforce-boundaries/constraints.js.

Refs: LIVE-29780
Copilot AI review requested due to automatic review settings April 29, 2026 13:47
@ysitbon ysitbon requested review from Copilot and removed request for Copilot April 29, 2026 13:50
Copilot AI review requested due to automatic review settings April 29, 2026 14:40
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.

Comment thread tools/nx-plugins/project-tags/plugin.js
Comment thread .github/workflows/build-and-test-pr.yml Outdated
Comment thread .github/workflows/build-and-test-pr.yml
Adds a linter-agnostic validator that walks the Nx project graph and
verifies every workspace -> workspace edge against the new-arch layering
rules. Runs via @nx/devkit's createProjectGraphAsync, no ESLint involved
(the repo is migrating to oxlint; 143/149 packages already use it).

Rules (DEP_CONSTRAINTS, defined in tools/nx-plugins/enforce-boundaries/
constraints.js):

- scope:shared       can depend on scope:shared only (leaf layer)
- scope:domain       can depend on scope:domain + scope:shared
- scope:features     can depend on scope:features + scope:domain + scope:shared
- type:domain-entity can depend on type:domain-entity + scope:shared
- type:domain-api    can depend on type:domain-entity + type:domain-api + scope:shared
@ysitbon ysitbon force-pushed the ci/nx-enforce-module-boundaries-new-arch branch from 94951ec to cff540c Compare April 29, 2026 15:22
…heck workflow

inferTags: drop the duplicate domain/ and shared/ blocks. The
type-tag-aware blocks higher up already emit scope:domain /
scope:shared (alongside type:domain-entity / type:domain-api),
so behavior is preserved — just clearer to read.

CI: extract the boundary check into its own reusable workflow at
.github/workflows/test-boundaries-reusable.yml and call it from
build-and-test-pr.yml as a dedicated enforce-boundaries job, gated
on PRs touching domain/, shared/, or features/. Removes the now-
redundant step from test-libs-reusable.yml.

The new workflow is temporarily called via
@ci/nx-enforce-module-boundaries-new-arch so this PR can prove it
runs end-to-end. MUST be flipped back to @develop before merge.

Refs: LIVE-29780
Copilot AI review requested due to automatic review settings April 29, 2026 15:47
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.

Comment thread tools/nx-plugins/enforce-boundaries/constraints.js
Comment thread .github/workflows/build-and-test-pr.yml
Comment thread tools/nx-plugins/enforce-boundaries/validate.js
ysitbon added 2 commits April 29, 2026 18:06
A source project can match multiple depConstraints (e.g. a
type:domain-api project also has scope:domain). Before this fix
findViolations emitted one violation per matching rule, so the same
forbidden edge could surface twice in CI output and inflate the
violation count.

Now keyed by (sourceName, target): one entry per offending edge with
the failing source tags accumulated. Output formatting joins the
source tags with a comma. Adds a node:test case covering the multi-
tag dedup; existing single-tag tests adjusted from sourceTag (string)
to sourceTags (array).

Refs: LIVE-29780
@ysitbon ysitbon requested review from Copilot and removed request for Copilot April 29, 2026 17:00
@sonarqubecloud
Copy link
Copy Markdown

Copilot AI review requested due to automatic review settings April 30, 2026 08:06
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 9 changed files in this pull request and generated 1 comment.

Comment thread .github/workflows/test-boundaries-reusable.yml
Comment thread .github/workflows/build-and-test-pr.yml
Comment thread tools/nx-plugins/enforce-boundaries/validate.js
Copy link
Copy Markdown
Member

@LL782 LL782 left a comment

Choose a reason for hiding this comment

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

A couple of questions but happy to approve regardless of the answers

Edit: Thanks for answering the questions! Happy to approve

Comment thread tools/nx-plugins/enforce-boundaries/validate.test.js
@lewisd5 lewisd5 merged commit bc30cf9 into develop Apr 30, 2026
34 checks passed
@lewisd5 lewisd5 deleted the ci/nx-enforce-module-boundaries-new-arch branch April 30, 2026 14:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

automation CI/CD stuff skip-sync-check tools Has changes in tools

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants