'use strict'; /** * #2071 — `msd-tools effort sync` crashed in an INSTALLED runtime because * commands.cjs did `require('../../../bin/install.js')`, but the installer only * copies the `msd-core/` subtree into a runtime home — the package-root * `bin/install.js` is never present there, so the require threw MODULE_NOT_FOUND. * * This does a real minimal install into a temp home (the same helper the * golden-parity suite uses) and runs the exact repro from the issue against the * installed shim: `node /msd-core/bin/msd-tools.cjs effort sync`. Pre-fix * this throws `Cannot find module '../../../bin/install.js'`; post-fix the * install-time resolvers live in the shipped sibling * `msd-core/bin/lib/install-effort-resolver.cjs` and the require resolves. * * `--config-dir ` keeps it hermetic (targets the temp install, never the * developer's real ~/.claude); effort sync defaults to dry-run so nothing is written. */ const { test, describe } = require('node:test'); const assert = require('node:assert/strict'); const fs = require('node:fs'); const path = require('node:path'); const os = require('node:os'); const { runNode } = require('./helpers/process-seam.cjs'); const { runMinimalInstall } = require('./helpers/install-shared.cjs'); const { cleanup } = require('./helpers.cjs'); const { PROBE_TIMEOUT_MS } = require('./helpers/timeouts.cjs'); // Absolute path to the built module, spawned in a child process below so the // JSON `cmdEffortSync` writes straight to fd 1 (via io.cjs's writeAllSync) can // actually be captured — overriding process.stdout.write in-process does not // intercept that write. const COMMANDS_CJS = path.join(__dirname, '..', 'msd-core', 'bin', 'lib', 'commands.cjs'); describe('#2071: effort sync runs in an installed runtime (no package-root bin/install.js)', () => { test('effort sync does not crash reaching for the un-shipped bin/install.js', () => { if (process.platform === 'win32') return; // install layout is POSIX-path-shaped const { configDir, root } = runMinimalInstall({ runtime: 'claude', scope: 'global' }); try { // Installed layout invariant: the package-root installer is never copied in. assert.ok(!fs.existsSync(path.join(root, 'bin', 'install.js')), 'installed home must not contain bin/install.js'); assert.ok(!fs.existsSync(path.join(configDir, 'bin', 'install.js')), 'no bin/install.js beside msd-core'); // A project effort config gives the sync something to resolve. fs.mkdirSync(path.join(root, '.planning'), { recursive: true }); fs.writeFileSync( path.join(root, '.planning', 'config.json'), JSON.stringify({ effort: { default: 'high' } }), ); const msdTools = path.join(configDir, 'msd-core', 'bin', 'msd-tools.cjs'); const result = runNode( [msdTools, 'effort', 'sync', '--config-dir', configDir], { cwd: root, env: { ...process.env, HOME: root }, timeoutMs: PROBE_TIMEOUT_MS }, ); const combined = `${result.stdout || ''}${result.stderr || ''}`; assert.doesNotMatch( combined, /Cannot find module[^\n]*install\.js|'\.\.\/\.\.\/\.\.\/bin\/install\.js'/, `effort sync must not reach for the un-shipped bin/install.js:\n${combined}`, ); assert.doesNotMatch( combined, /MODULE_NOT_FOUND/, `effort sync must not crash on module resolution in an installed runtime:\n${combined}`, ); } finally { cleanup(root); } }); }); // #3706 — OpenCode's `effort sync` path (cmdEffortSyncOpencode) maintains the // `variant:` frontmatter key install bakes into `~/.config/opencode/agents/ // msd-*.md`, mirroring the pre-existing claude/`effort:` and codex branches. // Each case is run against a fresh sandbox: a project `cwd` (holding // `.planning/config.json`), a `configDir` (holding `agents/`), and an // isolated `home` (HOME env, so `~/.msd/defaults.json` can never leak in from // the real developer machine) — cmdEffortSync merges home defaults with the // project config, so a hermetic test must control both sources. describe('#3706: effort sync maintains OpenCode variant: frontmatter', () => { function makeSandbox() { const root = fs.mkdtempSync(path.join(os.tmpdir(), 'msd-effort-sync-opencode-')); const cwd = path.join(root, 'project'); const configDir = path.join(root, 'runtime-home'); const agentsDir = path.join(configDir, 'agents'); const home = path.join(root, 'home'); fs.mkdirSync(cwd, { recursive: true }); fs.mkdirSync(agentsDir, { recursive: true }); fs.mkdirSync(home, { recursive: true }); return { root, cwd, configDir, agentsDir, home }; } function writeProjectEffortConfig(cwd, effort) { fs.mkdirSync(path.join(cwd, '.planning'), { recursive: true }); fs.writeFileSync( path.join(cwd, '.planning', 'config.json'), JSON.stringify(effort === undefined ? {} : { effort }), ); } function writeAgent(agentsDir, name, lines) { const filePath = path.join(agentsDir, name); fs.writeFileSync(filePath, lines.join('\n')); return filePath; } /** * Invokes `cmdEffortSync(cwd, false, opts)` in a CHILD process (required * per module — see COMMANDS_CJS comment above) and parses the JSON result * `output()` writes to fd 1. Callers that only need the on-disk effect of * the sync (most cases below) still go through this so the harness stays * single-shaped, but only cases 2 and 6 actually assert on the returned * `result`. */ function runEffortSync({ cwd, home, configDir, runtime, dryRun }) { const opts = { dryRun, configDir, runtime }; const script = [ `const { cmdEffortSync } = require(${JSON.stringify(COMMANDS_CJS)});`, `cmdEffortSync(${JSON.stringify(cwd)}, false, ${JSON.stringify(opts)});`, ].join('\n'); const spawned = runNode(['-e', script], { cwd, env: { ...process.env, HOME: home, USERPROFILE: home }, }); assert.strictEqual( spawned.exitCode, 0, `cmdEffortSync child process failed (outcome=${spawned.outcome}):\nstdout: ${spawned.stdout}\nstderr: ${spawned.stderr}`, ); const jsonStart = spawned.stdout.indexOf('{'); assert.notStrictEqual(jsonStart, -1, `expected JSON output on stdout, got:\n${spawned.stdout}`); return JSON.parse(spawned.stdout.slice(jsonStart)); } test('writes the resolved variant into an agent that has none', () => { // Protects: cmdEffortSyncOpencode's happy-path write — a fresh agent // with no `variant:` key gets the resolved effort injected verbatim. const { root, cwd, configDir, agentsDir, home } = makeSandbox(); try { writeProjectEffortConfig(cwd, { agent_overrides: { 'msd-executor': 'xhigh' } }); const filePath = writeAgent(agentsDir, 'msd-executor.md', [ '---', 'name: msd-executor', 'description: x', 'mode: subagent', '---', '', 'Body.', ]); runEffortSync({ cwd, home, configDir, runtime: 'opencode', dryRun: false }); const content = fs.readFileSync(filePath, 'utf8'); assert.match(content, /^variant: xhigh$/m); } finally { cleanup(root); } }); test('a synced agent keeps its original file mode', () => { // The tmp-file + rename publish does not preserve mode the way an // in-place writeFileSync would — cmdEffortSyncOpencode stat+chmods the // tmp file before the rename specifically to compensate. Mode bits are // not meaningful on Windows (no POSIX permission model), so skip there. if (process.platform === 'win32') return; const { root, cwd, configDir, agentsDir, home } = makeSandbox(); try { writeProjectEffortConfig(cwd, { agent_overrides: { 'msd-executor': 'xhigh' } }); const filePath = writeAgent(agentsDir, 'msd-executor.md', [ '---', 'name: msd-executor', 'description: x', 'mode: subagent', '---', '', 'Body.', ]); fs.chmodSync(filePath, 0o600); runEffortSync({ cwd, home, configDir, runtime: 'opencode', dryRun: false }); const content = fs.readFileSync(filePath, 'utf8'); assert.match(content, /^variant: xhigh$/m, 'the sync must have actually rewritten the file'); assert.strictEqual( fs.statSync(filePath).mode & 0o777, 0o600, 'the published file must keep the original file mode', ); } finally { cleanup(root); } }); test('the temp file is never more permissive than the agent it replaces', () => { // A plain `writeFileSync(tmpPath, data)` creates the tmp file at the // default `0666 & ~umask`, then only tightens it afterward via chmod — // for a 0600 agent that briefly leaves its contents world-readable // inside agents/. Assert the mode is correct at CREATION, not just // after the later chmod, by monkeypatching fs.writeFileSync in the // child process to record the on-disk mode immediately after the real // write runs. Mode bits are not meaningful on Windows, so skip there. if (process.platform === 'win32') return; const { root, cwd, configDir, agentsDir, home } = makeSandbox(); try { writeProjectEffortConfig(cwd, { agent_overrides: { 'msd-executor': 'xhigh' } }); const filePath = writeAgent(agentsDir, 'msd-executor.md', [ '---', 'name: msd-executor', 'description: x', 'mode: subagent', '---', '', 'Body.', ]); fs.chmodSync(filePath, 0o600); const opts = { dryRun: false, configDir, runtime: 'opencode' }; const script = [ "const fs = require('node:fs');", 'const captures = [];', 'const originalWriteFileSync = fs.writeFileSync;', 'fs.writeFileSync = function (targetPath, data, options) {', ' const result = originalWriteFileSync.call(fs, targetPath, data, options);', ' if (typeof targetPath === "string" && /\\.tmp\\.\\d+$/.test(targetPath)) {', ' captures.push({ options: options || null, modeAfterWrite: fs.statSync(targetPath).mode & 0o777 });', ' }', ' return result;', '};', `const { cmdEffortSync } = require(${JSON.stringify(COMMANDS_CJS)});`, `cmdEffortSync(${JSON.stringify(cwd)}, false, ${JSON.stringify(opts)});`, 'process.stdout.write("###CAPTURE_START###" + JSON.stringify(captures) + "###CAPTURE_END###");', ].join('\n'); const spawned = runNode(['-e', script], { cwd, env: { ...process.env, HOME: home, USERPROFILE: home }, }); assert.strictEqual( spawned.exitCode, 0, `capture child process failed (outcome=${spawned.outcome}):\nstdout: ${spawned.stdout}\nstderr: ${spawned.stderr}`, ); const match = /###CAPTURE_START###([\s\S]*?)###CAPTURE_END###/.exec(spawned.stdout); assert.ok(match, `expected capture marker on stdout, got:\n${spawned.stdout}`); const captures = JSON.parse(match[1]); assert.strictEqual(captures.length, 1, `expected exactly one tmp-file write, got:\n${JSON.stringify(captures)}`); // The tmp file's mode immediately after creation must already match // the target agent's 0600, not the default 0644 a bare writeFileSync // would produce. assert.strictEqual( captures[0].modeAfterWrite, 0o600, 'the tmp file must never be created more permissive than the agent it replaces', ); const content = fs.readFileSync(filePath, 'utf8'); assert.match(content, /^variant: xhigh$/m, 'the sync must have actually rewritten the file'); assert.strictEqual(fs.statSync(filePath).mode & 0o777, 0o600, 'the published file must keep the original file mode'); } finally { cleanup(root); } }); test('reports the change without writing under dry run', () => { // Protects: dry-run reports the pending change but leaves the file // byte-identical — no write happens until dryRun is explicitly false. const { root, cwd, configDir, agentsDir, home } = makeSandbox(); try { writeProjectEffortConfig(cwd, { agent_overrides: { 'msd-executor': 'xhigh' } }); const filePath = writeAgent(agentsDir, 'msd-executor.md', [ '---', 'name: msd-executor', 'description: x', 'mode: subagent', '---', '', 'Body.', ]); const before = fs.readFileSync(filePath); const result = runEffortSync({ cwd, home, configDir, runtime: 'opencode', dryRun: true }); const after = fs.readFileSync(filePath); assert.ok(before.equals(after), 'dry run must not touch the file on disk'); assert.strictEqual(result.synced, 1); assert.deepStrictEqual(result.changes[0], { agent: 'msd-executor', from: null, to: 'xhigh' }); } finally { cleanup(root); } }); test('an already-correct agent is skipped, not rewritten', () => { // Protects: an agent already carrying the resolved variant is reported // skipped and its bytes are left completely untouched (no rewrite churn). const { root, cwd, configDir, agentsDir, home } = makeSandbox(); try { writeProjectEffortConfig(cwd, { agent_overrides: { 'msd-executor': 'high' } }); const filePath = writeAgent(agentsDir, 'msd-executor.md', [ '---', 'name: msd-executor', 'description: x', 'mode: subagent', 'variant: high', '---', '', 'Body.', ]); const before = fs.readFileSync(filePath); const result = runEffortSync({ cwd, home, configDir, runtime: 'opencode', dryRun: false }); const after = fs.readFileSync(filePath); assert.ok(before.equals(after), 'an in-sync agent must not be rewritten'); assert.strictEqual(result.skipped, 1); assert.strictEqual(result.synced, 0); } finally { cleanup(root); } }); test('inherit strips the key rather than writing it literally', () => { // #3533 (10d) — inherit means the key must not exist; writing // `variant: inherit` would name a variant that cannot resolve. const { root, cwd, configDir, agentsDir, home } = makeSandbox(); try { writeProjectEffortConfig(cwd, { agent_overrides: { 'msd-executor': 'inherit' } }); const filePath = writeAgent(agentsDir, 'msd-executor.md', [ '---', 'name: msd-executor', 'description: x', 'mode: subagent', 'variant: high', '---', '', 'Body.', ]); const result = runEffortSync({ cwd, home, configDir, runtime: 'opencode', dryRun: false }); const content = fs.readFileSync(filePath, 'utf8'); assert.doesNotMatch(content, /^variant:/m); assert.match(content, /^name: msd-executor$/m); assert.match(content, /^description: x$/m); assert.match(content, /^mode: subagent$/m); assert.deepStrictEqual(result.changes[0], { agent: 'msd-executor', from: 'high', to: null }); } finally { cleanup(root); } }); test('no effort config at all strips a stale key', () => { // Matches what install bakes with no config: an agent that carries a // stale `variant:` key from a prior sync must lose it, not keep it. const { root, cwd, configDir, agentsDir, home } = makeSandbox(); try { writeProjectEffortConfig(cwd, undefined); const filePath = writeAgent(agentsDir, 'msd-executor.md', [ '---', 'name: msd-executor', 'description: x', 'mode: subagent', 'variant: high', '---', '', 'Body.', ]); runEffortSync({ cwd, home, configDir, runtime: 'opencode', dryRun: false }); const content = fs.readFileSync(filePath, 'utf8'); assert.doesNotMatch(content, /^variant:/m); } finally { cleanup(root); } }); test('a missing agents directory is reported, not thrown', () => { // Protects: an install with no agents/ subdir under configDir must // report the condition structurally, never throw out of cmdEffortSync. const { root, cwd, configDir, home } = makeSandbox(); try { cleanup(path.join(configDir, 'agents')); const result = runEffortSync({ cwd, home, configDir, runtime: 'opencode', dryRun: false }); assert.strictEqual(result.reason, 'agents directory not found'); } finally { cleanup(root); } }); test('files that are not msd-*.md are ignored', () => { // Protects: the msd-*.md filter — a non-msd file sitting in agents/ must // never be synced or skipped, i.e. never even enter the loop. const { root, cwd, configDir, agentsDir, home } = makeSandbox(); try { writeProjectEffortConfig(cwd, { agent_overrides: { 'msd-executor': 'xhigh' } }); writeAgent(agentsDir, 'not-msd.md', [ '---', 'name: not-msd', 'description: x', 'mode: subagent', '---', '', 'Body.', ]); const result = runEffortSync({ cwd, home, configDir, runtime: 'opencode', dryRun: false }); assert.strictEqual(result.synced, 0); assert.strictEqual(result.skipped, 0); } finally { cleanup(root); } }); test('the document body is untouched', () => { // Protects: the frontmatter line-editors only ever touch the frontmatter // span — a body containing a colon, a `#`, and a `---` rule must survive // byte-identical past the closing frontmatter delimiter. const { root, cwd, configDir, agentsDir, home } = makeSandbox(); try { writeProjectEffortConfig(cwd, { agent_overrides: { 'msd-executor': 'max' } }); const filePath = writeAgent(agentsDir, 'msd-executor.md', [ '---', 'name: msd-executor', 'description: x', '---', '', 'Body with: colons #hash and a --- rule.', '', 'more.', ]); const before = fs.readFileSync(filePath, 'utf8'); const beforeBody = before.slice(before.indexOf('---', 3) + 3); runEffortSync({ cwd, home, configDir, runtime: 'opencode', dryRun: false }); const after = fs.readFileSync(filePath, 'utf8'); const afterBody = after.slice(after.indexOf('---', 3) + 3); assert.strictEqual(afterBody, beforeBody); assert.match(after, /^variant: max$/m); } finally { cleanup(root); } }); test('a key present with an empty value is removed, not mistaken for absent', () => { // The value regex's `(.+?)` requires at least one character, so a bare // `variant:` line (zero-width value) used to read as "key absent" rather // than "key present, value empty" — presence and value are now distinct // questions, and a stale empty-valued key must still be stripped when no // effort config resolves one. const { root, cwd, configDir, agentsDir, home } = makeSandbox(); try { writeProjectEffortConfig(cwd, undefined); const filePath = writeAgent(agentsDir, 'msd-executor.md', [ '---', 'name: msd-executor', 'description: x', 'mode: subagent', 'variant:', '---', '', 'Body.', ]); runEffortSync({ cwd, home, configDir, runtime: 'opencode', dryRun: false }); const content = fs.readFileSync(filePath, 'utf8'); assert.doesNotMatch(content, /^variant:/m); } finally { cleanup(root); } }); test('a key present with a whitespace-only value is removed too (the spelling that always worked)', () => { // Trailing whitespace after the colon always matched the old regex (it is // not zero-width), so this spelling never exhibited the absent-vs-empty // bug above — pinned as the control that makes the bug look like a // whitespace lottery rather than a real presence/value distinction. const { root, cwd, configDir, agentsDir, home } = makeSandbox(); try { writeProjectEffortConfig(cwd, undefined); const filePath = writeAgent(agentsDir, 'msd-executor.md', [ '---', 'name: msd-executor', 'description: x', 'mode: subagent', 'variant: ', '---', '', 'Body.', ]); runEffortSync({ cwd, home, configDir, runtime: 'opencode', dryRun: false }); const content = fs.readFileSync(filePath, 'utf8'); assert.doesNotMatch(content, /^variant:/m); } finally { cleanup(root); } }); test('CRLF agents keep their line endings through a write and a strip', () => { // Key-parameterising the frontmatter editors (claude's effort: vs // opencode's variant:) is exactly the kind of change that would regress // CRLF handling if the line ending were baked in per-key rather than // detected from the matched frontmatter block. const { root, cwd, configDir, agentsDir, home } = makeSandbox(); try { writeProjectEffortConfig(cwd, { agent_overrides: { 'msd-executor': 'xhigh' } }); const filePath = path.join(agentsDir, 'msd-executor.md'); const beforeWrite = [ '---', 'name: msd-executor', 'description: x', 'mode: subagent', '---', '', 'Body.', ].join('\r\n'); fs.writeFileSync(filePath, beforeWrite); runEffortSync({ cwd, home, configDir, runtime: 'opencode', dryRun: false }); const afterWrite = fs.readFileSync(filePath, 'utf8'); assert.match(afterWrite, /^variant: xhigh\r$/m); assert.doesNotMatch(afterWrite, /(? { // A symlinked msd-*.md must never have its TARGET file rewritten — the // sync must skip it structurally (readdir's Dirent reports a symlink // entry as not-a-file), not follow it and edit whatever it points to. const { root, cwd, configDir, agentsDir, home } = makeSandbox(); try { const targetPath = path.join(root, 'outside-target.md'); const targetContent = [ '---', 'name: msd-executor', 'description: x', 'mode: subagent', '---', '', 'Body.', ].join('\n'); fs.writeFileSync(targetPath, targetContent); const linkPath = path.join(agentsDir, 'msd-executor.md'); try { fs.symlinkSync(targetPath, linkPath); } catch { return; // platform cannot create symlinks (e.g. unprivileged Windows) — skip } writeProjectEffortConfig(cwd, { agent_overrides: { 'msd-executor': 'xhigh' } }); runEffortSync({ cwd, home, configDir, runtime: 'opencode', dryRun: false }); const after = fs.readFileSync(targetPath, 'utf8'); assert.strictEqual(after, targetContent, 'the symlink target must be left untouched'); } finally { cleanup(root); } }); test('a body line starting with variant: is never the line edited', () => { // Scoping-by-content, not a whole-file /m replace: a body line that // happens to start with `variant:` must survive untouched while the // frontmatter gains its own key. const { root, cwd, configDir, agentsDir, home } = makeSandbox(); try { writeProjectEffortConfig(cwd, { agent_overrides: { 'msd-executor': 'xhigh' } }); const filePath = writeAgent(agentsDir, 'msd-executor.md', [ '---', 'name: msd-executor', 'description: x', 'mode: subagent', '---', '', 'variant: in-the-body', '', 'more.', ]); runEffortSync({ cwd, home, configDir, runtime: 'opencode', dryRun: false }); const content = fs.readFileSync(filePath, 'utf8'); assert.ok(content.includes('variant: in-the-body'), 'the body line must survive untouched'); const fmEnd = content.indexOf('\n---', 4); assert.match(content.slice(0, fmEnd), /^variant: xhigh$/m, 'the frontmatter must gain its own variant: line'); } finally { cleanup(root); } }); test('a file with no frontmatter at all is skipped, not corrupted', () => { // No `---` fences at all: the sync must leave the file byte-identical // rather than guessing where a frontmatter block would go. const { root, cwd, configDir, agentsDir, home } = makeSandbox(); try { writeProjectEffortConfig(cwd, { agent_overrides: { 'msd-executor': 'xhigh' } }); const filePath = writeAgent(agentsDir, 'msd-executor.md', [ 'Just a body, no frontmatter fences at all.', ]); const before = fs.readFileSync(filePath); runEffortSync({ cwd, home, configDir, runtime: 'opencode', dryRun: false }); const after = fs.readFileSync(filePath); assert.ok(before.equals(after), 'a file with no frontmatter must be byte-identical afterward'); } finally { cleanup(root); } }); test('the claude path still writes effort:, not variant:', () => { // The frontmatter line-editors were key-parameterised for #3706; this is // the control that the pre-existing claude behavior did not move. const { root, cwd, configDir, agentsDir, home } = makeSandbox(); try { writeProjectEffortConfig(cwd, { agent_overrides: { 'msd-executor': 'xhigh' } }); const filePath = writeAgent(agentsDir, 'msd-executor.md', [ '---', 'name: msd-executor', 'description: x', 'mode: subagent', '---', '', 'Body.', ]); runEffortSync({ cwd, home, configDir, runtime: 'claude', dryRun: false }); const content = fs.readFileSync(filePath, 'utf8'); assert.match(content, /^effort: xhigh$/m); assert.doesNotMatch(content, /^variant:/m); } finally { cleanup(root); } }); test('a claude read failure reports failed without changing the result shape', () => { // Protects: the claude branch of cmdEffortSync deliberately does NOT gain // a `read_failures` key on a read failure — that result shape // (`{synced, skipped, changes, dry_run, agents_dir}`) is long-standing // and widely consumed. The failure is surfaced only through output()'s // third argument (the raw-mode summary token), which is never merged // into the JSON object. Asserts both halves: the raw token is 'failed', // and the JSON result's key set is exactly the historic five, with no // read_failures/write_failures key added. const { root, cwd, configDir, agentsDir, home } = makeSandbox(); try { writeProjectEffortConfig(cwd, { agent_overrides: { 'msd-unreadable': 'xhigh' } }); writeAgent(agentsDir, 'msd-unreadable.md', [ '---', 'name: msd-unreadable', 'description: x', 'mode: subagent', '---', '', 'Body.', ]); const opts = { dryRun: false, configDir, runtime: 'claude' }; const makeScript = raw => [ `const fs = require('node:fs');`, `const originalReadFileSync = fs.readFileSync;`, `fs.readFileSync = function (targetPath, ...rest) {`, ` if (typeof targetPath === 'string' && targetPath.includes('msd-unreadable.md')) {`, ` throw new Error('injected read failure');`, ` }`, ` return originalReadFileSync.call(fs, targetPath, ...rest);`, `};`, `const { cmdEffortSync } = require(${JSON.stringify(COMMANDS_CJS)});`, `cmdEffortSync(${JSON.stringify(cwd)}, ${raw}, ${JSON.stringify(opts)});`, ].join('\n'); const jsonRun = runNode(['-e', makeScript(false)], { cwd, env: { ...process.env, HOME: home, USERPROFILE: home }, }); assert.strictEqual( jsonRun.exitCode, 0, `cmdEffortSync child process failed (outcome=${jsonRun.outcome}):\nstdout: ${jsonRun.stdout}\nstderr: ${jsonRun.stderr}`, ); const jsonStart = jsonRun.stdout.indexOf('{'); assert.notStrictEqual(jsonStart, -1, `expected JSON output on stdout, got:\n${jsonRun.stdout}`); const result = JSON.parse(jsonRun.stdout.slice(jsonStart)); assert.strictEqual(result.skipped, 1); assert.deepStrictEqual( Object.keys(result).sort(), ['agents_dir', 'changes', 'dry_run', 'skipped', 'synced'], 'the claude result shape must gain no read_failures/write_failures key', ); const rawRun = runNode(['-e', makeScript(true)], { cwd, env: { ...process.env, HOME: home, USERPROFILE: home }, }); assert.strictEqual( rawRun.exitCode, 0, `cmdEffortSync child process failed (outcome=${rawRun.outcome}):\nstdout: ${rawRun.stdout}\nstderr: ${rawRun.stderr}`, ); assert.strictEqual(rawRun.stdout.trim(), 'failed', `expected the raw summary token 'failed', got:\n${rawRun.stdout}`); } finally { cleanup(root); } }); test('a claude write failure is reported and does not abort the sweep', () => { // Protects: the claude branch's fs.writeFileSync (both the inherit/strip // call site and the concrete/set call site) used to sit outside any try, // so a single unwritable agent file threw and aborted the entire sweep. // Injected deterministically by monkeypatching fs.writeFileSync inside // the child script for exactly ONE agent's path — per this repo's // CLAUDE.md §4, chmod-based injection is forbidden (root bypasses mode // bits under Docker/CI and it leaks resources). const { root, cwd, configDir, agentsDir, home } = makeSandbox(); try { writeProjectEffortConfig(cwd, { agent_overrides: { 'msd-broken': 'xhigh', 'msd-executor': 'xhigh' } }); const brokenPath = writeAgent(agentsDir, 'msd-broken.md', [ '---', 'name: msd-broken', 'description: x', 'mode: subagent', '---', '', 'Body.', ]); const okPath = writeAgent(agentsDir, 'msd-executor.md', [ '---', 'name: msd-executor', 'description: x', 'mode: subagent', '---', '', 'Body.', ]); const brokenBefore = fs.readFileSync(brokenPath); const opts = { dryRun: false, configDir, runtime: 'claude' }; const makeScript = raw => [ `const fs = require('node:fs');`, `const originalWriteFileSync = fs.writeFileSync;`, `fs.writeFileSync = function (targetPath, ...rest) {`, ` if (typeof targetPath === 'string' && targetPath.includes('msd-broken.md')) {`, ` throw new Error('injected write failure');`, ` }`, ` return originalWriteFileSync.call(fs, targetPath, ...rest);`, `};`, `const { cmdEffortSync } = require(${JSON.stringify(COMMANDS_CJS)});`, `cmdEffortSync(${JSON.stringify(cwd)}, ${raw}, ${JSON.stringify(opts)});`, ].join('\n'); const jsonRun = runNode(['-e', makeScript(false)], { cwd, env: { ...process.env, HOME: home, USERPROFILE: home }, }); assert.strictEqual( jsonRun.exitCode, 0, `cmdEffortSync child process failed (outcome=${jsonRun.outcome}):\nstdout: ${jsonRun.stdout}\nstderr: ${jsonRun.stderr}`, ); const jsonStart = jsonRun.stdout.indexOf('{'); assert.notStrictEqual(jsonStart, -1, `expected JSON output on stdout, got:\n${jsonRun.stdout}`); const result = JSON.parse(jsonRun.stdout.slice(jsonStart)); assert.strictEqual(result.skipped, 1); assert.deepStrictEqual( Object.keys(result).sort(), ['agents_dir', 'changes', 'dry_run', 'skipped', 'synced'], 'the claude result shape must gain no read_failures/write_failures key', ); const brokenAfter = fs.readFileSync(brokenPath); assert.ok(brokenBefore.equals(brokenAfter), 'the failing agent file must be byte-unchanged'); const okContent = fs.readFileSync(okPath, 'utf8'); assert.match(okContent, /^effort: xhigh$/m, 'the sweep must continue past the failing agent'); const rawRun = runNode(['-e', makeScript(true)], { cwd, env: { ...process.env, HOME: home, USERPROFILE: home }, }); assert.strictEqual( rawRun.exitCode, 0, `cmdEffortSync child process failed (outcome=${rawRun.outcome}):\nstdout: ${rawRun.stdout}\nstderr: ${rawRun.stderr}`, ); assert.strictEqual(rawRun.stdout.trim(), 'failed', `expected the raw summary token 'failed', got:\n${rawRun.stdout}`); } finally { cleanup(root); } }); test('a claude agent survives a fault mid-publish', () => { // Protects: the claude branch now publishes atomically (tmp-write + // chmod + retryRenameSync), same discipline as cmdEffortSyncOpencode. An // ENOSPC-mid-write injected on the TMP path must never truncate or empty // the real agent file — pre-fix, an in-place `writeFileSync(filePath, // ...)` truncates via O_TRUNC before the fault, leaving the file empty. // Injected deterministically by monkeypatching fs.writeFileSync inside // the child script for exactly the `.tmp.` path — per this repo's // CLAUDE.md §4, chmod-based injection is forbidden (root bypasses mode // bits under Docker/CI and it leaks resources). const { root, cwd, configDir, agentsDir, home } = makeSandbox(); try { writeProjectEffortConfig(cwd, { agent_overrides: { 'msd-executor': 'xhigh' } }); const filePath = writeAgent(agentsDir, 'msd-executor.md', [ '---', 'name: msd-executor', 'description: x', 'mode: subagent', '---', '', 'Body.', ]); const before = fs.readFileSync(filePath); const opts = { dryRun: false, configDir, runtime: 'claude' }; const makeScript = raw => [ `const fs = require('node:fs');`, `const originalWriteFileSync = fs.writeFileSync;`, // cmdEffortSync's claude branch writes to `.tmp.` // before renaming over the real path — throw only for that tmp // write, simulating an ENOSPC fault after the original file has // already been truncated by a naive in-place write (which this // atomic-publish path no longer performs). `fs.writeFileSync = function (targetPath, ...rest) {`, ` if (typeof targetPath === 'string' && targetPath.includes('msd-executor.md.tmp.')) {`, ` throw new Error('injected ENOSPC mid-write');`, ` }`, ` return originalWriteFileSync.call(fs, targetPath, ...rest);`, `};`, `const { cmdEffortSync } = require(${JSON.stringify(COMMANDS_CJS)});`, `cmdEffortSync(${JSON.stringify(cwd)}, ${raw}, ${JSON.stringify(opts)});`, ].join('\n'); const jsonRun = runNode(['-e', makeScript(false)], { cwd, env: { ...process.env, HOME: home, USERPROFILE: home }, }); assert.strictEqual( jsonRun.exitCode, 0, `cmdEffortSync child process failed (outcome=${jsonRun.outcome}):\nstdout: ${jsonRun.stdout}\nstderr: ${jsonRun.stderr}`, ); const after = fs.readFileSync(filePath); assert.ok(before.equals(after), 'the original agent file must be byte-identical after a fault mid-publish'); const leftoverTmp = fs.readdirSync(agentsDir).filter(f => f.includes('.tmp.')); assert.deepStrictEqual(leftoverTmp, [], `no orphan tmp file must remain in agents_dir, found: ${leftoverTmp.join(', ')}`); const rawRun = runNode(['-e', makeScript(true)], { cwd, env: { ...process.env, HOME: home, USERPROFILE: home }, }); assert.strictEqual( rawRun.exitCode, 0, `cmdEffortSync child process failed (outcome=${rawRun.outcome}):\nstdout: ${rawRun.stdout}\nstderr: ${rawRun.stderr}`, ); assert.strictEqual(rawRun.stdout.trim(), 'failed', `expected the raw summary token 'failed', got:\n${rawRun.stdout}`); } finally { cleanup(root); } }); test('a claude sync preserves the agent file mode', () => { // The tmp-file + rename publish does not preserve mode the way an // in-place writeFileSync would — cmdEffortSync's claude branch // stat+chmods the tmp file before the rename specifically to compensate, // mirroring cmdEffortSyncOpencode. Mode bits are not meaningful on // Windows (no POSIX permission model), so skip there. if (process.platform === 'win32') return; const { root, cwd, configDir, agentsDir, home } = makeSandbox(); try { writeProjectEffortConfig(cwd, { agent_overrides: { 'msd-executor': 'xhigh' } }); const filePath = writeAgent(agentsDir, 'msd-executor.md', [ '---', 'name: msd-executor', 'description: x', 'mode: subagent', '---', '', 'Body.', ]); fs.chmodSync(filePath, 0o600); runEffortSync({ cwd, home, configDir, runtime: 'claude', dryRun: false }); const content = fs.readFileSync(filePath, 'utf8'); assert.match(content, /^effort: xhigh$/m, 'the sync must have actually rewritten the file'); assert.strictEqual( fs.statSync(filePath).mode & 0o777, 0o600, 'the published file must keep the original file mode', ); } finally { cleanup(root); } }); test('effort values are written unquoted', () => { // Control for the shared-escaping fix: setFrontmatterKeyLine now routes // through the same agentScalarNeedsDoubleQuoting/escapeDoubleQuoted // helpers the install-side frontmatterScalar writer uses, but every // effort level the sync actually writes today is a plain scalar — the // output must stay byte-identical (unquoted) across runtimes/levels. for (const level of ['low', 'xhigh']) { const { root, cwd, configDir, agentsDir, home } = makeSandbox(); try { writeProjectEffortConfig(cwd, { agent_overrides: { 'msd-executor': level } }); const claudePath = writeAgent(agentsDir, 'msd-executor.md', [ '---', 'name: msd-executor', 'description: x', 'mode: subagent', '---', '', 'Body.', ]); runEffortSync({ cwd, home, configDir, runtime: 'claude', dryRun: false }); const claudeContent = fs.readFileSync(claudePath, 'utf8'); assert.match(claudeContent, new RegExp(`^effort: ${level}$`, 'm')); assert.doesNotMatch(claudeContent, /^effort: "/m); } finally { cleanup(root); } const { root: root2, cwd: cwd2, configDir: configDir2, agentsDir: agentsDir2, home: home2 } = makeSandbox(); try { writeProjectEffortConfig(cwd2, { agent_overrides: { 'msd-executor': level } }); const opencodePath = writeAgent(agentsDir2, 'msd-executor.md', [ '---', 'name: msd-executor', 'description: x', 'mode: subagent', '---', '', 'Body.', ]); runEffortSync({ cwd: cwd2, home: home2, configDir: configDir2, runtime: 'opencode', dryRun: false }); const opencodeContent = fs.readFileSync(opencodePath, 'utf8'); assert.match(opencodeContent, new RegExp(`^variant: ${level}$`, 'm')); assert.doesNotMatch(opencodeContent, /^variant: "/m); } finally { cleanup(root2); } } }); test('a write failure on one agent is reported and does not stop the sweep', () => { // Protects: cmdEffortSyncOpencode's atomic tmp-write + rename can fail // mid-sync (fs fault). The failure must be reported per-agent in // write_failures, the remaining agents must still be processed, the // failing agent's file must be byte-unchanged, and cmdEffortSync must // never throw. Injected deterministically by monkeypatching // fs.writeFileSync inside the child script — per this repo's CLAUDE.md // §4, chmod-based injection is forbidden (root bypasses mode bits under // Docker/CI and it leaks resources). const { root, cwd, configDir, agentsDir, home } = makeSandbox(); try { writeProjectEffortConfig(cwd, { agent_overrides: { 'msd-broken': 'xhigh', 'msd-executor': 'xhigh' } }); const brokenPath = writeAgent(agentsDir, 'msd-broken.md', [ '---', 'name: msd-broken', 'description: x', 'mode: subagent', '---', '', 'Body.', ]); const okPath = writeAgent(agentsDir, 'msd-executor.md', [ '---', 'name: msd-executor', 'description: x', 'mode: subagent', '---', '', 'Body.', ]); const brokenBefore = fs.readFileSync(brokenPath); const opts = { dryRun: false, configDir, runtime: 'opencode' }; const script = [ `const fs = require('node:fs');`, `const originalWriteFileSync = fs.writeFileSync;`, // The tmp-write + rename publish (cmdEffortSyncOpencode) writes to // `.tmp.` before renaming over the real path — throw // only for that one agent's tmp file, so every other write (and any // fs machinery the require chain itself performs) passes through // unmodified. `fs.writeFileSync = function (targetPath, ...rest) {`, ` if (typeof targetPath === 'string' && targetPath.includes('msd-broken.md.tmp.')) {`, ` throw new Error('injected write failure');`, ` }`, ` return originalWriteFileSync.call(fs, targetPath, ...rest);`, `};`, `const { cmdEffortSync } = require(${JSON.stringify(COMMANDS_CJS)});`, `cmdEffortSync(${JSON.stringify(cwd)}, false, ${JSON.stringify(opts)});`, ].join('\n'); const spawned = runNode(['-e', script], { cwd, env: { ...process.env, HOME: home, USERPROFILE: home }, }); assert.strictEqual( spawned.exitCode, 0, `cmdEffortSync child process failed (outcome=${spawned.outcome}):\nstdout: ${spawned.stdout}\nstderr: ${spawned.stderr}`, ); const jsonStart = spawned.stdout.indexOf('{'); assert.notStrictEqual(jsonStart, -1, `expected JSON output on stdout, got:\n${spawned.stdout}`); const result = JSON.parse(spawned.stdout.slice(jsonStart)); assert.strictEqual(result.write_failures.length, 1); assert.strictEqual(result.write_failures[0].agent, 'msd-broken'); const brokenAfter = fs.readFileSync(brokenPath); assert.ok(brokenBefore.equals(brokenAfter), 'the failing agent file must be byte-unchanged'); const okContent = fs.readFileSync(okPath, 'utf8'); assert.match(okContent, /^variant: xhigh$/m, 'the sweep must continue past the failing agent'); } finally { cleanup(root); } }); test('an unreadable agent file is reported and does not abort the sweep', () => { // Protects: cmdEffortSyncOpencode's fs.readFileSync used to sit outside // any try, so a single unreadable agent file threw and aborted the // entire sweep, unlike the write path in the same loop which degrades // into write_failures. Injected deterministically by monkeypatching // fs.readFileSync inside the child script — per this repo's CLAUDE.md // §4, chmod-based injection is forbidden (root bypasses mode bits under // Docker/CI and it leaks resources). const { root, cwd, configDir, agentsDir, home } = makeSandbox(); try { writeProjectEffortConfig(cwd, { agent_overrides: { 'msd-unreadable': 'xhigh', 'msd-executor': 'xhigh' } }); writeAgent(agentsDir, 'msd-unreadable.md', [ '---', 'name: msd-unreadable', 'description: x', 'mode: subagent', '---', '', 'Body.', ]); const okPath = writeAgent(agentsDir, 'msd-executor.md', [ '---', 'name: msd-executor', 'description: x', 'mode: subagent', '---', '', 'Body.', ]); const opts = { dryRun: false, configDir, runtime: 'opencode' }; const script = [ `const fs = require('node:fs');`, `const originalReadFileSync = fs.readFileSync;`, `fs.readFileSync = function (targetPath, ...rest) {`, ` if (typeof targetPath === 'string' && targetPath.includes('msd-unreadable.md')) {`, ` throw new Error('injected read failure');`, ` }`, ` return originalReadFileSync.call(fs, targetPath, ...rest);`, `};`, `const { cmdEffortSync } = require(${JSON.stringify(COMMANDS_CJS)});`, `cmdEffortSync(${JSON.stringify(cwd)}, false, ${JSON.stringify(opts)});`, ].join('\n'); const spawned = runNode(['-e', script], { cwd, env: { ...process.env, HOME: home, USERPROFILE: home }, }); assert.strictEqual( spawned.exitCode, 0, `cmdEffortSync child process failed (outcome=${spawned.outcome}):\nstdout: ${spawned.stdout}\nstderr: ${spawned.stderr}`, ); const jsonStart = spawned.stdout.indexOf('{'); assert.notStrictEqual(jsonStart, -1, `expected JSON output on stdout, got:\n${spawned.stdout}`); const result = JSON.parse(spawned.stdout.slice(jsonStart)); assert.strictEqual(result.read_failures.length, 1); assert.strictEqual(result.read_failures[0].agent, 'msd-unreadable'); const okContent = fs.readFileSync(okPath, 'utf8'); assert.match(okContent, /^variant: xhigh$/m, 'the sweep must continue past the unreadable agent'); } finally { cleanup(root); } }); test('the summary reports failed when an opencode write could not complete', () => { // Protects: the raw-mode summary TOKEN cmdEffortSync passes as output()'s // third argument (never merged into the JSON object — io.cts `output()` // only reads it when `raw === true`, entirely replacing the JSON // payload) must flip to 'failed' when a write_failures entry exists, even // though the JSON result itself carries no such flag. Captured by // running the child with `raw: true` and asserting on the literal stdout // text `output()` writes for that mode, not on parsed JSON. const { root, cwd, configDir, agentsDir, home } = makeSandbox(); try { writeProjectEffortConfig(cwd, { agent_overrides: { 'msd-broken': 'xhigh' } }); writeAgent(agentsDir, 'msd-broken.md', [ '---', 'name: msd-broken', 'description: x', 'mode: subagent', '---', '', 'Body.', ]); const opts = { dryRun: false, configDir, runtime: 'opencode' }; const script = [ `const fs = require('node:fs');`, `const originalWriteFileSync = fs.writeFileSync;`, `fs.writeFileSync = function (targetPath, ...rest) {`, ` if (typeof targetPath === 'string' && targetPath.includes('msd-broken.md.tmp.')) {`, ` throw new Error('injected write failure');`, ` }`, ` return originalWriteFileSync.call(fs, targetPath, ...rest);`, `};`, `const { cmdEffortSync } = require(${JSON.stringify(COMMANDS_CJS)});`, `cmdEffortSync(${JSON.stringify(cwd)}, true, ${JSON.stringify(opts)});`, ].join('\n'); const spawned = runNode(['-e', script], { cwd, env: { ...process.env, HOME: home, USERPROFILE: home }, }); assert.strictEqual( spawned.exitCode, 0, `cmdEffortSync child process failed (outcome=${spawned.outcome}):\nstdout: ${spawned.stdout}\nstderr: ${spawned.stderr}`, ); assert.strictEqual(spawned.stdout.trim(), 'failed', `expected the raw summary token 'failed', got:\n${spawned.stdout}`); } finally { cleanup(root); } }); }); // ADR-2313 D7 (#3243) — the Codex branch (cmdEffortSyncCodex) strips a stale // Anthropic-flavored `model` pin (and its coupled `model_reasoning_effort`) // from every installed `~/.codex/agents/.toml`, publishing via the same // tmp-file + chmod + retryRenameSync discipline as the OpenCode branch above. describe('#3243: effort sync strips Anthropic-flavored model pins from Codex agents', () => { function makeSandbox() { const root = fs.mkdtempSync(path.join(os.tmpdir(), 'msd-effort-sync-codex-')); const cwd = path.join(root, 'project'); const configDir = path.join(root, 'runtime-home'); const agentsDir = path.join(configDir, 'agents'); const home = path.join(root, 'home'); fs.mkdirSync(cwd, { recursive: true }); fs.mkdirSync(agentsDir, { recursive: true }); fs.mkdirSync(home, { recursive: true }); return { root, cwd, configDir, agentsDir, home }; } function writeAgent(agentsDir, name, lines) { const filePath = path.join(agentsDir, name); fs.writeFileSync(filePath, lines.join('\n')); return filePath; } test('a synced codex agent keeps its original file mode', () => { // The tmp-file + rename publish does not preserve mode the way an // in-place writeFileSync would — cmdEffortSyncCodex stat+chmods the tmp // file before the rename specifically to compensate, same discipline as // the OpenCode branch. Mode bits are not meaningful on Windows, so skip // there. The reachable rewrite path is the Anthropic-model-strip: a // `.toml` agent carrying an Anthropic-flavored `model` value. if (process.platform === 'win32') return; const { root, cwd, configDir, agentsDir, home } = makeSandbox(); try { const before = ['model = "claude-sonnet-4"', 'model_reasoning_effort = "high"', ''].join('\n'); const filePath = writeAgent(agentsDir, 'msd-executor.toml', [before]); fs.chmodSync(filePath, 0o600); const opts = { dryRun: false, configDir, runtime: 'codex' }; const script = [ `const { cmdEffortSync } = require(${JSON.stringify(COMMANDS_CJS)});`, `cmdEffortSync(${JSON.stringify(cwd)}, false, ${JSON.stringify(opts)});`, ].join('\n'); const spawned = runNode(['-e', script], { cwd, env: { ...process.env, HOME: home, USERPROFILE: home }, }); assert.strictEqual( spawned.exitCode, 0, `cmdEffortSync child process failed (outcome=${spawned.outcome}):\nstdout: ${spawned.stdout}\nstderr: ${spawned.stderr}`, ); const after = fs.readFileSync(filePath, 'utf8'); assert.notStrictEqual(after, before, 'the sync must have actually rewritten the file'); assert.doesNotMatch(after, /claude/i, 'the Anthropic-flavored model pin must have been stripped'); assert.strictEqual( fs.statSync(filePath).mode & 0o777, 0o600, 'the published file must keep the original file mode', ); } finally { cleanup(root); } }); test('an unreadable codex agent is reported and does not abort the sweep', () => { // Protects: cmdEffortSyncCodex's fs.readFileSync used to sit outside any // try, so a single unreadable agent file would throw and abort the // entire sweep instead of degrading into read_failures like the write // path in the same loop. Injected deterministically by monkeypatching // fs.readFileSync inside the child script — per this repo's CLAUDE.md // §4, chmod-based injection is forbidden (root bypasses mode bits under // Docker/CI and it leaks resources). The Anthropic-flavored `model` pin // is the reachable codex rewrite path (verified by execution above), so // the sibling agent uses that fixture to prove it still gets rewritten. const { root, cwd, configDir, agentsDir, home } = makeSandbox(); try { writeAgent(agentsDir, 'msd-unreadable.toml', [ 'model = "claude-sonnet-4"', 'model_reasoning_effort = "high"', '', ]); const okPath = writeAgent(agentsDir, 'msd-ok.toml', [ 'model = "claude-sonnet-4"', 'model_reasoning_effort = "high"', '', ]); const okBefore = fs.readFileSync(okPath, 'utf8'); const opts = { dryRun: false, configDir, runtime: 'codex' }; const script = [ `const fs = require('node:fs');`, `const originalReadFileSync = fs.readFileSync;`, `fs.readFileSync = function (targetPath, ...rest) {`, ` if (typeof targetPath === 'string' && targetPath.includes('msd-unreadable.toml')) {`, ` throw new Error('injected read failure');`, ` }`, ` return originalReadFileSync.call(fs, targetPath, ...rest);`, `};`, `const { cmdEffortSync } = require(${JSON.stringify(COMMANDS_CJS)});`, `cmdEffortSync(${JSON.stringify(cwd)}, false, ${JSON.stringify(opts)});`, ].join('\n'); const spawned = runNode(['-e', script], { cwd, env: { ...process.env, HOME: home, USERPROFILE: home }, }); assert.strictEqual( spawned.exitCode, 0, `cmdEffortSync child process failed (outcome=${spawned.outcome}):\nstdout: ${spawned.stdout}\nstderr: ${spawned.stderr}`, ); const jsonStart = spawned.stdout.indexOf('{'); assert.notStrictEqual(jsonStart, -1, `expected JSON output on stdout, got:\n${spawned.stdout}`); const result = JSON.parse(spawned.stdout.slice(jsonStart)); assert.strictEqual(result.read_failures.length, 1); assert.strictEqual(result.read_failures[0].agent, 'msd-unreadable'); const okAfter = fs.readFileSync(okPath, 'utf8'); assert.notStrictEqual(okAfter, okBefore, 'the sweep must continue past the unreadable agent and still rewrite the sibling'); assert.doesNotMatch(okAfter, /claude/i, 'the sibling agent must have had its Anthropic-flavored model pin stripped'); } finally { cleanup(root); } }); test('the summary reports failed when a codex sync could not complete', () => { // Protects: same raw-mode summary TOKEN contract as the opencode case // above — output()'s third argument is never merged into the JSON // object, so a raw-mode caller can only see the failure via this token. // Captured the same way: run with `raw: true` and assert on the literal // stdout text, not on parsed JSON. const { root, cwd, configDir, agentsDir, home } = makeSandbox(); try { writeAgent(agentsDir, 'msd-unreadable.toml', [ 'model = "claude-sonnet-4"', 'model_reasoning_effort = "high"', '', ]); const opts = { dryRun: false, configDir, runtime: 'codex' }; const script = [ `const fs = require('node:fs');`, `const originalReadFileSync = fs.readFileSync;`, `fs.readFileSync = function (targetPath, ...rest) {`, ` if (typeof targetPath === 'string' && targetPath.includes('msd-unreadable.toml')) {`, ` throw new Error('injected read failure');`, ` }`, ` return originalReadFileSync.call(fs, targetPath, ...rest);`, `};`, `const { cmdEffortSync } = require(${JSON.stringify(COMMANDS_CJS)});`, `cmdEffortSync(${JSON.stringify(cwd)}, true, ${JSON.stringify(opts)});`, ].join('\n'); const spawned = runNode(['-e', script], { cwd, env: { ...process.env, HOME: home, USERPROFILE: home }, }); assert.strictEqual( spawned.exitCode, 0, `cmdEffortSync child process failed (outcome=${spawned.outcome}):\nstdout: ${spawned.stdout}\nstderr: ${spawned.stderr}`, ); assert.strictEqual(spawned.stdout.trim(), 'failed', `expected the raw summary token 'failed', got:\n${spawned.stdout}`); } finally { cleanup(root); } }); }); // #3706 — setFrontmatterKeyLine / removeFrontmatterKeyLine are not exported // directly; they are reached through the exported cmdEffortSync (claude // runtime, `effort:` key), the only public entry point that exercises them. describe('#3706: frontmatter line editors are scoped to the matched block', () => { function makeSandbox() { const root = fs.mkdtempSync(path.join(os.tmpdir(), 'msd-effort-sync-fm-scope-')); const cwd = path.join(root, 'project'); const configDir = path.join(root, 'runtime-home'); const agentsDir = path.join(configDir, 'agents'); const home = path.join(root, 'home'); fs.mkdirSync(cwd, { recursive: true }); fs.mkdirSync(agentsDir, { recursive: true }); fs.mkdirSync(home, { recursive: true }); return { root, cwd, configDir, agentsDir, home }; } function writeProjectEffortConfig(cwd, override) { fs.mkdirSync(path.join(cwd, '.planning'), { recursive: true }); fs.writeFileSync( path.join(cwd, '.planning', 'config.json'), JSON.stringify({ effort: { agent_overrides: { 'msd-executor': override } } }), ); } function runEffortSync({ cwd, home, configDir }) { const opts = { dryRun: false, configDir, runtime: 'claude' }; const script = [ `const { cmdEffortSync } = require(${JSON.stringify(COMMANDS_CJS)});`, `cmdEffortSync(${JSON.stringify(cwd)}, false, ${JSON.stringify(opts)});`, ].join('\n'); const spawned = runNode(['-e', script], { cwd, env: { ...process.env, HOME: home, USERPROFILE: home }, }); assert.strictEqual( spawned.exitCode, 0, `cmdEffortSync child process failed (outcome=${spawned.outcome}):\nstdout: ${spawned.stdout}\nstderr: ${spawned.stderr}`, ); } test('a CRLF document with a preamble keeps its opening fence intact', () => { // Pre-fix: openLen was derived from `/^---\r\n/.test(content)` (start of // file, which here is "Preamble line", not CRLF) rather than from the // matched frontmatter block, so the CRLF fence misaligned by one byte. const { root, cwd, configDir, agentsDir, home } = makeSandbox(); try { writeProjectEffortConfig(cwd, 'inherit'); const filePath = path.join(agentsDir, 'msd-executor.md'); const before = 'Preamble line\r\n\r\n---\r\nname: x\r\neffort: high\r\n---\r\n\r\nBody.\r\n'; fs.writeFileSync(filePath, before); runEffortSync({ cwd, home, configDir }); const after = fs.readFileSync(filePath, 'utf8'); assert.strictEqual(after, 'Preamble line\r\n\r\n---\r\nname: x\r\n---\r\n\r\nBody.\r\n'); assert.ok(after.includes('---\r\nname: x\r\n'), 'the CRLF opening fence must survive intact'); assert.ok(after.startsWith('Preamble line\r\n\r\n'), 'preamble must survive untouched'); assert.ok(after.endsWith('\r\n\r\nBody.\r\n'), 'body must survive untouched'); assert.doesNotMatch(after, /^-{1,2}\r?\n/m, 'no truncated/stray fence'); } finally { cleanup(root); } }); test('a preamble line starting with the key is not the line rewritten', () => { // Pre-fix: `content.replace(keyLineRe, ...)` was a whole-file /m replace // gated only on the key being present in fmBody, so the FIRST matching // line in the whole file (the preamble) was rewritten instead of the // frontmatter line. const { root, cwd, configDir, agentsDir, home } = makeSandbox(); try { writeProjectEffortConfig(cwd, 'xhigh'); const filePath = path.join(agentsDir, 'msd-executor.md'); const before = 'effort: not-the-frontmatter\n\n---\nname: x\neffort: high\n---\n\nBody.\n'; fs.writeFileSync(filePath, before); runEffortSync({ cwd, home, configDir }); const after = fs.readFileSync(filePath, 'utf8'); assert.strictEqual(after, 'effort: not-the-frontmatter\n\n---\nname: x\neffort: xhigh\n---\n\nBody.\n'); // Bytes-based scoping (not a whole-file regex): the preamble line must // precede the first `---` fence, and only the line AFTER that fence may // read `effort: xhigh`. const firstFence = after.indexOf('---'); assert.ok(after.slice(0, firstFence).includes('effort: not-the-frontmatter'), 'preamble line must be untouched'); assert.ok(after.slice(firstFence).includes('effort: xhigh'), 'frontmatter line must carry the new value'); } finally { cleanup(root); } }); test('a document whose frontmatter starts at byte 0 is byte-identical to before', () => { // No-regression control: a normal install-written agent (frontmatter at // byte 0, LF) must see only the one targeted line change, nothing else. const { root, cwd, configDir, agentsDir, home } = makeSandbox(); try { writeProjectEffortConfig(cwd, 'xhigh'); const filePath = path.join(agentsDir, 'msd-executor.md'); const before = ['---', 'name: msd-executor', 'description: x', 'mode: subagent', '---', '', 'Body.'].join('\n'); fs.writeFileSync(filePath, before); runEffortSync({ cwd, home, configDir }); const afterSet = fs.readFileSync(filePath, 'utf8'); assert.strictEqual( afterSet, ['---', 'name: msd-executor', 'description: x', 'mode: subagent', 'effort: xhigh', '---', '', 'Body.'].join('\n'), ); writeProjectEffortConfig(cwd, 'inherit'); const beforeRemove = ['---', 'name: msd-executor', 'description: x', 'mode: subagent', 'effort: high', '---', '', 'Body.'].join('\n'); fs.writeFileSync(filePath, beforeRemove); runEffortSync({ cwd, home, configDir }); const afterRemove = fs.readFileSync(filePath, 'utf8'); assert.strictEqual( afterRemove, ['---', 'name: msd-executor', 'description: x', 'mode: subagent', '---', '', 'Body.'].join('\n'), ); } finally { cleanup(root); } }); test('a duplicated key converges to one occurrence on a single set', () => { // Protects: setFrontmatterKeyLine used to rewrite only the FIRST // occurrence of a duplicated key, leaving a stale second occurrence in // place. A last-wins YAML reader would then honour the stale value while // this function's own first-occurrence read reports "in sync" — a // permanently non-converging state. One run must collapse a duplicated // key to exactly one occurrence, carrying the new value, in the position // of the FIRST occurrence. const { root, cwd, configDir, agentsDir, home } = makeSandbox(); try { writeProjectEffortConfig(cwd, 'xhigh'); const filePath = path.join(agentsDir, 'msd-executor.md'); const before = [ '---', 'name: msd-executor', 'effort: low', 'description: x', 'effort: high', '---', '', 'Body.', ].join('\n'); fs.writeFileSync(filePath, before); runEffortSync({ cwd, home, configDir }); const after = fs.readFileSync(filePath, 'utf8'); assert.strictEqual( after, ['---', 'name: msd-executor', 'effort: xhigh', 'description: x', '---', '', 'Body.'].join('\n'), 'exactly one effort: line must remain, at the position of the first occurrence, carrying the resolved value', ); const occurrences = after.match(/^effort:/gm) || []; assert.strictEqual(occurrences.length, 1, 'exactly one effort: line must remain'); } finally { cleanup(root); } }); });