@mmnto/cli 1.14.10 → 1.14.12

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 (62) hide show
  1. package/dist/commands/compile-export-archive-filter.test.d.ts +2 -0
  2. package/dist/commands/compile-export-archive-filter.test.d.ts.map +1 -0
  3. package/dist/commands/compile-export-archive-filter.test.js +119 -0
  4. package/dist/commands/compile-export-archive-filter.test.js.map +1 -0
  5. package/dist/commands/compile-prune.test.js +35 -18
  6. package/dist/commands/compile-prune.test.js.map +1 -1
  7. package/dist/commands/compile-verbose-trace.test.d.ts +2 -0
  8. package/dist/commands/compile-verbose-trace.test.d.ts.map +1 -0
  9. package/dist/commands/compile-verbose-trace.test.js +128 -0
  10. package/dist/commands/compile-verbose-trace.test.js.map +1 -0
  11. package/dist/commands/compile.d.ts +33 -8
  12. package/dist/commands/compile.d.ts.map +1 -1
  13. package/dist/commands/compile.js +148 -13
  14. package/dist/commands/compile.js.map +1 -1
  15. package/dist/commands/docs.test.js +1 -0
  16. package/dist/commands/docs.test.js.map +1 -1
  17. package/dist/commands/doctor.d.ts +44 -0
  18. package/dist/commands/doctor.d.ts.map +1 -1
  19. package/dist/commands/doctor.js +147 -0
  20. package/dist/commands/doctor.js.map +1 -1
  21. package/dist/commands/doctor.test.js +342 -2
  22. package/dist/commands/doctor.test.js.map +1 -1
  23. package/dist/commands/install.d.ts +82 -0
  24. package/dist/commands/install.d.ts.map +1 -0
  25. package/dist/commands/install.js +440 -0
  26. package/dist/commands/install.js.map +1 -0
  27. package/dist/commands/install.test.d.ts +2 -0
  28. package/dist/commands/install.test.d.ts.map +1 -0
  29. package/dist/commands/install.test.js +196 -0
  30. package/dist/commands/install.test.js.map +1 -0
  31. package/dist/commands/pre-compact-hook.test.d.ts +10 -0
  32. package/dist/commands/pre-compact-hook.test.d.ts.map +1 -0
  33. package/dist/commands/pre-compact-hook.test.js +131 -0
  34. package/dist/commands/pre-compact-hook.test.js.map +1 -0
  35. package/dist/commands/run-compiled-rules.d.ts.map +1 -1
  36. package/dist/commands/run-compiled-rules.js +17 -2
  37. package/dist/commands/run-compiled-rules.js.map +1 -1
  38. package/dist/commands/run-compiled-rules.test.js +65 -0
  39. package/dist/commands/run-compiled-rules.test.js.map +1 -1
  40. package/dist/commands/shield-learn.test.js +1 -0
  41. package/dist/commands/shield-learn.test.js.map +1 -1
  42. package/dist/commands/shield.content-hash-parity.test.d.ts +2 -0
  43. package/dist/commands/shield.content-hash-parity.test.d.ts.map +1 -0
  44. package/dist/commands/shield.content-hash-parity.test.js +155 -0
  45. package/dist/commands/shield.content-hash-parity.test.js.map +1 -0
  46. package/dist/commands/shield.d.ts +8 -1
  47. package/dist/commands/shield.d.ts.map +1 -1
  48. package/dist/commands/shield.js +59 -9
  49. package/dist/commands/shield.js.map +1 -1
  50. package/dist/commands/sync.d.ts +7 -0
  51. package/dist/commands/sync.d.ts.map +1 -1
  52. package/dist/commands/sync.js +39 -3
  53. package/dist/commands/sync.js.map +1 -1
  54. package/dist/commands/sync.test.js +131 -9
  55. package/dist/commands/sync.test.js.map +1 -1
  56. package/dist/index.js +13 -0
  57. package/dist/index.js.map +1 -1
  58. package/dist/utils/pilot.test.js +1 -0
  59. package/dist/utils/pilot.test.js.map +1 -1
  60. package/dist/utils.test.js +1 -0
  61. package/dist/utils.test.js.map +1 -1
  62. package/package.json +2 -2
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=compile-export-archive-filter.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile-export-archive-filter.test.d.ts","sourceRoot":"","sources":["../../src/commands/compile-export-archive-filter.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,119 @@
1
+ import * as fs from 'node:fs';
2
+ import * as os from 'node:os';
3
+ import * as path from 'node:path';
4
+ import { afterEach, beforeEach, describe, expect, it } from 'vitest';
5
+ import { generateInputHash, hashLesson } from '@mmnto/totem';
6
+ import { cleanTmpDir } from '../test-utils.js';
7
+ import { compileCommand } from './compile.js';
8
+ // ─── Helpers ─────────────────────────────────────────
9
+ //
10
+ // These tests exercise the export path's archive filter. The fix ensures
11
+ // `totem lesson compile --export` does not emit lessons whose compiled
12
+ // rule is marked `status: archived`, closing the symmetric counterpart of
13
+ // the mmnto-ai/totem#1345 lint-path filter in loadCompiledRules.
14
+ function makeTmpDir() {
15
+ return fs.mkdtempSync(path.join(os.tmpdir(), 'totem-export-archive-'));
16
+ }
17
+ function lessonMarkdown(heading, body) {
18
+ return `## Lesson — ${heading}\n\n**Tags:** test\n\n${body}\n`;
19
+ }
20
+ function setupWorkspace(tmpDir, lessons, rules, exportTargetPath) {
21
+ fs.writeFileSync(path.join(tmpDir, 'totem.config.ts'), [
22
+ 'export default {',
23
+ ' targets: [{ glob: "**/*.ts", type: "code", strategy: "typescript-ast" }],',
24
+ ' totemDir: ".totem",',
25
+ ' orchestrator: {',
26
+ ' provider: "shell",',
27
+ ' command: "echo should-never-run",',
28
+ ' defaultModel: "test-model",',
29
+ ' },',
30
+ ` exports: { copilot: ${JSON.stringify(exportTargetPath)} },`,
31
+ '};',
32
+ '',
33
+ ].join('\n'), 'utf-8');
34
+ const totemDir = path.join(tmpDir, '.totem');
35
+ const lessonsDir = path.join(totemDir, 'lessons');
36
+ fs.mkdirSync(lessonsDir, { recursive: true });
37
+ for (const [name, body] of Object.entries(lessons)) {
38
+ fs.writeFileSync(path.join(lessonsDir, name), body, 'utf-8');
39
+ }
40
+ const rulesPath = path.join(totemDir, 'compiled-rules.json');
41
+ const now = '2026-04-16T00:00:00Z';
42
+ fs.writeFileSync(rulesPath, JSON.stringify({
43
+ version: 1,
44
+ rules: rules.map((r) => ({
45
+ lessonHash: r.lessonHash,
46
+ lessonHeading: r.lessonHeading,
47
+ pattern: 'dummy-never-matches',
48
+ message: r.lessonHeading,
49
+ engine: 'regex',
50
+ compiledAt: now,
51
+ ...(r.archived
52
+ ? { status: 'archived', archivedReason: 'over-broad in test' }
53
+ : {}),
54
+ })),
55
+ nonCompilable: [],
56
+ }, null, 2) + '\n', 'utf-8');
57
+ const manifestPath = path.join(totemDir, 'compile-manifest.json');
58
+ fs.writeFileSync(manifestPath, JSON.stringify({
59
+ compiled_at: now,
60
+ model: 'test-model',
61
+ input_hash: generateInputHash(lessonsDir),
62
+ output_hash: '0000000000000000000000000000000000000000000000000000000000000000',
63
+ rule_count: rules.length,
64
+ }, null, 2) + '\n', 'utf-8');
65
+ }
66
+ describe('compileCommand --export archive filter', () => {
67
+ let tmpDir;
68
+ let originalCwd;
69
+ beforeEach(() => {
70
+ tmpDir = makeTmpDir();
71
+ originalCwd = process.cwd();
72
+ process.chdir(tmpDir);
73
+ });
74
+ afterEach(() => {
75
+ process.chdir(originalCwd);
76
+ cleanTmpDir(tmpDir);
77
+ });
78
+ it('excludes lessons whose compiled rule is archived from the export', async () => {
79
+ const liveHeading = 'Keep this guidance';
80
+ const liveBody = 'Good advice that should always ship.';
81
+ const archivedHeading = 'Suppress this guidance';
82
+ const archivedBody = 'Over-broad pattern; archived post-compile.';
83
+ setupWorkspace(tmpDir, {
84
+ 'live.md': lessonMarkdown(liveHeading, liveBody),
85
+ 'archived.md': lessonMarkdown(archivedHeading, archivedBody),
86
+ }, [
87
+ { lessonHash: hashLesson(liveHeading, liveBody), lessonHeading: liveHeading },
88
+ {
89
+ lessonHash: hashLesson(archivedHeading, archivedBody),
90
+ lessonHeading: archivedHeading,
91
+ archived: true,
92
+ },
93
+ ], 'copilot-instructions.md');
94
+ await compileCommand({ export: true });
95
+ const exportPath = path.join(tmpDir, 'copilot-instructions.md');
96
+ const exported = fs.readFileSync(exportPath, 'utf-8');
97
+ expect(exported).toContain(liveHeading);
98
+ expect(exported).not.toContain(archivedHeading);
99
+ });
100
+ it('passes all lessons through when no rules are archived (no-op filter)', async () => {
101
+ const h1 = 'First guidance';
102
+ const b1 = 'Body one.';
103
+ const h2 = 'Second guidance';
104
+ const b2 = 'Body two.';
105
+ setupWorkspace(tmpDir, {
106
+ 'a.md': lessonMarkdown(h1, b1),
107
+ 'b.md': lessonMarkdown(h2, b2),
108
+ }, [
109
+ { lessonHash: hashLesson(h1, b1), lessonHeading: h1 },
110
+ { lessonHash: hashLesson(h2, b2), lessonHeading: h2 },
111
+ ], 'copilot-instructions.md');
112
+ await compileCommand({ export: true });
113
+ const exportPath = path.join(tmpDir, 'copilot-instructions.md');
114
+ const exported = fs.readFileSync(exportPath, 'utf-8');
115
+ expect(exported).toContain(h1);
116
+ expect(exported).toContain(h2);
117
+ });
118
+ });
119
+ //# sourceMappingURL=compile-export-archive-filter.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile-export-archive-filter.test.js","sourceRoot":"","sources":["../../src/commands/compile-export-archive-filter.test.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,9 @@
1
1
  import { describe, expect, it } from 'vitest';
2
2
  import { pruneStaleNonCompilable, pruneStaleRules } from './compile.js';
3
+ // ─── 4-tuple helpers (mmnto-ai/totem#1481) ───────────
4
+ function entry(title, reasonCode = 'out-of-scope', reason) {
5
+ return reason === undefined ? { title, reasonCode } : { title, reasonCode, reason };
6
+ }
3
7
  // ─── Test helpers ────────────────────────────────────
4
8
  function makeRule(lessonHash, heading = `Heading for ${lessonHash}`) {
5
9
  return {
@@ -19,51 +23,64 @@ describe('pruneStaleNonCompilable', () => {
19
23
  });
20
24
  it('returns all entries when every hash is still current', () => {
21
25
  const map = new Map([
22
- ['abc', 'First lesson'],
23
- ['def', 'Second lesson'],
26
+ ['abc', entry('First lesson')],
27
+ ['def', entry('Second lesson', 'missing-badexample')],
24
28
  ]);
25
29
  const current = new Set(['abc', 'def']);
26
30
  const result = pruneStaleNonCompilable(map, current);
27
31
  expect(result.fresh).toEqual([
28
- { hash: 'abc', title: 'First lesson' },
29
- { hash: 'def', title: 'Second lesson' },
32
+ { hash: 'abc', title: 'First lesson', reasonCode: 'out-of-scope' },
33
+ { hash: 'def', title: 'Second lesson', reasonCode: 'missing-badexample' },
30
34
  ]);
31
35
  expect(result.drained).toBe(0);
32
36
  });
33
37
  it('drops entries whose hashes are no longer present in current lessons', () => {
34
38
  const map = new Map([
35
- ['abc', 'Kept lesson'],
36
- ['stale1', 'Removed lesson A'],
37
- ['stale2', 'Removed lesson B'],
39
+ ['abc', entry('Kept lesson')],
40
+ ['stale1', entry('Removed lesson A')],
41
+ ['stale2', entry('Removed lesson B')],
38
42
  ]);
39
43
  const current = new Set(['abc']);
40
44
  const result = pruneStaleNonCompilable(map, current);
41
- expect(result.fresh).toEqual([{ hash: 'abc', title: 'Kept lesson' }]);
45
+ expect(result.fresh).toEqual([
46
+ { hash: 'abc', title: 'Kept lesson', reasonCode: 'out-of-scope' },
47
+ ]);
42
48
  expect(result.drained).toBe(2);
43
49
  });
44
50
  it('drains everything when no hashes are current', () => {
45
51
  const map = new Map([
46
- ['stale1', 'Removed A'],
47
- ['stale2', 'Removed B'],
52
+ ['stale1', entry('Removed A')],
53
+ ['stale2', entry('Removed B')],
48
54
  ]);
49
55
  const current = new Set();
50
56
  const result = pruneStaleNonCompilable(map, current);
51
57
  expect(result.fresh).toEqual([]);
52
58
  expect(result.drained).toBe(2);
53
59
  });
54
- it('preserves tuple shape including titles from legacy-normalized entries', () => {
55
- // Legacy string-form entries get normalized to {hash, title: '(legacy entry)'}
56
- // by the schema transform. The prune helper must preserve that title verbatim.
57
- const map = new Map([['legacy-hash', '(legacy entry)']]);
58
- const current = new Set(['legacy-hash']);
60
+ it('preserves reasonCode and reason fields through the prune', () => {
61
+ // mmnto-ai/totem#1481 invariant #8: the 4-tuple must survive the prune
62
+ // intact, not collapse back to a 2-tuple.
63
+ const map = new Map([
64
+ ['hash-a', entry('Legacy entry', 'legacy-unknown')],
65
+ ['hash-b', entry('Modern entry', 'out-of-scope', 'Architectural principle.')],
66
+ ]);
67
+ const current = new Set(['hash-a', 'hash-b']);
59
68
  const result = pruneStaleNonCompilable(map, current);
60
- expect(result.fresh).toEqual([{ hash: 'legacy-hash', title: '(legacy entry)' }]);
69
+ expect(result.fresh).toEqual([
70
+ { hash: 'hash-a', title: 'Legacy entry', reasonCode: 'legacy-unknown' },
71
+ {
72
+ hash: 'hash-b',
73
+ title: 'Modern entry',
74
+ reasonCode: 'out-of-scope',
75
+ reason: 'Architectural principle.',
76
+ },
77
+ ]);
61
78
  expect(result.drained).toBe(0);
62
79
  });
63
80
  it('does not mutate the input map', () => {
64
81
  const map = new Map([
65
- ['abc', 'Kept'],
66
- ['stale', 'Removed'],
82
+ ['abc', entry('Kept')],
83
+ ['stale', entry('Removed')],
67
84
  ]);
68
85
  const current = new Set(['abc']);
69
86
  pruneStaleNonCompilable(map, current);
@@ -1 +1 @@
1
- {"version":3,"file":"compile-prune.test.js","sourceRoot":"","sources":["../../src/commands/compile-prune.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"compile-prune.test.js","sourceRoot":"","sources":["../../src/commands/compile-prune.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=compile-verbose-trace.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile-verbose-trace.test.d.ts","sourceRoot":"","sources":["../../src/commands/compile-verbose-trace.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,128 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { formatVerboseTraceBlock } from './compile.js';
3
+ // ─── Format verbose trace block (mmnto-ai/totem#1482) ──
4
+ describe('formatVerboseTraceBlock', () => {
5
+ const lesson = { heading: 'No console.log in production', hash: 'abc12345def67890' };
6
+ it('renders a pipeline 1 single-result trace as a header plus result line', () => {
7
+ const trace = [{ layer: 1, action: 'result', outcome: 'compiled' }];
8
+ const block = formatVerboseTraceBlock(lesson, 'compiled', undefined, trace);
9
+ const lines = block.split('\n');
10
+ expect(lines[0]).toBe('lesson-abc12345 "No console.log in production":');
11
+ expect(lines[1]).toBe(' result: compiled');
12
+ expect(lines).toHaveLength(2);
13
+ });
14
+ it('renders a pipeline 2 first-try success with generate + verify + result', () => {
15
+ const trace = [
16
+ { layer: 3, action: 'generate', outcome: 'attempt-1', patternHash: 'deadbeefcafebabe' },
17
+ { layer: 3, action: 'verify', outcome: 'MATCH' },
18
+ { layer: 3, action: 'result', outcome: 'compiled' },
19
+ ];
20
+ const block = formatVerboseTraceBlock(lesson, 'compiled', undefined, trace);
21
+ expect(block).toContain('lesson-abc12345');
22
+ expect(block).toContain('Layer 3 (Pipeline 3 (LLM + verify-retry)) -> attempt-1 (patternHash=deadbeefcafebabe)');
23
+ expect(block).toContain('verify on example: MATCH');
24
+ expect(block).toContain('result: compiled');
25
+ });
26
+ it('renders a verify-retry-exhausted trace with retry counters and reasonCode', () => {
27
+ const trace = [
28
+ { layer: 3, action: 'generate', outcome: 'attempt-1', patternHash: 'a'.repeat(16) },
29
+ { layer: 3, action: 'verify', outcome: 'example-hit-miss' },
30
+ { layer: 3, action: 'retry', outcome: 'attempt-2-scheduled' },
31
+ { layer: 3, action: 'generate', outcome: 'attempt-2', patternHash: 'b'.repeat(16) },
32
+ { layer: 3, action: 'verify', outcome: 'example-hit-miss' },
33
+ { layer: 3, action: 'retry', outcome: 'attempt-3-scheduled' },
34
+ { layer: 3, action: 'generate', outcome: 'attempt-3', patternHash: 'c'.repeat(16) },
35
+ { layer: 3, action: 'verify', outcome: 'example-hit-miss' },
36
+ {
37
+ layer: 3,
38
+ action: 'result',
39
+ outcome: 'skipped',
40
+ reasonCode: 'verify-retry-exhausted',
41
+ },
42
+ ];
43
+ const block = formatVerboseTraceBlock(lesson, 'skipped', 'verify-retry-exhausted', trace);
44
+ expect(block).toContain('retry 1: attempt-2-scheduled');
45
+ expect(block).toContain('retry 2: attempt-3-scheduled');
46
+ expect(block).toContain('result: skipped (verify-retry-exhausted)');
47
+ // Exactly three generate lines (one per attempt)
48
+ const genCount = (block.match(/Layer 3 \(Pipeline 3 \(LLM \+ verify-retry\)\) -> attempt-/g) ?? []).length;
49
+ expect(genCount).toBe(3);
50
+ });
51
+ it('renders pipeline 3 (layer 2) with the correct pipeline label', () => {
52
+ const trace = [
53
+ { layer: 2, action: 'generate', outcome: 'produced', patternHash: '0'.repeat(16) },
54
+ { layer: 2, action: 'verify', outcome: 'passed' },
55
+ { layer: 2, action: 'result', outcome: 'compiled' },
56
+ ];
57
+ const block = formatVerboseTraceBlock(lesson, 'compiled', undefined, trace);
58
+ expect(block).toContain('Layer 2 (Pipeline 2 (example-based)) -> produced');
59
+ });
60
+ it('falls back gracefully when trace is undefined or empty', () => {
61
+ const undefinedBlock = formatVerboseTraceBlock(lesson, 'failed', undefined, undefined);
62
+ expect(undefinedBlock).toContain('(no trace events recorded)');
63
+ expect(undefinedBlock).toContain('result: failed');
64
+ const emptyBlock = formatVerboseTraceBlock(lesson, 'noop', undefined, []);
65
+ expect(emptyBlock).toContain('(no trace events recorded)');
66
+ });
67
+ it('emits a single contiguous multi-line string (no intermediate newlines before content)', () => {
68
+ // Invariant: the caller writes this block via one process.stdout.write
69
+ // call, so the block must already contain its internal newlines and
70
+ // must not start or end with bare whitespace that would collide with
71
+ // the trailing \n the caller appends.
72
+ const trace = [{ layer: 1, action: 'result', outcome: 'compiled' }];
73
+ const block = formatVerboseTraceBlock(lesson, 'compiled', undefined, trace);
74
+ expect(block.startsWith('lesson-')).toBe(true);
75
+ expect(block.endsWith('\n')).toBe(false);
76
+ });
77
+ it('renders a skipped lesson with reasonCode from the terminal event', () => {
78
+ const trace = [
79
+ {
80
+ layer: 3,
81
+ action: 'result',
82
+ outcome: 'skipped',
83
+ reasonCode: 'out-of-scope',
84
+ },
85
+ ];
86
+ const block = formatVerboseTraceBlock(lesson, 'skipped', 'out-of-scope', trace);
87
+ expect(block).toContain('result: skipped (out-of-scope)');
88
+ });
89
+ it('tolerates unknown layer numbers via the fallback label', () => {
90
+ const trace = [
91
+ {
92
+ layer: 99,
93
+ action: 'generate',
94
+ outcome: 'produced',
95
+ },
96
+ {
97
+ layer: 99,
98
+ action: 'result',
99
+ outcome: 'compiled',
100
+ },
101
+ ];
102
+ const block = formatVerboseTraceBlock(lesson, 'compiled', undefined, trace);
103
+ expect(block).toContain('Layer 99');
104
+ });
105
+ });
106
+ // ─── Atomic stdout.write invocation ──────────────────
107
+ describe('verbose trace atomic emission', () => {
108
+ it('guarantees the trace block formats as a single string the caller can ship via one stdout.write call', () => {
109
+ // The compile command invokes process.stdout.write(block + '\n') once
110
+ // per lesson so concurrent lessons cannot interleave inside the block.
111
+ // That invariant reduces to: formatVerboseTraceBlock returns a single
112
+ // string. The test below pins the shape so a refactor that splits the
113
+ // render across multiple returns fails loudly.
114
+ const lesson = { heading: 'Atomic test lesson', hash: 'aaaa1111bbbb2222' };
115
+ const trace = [
116
+ { layer: 3, action: 'generate', outcome: 'attempt-1', patternHash: 'f'.repeat(16) },
117
+ { layer: 3, action: 'verify', outcome: 'MATCH' },
118
+ { layer: 3, action: 'result', outcome: 'compiled' },
119
+ ];
120
+ const out = formatVerboseTraceBlock(lesson, 'compiled', undefined, trace);
121
+ expect(typeof out).toBe('string');
122
+ // Block must contain every event's outcome; no event gets dropped.
123
+ for (const ev of trace) {
124
+ expect(out).toContain(ev.outcome);
125
+ }
126
+ });
127
+ });
128
+ //# sourceMappingURL=compile-verbose-trace.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile-verbose-trace.test.js","sourceRoot":"","sources":["../../src/commands/compile-verbose-trace.test.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { CompiledRule, LessonInput } from '@mmnto/totem';
1
+ import type { CompiledRule, LayerTraceEvent, LessonInput, NonCompilableEntry, NonCompilableReasonCode } from '@mmnto/totem';
2
2
  /**
3
3
  * Terminal outcome of a `--upgrade <hash>` run, returned by `compileCommand`
4
4
  * so callers (like `totem doctor --pr` self-healing) can distinguish an actual
@@ -69,16 +69,18 @@ export declare function buildTelemetryPrefix(contextCounts: {
69
69
  unknown: number;
70
70
  }): string;
71
71
  /**
72
- * Non-compilable entry as it lives on disk after the schema transform in
73
- * `@mmnto/totem` normalizes legacy `string[]` entries to `{hash, title}` tuples.
72
+ * Value side of the in-memory `nonCompilableMap`. Carries the title plus the
73
+ * machine-readable reasonCode (mmnto-ai/totem#1481) so prune / serialize
74
+ * steps round-trip the full 4-tuple without a lookup.
74
75
  */
75
- export interface NonCompilableTuple {
76
- hash: string;
76
+ export interface NonCompilableMapValue {
77
77
  title: string;
78
+ reasonCode: NonCompilableReasonCode;
79
+ reason?: string;
78
80
  }
79
81
  /**
80
82
  * Filter stale entries from a non-compilable map against the current set of
81
- * lesson hashes. Returns the fresh tuple-form list and a count of how many
83
+ * lesson hashes. Returns the fresh 4-tuple list and a count of how many
82
84
  * entries were drained.
83
85
  *
84
86
  * Extracted for mmnto/totem#1281 so the no-op compile path can drain stale
@@ -86,9 +88,14 @@ export interface NonCompilableTuple {
86
88
  * leaving stale entries stranded on no-op runs (e.g. after a lesson was
87
89
  * removed or after a parser-bug fix invalidated old non-compilable hashes).
88
90
  * Pure function; does not mutate the input map.
91
+ *
92
+ * mmnto-ai/totem#1481: preserves `reasonCode` and `reason` through the
93
+ * prune so ledger entries stay 4-tuple-shaped on disk. Dropping them back
94
+ * to 2-tuple would silently reintroduce `'legacy-unknown'` on the next
95
+ * load via the Read transform.
89
96
  */
90
- export declare function pruneStaleNonCompilable(nonCompilableMap: Map<string, string>, currentHashes: Set<string>): {
91
- fresh: NonCompilableTuple[];
97
+ export declare function pruneStaleNonCompilable(nonCompilableMap: Map<string, NonCompilableMapValue>, currentHashes: Set<string>): {
98
+ fresh: NonCompilableEntry[];
92
99
  drained: number;
93
100
  };
94
101
  /**
@@ -105,6 +112,24 @@ export declare function pruneStaleRules(rules: readonly CompiledRule[], currentH
105
112
  fresh: CompiledRule[];
106
113
  pruned: number;
107
114
  };
115
+ /**
116
+ * Format a lesson's trace array into a single multi-line block for the
117
+ * `--verbose` renderer. Returns a string (no trailing newline — caller
118
+ * controls that). Output shape:
119
+ *
120
+ * lesson-<hash8> "<heading>":
121
+ * Layer <N> (<pipeline label>) -> <outcome> (<patternHash?>)
122
+ * verify on example: <outcome>
123
+ * retry N: scheduled
124
+ * result: <status> (<reasonCode or detail>)
125
+ *
126
+ * The renderer is defensive: malformed / unknown layer numbers render as
127
+ * "(unknown)" rather than throwing.
128
+ */
129
+ export declare function formatVerboseTraceBlock(lesson: {
130
+ heading: string;
131
+ hash: string;
132
+ }, status: 'compiled' | 'skipped' | 'failed' | 'noop', reasonCode: NonCompilableReasonCode | undefined, trace: readonly LayerTraceEvent[] | undefined): string;
108
133
  export interface AutoScaffoldDeps {
109
134
  fs: typeof import('node:fs');
110
135
  path: typeof import('node:path');
@@ -1 +1 @@
1
- {"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/commands/compile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAqB,WAAW,EAAE,MAAM,cAAc,CAAC;AAYjF;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEvE,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,aAAa,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;;OAKG;IACH,YAAY,CAAC,EAAE,KAAK,CAAC;QACnB,IAAI,EAAE,MAAM,CAAC;QACb,gFAAgF;QAChF,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC,CAAC;CACJ;AAID;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,aAAa,EAAE;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,MAAM,CAcT;AAID;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CACrC,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACrC,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,GACzB;IAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAQlD;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,SAAS,YAAY,EAAE,EAC9B,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,GACzB;IAAE,KAAK,EAAE,YAAY,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAG3C;AAwDD,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,cAAc,SAAS,CAAC,CAAC;IAC7B,IAAI,EAAE,cAAc,WAAW,CAAC,CAAC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1B,GAAG,EAAE;QAAE,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,CAAC;IAClD,mBAAmB,EAAE,cAAc,cAAc,EAAE,mBAAmB,CAAC;IACvE,qBAAqB,EAAE,cAAc,cAAc,EAAE,qBAAqB,CAAC;IAC3E,eAAe,EAAE,cAAc,cAAc,EAAE,eAAe,CAAC;IAC/D,mBAAmB,EAAE,cAAc,cAAc,EAAE,mBAAmB,CAAC;CACxE;AAED,iEAAiE;AACjE,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,WAAW,EACnB,IAAI,EAAE,YAAY,EAClB,IAAI,EAAE,gBAAgB,GACrB,OAAO,CAyBT;AAID,wBAAsB,cAAc,CAClC,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,cAAc,GAAG,cAAc,EAAE,GAAG,IAAI,CAAC,CA60BnD"}
1
+ {"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/commands/compile.ts"],"names":[],"mappings":"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"}