Files
stack/docs/scratchpads/webui-p4-1.md
T

19 KiB

WebUI Phase P — P4-1 Projects + Tasks SPA Scratchpad

Task ID: P4-1 Tracking ref: Phase P RFC §6.4 / §2.4 author brief; no provider issue supplied Mission context: mvp-20260312 (active) Branch: feat/webui-p4-1 from origin/next Started: 2026-08-11 Role: orchestrator-controlled author worker; docs/TASKS.md remains orchestrator-only and is not part of this increment

Original tasking

Implement the bounded P4-1 SPA parity slice exactly as briefed: real authenticated /projects, /projects/:id, and /tasks React Router pages ported from the existing Next baseline; reuse existing project/task components; preserve relative same-origin REST access; support only the existing project/task PATCH edit flows; add route error boundaries and page tests; pin Vite strict port 3100 and legacy Next dev/start to 3101; make no gateway, package, dependency, nav-shell, chat, settings, or admin changes; verify, commit, and push only feat/webui-p4-1 (no PR or merge). If any required REST endpoint is absent, stop as BLOCKED: rather than inventing a workaround.

Objective and acceptance map

  • A: /projects list with loading, cards, empty, and surfaced API-error states; defer MissionStatus side panel.
  • B: /projects/:id detail with overview/tasks/missions tabs, parallel project/mission/task load, bounded project and task PATCH edits.
  • C: /tasks list/kanban with bounded task PATCH edits.
  • D: replace the three route placeholders and add route error boundaries without changing chat.
  • E: use only @/lib/types and @/lib/api; relative /api/... REST paths only.
  • F: Vite strictPort: true; Next dev/start pinned to 3101; no proxy/dependency changes.
  • G: fixture-backed Vitest coverage for lists, states, tabs/toggles, PATCH calls, and real route elements; all named verification gates pass.

Plan

  1. Verify the required gateway REST routes and inspect the exact origin/next SPA, Next baseline pages, shared components, types, API helper, and P3 test conventions.
  2. Record the pre-change web test count and add required page/route tests first, observing expected RED failures.
  3. Port the three pages and shared route error boundary, then wire routes and bounded PATCH flows.
  4. Apply only the two dev-port pin changes.
  5. Run focused tests, all user-required gates, lockfile and same-origin checks, and git diff --check.
  6. Obtain independent spec/code/security review; remediate and repeat affected gates until clear.
  7. Commit conventionally, run the required pre-push queue guard, push only the feature branch, and record exact evidence here.

Testing strategy

TDD is applied because this adds user-visible data/edit behavior. Component tests mock only the existing API boundary and exercise rendered behavior and PATCH payloads. Primary situational evidence is the required page interaction suite plus route-resolution checks; baseline evidence is typecheck, lint, full web test, build, frozen install, formatting/diff hygiene, and same-origin grep.

Budget

No explicit token cap was supplied. Working soft cap: 50K tokens, derived from three coupled React pages, route/error wiring, interaction tests, port config, review/remediation, and full verification. One Codex implementation worker and independent review workers will be used serially to avoid worktree collisions.

Base evidence

  • git fetch origin rc=0.
  • origin/next and branch start: e00cc475a2b1e9866bd4e2f8df80aff640c3a543.
  • Branch created: feat/webui-p4-1 tracking origin/next.
  • Harness-owned .mosaic/orchestrator/session.lock is dirty and must remain unstaged/uncommitted.

Progress / evidence

  • Loaded active mission manifest, latest scratchpad, top-level tasks, PRD, orchestration/delivery/frontend/QA/documentation/review/TypeScript guides, and matching implementation skills.
  • Confirmed exact base SHA and created the feature branch.
  • Required REST endpoints verified in Gateway source: project list/detail/PATCH, task list/filter/detail/PATCH, and mission list all exist.
  • Scope assumption check found a blocking contradiction before source implementation.
  • Pre-change web test count recorded.
  • RED tests observed.
  • Implementation complete.
  • Independent review clear.
  • Required verification gates run against the unchanged web baseline; exact leak-grep expectation is independently blocked by 12 pre-existing matches.
  • Blocker record committed as 5ede86a5 and feature branch pushed; no PR opened and no merge performed.

Blocker — 2026-08-11

P4-1 is blocked because the bounded edit UX asserted by the brief does not exist at the confirmed origin/next base (e00cc475):

  • apps/web/src/components/tasks/task-detail-modal.tsx is read-only. Its props are only task and onClose; it contains no input/select/textarea, update callback, or api()/PATCH call.
  • apps/web/src/app/(dashboard)/projects/[id]/page.tsx contains no project edit controls and no project/task PATCH call.
  • apps/web/src/app/(dashboard)/tasks/page.tsx does not open TaskDetailModal; its click handler only logs that a future detail view will be added.
  • A repository grep over those reference/component paths finds zero method: 'PATCH' calls and zero edit/save form controls.
  • The required leak grep also disproves the brief's baseline claim that apps/web/src is clean: the exact command returns rc=0 with 12 pre-existing matches at origin/next (external font links, an avatar placeholder, an SVG namespace, and test fixtures). There are zero new matches in the worktree, but making the exact grep empty would require unrelated changes the brief forbids.

The brief simultaneously requires tests proving task/project PATCH edits and forbids inventing edit UX, fields, or flows beyond what those references expose. Adding controls or callback contracts would therefore be new design outside the authorized port/wiring scope. Per the explicit stop rule, no SPA source, route, config, package, lockfile, or test implementation was started.

Verification evidence on unchanged web baseline

These gates were still run to distinguish the brief contradiction from a broken base:

  • pnpm --filter @mosaicstack/web typecheck — rc=0.
  • pnpm --filter @mosaicstack/web lint — rc=0.
  • pnpm --filter @mosaicstack/web test — rc=0; 15 files, 133 tests passed. Before→after remains 133→133 because implementation was halted.
  • pnpm --filter @mosaicstack/web build — rc=0; Next production build completed, 10/10 static pages generated.
  • pnpm install --frozen-lockfile — rc=0; lock SHA-256 remained 9acaa89d213b3281e757b6edf6fdb8727176570d725b78a0de234c61a7f3c332; git diff for the lockfile rc=0.
  • git grep -nE "http://|https://" -- apps/web/src — rc=0 with 12 pre-existing matches; origin/next count=12, current HEAD count=12, new worktree additions=0.
  • pnpm format:check — rc=0.
  • git diff --check — rc=0.

Delivery evidence

  • Initial queue-guard invocation through shell ~ failed rc=127 because this Distrobox resolves HOME to /home/jwoltje/distrobox-homes/mosaic-dev, where the injected fleet status already reports the tools installation missing.
  • Correct supported host-tool invocation /home/jwoltje/.config/mosaic/tools/git/ci-queue-wait.sh --purpose push -B feat/webui-p4-1 — rc=0; branch absent remotely and queue clear.
  • git push -u origin feat/webui-p4-1 — rc=0. The push hook additionally ran repository preflight, typecheck (45/45 tasks), lint (25/25 tasks), and format check successfully.
  • No PR was opened and no merge was attempted, per the brief.

Risks / blockers

  • The active harness mutates .mosaic/orchestrator/session.lock; it is excluded from staging.
  • The Phase P §6.4 prose is absent from this checkout, so the brief-named route spec and existing Next pages are the bounded implementation anchors.
  • The MissionStatus /api/coord/status panel is explicitly deferred to a follow-up and must not enter P4-1.

REV 2 continuation — 2026-08-10T21:59:17-05:00

REV 2 supersedes the original tasking above. The independent check confirmed that the Next reference pages and task-detail-modal.tsx are read-only, so project/task editing is deliberately deferred to P4-1b. Do not re-litigate or implement the former PATCH requirements.

Revised objective and acceptance map

  • A: /projects read-only SPA list with loading, cards, empty, and surfaced API-error states; card navigation to /projects/:id; no MissionStatus panel.
  • B: /projects/:id read-only SPA detail using useParams, useNavigate, and the specified three-request Promise.all; preserve reference overview/tasks/missions tabs and read-only task modal.
  • C: /tasks read-only SPA list/kanban view with the existing read-only task modal.
  • D: replace only the three route placeholders and add page-local route error boundaries without modifying chat.
  • E: use only @/lib/types and @/lib/api with relative /api/... REST paths.
  • F: add Vite strictPort: true and pin legacy Next dev/start to 3101 without dependency or proxy changes.
  • G: add fixture-backed page tests and route-resolution assertions; run every user-specified verification gate and the narrowed new-code origin check.

Revised plan

  1. Reset feat/webui-p4-1 to the exact origin/next base and independently verify the read-only reference/component/API assumptions.
  2. Record the pre-change web suite count; write and run focused page/route tests first to observe expected RED failures.
  3. Port the three read-only pages, add independent route error boundaries, wire routes, and apply only the two dev-port pins.
  4. Run focused tests, full required web gates, frozen install/lockfile proof, origin check, format/diff hygiene, and accessibility/state-transition sanity checks.
  5. Obtain independent spec/code/security review, remediate every blocker, and repeat affected gates.
  6. Commit conventionally, run the supported pre-push queue guard, and push only feat/webui-p4-1; no PR and no merge.

Revised budget and session state

  • No explicit token cap was supplied. Working soft cap remains 50K tokens.
  • TDD is required by the user and frontend skill for the new SPA behavior; tests must fail for missing pages before production implementation.
  • Documentation assessment: this is a parity port of existing read-only behavior, not a new public workflow or API contract; the task scratchpad is the required delivery record, with no user/developer/API documentation changes in this bounded increment.
  • Exact base confirmed after fresh fetch/reset: e00cc475a2b1e9866bd4e2f8df80aff640c3a543.
  • Remote feat/webui-p4-1 is absent; the eventual push is a fresh branch creation.
  • Harness-owned .mosaic/orchestrator/session.lock remains excluded from staging.

REV 2 implementation pass — 2026-08-11T22:05:00Z

Startup verification

  • Loaded required startup files: /home/jwoltje/.config/mosaic/CONSTITUTION.md, /home/jwoltje/.config/mosaic/SOUL.md, project AGENTS.md, /home/jwoltje/.config/mosaic/guides/E2E-DELIVERY.md, docs/PRD.md, and this scratchpad.
  • Loaded required skills: test-driven-development, vitest, vite, next-best-practices, and verification-before-completion.
  • Loaded required runtime guide: /home/jwoltje/.config/mosaic/runtime/codex/RUNTIME.md.
  • Structured reasoning tool availability verified through the harness before planning.
  • git rev-parse HEAD confirmed exact required base: e00cc475a2b1e9866bd4e2f8df80aff640c3a543.
  • git status --short at startup showed only the expected untracked append-only scratchpad; .mosaic/orchestrator/session.lock did not appear and must remain unstaged if it changes later.

Current plan

  1. Record baseline evidence.
  2. Add focused failing SPA page/route specs first.
  3. Run focused RED command and record the missing-page failure.
  4. Implement the bounded read-only SPA pages, boundaries, route wiring, and the two dev-port pins.
  5. Run the required verification matrix and inspect diff hygiene.

Pre-change baseline

  • Command: pnpm --filter @mosaicstack/web test
  • rc=0
  • File/test totals before changes: 15 files / 133 tests
  • Notes: baseline already includes /chat SPA route coverage and raw React createRoot/act page specs that this pass should mirror.

RED evidence before production implementation

  • Command: pnpm --filter @mosaicstack/web test -- src/spa/pages/projects.spec.tsx src/spa/pages/project-detail.spec.tsx src/spa/pages/tasks.spec.tsx src/spa/pages/resource-route-boundaries.spec.tsx src/spa/routes.spec.tsx
  • rc=1
  • Expected missing-feature reason confirmed:
    • src/spa/pages/projects.spec.tsx, src/spa/pages/project-detail.spec.tsx, src/spa/pages/tasks.spec.tsx, and src/spa/routes.spec.tsx fail import resolution because the SPA page modules do not exist yet.
    • src/spa/pages/resource-route-boundaries.spec.tsx fails because the current /projects, /projects/:id, and /tasks routes still render placeholders without route-level alert fallbacks.

Implementation summary

  • Added SPA pages:
    • apps/web/src/spa/pages/projects.tsx
    • apps/web/src/spa/pages/project-detail.tsx
    • apps/web/src/spa/pages/tasks.tsx
  • Added page-local route boundary components in apps/web/src/spa/pages/resource-route-error-boundaries.tsx.
  • Wired /projects, /projects/:id, and /tasks in apps/web/src/routes.tsx with real elements and errorElements.
  • Added fixture-backed raw React Vitest coverage plus route assertions for the three pages and their boundaries.
  • Applied only the requested dev topology pins:
    • apps/web/vite.config.ts: server.strictPort = true
    • apps/web/package.json: next dev -p 3101, next start -p 3101

Post-implementation verification

  • Focused changed specs:
    • Command: pnpm --filter @mosaicstack/web exec vitest run src/spa/pages/projects.spec.tsx src/spa/pages/project-detail.spec.tsx src/spa/pages/tasks.spec.tsx src/spa/pages/resource-route-boundaries.spec.tsx src/spa/routes.spec.tsx
    • rc=0
    • Result: 5 files / 26 tests passed.
  • pnpm --filter @mosaicstack/web typecheck — rc=0.
  • pnpm --filter @mosaicstack/web lint — rc=0.
  • pnpm --filter @mosaicstack/web test — rc=0; post-change totals 19 files / 153 tests.
  • pnpm --filter @mosaicstack/web build — rc=1.
    • Limitation: Next/Turbopack hit a sandbox/runtime failure while processing apps/web/src/app/globals.css: creating new process, binding to a port, Operation not permitted (os error 1). This appears environmental, not route-code-specific.
  • pnpm --filter @mosaicstack/web build:vite — rc=0.
  • pnpm install --frozen-lockfile — rc=1.
    • Limitation: repo prepare hook attempted to lock /home/jwoltje/distrobox-homes/mosaic-dev/src/stack/.git/config, which is read-only in this harness.
  • pnpm-lock.yaml SHA-256 before/after install attempt: 9acaa89d213b3281e757b6edf6fdb8727176570d725b78a0de234c61a7f3c332.
  • origin/next pnpm-lock.yaml SHA-256: 9acaa89d213b3281e757b6edf6fdb8727176570d725b78a0de234c61a7f3c332.
  • git diff -- pnpm-lock.yaml — rc=0 (unchanged).
  • git diff -- apps/web/src | grep -nE '^\+.*(fetch|io|api)\(\s*[\x27\"]https?://' — rc=1 (empty, as required).
  • pnpm format:check — rc=0.
  • git diff --check — rc=0.

Final worktree check

  • git status --short shows only the authorized web files plus this scratchpad.
  • .mosaic/orchestrator/session.lock remains unstaged.
  • Current changed file set:
    • apps/web/package.json
    • apps/web/src/routes.tsx
    • apps/web/src/spa/routes.spec.tsx
    • apps/web/vite.config.ts
    • apps/web/src/spa/pages/page-errors.ts
    • apps/web/src/spa/pages/page-fixtures.ts
    • apps/web/src/spa/pages/project-detail.spec.tsx
    • apps/web/src/spa/pages/project-detail.tsx
    • apps/web/src/spa/pages/projects.spec.tsx
    • apps/web/src/spa/pages/projects.tsx
    • apps/web/src/spa/pages/resource-route-boundaries.spec.tsx
    • apps/web/src/spa/pages/resource-route-error-boundaries.tsx
    • apps/web/src/spa/pages/tasks.spec.tsx
    • apps/web/src/spa/pages/tasks.tsx
    • docs/scratchpads/webui-p4-1.md

P4-1 REV 2 Final Delivery Verification — 2026-08-10T22:23:00Z

Spec/Security Review Verdicts (Independent Reviews)

Both independent reviews cleared P4-1 REV 2 implementation without blockers:

  • Spec review: approved; 0 blockers, 0 should-fix findings
  • Code/security review: approved; 0 blockers, 0 critical/high findings, 0 should-fix recommendations

Final Fresh Gate Verification (This Session)

All verification gates executed sequentially with rc=0 (except where noted):

  1. pnpm --filter @mosaicstack/web typecheck — rc=0
  2. pnpm --filter @mosaicstack/web lint — rc=0
  3. pnpm --filter @mosaicstack/web test — rc=0; 19 files / 153 tests (baseline: 15 files / 133 tests; added: 4 files / 20 tests)
  4. pnpm --filter @mosaicstack/web build — rc=0; Next production build completed, 10/10 static pages generated
  5. pnpm --filter @mosaicstack/web build:vite — rc=0; Vite production bundle generated
  6. Lockfile integrity:
    • Before install: SHA-256 9acaa89d213b3281e757b6edf6fdb8727176570d725b78a0de234c61a7f3c332
    • After frozen install: SHA-256 9acaa89d213b3281e757b6edf6fdb8727176570d725b78a0de234c61a7f3c332
    • Equality: ✓ verified
    • git diff --quiet origin/next -- pnpm-lock.yaml rc=0 ✓
  7. pnpm format:check — rc=0; all matched files use Prettier code style
  8. git diff --check — rc=0; no trailing whitespace or merged conflict markers
  9. New-code origin check: git diff -- apps/web/src | grep -nE '^\+.*(fetch|io|api)\(\s*[\x27\"]https?://' — rc=1 (empty result, as required)
  10. pnpm --filter @mosaicstack/web exec vitest run src/spa/pages/projects.spec.tsx src/spa/pages/project-detail.spec.tsx src/spa/pages/tasks.spec.tsx src/spa/pages/resource-route-boundaries.spec.tsx src/spa/routes.spec.tsx — rc=0; 5 files / 26 tests passed

Scope Audit

Authorized in-scope changes:

  • apps/web/package.json — dev port pins only
  • apps/web/vite.config.ts — strictPort flag only
  • apps/web/src/routes.tsx — route wiring with errorElements
  • apps/web/src/spa/pages/projects.tsx — read-only SPA list
  • apps/web/src/spa/pages/project-detail.tsx — read-only SPA detail
  • apps/web/src/spa/pages/tasks.tsx — read-only SPA list/kanban
  • apps/web/src/spa/pages/resource-route-error-boundaries.tsx — page-local error components
  • apps/web/src/spa/pages/*.spec.tsx — fixture-backed tests (4 new)
  • docs/scratchpads/webui-p4-1.md — append-only record

Out-of-scope verification:

  • .mosaic/orchestrator/session.lock — not modified/staged ✓
  • pnpm-lock.yaml — not modified ✓
  • apps/gateway/** — not modified ✓
  • packages/** — not modified ✓
  • Chat SPA — not modified ✓
  • Settings, admin, navigation, or auth flow — not modified ✓

Next Action

Commit, run authorized queue guard, and push only feat/webui-p4-1 (no PR, no merge).