-
Implements the §P4 acceptance gate from plan-migration.md, with one scope adjustment confirmed up-front: full Vue Dashboard (~1650 lines) deferred to a future UI phase, replaced by extending the existing P3 static status page with Sign Off / Abandon / Feedback controls. All P4 backend acceptance criteria are scripted (phase4-verify.js). Project status FSM (project.json.status): - server/src/core/devloop/loop-controller.js * draft → running → shipped → shipped-final | abandoned ↓ ↓ l2_blocked (feedback flips back to running) l2_exhausted * `_setProjectStatus` validates transitions via STATUS_TRANSITIONS, emits SSE `project.status`, writes timeline event. * createProject seeds status=draft; runDocsPhase end → running; runProject(shipped) → shipped; all dead-end branches (l2_blocked, l2_exhausted) also propagate to status via _safeSetStatus. L3 helpers: - signOff(pid, opts) — requires status=shipped → shipped-final; commits a `chore: sign-off` git entry; rejects other source states with InvalidProjectStatusTransition. - abandon(pid, opts) — any non-terminal → abandoned; commits + calls sseBroker.close(pid) to send SSE close frame to subscribers. - submitFeedback(pid, text, opts) — rejects in shipped-final/abandoned; invokes PM in incremental mode; on prd_rev bump writes changelog.ndjson prd_rev entry + emits prd.updated SSE; if prior status was shipped, flips back to running so next runProject can rebuild. PM incremental mock fixture: - fixtures/devloop-mock/devloop-pm.json — converted to sequence form: * sequence[0] (init) — original P1 fixture (PRD rev=1, 14 files). * sequence[1] (incremental) — appends a new section to prd/feature/feature-tree.html, bumps article data-rev to 2, writes history/prd-rev-002.html. Baseline happy-path Integrator: - fixtures/devloop-mock/devloop-integrator.json — single-shot pass. Makes vanilla runProject ship without a scenario override. P4 happy-path scenario: - fixtures/devloop-mock-scenarios/happy_path/devloop-architect.json — single-unit (todo-be only) Architect so end-to-end ship works with the baseline Coder/Tester (which only know todo-be paths). Routes: - server/routes/devloop.js: * POST /projects/:pid/sign-off — 400 InvalidProjectStatusTransition when status != 'shipped'; 200 returns { status }. * POST /projects/:pid/abandon — body { by?, reason?, note? }; 400 on terminal state; 200 returns { status: 'abandoned' }. * POST /projects/:pid/feedback — body { text (req), by?, mockFixtureDir? }; 400 on missing text or shipped-final/abandoned; 200 returns { prd_rev_before, prd_rev_after, status }. * POST /projects: now accepts optional `mockFixtureDir` so the same fixture dir threads through both the create call and later feedback (keeps mock-sequence counters aligned). Static status page (replaces full Vue Dashboard for P4): - server/public/devloop-status.html — adds: * Status badge in header (color-coded per status). * Sign Off / Abandon control buttons (disabled per current state). * Feedback textarea + Submit button → POST /feedback. * Buttons reflect FSM (signoff only when shipped; abandon/feedback locked at terminal states). Acceptance: - scripts/phase4-verify.js — 9 steps, full HTTP path: ① POST /projects → running ② POST /run → shipped ③ POST /feedback → PRD rev 1→2 + running (+ changelog entry) ④ POST /run again → shipped ⑤ POST /sign-off → shipped-final ⑥ POST /feedback (after sign-off) → 400 ⑦ POST /sign-off (after sign-off) → 400 ⑧ second project: POST /abandon → abandoned ⑨ POST /abandon (after abandon) → 400 Tests (+19 cases): - server/tests/devloop/p4-l3-feedback.test.js * 14 FSM cases covering happy path + abandon path + signOff pre-conditions + empty feedback rejection. * 5 route cases via fetch on ephemeral express app. Results: - phase0-verify: 8/8 - phase0-test-call: 7/7 - phase1-verify: 7/7 - phase2-verify: 6/6 - phase3-verify: 9/9 - phase4-verify: 9/9 - vitest devloop+acp-core: 213/213 (was 194 → +19) Spec deviations explicit: - Full Vue DevLoopDashboard.vue + Ops 4 sub-pages NOT implemented; static status page handles the demoable surface area instead. - All backend endpoints from §P4 (sign-off, abandon, feedback) are complete and tested. Specs: docs/prd/newfunction/_spec/plan-migration.md · P4 L3 + UI Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>