- Do not copy code, specs, UI text, database schemas, or implementation details from AGPL projects.
- Use Cloudflare documentation, public product behavior, and locally authored specs as inputs.
- Keep this project under Apache-2.0-compatible dependencies unless explicitly reviewed.
- When comparing another project, use it only to identify capability categories, test gaps, and workflow ideas. Re-express all requirements in this repository's own product language.
- Any Managed Agents is Cloudflare-native: Workers, D1, Durable Objects, Cloudflare Sandbox, Workers AI, and Cloudflare Secrets are the default platform assumptions.
- Prefer mature community libraries for established protocols and hard problems instead of reimplementing them locally. This applies to auth protocols, OpenAPI tooling, validation, crypto, date/time handling, UI primitives, routing, data fetching, and runtime integrations.
- FlareAuth owns authentication, users, and organizations. OIDC must use mature community libraries such as
openid-clientandoidc-client-ts; do not hand-roll token parsing, token validation, callback validation, or discovery logic. - Pi coding agent is the v1.0 runtime inside one Cloudflare Sandbox per running session.
- AMA owns the control plane: auth integration, FlareAuth-backed tenancy enforcement, projects, agents, environments, sessions, providers, vaults, governance, usage, audit, OpenAPI, UI, sandbox lifecycle, and runtime proxy metadata. AMA must not maintain local user or organization tables.
- AMA must not invent a competing runtime protocol, sandbox SDK, or agent loop. Runtime traffic uses Pi protocol directly or a transparent AMA proxy.
- Cloudflare Agents SDK is not the v1.0 runtime contract. It may be added later as an adapter, but v1.0 must not require
/agents/*compatibility. - Command-line automation uses
restishagainst the published OpenAPI document. Do not add a bespoke CLI binary unless the product decision changes. - Agent-facing skills may document restish workflows, but they must call OpenAPI-described control-plane operations and preserve the Pi runtime boundary.
- Web UI code is an internal product entrypoint and should call the control plane through the shared Hono RPC client. External operators, generated SDKs, and restish use the published OpenAPI document.
- Secret values belong in Cloudflare Secrets or an approved external vault. D1 stores metadata, policy, snapshots, and secret references only.
Specs are BDD-lite (see spec/README.md). spec/*.feature is the product source of
truth — documentation only, one file per capability — and is NOT executed; there is
no Cucumber runner. Tests trace back to scenarios with [spec: <id>] breadcrumbs.
- Write or update a scenario in the capability's
spec/<capability>.feature. Give it a stable id@<capability>/<slug>and one layer tag (@domain/@usecase/@web/@api/@e2e— the cheapest layer that can prove it). - Add or update the home test at that layer (see the table in
spec/README.md) and put[spec: <id>]in itsdescribe/itname. - Implement the Worker, Agent, D1, or UI behavior.
- Run the smallest meaningful check:
npm run test(unit + web + integration vitest projects)npm run test:coverage(enforced per-file coverage gate)npm run typechecknpm run lint:spec(every enforced scenario id has a breadcrumb)npm run e2e(native Playwright crowns ine2e/*.spec.ts— real cross-stack journeys)
Scenarios describe business behaviour. Selectors, fixtures, and platform details belong in the home test and its helpers.
If implementation discovers a missing product decision, stop widening the code change
and update the relevant spec/ scenario or product doc first.
spec/holds only.featurefiles and its README — no test code, no step definitions. The id@<capability>/<slug>never changes once written.- Verify at the cheapest layer. Old
@apiscenarios usually map to@api(assembled server, real D1) or@usecase(fake-port business branch); old@uiscenarios map to@web(jsdom + vi-mocked api) or@e2e(real browser). Reserve@e2efor genuinely cross-stack, hermetic journeys — do not turn every scenario into a slow E2E. npm run e2eruns the native Playwright crowns ine2e/*.spec.ts(auth.spec.ts,api-contracts.spec.ts,projects.spec.ts) against local resources;npm run e2e:serverboots the dev stack for them. Do not make e2e depend on production, staging, real model quota, real user credentials, or direct database access.npm run test:coverageis the enforced coverage gate (vitest run --project unit --project web --coverage): business logic (server/domain + server/usecases) ≥95% per-file, everything else included (gateways, shared, src/features, src/lib) ≥90% per-file.npm run lint:specis a governance lint (sibling tolint:arch): it fails when an enforced capability has a scenario id with no[spec: id]breadcrumb. Add a capability toENFORCED_CAPABILITIESinscripts/check-spec-coverage.tsonce its spec and breadcrumbs land.- Do not add standalone
scripts/test runners for product behaviour. Restish/OpenAPI contract behaviour lives inserver/http/*.test.ts(integration) or the native Playwright crowns ine2e/*.spec.ts.
server/- Cloudflare Worker backend, Hono routes, auth, D1 access, runtime orchestration, and Pi bridge code.server/routes/- API routes and OpenAPI-backed control-plane surfaces.server/auth/- FlareAuth and session integration.server/db/- D1 schema and persistence helpers.server/runtime/- Cloudflare Sandbox and Pi runtime integration.src/app/- React application providers and router setup.src/features/- Route-level feature orchestration for console pages.src/features/console/- Shared authenticated console shell and context.src/console/- Reusable AMA product components, form helpers, formatting, defaults, and view models.src/components/ui/- shadcn-generated primitives. Prefer these before writing custom primitives.spec/- Product behaviour in Gherkin (BDD-lite). One.featureper capability; tests trace back via[spec: id]. Seespec/README.md.e2e/- Native Playwright crowns (*.spec.ts), fixtures, browser helpers, and local e2e harnesses for@e2escenarios.docs/product/- Product decisions, UI/UX standards, API/SDK boundaries, and implementation notes.docs/infra/- Cloudflare deployment and infrastructure notes.
- Follow
docs/product/ui-ux-standards.mdfor all visible console work. src/App.tsxshould compose providers andRouterProvider; primary route definitions belong insrc/app/router.tsx.- Primary resources must be URL-routed and deep-linkable. Do not drive major pages only through local view state.
- Use React Query for server state. Do not add feature-level
useEffect + useStateAPI loading loops. - Use the shared Hono RPC client for browser control-plane calls. Do not add ad hoc
fetch('/api/...')clients in feature code. - Compose route pages from shadcn primitives and shared AMA components. Do not recreate local button, input, card, panel, or field systems.
- Forms use shadcn
Fieldprimitives for labels, descriptions, errors, and validation layout. - Date and time display uses the shared dayjs-backed formatter in
src/console/format.ts. - Destructive actions use the shared confirmation dialog.
- For visible UI changes, check desktop and 390px mobile behavior. Avoid horizontal scrolling, truncated mobile nav labels, card-in-card layouts, and marketing-style hero surfaces inside the console.
- Control-plane API behavior must be represented in OpenAPI generated from route schemas.
- Keep route handlers, validation schemas, tests, and OpenAPI output aligned in the same change.
- Stable error envelopes matter; do not replace structured API errors with ad hoc strings.
- OpenAPI is the contract for direct HTTP, generated SDKs, and restish CLI workflows.
- OpenAPI is the external contract. It should not become the internal browser client implementation when Hono RPC can provide the project-local API entrypoint.
- A running session owns exactly one sandbox.
- Environments are reusable configuration and policy snapshots, not running containers.
- A session binds immutable agent and environment snapshots for runtime execution.
- Session events, transcript, tool calls, usage, policy decisions, and safe runtime errors must remain inspectable after completion or failure.
- Do not expose raw sandbox ports or preview URLs as the product surface.
Choose the smallest meaningful check, then broaden when touching shared contracts:
- Native Playwright e2e crowns:
npm run e2e - Coverage gate:
npm run test:coverage - Type safety:
npm run typecheck - Unit/integration/runtime tests:
npm test - Lint/format checks:
npm run lint - Production build:
npm run build
For v1 acceptance or broad changes, run npm run lint, npm run typecheck, npm test, npm run test:coverage, npm run e2e, and npm run build.
- Do not commit
.dev.vars,.env, secrets, local Playwright captures, Wrangler state, or generated runtime artifacts. - Do not change real Cloudflare resource names, account ids, service bindings, or deployment targets unless the task requires it.
- Prefer failing fast over adding fallback logic. Add defensive handling only at real boundaries: user input, external APIs, network, filesystem, and process execution.