[E00-S01-T04] Add dependency-boundary rule/test #371
No Reviewers
Labels
Clear labels
agent/analyst-drafted
agent/analyst-drafted
needs/human-decision
needs/human-decision
needs/security-review
needs/security-review
tier/t0
tier/t1
tier/t2
tier/t3
kind
bug
kind
bug
kind
epic
kind
epic
kind
initiative
EPPP programme initiative
kind
story
kind
story
kind
task
EPPP engineering card/task decomposed from a story
kind
toil
kind
toil
loop
1
loop
1
loop
2
loop
2
loop
3
loop
3
risk
agent-full
risk
agent-full
risk
human-gated
risk
human-gated
risk
human-only
risk
human-only
size
l
size
l
size
m
size
m
size
s
size
s
status
blocked
status
blocked
status
done
Workflow: Done
status
in-progress
status
in-progress
status
proposed
status
proposed
status
ready
status
ready
status
review
status
review
stream
checkout
stream
checkout
stream
onboarding
stream
onboarding
stream
platform
stream
platform
trivial — implementer only, auto-merge
standard — implementer + reviewer + tester
complex — security if triggered, human merge
critical — full chain + security, human merge
No labels
Milestone
No items
No Milestone
Projects
Clear projects
No projects
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: Fabrika/PersonalBlog#371
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
What changed
Adds the dependency-boundary rule and its enforcing architecture import test for [E00-S01-T04] Add dependency-boundary rule/test (#157):
dependency-boundaries.json(new, repo root) — the dependency-boundary rule, declared as machine-readable JSON:groups— classifies workspace packages by directory:apps/→apps,packages/→packages,extensions/→extensionsboundaries— encodes the boundary:packages -> extensionswith"allow": false("no core package can import a concrete extension"; core depends only on extension contracts, concrete extensions are wired in by the app layer)tests/architecture-import.test.mjs(new) — the architecture import test that enforces the rule. Built onnode:testwith zero new dependencies (lockfile untouched):package.jsonname)apps/*,packages/*,extensions/*; skipsnode_modules/dist/coverage) and resolves every module specifier — bare workspace names (@personal-blog/...), relative/absolute/file: paths,import,export … from, dynamicimport(),require()— to a workspace grouppackages/* -> extensions/*edgeExplicitly out of scope per the brief: ESM package boundaries (E00-S01-T03, merged), root build/test scripts (E00-S01-T05 — no root
scripts, no CI wiring here; run withnode --test tests/architecture-import.test.mjs), non-container developer path docs (E00-S01-T06). No manifests, no lockfile, no CI changes in this PR.Criterion → test table
dependency-boundaries.jsondeclaresgroups(apps/packages/extensions→apps/,packages/,extensions/) and aboundariesentrypackages -> extensionswith"allow": false; test "dependency-boundaries.json is present and declares the core -> extensions boundary" asserts the rule file exists and contains that forbidden edgetests/architecture-import.test.mjsloads the rule, scans every workspace package's source, resolves each import to a group and fails on any core→extension edge. Unit tests prove detection (bare name / relative path / export-from / dynamic import / require → violation; comments, allowed directions, external +node:imports → no violation). Integration test over the real workspace graph passes with zero violations; a deliberately injectedimport … from '@personal-blog/example-extension'inpackages/core/src/index.tsmakes it fail withpackages/core/src/index.ts:1 … violates packages -> extensionsTest plan executed
node --test tests/architecture-import.test.mjs(Node 22;node:test, CI runs Node 24) → 10/10 pass ✓export { register } from '@personal-blog/example-extension';intopackages/core/src/index.ts→ integration test fails withpackages/core/src/index.ts:1 imports @personal-blog/example-extension (@personal-blog/example-extension [extensions]) — violates packages -> extensions; reverted → green again ✓corepack pnpm install --frozen-lockfile(pnpm 11.23.0, same as CI) → "Already up to date", exit 0,pnpm-lock.yamlunchanged (git statusclean apart from the two new files) ✓node --check tests/architecture-import.test.mjs+ JSON parse of the rule file → valid ✓Risks / notes
packages -> extensionsedge is currently forbidden (per the issue intent); the rule file'sgroups+boundariesstructure is designed for more edges to be added later.Closes #157