@mmnto/cli 1.122.0 → 1.124.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 (85) hide show
  1. package/dist/commands/config-drift.test.js +73 -1
  2. package/dist/commands/config-drift.test.js.map +1 -1
  3. package/dist/commands/extract-shared.d.ts.map +1 -1
  4. package/dist/commands/extract-shared.js +2 -6
  5. package/dist/commands/extract-shared.js.map +1 -1
  6. package/dist/commands/extract.test.js +19 -1
  7. package/dist/commands/extract.test.js.map +1 -1
  8. package/dist/commands/init-templates.d.ts +6 -6
  9. package/dist/commands/init-templates.d.ts.map +1 -1
  10. package/dist/commands/init-templates.js +8 -7
  11. package/dist/commands/init-templates.js.map +1 -1
  12. package/dist/commands/init.test.js +18 -5
  13. package/dist/commands/init.test.js.map +1 -1
  14. package/dist/commands/install-hooks.d.ts.map +1 -1
  15. package/dist/commands/install-hooks.js +58 -0
  16. package/dist/commands/install-hooks.js.map +1 -1
  17. package/dist/commands/install-hooks.test.js +460 -5
  18. package/dist/commands/install-hooks.test.js.map +1 -1
  19. package/dist/commands/legs.d.ts +259 -0
  20. package/dist/commands/legs.d.ts.map +1 -0
  21. package/dist/commands/legs.js +623 -0
  22. package/dist/commands/legs.js.map +1 -0
  23. package/dist/commands/legs.test.d.ts +20 -0
  24. package/dist/commands/legs.test.d.ts.map +1 -0
  25. package/dist/commands/legs.test.js +1004 -0
  26. package/dist/commands/legs.test.js.map +1 -0
  27. package/dist/commands/pre-push-gate-matrix.test.js +14 -0
  28. package/dist/commands/pre-push-gate-matrix.test.js.map +1 -1
  29. package/dist/commands/review-fan.d.ts +40 -1
  30. package/dist/commands/review-fan.d.ts.map +1 -1
  31. package/dist/commands/review-fan.js +108 -3
  32. package/dist/commands/review-fan.js.map +1 -1
  33. package/dist/commands/review-fan.test.js +444 -6
  34. package/dist/commands/review-fan.test.js.map +1 -1
  35. package/dist/commands/review-learn.d.ts +3 -0
  36. package/dist/commands/review-learn.d.ts.map +1 -1
  37. package/dist/commands/review-learn.js +4 -7
  38. package/dist/commands/review-learn.js.map +1 -1
  39. package/dist/commands/review-learn.test.js +19 -2
  40. package/dist/commands/review-learn.test.js.map +1 -1
  41. package/dist/commands/shield-covariate.test.js +19 -2
  42. package/dist/commands/shield-covariate.test.js.map +1 -1
  43. package/dist/commands/shield-learn.test.js +27 -5
  44. package/dist/commands/shield-learn.test.js.map +1 -1
  45. package/dist/commands/shield-nonreview.test.js +140 -1
  46. package/dist/commands/shield-nonreview.test.js.map +1 -1
  47. package/dist/commands/shield-retrieve.test.d.ts +2 -0
  48. package/dist/commands/shield-retrieve.test.d.ts.map +1 -0
  49. package/dist/commands/shield-retrieve.test.js +91 -0
  50. package/dist/commands/shield-retrieve.test.js.map +1 -0
  51. package/dist/commands/shield-templates.d.ts +7 -0
  52. package/dist/commands/shield-templates.d.ts.map +1 -1
  53. package/dist/commands/shield-templates.js +7 -0
  54. package/dist/commands/shield-templates.js.map +1 -1
  55. package/dist/commands/shield.d.ts +3 -1
  56. package/dist/commands/shield.d.ts.map +1 -1
  57. package/dist/commands/shield.js +70 -10
  58. package/dist/commands/shield.js.map +1 -1
  59. package/dist/commands/spec.d.ts +29 -4
  60. package/dist/commands/spec.d.ts.map +1 -1
  61. package/dist/commands/spec.js +51 -13
  62. package/dist/commands/spec.js.map +1 -1
  63. package/dist/commands/spec.test.js +221 -15
  64. package/dist/commands/spec.test.js.map +1 -1
  65. package/dist/commands/triage-retrieve.test.d.ts +2 -0
  66. package/dist/commands/triage-retrieve.test.d.ts.map +1 -0
  67. package/dist/commands/triage-retrieve.test.js +90 -0
  68. package/dist/commands/triage-retrieve.test.js.map +1 -0
  69. package/dist/commands/triage.d.ts +14 -1
  70. package/dist/commands/triage.d.ts.map +1 -1
  71. package/dist/commands/triage.js +21 -6
  72. package/dist/commands/triage.js.map +1 -1
  73. package/dist/git.d.ts +19 -0
  74. package/dist/git.d.ts.map +1 -1
  75. package/dist/git.js +13 -4
  76. package/dist/git.js.map +1 -1
  77. package/dist/index.js +40 -0
  78. package/dist/index.js.map +1 -1
  79. package/dist/utils.d.ts +5 -5
  80. package/dist/utils.d.ts.map +1 -1
  81. package/dist/utils.js +5 -6
  82. package/dist/utils.js.map +1 -1
  83. package/dist/utils.test.js +42 -48
  84. package/dist/utils.test.js.map +1 -1
  85. package/package.json +2 -2
@@ -0,0 +1,623 @@
1
+ /**
2
+ * `totem legs deposit` / `totem legs gate` — the two verbs over the
3
+ * leg-deposit store (mmnto-ai/totem#2698, ruled 2026-09-03;
4
+ * `doctrine/model-tiering.md` § Review legs).
5
+ *
6
+ * `deposit` is the ONLY writer: it resolves the head a falsification leg
7
+ * actually read, binds the leg's findings file to that sha, and hands the
8
+ * bytes to core's validate-on-write `saveLegDeposit`. `gate` is a READER — it
9
+ * never writes, never judges a finding's severity, and never decides policy:
10
+ * it answers one question for a push, *was this head read by a leg*, and says
11
+ * exactly how it derived the answer.
12
+ *
13
+ * Three properties of the gate are contract, not style:
14
+ *
15
+ * 1. **The tier changes only the exit code.** `--advisory` prints the
16
+ * BYTE-IDENTICAL lines of every state and exits 0; the strict caller is
17
+ * the pre-push hook, which maps 3 and 2 to a block. That is why the
18
+ * derivation returns its lines and BOTH codes, and the flag is applied at
19
+ * one place at the very end — a second formatting path per tier is how the
20
+ * advisory line and the blocking line drift apart.
21
+ * 2. **Not owed never consults the store.** The predicate is derived from the
22
+ * changed-file set alone; a repo whose diff matches no glob must not have
23
+ * its deposit directory read, so the "not owed" line is honest about
24
+ * having judged globs and nothing else.
25
+ * 3. **stdout is written SYNCHRONOUSLY before exit.** A piped write is
26
+ * asynchronous on macOS, so `process.stdout.write` followed by
27
+ * `process.exit` can truncate the very line the `sh` arm is about to echo
28
+ * — the `fs.writeSync(1, …)` precedent from the strict pre-commit reader.
29
+ *
30
+ * Everything the gate echoes is control-character sanitized. The deposit's own
31
+ * strings are already refused at the schema boundary (core `artifacts/legs.ts`),
32
+ * but paths, glob names and corrupt-file reasons come off a filesystem and a
33
+ * config file, so they are sanitized here too rather than trusted by provenance.
34
+ *
35
+ * Per the CLI command-module contract, every VALUE import is dynamic inside
36
+ * the command bodies (the core barrel pulls LanceDB into `--help` otherwise);
37
+ * `import type` is erased at build and stays static.
38
+ */
39
+ /** Log tag for this command pair's human output (`log.*` writes to stderr). */
40
+ const TAG = 'Legs';
41
+ /**
42
+ * How many `glob → file` basis pairs the BLOCKED line names before it
43
+ * collapses the rest into `+K more`. Sized like `MAX_DISCLOSED_FILTERED_FILES`
44
+ * in `git.ts`: enough to show the reason, bounded so one broad glob cannot
45
+ * flood a hook's output.
46
+ */
47
+ const MAX_DISCLOSED_BASIS_PAIRS = 5;
48
+ /**
49
+ * How many changed paths the gate's own scope line names before it collapses
50
+ * the rest into `+K more`. Higher than the basis cap because this line is the
51
+ * scope itself rather than a reason, but still bounded: an unbounded list is a
52
+ * screenful in a hook's output on a large branch, and the true count stays in
53
+ * the parentheses either way.
54
+ */
55
+ const MAX_DISCLOSED_CHANGED_FILES = 12;
56
+ /**
57
+ * List what a candidate could have READ: the paths its own branch diff added
58
+ * relative to `base` (three-dot).
59
+ *
60
+ * `-z` is load-bearing, not a style choice (mmnto-ai/totem#2698 fold 4). Under
61
+ * git's default `core.quotePath=true`, `--name-only` C-QUOTES any path with a
62
+ * non-ASCII byte, a quote or a backslash — `docs/caf\303\251.md` — while the
63
+ * owed set comes from `extractChangedFiles`, which is unquoted. The two sets
64
+ * then never intersect for such a path, and a covering ancestor is rejected
65
+ * with the false reason "predates every owed change". `-z` emits raw
66
+ * NUL-separated names and never quotes, so both sides speak one spelling.
67
+ *
68
+ * One helper, taking the runner: the gate shells out through `safeExec` and the
69
+ * covariate through its injected `GitExec`, and a second copy of this argv is
70
+ * exactly how one of them would drift back to the quoted form.
71
+ */
72
+ export function legReachPaths(run, base, head) {
73
+ const raw = run(['diff', '--name-only', '-z', `${base}...${head}`]);
74
+ // NUL-terminated, not NUL-separated: the payload ends with one, so the final
75
+ // split element is empty and is dropped along with any other empty.
76
+ return raw.split(LEG_PATH_SEPARATOR).filter((entry) => entry.length > 0);
77
+ }
78
+ /** The `-z` record separator, built rather than escaped (the banked decode trap). */
79
+ const LEG_PATH_SEPARATOR = String.fromCharCode(0);
80
+ /** The prefix `TotemError` stamps on every message — stripped when re-branding. */
81
+ const TOTEM_ERROR_BRAND = '[Totem Error] ';
82
+ /** Milliseconds in a day — the evidence line's age is reported in days. */
83
+ const MS_PER_DAY = 86_400_000;
84
+ /**
85
+ * Collapse every C0 (0-31) and DEL/C1 (127-159) code point to `?`.
86
+ *
87
+ * `sanitizeForTerminal` deliberately PRESERVES LF and HT — it defends a
88
+ * multi-line log payload — so it is not sufficient on its own for a value
89
+ * landing inside a single `[Totem] …` line that a shell arm echoes: one
90
+ * newline in a glob or a path would forge a second line and a reader could not
91
+ * tell the forged one from the gate's own. This is the strict-pre-commit
92
+ * reader's `safe()` rule (`install-hooks.ts`), applied AFTER the ANSI/CSI strip
93
+ * so both defenses hold: escapes removed, then every remaining control byte
94
+ * flattened. U+0085 (NEL) is inside the band because it breaks a line on some
95
+ * terminals.
96
+ *
97
+ * Written as a `charCodeAt` loop, not the equivalent regex class: the class
98
+ * would have to be authored with `\u`/`\x` escapes, and this repo has a banked
99
+ * incident where an editing tool decoded such an escape into a RAW control byte
100
+ * in the source (mmnto-ai/totem#2692 fold 3).
101
+ */
102
+ function safeLine(text) {
103
+ let out = '';
104
+ for (let i = 0; i < text.length; i++) {
105
+ const code = text.charCodeAt(i);
106
+ const control = code < 32 || (code >= 127 && code <= 159);
107
+ out = out + (control ? '?' : text.charAt(i));
108
+ }
109
+ return out;
110
+ }
111
+ /**
112
+ * The ONE spelling of "this value came from outside and is about to be echoed":
113
+ * strip ANSI/CSI escapes, then flatten every remaining control byte. Both verbs
114
+ * pass every filesystem-, config- and argv-sourced value through it
115
+ * (mmnto-ai/totem#2698 fold 2).
116
+ */
117
+ function echoSafe(value) {
118
+ return safeLine(sanitizeForTerminalSync(value));
119
+ }
120
+ /**
121
+ * `sanitizeForTerminal`, bound through a module-local slot so {@link echoSafe}
122
+ * stays synchronous inside message templates. Assigned from the same dynamic
123
+ * core import the rest of the module uses, before either verb echoes anything.
124
+ */
125
+ let sanitizeForTerminalSync = (value) => value;
126
+ /** Bind the core sanitizer for this process. Idempotent; called by both verbs. */
127
+ async function loadSanitizer() {
128
+ const { sanitizeForTerminal } = await import('@mmnto/totem');
129
+ sanitizeForTerminalSync = sanitizeForTerminal;
130
+ }
131
+ /** Render the four counts the way both verbs spell them. */
132
+ function renderCounts(counts) {
133
+ return `blocking=${counts.blocking} material=${counts.material} minor=${counts.minor} folded=${counts.folded}`;
134
+ }
135
+ /**
136
+ * Resolve `ref` to a full 40-hex COMMIT sha, refusing anything that is not a
137
+ * commit in this repo by name. `^{commit}` is the peel that makes a tag or a
138
+ * tree fail here rather than silently addressing the store under a non-commit
139
+ * object name.
140
+ */
141
+ async function resolveCommitSha(cwd, ref) {
142
+ const { safeExec, TotemError } = await import('@mmnto/totem');
143
+ await loadSanitizer();
144
+ const trimmed = ref.trim();
145
+ if (trimmed.length === 0 || trimmed.startsWith('-')) {
146
+ // Mirrors `getGitDiffRange`'s flag-injection guard: a ref starting with
147
+ // `-` reaches git as an option, not a revision.
148
+ throw new TotemError('GIT_FAILED', `Invalid --sha ${JSON.stringify(echoSafe(ref))}: a revision may not be empty or start with '-' (git-flag injection guard).`, 'Pass a plain revision such as HEAD or a commit sha.');
149
+ }
150
+ let out;
151
+ try {
152
+ out = safeExec('git', ['rev-parse', '--verify', `${trimmed}^{commit}`], { cwd });
153
+ }
154
+ catch (err) {
155
+ // git's own failure rides as the CAUSE (styleguide rule 9): the message
156
+ // names the ref the seat passed, and `--debug` can still reach what git
157
+ // actually said.
158
+ throw new TotemError('GIT_FAILED', `--sha ${echoSafe(trimmed)} does not name a commit in this repository.`, 'Pass a commit this checkout can resolve (e.g. HEAD), or fetch the missing history first.', err);
159
+ }
160
+ const sha = out.trim();
161
+ if (!/^[0-9a-f]{40}$/.test(sha)) {
162
+ throw new TotemError('GIT_FAILED', `--sha ${echoSafe(trimmed)} resolved to ${JSON.stringify(echoSafe(sha))}, which is not a 40-character commit sha.`, 'Pass a commit this checkout can resolve (e.g. HEAD).');
163
+ }
164
+ return sha;
165
+ }
166
+ /**
167
+ * `totem legs deposit --sha <ref> --from <file> [--replace] [--read-at <iso>]`
168
+ *
169
+ * The writer. Refuses, loudly and before touching the store, every way the
170
+ * deposit could name the wrong head: a `--sha` that is not a commit, a file
171
+ * whose own `diffSha` disagrees with it, and an occupied address without
172
+ * `--replace`. `readAt` is the leg's own instant — when the file carries none
173
+ * and none is passed, the stamp is `now` and that substitution is PRINTED,
174
+ * because a deposit's instant is what the resolver breaks ties on.
175
+ */
176
+ export async function legsDepositCommand(options) {
177
+ const fs = await import('node:fs');
178
+ const path = await import('node:path');
179
+ const { LEG_DEPOSIT_SCHEMA_VERSION, countLegFindings, saveLegDeposit, TotemError } = await import('@mmnto/totem');
180
+ const { log } = await import('../ui.js');
181
+ const { loadConfig, loadEnv, resolveConfigPath } = await import('../utils.js');
182
+ await loadSanitizer();
183
+ const cwd = process.cwd();
184
+ const configPath = resolveConfigPath(cwd);
185
+ loadEnv(cwd);
186
+ const config = await loadConfig(configPath);
187
+ const totemDirAbs = path.join(path.dirname(configPath), config.totemDir);
188
+ const diffSha = await resolveCommitSha(cwd, options.sha ?? 'HEAD');
189
+ const fromPath = path.resolve(cwd, options.from);
190
+ let raw;
191
+ try {
192
+ raw = JSON.parse(fs.readFileSync(fromPath, 'utf-8'));
193
+ }
194
+ catch (err) {
195
+ throw new TotemError('PARSE_FAILED', `Could not read the leg's findings at ${echoSafe(options.from)}.`, 'Pass --from <file> pointing at the leg deposit JSON the review leg returned.', err);
196
+ }
197
+ if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {
198
+ throw new TotemError('PARSE_FAILED', `The leg's findings at ${echoSafe(options.from)} are not a JSON object.`, 'The file must be a deposit object: { findings, folded, verdict, ... }.');
199
+ }
200
+ const fields = raw;
201
+ // The deposit must NAME the head it read: a file that carries its own
202
+ // `diffSha` and disagrees with `--sha` is a mismatch, never a rewrite.
203
+ const declaredSha = fields['diffSha'];
204
+ if (typeof declaredSha === 'string' && declaredSha !== diffSha) {
205
+ throw new TotemError('PARSE_FAILED', `The findings file names diffSha ${echoSafe(declaredSha)}, but --sha resolved to ${diffSha}.`, 'Deposit against the head the leg actually read, or correct the diffSha in the file.');
206
+ }
207
+ const fileReadAt = typeof fields['readAt'] === 'string' ? fields['readAt'] : undefined;
208
+ const readAt = options.readAt ?? fileReadAt ?? new Date().toISOString();
209
+ if (options.readAt === undefined && fileReadAt === undefined) {
210
+ log.warn(TAG, `readAt defaulted to ${echoSafe(readAt)} — pass --read-at for the leg's own instant`);
211
+ }
212
+ const schemaVersion = typeof fields['schemaVersion'] === 'string'
213
+ ? fields['schemaVersion']
214
+ : LEG_DEPOSIT_SCHEMA_VERSION;
215
+ // Assembled as `unknown` and handed to the validate-on-write path: the
216
+ // schema is the ONE validation boundary, so a malformed findings array
217
+ // surfaces with its Zod path instead of a hand-rolled second opinion.
218
+ const candidate = {
219
+ ...fields,
220
+ schemaVersion,
221
+ diffSha,
222
+ readAt,
223
+ };
224
+ let result;
225
+ try {
226
+ result = saveLegDeposit(totemDirAbs, candidate, { replace: options.replace === true });
227
+ }
228
+ catch (err) {
229
+ // A ZodError's own message is a JSON blob; re-state it as the path→message
230
+ // pairs the seat has to fix (the `loadConfig` idiom). Every other failure —
231
+ // including core's typed LegDepositExistsError, which already carries the
232
+ // incumbent's readAt and names --replace — propagates untouched.
233
+ if (err instanceof Error && err.name === 'ZodError' && 'issues' in err) {
234
+ const issues = err.issues
235
+ // Each issue's path and message are line-safed INDIVIDUALLY; the
236
+ // newline between entries is this code's own layout, not attacker
237
+ // input, so it survives (a whole-block flatten would destroy the list).
238
+ .map((issue) => ` ${echoSafe(issue.path.join('.') || '<root>')}: ${echoSafe(issue.message)}`)
239
+ .join('\n');
240
+ throw new TotemError('PARSE_FAILED', `The leg deposit built from ${echoSafe(options.from)} is not valid:\n${issues}`, 'Fix the fields listed above; every finding needs a unique id, and folded may only name finding ids.', err);
241
+ }
242
+ throw err;
243
+ }
244
+ if (result.replaced !== undefined) {
245
+ log.warn(TAG, `replaced the deposit read at ${echoSafe(result.replaced.readAt ?? 'an unreadable instant')} for ${diffSha}`);
246
+ }
247
+ log.success(TAG, `${echoSafe(result.path)} · ${renderCounts(countLegFindings(candidate))}`);
248
+ }
249
+ /**
250
+ * The coverage query for a set of owed paths, or `undefined` when it cannot be
251
+ * derived (no base). Exported because the covariate resolves through the SAME
252
+ * inputs as the gate — a field that named a deposit the gate rejects would be
253
+ * the round reading evidence the push gate does not accept.
254
+ *
255
+ * The basis lists one entry per `glob -> file` MATCH, so a file matching three
256
+ * globs appears three times; the owed set is those files, deduplicated in
257
+ * basis order.
258
+ */
259
+ export function legsCoverageForBasis(base, basis) {
260
+ if (base === undefined)
261
+ return undefined;
262
+ const owedFiles = [...new Set(basis.map((entry) => entry.file))];
263
+ return owedFiles.length === 0 ? undefined : { base, owedFiles };
264
+ }
265
+ /**
266
+ * Derive the gate's verdict and its lines.
267
+ *
268
+ * The tier is applied ONLY to `status`; `stdout` is produced once, so an
269
+ * advisory run and a strict run of the same state cannot print different text.
270
+ */
271
+ export async function runLegsGate(options, deps) {
272
+ const path = await import('node:path');
273
+ const { classifyLegsOwed, countLegFindings, findLegDepositForHead, sanitizeForTerminal } = await import('@mmnto/totem');
274
+ const advisory = options.advisory === true;
275
+ const finish = (derived, stdout, stderr) => ({
276
+ derived,
277
+ status: advisory ? 0 : derived,
278
+ stdout,
279
+ stderr,
280
+ });
281
+ // Two-stage, in this order: strip ANSI/CSI escapes, then flatten every
282
+ // remaining control byte. The second stage is what keeps a newline in a glob
283
+ // or a path from forging a second `[Totem]` line (mmnto-ai/totem#2698 fold 2).
284
+ const safe = (value) => safeLine(sanitizeForTerminal(value));
285
+ /** Repo-root-relative, forward-slashed — the address a reader can act on. */
286
+ const relative = (target) => safe(path.relative(deps.root, target).split(path.sep).join('/'));
287
+ let head;
288
+ let scope;
289
+ let resolution;
290
+ let owed;
291
+ try {
292
+ const { TotemError } = await import('@mmnto/totem');
293
+ head = deps.resolveHead();
294
+ scope = await deps.changedFiles();
295
+ owed = classifyLegsOwed(scope.files, deps.globs);
296
+ // The store is consulted ONLY when the diff is owed — a not-owed push must
297
+ // not depend on the deposit directory being readable at all.
298
+ if (owed.owed) {
299
+ // Coverage is not optional for the GATE (mmnto-ai/totem#2698 fold 3): it
300
+ // only ever runs on the branch scope, so a scope that resolved without a
301
+ // base is a failure to derive, not a licence to fall back to
302
+ // ancestry-only — that fallback is exactly the merge-base pass the
303
+ // ruling closed.
304
+ const query = legsCoverageForBasis(scope.base, owed.basis);
305
+ if (query === undefined) {
306
+ throw new TotemError('GIT_FAILED', 'the branch scope resolved without a base ref, so coverage is not derivable', 'Fetch the base branch (git fetch origin <base>) and retry.');
307
+ }
308
+ resolution = findLegDepositForHead(deps.totemDirAbs, head, deps.git, query);
309
+ }
310
+ // totem-context: intentional — this is not a swallow but the gate's LOUDEST arm: any failure to derive (no repo, an unresolvable head, a branch diff or an ancestry probe that will not resolve) becomes the NOT DERIVED verdict, printed with its cause and exit 2, which the strict pre-push arm blocks on with its own line (mmnto-ai/totem#2698)
311
+ }
312
+ catch (err) {
313
+ // `TotemError` brands its own message, and this line is already branded —
314
+ // `[Totem] legs: NOT DERIVED — [Totem Error] …` reads as two speakers. The
315
+ // gate owns the shape of its line, so the inner brand is stripped; the
316
+ // recovery hint stays on the error for any programmatic caller.
317
+ const raw = err instanceof Error ? err.message : String(err);
318
+ const cause = safe(raw.startsWith(TOTEM_ERROR_BRAND) ? raw.slice(TOTEM_ERROR_BRAND.length) : raw);
319
+ return finish(2, [`[Totem] legs: NOT DERIVED — ${cause}`], []);
320
+ }
321
+ const head8 = safe(head.slice(0, 8));
322
+ if (!owed.owed) {
323
+ return finish(0, [
324
+ `[Totem] legs: not owed — no changed path matched hooks.legsOwed.globs (${deps.globs.length} globs; head ${head8})`,
325
+ ], []);
326
+ }
327
+ // The corrupt rows are a SENSOR, not a verdict: they are disclosed on stderr
328
+ // whatever the outcome, and they never mask a valid sibling deposit.
329
+ const stderr = (resolution?.corrupt ?? []).map((entry) => `[Totem] legs: sensor — ignoring corrupt deposit ${safe(entry.file)}: ${safe(entry.reason)}`);
330
+ const winner = resolution?.winner;
331
+ if (winner !== undefined) {
332
+ const counts = countLegFindings(winner.deposit);
333
+ const stamp = Date.parse(winner.deposit.readAt);
334
+ const deltaMs = Number.isNaN(stamp) ? undefined : Date.now() - stamp;
335
+ const days = deltaMs === undefined ? undefined : Math.floor(deltaMs / MS_PER_DAY);
336
+ // A negative age is not an unknown age. A deposit stamped in the FUTURE —
337
+ // a skewed clock, a hand-edited instant — used to print `age unknown`,
338
+ // which reads as "unparseable" and hides the one thing worth acting on:
339
+ // this instant is wrong, and ranking breaks ties on it.
340
+ const age = days === undefined
341
+ ? 'age unknown'
342
+ : days >= 0
343
+ ? `${days} days old`
344
+ : // The MAGNITUDE is floored, not the signed value: `Math.floor` on a
345
+ // negative delta rounds AWAY from zero, so a stamp two days and a
346
+ // second ahead reported three.
347
+ `read ${Math.floor(Math.abs(deltaMs ?? 0) / MS_PER_DAY)} days in the FUTURE — check the clock or the deposit`;
348
+ const reach = winner.rank === 'exact'
349
+ ? 'exact'
350
+ : `nearest ancestor, +${winner.distance} commits since the leg read`;
351
+ // `covers K/N owed paths` is DISCLOSURE, never a block: a leg that read
352
+ // some of what this push owes is still a leg that read this head, and the
353
+ // re-arm is doctrine's call. The gate always supplies a coverage query, so
354
+ // the field is always present here; the guard exists because the core
355
+ // resolution is shared with the covariate, which may resolve without one.
356
+ const covers = winner.coverage === undefined
357
+ ? ''
358
+ : ` · covers ${winner.coverage.covered}/${winner.coverage.owed} owed paths`;
359
+ const stdout = [
360
+ `[Totem] legs evidence: ${relative(winner.path)} (read ${safe(winner.deposit.readAt)}, ${age}) · head ${head8} · ${reach}${covers} · blocking=${counts.blocking} material=${counts.material} folded=${counts.folded}`,
361
+ ];
362
+ const superseded = resolution?.superseded ?? [];
363
+ if (superseded.length > 0) {
364
+ const named = superseded
365
+ .map((candidate) => `${safe(candidate.diffSha.slice(0, 8))} (read ${safe(candidate.readAt)}, ${candidate.rank === 'exact' ? 'exact' : `ancestor +${candidate.distance}`})`)
366
+ .join(', ');
367
+ stdout.push(`[Totem] legs: ${superseded.length} superseded candidate(s) for this head: ${named}`);
368
+ }
369
+ return finish(0, stdout, stderr);
370
+ }
371
+ // Owed, and nothing answers for this head. The basis is what makes the block
372
+ // actionable — WHICH glob matched WHICH file — and every stale candidate is
373
+ // named with its own reason, because "not an ancestor" and "unknown to this
374
+ // repo" are different repairs.
375
+ const shown = owed.basis
376
+ .slice(0, MAX_DISCLOSED_BASIS_PAIRS)
377
+ .map((entry) => `${safe(entry.glob)} → ${safe(entry.file)}`)
378
+ .join(', ');
379
+ const more = owed.basis.length > MAX_DISCLOSED_BASIS_PAIRS
380
+ ? `, +${owed.basis.length - MAX_DISCLOSED_BASIS_PAIRS} more`
381
+ : '';
382
+ const stdout = [
383
+ `[Totem] BLOCKED: this push is legs-owed (${shown}${more}) and carries no fresh falsification-leg deposit for head ${head8}`,
384
+ ];
385
+ for (const candidate of resolution?.stale ?? []) {
386
+ // One reason per candidate, because the repairs differ: fetch the missing
387
+ // history, deposit against this branch, or run the leg over the owed diff.
388
+ // Exhaustive on purpose — a ternary chain's final arm silently ADOPTS any
389
+ // reason core adds later, printing the wrong repair for it.
390
+ const reason = (() => {
391
+ switch (candidate.reason) {
392
+ case 'not-ancestor':
393
+ return 'not an ancestor of head';
394
+ case 'unknown-commit':
395
+ return 'unknown to this repo';
396
+ case 'no-coverage':
397
+ return 'covers none of the owed paths (the deposit predates every owed change)';
398
+ default: {
399
+ const unreachable = candidate.reason;
400
+ return String(unreachable);
401
+ }
402
+ }
403
+ })();
404
+ stdout.push(`[Totem] legs: stale deposit ${safe(candidate.diffSha.slice(0, 8))}: ${reason}`);
405
+ }
406
+ stdout.push('[Totem] legs: run the leg, then: totem legs deposit --sha HEAD --from <findings.json>');
407
+ return finish(3, stdout, stderr);
408
+ }
409
+ /**
410
+ * Resolve the branch scope the floor is judged on — the ONE derivation the gate
411
+ * and the covariate both use (mmnto-ai/totem#2698 fold 3 item 3), so the
412
+ * covariate can never name a deposit the gate would reject.
413
+ *
414
+ * The push-gate scope (`--branch`): the branch-vs-base diff is what the leg
415
+ * read, and it is what the push actually proposes. An empty result is not owed
416
+ * — there is nothing for a leg to read.
417
+ *
418
+ * UNFILTERED, deliberately (mmnto-ai/totem#2698 fold 1). The same base/head
419
+ * resolution runs, but with an EMPTY ignore configuration, so neither
420
+ * `ignorePatterns` nor `shieldIgnorePatterns` can hide a path from the floor.
421
+ * Those keys carry INDEX-exclusion semantics that were merged into the
422
+ * review/lint diff filter for back-compat (mmnto-ai/totem#1746,
423
+ * mmnto-ai/totem#1748) — letting them narrow this predicate would mean a repo
424
+ * that excludes `README.md` from its index silently stops owing a leg for its
425
+ * public copy, which is the claim-without-mechanism shape the floor exists to
426
+ * close.
427
+ *
428
+ * The resolved BASE rides back with the files: coverage is measured against it,
429
+ * and it must be the same base HEAD was resolved against.
430
+ */
431
+ export async function resolveUnfilteredBranchScope(cwd, options = {}) {
432
+ const { safeExec } = await import('@mmnto/totem');
433
+ const { getDiffForReview } = await import('../git.js');
434
+ const { log } = await import('../ui.js');
435
+ await loadSanitizer();
436
+ const run = options.run ?? ((args) => safeExec('git', [...args], { cwd }));
437
+ const narrate = options.suppressScopeNarration !== true;
438
+ // The GATE narrates its scope; the covariate does not. Since fold 4 the leg
439
+ // field derives coverage from HEAD's branch scope on every review scope, so
440
+ // this resolution runs inside `totem review` runs too — and a `[Legs]` line
441
+ // in the middle of a `[Review]` run describes a probe nobody asked for.
442
+ // `getDiffForReview` still resolves the BASE (its origin-preference logic is
443
+ // the one this gate must agree with) and still rules on the empty-diff case,
444
+ // but its narration is ALWAYS suppressed: its `Changed files` line is built
445
+ // from `extractChangedFiles`, which spells a non-ASCII path the C-quoted way,
446
+ // and this module prints the RAW list below. Letting both speak printed the
447
+ // same line twice, in two different spellings (caught on this branch's own
448
+ // gate run, mmnto-ai/totem#2698 fold 5).
449
+ const result = await getDiffForReview({ branch: true, suppressScopeNarration: true }, { ignorePatterns: [], shieldIgnorePatterns: [] }, cwd, TAG);
450
+ const base = result.base;
451
+ // One disclosure, ours, carrying the resolved base so nothing the suppressed
452
+ // line said is lost.
453
+ if (narrate) {
454
+ log.info(TAG, safeLine(`Diff source: branch-vs-base (${base ?? 'no base resolved'}...HEAD, unfiltered — ignorePatterns do not apply to the floor)`));
455
+ }
456
+ // The FILE LIST is read separately, with `-z` (mmnto-ai/totem#2698 fold 5).
457
+ //
458
+ // Not a preference: `extractChangedFiles` parses `diff --git` headers, which
459
+ // git C-QUOTES for any path carrying a non-ASCII byte, a double quote or a
460
+ // backslash. The reach probe reads the same names raw. Fold 4 tried to
461
+ // reconcile them by DECODING the quoted side, which handled octal triples
462
+ // and nothing else — a name with a quote or a backslash still missed, and a
463
+ // literal `\123` inside a legal filename was rewritten to `S`. Reading the
464
+ // owed side through the SAME `-z` helper the reach uses makes both sides raw
465
+ // by construction, so there is nothing left to decode and no name a decoder
466
+ // could corrupt.
467
+ const files = 'empty' in result || base === undefined
468
+ ? // No base, or nothing changed: there is no `base...HEAD` to list, and
469
+ // an empty scope is not owed anyway.
470
+ []
471
+ : legReachPaths(run, base, 'HEAD');
472
+ // The gate's own disclosure, from the RAW list — so the names it prints are
473
+ // the names it judged, spelled as they are on disk.
474
+ if (narrate) {
475
+ const shownFiles = files.slice(0, MAX_DISCLOSED_CHANGED_FILES).map(safeLine);
476
+ const moreFiles = files.length > shownFiles.length ? `, +${files.length - shownFiles.length} more` : '';
477
+ // The count in the parentheses is the TRUE one — the cap shortens the list,
478
+ // never the number.
479
+ log.info(TAG, safeLine(`Changed files (${files.length}): ${shownFiles.join(', ')}${moreFiles}`));
480
+ }
481
+ return { files, ...(base === undefined ? {} : { base }) };
482
+ }
483
+ /**
484
+ * The judgment-dense floor this repo declares, or the default when it declares
485
+ * none — the ONE spelling, shared by the gate and both covariate sites.
486
+ */
487
+ export async function legsOwedGlobs(config) {
488
+ const { DEFAULT_LEGS_OWED_GLOBS } = await import('@mmnto/totem');
489
+ return config.hooks?.legsOwed?.globs ?? [...DEFAULT_LEGS_OWED_GLOBS];
490
+ }
491
+ /**
492
+ * Derive the coverage query for a COVARIATE site (mmnto-ai/totem#2698 fold 3,
493
+ * corrected in fold 4).
494
+ *
495
+ * The inputs come from HEAD's branch-vs-base scope ALWAYS — never from the
496
+ * scope the review itself ran on. The leg field answers "was THIS HEAD read",
497
+ * so what it owes is a property of HEAD, not of whether the operator happened
498
+ * to review a staged slice or a dirty tree. Deriving from the review's scope
499
+ * meant the default `uncommitted` scope resolved ancestry-only and NAMED the
500
+ * merge-base deposit the gate rejects — the field disagreeing with the gate,
501
+ * which is the one thing it must never do.
502
+ *
503
+ * Both covariate sites route through this one function, and it reuses the
504
+ * gate's own pieces — the unfiltered branch scope and core's single
505
+ * `classifyLegsOwed` — so the guarantee is unconditional: the field never names
506
+ * a deposit the gate would reject. When HEAD has no branch base the answer is
507
+ * `leg: none` plus one sensor, never a name resolved on ancestry alone.
508
+ */
509
+ export async function deriveLegsCoverageForHead(cwd, globs, options = {}) {
510
+ const { classifyLegsOwed } = await import('@mmnto/totem');
511
+ await loadSanitizer();
512
+ let scope;
513
+ try {
514
+ scope = await resolveUnfilteredBranchScope(cwd, options);
515
+ // totem-context: intentional — `--covariate` is a read-only sensor whose contract is to print a line and exit 0, so a branch scope that will not resolve (no repo, an unfetched base) yields the no-coverage answer with its reason printed, never a throw out of a transport verb
516
+ }
517
+ catch (err) {
518
+ return {
519
+ reason: `coverage was not derivable — HEAD has no branch base (${echoSafe(err instanceof Error ? err.message : String(err))})`,
520
+ };
521
+ }
522
+ const owed = classifyLegsOwed(scope.files, globs);
523
+ const query = legsCoverageForBasis(scope.base, owed.basis);
524
+ if (query !== undefined)
525
+ return { query };
526
+ // Two shapes reach here and they are NOT the same answer. No base: coverage
527
+ // is underivable, so no deposit can be credited. Nothing owed: HEAD owes no
528
+ // leg at all, so an empty query is vacuously satisfied and the field resolves
529
+ // on ancestry — the gate would not even consult the store for this head.
530
+ return scope.base === undefined
531
+ ? { reason: 'coverage was not derivable — HEAD has no branch base' }
532
+ : { query: { base: scope.base, owedFiles: [] } };
533
+ }
534
+ /**
535
+ * Build the gate's real-world seam from the repo's config and git.
536
+ *
537
+ * Exported so the UNFILTERED-diff contract below is testable against a real
538
+ * checkout without capturing a process exit: a test resolves these deps in a
539
+ * fixture repo and asserts what `changedFiles()` actually returns.
540
+ *
541
+ * It takes no options: since `--head` was removed (mmnto-ai/totem#2698 fold 2)
542
+ * nothing about the seam varies with a flag — `--advisory` is applied to the
543
+ * STATUS, after the derivation, and never to what is derived.
544
+ */
545
+ export async function buildLegsGateDeps() {
546
+ const path = await import('node:path');
547
+ const { safeExec, TotemError } = await import('@mmnto/totem');
548
+ // The branch scope (and its `Diff source:` disclosure) now lives in the
549
+ // shared `resolveUnfilteredBranchScope`, which the covariate calls too.
550
+ const { isAncestor } = await import('../git.js');
551
+ const { loadConfig, loadEnv, resolveConfigPath } = await import('../utils.js');
552
+ await loadSanitizer();
553
+ const cwd = process.cwd();
554
+ const configPath = resolveConfigPath(cwd);
555
+ loadEnv(cwd);
556
+ const config = await loadConfig(configPath);
557
+ const root = path.dirname(configPath);
558
+ const git = {
559
+ isCommit(sha) {
560
+ try {
561
+ safeExec('git', ['cat-file', '-e', `${sha}^{commit}`], { cwd });
562
+ return true;
563
+ // totem-context: intentional — "does this repo know that object" IS the boolean; git's failure text is not a second signal, and the caller reports the deposit as `unknown to this repo`
564
+ }
565
+ catch {
566
+ return false;
567
+ }
568
+ },
569
+ isAncestor(base, head) {
570
+ return isAncestor(cwd, base, head);
571
+ },
572
+ changedFiles: (base, head) => legReachPaths((args) => safeExec('git', [...args], { cwd }), base, head),
573
+ distance(base, head) {
574
+ const raw = safeExec('git', ['rev-list', '--count', `${base}..${head}`], { cwd }).trim();
575
+ const count = Number.parseInt(raw, 10);
576
+ if (Number.isNaN(count)) {
577
+ // Never guessed (mmnto-ai/totem#2698 fold 2, MINOR). The number is
578
+ // PRINTED as fact — `+N commits since the leg read` — so an
579
+ // unparseable answer is a failure to derive, not a zero: it throws,
580
+ // reaches the gate's NOT DERIVED arm, and the strict hook blocks on it.
581
+ // Guessing 0 would render a stale read as an exact one.
582
+ throw new TotemError('GIT_FAILED', `git rev-list --count ${base}..${head} returned ${JSON.stringify(echoSafe(raw))}, which is not a commit count.`, 'Fix the checkout (a corrupt or truncated object store) and retry.');
583
+ }
584
+ return count;
585
+ },
586
+ };
587
+ const deps = {
588
+ root,
589
+ totemDirAbs: path.join(root, config.totemDir),
590
+ globs: await legsOwedGlobs(config),
591
+ git,
592
+ resolveHead() {
593
+ return safeExec('git', ['rev-parse', '--verify', 'HEAD^{commit}'], { cwd }).trim();
594
+ },
595
+ changedFiles: () => resolveUnfilteredBranchScope(cwd, {
596
+ run: (args) => safeExec('git', [...args], { cwd }),
597
+ }),
598
+ };
599
+ return deps;
600
+ }
601
+ /**
602
+ * `totem legs gate [--advisory]`
603
+ *
604
+ * The reader the strict pre-push arm calls. Loads the repo's config, builds
605
+ * the real git and diff seams, derives, writes SYNCHRONOUSLY, exits with the
606
+ * tier-mapped status. `--advisory` maps every GATE state to 0; a failure
607
+ * before the derivation (config load, flag parse) still exits non-zero
608
+ * through the CLI's error boundary.
609
+ */
610
+ export async function legsGateCommand(options) {
611
+ const fs = await import('node:fs');
612
+ const deps = await buildLegsGateDeps();
613
+ const outcome = await runLegsGate(options, deps);
614
+ for (const line of outcome.stderr)
615
+ fs.writeSync(2, `${line}\n`);
616
+ // fs.writeSync, not console.log: stdout is a PIPE under the hook, and a
617
+ // piped write is asynchronous on macOS — process.exit could truncate the
618
+ // line the `sh` arm is about to echo.
619
+ for (const line of outcome.stdout)
620
+ fs.writeSync(1, `${line}\n`);
621
+ process.exit(outcome.status);
622
+ }
623
+ //# sourceMappingURL=legs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legs.js","sourceRoot":"","sources":["../../src/commands/legs.ts"],"names":[],"mappings":"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"}