docs(voyage): S32 — audit V01/V07/V08/V11/V24 native-delegation; document "delegate the engine, keep the policy"

Balance-backlog S32 (CODE+AUDIT). Audited whether the brief interview and the
research / exploration / reviewer swarms ride NATIVE Claude Code primitives or
hand-roll their own engine. Finding: all five ALREADY delegate natively — no
re-implementation, so no command-file change. Documented the principle + a
standing regression guard instead.

- V01 (trekbrief Phase 3): Q&A turn-taking is `AskUserQuestion` (line 144 / step
  4); the "selection rule" is section-selection POLICY, not a hand-rolled menu.
- V07 (research interview): `AskUserQuestion`, one-at-a-time.
- V08/V11/V24 (research / exploration / reviewer swarms): parallel `Agent`
  fan-out in a single message ("in parallel … single message" / "via the Agent
  tool — one message, multiple tool calls"). Policy layers (dimensions/schemas/
  triangulation, typed roles/effort/scaling, 12-key rule catalogue/no-cross-feed/
  dedup) cleanly separated from the engine.

- docs/architecture.md: new cross-cutting principle note "delegate the engine,
  keep the policy" recording the native primitives, the per-command policy, and
  the audit verdict.
- tests/lib/doc-consistency.test.mjs: +3 S32 pins (architecture note present;
  each swarm command lists Agent + mandates single-message parallel spawn;
  trekbrief Phase 3 delegates to AskUserQuestion). Guards engine creep-back.

No command-file edits (all native). No model/frontmatter change (D3 firm). No
Handover-1 change. Non-breaking. Tests 734 (732 pass / 2 skip / 0 fail), bar
`node --test`; `claude plugin validate` green (1 accepted warning).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LqBYc8Ltrk7LipyJmGxXiB
This commit is contained in:
Kjell Tore Guttormsen 2026-06-20 09:36:06 +02:00
commit 2849157ba2
2 changed files with 64 additions and 0 deletions

View file

@ -1038,3 +1038,65 @@ test('S18: HANDOVER-CONTRACTS documents the pre-2.2 zero-framing-enforcement hol
'HANDOVER-CONTRACTS.md must state that pre-2.2 briefs receive zero framing enforcement',
);
});
// ── S32 — "delegate the engine, keep the policy": native-delegation hygiene ──
//
// Balance-analysis V01 / V07 / V08 / V11 / V24 audit (2026-06-20): the brief
// interview and the research / exploration / reviewer swarms must ride NATIVE
// Claude Code primitives — parallel `Agent` spawn in a single message +
// `AskUserQuestion` for interviews — and re-implement no scheduler /
// concurrency-loop / menu engine of their own. The audit found all five ALREADY
// native (no code change), so these pins are the standing guard against an
// engine creeping back in, plus the documented principle in docs/architecture.md.
// Fix the SOURCE (command prose / the architecture.md note), not the test.
const SWARM_COMMANDS = ['commands/trekresearch.md', 'commands/trekplan.md', 'commands/trekreview.md'];
test('S32: docs/architecture.md records the "delegate the engine, keep the policy" principle', () => {
const t = read('docs/architecture.md');
assert.ok(
/delegate the engine, keep the policy/i.test(t),
'docs/architecture.md must name the "delegate the engine, keep the policy" principle (V01/V07/V08/V11/V24 audit, S32)',
);
// The note must name the native primitives it delegates to (so the principle is
// anchored to real CC tools, not abstract prose).
assert.ok(
/AskUserQuestion/.test(t) && /\bAgent\b/.test(t),
'the principle note must name the native primitives delegated to (Agent + AskUserQuestion)',
);
});
test('S32: each swarm command lists the Agent tool and mandates native parallel single-message spawn', () => {
for (const f of SWARM_COMMANDS) {
const text = read(f);
assert.ok(
/^allowed-tools:.*\bAgent\b/m.test(text),
`${f}: allowed-tools frontmatter must list Agent (the native swarm-spawn engine)`,
);
assert.ok(
/in parallel/i.test(text),
`${f}: must instruct parallel swarm spawn (native delegation, not a hand-rolled scheduler)`,
);
assert.ok(
/single (assistant )?message|one message|multiple tool calls/i.test(text),
`${f}: must mandate single-message multi-tool-call dispatch (the native parallel-Agent pattern)`,
);
}
});
test('S32: trekbrief Phase 3 delegates Q&A turn-taking to AskUserQuestion (V01 — selection rule is policy, asking is native)', () => {
const text = read('commands/trekbrief.md');
assert.ok(
/^allowed-tools:.*AskUserQuestion/m.test(text),
'commands/trekbrief.md: allowed-tools must list AskUserQuestion (the native Q&A engine)',
);
const p3Start = text.indexOf('## Phase 3 — Completeness loop');
assert.ok(p3Start >= 0, 'trekbrief.md must have a "## Phase 3 — Completeness loop" section');
const p3End = text.indexOf('## Phase 3.5', p3Start);
const p3 = text.slice(p3Start, p3End > p3Start ? p3End : undefined);
assert.ok(
/Use `AskUserQuestion` for every question/.test(p3),
'Phase 3 must delegate Q&A turn-taking to AskUserQuestion — the selection rule picks WHICH ' +
'question to ask (policy); AskUserQuestion does the asking (engine). No hand-rolled menu loop.',
);
});