docs(work): decompose platform-retrofit and walking-skeleton epics
platform-retrofit: 8 stories / 18 tasks (spec bundle into docs/product, single-version release-please before deletions, demo feature removal, web-next auth shell, optional cores, work-tree archive, library traces, agent-doc rewrite). walking-skeleton: 11 stories / 28 tasks across workspaces, discovery, core-runner-protocol, runner app, editor, and the flagship connect-to-selection e2e; builds on platform-retrofit (prose dependency note — cross-epic frontmatter unsupported). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016j8z4VHjedXDTjEDNg7qHK
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"updated_at": "2026-05-20T12:57:04.572Z",
|
"updated_at": "2026-07-12T10:28:27.450Z",
|
||||||
"epics": {
|
"epics": {
|
||||||
"binder-wrap-helper": {
|
"binder-wrap-helper": {
|
||||||
"status": "done",
|
"status": "done",
|
||||||
@@ -537,6 +537,93 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"platform-retrofit": {
|
||||||
|
"status": "in-progress",
|
||||||
|
"title": "Platform retrofit — repurpose template-vertical as the Veect monorepo",
|
||||||
|
"prd": "docs/work/prds/platform-retrofit.prd.md",
|
||||||
|
"stories": {
|
||||||
|
"01-commit-product-docs": {
|
||||||
|
"status": "in-progress",
|
||||||
|
"title": "Commit the product spec and design references under docs/product/",
|
||||||
|
"ac_total": 3,
|
||||||
|
"ac_completed": 0,
|
||||||
|
"depends_on": [],
|
||||||
|
"blocks": [
|
||||||
|
"08-rewrite-agent-docs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"02-single-version-release-please": {
|
||||||
|
"status": "todo",
|
||||||
|
"title": "Rewrite release-please to a single root product version",
|
||||||
|
"ac_total": 1,
|
||||||
|
"ac_completed": 0,
|
||||||
|
"depends_on": [],
|
||||||
|
"blocks": [
|
||||||
|
"03-delete-demo-apps-and-features",
|
||||||
|
"08-rewrite-agent-docs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"03-delete-demo-apps-and-features": {
|
||||||
|
"status": "todo",
|
||||||
|
"title": "Delete web-tanstack and the four demo content features",
|
||||||
|
"ac_total": 5,
|
||||||
|
"ac_completed": 0,
|
||||||
|
"depends_on": [
|
||||||
|
"02-single-version-release-please"
|
||||||
|
],
|
||||||
|
"blocks": [
|
||||||
|
"04-web-next-shell",
|
||||||
|
"08-rewrite-agent-docs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"04-web-next-shell": {
|
||||||
|
"status": "todo",
|
||||||
|
"title": "Reduce web-next to an auth shell with a boot smoke assertion",
|
||||||
|
"ac_total": 2,
|
||||||
|
"ac_completed": 0,
|
||||||
|
"depends_on": [
|
||||||
|
"03-delete-demo-apps-and-features"
|
||||||
|
],
|
||||||
|
"blocks": [
|
||||||
|
"08-rewrite-agent-docs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"05-scaffold-optional-cores": {
|
||||||
|
"status": "todo",
|
||||||
|
"title": "Scaffold core-events and core-realtime",
|
||||||
|
"ac_total": 2,
|
||||||
|
"ac_completed": 0,
|
||||||
|
"depends_on": [],
|
||||||
|
"blocks": [
|
||||||
|
"08-rewrite-agent-docs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"06-archive-template-work": {
|
||||||
|
"status": "todo",
|
||||||
|
"title": "Archive the shipped template work tree",
|
||||||
|
"ac_total": 1,
|
||||||
|
"ac_completed": 0,
|
||||||
|
"depends_on": [],
|
||||||
|
"blocks": []
|
||||||
|
},
|
||||||
|
"07-editor-library-traces": {
|
||||||
|
"status": "todo",
|
||||||
|
"title": "Library traces for @xyflow/react and zustand",
|
||||||
|
"ac_total": 2,
|
||||||
|
"ac_completed": 0,
|
||||||
|
"depends_on": [],
|
||||||
|
"blocks": []
|
||||||
|
},
|
||||||
|
"08-rewrite-agent-docs": {
|
||||||
|
"status": "todo",
|
||||||
|
"title": "Rewrite CLAUDE.md and AGENTS.md for Veect",
|
||||||
|
"ac_total": 2,
|
||||||
|
"ac_completed": 0,
|
||||||
|
"depends_on": [],
|
||||||
|
"blocks": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"product-analytics-channel": {
|
"product-analytics-channel": {
|
||||||
"status": "done",
|
"status": "done",
|
||||||
"title": "Product analytics as a fourth capture channel (ADR-024 implementation)",
|
"title": "Product analytics as a fourth capture channel (ADR-024 implementation)",
|
||||||
@@ -756,9 +843,262 @@
|
|||||||
"blocks": []
|
"blocks": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"walking-skeleton": {
|
||||||
|
"status": "in-progress",
|
||||||
|
"title": "Walking skeleton — one real component, end to end through the hosted spine",
|
||||||
|
"prd": "docs/work/prds/walking-skeleton.prd.md",
|
||||||
|
"stories": {
|
||||||
|
"01-vite-kitchen-fixture": {
|
||||||
|
"status": "in-progress",
|
||||||
|
"title": "vite-kitchen fixture + git-serving test helpers",
|
||||||
|
"ac_total": 2,
|
||||||
|
"ac_completed": 0,
|
||||||
|
"depends_on": [],
|
||||||
|
"blocks": [
|
||||||
|
"04-runner-app-protocol-clone-install"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"02-core-runner-protocol": {
|
||||||
|
"status": "todo",
|
||||||
|
"title": "core-runner-protocol package — versioned, zod-validated message schemas",
|
||||||
|
"ac_total": 2,
|
||||||
|
"ac_completed": 0,
|
||||||
|
"depends_on": [],
|
||||||
|
"blocks": [
|
||||||
|
"04-runner-app-protocol-clone-install",
|
||||||
|
"09-editor-package"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"03-workspaces-feature-core": {
|
||||||
|
"status": "todo",
|
||||||
|
"title": "workspaces feature core — connect, status, list + encrypted credential storage",
|
||||||
|
"ac_total": 4,
|
||||||
|
"ac_completed": 0,
|
||||||
|
"depends_on": [],
|
||||||
|
"blocks": []
|
||||||
|
},
|
||||||
|
"04-runner-app-protocol-clone-install": {
|
||||||
|
"status": "todo",
|
||||||
|
"title": "runner app — protocol server, clone stage, install stage",
|
||||||
|
"ac_total": 3,
|
||||||
|
"ac_completed": 0,
|
||||||
|
"depends_on": [
|
||||||
|
"01-vite-kitchen-fixture",
|
||||||
|
"02-core-runner-protocol"
|
||||||
|
],
|
||||||
|
"blocks": [
|
||||||
|
"05-runner-scan-and-preview-adapter",
|
||||||
|
"06-runner-provisioner-port"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"05-runner-scan-and-preview-adapter": {
|
||||||
|
"status": "todo",
|
||||||
|
"title": "runner scan stage + embedded-Vite preview adapter + canvas agent v0",
|
||||||
|
"ac_total": 2,
|
||||||
|
"ac_completed": 0,
|
||||||
|
"depends_on": [
|
||||||
|
"04-runner-app-protocol-clone-install"
|
||||||
|
],
|
||||||
|
"blocks": [
|
||||||
|
"07-runner-lifecycle-events-and-realtime"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"06-runner-provisioner-port": {
|
||||||
|
"status": "todo",
|
||||||
|
"title": "IRunnerProvisioner port + local-process and single-host Docker implementations",
|
||||||
|
"ac_total": 2,
|
||||||
|
"ac_completed": 0,
|
||||||
|
"depends_on": [
|
||||||
|
"03-workspaces-feature-core",
|
||||||
|
"04-runner-app-protocol-clone-install"
|
||||||
|
],
|
||||||
|
"blocks": [
|
||||||
|
"07-runner-lifecycle-events-and-realtime"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"07-runner-lifecycle-events-and-realtime": {
|
||||||
|
"status": "todo",
|
||||||
|
"title": "runner lifecycle — status events, scan event, realtime channel",
|
||||||
|
"ac_total": 3,
|
||||||
|
"ac_completed": 0,
|
||||||
|
"depends_on": [],
|
||||||
|
"blocks": [
|
||||||
|
"08-discovery-feature",
|
||||||
|
"10-web-next-wiring"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"08-discovery-feature": {
|
||||||
|
"status": "todo",
|
||||||
|
"title": "discovery feature — registry snapshots, getRegistry, scan ingestion",
|
||||||
|
"ac_total": 3,
|
||||||
|
"ac_completed": 0,
|
||||||
|
"depends_on": [
|
||||||
|
"07-runner-lifecycle-events-and-realtime"
|
||||||
|
],
|
||||||
|
"blocks": [
|
||||||
|
"10-web-next-wiring"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"09-editor-package": {
|
||||||
|
"status": "todo",
|
||||||
|
"title": "editor package — React Flow board, iframe frame node, canvas-protocol client",
|
||||||
|
"ac_total": 3,
|
||||||
|
"ac_completed": 0,
|
||||||
|
"depends_on": [
|
||||||
|
"02-core-runner-protocol"
|
||||||
|
],
|
||||||
|
"blocks": [
|
||||||
|
"10-web-next-wiring"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10-web-next-wiring": {
|
||||||
|
"status": "todo",
|
||||||
|
"title": "web-next wiring — connect UX, staged progress, editor route",
|
||||||
|
"ac_total": 3,
|
||||||
|
"ac_completed": 0,
|
||||||
|
"depends_on": [],
|
||||||
|
"blocks": [
|
||||||
|
"11-flagship-e2e"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"11-flagship-e2e": {
|
||||||
|
"status": "todo",
|
||||||
|
"title": "flagship e2e — connect vite-kitchen to selection round-trip",
|
||||||
|
"ac_total": 1,
|
||||||
|
"ac_completed": 0,
|
||||||
|
"depends_on": [
|
||||||
|
"10-web-next-wiring"
|
||||||
|
],
|
||||||
|
"blocks": []
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ready": [],
|
"ready": [
|
||||||
"blocked": [],
|
{
|
||||||
|
"epic": "platform-retrofit",
|
||||||
|
"story": "01-commit-product-docs",
|
||||||
|
"title": "Commit the product spec and design references under docs/product/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"epic": "platform-retrofit",
|
||||||
|
"story": "02-single-version-release-please",
|
||||||
|
"title": "Rewrite release-please to a single root product version"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"epic": "platform-retrofit",
|
||||||
|
"story": "05-scaffold-optional-cores",
|
||||||
|
"title": "Scaffold core-events and core-realtime"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"epic": "platform-retrofit",
|
||||||
|
"story": "06-archive-template-work",
|
||||||
|
"title": "Archive the shipped template work tree"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"epic": "platform-retrofit",
|
||||||
|
"story": "07-editor-library-traces",
|
||||||
|
"title": "Library traces for @xyflow/react and zustand"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"epic": "platform-retrofit",
|
||||||
|
"story": "08-rewrite-agent-docs",
|
||||||
|
"title": "Rewrite CLAUDE.md and AGENTS.md for Veect"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"epic": "walking-skeleton",
|
||||||
|
"story": "01-vite-kitchen-fixture",
|
||||||
|
"title": "vite-kitchen fixture + git-serving test helpers"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"epic": "walking-skeleton",
|
||||||
|
"story": "02-core-runner-protocol",
|
||||||
|
"title": "core-runner-protocol package — versioned, zod-validated message schemas"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"epic": "walking-skeleton",
|
||||||
|
"story": "03-workspaces-feature-core",
|
||||||
|
"title": "workspaces feature core — connect, status, list + encrypted credential storage"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"epic": "walking-skeleton",
|
||||||
|
"story": "07-runner-lifecycle-events-and-realtime",
|
||||||
|
"title": "runner lifecycle — status events, scan event, realtime channel"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"epic": "walking-skeleton",
|
||||||
|
"story": "10-web-next-wiring",
|
||||||
|
"title": "web-next wiring — connect UX, staged progress, editor route"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"blocked": [
|
||||||
|
{
|
||||||
|
"epic": "platform-retrofit",
|
||||||
|
"story": "03-delete-demo-apps-and-features",
|
||||||
|
"title": "Delete web-tanstack and the four demo content features",
|
||||||
|
"waiting_on": [
|
||||||
|
"platform-retrofit/02-single-version-release-please"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"epic": "platform-retrofit",
|
||||||
|
"story": "04-web-next-shell",
|
||||||
|
"title": "Reduce web-next to an auth shell with a boot smoke assertion",
|
||||||
|
"waiting_on": [
|
||||||
|
"platform-retrofit/03-delete-demo-apps-and-features"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"epic": "walking-skeleton",
|
||||||
|
"story": "04-runner-app-protocol-clone-install",
|
||||||
|
"title": "runner app — protocol server, clone stage, install stage",
|
||||||
|
"waiting_on": [
|
||||||
|
"walking-skeleton/01-vite-kitchen-fixture",
|
||||||
|
"walking-skeleton/02-core-runner-protocol"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"epic": "walking-skeleton",
|
||||||
|
"story": "05-runner-scan-and-preview-adapter",
|
||||||
|
"title": "runner scan stage + embedded-Vite preview adapter + canvas agent v0",
|
||||||
|
"waiting_on": [
|
||||||
|
"walking-skeleton/04-runner-app-protocol-clone-install"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"epic": "walking-skeleton",
|
||||||
|
"story": "06-runner-provisioner-port",
|
||||||
|
"title": "IRunnerProvisioner port + local-process and single-host Docker implementations",
|
||||||
|
"waiting_on": [
|
||||||
|
"walking-skeleton/03-workspaces-feature-core",
|
||||||
|
"walking-skeleton/04-runner-app-protocol-clone-install"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"epic": "walking-skeleton",
|
||||||
|
"story": "08-discovery-feature",
|
||||||
|
"title": "discovery feature — registry snapshots, getRegistry, scan ingestion",
|
||||||
|
"waiting_on": [
|
||||||
|
"walking-skeleton/07-runner-lifecycle-events-and-realtime"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"epic": "walking-skeleton",
|
||||||
|
"story": "09-editor-package",
|
||||||
|
"title": "editor package — React Flow board, iframe frame node, canvas-protocol client",
|
||||||
|
"waiting_on": [
|
||||||
|
"walking-skeleton/02-core-runner-protocol"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"epic": "walking-skeleton",
|
||||||
|
"story": "11-flagship-e2e",
|
||||||
|
"title": "flagship e2e — connect vite-kitchen to selection round-trip",
|
||||||
|
"waiting_on": [
|
||||||
|
"walking-skeleton/10-web-next-wiring"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
"needs_prd_ship": []
|
"needs_prd_ship": []
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
---
|
||||||
|
id: 01-commit-product-docs
|
||||||
|
epic: platform-retrofit
|
||||||
|
title: Commit the product spec and design references under docs/product/
|
||||||
|
type: technical-story
|
||||||
|
status: in-progress
|
||||||
|
feature: docs
|
||||||
|
depends-on: []
|
||||||
|
blocks: [08-rewrite-agent-docs]
|
||||||
|
created: 2026-07-12T10:22:00Z
|
||||||
|
---
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
The full Veect specification bundle is committed and authoritative under `docs/product/`: spec docs at top level (filenames preserved from the `.proto/veect-product-docs/` bundle), design references (`Veect.dc.html`, `Veect Landing.dc.html`, the Weave backup, the `veect-codebase/` prototype, upload PNGs) under `docs/product/reference/`, the product README amended with the ADR-027/028/029 supersessions and the `Veect.dc.html` ground-truth authority row (ADR-029 §5). `veect-product-docs.zip` and the emptied `.proto/` are gone.
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
Sandcastle implementers run in git worktrees, which contain only committed files — every PRD referencing the spec would be unreadable to the agents implementing it while the bundle sits untracked in `.proto/`. Committing the spec makes it the canonical source dispatch agents can read (PRD user stories 1 and 7).
|
||||||
|
|
||||||
|
## Done when
|
||||||
|
|
||||||
|
- `git ls-files docs/product/` shows the full committed spec bundle; `.proto/` and `veect-product-docs.zip` no longer exist.
|
||||||
|
- Design references live under `docs/product/reference/`; the prototype codebase is NOT vendored into `packages/` (ADR-029) and its `package.json` stays outside the pnpm workspace globs (`packages/*`, `apps/*`) by construction.
|
||||||
|
- Fallow/lint ignore lists skip `docs/product/reference/` so whole-codebase auditors don't flag reference material.
|
||||||
|
- `docs/product/README.md` opens with a short "Repo supersessions" section linking ADR-027/028/029, and its authority table includes the `Veect.dc.html` ground-truth row.
|
||||||
|
- HTML prototypes committed as-is (no LFS — PRD Q1).
|
||||||
|
- `pnpm typecheck && pnpm lint && pnpm test && pnpm conformance && pnpm fallow:audit && pnpm coverage:diff` pass on every commit.
|
||||||
|
|
||||||
|
## In scope
|
||||||
|
|
||||||
|
- Moving `.proto/veect-product-docs/*` → `docs/product/` (top level, filenames preserved).
|
||||||
|
- Moving the design references from `.proto/design/` → `docs/product/reference/`.
|
||||||
|
- Deleting `veect-product-docs.zip` (repo root) and the emptied `.proto/` directory.
|
||||||
|
- Fallow/lint ignore-list entries for `docs/product/reference/`.
|
||||||
|
- The "Repo supersessions" + authority-table amendment to `docs/product/README.md`.
|
||||||
|
|
||||||
|
## Out of scope
|
||||||
|
|
||||||
|
- Vendoring the prototype codebase into `packages/` (never — ADR-029).
|
||||||
|
- CLAUDE.md/AGENTS.md updates that point at `docs/product/` (story 08).
|
||||||
|
- Any edits to the spec documents' content beyond the README amendment.
|
||||||
|
|
||||||
|
## Tasks
|
||||||
|
|
||||||
|
- [ ] Migrate the spec bundle `.proto/veect-product-docs/` → `docs/product/` (top level, filenames preserved) and delete the stray `veect-product-docs.zip` at the repo root — spec docs committed and greppable; all gates pass on this commit.
|
||||||
|
- [ ] Migrate the design references from `.proto/design/` → `docs/product/reference/` (HTML prototypes as-is, `veect-codebase/` prototype, upload PNGs and remaining bundle files), add `docs/product/reference/` to the fallow/lint ignore lists so whole-codebase auditors skip reference material, and delete the emptied `.proto/` — one commit, all gates pass.
|
||||||
|
- [ ] Amend `docs/product/README.md`: prepend a short "Repo supersessions" section linking ADR-027/028/029 and add the `Veect.dc.html` ground-truth row to the authority table (ADR-029 §5) — one commit, all gates pass.
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
---
|
||||||
|
id: 02-single-version-release-please
|
||||||
|
epic: platform-retrofit
|
||||||
|
title: Rewrite release-please to a single root product version
|
||||||
|
type: technical-story
|
||||||
|
status: todo
|
||||||
|
feature: tooling
|
||||||
|
depends-on: []
|
||||||
|
blocks: [03-delete-demo-apps-and-features, 08-rewrite-agent-docs]
|
||||||
|
created: 2026-07-12T10:22:00Z
|
||||||
|
---
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
`release-please-config.json` + `.release-please-manifest.json` track the root package only — a single product version with plain `v*` tags (`include-component-in-tag` dropped), pre-1.0 bump policy retained. Veect is a hosted SaaS that deploys continuously; per-feature versions return only if an npm distribution ships.
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
release-please currently tracks five demo feature packages that stories 03/04 delete. Rewriting to root-only FIRST keeps ADR-021's Conventional-Commit → release automation working through the deletions: if a deletion commit touched a still-tracked `packages/<feature>/**` path, release-please would try to bump a package whose `package.json` no longer exists. Story 03 therefore depends on this story (PRD user story 5 + ADR-021 constraint).
|
||||||
|
|
||||||
|
## Done when
|
||||||
|
|
||||||
|
- `release-please-config.json` validates against its schema and tracks only `"."`.
|
||||||
|
- `include-component-in-tag` is dropped (single `v*` tags); pre-1.0 bump policy (`bump-patch-for-minor-pre-major`) retained; changelog sections retained.
|
||||||
|
- `.release-please-manifest.json` contains only the root entry.
|
||||||
|
- Any release-please CI workflow references to per-package components still work.
|
||||||
|
- `pnpm typecheck && pnpm lint && pnpm test && pnpm conformance && pnpm fallow:audit && pnpm coverage:diff` pass.
|
||||||
|
|
||||||
|
## In scope
|
||||||
|
|
||||||
|
- `release-please-config.json`, `.release-please-manifest.json`, and any CI workflow wiring that assumes per-component tags.
|
||||||
|
|
||||||
|
## Out of scope
|
||||||
|
|
||||||
|
- Deleting the feature packages themselves (story 03).
|
||||||
|
- Renaming the root package (`template-vertical` → product name changes belong to the docs rewrite only if the PRD's next-PRD work requires it; this story touches versioning config only).
|
||||||
|
- Retagging or rewriting existing git tags/releases.
|
||||||
|
|
||||||
|
## Tasks
|
||||||
|
|
||||||
|
- [ ] Rewrite `release-please-config.json` to track the root package only (drop the five `packages/*` entries and `include-component-in-tag`, keep the pre-1.0 bump policy and changelog sections), shrink `.release-please-manifest.json` to the root entry, and adjust any release CI workflow that assumed per-component tags — config validates, one commit, all gates pass.
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
---
|
||||||
|
id: 03-delete-demo-apps-and-features
|
||||||
|
epic: platform-retrofit
|
||||||
|
title: Delete web-tanstack and the four demo content features
|
||||||
|
type: technical-story
|
||||||
|
status: todo
|
||||||
|
feature: web-tanstack, blog, media, marketing-pages, navigation
|
||||||
|
depends-on: [02-single-version-release-please]
|
||||||
|
blocks: [04-web-next-shell, 08-rewrite-agent-docs]
|
||||||
|
created: 2026-07-12T10:22:00Z
|
||||||
|
---
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
`apps/web-tanstack` and the demo features `blog`, `media`, `marketing-pages`, `navigation` are gone, including all composition wiring: core-api router anchors, core-cms collection anchors, web-next pages/imports, the bindAll dispatcher entries, seeds, e2e specs, and Storybook references. Only `auth` remains at the feature tier. Deletion order is dependency-order — app first, then features — and each deletion is one slice/commit that leaves every gate green.
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
The demo content blocks the package map: the Veect features (workspaces, projects, design-doc, discovery, ai) can't land cleanly while blog/media/navigation/marketing-pages occupy the workspace, the router/CMS composition, and the app surfaces (PRD user story 4). The generators are template-driven (`turbo/generators/templates/`), not derived from live features, so all four content features go (PRD Q2).
|
||||||
|
|
||||||
|
## Done when
|
||||||
|
|
||||||
|
- `apps/web-tanstack`, `packages/blog`, `packages/media`, `packages/marketing-pages`, `packages/navigation` no longer exist; no imports from deleted features anywhere; `pnpm turbo boundaries` clean.
|
||||||
|
- Each deleted feature's wiring (core-api router anchor, core-cms collection anchor, bindAll entry, web-next UI imports, seeds, e2e specs, Storybook references) was pruned in the same slice as the package deletion.
|
||||||
|
- `docs/glossary.md` Packages-section terms describing each deleted feature were pruned in the same slice that deleted the feature (no orphaned glossary terms); `auth` entries stay.
|
||||||
|
- The `auth` feature's manifest, tests, and coverage bands are untouched (regression canary — ADR-027 §4).
|
||||||
|
- ESLint/turbo boundary configs and the generators survived the deletions (spot-check: `pnpm turbo gen feature` still scaffolds; any config a deletion breaks is fixed inside that same slice).
|
||||||
|
- `pnpm typecheck && pnpm lint && pnpm test && pnpm conformance && pnpm fallow:audit && pnpm coverage:diff` pass on EVERY slice — no big-bang broken middle.
|
||||||
|
|
||||||
|
## In scope
|
||||||
|
|
||||||
|
- The five deletion slices and their wiring/seed/e2e/Storybook/glossary pruning.
|
||||||
|
- Fixing any ESLint/turbo boundary config or generator breakage a deletion causes, inside the causing slice.
|
||||||
|
|
||||||
|
## Out of scope
|
||||||
|
|
||||||
|
- Replacing the web-next home page and the boot smoke assertion (story 04).
|
||||||
|
- Deleting `auth`, `apps/cms`, `apps/storybook`, or any core package — they stay wired.
|
||||||
|
- Generator retargeting beyond what deletions force (PRD out of scope).
|
||||||
|
|
||||||
|
## Tasks
|
||||||
|
|
||||||
|
- [ ] Delete `apps/web-tanstack` and all its wiring in one slice — workspace/turbo entries, root scripts, CI references (e.g. `WEB_TANSTACK_SENTRY_DSN` / `VITE_` DSN wiring), e2e project entries — one commit, all gates green.
|
||||||
|
- [ ] Delete `packages/blog` and prune its composition wiring in the same slice — core-api router anchor, core-cms collection anchor, bindAll entry, web-next pages/imports, seeds, e2e specs, Storybook references, glossary terms — one commit, all gates green.
|
||||||
|
- [ ] Delete `packages/media` and prune its composition wiring in the same slice (same checklist as blog) — one commit, all gates green.
|
||||||
|
- [ ] Delete `packages/marketing-pages` and prune its composition wiring in the same slice (same checklist; includes its cross-feature event handlers consuming auth events) — one commit, all gates green.
|
||||||
|
- [ ] Delete `packages/navigation` and prune its composition wiring in the same slice (same checklist) — one commit, all gates green.
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
---
|
||||||
|
id: 04-web-next-shell
|
||||||
|
epic: platform-retrofit
|
||||||
|
title: Reduce web-next to an auth shell with a boot smoke assertion
|
||||||
|
type: technical-story
|
||||||
|
status: todo
|
||||||
|
feature: web-next
|
||||||
|
depends-on: [03-delete-demo-apps-and-features]
|
||||||
|
blocks: [08-rewrite-agent-docs]
|
||||||
|
created: 2026-07-12T10:22:00Z
|
||||||
|
---
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
`apps/web-next` is a compiling shell: auth (sign-in/out) plus a minimal authenticated placeholder home page. The app bootstrap stays intact — `bindAll()`, instrumentation — and a dev-seed boot smoke test asserts `bindAll()` resolves with only auth bound, proving no dangling DI symbols from the deleted features. `apps/cms` (Payload admin over the remaining collections) and `apps/storybook` stay as-is.
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
Veect features land on a stable floor: the repo must typecheck/test green with only auth + core packages (PRD user story 4). The workspaces UI that replaces the placeholder arrives with the next PRD (walking skeleton), so the shell needs to prove exactly one thing — sign-in works and nothing references deleted features.
|
||||||
|
|
||||||
|
## Done when
|
||||||
|
|
||||||
|
- `pnpm dev` boots web-next in dev-seed mode (no Payload required) with sign-in working.
|
||||||
|
- The home page is a minimal authenticated placeholder; auth UI surfaces and app bootstrap (`bindAll()`, instrumentation) are untouched.
|
||||||
|
- A dev-seed boot smoke test asserts `bindAll()` resolves with only auth bound (mirrors the existing boot-assertion pattern in web-next's server bootstrap tests).
|
||||||
|
- The auth sign-in Playwright spec is green as the surviving e2e baseline.
|
||||||
|
- `pnpm typecheck && pnpm lint && pnpm test && pnpm conformance && pnpm fallow:audit && pnpm coverage:diff` pass on every commit.
|
||||||
|
|
||||||
|
## In scope
|
||||||
|
|
||||||
|
- Replacing the web-next home page with a minimal authenticated placeholder; removing any remaining demo-content leftovers in web-next (layouts, nav chrome, metadata).
|
||||||
|
- The boot smoke assertion in web-next's server bootstrap tests.
|
||||||
|
- Keeping the auth e2e sign-in spec green.
|
||||||
|
|
||||||
|
## Out of scope
|
||||||
|
|
||||||
|
- The workspaces UI / any new Veect feature surface (walking-skeleton PRD).
|
||||||
|
- The landing page (`polish-playground-landing` PRD — this epic leaves no marketing surface).
|
||||||
|
- Changes to `apps/cms` or `apps/storybook`.
|
||||||
|
- Auth feature changes — its manifest, tests, and coverage bands stay untouched.
|
||||||
|
|
||||||
|
## Tasks
|
||||||
|
|
||||||
|
- [ ] Replace the web-next home page with a minimal authenticated placeholder, keeping the auth UI surfaces (sign-in/out) and app bootstrap (`bindAll()`, instrumentation) intact, and remove any remaining demo-content leftovers in the app — one commit, all gates green, auth e2e spec still passing.
|
||||||
|
- [ ] Add the dev-seed boot smoke assertion: a web-next server bootstrap test proving `bindAll()` resolves with only auth bound (no dangling DI symbols from deleted features), mirroring the existing boot-assertion pattern — one commit, all gates green.
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
---
|
||||||
|
id: 05-scaffold-optional-cores
|
||||||
|
epic: platform-retrofit
|
||||||
|
title: Scaffold core-events and core-realtime
|
||||||
|
type: technical-story
|
||||||
|
status: todo
|
||||||
|
feature: core-events, core-realtime
|
||||||
|
depends-on: []
|
||||||
|
blocks: [08-rewrite-agent-docs]
|
||||||
|
created: 2026-07-12T10:22:00Z
|
||||||
|
---
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
`@repo/core-events` and `@repo/core-realtime` exist as workspace packages, scaffolded via `pnpm turbo gen core-package`, each with its generator-emitted test suite and pre-shipped library trace (ADR-022 "pre-shipped trace" mechanism). No consumers are wired yet beyond compile-green.
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
The walking-skeleton PRD needs runner status events and pushes; scaffolding the two optional cores now means that PRD lands on a floor where the bus and realtime substrate already compile and pass gates (PRD in-scope item).
|
||||||
|
|
||||||
|
## Done when
|
||||||
|
|
||||||
|
- `packages/core-events` and `packages/core-realtime` exist and build.
|
||||||
|
- Generator-emitted test suites pass; pre-shipped traces satisfy the ADR-022 pre-commit hook.
|
||||||
|
- No consumers wired — nothing in `auth` or the apps depends on them yet.
|
||||||
|
- `pnpm typecheck && pnpm lint && pnpm test && pnpm conformance && pnpm fallow:audit && pnpm coverage:diff` pass on each commit.
|
||||||
|
|
||||||
|
## Out of scope
|
||||||
|
|
||||||
|
- Wiring any publisher/consumer or realtime channel (walking-skeleton PRD).
|
||||||
|
- Additional test coverage beyond the generator-emitted suites (PRD testing decision: none required until consumers exist).
|
||||||
|
|
||||||
|
## Tasks
|
||||||
|
|
||||||
|
- [ ] Run `pnpm turbo gen core-package events` to scaffold `@repo/core-events` with its generator-emitted tests and pre-shipped trace (ADR-022) — compile-green, no consumers wired, one commit, all gates pass.
|
||||||
|
- [ ] Run `pnpm turbo gen core-package realtime` to scaffold `@repo/core-realtime` with its generator-emitted tests and pre-shipped trace (ADR-022) — compile-green, no consumers wired, one commit, all gates pass.
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
---
|
||||||
|
id: 06-archive-template-work
|
||||||
|
epic: platform-retrofit
|
||||||
|
title: Archive the shipped template work tree
|
||||||
|
type: technical-story
|
||||||
|
status: todo
|
||||||
|
feature: docs
|
||||||
|
depends-on: []
|
||||||
|
blocks: []
|
||||||
|
created: 2026-07-12T10:22:00Z
|
||||||
|
---
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
The eight shipped template epics and their nine PRDs live under `docs/work/archive/{epics,prds}/` (with a one-line README), `_state.json` is rebuilt via `pnpm work rebuild-state`, and `pnpm work status` shows only Veect work.
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
Dispatch context and prioritization are assembled from the work tree; eight shipped template epics pollute it and point agents at the wrong product (PRD user story 2). Archived work stays greppable — it documents how the machinery was built.
|
||||||
|
|
||||||
|
## Done when
|
||||||
|
|
||||||
|
- `pnpm work status` lists zero template epics (only the Veect epics — `platform-retrofit`, `walking-skeleton` — remain under `docs/work/epics/`).
|
||||||
|
- The eight epics (`binder-wrap-helper`, `ci-security-and-supply-chain`, `compliance-docs-scaffolds`, `compliance-manifests-pii-retention-subprocessors`, `dsr-consent-and-cookie-banner`, `library-evaluation-policy`, `product-analytics-channel`, `security-headers-rate-limit-sbom`) and their nine PRDs (the eight matching PRDs + `coverage-architecture`) are under `docs/work/archive/` and greppable; `platform-retrofit.prd.md` and `walking-skeleton.prd.md` stay in `docs/work/prds/`.
|
||||||
|
- The work CLI ignores the archive path (its state builder walks `docs/work/epics/` only — verified, glob adjusted if not).
|
||||||
|
- `docs/work/_system/_state.json` is regenerated and passes the state-sync pre-commit guard.
|
||||||
|
- `pnpm typecheck && pnpm lint && pnpm test && pnpm conformance && pnpm fallow:audit && pnpm coverage:diff` pass.
|
||||||
|
|
||||||
|
## Out of scope
|
||||||
|
|
||||||
|
- Editing archived epic/story/PRD content.
|
||||||
|
- Archiving `walking-skeleton.prd.md` or this epic's PRD — they are live Veect work.
|
||||||
|
|
||||||
|
## Tasks
|
||||||
|
|
||||||
|
- [ ] Create `docs/work/archive/{epics,prds}/` with a one-line README, move the eight shipped template epics and nine shipped PRDs into it, verify the work CLI ignores the archive path (adjust its glob if it doesn't), and run `pnpm work rebuild-state` to regenerate `_state.json` — one commit, `pnpm work status` shows only Veect work, all gates pass.
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
---
|
||||||
|
id: 07-editor-library-traces
|
||||||
|
epic: platform-retrofit
|
||||||
|
title: Library traces for @xyflow/react and zustand
|
||||||
|
type: technical-story
|
||||||
|
status: todo
|
||||||
|
feature: docs
|
||||||
|
depends-on: []
|
||||||
|
blocks: []
|
||||||
|
created: 2026-07-12T10:22:00Z
|
||||||
|
---
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
`docs/library-decisions/` contains approved traces (via the `/evaluate-library` skill, ADR-022) for the feature-tier runtime deps the walking-skeleton PRD needs: `@xyflow/react` and `zustand` (v5). Traces only — the packages are not installed by this story.
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
Walking-skeleton tasks must not stall on the library-policy pre-commit hook (PRD user story 6). Pre-approving the traces decouples library evaluation from feature implementation.
|
||||||
|
|
||||||
|
## Done when
|
||||||
|
|
||||||
|
- `docs/library-decisions/` contains an approved trace for `@xyflow/react` and an approved trace for `zustand` (v5), each produced by the `/evaluate-library` protocol.
|
||||||
|
- The ADR-022 pre-commit hook passes on each commit.
|
||||||
|
- `pnpm typecheck && pnpm lint && pnpm test && pnpm conformance && pnpm fallow:audit && pnpm coverage:diff` pass.
|
||||||
|
|
||||||
|
## Out of scope
|
||||||
|
|
||||||
|
- Installing either package into any workspace package (the consuming feature installs them in the walking-skeleton PRD).
|
||||||
|
- Traces for runner-side deps (execa, vite, react-docgen-typescript) — app-tier `apps/runner` deps are exempt from ADR-022; traces for them are optional hardening, deferred.
|
||||||
|
|
||||||
|
## Tasks
|
||||||
|
|
||||||
|
- [ ] Run `/evaluate-library` for `@xyflow/react` and commit the approved trace to `docs/library-decisions/` — one commit, all gates pass.
|
||||||
|
- [ ] Run `/evaluate-library` for `zustand` (v5) and commit the approved trace to `docs/library-decisions/` — one commit, all gates pass.
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
---
|
||||||
|
id: 08-rewrite-agent-docs
|
||||||
|
epic: platform-retrofit
|
||||||
|
title: Rewrite CLAUDE.md and AGENTS.md for Veect
|
||||||
|
type: technical-story
|
||||||
|
status: todo
|
||||||
|
feature: docs
|
||||||
|
depends-on:
|
||||||
|
[
|
||||||
|
01-commit-product-docs,
|
||||||
|
02-single-version-release-please,
|
||||||
|
03-delete-demo-apps-and-features,
|
||||||
|
04-web-next-shell,
|
||||||
|
05-scaffold-optional-cores,
|
||||||
|
]
|
||||||
|
blocks: []
|
||||||
|
created: 2026-07-12T10:22:00Z
|
||||||
|
---
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
CLAUDE.md and AGENTS.md describe Veect: control-plane/runner vocabulary, the new package map (auth + core packages, `apps/{web-next,cms,storybook}`, no demo features, no web-tanstack), ADR-027/028/029 references, the single-root versioning policy, and `docs/product/` as the authoritative spec location. The "15 conformance rules" miscount is fixed to sixteen.
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
Agent context is assembled from these files; today they describe a blog/CMS starter, so generated epics use the wrong vocabulary and package map (PRD user story 3). This story lands last because the docs describe the state the other stories produce.
|
||||||
|
|
||||||
|
## Done when
|
||||||
|
|
||||||
|
- CLAUDE.md and AGENTS.md project-overview sections describe Veect (spot check: no mention of blog/media/marketing-pages/navigation or web-tanstack as live packages/apps).
|
||||||
|
- Control-plane/runner vocabulary and ADR-027/028/029 references are present; `docs/product/` appears where the spec is referenced.
|
||||||
|
- CLAUDE.md's versioning bullet reflects the root-only release-please policy (story 02), and the "15 conformance/\* rules" Quick Start miscount reads sixteen, matching the enumerated rule list.
|
||||||
|
- Stale artifacts of the deletions are gone from both files (ports table, Sentry DSN trio, five-feature package lists).
|
||||||
|
- `docs/glossary.md` needs no further changes here — the Veect domain section already exists and deleted-feature terms were pruned in story 03's slices; verify only.
|
||||||
|
- `pnpm typecheck && pnpm lint && pnpm test && pnpm conformance && pnpm fallow:audit && pnpm coverage:diff` pass on each commit.
|
||||||
|
|
||||||
|
## In scope
|
||||||
|
|
||||||
|
- CLAUDE.md: project overview, Read First, key conventions/versioning bullets, ports/DSN references, conformance-rule count.
|
||||||
|
- AGENTS.md: package map, boundary rules, per-package conventions sections.
|
||||||
|
|
||||||
|
## Out of scope
|
||||||
|
|
||||||
|
- Glossary edits (handled in story 03's deletion slices; Veect section already exists).
|
||||||
|
- Guide rewrites under `docs/guides/` beyond what CLAUDE.md/AGENTS.md link corrections force.
|
||||||
|
- Generator template documentation changes (generators stay as-is per PRD).
|
||||||
|
|
||||||
|
## Tasks
|
||||||
|
|
||||||
|
- [ ] Rewrite CLAUDE.md for Veect — project overview and Read First (control-plane/runner vocabulary, new package map, ADR-027/028/029 + `docs/product/` references), versioning bullet updated to the root-only policy, ports/DSN/feature lists purged of deleted packages, and the "15 conformance rules" miscount fixed to sixteen — one commit, all gates pass.
|
||||||
|
- [ ] Rewrite AGENTS.md for Veect — package map, boundary rules, and per-package conventions reflecting auth + cores + the three surviving apps, same vocabulary and ADR references as CLAUDE.md — one commit, all gates pass.
|
||||||
45
docs/work/epics/platform-retrofit/_epic.md
Normal file
45
docs/work/epics/platform-retrofit/_epic.md
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
---
|
||||||
|
id: platform-retrofit
|
||||||
|
prd: docs/work/prds/platform-retrofit.prd.md
|
||||||
|
title: Platform retrofit — repurpose template-vertical as the Veect monorepo
|
||||||
|
type: epic
|
||||||
|
status: in-progress
|
||||||
|
features:
|
||||||
|
[
|
||||||
|
blog,
|
||||||
|
media,
|
||||||
|
marketing-pages,
|
||||||
|
navigation,
|
||||||
|
web-tanstack,
|
||||||
|
web-next,
|
||||||
|
core-events,
|
||||||
|
core-realtime,
|
||||||
|
]
|
||||||
|
created: 2026-07-12T10:22:00Z
|
||||||
|
---
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Turn the `template-vertical` starter into a clean, truthful Veect monorepo: commit the product spec under `docs/product/`, delete the four demo content features and `apps/web-tanstack`, reduce `apps/web-next` to a compiling auth shell, scaffold `core-events` + `core-realtime`, archive the shipped template work, move release-please to a single root version, pre-approve the editor's library traces, and rewrite CLAUDE.md/AGENTS.md for Veect — with every conformance gate green on every slice.
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
Three concrete pains (PRD): dispatch agents in worktrees cannot read the untracked `.proto/` spec bundle; `pnpm work status`, CLAUDE.md/AGENTS.md, and release-please all describe a blog/CMS starter that no longer reflects the product; and the demo features occupy the workspace, router/CMS composition, and versioning config that the Veect features (workspaces, projects, design-doc, discovery, ai) need. ADR-027/028/029 are the decision baseline; this epic implements their repo-level consequences only.
|
||||||
|
|
||||||
|
## Stories
|
||||||
|
|
||||||
|
- [ ] [01 — Commit the product spec and design references under docs/product/](01-commit-product-docs/_story.md)
|
||||||
|
- [ ] [02 — Rewrite release-please to a single root product version](02-single-version-release-please/_story.md)
|
||||||
|
- [ ] [03 — Delete web-tanstack and the four demo content features](03-delete-demo-apps-and-features/_story.md)
|
||||||
|
- [ ] [04 — Reduce web-next to an auth shell with a boot smoke assertion](04-web-next-shell/_story.md)
|
||||||
|
- [ ] [05 — Scaffold core-events and core-realtime](05-scaffold-optional-cores/_story.md)
|
||||||
|
- [ ] [06 — Archive the shipped template work tree](06-archive-template-work/_story.md)
|
||||||
|
- [ ] [07 — Library traces for @xyflow/react and zustand](07-editor-library-traces/_story.md)
|
||||||
|
- [ ] [08 — Rewrite CLAUDE.md and AGENTS.md for Veect](08-rewrite-agent-docs/_story.md)
|
||||||
|
|
||||||
|
## Out of scope (from PRD)
|
||||||
|
|
||||||
|
- Any new Veect feature code (walking-skeleton PRD and successors).
|
||||||
|
- The landing page (`polish-playground-landing` PRD).
|
||||||
|
- 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; billing, GitHub App, self-host distribution (deferred per ADR-027).
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
---
|
||||||
|
id: 01-vite-kitchen-fixture
|
||||||
|
epic: walking-skeleton
|
||||||
|
title: vite-kitchen fixture + git-serving test helpers
|
||||||
|
type: technical-story
|
||||||
|
status: in-progress
|
||||||
|
feature: core-testing
|
||||||
|
depends-on: []
|
||||||
|
blocks: [04-runner-app-protocol-clone-install]
|
||||||
|
created: 2026-07-12T10:24:14Z
|
||||||
|
---
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Land `fixtures/vite-kitchen` — a minimal Vite + React + TS + Tailwind repo with a `Button` component — at the repo root, outside the pnpm workspace and turbo graph, plus `core-testing` helpers that serve any fixture as a local bare repo over the git protocol so integration tests can drive a real `git clone` without cloud resources.
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
The protocol integration suite (the load-bearing test tier of this epic) spawns a real runner against a `git daemon`-served `vite-kitchen` (tech spec §15). The fixture and its serving helpers are the substrate every runner story's tests stand on, so they land first.
|
||||||
|
|
||||||
|
**Sequencing note (cross-epic):** the sibling `platform-retrofit` epic (clean floor, ADR-022 traces, scaffolded optional cores incl. `core-events` + `core-realtime`, pre-approved editor deps) must complete before this epic starts — the PRD's "Builds on" names it. Cross-epic `depends-on` frontmatter is not supported; this note is the dependency record.
|
||||||
|
|
||||||
|
## Done when
|
||||||
|
|
||||||
|
- `fixtures/vite-kitchen` exists at the repo root: minimal Vite + React + TS + Tailwind app with a `Button` component (typed props for the docgen scan), invisible to pnpm workspace resolution and the turbo graph.
|
||||||
|
- `core-testing` exports helpers that serve a fixture directory as a local bare repo / `git daemon` remote (setup/teardown, clone URL), with tests exercising a real `git clone` of `vite-kitchen`.
|
||||||
|
- `pnpm typecheck && pnpm lint && pnpm test && pnpm conformance && pnpm fallow:audit && pnpm coverage:diff` all pass after each task.
|
||||||
|
|
||||||
|
## In scope
|
||||||
|
|
||||||
|
- `fixtures/` directory at repo root, outside pnpm workspace and turbo graph (PRD Implementation decisions).
|
||||||
|
- The `Button` component with props the react-docgen-typescript scan can discover (name + props).
|
||||||
|
- `core-testing` bare-repo/`git daemon` serving helpers for tests.
|
||||||
|
|
||||||
|
## Out of scope
|
||||||
|
|
||||||
|
- The runner's clone/install/scan of the fixture (stories 04–05).
|
||||||
|
- PAT-authenticated fixture hosting beyond what the leak-assertion tests need (real GitHub/GitLab connections are out of PRD scope).
|
||||||
|
- Additional fixtures (Next.js fixture arrives with `preview-and-nextjs-depth`).
|
||||||
|
|
||||||
|
## Tasks
|
||||||
|
|
||||||
|
- [ ] Create `fixtures/vite-kitchen` at the repo root — minimal Vite + React + TS + Tailwind app with a `Button` component (typed props) — outside the pnpm workspace and turbo graph; confirm `pnpm install` and turbo ignore it and all gates stay green.
|
||||||
|
- [ ] Add `core-testing` helpers that serve a fixture directory as a local bare repo / `git daemon` remote (setup/teardown, clone URL) with tests exercising a real `git clone` of `vite-kitchen`.
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
---
|
||||||
|
id: 02-core-runner-protocol
|
||||||
|
epic: walking-skeleton
|
||||||
|
title: core-runner-protocol package — versioned, zod-validated message schemas
|
||||||
|
type: technical-story
|
||||||
|
status: todo
|
||||||
|
feature: core-runner-protocol
|
||||||
|
depends-on: []
|
||||||
|
blocks: [04-runner-app-protocol-clone-install, 09-editor-package]
|
||||||
|
created: 2026-07-12T10:24:14Z
|
||||||
|
---
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Ship `@repo/core-runner-protocol`: 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, so the three sides cannot drift apart silently (PRD user story 7).
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
The runner protocol is plain WS/JSON, not tRPC (ADR-027) — which means nothing type-checks the wire unless every message is zod-parsed against one shared schema package. Every other story in this epic (runner app, provisioner, lifecycle events, editor frame) consumes these schemas; they must exist first.
|
||||||
|
|
||||||
|
## Done when
|
||||||
|
|
||||||
|
- `@repo/core-runner-protocol` exists as a green optional core package.
|
||||||
|
- Message envelope carries `protocolVersion: "0"` and a workspace-scoped auth token (PRD Implementation decisions).
|
||||||
|
- Zod-validated schemas exist for: hello/ready, clone, install, scan, adapter-start, render-frame, and status/error events — status events carry stage + elapsed (ui-gap §5 staged-progress), error events carry named causes.
|
||||||
|
- Unit tests cover accept/reject round-trips for every message type (`.strict()` schemas reject unknown fields).
|
||||||
|
- `pnpm typecheck && pnpm lint && pnpm test && pnpm conformance && pnpm fallow:audit && pnpm coverage:diff` all pass after each task.
|
||||||
|
|
||||||
|
## In scope
|
||||||
|
|
||||||
|
- `pnpm turbo gen core-package runner-protocol` scaffold.
|
||||||
|
- Versioned envelope + the message schema set listed above.
|
||||||
|
- Schema unit tests.
|
||||||
|
|
||||||
|
## Out of scope
|
||||||
|
|
||||||
|
- The WS server/client implementations (stories 04 and 07) — this package is schemas only.
|
||||||
|
- Protocol version negotiation beyond the pinned `"0"` (later PRDs).
|
||||||
|
- Watch/HMR messages (`discovery-and-library`).
|
||||||
|
|
||||||
|
## Tasks
|
||||||
|
|
||||||
|
- [ ] Run `pnpm turbo gen core-package runner-protocol` → green `@repo/core-runner-protocol` package shell.
|
||||||
|
- [ ] Add the versioned protocol surface: message envelope (`protocolVersion: "0"`, workspace-scoped auth token) + zod-validated `.strict()` schemas for hello/ready, clone, install, scan, adapter-start, render-frame, and status/error events (staged progress carries stage + elapsed; errors carry named causes), with unit tests covering accept/reject round-trips for every message type.
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
---
|
||||||
|
id: 03-workspaces-feature-core
|
||||||
|
epic: walking-skeleton
|
||||||
|
title: workspaces feature core — connect, status, list + encrypted credential storage
|
||||||
|
type: user-story
|
||||||
|
status: todo
|
||||||
|
feature: workspaces
|
||||||
|
depends-on: []
|
||||||
|
blocks:
|
||||||
|
[
|
||||||
|
06-runner-provisioner-port,
|
||||||
|
07-runner-lifecycle-events-and-realtime,
|
||||||
|
10-web-next-wiring,
|
||||||
|
]
|
||||||
|
created: 2026-07-12T10:24:14Z
|
||||||
|
---
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Ship the minimal `workspaces` feature: `connectWorkspace` (name + git URL + PAT, audited), `getWorkspaceStatus`, `listWorkspaces`, and a Workspaces Payload collection whose PAT field is encrypted at rest and write-only — so a signed-in user can connect a repository by git URL + token (PRD user story 1).
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
The workspace is the root entity of the entire skeleton: provisioning (story 06), lifecycle events (story 07), and the web-next UX (story 10) all hang off it. Credential handling is the security-critical part and must land with the collection, not be retrofitted: PAT stored encrypted AES-256-GCM with a scrypt-derived key from `VEECT_SECRET`, decrypted only server-side, never returned by the Payload API (PRD Implementation decisions; tech spec §13).
|
||||||
|
|
||||||
|
## Done when
|
||||||
|
|
||||||
|
- `pnpm turbo gen feature workspaces` scaffold is green.
|
||||||
|
- `connectWorkspace` (`mutates: true`, `audits: ["workspace-connected"]`), `getWorkspaceStatus`, and `listWorkspaces` are declared in `feature.manifest.ts`, implemented manifest-first with contracts, unit tests (mocks injected directly), DI wiring, and tRPC procedures.
|
||||||
|
- Workspaces Payload collection stores the PAT encrypted AES-256-GCM (scrypt key derivation from `VEECT_SECRET`); the field is write-only — no API read path returns it.
|
||||||
|
- Repository contract suite runs against both the mock and the Payload impl, including the write-only credential behavior (PRD Testing decisions).
|
||||||
|
- No use-case output schema ever includes the credential.
|
||||||
|
- Coverage bands: template defaults (PRD Implementation decisions — use cases are thin orchestration).
|
||||||
|
- Boot assertion (`assertFeatureConformance`) green in dev-seed mode.
|
||||||
|
- `pnpm typecheck && pnpm lint && pnpm test && pnpm conformance && pnpm fallow:audit && pnpm coverage:diff` all pass after each task.
|
||||||
|
|
||||||
|
## In scope
|
||||||
|
|
||||||
|
- Feature scaffold, three use cases, manifest declarations, audit emission for `connectWorkspace`.
|
||||||
|
- Workspaces Payload collection + real repository + encrypted write-only credential field.
|
||||||
|
- Repository contract suite (mock + Payload).
|
||||||
|
- Dev-seed binder (`__seeds__/dev.ts`) so `pnpm dev` boots without Payload.
|
||||||
|
|
||||||
|
## Out of scope
|
||||||
|
|
||||||
|
- Runner provisioning + lifecycle status events (stories 06–07) — `getWorkspaceStatus` returns persisted state only in this story.
|
||||||
|
- The manifest's `publishes` / realtime declarations (story 07).
|
||||||
|
- Connect UX (story 10); org walls, trust prompt, env manager (`workspaces-and-connections`).
|
||||||
|
- Real GitHub/GitLab connections beyond git URL + PAT.
|
||||||
|
|
||||||
|
## Tasks
|
||||||
|
|
||||||
|
- [ ] Run `pnpm turbo gen feature workspaces` → green feature scaffold (manifest, contracts, binders, controllers, tests, dev-seed).
|
||||||
|
- [ ] Add `connectWorkspace` use case — manifest entry (`mutates: true`, `audits: ["workspace-connected"]`), input schema (name + git URL + PAT), output schema (credential never included), red test → green impl, DI wiring with audit emission, tRPC procedure.
|
||||||
|
- [ ] Add the Workspaces Payload collection + real repository: PAT encrypted AES-256-GCM with a scrypt-derived key from `VEECT_SECRET`, write-only field (Payload API never returns it); repository contract suite covering mock + Payload impls incl. the write-only credential behavior.
|
||||||
|
- [ ] Add `getWorkspaceStatus` and `listWorkspaces` use cases — manifest entries, contracts, red tests → green impls, DI wiring, tRPC procedures — returning persisted workspace/runner status.
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
---
|
||||||
|
id: 04-runner-app-protocol-clone-install
|
||||||
|
epic: walking-skeleton
|
||||||
|
title: runner app — protocol server, clone stage, install stage
|
||||||
|
type: technical-story
|
||||||
|
status: todo
|
||||||
|
feature: runner
|
||||||
|
depends-on: [01-vite-kitchen-fixture, 02-core-runner-protocol]
|
||||||
|
blocks: [05-runner-scan-and-preview-adapter, 06-runner-provisioner-port]
|
||||||
|
created: 2026-07-12T10:24:14Z
|
||||||
|
---
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Ship the first half of `apps/runner`: a WS server speaking `@repo/core-runner-protocol` (hello/ready handshake gated on the workspace-scoped auth token), then the clone stage (PAT via ephemeral credential helper, spec §6 verbatim) and the install stage (package-manager detection), each emitting staged progress and named error events, each proven by the protocol integration suite against a real spawned runner and a `git daemon`-served `vite-kitchen`.
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
The runner ↔ repo-toolchain seam is one of the three risks this epic exists to burn down. Clone and install are where credentials touch disk and subprocesses — the credential-leak assertions (no PAT in URLs, argv, logs, or `.git/config`; spec §15) must grow up with the code, not after it. App-tier imperative code is expected here (PRD Implementation decisions); the protocol is the contract, so tests assert through the protocol and never against runner internals (PRD Testing decisions).
|
||||||
|
|
||||||
|
## Done when
|
||||||
|
|
||||||
|
- `apps/runner` exists; every inbound/outbound message is zod-parsed against `core-runner-protocol`; handshake rejects a bad/missing workspace-scoped token.
|
||||||
|
- Clone stage delivers the PAT to git via an ephemeral credential helper (spec §6 mechanics verbatim); credential never appears in any log, process argv, or `.git/config` in the runner workspace — asserted by the integration suite.
|
||||||
|
- Install stage detects the package manager and installs, streaming staged progress events.
|
||||||
|
- Named error events for bad URL, bad token, and install failure (PRD user story 5).
|
||||||
|
- Protocol integration suite (real spawned runner + `git daemon`-served fixture, real WS) passes in CI on ubuntu.
|
||||||
|
- `pnpm typecheck && pnpm lint && pnpm test && pnpm conformance && pnpm fallow:audit && pnpm coverage:diff` all pass after each task.
|
||||||
|
|
||||||
|
## In scope
|
||||||
|
|
||||||
|
- `apps/runner` app scaffold (app-tier — no feature generator applies; template app conventions).
|
||||||
|
- WS server + envelope parsing + hello/ready handshake + status/error emission.
|
||||||
|
- Clone stage with ephemeral credential helper + leak assertions.
|
||||||
|
- Install stage with package-manager detection + progress events.
|
||||||
|
- Integration tests using `core-testing`'s git-serving helpers (story 01).
|
||||||
|
|
||||||
|
## Out of scope
|
||||||
|
|
||||||
|
- Scan + preview adapter + agent script (story 05).
|
||||||
|
- Provisioning of the runner (story 06) — tests spawn it directly.
|
||||||
|
- Watch/HMR, perf budgets (`discovery-and-library`); Next.js adapter (`preview-and-nextjs-depth`).
|
||||||
|
- Local runner / CLI agent (`local-runner-cli`).
|
||||||
|
|
||||||
|
## Tasks
|
||||||
|
|
||||||
|
- [ ] Scaffold `apps/runner`: WS server speaking `@repo/core-runner-protocol` (every message zod-parsed), hello/ready handshake gated on the workspace-scoped auth token, status/error event emission; integration test spawns the real runner and completes the handshake over real WS.
|
||||||
|
- [ ] Add the clone stage: git clone of the requested repo with the PAT delivered via an ephemeral credential helper (spec §6 verbatim — never in URLs, argv, logs, or `.git/config`), staged progress events; integration test clones the `git daemon`-served `vite-kitchen`, asserts credential-leak absence (grep argv/logs/`.git/config`), and asserts named failure events for bad URL / bad token.
|
||||||
|
- [ ] Add the install stage: package-manager detection + install with staged progress events; integration test asserts install completes on the fixture and a named failure event is emitted on install error.
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
---
|
||||||
|
id: 05-runner-scan-and-preview-adapter
|
||||||
|
epic: walking-skeleton
|
||||||
|
title: runner scan stage + embedded-Vite preview adapter + canvas agent v0
|
||||||
|
type: technical-story
|
||||||
|
status: todo
|
||||||
|
feature: runner
|
||||||
|
depends-on: [04-runner-app-protocol-clone-install]
|
||||||
|
blocks: [07-runner-lifecycle-events-and-realtime]
|
||||||
|
created: 2026-07-12T10:24:14Z
|
||||||
|
---
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Complete `apps/runner`: a minimal react-docgen-typescript scan that returns ≥1 component (name + props) from the fixture, and an embedded-Vite preview adapter rooted at the clone that serves a Veect frame-host page — importing the component requested via `render-frame` and mounting the injected, Veect-authored canvas agent script v0.
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
This is invariant #1 made real: the component renders through the repo's own toolchain, not a Veect re-implementation (ADR-028 — no NodeRenderer on the board path). The agent script is the editor's only eyes inside the cross-origin iframe; it must be adapter-injected and never sourced from the repo (ADR-028 consequences — security floor even at fixture scale).
|
||||||
|
|
||||||
|
## Done when
|
||||||
|
|
||||||
|
- Scan stage runs react-docgen-typescript over the fixture's component glob and emits a scan-result message with ≥1 component carrying name + props (skeleton fidelity; full `ComponentMeta` comes with `discovery-and-library`).
|
||||||
|
- Preview adapter starts embedded Vite rooted at the clone on a dedicated port = dedicated origin (spec §9), serving a frame-host entry that imports the requested component with default props (`render-frame`) and mounts the agent script.
|
||||||
|
- Canvas agent v0 reports `runtime.ready`, component bounding boxes (post `fonts.loaded`), and click-target resolution; `targetOrigin` pinned in both directions (ADR-028).
|
||||||
|
- Agent script is Veect-authored and adapter-injected — never sourced from the repo.
|
||||||
|
- Protocol integration suite extends to: scan returns ≥1 component → adapter serves the frame host with the agent script → adapter origin liveness (PRD Success criteria).
|
||||||
|
- `pnpm typecheck && pnpm lint && pnpm test && pnpm conformance && pnpm fallow:audit && pnpm coverage:diff` all pass after each task.
|
||||||
|
|
||||||
|
## In scope
|
||||||
|
|
||||||
|
- Scan stage (react-docgen-typescript, minimal glob) + scan-result message.
|
||||||
|
- Embedded-Vite adapter, frame-host entry, `render-frame` handling, adapter-ready/status events.
|
||||||
|
- Canvas agent script v0 (ready, geometry, click-target resolution; pinned `targetOrigin`).
|
||||||
|
- Integration tests for scan payload, adapter origin liveness, and agent-script presence.
|
||||||
|
|
||||||
|
## Out of scope
|
||||||
|
|
||||||
|
- The editor-side canvas-protocol client (story 09).
|
||||||
|
- Watch/HMR, perf-500 budgets (`discovery-and-library`); Next.js adapter (`preview-and-nextjs-depth`).
|
||||||
|
- Multi-view frames, isolation, code panel (later PRDs).
|
||||||
|
|
||||||
|
## Tasks
|
||||||
|
|
||||||
|
- [ ] Add the scan stage: minimal react-docgen-typescript scan over the fixture's component glob → scan-result message with ≥1 component (name + props); integration test asserts the `Button` payload arrives over real WS.
|
||||||
|
- [ ] Add the preview adapter: embedded Vite rooted at the clone on a dedicated port/origin (spec §9), frame-host entry importing the component requested via `render-frame` (default props) and mounting the injected Veect-authored canvas agent script v0 (`runtime.ready`, bounding boxes post `fonts.loaded`, click-target resolution; pinned `targetOrigin` both directions; never sourced from the repo); adapter-ready/status events; integration test asserts adapter origin liveness and that the frame host serves with the agent script.
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
---
|
||||||
|
id: 06-runner-provisioner-port
|
||||||
|
epic: walking-skeleton
|
||||||
|
title: IRunnerProvisioner port + local-process and single-host Docker implementations
|
||||||
|
type: technical-story
|
||||||
|
status: todo
|
||||||
|
feature: workspaces
|
||||||
|
depends-on: [03-workspaces-feature-core, 04-runner-app-protocol-clone-install]
|
||||||
|
blocks: [07-runner-lifecycle-events-and-realtime]
|
||||||
|
created: 2026-07-12T10:24:14Z
|
||||||
|
---
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Ship the runner provisioning port — `IRunnerProvisioner` (`provision(workspaceId) → RunnerHandle`, `terminate`, `status`) in `workspaces` infrastructure — with two implementations: a local child-process provisioner (dev/CI) and a single-host Docker provisioner (the container-per-workspace baseline of ADR-027 §2).
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
Each workspace's repo code must execute in its own isolated runner so a malicious repo cannot touch other tenants (PRD user story 6, ADR-027). Putting provisioning behind a port keeps fleet orchestration explicitly a later concern behind the same interface, and lets `pnpm dev` + CI run the whole skeleton with a plain child process (PRD user story 8).
|
||||||
|
|
||||||
|
## Done when
|
||||||
|
|
||||||
|
- `IRunnerProvisioner` service port lives in `workspaces` infrastructure with `provision(workspaceId) → RunnerHandle`, `terminate`, `status` (PRD Implementation decisions).
|
||||||
|
- Local child-process implementation spawns the real `apps/runner`; tests provision, complete the protocol handshake, and terminate cleanly.
|
||||||
|
- Docker implementation: docker CLI via execa (PRD Q1 — app/infra-tier placement, so no ADR-022 trace required); image `node:22-bookworm-slim` + git at a pinned digest (PRD Q3); container-per-workspace with no cross-tenant network (PRD security floor).
|
||||||
|
- The Docker path has a documented manual dev-machine check; CI uses the process provisioner (PRD Success criteria).
|
||||||
|
- `pnpm typecheck && pnpm lint && pnpm test && pnpm conformance && pnpm fallow:audit && pnpm coverage:diff` all pass after each task.
|
||||||
|
|
||||||
|
## In scope
|
||||||
|
|
||||||
|
- The port + `RunnerHandle` shape.
|
||||||
|
- Local child-process implementation + tests against the real runner.
|
||||||
|
- Single-host Docker implementation (docker CLI via execa) + tests against a stubbed docker CLI + documented manual verification steps.
|
||||||
|
|
||||||
|
## Out of scope
|
||||||
|
|
||||||
|
- Fleet orchestration, hibernation, egress policy hardening, resource-limit tuning (`workspaces-and-connections`).
|
||||||
|
- Quotas, metering, billing.
|
||||||
|
- Doctor-style runner image version checks (`workspaces-and-connections`, PRD Q3).
|
||||||
|
|
||||||
|
## Tasks
|
||||||
|
|
||||||
|
- [ ] Add the `IRunnerProvisioner` service port in `workspaces` infrastructure (`provision(workspaceId) → RunnerHandle`, `terminate`, `status`) + the local child-process implementation spawning `apps/runner`; tests provision a real runner, complete the protocol handshake, and terminate cleanly.
|
||||||
|
- [ ] Add the single-host Docker implementation (docker CLI via execa, app/infra-tier per PRD Q1; `node:22-bookworm-slim` + git at a pinned digest; container-per-workspace, no cross-tenant network) with unit tests against a stubbed docker CLI + documented manual dev-machine verification (CI stays on the process provisioner).
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
---
|
||||||
|
id: 07-runner-lifecycle-events-and-realtime
|
||||||
|
epic: walking-skeleton
|
||||||
|
title: runner lifecycle — status events, scan event, realtime channel
|
||||||
|
type: technical-story
|
||||||
|
status: todo
|
||||||
|
feature: workspaces
|
||||||
|
depends-on:
|
||||||
|
[
|
||||||
|
03-workspaces-feature-core,
|
||||||
|
05-runner-scan-and-preview-adapter,
|
||||||
|
06-runner-provisioner-port,
|
||||||
|
]
|
||||||
|
blocks: [08-discovery-feature, 10-web-next-wiring]
|
||||||
|
created: 2026-07-12T10:24:14Z
|
||||||
|
---
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Wire the control-plane side of the runner lifecycle: `connectWorkspace` provisions via `IRunnerProvisioner` and drives the protocol session (clone → install → scan → start preview); `workspaces` publishes `runner-status-changed` and the scan event on `IEventBus`; a realtime channel pushes stage progress + adapter-ready to the browser. This wires `core-events` and `core-realtime` end to end (PRD In scope).
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
Staged, honest progress is what keeps a minutes-long operation from looking hung (PRD user story 2, ui-gap §5) — and named error events (bad URL, bad token, install failure) are what make failure states diagnosable instead of a blank board (user story 5). Registry ingestion is a cross-feature reaction, so it must cross the boundary via the event bus, not a direct call (rule E0) — this story publishes; story 08 consumes.
|
||||||
|
|
||||||
|
## Done when
|
||||||
|
|
||||||
|
- `connectWorkspace` kicks off provisioning + the protocol session; the credential is decrypted only server-side and passed to the runner over the authenticated protocol channel (PRD Implementation decisions).
|
||||||
|
- `runner-status-changed` event contract lives in `workspaces` `events/`, is exported from the feature root barrel (rule E1), and is declared under `publishes` in `feature.manifest.ts`; staged events carry stage + elapsed; error events carry named causes.
|
||||||
|
- The scan event contract is likewise public + declared; the lifecycle session publishes it with the scan-result payload when the runner's scan completes.
|
||||||
|
- Realtime channel descriptor is exported from the root barrel (rule R1) and declared in the manifest; it pushes stage progress + adapter-ready to the browser; no direct `socket.io` import in the feature (rule R2).
|
||||||
|
- `getWorkspaceStatus` reflects live staged status, including named error states.
|
||||||
|
- Tests use a recording bus + scripted runner double (protocol as the contract — no assertions on runner internals).
|
||||||
|
- `pnpm conformance` event closure green; boot assertion green.
|
||||||
|
- `pnpm typecheck && pnpm lint && pnpm test && pnpm conformance && pnpm fallow:audit && pnpm coverage:diff` all pass after each task.
|
||||||
|
|
||||||
|
## In scope
|
||||||
|
|
||||||
|
- Lifecycle orchestration in `workspaces` (provision → protocol session → staged status), off the request path.
|
||||||
|
- `runner-status-changed` + scan event contracts, manifest `publishes` declarations, bus publishing.
|
||||||
|
- Realtime channel descriptor + broadcast wiring, manifest declaration.
|
||||||
|
- Named error states for bad URL / bad token / install failure.
|
||||||
|
|
||||||
|
## Out of scope
|
||||||
|
|
||||||
|
- The scan-event consumer (story 08 — discovery).
|
||||||
|
- Browser subscription UI (story 10).
|
||||||
|
- Workspace hibernation, runner fleet concerns (`workspaces-and-connections`).
|
||||||
|
|
||||||
|
## Tasks
|
||||||
|
|
||||||
|
- [ ] Run `pnpm turbo gen event` for the `runner-status-changed` contract (public from the `workspaces` root barrel; manifest `publishes` declaration) + wire the lifecycle orchestration: `connectWorkspace` provisions via `IRunnerProvisioner`, drives the protocol session (clone → install → scan → start preview) with the credential passed only over the authenticated channel, publishes staged status events (stage + elapsed) and named error events (bad URL, bad token, install failure); `getWorkspaceStatus` reflects live staged status; tests with recording bus + scripted runner double.
|
||||||
|
- [ ] Run `pnpm turbo gen event` for the scan event contract (public + manifest-declared) + publish the scan-result payload from the lifecycle session when the runner's scan completes; test asserts the publish carries the registry payload.
|
||||||
|
- [ ] Run `pnpm turbo gen realtime` for the workspace-status channel: exported channel descriptor + broadcast wiring pushing stage progress + adapter-ready to the browser; manifest declaration; handlers stay private (rule R1); tests.
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
---
|
||||||
|
id: 08-discovery-feature
|
||||||
|
epic: walking-skeleton
|
||||||
|
title: discovery feature — registry snapshots, getRegistry, scan ingestion
|
||||||
|
type: technical-story
|
||||||
|
status: todo
|
||||||
|
feature: discovery
|
||||||
|
depends-on: [07-runner-lifecycle-events-and-realtime]
|
||||||
|
blocks: [10-web-next-wiring]
|
||||||
|
created: 2026-07-12T10:24:14Z
|
||||||
|
---
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Ship the minimal `discovery` feature: registry snapshot storage, a `getRegistry` use case, and a scan-event handler that ingests the runner's scan results — so the editor has one real component (name + props) to render (skeleton bar; full `ComponentMeta` fidelity comes with `discovery-and-library`).
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
Discovery is its own vertical — the registry outlives any single runner session, and later PRDs (`discovery-and-library`) grow it heavily. Ingestion arrives as a cross-feature reaction to the scan event `workspaces` publishes (rule E0); the handler stays private (rule E1) while `getRegistry` is the public read surface the editor route consumes.
|
||||||
|
|
||||||
|
## Done when
|
||||||
|
|
||||||
|
- `pnpm turbo gen feature discovery` scaffold is green.
|
||||||
|
- Registry snapshot storage + `getRegistry` use case land manifest-first (contracts, unit tests with direct mock injection, DI wiring, tRPC procedure); the registry exposes one component with name + props from the fixture scan.
|
||||||
|
- The scan-event handler (`events/handlers/`, never re-exported) ingests scan results into a registry snapshot; `consumes` is declared in `feature.manifest.ts`.
|
||||||
|
- `pnpm conformance` cross-feature event closure passes — no orphan consumer.
|
||||||
|
- Coverage bands: template defaults (PRD Implementation decisions).
|
||||||
|
- Boot assertion green in dev-seed mode.
|
||||||
|
- `pnpm typecheck && pnpm lint && pnpm test && pnpm conformance && pnpm fallow:audit && pnpm coverage:diff` all pass after each task.
|
||||||
|
|
||||||
|
## In scope
|
||||||
|
|
||||||
|
- Feature scaffold, registry snapshot storage, `getRegistry`, scan-event handler + manifest `consumes` declaration.
|
||||||
|
- Dev-seed binder with a seeded registry so the editor works in dev-seed mode.
|
||||||
|
|
||||||
|
## Out of scope
|
||||||
|
|
||||||
|
- Full `ComponentMeta` fidelity, watch/HMR re-scan, perf-500 budgets (`discovery-and-library`).
|
||||||
|
- Any write surface beyond event ingestion.
|
||||||
|
|
||||||
|
## Tasks
|
||||||
|
|
||||||
|
- [ ] Run `pnpm turbo gen feature discovery` → green feature scaffold (manifest, contracts, binders, controllers, tests, dev-seed).
|
||||||
|
- [ ] Add registry snapshot storage + the `getRegistry` use case — manifest entry, contracts, red test → green impl, DI wiring, tRPC procedure; registry exposes one component with name + props; dev-seed provides a seeded registry.
|
||||||
|
- [ ] Run `pnpm turbo gen event` for the scan-event handler (`events/handlers/on-workspaces-*.handler.ts`, never re-exported per rule E1): ingest scan results into a registry snapshot; manifest `consumes` declaration; `pnpm conformance` event closure green; handler test.
|
||||||
49
docs/work/epics/walking-skeleton/09-editor-package/_story.md
Normal file
49
docs/work/epics/walking-skeleton/09-editor-package/_story.md
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
---
|
||||||
|
id: 09-editor-package
|
||||||
|
epic: walking-skeleton
|
||||||
|
title: editor package — React Flow board, iframe frame node, canvas-protocol client
|
||||||
|
type: technical-story
|
||||||
|
status: todo
|
||||||
|
feature: editor
|
||||||
|
depends-on: [02-core-runner-protocol]
|
||||||
|
blocks: [10-web-next-wiring]
|
||||||
|
created: 2026-07-12T10:24:14Z
|
||||||
|
---
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Ship `packages/editor` v0 — the first code of the ADR-029 rebuild: a React Flow board shell, one iframe frame node hosting the adapter origin, a canvas-protocol client proving the selection round-trip, a minimal zustand store (registry + selection only), and an editor-side selection overlay rendered from agent-reported geometry. Stories + tests from day one.
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
The editor ↔ iframe canvas seam across the origin boundary is the third risk this epic burns down (ADR-028): chrome renders as editor-side overlays from agent-reported geometry, never inside the repo's frame, and `targetOrigin` is pinned in both directions. ADR-029 mandates template conventions from the first commit — `component-must-have-story`/`-test`, React 19, no prototype vendoring — so the skeleton editor is the permanent foundation, not a throwaway.
|
||||||
|
|
||||||
|
## Done when
|
||||||
|
|
||||||
|
- `@repo/editor` exists as a green package following template conventions (vitest `@` alias, `rootDir: "."`, conformance ESLint rules active).
|
||||||
|
- Canvas-protocol client handles `runtime.ready`, geometry reports, and click-target resolution with pinned `targetOrigin` both directions; unit-tested against a scripted agent double (PRD Testing decisions).
|
||||||
|
- Zustand store holds registry + selection only (no document tree — DesignDoc v1 arrives with `design-doc-and-editor-foundation`).
|
||||||
|
- React Flow board with one frame node hosting the adapter iframe; the frame renders a single Element (the discovered component with default props) requested via `render-frame`.
|
||||||
|
- Selection overlay renders editor-side from agent-reported geometry; board pan/zoom stays editor-side (< 16 ms/frame — no protocol round-trip on drag; PRD budget).
|
||||||
|
- Every component has a story + test (`component-must-have-story` / `component-must-have-test`).
|
||||||
|
- React Flow + zustand runtime deps are covered by the `platform-retrofit` pre-approved traces (ADR-022) — no new trace expected; if any additional runtime dep is needed, it gets an `/evaluate-library` trace.
|
||||||
|
- `pnpm typecheck && pnpm lint && pnpm test && pnpm conformance && pnpm fallow:audit && pnpm coverage:diff` all pass after each task.
|
||||||
|
|
||||||
|
## In scope
|
||||||
|
|
||||||
|
- Package scaffold for `packages/editor`.
|
||||||
|
- Canvas-protocol client + scripted agent double tests.
|
||||||
|
- Zustand store (registry + selection).
|
||||||
|
- Board shell, frame node, selection overlay, stories + component tests.
|
||||||
|
|
||||||
|
## Out of scope
|
||||||
|
|
||||||
|
- Design-doc persistence — the frame is an ephemeral in-memory doc (PRD Out of scope).
|
||||||
|
- AI compose, Polish, history, multi-view frames, isolation, code panel.
|
||||||
|
- The web-next route hosting the board (story 10).
|
||||||
|
|
||||||
|
## Tasks
|
||||||
|
|
||||||
|
- [ ] Scaffold `packages/editor` (`@repo/editor`) as a green package shell using `pnpm turbo gen core-package` output as the baseline shape (adapted for a non-core package): tsconfig `rootDir: "."`, vitest config with `@` alias, conformance ESLint rules active; React 19; React Flow + zustand wired against the pre-approved `platform-retrofit` traces.
|
||||||
|
- [ ] Add the canvas-protocol client (pinned `targetOrigin` both directions; `runtime.ready`, geometry reports, click-target selection round-trip) unit-tested against a scripted agent double + the minimal zustand store holding registry + selection only.
|
||||||
|
- [ ] Add the React Flow board shell + one iframe frame node hosting the adapter origin + editor-side selection overlay rendered from agent-reported geometry; the frame renders a single Element (discovered component, default props) requested via `render-frame`; pan/zoom stays editor-side (< 16 ms/frame, no protocol round-trip on drag); stories + component tests for board/frame/overlay.
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
---
|
||||||
|
id: 10-web-next-wiring
|
||||||
|
epic: walking-skeleton
|
||||||
|
title: web-next wiring — connect UX, staged progress, editor route
|
||||||
|
type: user-story
|
||||||
|
status: todo
|
||||||
|
feature: web-next
|
||||||
|
depends-on:
|
||||||
|
[
|
||||||
|
03-workspaces-feature-core,
|
||||||
|
07-runner-lifecycle-events-and-realtime,
|
||||||
|
08-discovery-feature,
|
||||||
|
09-editor-package,
|
||||||
|
]
|
||||||
|
blocks: [11-flagship-e2e]
|
||||||
|
created: 2026-07-12T10:24:14Z
|
||||||
|
---
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Wire the skeleton into `apps/web-next`: workspace list + connect form + staged progress (cloning → installing → scanning → starting preview, with named error states), realtime push of runner status, feature routers composed into the appRouter, `bindAll()` for both features, and the editor route `/w/[workspace]` hosting the board (PRD Q2 — a real route, the editor's permanent home).
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
This story is where the user stories become visible: honest staged progress instead of a hung spinner (user story 2, ui-gap §5), a clear named error state instead of a blank board (user story 5), and the real component rendered by the repo's own toolchain on a real route (user story 3). Dev-seed mode + the process provisioner keep `pnpm dev` + fixtures free of cloud resources (user story 8).
|
||||||
|
|
||||||
|
## Done when
|
||||||
|
|
||||||
|
- `bindAll()` in `apps/web-next` binds `workspaces` + `discovery` in production and dev-seed modes; boot assertion green in both (PRD Success criteria); dev-seed + process provisioner boots with `pnpm dev` and no cloud resources.
|
||||||
|
- Both feature routers are composed into the appRouter; schemas imported from the use-case files, never redefined inline.
|
||||||
|
- Workspace list + connect form (name + git URL + PAT) built from feature `ui/` hooks + connected components per `docs/guides/building-feature-ui.md`.
|
||||||
|
- Staged progress UI driven by the realtime channel: cloning → installing → scanning → starting preview, plus adapter-ready; named error states for bad URL, bad token, install failure — never a blank board.
|
||||||
|
- Editor route `/w/[workspace]` hosts the board: registry via `getRegistry`, frame node requests `render-frame` of the discovered component with default props; clicking the component in the iframe selects it and the selection state names it.
|
||||||
|
- Stories + component tests per conformance rules.
|
||||||
|
- `pnpm typecheck && pnpm lint && pnpm test && pnpm conformance && pnpm fallow:audit && pnpm coverage:diff` all pass after each task.
|
||||||
|
|
||||||
|
## In scope
|
||||||
|
|
||||||
|
- `bindAll()` + appRouter composition + provisioner selection (process provisioner as the dev/CI default).
|
||||||
|
- Workspaces UI: list, connect form, staged progress, error states, realtime subscription.
|
||||||
|
- Editor route `/w/[workspace]` composing `@repo/editor` with registry + frame data.
|
||||||
|
|
||||||
|
## Out of scope
|
||||||
|
|
||||||
|
- Full connect UX states — org walls, trust prompt, env manager (`workspaces-and-connections`).
|
||||||
|
- The Playwright flagship spec (story 11).
|
||||||
|
- web-tanstack wiring (not in PRD scope).
|
||||||
|
|
||||||
|
## Tasks
|
||||||
|
|
||||||
|
- [ ] Wire `workspaces` + `discovery` into `apps/web-next`: `bindAll()` in production + dev-seed modes (dev-seed + process provisioner boots via `pnpm dev` with no cloud resources), feature routers composed into the appRouter, realtime channel plumbed to the browser; boot assertion green in both modes; tests.
|
||||||
|
- [ ] Add the workspace list + connect form + staged progress UI (feature `ui/` hooks + connected components per `building-feature-ui.md`): staged progress cloning → installing → scanning → starting preview driven by realtime push, named error states (bad URL, bad token, install failure — never a blank board); stories + component tests.
|
||||||
|
- [ ] Add the editor route `/w/[workspace]` hosting the board: registry via `getRegistry`, frame node requesting `render-frame` of the discovered component with default props, click-in-iframe → selection overlay + selection state naming the component; tests.
|
||||||
41
docs/work/epics/walking-skeleton/11-flagship-e2e/_story.md
Normal file
41
docs/work/epics/walking-skeleton/11-flagship-e2e/_story.md
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
---
|
||||||
|
id: 11-flagship-e2e
|
||||||
|
epic: walking-skeleton
|
||||||
|
title: flagship e2e — connect vite-kitchen to selection round-trip
|
||||||
|
type: user-story
|
||||||
|
status: todo
|
||||||
|
feature: web-next
|
||||||
|
depends-on: [10-web-next-wiring]
|
||||||
|
blocks: []
|
||||||
|
created: 2026-07-12T10:24:14Z
|
||||||
|
---
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Land the repo's flagship Playwright spec — the M0-recast acceptance: sign in → connect `vite-kitchen` via git URL + PAT → staged progress completes → the editor shows `Button` rendered inside the adapter's iframe → click the button in the iframe → the editor selection overlay appears and the selection state names the component.
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
This spec is the epic's definition of done in executable form. It exercises every seam at once — provisioning, clone/install/scan, adapter, realtime progress, and the cross-origin selection round-trip — asserting through the UI and the protocol, never against runner internals, so the runner stays refactorable while the protocol is the contract (PRD Testing decisions).
|
||||||
|
|
||||||
|
## Done when
|
||||||
|
|
||||||
|
- The Playwright spec (dev-seed + local-process provisioner) covers the full flow from the PRD Success criteria and asserts on iframe content, not a screenshot double.
|
||||||
|
- The flow completes within the connect-to-rendered-component budget: < 3 min on the warm fixture (PRD budget, spec §16).
|
||||||
|
- The spec is tagged as the repo's flagship spec and runs green in CI.
|
||||||
|
- The equivalent flow with the Docker provisioner works on a dev machine per story 06's documented manual check (CI stays on the process provisioner).
|
||||||
|
- `pnpm typecheck && pnpm lint && pnpm test && pnpm test:e2e && pnpm conformance && pnpm fallow:audit && pnpm coverage:diff` all pass.
|
||||||
|
|
||||||
|
## In scope
|
||||||
|
|
||||||
|
- The flagship Playwright spec under the existing `pnpm test:e2e` surface, running against dev-seed mode with the process provisioner.
|
||||||
|
- Any test-only plumbing needed to run the spec in CI (fixture serving, runner spawn) reusing the story 01 helpers.
|
||||||
|
|
||||||
|
## Out of scope
|
||||||
|
|
||||||
|
- Docker-provisioner automation in CI (manual check only, per PRD Success criteria).
|
||||||
|
- Additional e2e coverage beyond the flagship flow (later PRDs).
|
||||||
|
|
||||||
|
## Tasks
|
||||||
|
|
||||||
|
- [ ] Add the flagship Playwright spec (dev-seed + process provisioner): sign in → connect `vite-kitchen` via git URL + PAT → staged progress completes → `Button` rendered inside the adapter iframe (assert on iframe content) → click in the iframe → selection overlay appears and the selection state names the component; completes within the < 3 min warm-fixture budget; tagged as the repo's flagship spec; green in CI.
|
||||||
34
docs/work/epics/walking-skeleton/_epic.md
Normal file
34
docs/work/epics/walking-skeleton/_epic.md
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
---
|
||||||
|
id: walking-skeleton
|
||||||
|
prd: docs/work/prds/walking-skeleton.prd.md
|
||||||
|
title: Walking skeleton — one real component, end to end through the hosted spine
|
||||||
|
type: epic
|
||||||
|
status: in-progress
|
||||||
|
features:
|
||||||
|
[workspaces, discovery, core-runner-protocol, editor, runner, web-next, core-testing]
|
||||||
|
created: 2026-07-12T10:24:14Z
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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 through every seam that matters: control plane ↔ runner provisioning, runner ↔ repo toolchain, and editor ↔ iframe canvas across the origin boundary (ADR-027/028/029).
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
Every Veect risk that matters lives in the seams, not the parts. The original tech spec front-loaded exactly this with its M0 walking skeleton, but its acceptance criteria 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.
|
||||||
|
|
||||||
|
**Sequencing note:** this epic builds on the sibling `platform-retrofit` epic (clean floor, ADR-022 traces, scaffolded optional cores incl. `core-events` + `core-realtime`, pre-approved editor deps). `platform-retrofit` must complete before this epic starts; cross-epic `depends-on` frontmatter is not supported, so this note (and story 01's Why) is the dependency record.
|
||||||
|
|
||||||
|
## Stories
|
||||||
|
|
||||||
|
- [ ] [01 — vite-kitchen fixture + git-serving test helpers](01-vite-kitchen-fixture/_story.md)
|
||||||
|
- [ ] [02 — core-runner-protocol package](02-core-runner-protocol/_story.md)
|
||||||
|
- [ ] [03 — workspaces feature core: connect, status, list + encrypted credentials](03-workspaces-feature-core/_story.md)
|
||||||
|
- [ ] [04 — runner app: protocol server, clone, install](04-runner-app-protocol-clone-install/_story.md)
|
||||||
|
- [ ] [05 — runner scan + preview adapter + canvas agent](05-runner-scan-and-preview-adapter/_story.md)
|
||||||
|
- [ ] [06 — IRunnerProvisioner port + process/Docker implementations](06-runner-provisioner-port/_story.md)
|
||||||
|
- [ ] [07 — runner lifecycle: events + realtime channel](07-runner-lifecycle-events-and-realtime/_story.md)
|
||||||
|
- [ ] [08 — discovery feature: registry + scan ingestion](08-discovery-feature/_story.md)
|
||||||
|
- [ ] [09 — editor package: board, frame, canvas-protocol client](09-editor-package/_story.md)
|
||||||
|
- [ ] [10 — web-next wiring: connect UX, staged progress, editor route](10-web-next-wiring/_story.md)
|
||||||
|
- [ ] [11 — flagship e2e: connect-to-selection](11-flagship-e2e/_story.md)
|
||||||
Reference in New Issue
Block a user