// tests/lib/claimed-order.test.mjs // The recorder that tells /trekbrief which coord-queue order it is running. // // It mirrors repo-mailbox's claim contract (coord root, mailbox = basename of the // git toplevel, `_*` reserved, the claimed file's stem is the order id, a // `.claim` sidecar carries `claimed-at:`), and it must never guess: exactly // one claimed order is an attribution, zero or several is `null` plus a reason. // Every test builds its own coord dir and git repos; nothing reads the real // queue. The module is loaded per test, so a missing module fails each test on // its own instead of failing the file at link time. import { test } from 'node:test'; import { strict as assert } from 'node:assert'; import { mkdtempSync, mkdirSync, writeFileSync, rmSync, readdirSync, statSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join, dirname } from 'node:path'; import { spawnSync } from 'node:child_process'; const load = () => import('../../lib/stats/claimed-order.mjs'); // --- helpers --------------------------------------------------------------- function fixture(files) { const dir = mkdtempSync(join(tmpdir(), 'claimed-order-')); for (const [rel, body] of Object.entries(files)) { const p = join(dir, rel); mkdirSync(dirname(p), { recursive: true }); writeFileSync(p, body); } return dir; } const cleanup = (...dirs) => { for (const d of dirs) rmSync(d, { recursive: true, force: true }); }; function orderFile({ id, to, quoted = false }) { const lines = ['---', 'from: .claude']; if (to !== undefined) lines.push(`to: ${to}`); lines.push(`order-id: ${quoted ? `"${id}"` : id}`, `subject: order ${id}`, 'date: 2026-10-01T10:00:00Z', '---', '', `# ORDER ${id}`, ''); return lines.join('\n'); } const claimFile = (at) => `claimed-at: ${at}\nclaimed-by-pid: 1\n`; // A claimed order in , with its sidecar unless `claim: false`. function claimed(mailbox, id, { at = '2026-10-04T10:00:00Z', claim = true, to = mailbox } = {}) { const files = { [`${mailbox}/orders/claimed/${id}.md`]: orderFile({ id, to }) }; if (claim) files[`${mailbox}/orders/claimed/${id}.claim`] = claimFile(at); return files; } function git(cwd, ...args) { const r = spawnSync('git', ['-c', 'user.email=t@example.invalid', '-c', 'user.name=t', ...args], { cwd, encoding: 'utf8' }); assert.equal(r.status, 0, `git ${args.join(' ')}: ${r.stderr}`); return r.stdout.trim(); } // A git repo whose directory is named `name`, with one commit (a worktree needs a HEAD). function repo(name) { const parent = mkdtempSync(join(tmpdir(), 'claimed-order-git-')); const dir = join(parent, name); mkdirSync(dir); git(dir, 'init', '-q'); writeFileSync(join(dir, 'README'), 'x\n'); git(dir, 'add', 'README'); git(dir, 'commit', '-q', '-m', 'init'); return { parent, dir }; } function snapshot(dir) { const out = []; const walk = (d) => { for (const n of readdirSync(d).sort()) { const p = join(d, n); const s = statSync(p); out.push(`${p} ${s.mtimeMs}`); if (s.isDirectory()) walk(p); } }; walk(dir); return out.join('\n'); } // --- findClaimedOrder ---------------------------------------------------------- test('findClaimedOrder: exactly one claimed order gives its order id and its claimed-at', async () => { const { findClaimedOrder } = await load(); const coord = fixture(claimed('mbx', 'o-1', { at: '2026-10-04T17:10:51Z' })); try { assert.deepEqual(findClaimedOrder({ coordDir: coord, mailboxes: ['mbx'] }), { order_id: 'o-1', order_claimed_at: '2026-10-04T17:10:51Z', order_reason: null }); } finally { cleanup(coord); } }); test('findClaimedOrder: no claimed/ directory gives null and none-claimed, never a guess', async () => { const { findClaimedOrder } = await load(); const coord = fixture({ 'mbx/orders/o-1.md': orderFile({ id: 'o-1', to: 'mbx' }) }); try { assert.deepEqual(findClaimedOrder({ coordDir: coord, mailboxes: ['mbx'] }), { order_id: null, order_claimed_at: null, order_reason: 'none-claimed' }); } finally { cleanup(coord); } }); test('findClaimedOrder: an empty claimed/ gives null and none-claimed', async () => { const { findClaimedOrder } = await load(); const coord = fixture({ 'mbx/orders/claimed/.keep': '' }); try { assert.equal(findClaimedOrder({ coordDir: coord, mailboxes: ['mbx'] }).order_reason, 'none-claimed'); } finally { cleanup(coord); } }); test('findClaimedOrder: two claimed orders give null and several-claimed:2 - the older one is never picked', async () => { const { findClaimedOrder } = await load(); const coord = fixture({ ...claimed('mbx', 'o-1', { at: '2026-10-01T00:00:00Z' }), ...claimed('mbx', 'o-2') }); try { assert.deepEqual(findClaimedOrder({ coordDir: coord, mailboxes: ['mbx'] }), { order_id: null, order_claimed_at: null, order_reason: 'several-claimed:2' }); } finally { cleanup(coord); } }); test('findClaimedOrder: an unparseable claimed .md still counts - "several" is never undercounted', async () => { const { findClaimedOrder } = await load(); const coord = fixture({ ...claimed('mbx', 'o-1'), 'mbx/orders/claimed/o-2.md': 'no frontmatter at all\n' }); try { assert.equal(findClaimedOrder({ coordDir: coord, mailboxes: ['mbx'] }).order_reason, 'several-claimed:2'); } finally { cleanup(coord); } }); test('findClaimedOrder: the .claim sidecar and other non-.md files are not orders', async () => { const { findClaimedOrder } = await load(); const coord = fixture({ ...claimed('mbx', 'o-1'), 'mbx/orders/claimed/notes.txt': 'x\n' }); try { assert.equal(findClaimedOrder({ coordDir: coord, mailboxes: ['mbx'] }).order_id, 'o-1'); } finally { cleanup(coord); } }); test('findClaimedOrder: pending orders/ and archive/ are not claimed', async () => { const { findClaimedOrder } = await load(); const coord = fixture({ 'mbx/orders/o-1.md': orderFile({ id: 'o-1', to: 'mbx' }), 'mbx/orders/archive/o-2.md': orderFile({ id: 'o-2', to: 'mbx' }), }); try { assert.equal(findClaimedOrder({ coordDir: coord, mailboxes: ['mbx'] }).order_reason, 'none-claimed'); } finally { cleanup(coord); } }); test("findClaimedOrder: another mailbox's claimed order is never ours", async () => { const { findClaimedOrder } = await load(); const coord = fixture(claimed('other', 'o-1')); try { assert.equal(findClaimedOrder({ coordDir: coord, mailboxes: ['mbx'] }).order_reason, 'none-claimed'); } finally { cleanup(coord); } }); test('findClaimedOrder: a missing coord dir gives null and coord-missing, without throwing', async () => { const { findClaimedOrder } = await load(); const r = findClaimedOrder({ coordDir: join(tmpdir(), 'claimed-order-does-not-exist-'), mailboxes: ['mbx'] }); assert.deepEqual(r, { order_id: null, order_claimed_at: null, order_reason: 'coord-missing' }); }); test('findClaimedOrder: a claimed order without its .claim keeps the id, with no-claim-time', async () => { const { findClaimedOrder } = await load(); const coord = fixture(claimed('mbx', 'o-1', { claim: false })); try { assert.deepEqual(findClaimedOrder({ coordDir: coord, mailboxes: ['mbx'] }), { order_id: 'o-1', order_claimed_at: null, order_reason: 'no-claim-time' }); } finally { cleanup(coord); } }); test('findClaimedOrder: a to: that names another repo is to-mismatch; a missing to: is accepted', async () => { const { findClaimedOrder } = await load(); const wrong = fixture(claimed('mbx', 'o-1', { to: 'elsewhere' })); const none = fixture(claimed('mbx', 'o-2', { to: undefined })); try { assert.deepEqual(findClaimedOrder({ coordDir: wrong, mailboxes: ['mbx'] }), { order_id: null, order_claimed_at: null, order_reason: 'to-mismatch' }); assert.equal(findClaimedOrder({ coordDir: none, mailboxes: ['mbx'] }).order_id, 'o-2'); } finally { cleanup(wrong, none); } }); test('findClaimedOrder: the id is the file stem, also when the frontmatter quotes order-id', async () => { const { findClaimedOrder } = await load(); const coord = fixture({ 'mbx/orders/claimed/o-1.md': orderFile({ id: 'o-1', to: 'mbx', quoted: true }), 'mbx/orders/claimed/o-1.claim': claimFile('2026-10-04T10:00:00Z'), }); try { assert.equal(findClaimedOrder({ coordDir: coord, mailboxes: ['mbx'] }).order_id, 'o-1'); } finally { cleanup(coord); } }); test('findClaimedOrder: a _-prefixed mailbox is never read (the claim script reserves the namespace)', async () => { const { findClaimedOrder } = await load(); const coord = fixture(claimed('_retired', 'o-1')); try { assert.equal(findClaimedOrder({ coordDir: coord, mailboxes: ['_retired'] }).order_id, null); } finally { cleanup(coord); } }); test('findClaimedOrder: it only reads - the coord dir is identical before and after', async () => { const { findClaimedOrder } = await load(); const coord = fixture({ ...claimed('mbx', 'o-1'), ...claimed('other', 'o-2') }); try { const before = snapshot(coord); findClaimedOrder({ coordDir: coord, mailboxes: ['mbx', 'other'] }); findClaimedOrder({ coordDir: coord, mailboxes: ['mbx'] }); assert.equal(snapshot(coord), before); } finally { cleanup(coord); } }); test('findClaimedOrder: one claimed order across two mailbox names is found; one in each is several', async () => { const { findClaimedOrder } = await load(); const one = fixture(claimed('main-repo', 'o-1')); const two = fixture({ ...claimed('main-repo', 'o-1'), ...claimed('wt-name', 'o-2') }); try { assert.equal(findClaimedOrder({ coordDir: one, mailboxes: ['wt-name', 'main-repo'] }).order_id, 'o-1'); assert.equal(findClaimedOrder({ coordDir: two, mailboxes: ['wt-name', 'main-repo'] }).order_reason, 'several-claimed:2'); } finally { cleanup(one, two); } }); // --- resolveCoordDir ------------------------------------------------------------- test('resolveCoordDir: CLAUDE_COORD_DIR wins, else HOME/.claude/coord from the given env', async () => { const { resolveCoordDir } = await load(); assert.equal(resolveCoordDir({ CLAUDE_COORD_DIR: '/x/coord', HOME: '/h' }), '/x/coord'); assert.equal(resolveCoordDir({ HOME: '/h' }), join('/h', '.claude', 'coord')); assert.equal(resolveCoordDir({ CLAUDE_COORD_DIR: '', HOME: '/h' }), join('/h', '.claude', 'coord')); }); // --- resolveMailboxes ------------------------------------------------------------ test('resolveMailboxes: a repo gives its basename; a worktree gives its own and the main repo name; outside git gives []', async () => { const { resolveMailboxes } = await load(); const main = repo('main-repo'); const outside = mkdtempSync(join(tmpdir(), 'claimed-order-nogit-')); try { assert.deepEqual(resolveMailboxes(main.dir, { env: {} }), ['main-repo']); const wt = join(main.parent, 'wt-name'); git(main.dir, 'worktree', 'add', '-q', '-b', 'wt-branch', wt); assert.deepEqual([...resolveMailboxes(wt, { env: {} })].sort(), ['main-repo', 'wt-name']); assert.deepEqual(resolveMailboxes(outside, { env: {} }), []); } finally { cleanup(main.parent, outside); } }); test('resolveMailboxes: an inherited GIT_DIR pointing at another repo is ignored', async () => { const { resolveMailboxes } = await load(); const mine = repo('mine'); const theirs = repo('theirs'); try { const env = { GIT_DIR: join(theirs.dir, '.git'), GIT_WORK_TREE: theirs.dir }; assert.deepEqual(resolveMailboxes(mine.dir, { env }), ['mine']); } finally { cleanup(mine.parent, theirs.parent); } }); // --- attributeOrder -------------------------------------------------------------- test('attributeOrder: outside git the mailbox is unresolved - null, never a guess', async () => { const { attributeOrder } = await load(); const outside = mkdtempSync(join(tmpdir(), 'claimed-order-nogit-')); const coord = fixture(claimed('mbx', 'o-1')); try { assert.deepEqual(attributeOrder({ cwd: outside, env: { CLAUDE_COORD_DIR: coord, HOME: outside } }), { order_id: null, order_claimed_at: null, order_reason: 'mailbox-unresolved' }); } finally { cleanup(outside, coord); } }); test('attributeOrder: finds the claimed order of the cwd repo; a projectDir outside cwd cannot steer it elsewhere', async () => { const { attributeOrder } = await load(); const a = repo('repo-a'); const b = repo('repo-b'); const coord = fixture(claimed('repo-b', 'o-1')); try { const env = { CLAUDE_COORD_DIR: coord, HOME: a.parent }; // Positive control: the fixture is findable from repo-b itself. assert.equal(attributeOrder({ cwd: b.dir, env }).order_id, 'o-1'); // From repo-a, a project_dir that walks out of cwd into repo-b is ignored. assert.equal(attributeOrder({ cwd: a.dir, env, projectDir: b.dir }).order_reason, 'none-claimed'); assert.equal(attributeOrder({ cwd: a.dir, env, projectDir: '../../' + b.parent.split('/').pop() + '/repo-b' }).order_reason, 'none-claimed'); } finally { cleanup(a.parent, b.parent, coord); } }); test('attributeOrder: a projectDir inside cwd moves the lookup to the repo that holds it', async () => { const { attributeOrder } = await load(); const m = repo('mbx'); const coord = fixture(claimed('mbx', 'o-1')); try { mkdirSync(join(m.dir, '.claude', 'projects', 'x'), { recursive: true }); const env = { CLAUDE_COORD_DIR: coord, HOME: m.parent }; // Control: cwd (the repo's parent) is outside git, so without projectDir there is no mailbox. assert.equal(attributeOrder({ cwd: m.parent, env }).order_reason, 'mailbox-unresolved'); assert.deepEqual(attributeOrder({ cwd: m.parent, env, projectDir: 'mbx/.claude/projects/x' }), { order_id: 'o-1', order_claimed_at: '2026-10-04T10:00:00Z', order_reason: null }); } finally { cleanup(m.parent, coord); } });