@memnexus-ai/mx-agent-cli 0.1.198 → 0.1.200

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.
@@ -1 +1 @@
1
- {"version":3,"file":"config-mirror-integrity.test.js","sourceRoot":"","sources":["../../src/__tests__/config-mirror-integrity.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config-mirror-integrity.test.js","sourceRoot":"","sources":["../../src/__tests__/config-mirror-integrity.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Tests for the `.claude/` generator (scripts/generate-claude.mjs) — Direction B
3
+ * config single-source-of-truth (#4304), Phase 2.
4
+ *
5
+ * The load-bearing guarantee is the BYTE-IDENTICAL NO-OP: generating from the
6
+ * committed `agent-config/` (+ `local/`) must reproduce the committed `.claude/`
7
+ * exactly, so shipping the generator while `.claude/` is still committed changes
8
+ * nothing.
9
+ *
10
+ * NO SYMLINKS, ANYWHERE (PO directive 2026-07-20): the generator emits only plain
11
+ * files and real directories and FAILS CLOSED on any symlink in the source tree
12
+ * (nothing materialized). These tests lock down the no-op, idempotence, the
13
+ * symlink ban, the container-boot split (permission layer from origin / rest from
14
+ * working tree), and the fail-closed guards — including through the REAL
15
+ * production path (`generateClaudeConfigFromGit` against a committed git fixture).
16
+ */
17
+ export {};
18
+ //# sourceMappingURL=generate-claude.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-claude.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/generate-claude.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG"}
@@ -0,0 +1,484 @@
1
+ /**
2
+ * Tests for the `.claude/` generator (scripts/generate-claude.mjs) — Direction B
3
+ * config single-source-of-truth (#4304), Phase 2.
4
+ *
5
+ * The load-bearing guarantee is the BYTE-IDENTICAL NO-OP: generating from the
6
+ * committed `agent-config/` (+ `local/`) must reproduce the committed `.claude/`
7
+ * exactly, so shipping the generator while `.claude/` is still committed changes
8
+ * nothing.
9
+ *
10
+ * NO SYMLINKS, ANYWHERE (PO directive 2026-07-20): the generator emits only plain
11
+ * files and real directories and FAILS CLOSED on any symlink in the source tree
12
+ * (nothing materialized). These tests lock down the no-op, idempotence, the
13
+ * symlink ban, the container-boot split (permission layer from origin / rest from
14
+ * working tree), and the fail-closed guards — including through the REAL
15
+ * production path (`generateClaudeConfigFromGit` against a committed git fixture).
16
+ */
17
+ import { describe, it, expect, beforeAll, beforeEach, afterEach, afterAll } from 'vitest';
18
+ import { cpSync, existsSync, lstatSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, readlinkSync, rmSync, statSync, symlinkSync, writeFileSync, } from 'fs';
19
+ import { tmpdir } from 'os';
20
+ import { dirname, join } from 'path';
21
+ import { fileURLToPath } from 'url';
22
+ import { spawnSync } from 'child_process';
23
+ // @ts-expect-error — plain ESM script, no type declarations.
24
+ import { generateClaudeConfig, generateClaudeConfigFromGit, generateClaudeConfigForBoot, refreshPermissionCache } from '../../scripts/generate-claude.mjs';
25
+ const HERE = dirname(fileURLToPath(import.meta.url));
26
+ /** Walk up from the test file to the repo root that holds mx-agent-system/agent-config. */
27
+ function findRepoRoot() {
28
+ let dir = HERE;
29
+ for (let i = 0; i < 20; i++) {
30
+ if (existsSync(join(dir, 'mx-agent-system', 'agent-config', 'settings.json')))
31
+ return dir;
32
+ const parent = dirname(dir);
33
+ if (parent === dir)
34
+ break;
35
+ dir = parent;
36
+ }
37
+ throw new Error('could not locate repo root from ' + HERE);
38
+ }
39
+ const REPO_ROOT = findRepoRoot();
40
+ const CONFIG_SOURCE = 'mx-agent-system/agent-config';
41
+ const SRC = join(REPO_ROOT, CONFIG_SOURCE);
42
+ const COMMITTED_CLAUDE = join(REPO_ROOT, '.claude');
43
+ /** baseDir/overlayDir for a copied agent-config tree at <root>/<CONFIG_SOURCE>. */
44
+ function layers(srcRoot) {
45
+ return { baseDir: srcRoot, overlayDir: join(srcRoot, 'local') };
46
+ }
47
+ /** Recursively list files (relative POSIX paths) and symlinks under a dir. */
48
+ function walk(root, base = '') {
49
+ const files = [];
50
+ const links = [];
51
+ for (const ent of readdirSync(join(root, base), { withFileTypes: true })) {
52
+ const rel = base ? `${base}/${ent.name}` : ent.name;
53
+ if (ent.isSymbolicLink())
54
+ links.push(rel);
55
+ else if (ent.isDirectory()) {
56
+ const sub = walk(root, rel);
57
+ files.push(...sub.files);
58
+ links.push(...sub.links);
59
+ }
60
+ else if (ent.isFile())
61
+ files.push(rel);
62
+ }
63
+ return { files: files.sort(), links: links.sort() };
64
+ }
65
+ let tmpRoots = [];
66
+ function mkTmp(prefix) {
67
+ const d = mkdtempSync(join(tmpdir(), prefix));
68
+ tmpRoots.push(d);
69
+ return d;
70
+ }
71
+ afterEach(() => {
72
+ for (const d of tmpRoots)
73
+ rmSync(d, { recursive: true, force: true });
74
+ tmpRoots = [];
75
+ });
76
+ // Isolate the origin-verified permission cache (~/.mx-agent/, Red Team CRITICAL B)
77
+ // to a throwaway HOME so the fromGit/boot paths — which now refresh the cache —
78
+ // never touch the real home dir. Each test gets a fresh HOME (cleaned by afterEach
79
+ // via tmpRoots), so cache state does not leak between tests.
80
+ let ORIG_HOME;
81
+ beforeAll(() => { ORIG_HOME = process.env.HOME; });
82
+ beforeEach(() => { process.env.HOME = mkTmp('mx-genclaude-home-'); });
83
+ afterAll(() => {
84
+ if (ORIG_HOME === undefined)
85
+ delete process.env.HOME;
86
+ else
87
+ process.env.HOME = ORIG_HOME;
88
+ });
89
+ /**
90
+ * Copy the real committed agent-config source into an isolated <tmp>/<CONFIG_SOURCE>.
91
+ * The source is symlink-free now (the mx-find/mx-rules/mx-save command files are
92
+ * plain files), so a plain recursive copy is a faithful reproduction.
93
+ */
94
+ function buildFixture() {
95
+ const root = mkTmp('mx-genclaude-fx-');
96
+ const src = join(root, CONFIG_SOURCE);
97
+ mkdirSync(dirname(src), { recursive: true });
98
+ cpSync(SRC, src, { recursive: true });
99
+ return { root, src };
100
+ }
101
+ // ── byte-identical no-op ──────────────────────────────────────────────────────
102
+ describe('generateClaudeConfig — byte-identical no-op vs committed .claude', () => {
103
+ let dest;
104
+ let root;
105
+ beforeAll(() => {
106
+ root = mkdtempSync(join(tmpdir(), 'mx-genclaude-noop-'));
107
+ const src = join(root, CONFIG_SOURCE);
108
+ mkdirSync(dirname(src), { recursive: true });
109
+ cpSync(SRC, src, { recursive: true });
110
+ dest = join(root, '.claude');
111
+ generateClaudeConfig({ ...layers(src), destRoot: dest });
112
+ });
113
+ it('reproduces every committed regular file byte-for-byte', () => {
114
+ const committed = walk(COMMITTED_CLAUDE);
115
+ // Ignore runtime-only artifacts that live in .claude/ but are not managed
116
+ // config (settings.local.json, scheduled task locks).
117
+ const managed = committed.files.filter(f => f !== 'settings.local.json' && !f.endsWith('.lock') && !f.startsWith('scheduled_tasks'));
118
+ for (const rel of managed) {
119
+ const g = join(dest, rel);
120
+ expect(existsSync(g), `generated missing ${rel}`).toBe(true);
121
+ expect(readFileSync(g).equals(readFileSync(join(COMMITTED_CLAUDE, rel))), `content mismatch: ${rel}`).toBe(true);
122
+ }
123
+ });
124
+ it('emits ZERO symlinks and the committed tree has none either', () => {
125
+ expect(walk(dest).links).toEqual([]);
126
+ expect(walk(COMMITTED_CLAUDE).links).toEqual([]);
127
+ });
128
+ it('emits the mx-find/mx-rules/mx-save commands as plain regular files', () => {
129
+ for (const name of ['mx-find.md', 'mx-rules.md', 'mx-save.md']) {
130
+ const g = join(dest, 'commands', name);
131
+ expect(lstatSync(g).isSymbolicLink(), `${name} must not be a symlink`).toBe(false);
132
+ expect(lstatSync(g).isFile(), `${name} must be a regular file`).toBe(true);
133
+ expect(readFileSync(g).equals(readFileSync(join(COMMITTED_CLAUDE, 'commands', name)))).toBe(true);
134
+ }
135
+ });
136
+ it('produces no managed files absent from committed .claude', () => {
137
+ const committed = new Set(walk(COMMITTED_CLAUDE).files);
138
+ for (const rel of walk(dest).files) {
139
+ expect(committed.has(rel), `generated an extra file not in committed: ${rel}`).toBe(true);
140
+ }
141
+ });
142
+ it('marks *.sh hooks executable (0755) and .conf non-executable', () => {
143
+ const shMode = statSync(join(dest, 'hooks', 'git-mutation-guard.sh')).mode & 0o777;
144
+ const confMode = statSync(join(dest, 'hooks', 'ci-validate-routes.conf')).mode & 0o777;
145
+ expect(shMode).toBe(0o755);
146
+ expect(confMode).toBe(0o644);
147
+ });
148
+ it('unions shipped + local agents (26) and skills (13)', () => {
149
+ expect(readdirSync(join(dest, 'agents')).filter(f => f.endsWith('.md')).length).toBe(26);
150
+ expect(readdirSync(join(dest, 'skills')).length).toBe(13);
151
+ });
152
+ it('(cleanup) removes the shared no-op fixture', () => {
153
+ rmSync(root, { recursive: true, force: true });
154
+ expect(existsSync(root)).toBe(false);
155
+ });
156
+ });
157
+ // ── idempotence ────────────────────────────────────────────────────────────────
158
+ describe('generateClaudeConfig — idempotence', () => {
159
+ it('two runs produce identical output', () => {
160
+ const { root, src } = buildFixture();
161
+ const destA = join(root, '.claude');
162
+ generateClaudeConfig({ ...layers(src), destRoot: destA });
163
+ const snap1 = snapshot(destA);
164
+ generateClaudeConfig({ ...layers(src), destRoot: destA });
165
+ const snap2 = snapshot(destA);
166
+ expect(snap2).toEqual(snap1);
167
+ });
168
+ function snapshot(dest) {
169
+ const out = {};
170
+ const { files, links } = walk(dest);
171
+ for (const f of files)
172
+ out[f] = 'F:' + readFileSync(join(dest, f)).toString('base64');
173
+ for (const l of links)
174
+ out[l] = 'L:' + readlinkSync(join(dest, l));
175
+ return out;
176
+ }
177
+ });
178
+ // ── symlink ban / FAIL-CLOSED ────────────────────────────────────────────────
179
+ describe('generateClaudeConfig — FAIL-CLOSED symlink ban (nothing materialized)', () => {
180
+ it('throws and materializes NOTHING when a command is a symlink', () => {
181
+ const { root, src } = buildFixture();
182
+ const dest = join(root, '.claude');
183
+ symlinkSync('../../../../etc/passwd', join(src, 'local', 'commands', 'evil.md'));
184
+ expect(() => generateClaudeConfig({ ...layers(src), destRoot: dest })).toThrow(/FAIL-CLOSED/);
185
+ expect(existsSync(dest)).toBe(false);
186
+ });
187
+ it('throws and materializes NOTHING when a skill file is a symlink (deep)', () => {
188
+ const { root, src } = buildFixture();
189
+ const dest = join(root, '.claude');
190
+ const skillDir = join(src, 'skills', 'mx-save');
191
+ symlinkSync('SKILL.md', join(skillDir, 'aliased.md'));
192
+ expect(() => generateClaudeConfig({ ...layers(src), destRoot: dest })).toThrow(/FAIL-CLOSED/);
193
+ expect(existsSync(dest)).toBe(false);
194
+ });
195
+ it('throws and materializes NOTHING when a rules file is a symlink', () => {
196
+ const { root, src } = buildFixture();
197
+ const dest = join(root, '.claude');
198
+ symlinkSync('eval-harness.md', join(src, 'rules', 'aliased-rule.md'));
199
+ expect(() => generateClaudeConfig({ ...layers(src), destRoot: dest })).toThrow(/FAIL-CLOSED/);
200
+ expect(existsSync(dest)).toBe(false);
201
+ });
202
+ it('accepts a fully symlink-free source (control)', () => {
203
+ const { root, src } = buildFixture();
204
+ const dest = join(root, '.claude');
205
+ expect(() => generateClaudeConfig({ ...layers(src), destRoot: dest })).not.toThrow();
206
+ expect(walk(dest).links).toEqual([]);
207
+ });
208
+ });
209
+ describe('generateClaudeConfig — prune guard (Red Team MAJOR 4)', () => {
210
+ it('FAILS CLOSED when a managed dest subdir is itself a symlink', () => {
211
+ const { root, src } = buildFixture();
212
+ const dest = join(root, '.claude');
213
+ mkdirSync(dest, { recursive: true });
214
+ // Attacker pre-plants a `hooks` symlink pointing outside .claude/.
215
+ const outside = mkTmp('mx-genclaude-outside-');
216
+ symlinkSync(outside, join(dest, 'hooks'));
217
+ expect(() => generateClaudeConfig({ ...layers(src), destRoot: dest })).toThrow(/FAIL-CLOSED/);
218
+ // The symlinked-away directory was never pruned/written through.
219
+ expect(walk(outside).files).toEqual([]);
220
+ });
221
+ });
222
+ // ── nested dest-side symlink guard (Red Team CRITICAL A) ──────────────────────
223
+ //
224
+ // guardManagedDir was only applied to the 4 apex managed dirs. A pre-planted
225
+ // symlink at a NESTED dest dir (.claude/skills/<name>, .claude/commands/<name>,
226
+ // or a deeper subdir) was followed by mkdirSync/writeFileSync, letting a write
227
+ // escape .claude/. The fix guards every dest-dir mkdir; these tests plant symlinks
228
+ // at each nested level and assert FAIL-CLOSED with the target sentinel untouched.
229
+ describe('generateClaudeConfig — nested dest symlink guard (Red Team CRITICAL A)', () => {
230
+ /** Scratch dir holding a sentinel that a followed symlink would clobber. */
231
+ function scratchWithSentinel() {
232
+ const dir = mkTmp('mx-genclaude-target-');
233
+ const sentinel = join(dir, 'sentinel.txt');
234
+ const bytes = 'DO NOT TOUCH\n';
235
+ writeFileSync(sentinel, bytes);
236
+ return { dir, sentinel, bytes };
237
+ }
238
+ it('FAILS CLOSED when .claude/skills/<name> (apex skill dir) is a symlink', () => {
239
+ const { root, src } = buildFixture();
240
+ const dest = join(root, '.claude');
241
+ const { dir: target, sentinel, bytes } = scratchWithSentinel();
242
+ // Pick a skill that exists in the source so the loop reaches it.
243
+ const skillName = readdirSync(join(src, 'skills'), { withFileTypes: true })
244
+ .find(e => e.isDirectory()).name;
245
+ mkdirSync(join(dest, 'skills'), { recursive: true });
246
+ symlinkSync(target, join(dest, 'skills', skillName));
247
+ expect(() => generateClaudeConfig({ ...layers(src), destRoot: dest })).toThrow(/FAIL-CLOSED/);
248
+ expect(readFileSync(sentinel, 'utf-8')).toBe(bytes);
249
+ expect(walk(target).files).toEqual(['sentinel.txt']); // nothing written through
250
+ });
251
+ it('FAILS CLOSED when a DEEP nested skill subdir is a symlink', () => {
252
+ const { root, src } = buildFixture();
253
+ const dest = join(root, '.claude');
254
+ const { dir: target, sentinel, bytes } = scratchWithSentinel();
255
+ // Give a source skill a `sub/` subdir so copyFileTree recurses into it.
256
+ const skillName = readdirSync(join(src, 'skills'), { withFileTypes: true })
257
+ .find(e => e.isDirectory()).name;
258
+ mkdirSync(join(src, 'skills', skillName, 'sub'), { recursive: true });
259
+ writeFileSync(join(src, 'skills', skillName, 'sub', 'note.md'), '# note\n');
260
+ // Pre-plant the parent as a REAL dir and the nested `sub` as a symlink.
261
+ mkdirSync(join(dest, 'skills', skillName), { recursive: true });
262
+ symlinkSync(target, join(dest, 'skills', skillName, 'sub'));
263
+ expect(() => generateClaudeConfig({ ...layers(src), destRoot: dest })).toThrow(/FAIL-CLOSED/);
264
+ expect(readFileSync(sentinel, 'utf-8')).toBe(bytes);
265
+ expect(walk(target).files).toEqual(['sentinel.txt']);
266
+ });
267
+ it('FAILS CLOSED when .claude/commands/<name> (a command DIR) is a symlink', () => {
268
+ const { root, src } = buildFixture();
269
+ const dest = join(root, '.claude');
270
+ const { dir: target, sentinel, bytes } = scratchWithSentinel();
271
+ // Add a directory-shaped command to the overlay so the per-command dir loop runs.
272
+ const cmdDir = join(src, 'local', 'commands', 'evil-cmd');
273
+ mkdirSync(cmdDir, { recursive: true });
274
+ writeFileSync(join(cmdDir, 'inner.md'), '# inner\n');
275
+ mkdirSync(join(dest, 'commands'), { recursive: true });
276
+ symlinkSync(target, join(dest, 'commands', 'evil-cmd'));
277
+ expect(() => generateClaudeConfig({ ...layers(src), destRoot: dest })).toThrow(/FAIL-CLOSED/);
278
+ expect(readFileSync(sentinel, 'utf-8')).toBe(bytes);
279
+ expect(walk(target).files).toEqual(['sentinel.txt']);
280
+ });
281
+ it('FAILS CLOSED when the dest APEX (.claude) itself is a symlink', () => {
282
+ const { root, src } = buildFixture();
283
+ const { dir: target, sentinel, bytes } = scratchWithSentinel();
284
+ // Pre-plant `.claude` itself as a symlink to an outside sentinel dir. Without
285
+ // the apex guard, mkdirSync(destRoot) follows it and every write escapes.
286
+ const dest = join(root, '.claude');
287
+ symlinkSync(target, dest);
288
+ expect(() => generateClaudeConfig({ ...layers(src), destRoot: dest })).toThrow(/FAIL-CLOSED/);
289
+ expect(readFileSync(sentinel, 'utf-8')).toBe(bytes);
290
+ expect(walk(target).files).toEqual(['sentinel.txt']); // nothing written through
291
+ });
292
+ });
293
+ // ── REAL production path: --from-git against a committed git fixture (MAJOR 3) ──
294
+ /** Init a git repo with an agent-config tree committed at HEAD; return its root. */
295
+ function buildGitFixture() {
296
+ const root = mkTmp('mx-genclaude-git-');
297
+ const src = join(root, CONFIG_SOURCE);
298
+ const localCmds = join(src, 'local', 'commands');
299
+ const localAgents = join(src, 'local', 'agents');
300
+ const skillDir = join(src, 'skills', 'demo');
301
+ const hooksDir = join(src, 'hooks');
302
+ const rulesDir = join(src, 'rules');
303
+ const agentsDir = join(src, 'agents');
304
+ for (const d of [localCmds, localAgents, skillDir, hooksDir, rulesDir, agentsDir]) {
305
+ mkdirSync(d, { recursive: true });
306
+ }
307
+ writeFileSync(join(src, 'settings.json'), '{"allow":["Bash(git*)"],"deny":[]}\n');
308
+ writeFileSync(join(hooksDir, 'guard.sh'), '#!/bin/bash\necho guard\n');
309
+ writeFileSync(join(hooksDir, 'notes.conf'), 'k=v\n');
310
+ writeFileSync(join(rulesDir, 'rule.md'), '# rule\n');
311
+ writeFileSync(join(agentsDir, 'shipped.md'), '# shipped agent\n');
312
+ writeFileSync(join(localAgents, 'local.md'), '# local agent\n');
313
+ writeFileSync(join(skillDir, 'SKILL.md'), '# skill\n');
314
+ writeFileSync(join(localCmds, 'mx-demo.md'), '# demo command\n');
315
+ const git = (args) => {
316
+ const r = spawnSync('git', args, { cwd: root, encoding: 'utf-8' });
317
+ if (r.status !== 0)
318
+ throw new Error(`git ${args.join(' ')} failed: ${r.stderr}`);
319
+ };
320
+ git(['init', '-q']);
321
+ git(['config', 'user.email', 't@t']);
322
+ git(['config', 'user.name', 't']);
323
+ git(['add', '-A']);
324
+ git(['commit', '-q', '-m', 'fixture']);
325
+ return root;
326
+ }
327
+ describe('generateClaudeConfigFromGit — real production path', () => {
328
+ it('reproduces the tree from HEAD, emitting only plain files', () => {
329
+ const root = buildGitFixture();
330
+ const dest = join(root, 'out', '.claude');
331
+ const res = generateClaudeConfigFromGit({ ref: 'HEAD', repoRoot: root, destRoot: dest, configSource: CONFIG_SOURCE });
332
+ expect(res.counts.hooks).toBe(2); // guard.sh + notes.conf
333
+ expect(res.counts.agents).toBe(2); // shipped + local
334
+ expect(res.counts.commands).toBe(1); // mx-demo.md
335
+ expect(walk(dest).links).toEqual([]);
336
+ expect(readFileSync(join(dest, 'settings.json'), 'utf-8')).toContain('Bash(git*)');
337
+ expect(statSync(join(dest, 'hooks', 'guard.sh')).mode & 0o777).toBe(0o755);
338
+ expect(statSync(join(dest, 'hooks', 'notes.conf')).mode & 0o777).toBe(0o644);
339
+ });
340
+ it('FAILS CLOSED with nothing materialized when a symlink is committed into the source', () => {
341
+ const root = buildGitFixture();
342
+ // Smuggle a symlink into the committed config source and commit it.
343
+ const evil = join(root, CONFIG_SOURCE, 'local', 'commands', 'evil.md');
344
+ symlinkSync('../../../../../../etc/passwd', evil);
345
+ const g = (args) => spawnSync('git', args, { cwd: root, encoding: 'utf-8' });
346
+ g(['add', '-A']);
347
+ g(['commit', '-q', '-m', 'smuggle symlink']);
348
+ const dest = join(root, 'out', '.claude');
349
+ expect(() => generateClaudeConfigFromGit({ ref: 'HEAD', repoRoot: root, destRoot: dest, configSource: CONFIG_SOURCE })).toThrow(/FAIL-CLOSED/);
350
+ // QA obs: nothing materialized.
351
+ expect(existsSync(dest)).toBe(false);
352
+ });
353
+ });
354
+ // ── container-boot split (permission from origin / rest from working tree) ─────
355
+ describe('generateClaudeConfigForBoot — permission-layer split (Red Team CRITICAL 1)', () => {
356
+ it('sources settings.json + hooks from the git ref, and rules/commands from the working tree', () => {
357
+ const root = buildGitFixture();
358
+ const src = join(root, CONFIG_SOURCE);
359
+ // Tamper the WORKING-TREE permission layer + add a working-tree-only rule/command.
360
+ writeFileSync(join(src, 'settings.json'), '{"allow":["TAMPERED"],"deny":[]}\n');
361
+ writeFileSync(join(src, 'hooks', 'guard.sh'), '#!/bin/bash\necho TAMPERED\n');
362
+ writeFileSync(join(src, 'rules', 'wt-only.md'), '# working-tree rule\n');
363
+ writeFileSync(join(src, 'local', 'commands', 'wt-cmd.md'), '# working-tree command\n');
364
+ const dest = join(root, 'out', '.claude');
365
+ const { result, permissionPinned } = generateClaudeConfigForBoot({
366
+ permissionRef: 'HEAD', repoRoot: root, destRoot: dest, configSource: CONFIG_SOURCE,
367
+ });
368
+ expect(permissionPinned).toBe(true);
369
+ // Permission layer came from HEAD (committed), NOT the tampered working tree.
370
+ expect(readFileSync(join(dest, 'settings.json'), 'utf-8')).toContain('Bash(git*)');
371
+ expect(readFileSync(join(dest, 'settings.json'), 'utf-8')).not.toContain('TAMPERED');
372
+ expect(readFileSync(join(dest, 'hooks', 'guard.sh'), 'utf-8')).not.toContain('TAMPERED');
373
+ // Behavioral layers came from the WORKING TREE (the uncommitted additions show).
374
+ expect(existsSync(join(dest, 'rules', 'wt-only.md'))).toBe(true);
375
+ expect(existsSync(join(dest, 'commands', 'wt-cmd.md'))).toBe(true);
376
+ expect(result.counts.hooks).toBe(2);
377
+ expect(walk(dest).links).toEqual([]);
378
+ });
379
+ it('DEGRADES (warns, skips permission layer) when the git ref is unavailable', () => {
380
+ const root = buildGitFixture();
381
+ const src = join(root, CONFIG_SOURCE);
382
+ writeFileSync(join(src, 'rules', 'wt-only.md'), '# working-tree rule\n');
383
+ const dest = join(root, 'out', '.claude');
384
+ const warnings = [];
385
+ const { permissionPinned } = generateClaudeConfigForBoot({
386
+ permissionRef: 'origin/does-not-exist', repoRoot: root, destRoot: dest,
387
+ configSource: CONFIG_SOURCE, warn: (m) => warnings.push(m),
388
+ });
389
+ expect(permissionPinned).toBe(false);
390
+ expect(warnings.join('\n')).toMatch(/origin-pin/);
391
+ // Non-permission layers still generated from the working tree...
392
+ expect(existsSync(join(dest, 'rules', 'wt-only.md'))).toBe(true);
393
+ // ...but settings.json + hooks are NOT written (committed backstop left in place).
394
+ expect(existsSync(join(dest, 'settings.json'))).toBe(false);
395
+ expect(existsSync(join(dest, 'hooks'))).toBe(false);
396
+ });
397
+ });
398
+ // ── degrade path must not trust the working tree (Red Team CRITICAL B / Major 3) ──
399
+ //
400
+ // An attacker who commits a weakened settings/hooks to the LOCAL checkout and then
401
+ // blocks the origin fetch (rename remote, break DNS) must NOT get their layer kept
402
+ // on boot. The degrade path restores the last ORIGIN-VERIFIED permission layer
403
+ // from ~/.mx-agent/ cache instead. HOME is isolated per-test (see beforeEach), so
404
+ // these exercise a real on-disk cache without touching the real home dir.
405
+ describe('generateClaudeConfigForBoot — degrade restores origin-verified cache (Red Team CRITICAL B)', () => {
406
+ /** Build a trusted (origin-verified) permission source dir and prime the cache. */
407
+ function primeCacheWith(settingsContent) {
408
+ const trusted = mkTmp('mx-genclaude-trusted-');
409
+ writeFileSync(join(trusted, 'settings.json'), settingsContent);
410
+ mkdirSync(join(trusted, 'hooks'), { recursive: true });
411
+ writeFileSync(join(trusted, 'hooks', 'guard.sh'), '#!/bin/bash\necho cached-guard\n');
412
+ refreshPermissionCache(trusted);
413
+ }
414
+ it('with a populated cache, writes the CACHED layer — not the malicious committed one', () => {
415
+ const root = buildGitFixture();
416
+ const src = join(root, CONFIG_SOURCE);
417
+ // Attacker weakens the working-tree + committed permission layer.
418
+ const MALICIOUS = '{"allow":["MALICIOUS-BACKDOOR"],"deny":[]}\n';
419
+ writeFileSync(join(src, 'settings.json'), MALICIOUS);
420
+ writeFileSync(join(src, 'hooks', 'guard.sh'), '#!/bin/bash\necho MALICIOUS\n');
421
+ const g = (args) => spawnSync('git', args, { cwd: root, encoding: 'utf-8' });
422
+ g(['add', '-A']);
423
+ g(['commit', '-q', '-m', 'weaken permission layer']); // HEAD now malicious
424
+ // Prime the cache with a known-good origin-verified layer.
425
+ const BENIGN = '{"allow":["ORIGIN-VERIFIED-BENIGN"],"deny":[]}\n';
426
+ primeCacheWith(BENIGN);
427
+ // Pre-plant a malicious committed backstop on disk (the Phase 2 .claude/).
428
+ const dest = join(root, 'out', '.claude');
429
+ mkdirSync(dest, { recursive: true });
430
+ writeFileSync(join(dest, 'settings.json'), MALICIOUS);
431
+ const warnings = [];
432
+ const { permissionPinned } = generateClaudeConfigForBoot({
433
+ permissionRef: 'origin/does-not-exist', repoRoot: root, destRoot: dest,
434
+ configSource: CONFIG_SOURCE, warn: (m) => warnings.push(m),
435
+ });
436
+ expect(permissionPinned).toBe(false);
437
+ const written = readFileSync(join(dest, 'settings.json'), 'utf-8');
438
+ expect(written).toContain('ORIGIN-VERIFIED-BENIGN'); // cached layer restored
439
+ expect(written).not.toContain('MALICIOUS'); // neither working tree nor committed
440
+ expect(readFileSync(join(dest, 'hooks', 'guard.sh'), 'utf-8')).toContain('cached-guard');
441
+ expect(readFileSync(join(dest, 'hooks', 'guard.sh'), 'utf-8')).not.toContain('MALICIOUS');
442
+ expect(walk(dest).links).toEqual([]);
443
+ });
444
+ it('with NO cache, leaves the committed backstop and warns UNVERIFIED', () => {
445
+ const root = buildGitFixture();
446
+ const dest = join(root, 'out', '.claude');
447
+ // Committed backstop already on disk; cache is empty (fresh isolated HOME).
448
+ mkdirSync(dest, { recursive: true });
449
+ writeFileSync(join(dest, 'settings.json'), '{"allow":["COMMITTED-BACKSTOP"],"deny":[]}\n');
450
+ const warnings = [];
451
+ const { permissionPinned } = generateClaudeConfigForBoot({
452
+ permissionRef: 'origin/does-not-exist', repoRoot: root, destRoot: dest,
453
+ configSource: CONFIG_SOURCE, warn: (m) => warnings.push(m),
454
+ });
455
+ expect(permissionPinned).toBe(false);
456
+ expect(warnings.join('\n')).toContain('UNVERIFIED');
457
+ // Committed backstop left untouched (no cache to restore, working tree not trusted).
458
+ expect(readFileSync(join(dest, 'settings.json'), 'utf-8')).toContain('COMMITTED-BACKSTOP');
459
+ });
460
+ it('with a populated cache whose hash.txt is MISSING, FAILS CLOSED to UNVERIFIED backstop (S1)', () => {
461
+ const root = buildGitFixture();
462
+ // Prime a full cache, then strip its hash.txt (a hash-stripped / partially
463
+ // written cache). Restore must NOT trust it — it falls to the committed backstop.
464
+ primeCacheWith('{"allow":["CACHED-BENIGN"],"deny":[]}\n');
465
+ const hashPath = join(process.env.HOME, '.mx-agent', 'permission-cache', 'hash.txt');
466
+ expect(existsSync(hashPath)).toBe(true);
467
+ rmSync(hashPath, { force: true });
468
+ const dest = join(root, 'out', '.claude');
469
+ mkdirSync(dest, { recursive: true });
470
+ writeFileSync(join(dest, 'settings.json'), '{"allow":["COMMITTED-BACKSTOP"],"deny":[]}\n');
471
+ const warnings = [];
472
+ const { permissionPinned } = generateClaudeConfigForBoot({
473
+ permissionRef: 'origin/does-not-exist', repoRoot: root, destRoot: dest,
474
+ configSource: CONFIG_SOURCE, warn: (m) => warnings.push(m),
475
+ });
476
+ expect(permissionPinned).toBe(false);
477
+ expect(warnings.join('\n')).toContain('UNVERIFIED');
478
+ // Unverified cache rejected: neither the cached bytes nor a rewrite landed.
479
+ const written = readFileSync(join(dest, 'settings.json'), 'utf-8');
480
+ expect(written).toContain('COMMITTED-BACKSTOP');
481
+ expect(written).not.toContain('CACHED-BENIGN');
482
+ });
483
+ });
484
+ //# sourceMappingURL=generate-claude.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-claude.test.js","sourceRoot":"","sources":["../../src/__tests__/generate-claude.test.ts"],"names":[],"mappings":"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"}
@@ -31,3 +31,21 @@ Eval work is decision infrastructure. Treat harness code, fixtures, scoring, ana
31
31
  - Capture what memory was retrieved, shown, ignored, reused, contradicted, or invalidated in each run.
32
32
  - Ask the agent for a brief post-run memory-use reflection when diagnosing memory impact, but do not treat self-report as ground truth.
33
33
  - Check whether memory anchored the agent on a dead end, repeated an invalid patch, or suppressed exploration.
34
+
35
+ ## Real-Artifact Smoke Test (PO directive, 2026-07-09)
36
+
37
+ - Before committing any change that processes existing data (notes, transcripts, per_task rows, patches): execute the changed code path at least once against REAL stored artifacts from a prior run and inspect the output. Synthetic fixtures alone are insufficient — format-mismatch no-fires pass synthetic tests and silently do nothing in production (incident: trap-fix neutralizer, 2026-07-09, 0/22 real payloads fired despite 16 green fixtures).
38
+ - Before any billable fire of a new experiment shape (new retrieval mode, synthetic seeding path, or novel injection mechanism): run a real 1-task end-to-end smoke test — seed, then retrieve, then score — exercising REAL retrieval and a REAL model call, not a $0 structural dry-run. A dry-run that never talks to a real retrieval backend or a real model cannot catch credential gaps or format mismatches between the seed writer and the retrieval reader (incident: reverse-tier experiment, 2026-07-10, KI-REVERSE-TIER-SEED-RETRIEVAL — $0 dry-run validated plan/isolation/cost but missed both a missing-credentials bug and a seed-format vs retrieval-query mismatch; two fires, ~$35 spend, zero usable hypothesis-testing data). The smoke test must exercise the exact run-time retrieval path (e.g., with MX_DISABLE_XTASK=1 if the run uses it), not the verification path.
39
+ - Closeout artifacts (dev-log, ledger, outcomes entries): every factual claim must be checked against its source by someone other than the drafter before publication (Bar Raiser standing recommendation 2026-07-07, PO-endorsed; three fabrication incidents in one closeout).
40
+
41
+ ## In-Flight Run Sampling (PO directive, 2026-07-09)
42
+
43
+ - No scored run goes unobserved until completion. Run scripts/run_health_check.py against the live results dir on a WALL-CLOCK cadence: every 15 minutes from launch, AND within 15 minutes of the FIRST arm-round completing, AND again at ~50% completion. Read one live payload per arm. Partial-round reads are safe by design (only completed rows are compared), so the watch must NOT be gated on the very round-completion that a hung defect would delay — the wall-clock timer is the primary trigger.
44
+ - The check compares error-class rates ACROSS arms WITHIN the same repo family — arm-biased anomalies (one arm losing patches/timeouts at 3x another for the same round+family) are exactly the class of harness defect that invalidates comparisons while looking like a product effect (incident: task-only container names, arm-biased no_patch 29%/20%/1.8%, issue #4000, 2026-07-09 — visible in round-1 data 40 minutes in, discovered hours later).
45
+ - The halt mandate applies to DIFFERENTIAL alerts only (exit 1): same round, same family, a one-sided Fisher exact test on the 2×2 (error-class count vs rest; higher arm vs comparator arm) returns p ≤ 0.05, AND both arms have ≥ 15 completed rows → halt the run (kill drivers) before further spend, then diagnose. Halt FIRST, then diagnose which cause it is. A differential on a memory arm needs a first-pass check against the known baseline no_patch variance (9-22%) and the budget-exhaustion treatment effect before it is treated as a harness defect — but do that diagnosis after halting, not instead of halting.
46
+ - The Fisher gate REPLACED a raw "≥3× ratio, ≥2 occurrences" rule (recalibration #4024, 2026-07-09) after two live false halts on Stage A/B re-pilot: (A) retrypatch 3/22 vs baseline 1/22 — 3.0× ratio but Fisher one-sided p=0.303, benign; (B) memnexus/retrypatch 3/34 vs a baseline arm with a SINGLE completed row (0/1) — a round that had just started. The ≥15-rows-in-BOTH-arms minimum now excludes a just-started comparator arm from comparison entirely (not evidence, not an alert). Calibration: the v2-incident true positives (memnexus 6/22 p=0.011, retrypatch 9/22 p=0.0007 vs baseline 0/22) still halt.
47
+ - DIFFERENTIAL-WATCH band (advisory WARN, no halt): 0.05 < Fisher p ≤ 0.15 — the small-effect / small-sample zone where a real arm bias and benign variance are not yet separable. Loud and listed but never exit 1. The mini-tier contamination signature (retrypatch 3/22 vs baseline 0/22 → p=0.116; 4/32 vs 0/32 → p=0.057) lands here by design; it was caught by offline census, not required to auto-halt.
48
+ - A differential whose HIGHER arm is below the 15-row minimum (but whose comparator is not) is demoted to an advisory WARN ("differential pattern at low n, not halt-worthy"), not a halt.
49
+ - SPIKE findings (any error-class rate >5% in one arm-round-family) are informational WARN, NOT auto-halt: every valid mini-tier run trips this via budget-exhaustion no_patch (baseline arms show 9-22%), so a spike is investigate-but-don't-halt and does not change the exit code. A tripwire that fired on every valid run would be ignored. Advisory WARNs also cover a patch_empty count exceeding the no_patch marker (runner write-path / marker drift) and unparsed result dirs excluded from comparison.
50
+ - Exit-code contract: 0 = clean or spike/advisory-WARN only; 1 = differential (halt); 2 = usage/environment error (missing root, bad args, OR an existing root with 0 per_task.jsonl files — absence of data is never a clean verdict). Torn/partial trailing lines on a live file are skipped, counted, and reported ("N unparsable lines skipped") — informational only; a crash or read race must never masquerade as a halt-worthy alert.
51
+ - The launch monitor must include the health check on its poll cadence, not just process-liveness.
@@ -176,7 +176,11 @@
176
176
  "Bash(git push --force origin main)",
177
177
  "Bash(git push --force origin main *)",
178
178
  "Bash(git push -f origin main)",
179
- "Bash(git push -f origin main *)"
179
+ "Bash(git push -f origin main *)",
180
+ "Write(.claude/settings.json)",
181
+ "Edit(.claude/settings.json)",
182
+ "Write(.claude/hooks/**)",
183
+ "Edit(.claude/hooks/**)"
180
184
  ],
181
185
  "ask": [
182
186
  "Bash(sudo *)",