You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Neither client declares @types/node — #2196 consolidated it to the root. The cli copy is hoisted transitively via @types/express, so it is constrained by nothing of ours: no range
we own governs it, and nothing pulls it forward when the root moves.
Why the guard does not catch it
verify:dep-lockstep reports OK, and it is right to. It compares only packages that a single tscprogram loads from two installs, and no one program sees both copies — so the
difference is outside its candidate set entirely. AGENTS.md says this in as many words:
A transitive copy is constrained by nothing of ours at all, and cli's @types/node
(24.13.1 against the root's 24.13.3) has already diverged on exactly that. verify:dep-lockstep does not catch either […] the cli @types/node difference goes
unreported because no one program sees both copies.
So this is a known, documented drift rather than a new discovery. Filing it because the
documentation currently states the problem without anything tracking the fix, and because two
patch versions of @types/node is the harmless end of a failure mode whose expensive end is a
type error that reproduces on one machine and not another.
Impact today
Low. It is a types-only package (no runtime code ships), the skew is two patch releases, and npm run local:gate passes — verify:typecheck-coverage gives all 1082 tracked source files a tsc pass. Nothing is broken right now; the concern is that nothing would tell us when it stops
being two patches.
A root overrides entry for @types/node — one declaration, still one place to bump,
and it reaches the transitive copy. Consistent with the repo's "pin a transitive with overrides" rule.
Widen verify:dep-lockstep so it compares installed copies of root-declared packages
directly rather than only those a shared tsc program loads. Catches the whole class instead
of this instance — but it is a real change to what the guard means, and would likely surface
the peer shadows in web and tui too (which currently agree with the root, so it would start
green).
(3) is the one that stops the next instance; (2) fixes this one now. They are not exclusive.
Done when
clients/cli and the root resolve the same @types/node
Something fails when they next diverge — either the widened guard, or a stated decision
that an overrides pin is the whole mechanism and the guard is deliberately left as-is
npm run local:gate passes
Found while smoke-testing the v2.5.0 payload — see the note on #2215 (comment)
clients/cliresolves@types/node24.13.1 while the repo root declares and installs24.13.3:
Neither client declares
@types/node— #2196 consolidated it to the root. The cli copy ishoisted transitively via
@types/express, so it is constrained by nothing of ours: no rangewe own governs it, and nothing pulls it forward when the root moves.
Why the guard does not catch it
verify:dep-lockstepreports OK, and it is right to. It compares only packages that a singletscprogram loads from two installs, and no one program sees both copies — so thedifference is outside its candidate set entirely.
AGENTS.mdsays this in as many words:So this is a known, documented drift rather than a new discovery. Filing it because the
documentation currently states the problem without anything tracking the fix, and because two
patch versions of
@types/nodeis the harmless end of a failure mode whose expensive end is atype error that reproduces on one machine and not another.
Impact today
Low. It is a types-only package (no runtime code ships), the skew is two patch releases, and
npm run local:gatepasses —verify:typecheck-coveragegives all 1082 tracked source files atscpass. Nothing is broken right now; the concern is that nothing would tell us when it stopsbeing two patches.
Options
@types/nodeinclients/cli— simplest, but re-creates the second declarationchore: consolidate shared toolchain devDependencies into the root package.json #2196 removed, and
AGENTS.mdis explicit that re-adding a root-declared package to a clientmanifest re-creates the duplicate the rule exists to make impossible (chore(deps): zod 4.4 blows the tsc heap in clients/web — held at ~4.3.6 #1896). Probably wrong.
overridesentry for@types/node— one declaration, still one place to bump,and it reaches the transitive copy. Consistent with the repo's "pin a transitive with
overrides" rule.verify:dep-lockstepso it compares installed copies of root-declared packagesdirectly rather than only those a shared
tscprogram loads. Catches the whole class insteadof this instance — but it is a real change to what the guard means, and would likely surface
the peer shadows in web and tui too (which currently agree with the root, so it would start
green).
(3) is the one that stops the next instance; (2) fixes this one now. They are not exclusive.
Done when
clients/cliand the root resolve the same@types/nodethat an
overridespin is the whole mechanism and the guard is deliberately left as-isnpm run local:gatepassesFound while smoke-testing the v2.5.0 payload — see the note on
#2215 (comment)