@mmnto/cli 1.43.6 → 1.45.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.
@@ -0,0 +1,470 @@
1
+ /**
2
+ * Tests for `totem mail` (mmnto-ai/totem#1970, ADR-106 § 3 / ADR-107).
3
+ *
4
+ * Filesystem-driven: every test builds a fresh `<tmp>/workspace/<repo>/.totem/orchestration/`
5
+ * tree, exercises the poll, and asserts on the structured `MailPollResult`.
6
+ * Skips the human-text formatter path except where the formatter's behavior
7
+ * itself is under test — JSON output is the durable contract for hook
8
+ * consumers, the text output is human-only.
9
+ */
10
+ import * as fs from 'node:fs';
11
+ import * as os from 'node:os';
12
+ import * as path from 'node:path';
13
+ import { afterEach, beforeEach, describe, expect, it } from 'vitest';
14
+ import { cleanTmpDir } from '../test-utils.js';
15
+ import { pollMail } from './mail.js';
16
+ // ─── Fixture helpers ────────────────────────────────────
17
+ let tmpRoot;
18
+ let workspace;
19
+ function mkDir(p) {
20
+ fs.mkdirSync(p, { recursive: true });
21
+ return p;
22
+ }
23
+ /**
24
+ * Build a sibling repo with `<repo>/.totem/orchestration/<senderAgent>/outbox/<file>.md`
25
+ * entries. `senderAgent` is the agent-id directory name; recipient lives in
26
+ * the frontmatter `to:` field.
27
+ */
28
+ function writeOutbox(repo, senderAgent, files) {
29
+ const outbox = path.join(workspace, repo, '.totem', 'orchestration', senderAgent, 'outbox');
30
+ mkDir(outbox);
31
+ for (const f of files) {
32
+ const content = f.raw ??
33
+ [
34
+ '---',
35
+ `from: ${f.from ?? senderAgent}`,
36
+ `to: ${f.to}`,
37
+ `date: ${f.date ?? '2026-05-18T1700Z'}`,
38
+ `subject: ${f.subject ?? '(no subject)'}`,
39
+ '---',
40
+ '',
41
+ 'Body text.',
42
+ '',
43
+ ].join('\n');
44
+ fs.writeFileSync(path.join(outbox, f.name), content, 'utf-8');
45
+ }
46
+ return outbox;
47
+ }
48
+ function writeProcessed(repo, recipientAgent, names) {
49
+ const dir = path.join(workspace, repo, '.totem', 'orchestration', recipientAgent, 'processed');
50
+ mkDir(dir);
51
+ for (const n of names)
52
+ fs.writeFileSync(path.join(dir, n), '---\nto: x\n---\n', 'utf-8');
53
+ }
54
+ function writeBroadcastProcessed(repo, recipientAgent, names) {
55
+ const dir = path.join(workspace, repo, '.totem', 'orchestration', recipientAgent, 'processed', '_broadcast');
56
+ mkDir(dir);
57
+ for (const n of names)
58
+ fs.writeFileSync(path.join(dir, n), '---\nto: broadcast\n---\n', 'utf-8');
59
+ }
60
+ /**
61
+ * `totem` is the only cohort name resolveSelfAgents pre-knows; using it as
62
+ * the "self" repo keeps the SELF_AGENT resolution working off the basename
63
+ * map without needing a config.json or env override for every test.
64
+ */
65
+ function selfRepoRoot() {
66
+ return mkDir(path.join(workspace, 'totem'));
67
+ }
68
+ beforeEach(() => {
69
+ tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'totem-mail-'));
70
+ workspace = mkDir(path.join(tmpRoot, 'workspace'));
71
+ });
72
+ afterEach(() => {
73
+ cleanTmpDir(tmpRoot);
74
+ });
75
+ function poll(opts = {}) {
76
+ return pollMail({ repoRoot: selfRepoRoot(), workspace, env: {}, ...opts });
77
+ }
78
+ // ─── Basic filter behavior ──────────────────────────────
79
+ describe('pollMail — basic filter behavior', () => {
80
+ it('returns no mail when workspace is empty', () => {
81
+ const result = poll();
82
+ expect(result.mail).toEqual([]);
83
+ expect(result.scanned).toBe(0);
84
+ expect(result.truncated).toBe(false);
85
+ expect(result.workspace).toBe(path.resolve(workspace));
86
+ });
87
+ it('returns mail addressed to a SELF_AGENT', () => {
88
+ writeOutbox('totem-strategy', 'strategy-claude', [
89
+ { name: '2026-05-18T1734Z-strategy-claude.md', to: 'totem-claude', subject: 'lane' },
90
+ ]);
91
+ const result = poll();
92
+ expect(result.mail).toHaveLength(1);
93
+ expect(result.mail[0].to).toBe('totem-claude');
94
+ expect(result.mail[0].from).toBe('strategy-claude');
95
+ expect(result.mail[0].repo).toBe('totem-strategy');
96
+ expect(result.mail[0].subject).toBe('lane');
97
+ });
98
+ it('returns mail addressed to broadcast', () => {
99
+ writeOutbox('totem-strategy', 'strategy-claude', [
100
+ { name: '2026-05-18T1734Z.md', to: 'broadcast', subject: 'cohort announcement' },
101
+ ]);
102
+ const result = poll();
103
+ expect(result.mail).toHaveLength(1);
104
+ expect(result.mail[0].to).toBe('broadcast');
105
+ });
106
+ it('skips mail addressed to a different agent', () => {
107
+ writeOutbox('totem-strategy', 'strategy-claude', [
108
+ { name: '2026-05-18T1918Z.md', to: 'lc-claude', subject: 'not-mine' },
109
+ ]);
110
+ const result = poll();
111
+ expect(result.mail).toEqual([]);
112
+ });
113
+ it('matches `to:` case-insensitively (back-compat with arhgap11-Gemini)', () => {
114
+ writeOutbox('totem-strategy', 'strategy-claude', [
115
+ { name: '2026-05-18T1734Z.md', to: 'Totem-Claude', subject: 'case test' },
116
+ ]);
117
+ const result = poll();
118
+ expect(result.mail).toHaveLength(1);
119
+ expect(result.mail[0].to).toBe('Totem-Claude');
120
+ });
121
+ it('returns mail from multiple sibling repos in one scan', () => {
122
+ writeOutbox('totem-strategy', 'strategy-claude', [
123
+ { name: '2026-05-18T1700Z.md', to: 'totem-claude', subject: 'strategy reply' },
124
+ ]);
125
+ writeOutbox('liquid-city', 'lc-claude', [
126
+ { name: '2026-05-18T1800Z.md', to: 'totem-claude', subject: 'lc heads-up' },
127
+ ]);
128
+ const result = poll();
129
+ expect(result.mail).toHaveLength(2);
130
+ const repos = result.mail.map((m) => m.repo).sort();
131
+ expect(repos).toEqual(['liquid-city', 'totem-strategy']);
132
+ });
133
+ });
134
+ // ─── Processed/ exclusion ───────────────────────────────
135
+ describe('pollMail — processed/ exclusion', () => {
136
+ it('excludes mail already in processed/', () => {
137
+ writeOutbox('totem-strategy', 'strategy-claude', [
138
+ { name: '2026-05-18T1734Z.md', to: 'totem-claude', subject: 'already actioned' },
139
+ { name: '2026-05-18T1918Z.md', to: 'totem-claude', subject: 'still unread' },
140
+ ]);
141
+ writeProcessed('totem', 'totem-claude', ['2026-05-18T1734Z.md']);
142
+ const result = poll();
143
+ expect(result.mail).toHaveLength(1);
144
+ expect(result.mail[0].file).toBe('2026-05-18T1918Z.md');
145
+ });
146
+ it('excludes mail already in processed/_broadcast/', () => {
147
+ writeOutbox('totem-strategy', 'strategy-claude', [
148
+ { name: '2026-05-17T0103Z.md', to: 'broadcast', subject: 'cohort freeze' },
149
+ ]);
150
+ writeBroadcastProcessed('totem', 'totem-claude', ['2026-05-17T0103Z.md']);
151
+ const result = poll();
152
+ expect(result.mail).toEqual([]);
153
+ });
154
+ it('uses processed/ from every SELF_AGENT (multi-agent repos)', () => {
155
+ // Pre-populate processed for totem-gemini; mail addressed to totem-gemini
156
+ // should be excluded even though totem-claude is also a SELF_AGENT.
157
+ writeOutbox('totem-strategy', 'strategy-claude', [
158
+ { name: '2026-05-18T1700Z.md', to: 'totem-gemini', subject: 'already done' },
159
+ ]);
160
+ writeProcessed('totem', 'totem-gemini', ['2026-05-18T1700Z.md']);
161
+ const result = poll();
162
+ expect(result.mail).toEqual([]);
163
+ });
164
+ });
165
+ // ─── Sort + metadata ────────────────────────────────────
166
+ describe('pollMail — sort + metadata', () => {
167
+ it('sorts newest-first by frontmatter date', () => {
168
+ writeOutbox('totem-strategy', 'strategy-claude', [
169
+ { name: 'a.md', to: 'totem-claude', date: '2026-05-18T1000Z', subject: 'older' },
170
+ { name: 'b.md', to: 'totem-claude', date: '2026-05-18T2000Z', subject: 'newer' },
171
+ { name: 'c.md', to: 'totem-claude', date: '2026-05-18T1500Z', subject: 'middle' },
172
+ ]);
173
+ const result = poll();
174
+ expect(result.mail.map((m) => m.subject)).toEqual(['newer', 'middle', 'older']);
175
+ });
176
+ it('falls back to filename sort when date is absent', () => {
177
+ writeOutbox('totem-strategy', 'strategy-claude', [
178
+ { name: '2026-05-18T1000Z.md', to: 'totem-claude', raw: '---\nto: totem-claude\n---\n' },
179
+ { name: '2026-05-18T2000Z.md', to: 'totem-claude', raw: '---\nto: totem-claude\n---\n' },
180
+ ]);
181
+ const result = poll();
182
+ expect(result.mail[0].file).toBe('2026-05-18T2000Z.md');
183
+ expect(result.mail[1].file).toBe('2026-05-18T1000Z.md');
184
+ });
185
+ it('preserves the `to:` field verbatim (mixed case) in result metadata', () => {
186
+ writeOutbox('totem-strategy', 'strategy-claude', [
187
+ { name: 'x.md', to: 'Totem-Claude', subject: 'mixed case to' },
188
+ ]);
189
+ const result = poll();
190
+ expect(result.mail[0].to).toBe('Totem-Claude');
191
+ });
192
+ it('captures `from:` from frontmatter when present', () => {
193
+ writeOutbox('totem-strategy', 'strategy-claude', [
194
+ {
195
+ name: 'x.md',
196
+ to: 'totem-claude',
197
+ from: 'override-sender',
198
+ subject: 'overridden from field',
199
+ },
200
+ ]);
201
+ const result = poll();
202
+ expect(result.mail[0].from).toBe('override-sender');
203
+ });
204
+ it('falls back to outbox-dir name when from: is absent', () => {
205
+ writeOutbox('totem-strategy', 'strategy-claude', [
206
+ {
207
+ name: 'x.md',
208
+ to: 'totem-claude',
209
+ raw: '---\nto: totem-claude\nsubject: no from field\n---\n',
210
+ },
211
+ ]);
212
+ const result = poll();
213
+ expect(result.mail[0].from).toBe('strategy-claude');
214
+ });
215
+ it('reports `(no subject)` when subject is absent', () => {
216
+ writeOutbox('totem-strategy', 'strategy-claude', [
217
+ { name: 'x.md', to: 'totem-claude', raw: '---\nto: totem-claude\n---\n' },
218
+ ]);
219
+ const result = poll();
220
+ expect(result.mail[0].subject).toBe('(no subject)');
221
+ });
222
+ });
223
+ // ─── Frontmatter parsing robustness ─────────────────────
224
+ describe('pollMail — frontmatter parsing', () => {
225
+ it('skips files without `to:` in the frontmatter', () => {
226
+ writeOutbox('totem-strategy', 'strategy-claude', [
227
+ { name: 'noto.md', to: 'totem-claude', raw: '---\nfrom: x\n---\n' },
228
+ ]);
229
+ const result = poll();
230
+ expect(result.mail).toEqual([]);
231
+ });
232
+ it('only reads frontmatter from the header block (body `to:` cannot fabricate a match)', () => {
233
+ writeOutbox('totem-strategy', 'strategy-claude', [
234
+ {
235
+ name: 'body-to.md',
236
+ to: 'unused',
237
+ raw: '---\nfrom: x\n---\n\nto: totem-claude\nsubject: body forge\n',
238
+ },
239
+ ]);
240
+ const result = poll();
241
+ expect(result.mail).toEqual([]);
242
+ });
243
+ it('handles CRLF line endings', () => {
244
+ writeOutbox('totem-strategy', 'strategy-claude', [
245
+ {
246
+ name: 'crlf.md',
247
+ to: 'totem-claude',
248
+ raw: '---\r\nfrom: strategy-claude\r\nto: totem-claude\r\nsubject: crlf\r\n---\r\n\r\nBody.\r\n',
249
+ },
250
+ ]);
251
+ const result = poll();
252
+ expect(result.mail).toHaveLength(1);
253
+ expect(result.mail[0].subject).toBe('crlf');
254
+ });
255
+ it('non-.md files are ignored', () => {
256
+ const outbox = writeOutbox('totem-strategy', 'strategy-claude', []);
257
+ fs.writeFileSync(path.join(outbox, 'note.txt'), '---\nto: totem-claude\n---\nshould be skipped', 'utf-8');
258
+ const result = poll();
259
+ expect(result.mail).toEqual([]);
260
+ });
261
+ });
262
+ // ─── SELF_AGENT precedence + warnings ───────────────────
263
+ describe('pollMail — SELF_AGENT resolution', () => {
264
+ it('records resolution source = map for a known repo', () => {
265
+ const result = poll();
266
+ expect(result.selfAgents.source).toBe('map');
267
+ expect(result.selfAgents.agents).toEqual(['totem-claude', 'totem-gemini']);
268
+ });
269
+ it('respects TOTEM_SELF_AGENT env override', () => {
270
+ writeOutbox('totem-strategy', 'strategy-claude', [
271
+ { name: 'x.md', to: 'custom-id', subject: 'custom' },
272
+ ]);
273
+ const result = poll({ env: { TOTEM_SELF_AGENT: 'custom-id' } });
274
+ expect(result.selfAgents.source).toBe('env');
275
+ expect(result.mail).toHaveLength(1);
276
+ });
277
+ it('warns when SELF_AGENT cannot be resolved', () => {
278
+ const unknownRoot = mkDir(path.join(tmpRoot, 'workspace', 'unknown-repo'));
279
+ writeOutbox('totem-strategy', 'strategy-claude', [
280
+ { name: 'x.md', to: 'something', subject: 'orphan' },
281
+ ]);
282
+ const result = pollMail({ repoRoot: unknownRoot, workspace, env: {} });
283
+ expect(result.selfAgents.source).toBe('none');
284
+ expect(result.selfAgents.agents).toEqual([]);
285
+ expect(result.warnings.some((w) => w.includes('no SELF_AGENT resolved'))).toBe(true);
286
+ // With no SELF, only broadcast survives the filter.
287
+ expect(result.mail).toEqual([]);
288
+ });
289
+ it('still surfaces broadcast mail when SELF_AGENT cannot be resolved', () => {
290
+ const unknownRoot = mkDir(path.join(tmpRoot, 'workspace', 'unknown-repo'));
291
+ writeOutbox('totem-strategy', 'strategy-claude', [
292
+ { name: 'b.md', to: 'broadcast', subject: 'cohort' },
293
+ ]);
294
+ const result = pollMail({ repoRoot: unknownRoot, workspace, env: {} });
295
+ expect(result.mail).toHaveLength(1);
296
+ expect(result.mail[0].to).toBe('broadcast');
297
+ });
298
+ });
299
+ // ─── Workspace + recursive ──────────────────────────────
300
+ describe('pollMail — workspace', () => {
301
+ it('honors the --workspace option', () => {
302
+ const alt = mkDir(path.join(tmpRoot, 'alt-workspace'));
303
+ fs.mkdirSync(path.join(alt, 'totem-strategy', '.totem', 'orchestration', 'strategy-claude', 'outbox'), {
304
+ recursive: true,
305
+ });
306
+ fs.writeFileSync(path.join(alt, 'totem-strategy', '.totem', 'orchestration', 'strategy-claude', 'outbox', 'x.md'), '---\nto: totem-claude\nsubject: alt-workspace\n---\n', 'utf-8');
307
+ const result = poll({ workspace: alt });
308
+ expect(result.mail).toHaveLength(1);
309
+ expect(result.workspace).toBe(path.resolve(alt));
310
+ });
311
+ it('honors TOTEM_WORKSPACE env var', () => {
312
+ const alt = mkDir(path.join(tmpRoot, 'env-workspace'));
313
+ fs.mkdirSync(path.join(alt, 'totem-strategy', '.totem', 'orchestration', 'strategy-claude', 'outbox'), {
314
+ recursive: true,
315
+ });
316
+ fs.writeFileSync(path.join(alt, 'totem-strategy', '.totem', 'orchestration', 'strategy-claude', 'outbox', 'x.md'), '---\nto: totem-claude\n---\n', 'utf-8');
317
+ const result = poll({ workspace: undefined, env: { TOTEM_WORKSPACE: alt } });
318
+ expect(result.workspace).toBe(path.resolve(alt));
319
+ expect(result.mail).toHaveLength(1);
320
+ });
321
+ it('warns and returns empty when workspace does not exist', () => {
322
+ const missing = path.join(tmpRoot, 'does-not-exist');
323
+ const result = poll({ workspace: missing });
324
+ expect(result.warnings.some((w) => w.includes('workspace does not exist'))).toBe(true);
325
+ expect(result.mail).toEqual([]);
326
+ });
327
+ it('--recursive descends into nested layouts', () => {
328
+ // Sibling repo nested inside a wrapper dir; default scan misses it,
329
+ // recursive scan finds it.
330
+ const wrapper = mkDir(path.join(workspace, 'wrapper-dir'));
331
+ fs.mkdirSync(path.join(wrapper, 'nested-strategy', '.totem', 'orchestration', 'strategy-claude', 'outbox'), { recursive: true });
332
+ fs.writeFileSync(path.join(wrapper, 'nested-strategy', '.totem', 'orchestration', 'strategy-claude', 'outbox', 'x.md'), '---\nto: totem-claude\nsubject: nested\n---\n', 'utf-8');
333
+ const flat = poll({ recursive: false });
334
+ expect(flat.mail).toEqual([]);
335
+ const recursive = poll({ recursive: true });
336
+ expect(recursive.mail).toHaveLength(1);
337
+ expect(recursive.mail[0].subject).toBe('nested');
338
+ // Label uses the immediate parent dir (where `.totem/orchestration/`
339
+ // lives), not the top-level wrapper — readers expect "the repo" to be
340
+ // the leaf, not the container.
341
+ expect(recursive.mail[0].repo).toBe('nested-strategy');
342
+ });
343
+ it('skips dot-directories and node_modules during recursive scan', () => {
344
+ const node = mkDir(path.join(workspace, 'node_modules', 'fake-pkg'));
345
+ fs.mkdirSync(path.join(node, '.totem', 'orchestration', 'strategy-claude', 'outbox'), {
346
+ recursive: true,
347
+ });
348
+ fs.writeFileSync(path.join(node, '.totem', 'orchestration', 'strategy-claude', 'outbox', 'x.md'), '---\nto: totem-claude\nsubject: spam\n---\n', 'utf-8');
349
+ const result = poll({ recursive: true });
350
+ expect(result.mail).toEqual([]);
351
+ });
352
+ });
353
+ // ─── MAX_SCAN truncation ────────────────────────────────
354
+ describe('pollMail — MAX_SCAN truncation', () => {
355
+ it('marks truncated and stops scanning at the cap (scanned <= MAX_SCAN)', () => {
356
+ // Generate > MAX_SCAN files (501) so the cap is exercised. Filenames
357
+ // chosen ascending so DESC sort lists the highest-numbered first;
358
+ // truncation drops the *oldest* tail, preserving the newest mail.
359
+ const files = [];
360
+ for (let i = 0; i < 510; i++) {
361
+ const num = String(i).padStart(5, '0');
362
+ files.push({ name: `${num}.md`, to: 'totem-claude', subject: `n${i}` });
363
+ }
364
+ writeOutbox('totem-strategy', 'strategy-claude', files);
365
+ const result = poll();
366
+ expect(result.truncated).toBe(true);
367
+ // Contract: scanned never exceeds MAX_SCAN. Documents the pre-increment
368
+ // off-by-one fix from CR R1 (#1971).
369
+ expect(result.scanned).toBeLessThanOrEqual(500);
370
+ expect(result.scanned).toBe(500);
371
+ // Newest file (highest number) must be in the result; the cap drops the tail.
372
+ expect(result.mail.some((m) => m.file === '00509.md')).toBe(true);
373
+ });
374
+ it('preserves global newest-first ordering under truncation across repos (GCA R2 #1971)', () => {
375
+ // Without global ordering, alphabet-early repos (e.g. `apple-repo`) could
376
+ // hog MAX_SCAN. Confirm that the newest files across BOTH repos survive,
377
+ // even when alphabet-first repo has enough files to exhaust the cap alone.
378
+ const oldFiles = [];
379
+ for (let i = 0; i < 600; i++) {
380
+ // Year 2024 — these are "old" in the global ordering.
381
+ oldFiles.push({
382
+ name: `2024-${String(i).padStart(5, '0')}.md`,
383
+ to: 'totem-claude',
384
+ subject: `old-${i}`,
385
+ });
386
+ }
387
+ writeOutbox('apple-repo', 'apple-sender', oldFiles);
388
+ const newFiles = [];
389
+ for (let i = 0; i < 5; i++) {
390
+ // Year 2027 — newer than every apple-repo file. Global sort must
391
+ // surface these even though apple-repo would alphabetically come first.
392
+ newFiles.push({
393
+ name: `2027-${String(i).padStart(5, '0')}.md`,
394
+ to: 'totem-claude',
395
+ subject: `fresh-${i}`,
396
+ });
397
+ }
398
+ writeOutbox('zebra-repo', 'zebra-sender', newFiles);
399
+ const result = poll();
400
+ expect(result.truncated).toBe(true);
401
+ expect(result.scanned).toBe(500);
402
+ // All 5 fresh entries must be in the result. Pre-fix, they would have
403
+ // been dropped because apple-repo's 500 stale files hit the cap first.
404
+ const freshSubjects = result.mail.map((m) => m.subject).filter((s) => s.startsWith('fresh-'));
405
+ expect(freshSubjects).toHaveLength(5);
406
+ });
407
+ });
408
+ // ─── Frontmatter forge defense (GCA R2 security finding on #1971) ───────
409
+ describe('pollMail — frontmatter forge defense', () => {
410
+ it('rejects files that do not start with the YAML `---` delimiter', () => {
411
+ writeOutbox('totem-strategy', 'strategy-claude', [
412
+ {
413
+ name: 'no-delimiter.md',
414
+ to: 'unused',
415
+ raw: 'to: totem-claude\nsubject: forged\nbody text\n',
416
+ },
417
+ ]);
418
+ const result = poll();
419
+ expect(result.mail).toEqual([]);
420
+ });
421
+ it('rejects large files lacking a blank-line frontmatter separator', () => {
422
+ // Real frontmatter is tens of bytes; a file > 2 KiB without the
423
+ // blank-line separator is structurally malformed. Capping the header
424
+ // scan in that case prevents body lines from fabricating `to:` matches.
425
+ const filler = 'x'.repeat(2500);
426
+ writeOutbox('totem-strategy', 'strategy-claude', [
427
+ {
428
+ name: 'huge-no-separator.md',
429
+ to: 'unused',
430
+ raw: `---\nfrom: strategy-claude\n${filler}\nto: totem-claude\nsubject: forged\n`,
431
+ },
432
+ ]);
433
+ const result = poll();
434
+ expect(result.mail).toEqual([]);
435
+ });
436
+ it('accepts a small file without a blank-line separator (header fits in MAX_HEADER_BYTES)', () => {
437
+ // Below the 2 KiB cap, the whole file is treated as header — that's the
438
+ // existing lenient behavior, preserved for valid handoffs that omit the
439
+ // trailing blank line.
440
+ writeOutbox('totem-strategy', 'strategy-claude', [
441
+ {
442
+ name: 'small-no-separator.md',
443
+ to: 'totem-claude',
444
+ raw: '---\nfrom: strategy-claude\nto: totem-claude\nsubject: tight\n---\n',
445
+ },
446
+ ]);
447
+ const result = poll();
448
+ expect(result.mail).toHaveLength(1);
449
+ expect(result.mail[0].subject).toBe('tight');
450
+ });
451
+ });
452
+ // ─── Structured warnings on FS failures ─────────────────
453
+ describe('pollMail — structured warnings on FS failures', () => {
454
+ it('emits a warning when processed/ exists but is unreadable', () => {
455
+ writeOutbox('totem-strategy', 'strategy-claude', [
456
+ { name: '2026-05-18T1734Z.md', to: 'totem-claude', subject: 'live' },
457
+ ]);
458
+ // Create processed/ as a FILE (not a dir) so readdirSync throws ENOTDIR.
459
+ // existsSync is true (it's a file), readdir then fails — exercises the
460
+ // catch-and-warn path for processed/ specifically.
461
+ const selfProcessed = path.join(selfRepoRoot(), '.totem', 'orchestration', 'totem-claude');
462
+ mkDir(selfProcessed);
463
+ fs.writeFileSync(path.join(selfProcessed, 'processed'), 'not a directory');
464
+ const result = poll();
465
+ // Mail still surfaces (degraded — no exclusion filter), warning recorded.
466
+ expect(result.mail).toHaveLength(1);
467
+ expect(result.warnings.some((w) => w.startsWith('processed/ scan failed'))).toBe(true);
468
+ });
469
+ });
470
+ //# sourceMappingURL=mail.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mail.test.js","sourceRoot":"","sources":["../../src/commands/mail.test.ts"],"names":[],"mappings":"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"}
@@ -357,8 +357,8 @@ export declare const CompiledHooksManifestSchema: z.ZodObject<{
357
357
  recoveryHint?: string | undefined;
358
358
  verification_shadow?: unknown;
359
359
  }[];
360
- schemaVersion: 1;
361
360
  compiledAt: string;
361
+ schemaVersion: 1;
362
362
  sourcePackVersions: Record<string, string>;
363
363
  }, {
364
364
  hooks: {
@@ -376,8 +376,8 @@ export declare const CompiledHooksManifestSchema: z.ZodObject<{
376
376
  recoveryHint?: string | undefined;
377
377
  verification_shadow?: unknown;
378
378
  }[];
379
- schemaVersion: 1;
380
379
  compiledAt: string;
380
+ schemaVersion: 1;
381
381
  sourcePackVersions: Record<string, string>;
382
382
  }>;
383
383
  export type CompiledHooksManifest = z.infer<typeof CompiledHooksManifestSchema>;
package/dist/index.js CHANGED
@@ -443,6 +443,25 @@ program
443
443
  handleError(err);
444
444
  }
445
445
  });
446
+ // Canonical cross-repo outbox poll (mmnto-ai/totem#1970; ADR-106 § 3 / ADR-107).
447
+ // Replaces ad-hoc per-hook implementations with one cohort-portable surface.
448
+ program
449
+ .command('mail')
450
+ .description('Show unread cross-repo mail addressed to this repo’s agent(s) (ADR-106 § 3)')
451
+ .option('--json', 'Emit JSON to stdout instead of human-readable text to stderr')
452
+ .option('--recursive', 'Walk the workspace recursively for nested layouts (default: single-level siblings)')
453
+ .option('--workspace <path>', 'Workspace dir to scan (default: $TOTEM_WORKSPACE, else parent of cwd)')
454
+ .action(async (opts) => {
455
+ try {
456
+ const { mailCommand } = await import('./commands/mail.js');
457
+ await mailCommand(opts);
458
+ }
459
+ catch (err) {
460
+ handleError(err);
461
+ // totem-context: handleError returns `never` (process.exit), so the throw is unreachable but required to satisfy the Tenet 4 fail-loud rule that bans bare-catch silent-degrade. Mirrors the verify-badges pattern above.
462
+ throw err;
463
+ }
464
+ });
446
465
  program
447
466
  .command('remove-secret <index>')
448
467
  .description('Remove a custom secret from .totem/secrets.json by index (from list-secrets)')