Skip to content

chore(deps): remove runtime dependencies nothing imports, and unblock Dependabot's safe updates - #7

Merged
qmarcelle merged 2 commits into
mainfrom
chore/remove-unused-dependencies
Jul 26, 2026
Merged

chore(deps): remove runtime dependencies nothing imports, and unblock Dependabot's safe updates#7
qmarcelle merged 2 commits into
mainfrom
chore/remove-unused-dependencies

Conversation

@qmarcelle

Copy link
Copy Markdown
Contributor

Replaces Dependabot PRs #4, #5 and #6, and fixes the config flaw that produced the failing #3.

The finding

Cross-checking every declared dependency of @workspacejson/rules against every import in its source:

used     @workspacejson/spec      used     remark
used     ajv                      used     remark-parse
used     fast-glob                used     simple-git
UNUSED   dedent   UNUSED   ignore   UNUSED   unified   UNUSED   zod

zod and unified appear only as string literals in the framework-detection tables (agents-md-parser.ts:75, framework-drift.ts:21) — the parser looks for the word "zod" in a manifest, it never loads the library. ignore and dedent have no references of any kind.

These were dependencies, not devDependencies, so every consumer installed all four to support code that does not exist.

@workspacejson/spec had the same problem in dev scope: json-schema-to-typescript existed for scripts/generate-types.js, which was a no-op —

const schemaPath = new URL('../schema/v1.json', import.meta.url);
await readFile(schemaPath, 'utf8');   // reads it, discards it

src/types.ts is hand-written and committed. Nothing was ever generated. Build script is now plain tsc.

Why the Dependabot PRs were misleading

#4 (ignore 5→7) and #5 (zod 3→4) both passed CI on Node 20 and 22. They passed because nothing exercises those packages. A green check on an unused dependency is not evidence of anything — which is exactly the "no false green" failure mode worth guarding against.

What prevents recurrence

A new unused-dependency guard in scripts/check-architecture.mjs, with a red test and a matching acceptance test proving it does not simply flag everything:

PASS  rejected — unused-dependency: a runtime dependency nothing imports
PASS  unused-dependency: an imported subpath dependency is ACCEPTED
25 passed, 0 failed

devDependencies are deliberately not checked — build tools, type packages and test runners are legitimately invoked by config rather than by an import statement, so absence of an import proves nothing there.

Dependabot config fix (second commit)

#3 failed on error TS5102: Option 'baseUrl' has been removed. The dev-tooling group had bundled a harmless @types/node patch with typescript ^5.4 → ^7.0 and vitest ^1.6 → ^4.1 — one safe update held hostage by two ecosystem migrations.

  • The group is now restricted to minor and patch; majors arrive individually.
  • typescript and vitest majors are ignored. Both are migrations rather than updates: TypeScript emits the declarations consumers install, and @workspacejson/rules re-exports vitest helpers through its published ./testing entry point, making a vitest major a public-surface change for anyone writing rule tests.

Verification

check:architecture      OK — 139 tracked files, 0 violations
check:architecture:test 25/25 (2 new)
check:docs              OK
build / typecheck       OK
tests                   36 + 173 passed, unchanged
check:schema            sha256 7f1635bb… unchanged
check:examples          4/4
release:verify-packs    OK — both tarballs release-safe

Lockfile shrinks by ~15KB.

Follow-ups, not in this PR

  • tsconfig.base.json:6 sets baseUrl, which does nothing under moduleResolution: NodeNext with no paths — and is fatal under TypeScript 7. Deleting it is a one-liner that unblocks that upgrade whenever it is scheduled.
  • TypeScript 7 and vitest 4 are now deliberate work rather than bot PRs.

`@workspacejson/rules` declared `dedent`, `ignore`, `unified` and `zod` in
`dependencies`. None is imported anywhere in the package. `zod` and `unified`
appear only as string literals in the framework-detection tables — the parser
looks for the word "zod" in a manifest, it never loads the library.

These were `dependencies`, not `devDependencies`, so every consumer of
@workspacejson/rules installed all four to support code that does not exist.
Removing them changes no behavior: 36 + 173 tests pass unchanged, and the
schema hash is untouched at 7f1635bb.

The cost was not only install weight. Dependabot opened major-version upgrade
PRs for `ignore` (5 -> 7) and `zod` (3 -> 4), both of which passed CI cleanly —
because nothing exercises them. A green check on an unused dependency is not
evidence of anything.

`@workspacejson/spec` drops the unused `json-schema-to-typescript`
devDependency and `scripts/generate-types.js`, which read the schema file and
discarded the result. `src/types.ts` is hand-written and committed; nothing was
ever generated from it. The build script is now plain `tsc`.

Adds an `unused-dependency` guard to scripts/check-architecture.mjs with a red
test and a matching acceptance test, so a dependency that is declared but never
imported fails the build rather than waiting to be noticed. devDependencies are
deliberately not checked — build tools and type packages are legitimately
invoked by config rather than by an import.
The first run of the dev-tooling group bundled a harmless `@types/node` patch
(22.19.17 -> 22.20.1) with `typescript` ^5.4 -> ^7.0 and `vitest` ^1.6 -> ^4.1.
The group failed on `error TS5102: Option 'baseUrl' has been removed`, so one
safe update was held hostage by two ecosystem migrations.

The group is now restricted to minor and patch. Majors arrive as individual
PRs that can be scheduled as the real work they are.

Also ignores majors for two dependencies where a bump is a migration:

  * typescript — TypeScript 7 removes compiler options this tsconfig still
    sets, and it emits the declarations @workspacejson/rules typechecks
    against and consumers install.
  * vitest — @workspacejson/rules re-exports vitest helpers through its
    published ./testing entry point, so a vitest major is a public-surface
    change for consumers writing rule tests, not an internal bump.
Copilot AI review requested due to automatic review settings July 26, 2026 12:02

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@qmarcelle
qmarcelle merged commit d0bb585 into main Jul 26, 2026
2 checks passed
@qmarcelle
qmarcelle deleted the chore/remove-unused-dependencies branch July 26, 2026 12:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants