/** * /autoplan phase-order pin (free, static). * * The pipeline order is a deliberate design decision (2026-08-25, user-directed): * CEO → Design (if UI scope) → DX (if developer-facing scope) → Eng, ALWAYS LAST. * Eng is the required shipping gate — it must review the FINAL amended plan, so * every other phase's amendments land before it. The original order buried Eng * mid-pipeline (CEO → Design → Eng → DX), which let DX findings land AFTER the * gate had signed off — the gate validated a stale plan. * * These assertions pin the template so a refactor can't silently restore the * old order. The paid chain E2E (skill-e2e-autoplan-chain.test.ts) verifies the * runtime behavior; this pins the source of truth for free on every PR. */ import { describe, test, expect } from 'bun:test'; import * as fs from 'fs'; import * as path from 'path'; const ROOT = path.join(import.meta.dir, '..'); const read = (p: string) => fs.readFileSync(path.join(ROOT, p), 'utf-8'); describe('autoplan phase order (Eng always last)', () => { const tmpl = read('autoplan/SKILL.md.tmpl'); test('Sequential Execution block names Eng as the terminal phase', () => { const block = tmpl.split('## Sequential Execution')[1]?.split('---')[0] ?? ''; expect(block).toContain('Eng runs LAST, always'); expect(block).toMatch(/CEO → Design.*→ DX.*→ Eng/s); // The old order must not resurface anywhere in the template. expect(tmpl).not.toContain('CEO → Design → Eng → DX'); }); test('phase headings appear in the new order: 1, 2, 2.5, 3', () => { const idx = (h: string) => { const i = tmpl.indexOf(h); expect(i).toBeGreaterThan(-1); return i; }; const p1 = idx('## Phase 1: CEO Review'); const p2 = idx('## Phase 2: Design Review'); const p25 = idx('## Phase 2.5: DX Review'); const p3 = idx('## Phase 3: Eng Review'); expect(p1).toBeLessThan(p2); expect(p2).toBeLessThan(p25); expect(p25).toBeLessThan(p3); // No stale Phase 3.5 heading or transition marker survives. expect(tmpl).not.toContain('Phase 3.5'); }); test('phase sections hand off in the new order', () => { expect(read('autoplan/sections/dx-phase.md.tmpl')).toContain( 'Passing to Phase 3 (Eng Review', ); expect(read('autoplan/sections/eng-phase.md.tmpl')).toContain( 'Passing to Phase 4 (Final Gate)', ); // Eng's Codex voice sees every prior phase's consensus, DX included. expect(read('autoplan/sections/eng-phase.md.tmpl')).toContain( 'DX: { expect(tmpl).toContain('One exception class — never auto-decided'); expect(tmpl).not.toContain('Premise gate passed (user confirmed)'); const ceo = read('autoplan/sections/ceo-phase.md.tmpl'); expect(ceo).not.toContain('GATE: Present premises to user for confirmation'); expect(ceo).toContain('Final'); }); });