Spun off from #948, which removed the two stub files because they were green theatre: @pytest.mark.skip classes whose methods raise NotImplementedError, so scripts/lifecycle --mode api|web collected only skips and exited 0 while CLAUDE.md advertised it as the pre-PR gate.
#948 makes those modes fail loudly (exit 3, "not implemented — see this issue") instead of passing silently. This issue is the actual work.
Both plans below are preserved verbatim from the deleted stubs so nothing is lost.
Why the mock provider matters
test_cli_lifecycle.py costs real money and runs 10–30 minutes, which is why it is opt-in. An API/web lifecycle test driven by CODEFRAME_LLM_PROVIDER=mock costs nothing and can run in CI on every PR — it verifies the server layer, SSE streaming, auth and task execution wire together, which is precisely the seam no unit test covers. That is worth more than a paid duplicate of the CLI test.
API lifecycle plan (from tests/lifecycle/test_api_lifecycle.py)
test_agent_builds_project_via_api — agent builds csv-stats via REST API calls:
POST /api/v2/workspace/init
POST /api/v2/prd (upload PRD.md)
POST /api/v2/tasks/generate
GET /api/v2/tasks to find READY tasks
POST /api/v2/batches/run with all ready task IDs
GET /api/v2/tasks/{id}/stream (SSE) to monitor
- Poll until all tasks complete
- Run acceptance checks
Note the stub's docstring names endpoints that do not all exist as written — verify each against docs/PHASE_2_CLI_API_MAPPING.md and the live OpenAPI schema before implementing, rather than trusting the plan.
test_sse_streaming_delivers_events — task execution via API emits real-time SSE events.
Web lifecycle plan (from tests/lifecycle/test_web_lifecycle.py)
test_user_can_build_project_via_web_ui — a user drives the full pipeline through the web UI (Playwright):
- Navigate to
/
- Create workspace or use existing
- Go to
/prd → upload PRD.md
- Go to
/tasks → click "Generate Tasks"
- Verify tasks appear in the kanban board
- Launch execution and watch the live stream
- Verify the final state
Requires codeframe serve + the web-ui dev server. There is already a Playwright harness (#684/#703) with CI jobs — build on that rather than starting a second one.
Acceptance criteria
Spun off from #948, which removed the two stub files because they were green theatre:
@pytest.mark.skipclasses whose methodsraise NotImplementedError, soscripts/lifecycle --mode api|webcollected only skips and exited 0 while CLAUDE.md advertised it as the pre-PR gate.#948 makes those modes fail loudly (
exit 3, "not implemented — see this issue") instead of passing silently. This issue is the actual work.Both plans below are preserved verbatim from the deleted stubs so nothing is lost.
Why the mock provider matters
test_cli_lifecycle.pycosts real money and runs 10–30 minutes, which is why it is opt-in. An API/web lifecycle test driven byCODEFRAME_LLM_PROVIDER=mockcosts nothing and can run in CI on every PR — it verifies the server layer, SSE streaming, auth and task execution wire together, which is precisely the seam no unit test covers. That is worth more than a paid duplicate of the CLI test.API lifecycle plan (from
tests/lifecycle/test_api_lifecycle.py)test_agent_builds_project_via_api— agent builds csv-stats via REST API calls:POST /api/v2/workspace/initPOST /api/v2/prd(upload PRD.md)POST /api/v2/tasks/generateGET /api/v2/tasksto find READY tasksPOST /api/v2/batches/runwith all ready task IDsGET /api/v2/tasks/{id}/stream(SSE) to monitorNote the stub's docstring names endpoints that do not all exist as written — verify each against
docs/PHASE_2_CLI_API_MAPPING.mdand the live OpenAPI schema before implementing, rather than trusting the plan.test_sse_streaming_delivers_events— task execution via API emits real-time SSE events.Web lifecycle plan (from
tests/lifecycle/test_web_lifecycle.py)test_user_can_build_project_via_web_ui— a user drives the full pipeline through the web UI (Playwright)://prd→ upload PRD.md/tasks→ click "Generate Tasks"Requires
codeframe serve+ the web-ui dev server. There is already a Playwright harness (#684/#703) with CI jobs — build on that rather than starting a second one.Acceptance criteria
tests/lifecycle/test_api_lifecycle.pyexists with real assertions and passes underCODEFRAME_LLM_PROVIDER=mockANTHROPIC_API_KEY), not only underscripts/lifecycletests/lifecycle/test_web_lifecycle.pylikewise, reusing the existing Playwright harnessscripts/lifecycleaccepts--mode api|web|allagain: theexit 3guards and the "not implemented" list are removedtests/test_lifecycle_gates_948.pyis updated — its tests assert that the unimplemented modes are rejected, so they must flip when the modes become real