Skip to content

[Spec 83] v2-client-shell-apps-v2-render - #104

Merged
pseudoseed merged 51 commits into
mainfrom
builder/spir-83
Aug 24, 2026
Merged

[Spec 83] v2-client-shell-apps-v2-render#104
pseudoseed merged 51 commits into
mainfrom
builder/spir-83

Conversation

@pseudoseed

@pseudoseed pseudoseed commented Aug 24, 2026

Copy link
Copy Markdown
Owner

Summary

apps/v2 renders the live hierarchy from GET /v2/events. Five phases: static /v2/ + v2-dist pack, closed-read-set reducer, bootstrap and resume reconnect, containment site view, same-origin Playwright fixture.

Refs #83

Changes

  • New apps/v2 workspace (React 19 + Vite). Types from @cluesmith/codev-types only. No SDK behaviour, no EventSource, no setInterval. "test": "vitest run" (bare vitest is watch mode and hangs porch).
  • v2-static.ts plus one prologue branch in v2-routes.ts. Two public GET clauses for /v2/ and /v2/assets/*.
  • Site view: containment lots, D13 parentId-faithful tree (workspace-parented beside the architect; architect-parented nested under it; unresolvable parents labelled at machine level). Rust only on gate-waiting.
  • Playwright fixture on 127.0.0.1:4173 is the sole origin. 15 e2e tests.
  • Spec rev. 12 merged from main. FR-3 is satisfied; FR-3 is unmet: every builder reports the workspace as its parent, never its architect #97 closed; leftover defect is afx cleanup cannot remove an orphaned builder worktree, so orphans accumulate forever #100.
  • CI unit job now runs apps/v2 vitest. Packaging check is v2-packaging.e2e.test.ts. Production sourcemaps off.

Testing

  • apps/v2 vitest: 127 tests, 11 files
  • Playwright: 15/15. cold-load-ms=137 / idle-Bps=0
  • Frozen C1/C2: empty git diff --stat vs origin/main at phase 5 close (recorded in the review; not a durable test)
  • Architect verified phase 5 independently; header collision fixed before this PR

Spec

codev/specs/83-v2-client-shell.md

Review

codev/reviews/83-v2-client-shell.md

…events with resume

Bootstrap fetches /api/workspaces once. Stream reader reassembles SSE.
Reconnect uses since/stream. Bad frames recover once without resume.
@pseudoseed

Copy link
Copy Markdown
Owner Author

Integration review: REQUEST_CHANGES

Lanes: codex REQUEST_CHANGES, claude REQUEST_CHANGES. Gemini unauthenticated, opencode broken (#103) — 2 lanes, not 3, and this is not a CMAP. Every finding below was verified against the repo by the architect rather than relayed.

Problem. The unit is architecturally sound and the frozen-file seam held, but the tests that prove it don't run in CI, and two tests are in the wrong suite in ways that will break unrelated future work.

Blocking

1. CI never runs these tests. Found independently by both lanes. .github/workflows/test.yml:72 runs pnpm exec vitest run --coverage directly in packages/codevnot pnpm test. The package.json test-script change therefore has zero effect in CI, and no workflow step references apps/v2. 122 vitest + 14 Playwright tests execute only when porch or a human invokes them.

2. frozen-files.test.ts makes a one-PR constraint permanent. It runs git diff origin/main...HEAD against the C1/C2 list (line 22). Those files are frozen for spec 83, not forever — any future PR that legitimately touches apps/web, VS Code, Stream Deck, or the v2 server contract will fail the v2 unit suite for an unrelated reason. It also assumes a remote exists. The check itself was valuable and passed clean on all 12 paths when I ran it; it belongs in the review document as PR evidence, not in the durable suite.

3. v2-packaging.test.ts shells a full build inside the unit suite. CI's coverage run would now do tsc + vite build + npm pack and write packages/codev/v2-dist as a side effect. The convention already exists — vitest.config.ts:24 excludes **/*.e2e.test.ts as "server-spawning / integration tests," and vitest.e2e.config.ts owns them. This is also why the NODE_ENV=production patch was needed: wrong suite from the start.

4. buildTree silently drops nodes with an unresolvable parentId. if (plot) plot.architects.push(group) with no else, same for builders. A node whose parent isn't in the map vanishes with no signal — "I could not tell" spelled as "not there," which is the exact failure D1, D5 and D7 guard against everywhere else in this spec.

Not blocking

The test script change from watch to run stays. One lane called it "no CI benefit" — correct about CI, wrong about why it exists: bare vitest is watch mode and porch hangs on it. Worth stating in the PR body so the reason survives.

Follow-ups, as issues rather than changes here

  • Bare GET /v2 (no trailing slash) 401s, because isPublicRoute matches /v2/ exactly. That's the URL a person types, and it reads as a key problem.
  • A clean EOF keeps the drawn tree; a thrown fetch replaces the whole page with the unreachable banner, discarding a tree still in state. D2's "state survives the socket" argues for keeping it under the connection strip.

Verified independently before this review

  • apps/v2 vitest: 122 passed, 12 files
  • packages/codev agent-farm suite: 3,395 passed, 34 skipped, 0 failed
  • Playwright: 14/14, one per browser-facing criterion
  • Frozen-file check: zero diff vs origin/main on all 12 C1/C2 paths
  • Measured budgets: cold load 138ms against 2,000ms; idle 0 B/s against 1 KB/s. The zero is the strongest no-polling evidence in the unit and belongs in the review.
  • Rendered at 1440 and screenshotted: containment holds, rust appears only on the GATE stamp, counts read as machine totals. The ALPHARUN header defect I found pre-PR is fixed and confirmed.

#97 and #98 are correctly reported rather than patched — confirm both are linked from the review document before re-requesting.

Merge spec rev. 12. Run apps/v2 in CI. Drop the durable frozen-files
test. Move packaging to the e2e suite. Surface orphan nodes. Cover
architect-parented builders. Turn production sourcemaps off.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant