@mmnto/cli 1.107.0 → 1.108.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/commands/config-drift.test.js +51 -0
  2. package/dist/commands/config-drift.test.js.map +1 -1
  3. package/dist/commands/docs.d.ts +1 -1
  4. package/dist/commands/docs.d.ts.map +1 -1
  5. package/dist/commands/docs.js +1 -1
  6. package/dist/commands/init-templates.d.ts +2 -2
  7. package/dist/commands/init-templates.d.ts.map +1 -1
  8. package/dist/commands/init-templates.js +5 -5
  9. package/dist/commands/init-templates.js.map +1 -1
  10. package/dist/commands/mail-degraded-e4.test.d.ts +5 -1
  11. package/dist/commands/mail-degraded-e4.test.d.ts.map +1 -1
  12. package/dist/commands/mail-degraded-e4.test.js +129 -2
  13. package/dist/commands/mail-degraded-e4.test.js.map +1 -1
  14. package/dist/commands/mail.d.ts +1 -0
  15. package/dist/commands/mail.d.ts.map +1 -1
  16. package/dist/commands/mail.js +16 -3
  17. package/dist/commands/mail.js.map +1 -1
  18. package/dist/commands/shield-banner.test.d.ts +17 -0
  19. package/dist/commands/shield-banner.test.d.ts.map +1 -0
  20. package/dist/commands/shield-banner.test.js +118 -0
  21. package/dist/commands/shield-banner.test.js.map +1 -0
  22. package/dist/commands/shield-classify.d.ts.map +1 -1
  23. package/dist/commands/shield-classify.js +2 -0
  24. package/dist/commands/shield-classify.js.map +1 -1
  25. package/dist/commands/shield-classify.test.js +12 -0
  26. package/dist/commands/shield-classify.test.js.map +1 -1
  27. package/dist/commands/shield.d.ts.map +1 -1
  28. package/dist/commands/shield.js +11 -0
  29. package/dist/commands/shield.js.map +1 -1
  30. package/dist/commands/spec-templates.d.ts +1 -1
  31. package/dist/commands/spec-templates.d.ts.map +1 -1
  32. package/dist/commands/spec-templates.js +1 -1
  33. package/dist/commands/verify-lockfile-sync.d.ts +11 -0
  34. package/dist/commands/verify-lockfile-sync.d.ts.map +1 -1
  35. package/dist/commands/verify-lockfile-sync.js +457 -2
  36. package/dist/commands/verify-lockfile-sync.js.map +1 -1
  37. package/dist/commands/verify-lockfile-sync.test.js +1112 -0
  38. package/dist/commands/verify-lockfile-sync.test.js.map +1 -1
  39. package/dist/git.d.ts +7 -0
  40. package/dist/git.d.ts.map +1 -1
  41. package/dist/git.js +75 -4
  42. package/dist/git.js.map +1 -1
  43. package/dist/git.test.js +125 -1
  44. package/dist/git.test.js.map +1 -1
  45. package/dist/index.js +1 -1
  46. package/dist/index.js.map +1 -1
  47. package/package.json +2 -2
@@ -27,6 +27,408 @@ const AUX_LOOKUP_TIMEOUT_MS = 10_000;
27
27
  // which generally don't require a lockfile diff anyway) and
28
28
  // rejects `workspace:^` references (no leading digit).
29
29
  const DEP_BUMP_RE = /^\+\s*"(?!version")[^"]+"\s*:\s*"[\^~]?\d+\.\d+/m;
30
+ // Match a QUOTED pnpm-lockfile key line (sign already stripped when the line
31
+ // comes from a diff). Anchors, left to right:
32
+ // `^\s+` — required indent. Every key that names a package is nested (an
33
+ // importer's dependency block, `packages:`, `snapshots:`), so the
34
+ // document-level keys (`lockfileVersion:`, `importers:`) never match.
35
+ // `'([^']+)'`
36
+ // — the quoted key. pnpm quotes any key containing `@` or another
37
+ // YAML-special char, which is every scoped name and every
38
+ // `name@version` packages/snapshots key.
39
+ // `:` — the key terminator. A quoted key is accepted with or without a
40
+ // scalar value: pnpm only quotes package names, so there is no
41
+ // metadata-key collision to exclude here.
42
+ const LOCKFILE_QUOTED_KEY_RE = /^\s+'([^']+)':/;
43
+ // Match a BARE pnpm-lockfile key line (sign already stripped). Same indent
44
+ // anchor as above, plus:
45
+ // `([^'\s:]+)`
46
+ // — the unquoted key (`ajv@8.18.0`, `commander`, `packages/cli`).
47
+ // `:(?:\s*\{\})?\s*$`
48
+ // — the key must carry NO scalar value (`foo@1.0.0:`) or the empty
49
+ // mapping (`foo@1.0.0: {}`). That is what pnpm emits for package
50
+ // keys, and it structurally excludes the scalar metadata keys
51
+ // (`resolution:`, `specifier:`, `version:`, `engines:`, `optional:`)
52
+ // without maintaining a blocklist. A package that disappears from
53
+ // the lockfile always loses its valueless `packages:`/`snapshots:`
54
+ // key line, so the restriction costs no detection.
55
+ const LOCKFILE_BARE_KEY_RE = /^\s+([^'\s:]+):(?:\s*\{\})?\s*$/;
56
+ // Parse ONE lockfile line into its indent and key. Anchors, left to right:
57
+ // `^( *)` — the indent, CAPTURED: YAML nesting is the only structure signal
58
+ // the lockfile gives, and the section walker needs the depth, not
59
+ // just the key.
60
+ // `(?:'([^']+)'|([^'\s:]+))`
61
+ // — the key, quoted (pnpm quotes scoped names and any key holding a
62
+ // YAML-special char) or bare (`ajv@8.18.0`, `packages/cli`, `.`).
63
+ // `:(?:\s.*)?$`
64
+ // — the key terminator plus an optional value. A value is NOT
65
+ // disqualifying here, unlike the candidate-side regexes: the walker
66
+ // decides membership by section and depth, so it needs no
67
+ // value-shape proxy for structure.
68
+ const LOCKFILE_KEY_LINE_RE = /^( *)(?:'([^']+)'|([^'\s:]+)):(?:\s.*)?$/;
69
+ // pnpm-lockfile GRAMMAR keys that are valueless like a package key but never
70
+ // name a package. Candidate parsing works line-by-line off a DIFF, which carries
71
+ // no section context, so the guard is still needed there (the HEAD-side harvest
72
+ // is section-aware and needs no blocklist). Without it, removing a repo's last
73
+ // devDependency would make `devDependencies` a candidate — absent from the HEAD
74
+ // lockfile, and "declared" because package.json still carries a
75
+ // `"devDependencies": {}` key — a false block on a legitimate push. The cost is
76
+ // that a dependency named EXACTLY one of these strings is invisible to the gate;
77
+ // a false block on a real push is the worse failure (mmnto-ai/totem#2473 class).
78
+ const LOCKFILE_STRUCTURAL_KEYS = new Set([
79
+ 'catalogs',
80
+ 'dependencies',
81
+ 'devDependencies',
82
+ 'importers',
83
+ 'optionalDependencies',
84
+ 'overrides',
85
+ 'packages',
86
+ 'patchedDependencies',
87
+ 'peerDependencies',
88
+ 'peerDependenciesMeta',
89
+ 'settings',
90
+ 'snapshots',
91
+ 'transitivePeerDependencies',
92
+ ]);
93
+ // The manifest blocks whose keys are install-resolvable dependency
94
+ // declarations — the only blocks that answer "is this pin still declared?".
95
+ // `overrides` / `resolutions` are excluded by design (see
96
+ // collectImporterDeclarations). Doubles as the importer-side dependency-block
97
+ // set for the lockfile walker: the lockfile mirrors these manifest blocks.
98
+ const MANIFEST_DEPENDENCY_BLOCKS = [
99
+ 'dependencies',
100
+ 'devDependencies',
101
+ 'optionalDependencies',
102
+ 'peerDependencies',
103
+ ];
104
+ // `git show` blob-ref prefix for the HEAD revision. Named once so every
105
+ // HEAD-blob read in this file builds the same ref shape.
106
+ const HEAD_REF_PREFIX = 'HEAD:';
107
+ // The workspace definition, read at HEAD. Its `packages:` globs are what admit a
108
+ // manifest this branch ADDS — such a package is not yet an importer of the
109
+ // lockfile at HEAD, so the importer set alone cannot see it.
110
+ const WORKSPACE_FILE_PATH = 'pnpm-workspace.yaml';
111
+ // A `packages:` list entry in pnpm-workspace.yaml: ` - 'packages/*'`. Anchors:
112
+ // `^\s*-\s*` — the YAML sequence dash at any indent.
113
+ // `(?:'([^']*)'|"([^"]*)"|(\S+))` — the glob, single-quoted, double-quoted, or
114
+ // bare (all three occur in the wild).
115
+ // `\s*$` — nothing else on the line; a trailing comment or an inline map
116
+ // is not a plain glob entry and is skipped rather than guessed at.
117
+ const WORKSPACE_PACKAGES_ENTRY_RE = /^\s*-\s*(?:'([^']*)'|"([^"]*)"|(\S+))\s*$/;
118
+ // Any top-level (indent-0) key line — used only to detect that the `packages:`
119
+ // block has ended.
120
+ const WORKSPACE_TOP_LEVEL_KEY_RE = /^\S.*:/;
121
+ // Opening prose of the removed-pin failure message
122
+ // (mmnto-ai/totem-strategy#630). REASON TEXT ONLY — the failure CLASS travels in
123
+ // `VerifyLockfileSyncResult.failureClass`, so editing this sentence can no
124
+ // longer change which remedy a user is handed.
125
+ const REMOVED_PIN_REASON_PREFIX = `${LOCKFILE_PATH} no longer contains any entry for a package whose pin is still declared in a tracked package.json at HEAD`;
126
+ // ─── Removed-pin predicate (mmnto-ai/totem-strategy#630) ─
127
+ /**
128
+ * The package NAME a lockfile key denotes. Strips a peer parenthetical
129
+ * (`pkg@1.0.0(react@19.0.0)`) and the trailing `@<version>` suffix: npm forbids
130
+ * `@` inside a package name except the leading scope marker, so the last `@`
131
+ * past index 0 always opens the version.
132
+ */
133
+ function packageNameFromKey(key) {
134
+ // Leading-slash canonicalization. lockfileVersion 9 — what pnpm emits today —
135
+ // uses NO leading slash, so this is not a v9 defect; but v5/v6-vintage
136
+ // lockfiles wrote `/ajv@8.18.0:` and `/@scope/name@1.0.0:`, and this gate
137
+ // ships to consumer repos through the distributed pre-push hook. Without the
138
+ // strip, an old-vintage repo's `packages:`/`snapshots:` keys all parse as
139
+ // `/name`, match nothing in any manifest, and the gate silently degrades to
140
+ // importer-only coverage.
141
+ const withoutLeadingSlash = key.startsWith('/') ? key.slice(1) : key;
142
+ const withoutPeers = withoutLeadingSlash.split('(')[0];
143
+ const versionAt = withoutPeers.lastIndexOf('@');
144
+ return versionAt > 0 ? withoutPeers.slice(0, versionAt) : withoutPeers;
145
+ }
146
+ /**
147
+ * The package NAME a REMOVED diff line denotes, or `null` when the line is not a
148
+ * key line. Diff-side only: a hunk carries no section context, so this leans on
149
+ * key shape plus the structural-key blocklist.
150
+ */
151
+ function lockfileKeyName(line) {
152
+ const match = LOCKFILE_QUOTED_KEY_RE.exec(line) ?? LOCKFILE_BARE_KEY_RE.exec(line);
153
+ if (match === null)
154
+ return null;
155
+ if (LOCKFILE_STRUCTURAL_KEYS.has(match[1]))
156
+ return null;
157
+ return packageNameFromKey(match[1]);
158
+ }
159
+ /**
160
+ * Index the lockfile at HEAD by SECTION and DEPTH, not by key-line shape.
161
+ *
162
+ * A shape-only harvest laundered the very class this gate exists to catch:
163
+ * `peerDependenciesMeta:` children (` zod:` / `optional: true`) are
164
+ * valueless key lines that SURVIVE a package's total removal, so a fully dropped
165
+ * package still answered "resolves at HEAD" and the gate passed — 21 such blocks
166
+ * in this repo's own lockfile. Only two things prove resolution: a
167
+ * `packages:`/`snapshots:` entry, and a workspace importer's dependency-block
168
+ * key (a workspace link has no `packages:` entry). Peer metadata, catalogs and
169
+ * settings are commentary ABOUT resolution, not resolution.
170
+ *
171
+ * The same pass collects the importer paths — the lockfile's own answer to
172
+ * "which manifests do I resolve?" — which scopes the declaration probe below.
173
+ *
174
+ * Child indents are learned from the file rather than hardcoded: the first line
175
+ * deeper than a section header defines that level's indent.
176
+ */
177
+ function indexHeadLockfile(content) {
178
+ const resolved = new Set();
179
+ const importers = [];
180
+ let section = null;
181
+ let sectionChildIndent = null;
182
+ let dependencyBlockIndent = null;
183
+ let declarationIndent = null;
184
+ let inDependencyBlock = false;
185
+ for (const line of content.split('\n')) {
186
+ const match = LOCKFILE_KEY_LINE_RE.exec(line);
187
+ if (match === null)
188
+ continue;
189
+ const indent = match[1].length;
190
+ const key = match[2] ?? match[3];
191
+ if (indent === 0) {
192
+ section = key;
193
+ sectionChildIndent = null;
194
+ dependencyBlockIndent = null;
195
+ declarationIndent = null;
196
+ inDependencyBlock = false;
197
+ continue;
198
+ }
199
+ if (section === null)
200
+ continue;
201
+ if (section === 'packages' || section === 'snapshots') {
202
+ sectionChildIndent ??= indent;
203
+ if (indent === sectionChildIndent)
204
+ resolved.add(packageNameFromKey(key));
205
+ continue;
206
+ }
207
+ if (section !== 'importers')
208
+ continue;
209
+ sectionChildIndent ??= indent;
210
+ if (indent === sectionChildIndent) {
211
+ importers.push(key);
212
+ dependencyBlockIndent = null;
213
+ declarationIndent = null;
214
+ inDependencyBlock = false;
215
+ continue;
216
+ }
217
+ dependencyBlockIndent ??= indent;
218
+ if (indent === dependencyBlockIndent) {
219
+ inDependencyBlock = MANIFEST_DEPENDENCY_BLOCKS.includes(key);
220
+ declarationIndent = null;
221
+ continue;
222
+ }
223
+ if (!inDependencyBlock)
224
+ continue;
225
+ declarationIndent ??= indent;
226
+ if (indent === declarationIndent)
227
+ resolved.add(packageNameFromKey(key));
228
+ }
229
+ return { resolved, importers };
230
+ }
231
+ /** The manifest an importer path owns (`.` is the repo root). */
232
+ function importerManifestPath(importer) {
233
+ return importer === '.' ? 'package.json' : `${importer}/package.json`;
234
+ }
235
+ /**
236
+ * Compile one pnpm workspace glob into a whole-string directory matcher.
237
+ *
238
+ * Deliberately minimal, and narrower than a full globbing library: every regex
239
+ * metacharacter is escaped first, then exactly two wildcards are re-expanded —
240
+ * `**` to `.*` (crosses path separators) and `*` to `[^/]*` (one segment). No
241
+ * brace expansion, no character classes, no `?`. A glob using those forms simply
242
+ * fails to match, which costs coverage on an exotic workspace layout; it never
243
+ * mints a false block, and it keeps a push gate free of a glob dependency.
244
+ */
245
+ function workspaceGlobToRegExp(glob) {
246
+ const escaped = glob.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
247
+ const pattern = escaped.replace(/\\\*\\\*|\\\*/g, (match) => match === '\\*\\*' ? '.*' : '[^/]*');
248
+ return new RegExp(`^${pattern}$`);
249
+ }
250
+ /**
251
+ * The `packages:` globs declared in pnpm-workspace.yaml, split into includes and
252
+ * `!`-negated excludes. A hand parse of one list, not a YAML implementation:
253
+ * anything that is not a plain sequence entry inside the `packages:` block is
254
+ * ignored.
255
+ */
256
+ function parseWorkspaceGlobs(content) {
257
+ const include = [];
258
+ const exclude = [];
259
+ let inPackagesBlock = false;
260
+ for (const line of content.split('\n')) {
261
+ if (/^packages:\s*$/.test(line)) {
262
+ inPackagesBlock = true;
263
+ continue;
264
+ }
265
+ if (!inPackagesBlock)
266
+ continue;
267
+ // A new top-level key closes the block; blank lines and comments do not.
268
+ if (WORKSPACE_TOP_LEVEL_KEY_RE.test(line))
269
+ break;
270
+ const match = WORKSPACE_PACKAGES_ENTRY_RE.exec(line);
271
+ if (match === null)
272
+ continue;
273
+ const raw = match[1] ?? match[2] ?? match[3] ?? '';
274
+ if (raw.length === 0)
275
+ continue;
276
+ if (raw.startsWith('!')) {
277
+ exclude.push(workspaceGlobToRegExp(raw.slice(1)));
278
+ }
279
+ else {
280
+ include.push(workspaceGlobToRegExp(raw));
281
+ }
282
+ }
283
+ return { include, exclude };
284
+ }
285
+ /**
286
+ * The workspace globs at HEAD, or `null` with a declared skip when they cannot
287
+ * be read or carry no usable `packages:` entry. `null` degrades admission to the
288
+ * importer set alone — the pre-existing, narrower behavior.
289
+ */
290
+ function readWorkspaceGlobs(safeExec, log, repoRoot) {
291
+ let globs;
292
+ try {
293
+ globs = parseWorkspaceGlobs(safeExec('git', ['show', `${HEAD_REF_PREFIX}${WORKSPACE_FILE_PATH}`], {
294
+ cwd: repoRoot,
295
+ timeout: AUX_LOOKUP_TIMEOUT_MS,
296
+ }));
297
+ // totem-context: declared-skip probe — a repo with no workspace file (or an unreadable one) simply has no glob admission, so the gate falls back to the importer set rather than guessing at workspace membership (mmnto/totem#1440 Tenet 4 init-class)
298
+ }
299
+ catch {
300
+ log.info(TAG, `Could not read ${WORKSPACE_FILE_PATH} at HEAD — admitting workspace importers only; a package.json this branch ADDS will not be checked for a lockfile companion.`);
301
+ return null;
302
+ }
303
+ if (globs.include.length === 0) {
304
+ log.info(TAG, `No usable \`packages:\` globs in ${WORKSPACE_FILE_PATH} at HEAD — admitting workspace importers only.`);
305
+ return null;
306
+ }
307
+ return globs;
308
+ }
309
+ /**
310
+ * The lockfile at HEAD, indexed — or `null` with a declared skip when it cannot
311
+ * be read. Both the resolves-at-HEAD test and the importer scope derive from it,
312
+ * so a failed read means neither question can be answered honestly.
313
+ */
314
+ function readHeadLockfileIndex(safeExec, log, repoRoot) {
315
+ try {
316
+ return indexHeadLockfile(safeExec('git', ['show', `${HEAD_REF_PREFIX}${LOCKFILE_PATH}`], {
317
+ cwd: repoRoot,
318
+ timeout: AUX_LOOKUP_TIMEOUT_MS,
319
+ }));
320
+ // totem-context: declared-skip probe — without the HEAD lockfile the gate cannot tell a dedupe from a full removal, nor a workspace manifest from a stray one, so it announces the skip and passes (mmnto/totem#1440 Tenet 4 init-class)
321
+ }
322
+ catch {
323
+ log.info(TAG, `Could not read ${LOCKFILE_PATH} at HEAD — skipping the workspace-scoped checks.`);
324
+ return null;
325
+ }
326
+ }
327
+ /**
328
+ * Every package name declared in an install-resolvable dependency block of a
329
+ * WORKSPACE IMPORTER manifest at HEAD.
330
+ *
331
+ * Scoped to importers deliberately. A tracked manifest that is NOT an importer —
332
+ * a separately-deployed service, a test fixture — declares pins this lockfile
333
+ * never resolves, so counting it converts a legitimate transitive-dependency
334
+ * drop into a hard block with an unusable remedy. Reproduced against the built
335
+ * CLI: a `@modelcontextprotocol/sdk` bump dropped transitive `hono`, which
336
+ * `services/compile-worker/package.json` declares, and the gate blocked the
337
+ * push. The importer set is the lockfile's own definition of the manifests it
338
+ * resolves, so it is the only sound scope for the question.
339
+ *
340
+ * `overrides` / `resolutions` are not counted: a name appearing only there
341
+ * constrains how some OTHER package's dependency resolves and is not itself a
342
+ * declaration that must resolve.
343
+ */
344
+ function collectImporterDeclarations(safeExec, log, repoRoot, importers) {
345
+ const declared = new Set();
346
+ const unreadable = [];
347
+ for (const importer of importers) {
348
+ const file = importerManifestPath(importer);
349
+ let manifest;
350
+ try {
351
+ manifest = JSON.parse(safeExec('git', ['show', `${HEAD_REF_PREFIX}${file}`], {
352
+ cwd: repoRoot,
353
+ timeout: AUX_LOOKUP_TIMEOUT_MS,
354
+ }));
355
+ // totem-context: per-manifest skip, DECLARED once below — an unreadable or unparseable importer manifest at HEAD cannot answer the membership question; the paths are collected and reported in a single log line rather than silently dropped or spammed per file (mmnto/totem#1440 Tenet 4 init-class)
356
+ }
357
+ catch {
358
+ unreadable.push(file);
359
+ continue;
360
+ }
361
+ if (typeof manifest !== 'object' || manifest === null) {
362
+ unreadable.push(file);
363
+ continue;
364
+ }
365
+ for (const block of MANIFEST_DEPENDENCY_BLOCKS) {
366
+ const deps = manifest[block];
367
+ if (typeof deps !== 'object' || deps === null)
368
+ continue;
369
+ for (const name of Object.keys(deps))
370
+ declared.add(name);
371
+ }
372
+ }
373
+ if (unreadable.length > 0) {
374
+ log.info(TAG, `Could not read ${unreadable.length} importer manifest(s) at HEAD (${unreadable.join(', ')}) — their declarations are not counted.`);
375
+ }
376
+ return declared;
377
+ }
378
+ /**
379
+ * Packages the diff range removes from the lockfile entirely while their pin
380
+ * stays declared by a workspace importer — the mmnto-ai/totem-strategy#630
381
+ * live-fire class, where a failed optional-dependency fetch drops every
382
+ * importer/packages/snapshots entry for a working dep and `pnpm install` still
383
+ * exits 0.
384
+ *
385
+ * Candidates are every name on a REMOVED key line, with no added-side
386
+ * subtraction: that subtraction was an optimization the corrected
387
+ * resolves-at-HEAD test already subsumes, and it was itself a laundering vector
388
+ * (an ADDED `peerDependenciesMeta` child naming the dropped package excluded it
389
+ * from the candidate set entirely). Over-generation stays safe because the
390
+ * decisive predicate is sound: a candidate fails only when it resolves NOWHERE
391
+ * at HEAD AND a workspace importer still declares it. Every git read is
392
+ * best-effort with a DECLARED skip — this feature has no silent skips.
393
+ *
394
+ * Candidate volume is deliberately UNBOUNDED. An earlier cap was costed against
395
+ * a per-candidate `git grep`; the decisive predicate is now an O(1) lookup
396
+ * against one lockfile index plus at most one manifest read per importer, so a
397
+ * cap would only buy false negatives — a real drop riding in behind an ordinary
398
+ * large update is exactly the shape this gate exists to catch.
399
+ */
400
+ function findRemovedPins(safeExec, log, repoRoot, resolvedRef) {
401
+ let lockfileDiff;
402
+ try {
403
+ lockfileDiff = safeExec('git', ['diff', `${resolvedRef}...HEAD`, '--', LOCKFILE_PATH], {
404
+ cwd: repoRoot,
405
+ timeout: AUX_LOOKUP_TIMEOUT_MS,
406
+ });
407
+ // totem-context: declared-skip probe — failure means the removed-pin check cannot evaluate, so it announces the skip and passes rather than blocking (mmnto/totem#1440 Tenet 4 init-class)
408
+ }
409
+ catch {
410
+ log.info(TAG, `Could not read the ${LOCKFILE_PATH} diff — skipping the removed-pin check.`);
411
+ return [];
412
+ }
413
+ const candidates = new Set();
414
+ for (const line of lockfileDiff.split('\n')) {
415
+ if (line[0] !== '-')
416
+ continue;
417
+ const name = lockfileKeyName(line.slice(1));
418
+ if (name !== null)
419
+ candidates.add(name);
420
+ }
421
+ if (candidates.size === 0)
422
+ return [];
423
+ const index = readHeadLockfileIndex(safeExec, log, repoRoot);
424
+ if (index === null)
425
+ return [];
426
+ const unresolved = [...candidates].filter((name) => !index.resolved.has(name));
427
+ if (unresolved.length === 0)
428
+ return [];
429
+ const declared = collectImporterDeclarations(safeExec, log, repoRoot, index.importers);
430
+ return unresolved.filter((name) => declared.has(name));
431
+ }
30
432
  // ─── Main command ───────────────────────────────────────
31
433
  /**
32
434
  * Programmatic surface — returns the verification result without exiting or
@@ -111,6 +513,18 @@ export async function verifyLockfileSyncCommand() {
111
513
  // alongside it. Most cohort-sync PRs and all Version Packages PRs land
112
514
  // here.
113
515
  if (files.includes(LOCKFILE_PATH)) {
516
+ // A present lockfile is not a synced lockfile: the diff can also REMOVE a
517
+ // package outright while package.json keeps its pin
518
+ // (mmnto-ai/totem-strategy#630). Checked before the pass so the fast-pass
519
+ // cannot launder that shape.
520
+ const removedPins = findRemovedPins(safeExec, log, repoRoot, resolvedRef);
521
+ if (removedPins.length > 0) {
522
+ return {
523
+ valid: false,
524
+ failureClass: 'removed-pin',
525
+ reason: `${REMOVED_PIN_REASON_PREFIX}: ${removedPins.join(', ')}. The diff range removes every lockfile entry for the package(s), so the declared dependency cannot resolve.`,
526
+ };
527
+ }
114
528
  const label = successColor(bold('PASS'));
115
529
  log.success(TAG, `${label} — ${LOCKFILE_PATH} present in diff range.`);
116
530
  return { valid: true };
@@ -120,12 +534,45 @@ export async function verifyLockfileSyncCommand() {
120
534
  if (pkgJsonPaths.length === 0) {
121
535
  return { valid: true };
122
536
  }
537
+ // Narrow to WORKSPACE IMPORTER manifests. A tracked manifest this lockfile
538
+ // does not resolve — a test fixture, a separately-deployed service — needs no
539
+ // lockfile companion when it gains a pin, so counting it hard-fails a correct
540
+ // push (reproduced against the built CLI). The importer set is the lockfile's
541
+ // own answer, so it is derived from the lockfile at HEAD here too.
542
+ const headIndex = readHeadLockfileIndex(safeExec, log, repoRoot);
543
+ if (headIndex === null) {
544
+ return { valid: true };
545
+ }
546
+ const importerManifests = new Set(headIndex.importers.map(importerManifestPath));
547
+ // A manifest this branch ADDS is not an importer at HEAD, so the importer set
548
+ // alone would let a new package ship pins with no lockfile companion. The
549
+ // workspace globs at HEAD close that hole; the root manifest is always in
550
+ // scope. (The removed-pin branch needs none of this: the lockfile is in the
551
+ // diff there, so its own importer list already includes any new package.)
552
+ const workspaceGlobs = readWorkspaceGlobs(safeExec, log, repoRoot);
553
+ const isWorkspaceManifest = (file) => {
554
+ if (file === 'package.json')
555
+ return true;
556
+ if (importerManifests.has(file))
557
+ return true;
558
+ if (workspaceGlobs === null)
559
+ return false;
560
+ const dir = file.slice(0, -'/package.json'.length);
561
+ if (!workspaceGlobs.include.some((re) => re.test(dir)))
562
+ return false;
563
+ return !workspaceGlobs.exclude.some((re) => re.test(dir));
564
+ };
565
+ const workspacePkgJsonPaths = pkgJsonPaths.filter(isWorkspaceManifest);
566
+ if (workspacePkgJsonPaths.length === 0) {
567
+ log.info(TAG, `Changed package.json file(s) are not workspace importers of ${LOCKFILE_PATH} — no lockfile companion is required.`);
568
+ return { valid: true };
569
+ }
123
570
  // Pull the unified diff for the package.json files and scan for
124
571
  // dependency-pin additions. `safeExec`'s arg-array form handles quoting,
125
572
  // so multiple paths pass safely with no shell metacharacter risk.
126
573
  let unifiedDiff = '';
127
574
  try {
128
- unifiedDiff = safeExec('git', ['diff', `${resolvedRef}...HEAD`, '--', ...pkgJsonPaths], {
575
+ unifiedDiff = safeExec('git', ['diff', `${resolvedRef}...HEAD`, '--', ...workspacePkgJsonPaths], {
129
576
  cwd: repoRoot,
130
577
  timeout: AUX_LOOKUP_TIMEOUT_MS,
131
578
  });
@@ -137,6 +584,7 @@ export async function verifyLockfileSyncCommand() {
137
584
  if (DEP_BUMP_RE.test(unifiedDiff)) {
138
585
  return {
139
586
  valid: false,
587
+ failureClass: 'missing-lockfile',
140
588
  reason: `Tracked lockfile detected, but ${LOCKFILE_PATH} is missing from the diff range while a package.json adds a dependency pin.`,
141
589
  };
142
590
  }
@@ -153,7 +601,14 @@ export async function verifyLockfileSyncCliCommand() {
153
601
  const { TotemError } = await import('@mmnto/totem');
154
602
  const result = await verifyLockfileSyncCommand();
155
603
  if (!result.valid) {
156
- throw new TotemError('CHECK_FAILED', result.reason, `Run \`pnpm install\` from the repo root to regenerate ${LOCKFILE_PATH}, then stage and commit it before re-pushing. CI runs with \`--frozen-lockfile\` and rejects pushes where a tracked package.json declares dependency pins that the lockfile does not reflect.`);
604
+ // Two failure classes, two remedies. The removed-pin class is NOT fixed by a
605
+ // plain `pnpm install` — that is precisely the command that produced it.
606
+ // Selected from the structured discriminant, never from the reason prose: a
607
+ // wording edit must not be able to downgrade a user's remedy.
608
+ const recoveryHint = result.failureClass === 'removed-pin'
609
+ ? `A failed optional-dependency fetch (an expired or missing registry token) silently removes every ${LOCKFILE_PATH} entry for a package while its pin stays declared in package.json — exit 0, no warning (mmnto-ai/totem-strategy#630 class). Verify registry auth with \`npm whoami\`, regenerate with \`pnpm update <pkg>\` (NOT \`pnpm install --lockfile-only\`, which false-reports "Already up to date" on an optional-dependency drop), then commit the regenerated ${LOCKFILE_PATH}.`
610
+ : `Run \`pnpm install\` from the repo root to regenerate ${LOCKFILE_PATH}, then stage and commit it before re-pushing. CI runs with \`--frozen-lockfile\` and rejects pushes where a tracked package.json declares dependency pins that the lockfile does not reflect.`;
611
+ throw new TotemError('CHECK_FAILED', result.reason, recoveryHint);
157
612
  }
158
613
  }
159
614
  //# sourceMappingURL=verify-lockfile-sync.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"verify-lockfile-sync.js","sourceRoot":"","sources":["../../src/commands/verify-lockfile-sync.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"verify-lockfile-sync.js","sourceRoot":"","sources":["../../src/commands/verify-lockfile-sync.ts"],"names":[],"mappings":"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"}