docs(work): add Veect ADRs 027-029, glossary terms, first two PRDs

Records the 2026-07-12 grill-session decisions repurposing this repo
for Veect v1 as a hosted SaaS: ADR-027 (hosted distribution +
control-plane/runner split), ADR-028 (iframe canvas), ADR-029
(DesignDoc v1 canonical + editor rebuild). Seeds the work pipeline
with the platform-retrofit and walking-skeleton PRDs (approved) and
adds the Veect product-domain section to the glossary. These
consciously supersede the .proto bundle's Electron/local-first
distribution decisions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016j8z4VHjedXDTjEDNg7qHK
This commit is contained in:
2026-07-12 12:17:35 +02:00
parent ee0fec0691
commit 442b70476c
6 changed files with 415 additions and 0 deletions

View File

@@ -0,0 +1,111 @@
---
id: platform-retrofit
title: Platform retrofit — repurpose template-vertical as the Veect monorepo
type: prd
status: approved
author: Danijel Martinek
elicitation-session: session_016j8z4VHjedXDTjEDNg7qHK
created: 2026-07-12T09:05:00Z
---
## Problem
This repo is the `template-vertical` starter: five demo content features (auth, blog, media, marketing-pages, navigation), three frontend apps, and a work tree full of shipped template epics. We are building **Veect** in it — a hosted design-to-code SaaS (ADR-027) — and almost none of the demo *content* is Veect, while almost all of the *machinery* (conformance, coverage, generators, work pipeline, DI/testing conventions, compliance and instrumentation cores) is exactly what Veect needs.
Three concrete pains today:
1. **Dispatch agents cannot read the product spec.** The entire Veect specification bundle sits untracked in `.proto/` (plus a stray `veect-product-docs.zip` at root). Sandcastle implementers run in git worktrees, which contain only committed files — every PRD referencing the spec would be unreadable to the agents implementing it.
2. **The repo actively misleads.** `pnpm work status` surfaces eight shipped template epics; CLAUDE.md/AGENTS.md describe a blog/CMS starter; release-please tracks five demo features that are about to be deleted. Agent context assembled from this repo points at the wrong product.
3. **Demo content blocks the package map.** The Veect features (workspaces, projects, design-doc, discovery, ai — per the 2026-07-12 grill decisions) can't land cleanly while blog/media/navigation/marketing-pages occupy the workspace, the router/CMS composition, and the versioning config.
## Goal
The repo is a clean, truthful Veect monorepo: only Veect-relevant packages, the product docs committed and authoritative, the work pipeline showing only Veect work — with every conformance gate still green.
## In scope
- Delete demo features `blog`, `media`, `navigation`, `marketing-pages` and app `web-tanstack`, including all composition wiring (core-api router, core-cms collections, web-next pages/imports, bindAll dispatcher, seeds, e2e specs, Storybook references).
- Reduce `apps/web-next` to a compiling shell: auth (sign-in/out) + a placeholder home. `apps/cms` stays (Payload admin over the remaining collections). `apps/storybook` stays.
- Keep and leave wired: `auth` feature, `core-audit`, `core-analytics`, `core-consent`, `core-dsr`, OTel/Sentry instrumentation (ADR-027 §6 flips the spec's "no telemetry" stance).
- Scaffold `core-events` and `core-realtime` via `pnpm turbo gen core-package` (needed by the walking skeleton for runner status events/pushes).
- Migrate `.proto/veect-product-docs/``docs/product/` (committed); migrate the design references (`Veect.dc.html`, `Veect Landing.dc.html`, `Weave backup`, `veect-codebase/` prototype, upload PNGs) → `docs/product/reference/` (committed, read-only reference — the prototype codebase is **never** vendored into `packages/`, per ADR-029). Delete `veect-product-docs.zip` and the emptied `.proto/`.
- Amend the committed product README's authority table with the ADR-027/028/029 supersessions and the `Veect.dc.html` ground-truth row (ADR-029 §5).
- Archive the eight shipped template epics and their nine PRDs to `docs/work/archive/`; rebuild `_state.json` so `pnpm work status` shows only Veect work.
- Rewrite `release-please-config.json` + manifest to track the **root only** (single product version; hosted SaaS deploys continuously — per-feature versions return only if an npm distribution ships).
- Rewrite CLAUDE.md and AGENTS.md project-overview sections for Veect (control-plane/runner vocabulary, new package map, ADR-027/028/029 references); fix the "15 conformance rules" → sixteen miscount.
- Library-trace batch (`/evaluate-library`, ADR-022) for the feature-tier runtime deps the next PRD needs: `@xyflow/react`, `zustand` (v5). (Runner-side deps like execa/vite/react-docgen-typescript live in the app-tier `apps/runner` and are exempt from ADR-022; traces for them are optional hardening.)
- Verify the ESLint/turbo boundary configs and generators survive the deletions (generators are template-driven, not dependent on the deleted features).
## Out of scope
- Any new Veect feature code (walking-skeleton PRD and successors).
- The landing page (arrives with the `polish-playground-landing` PRD; this PRD deletes `marketing-pages` and leaves no marketing surface).
- Generator retargeting beyond what deletions force — the feature generator's Payload+tRPC shape is **correct** for Veect's control plane (ADR-027 §5) and stays as-is.
- Runner infrastructure, Docker images, fixtures (walking-skeleton PRD).
- Billing, GitHub App, self-host distribution (all deferred per ADR-027).
## Constraints
- ADR-027 (hosted SaaS + runner split), ADR-028 (iframe canvas), ADR-029 (DesignDoc v1 + editor rebuild) are the decision baseline; this PRD implements their repo-level consequences only.
- ADR-021 (release-please) — the versioning rewrite must keep Conventional-Commit → release automation working; ADR-022 (library traces) — pre-commit hook must pass on every slice.
- Conformance rules stay enforced throughout: every deletion slice leaves `pnpm typecheck && pnpm lint && pnpm test && pnpm conformance && pnpm fallow:audit` green — no "big bang broken middle".
- The `auth` feature's manifest, tests, and coverage bands must remain intact (it is load-bearing for Veect accounts, ADR-027 §4).
- Deletions must not orphan `docs/glossary.md` terms — the template terms describing deleted features get pruned in the same slice that deletes the feature.
## Success criteria
- `pnpm typecheck && pnpm lint && pnpm test && pnpm conformance && pnpm fallow && pnpm coverage:diff` all green on the final commit.
- `pnpm dev` boots web-next (dev-seed mode, no Payload required) with sign-in working and no imports from deleted features anywhere (`pnpm turbo boundaries` clean).
- `git ls-files docs/product/` shows the full committed spec bundle; `.proto/` and `veect-product-docs.zip` are gone.
- `pnpm work status` lists zero template epics; archived work remains greppable under `docs/work/archive/`.
- `release-please-config.json` validates and tracks only the root package.
- `docs/library-decisions/` contains approved traces for `@xyflow/react` and `zustand`.
- CLAUDE.md/AGENTS.md describe Veect (spot check: no mention of blog/media/marketing-pages as live features).
## User stories
1. As an AI implementer dispatched into a worktree, I want the product spec committed under `docs/product/`, so that I can read the authoritative requirements without host-machine access.
2. As the founder, I want `pnpm work status` to show only Veect work, so that dispatch context and prioritization aren't polluted by shipped template epics.
3. As an AI decomposer, I want CLAUDE.md/AGENTS.md/glossary to describe the Veect architecture, so that generated epics use the right vocabulary and package map.
4. As a developer, I want the repo to typecheck/test green with only auth + core packages, so that Veect features land on a stable floor.
5. As a release engineer, I want release-please to track a single product version, so that merges to main produce one meaningful release PR instead of five demo-feature bumps.
6. As an AI implementer, I want library traces for the editor's runtime deps pre-approved, so that walking-skeleton tasks don't stall on the library-policy pre-commit hook.
7. As a future contributor, I want the prototype codebase and HTML prototypes committed as reference material with a stated authority order, so that design questions have a canonical source (ADR-029 §5).
## Implementation decisions
- **Deletion order is dependency-order:** apps first (`web-tanstack`), then features (`blog`, `media`, `marketing-pages`, `navigation`), pruning each feature's wiring (core-api router anchor, core-cms collection anchor, bindAll entry, web-next UI imports, seeds, e2e) in the same slice as the package deletion. Each deletion is one slice/commit.
- **`web-next` shell:** keep the auth UI surfaces and app bootstrap (`bindAll()`, instrumentation); replace the home page with a minimal authenticated placeholder (the workspaces UI arrives in the next PRD).
- **`docs/product/` layout:** spec docs at top level (filenames preserved from the bundle); `reference/` subfolder for HTML prototypes + prototype codebase + PNGs. The prototype codebase's `package.json` stays outside pnpm workspace globs (`packages/*`, `apps/*`) by construction; add it to fallow/lint ignore lists so whole-codebase auditors skip reference material.
- **Authority amendment:** a short "Repo supersessions" section prepended to `docs/product/README.md` linking ADR-027/028/029 and adding the `Veect.dc.html` row to the authority table.
- **Work archive:** `docs/work/archive/{epics,prds}/` with a one-line README; `pnpm work rebuild-state` regenerates `_state.json`. Verify the work CLI ignores the archive path (adjust its glob if not).
- **release-please:** root-only config; `include-component-in-tag` dropped (single `v*` tags); pre-1.0 bump policy retained.
- **Optional cores:** `core-events` + `core-realtime` scaffolded by generator with their pre-shipped traces (ADR-022 "pre-shipped trace" mechanism); no consumers wired yet beyond compile-green.
- **Glossary:** Veect domain section already exists (added 2026-07-12); prune `blog`/`media`/`marketing-pages`/`navigation` mentions from the Packages section as those features are deleted; `auth` stays.
- No Payload schema changes; no new collections (those come with `workspaces` in the next PRD).
## Testing decisions
- This PRD is mostly subtractive: the test suite itself is the safety net — every slice must keep the full gate set green, and deleting a feature deletes its tests in the same slice.
- `auth` keeps its full test suite + coverage bands untouched (regression canary for the surviving floor).
- Add one boot smoke assertion (dev-seed): `bindAll()` resolves with only auth bound — proves no dangling DI symbols from deleted features (mirror the existing boot-assertion pattern in web-next's server bootstrap tests).
- Scaffolded `core-events`/`core-realtime` ship with their generator-emitted test suites; no additional coverage required until consumers exist.
- e2e: prune deleted-feature Playwright specs; keep an auth sign-in spec green as the surviving e2e baseline.
## Open questions
- Q1: Do the HTML prototypes (~640 KB total) go into git as-is or via LFS? — **As-is**; they're text, they diff, and the repo has no LFS setup to maintain.
- Q2: Should `navigation` survive temporarily as a generator reference? — **No**; the generators are template-driven (`turbo/generators/templates/`), not derived from live features. Delete all four content features.
- Q3: Keep `sentry-pii-guard.yml` CI? — **Yes**; ADR-027 keeps the Sentry/OTel stack, so the PII guard remains meaningful.
## Out of scope (deferred)
- Retargeting generator templates toward runner-side patterns (revisit after the first runner feature ships — rule-of-three).
- Security FAQ / trust documentation for design partners (needed before outreach, not before code — founder-owned, tracked in `docs/product/founder-os-audit.md`).
- npm `veect` name registration and related legal items (founder-owned).
## Further notes
- Builds on: ADR-027, ADR-028, ADR-029; the 2026-07-12 grill session decision log (13 decisions).
- Blocks: `walking-skeleton` (next PRD) — that PRD assumes the clean floor this one produces.
- The `.proto` bundle's own README §3 lists what the prototype seeds; ADR-029 supersedes its "codebase seeds packages/editor" instruction — reference-only now.

View File

@@ -0,0 +1,103 @@
---
id: walking-skeleton
title: Walking skeleton — one real component, end to end through the hosted spine
type: prd
status: approved
author: Danijel Martinek
elicitation-session: session_016j8z4VHjedXDTjEDNg7qHK
created: 2026-07-12T09:10:00Z
---
## Problem
Every Veect risk that matters lives in the seams, not the parts: control plane ↔ runner provisioning, runner ↔ repo toolchain (clone/install/dev-server of code we don't control), and editor ↔ iframe canvas across an origin boundary (ADR-028). The original tech spec front-loaded exactly this with its M0 "walking skeleton" — but its acceptance criteria ("boots with no system Node") died with the Electron distribution (ADR-027). Nothing yet proves the hosted spine works at all, and every subsequent PRD (workspaces, discovery, design-doc, codegen, projects, ai) builds on these seams. If the spine is wrong, we must find out before nine PRDs are stacked on it.
## Goal
A signed-in user connects a fixture repo; a cloud runner clones and installs it; discovery finds one real component; the editor renders that component on the board **through the repo's own Vite** in an iframe; clicking it inside the iframe selects it in the editor. One thin, honest, end-to-end vertical.
## In scope
- **`workspaces` feature (new, minimal):** `connectWorkspace` (name + git URL + PAT), `getWorkspaceStatus`, `listWorkspaces`; Workspaces Payload collection with encrypted credential storage; runner provisioning + lifecycle status events.
- **`discovery` feature (new, minimal):** registry snapshot storage; `getRegistry`; scan-result ingestion from runner events. Skeleton bar: one component with name + props from the fixture (full `ComponentMeta` fidelity comes in `discovery-and-library`).
- **`core-runner-protocol` (new core package):** versioned, zod-validated message schemas for the runner protocol (hello/ready, clone, install, scan, adapter-start, render-frame, status/error events) shared by features, editor, and runner.
- **`apps/runner` (new app):** the runner process — WS server speaking the protocol; git clone (PAT via ephemeral credential helper); package-manager install; minimal react-docgen-typescript scan; embedded-Vite preview adapter serving a frame host page with the injected **canvas agent script**; status/progress events.
- **`packages/editor` (new, minimal):** React Flow board shell, one iframe frame node, canvas-protocol client (selection round-trip), minimal zustand store. First code of the ADR-029 rebuild — stories + tests from day one.
- **`apps/web-next`:** workspace list + connect form + staged progress (cloning → installing → scanning → starting preview, the ui-gap §5 pattern); editor route hosting the board; tRPC routers for the two features; realtime push of runner status.
- **`fixtures/vite-kitchen` (new):** minimal Vite + React + TS + Tailwind repo with a `Button` component; served to tests via local bare-repo/`git daemon` helpers in `core-testing`.
- **Runner provisioning port:** `IRunnerProvisioner` with a local-child-process implementation (dev/CI) and a single-host Docker implementation (the container-per-workspace baseline of ADR-027 §2).
- Wire `core-events` (runner lifecycle events) and `core-realtime` (browser push) end to end.
## Out of scope
- Checkpoint, publish, worktrees, `projects` feature; design-doc persistence (the skeleton's frame is an ephemeral in-memory doc in the editor).
- AI compose, Polish, history, multi-view frames, isolation, code panel.
- Next.js adapter (`preview-and-nextjs-depth`); watch/HMR and perf-500 budgets (`discovery-and-library`); full connect UX states — org walls, trust prompt, env manager (`workspaces-and-connections`).
- Local runner / CLI agent (`local-runner-cli`); quotas, metering, billing.
- Real GitHub/GitLab connections beyond git-URL+PAT against fixtures; runner fleet orchestration, hibernation, egress policy hardening (single-host Docker is the v1 baseline; hardening tracked in `workspaces-and-connections`).
## Constraints
- ADR-027: container-per-workspace is the cloud baseline; runner protocol is plain WS/JSON (not tRPC); credentials never in URLs/argv/logs (spec §6 credential-helper rules apply verbatim).
- ADR-028: the component renders through the repo's own toolchain in a cross-origin iframe with pinned `targetOrigin`; **no NodeRenderer on the board path**; chrome (selection rings) renders as editor-side overlays from agent-reported geometry.
- ADR-029: editor code follows template conventions from the first commit (`component-must-have-story`/`-test`); React 19; no prototype vendoring.
- Conformance: manifest-first for every use case in both new features; generator-first (`pnpm turbo gen feature`) for `workspaces` and `discovery`; ADR-022 traces for any new feature/core-tier runtime dep (editor deps pre-approved by `platform-retrofit`).
- Budgets (adapted from spec §16): connect-to-rendered-component < 3 min on the warm fixture; board pan/zoom stays editor-side (< 16 ms/frame no protocol round-trip on drag).
- Security floor even at fixture scale: runner containers get no cross-tenant network; the agent script is Veect-authored, adapter-injected, never sourced from the repo (ADR-028 §consequences).
## Success criteria
- Full gate set green: `pnpm typecheck && pnpm lint && pnpm test && pnpm conformance && pnpm fallow:audit && pnpm coverage:diff`.
- e2e (Playwright, local-process provisioner): sign in connect `vite-kitchen` via git URL + PAT staged progress completes editor shows `Button` rendered inside the adapter's iframe (assert on iframe content, not a screenshot double) click the button in the iframe editor selection overlay appears and the selection state names the component. This is the M0-recast acceptance.
- The same flow works with the Docker provisioner on a dev machine (documented manual check; CI uses the process provisioner).
- Protocol integration suite passes against a real spawned runner + local git fixture: clone install scan returns 1 component adapter serves the frame host with the agent script.
- Credential never appears in any log, process argv, or `.git/config` in the runner workspace (asserted by the integration suite, per spec §15).
- Both feature manifests declare their use cases, events, and realtime channels; boot assertion green in dev-seed and production modes.
## User stories
1. As a signed-in user, I want to connect a repository by git URL + token, so that Veect can turn it into a design surface.
2. As a user, I want staged, honest progress while my repo clones and installs, so that a minutes-long operation never looks hung.
3. As a user, I want the editor to show my repo's real component rendered by my repo's own toolchain, so that what I see is exactly what ships (invariant #1).
4. As a user, I want to click a component on the canvas and see it selected, so that direct manipulation is proven across the iframe boundary.
5. As a user, I want a clear, named error state when clone or install fails (bad URL, bad token, install failure), so that I know the cause and next action never a blank board.
6. As the control plane operator, I want each workspace's repo code executing in its own isolated runner, so that a malicious repo cannot touch other tenants (ADR-027).
7. As an AI implementer, I want the runner protocol schemas in one shared package, so that features, editor, and runner cannot drift apart silently.
8. As a developer, I want the whole skeleton to run with a local-process runner and dev-seed mode, so that `pnpm dev` + fixtures need no cloud resources.
## Implementation decisions
- **Protocol:** WS + JSON messages, every message zod-parsed against `core-runner-protocol` schemas, envelope carries `protocolVersion: "0"` and workspace-scoped auth token. Progress is event-streamed (stage + elapsed), mirroring the ui-gap §5 staged-progress pattern.
- **Provisioning port:** `IRunnerProvisioner` (service port in `workspaces` infrastructure): `provision(workspaceId) → RunnerHandle`, `terminate`, `status`. Implementations: local child process (dev/test) and Docker single-host (dockerode or docker CLI app/infra-tier choice at implementation time). Fleet orchestration is explicitly a later concern behind the same port.
- **Credential handling:** PAT stored in the Workspaces collection encrypted AES-256-GCM with a key derived (scrypt) from `VEECT_SECRET` (the spec §13 Docker mechanism, now the primary); decrypted only server-side, passed to the runner over the authenticated protocol channel, delivered to git via ephemeral credential helper (spec §6 mechanics verbatim). The Payload API never returns the credential (write-only field).
- **Runner internals (app-tier, imperative code is expected here):** clone detect package manager install (progress events) scan (react-docgen-typescript over the fixture's component glob) start embedded Vite rooted at the clone with a Veect frame-host entry that imports the requested component and mounts the agent script. Dedicated port = dedicated origin per adapter (spec §9).
- **Canvas agent v0:** reports `runtime.ready`, component bounding boxes (post `fonts.loaded`), and click-target resolution; editor overlays selection ring from reported geometry. Pinned `targetOrigin` both directions.
- **Editor v0:** React Flow board with one frame node hosting the adapter iframe; zustand store holds registry + selection only (no document tree yet DesignDoc v1 arrives with `design-doc-and-editor-foundation`); the frame renders a single Element (the discovered component with default props) requested via `render-frame`.
- **Events/realtime:** runner lifecycle (`workspaces` publishes `runner-status-changed`; realtime channel pushes stage progress + adapter-ready to the browser). Registry snapshots land via `discovery` ingesting the scan event cross-feature reaction through `core-events`, per rule E0.
- **Manifests:** `workspaces` declares `connectWorkspace` (mutates, audits: workspace-connected), `getWorkspaceStatus`, `listWorkspaces`, publishes runner events, realtime channel; `discovery` declares `getRegistry`, consumes the scan event. Coverage bands: template defaults for both features (use cases are thin orchestration; the heavy imperative code lives in `apps/runner`, covered by the integration suite the honest-bands rationale from the grill session).
- **Fixtures:** `fixtures/` at repo root, outside pnpm workspace and turbo graph; `core-testing` gains helpers to serve a fixture as a bare repo over the git protocol for tests.
## Testing decisions
- **Use-case unit tests** for every declared use case (conformance-mandated), mocks injected directly.
- **Repository contract suite** for the Workspaces repository (mock + Payload impls) including the write-only credential field behavior.
- **Protocol integration suite** (the load-bearing one): spawns a real runner (process provisioner) against a `git daemon`-served `vite-kitchen`, drives cloneinstallscanadapter over real WS, asserts registry payload, adapter origin liveness, staged events, and credential-leak absence (grep argv/logs/`.git/config`). Runs in CI on ubuntu.
- **Editor:** stories + component tests for board/frame/overlay per conformance rules; canvas-protocol client unit-tested against a scripted agent double.
- **e2e:** the Playwright spec described in Success criteria, dev-seed + process provisioner, tagged as the repo's flagship spec.
- **Good test** here means: assert through the protocol and the UI, never against runner internals the runner must stay refactorable while the protocol is the contract.
## Open questions
- Q1: dockerode vs docker CLI for the Docker provisioner? **docker CLI via execa** (fewer moving parts, app-tier so no trace required); revisit with fleet work.
- Q2: Does the skeleton editor live at a real route (`/w/[workspace]`) or a dev-only page? **Real route**, minimal; it becomes the editor's permanent home and later PRDs extend it.
- Q3: Runner base image? **node:22-bookworm-slim + git**, pinned digest; doctor-style version checks come with `workspaces-and-connections`.
## Out of scope (deferred)
- Everything listed per-PRD in Out of scope above; plus runner resource limits tuning, egress allowlisting beyond Docker network defaults, and workspace hibernation tracked in `workspaces-and-connections`.
## Further notes
- Builds on: `platform-retrofit` (clean floor, traces, scaffolded cores). Blocks: every subsequent Veect PRD.
- Authority: ADR-027/028/029; tech spec §6 (credential mechanics), §9 (adapter/protocol), §15 (fixture + leak-assertion testing), §16 (budgets); ui-gap §5 (staged progress pattern).
- The spec's M0 acceptance ("no system Node", "`git status` untouched") is superseded by this PRD's Success criteria hosted equivalents: isolated runner, credential-leak assertions, honest progress.