Design history: the original vision PRD
Status: Implemented (P0 + P1; P2 items C4 /system:ship, E3 deferred) — open decisions resolved 2026-05-22, Java/Go shapes added as extensibility test 2026-05-22
Author: @ika100
Last updated: 2026-05-22
Audience: Future implementers (human + Claude agents)
1. Summary
Section titled “1. Summary”Today ika100/claude-platform supports two repo shapes: a Python service (service-python) and a Python library (library-python), wired together by an external GitOps repo. To build full SaaS products on a microservice architecture the platform needs more shapes — a web frontend, a first-class GitOps “application” repo, and additional backend languages — plus the agents and slash commands that operate on each. The platform must be extensible: adding a future shape should follow a documented contract, not a custom PRD per language.
This document specifies the target state. It does not prescribe an implementation order; that comes from the architect after this PRD is approved.
2. Goals
Section titled “2. Goals”- One marketplace, a registry of supported shapes, agents tuned to each — and a documented contract for adding more.
- Bootstrapping a new repo of any registered shape is a single slash command.
- The same orchestration model (
/component:build,/component:fix,/component:fix,/component:release) works across all shapes, with shape-specific agents routed in transparently. - GitOps repos describe whole applications (a set of services + their wiring) and are themselves a first-class shape with their own agents.
- Updates to agents flow via
/plugin marketplace update; updates to skeletons flow viacopier update. Two channels, same as today.
3. Non-goals
Section titled “3. Non-goals”- A developer portal / service catalog UI (still Backstage territory; see Architecture §“What this is NOT”). Re-evaluate past ~15–20 services.
- Languages beyond Python, TypeScript, Java, and Go in this PRD. Adding more (Rust, Kotlin, …) follows the §4.1 add-a-shape contract rather than a new PRD.
- Cloud provider abstractions. Manifests stay Kustomize + ArgoCD.
- A new agent orchestration framework. We extend the existing
svc/gitops/sharedmodel; we don’t replace it.
4. Shape registry
Section titled “4. Shape registry”The platform supports the following shapes. New shapes are added per §4.1.
| Shape | Plugin | Template | Default stack | Status |
|---|---|---|---|---|
service-python |
svc |
service-python |
Python 3.12, uv, FastAPI | stable |
library-python |
svc (subset) |
library-python |
Python 3.12, uv | stable |
web-nextjs |
web |
web-nextjs |
Node LTS, pnpm, Next.js App Router | stable |
gitops-app |
system |
gitops-app |
Kustomize + ArgoCD ApplicationSet, env-only overlays | stable |
cluster-gitops |
cluster |
cluster-gitops |
Argo CD app-of-apps for one cluster’s shared services and systems | stable |
service-java |
svc-java |
service-java |
JDK 21 LTS, Maven, Spring Boot 3.x | stable (extensibility case study) |
service-go |
svc-go |
service-go |
Go 1.22+, stdlib net/http + chi router |
stable (extensibility case study) |
gitops-app is distinct from the single platform-wide GitOps repo we already have. The platform-wide repo discovers all deployable-service repos via topic. A gitops-app repo is system-scoped — it pins which services, which versions, which environments make up one SaaS system. A user with N SaaS systems has N gitops-app repos.
service-java and service-go are in this PRD primarily to validate that §4.1’s add-a-shape contract works in practice. Per-shape stack details (Maven vs Gradle, chi vs gin, etc.) are deferred to per-shape ADRs at implementation time.
4.1 Adding a new shape (the extensibility contract)
Section titled “4.1 Adding a new shape (the extensibility contract)”A shape is fully specified by three artifacts. To add a new shape, deliver all three in one PR:
- Copier template at
templates/<shape>/with acopier.yml, aCLAUDE.mdtailored to the shape, adevbox.jsonthat defines the canonical recipes (test,lint,quality,image-build,deploy, plus shape-specific ones), and the same “always re-templated” / “project-owned” file conventions as existing templates. - Plugin providing the shape’s agents: at minimum
coderandtester;deploymentandobservabilityif the shape produces a deployable artifact. The plugin may be new (svc-java) or extend an existing one (svcalready coverslibrary-pythonas a subset). Agents always invokedevbox run <recipe>— never raw tools. - Shape detection registration: an entry in the detection table maintained in ADR-008: Shape detection —
.copier-answers.ymlwith sniffing fallback — primary mapping from the template’s_src_pathto the shape identifier, plus a sniffing-fallback rule (a file or content marker that uniquely identifies the shape for pre-Copier repos).
The Java and Go shapes are the reference implementations of this contract. After they ship, adding a third backend language (e.g. Rust) should be a documentable copy-paste exercise; if it isn’t, the contract has a gap and this section gets revised before the next shape lands.
5. Personas
Section titled “5. Personas”- Solo founder / small team lead (primary): builds and ships SaaS products on this platform. Owns one or more
gitops-apprepos plus the underlying services and libraries. - Contributor / future hire: works on one service at a time. Needs
/component:buildand friends to work without platform knowledge. - Claude agent: not a human, but a real consumer. Each agent reads
CLAUDE.mdand the marketplace plugins to do its job. PRD acceptance criteria explicitly include “an agent can do X without human handholding.”
6. User stories
Section titled “6. User stories”Stories are grouped by epic. Each has acceptance criteria a tester can verify. P0 = blocks first usable release; P1 = needed for the platform to be complete; P2 = nice-to-have, may be deferred.
Epic A — Bootstrapping any registered shape
Section titled “Epic A — Bootstrapping any registered shape”A1 (P0). Universal bootstrap command.
- As a developer, I can run
/component:new <name> --type <shape>and get a working repo for any shape in the §4 registry. - AC: the command resolves the shape, invokes Copier against
templates/<shape>/, creates the GitHub repo with the correct topic (deployable-servicefor everything exceptlibrary-pythonandgitops-app), and pushes the first commit. - AC: existing shape-specific flags continue to work as aliases (
--library→library-python,--web→web-nextjs,--gitops→gitops-app). - AC (regression):
/component:new <name>with no flag still produces aservice-pythonrepo.
A2 (P0). Bootstrap acceptance per shape. The bootstrap command produces a working repo for every shape. Per-shape acceptance:
web-nextjs:devbox run devstarts Next.js;devbox run test,devbox run quality,devbox run image-buildall succeed; repo taggeddeployable-service.gitops-app:applications/<name>/applicationset.yaml+applications/<name>/overlays/{dev,staging,prod}/+system.yamlexist; repo not taggeddeployable-service; Argo reconciles with no manual edits.service-java(P1):devbox run devstarts a Spring Boot app on the configured port;devbox run test,devbox run quality(Spotless + Checkstyle or equivalent), anddevbox run image-buildall succeed; repo taggeddeployable-service.service-go(P1):devbox run devrunsgo run ./cmd/<name>;devbox run test,devbox run quality(golangci-lint, which includesgo vet+staticcheck), anddevbox run image-buildall succeed; repo taggeddeployable-service.
A3 (P1). Extensibility contract is real.
- Adding a new shape follows §4.1 with no PRD edits — the contract is sufficient.
- AC:
docs/templates.mddocuments the contract end-to-end (file layout, agent requirements, detection registration). - AC: the Java and Go shapes are the canonical worked examples referenced from that doc.
Epic B — Per-shape agents
Section titled “Epic B — Per-shape agents”Each non-gitops shape needs language/framework-specific coder, tester, and (where deployable) deployment + observability agents. PM and architect agents stay shape-agnostic and route to the right plugin via the architect plan’s shape field.
B1 (P0). Shape-aware coder agents.
- Each shape ships a
coderthat writes idiomatic code for that stack and always invokesdevbox run(never rawnpm/pnpm/uv/mvn/go). - AC per shape:
web-nextjswrites TS/TSX in App Router style, ESLint +tsc --noEmitclean.service-javawrites Java 21 in Spring Boot 3.x conventions, Maven build green.service-gowrites idiomatic Go,go vet+staticcheckclean. Python coder unchanged.
B2 (P0). Shape-aware tester agents.
- Each shape ships a
testerthat produces tests in that shape’s idiom and runsdevbox run test. - AC per shape:
web-nextjsproduces Vitest tests, Playwright if e2e was enabled (per ADR-002: Web testing stack — Vitest + Playwright opt-in).service-javaproduces JUnit 5 + Spring Boot Test, coverage via JaCoCo.service-goproduces stdlibtesting(plustestifyif requested), coverage viago test -cover.
B3 (P0). Shape-aware deployment agents.
- Each deployable shape ships a
deploymentagent that writes Dockerfile + k8s manifests + CI workflow. - AC (all shapes): multi-stage Docker build, non-root user; k8s
Deployment+Service+Ingress; health/ready endpoints respond; CI matches the platform-wide workflow conventions.
B4 (P0). Shape-agnostic PM and architect.
product-managerandarchitectproduce specs and plans for any registered shape.- AC: architect plan YAML metadata includes a
shapefield whose value must be a key in the §4 registry; orchestrator routes coder spawns to the correct plugin’s coder agent based onshape. - AC: PM user stories may target multiple repos in one feature (“add billing” → web changes + service changes + gitops bump).
B5 (P1). Gitops-app composition agent.
- The
gitopsplugin gains acomposeagent that editssystem.yamland ApplicationSet manifests to add/remove services from an application. - AC: can add a new service to an existing gitops-app with one slash command.
- AC: validates that every referenced service repo has the
deployable-servicetopic before adding it.
B6 (P1). Cross-repo promote agent (extension of existing promote).
/instance:promoteworks against agitops-apprepo, promoting a service’s image tagdev → staging → prodwithin the application’s gitops repo.- AC:
/instance:promote <component> --to <to>opens a PR against the gitops-app repo pinning the new tag. - AC: works when invoked from inside the gitops-app repo OR from a service repo (auto-resolves the target gitops-app via a config file).
Epic C — Slash commands span the full app lifecycle
Section titled “Epic C — Slash commands span the full app lifecycle”C1 (P0). /component:build is shape-aware.
- Running
/component:build <description>in any registered shape’s repo invokes the correct shape’s coder/tester/deployment chain. - AC: detection follows ADR-008: Shape detection —
.copier-answers.ymlwith sniffing fallback; orchestrator dispatches to the right plugin’s agents;gitops-apprepos route tocompose+promoteinstead.
C2 (P1). /system:plan (new) spans multiple repos.
- Running
/system:plan <description>from agitops-apprepo can fan work out to multiple component services + the web frontend, then bump versions in the gitops-app overlays. - AC: the command takes a feature description, plans which repos are touched, dispatches
/component:build(or shape equivalent) into each affected repo’s worktree, opens PRs in each, then opens a final PR in the gitops-app repo pinning the new tags after merges. - AC: failure in one repo’s PR pauses the chain and surfaces the error; partial state is recoverable.
C3 (P1). /component:release works for web repos.
- Releasing a Next.js repo follows the same semver + CHANGELOG + tag flow.
- AC: tag triggers a Docker image push tagged with semver (same matrix as Python service).
C4 (P2). /system:ship (new) cuts a coordinated release across an application.
- AC: bumps the application version (semver), pins each component service to its current
mainimage tag inprodoverlay, writes an aggregated CHANGELOG composed of each component’s recent changes since the last app release.
Epic D — Templates and updates
Section titled “Epic D — Templates and updates”D1 (P0/P1). Each registered shape has a Copier template.
- AC (P0):
templates/web-nextjs/andtemplates/gitops-app/exist withcopier.ymland the same conflict-resolution semantics asservice-python. - AC (P1):
templates/service-java/andtemplates/service-go/exist with parity to the other templates (canonicaldevbox.jsonrecipes, CI workflow, Dockerfile, k8s manifests, CLAUDE.md, marketplace plugins enabled).
D2 (P0). copier update works on existing repos of any shape.
- AC: an existing web repo can pull skeleton updates (CI workflow, devbox recipes, Dockerfile base image bumps) via
copier update --skip-answeredwithout losing project-owned files.
D3 (P1). Template authoring guide.
- A short doc explains how to add a new shape’s template (file layout, what goes in
copier.yml, which files are “always re-templated” vs project-owned). - AC: doc lives at
docs/templates.mdand is referenced fromARCHITECTURE.md.
Epic E — Quality, security, observability across shapes
Section titled “Epic E — Quality, security, observability across shapes”E1 (P0). /component:check works on every shape.
- AC: Python repo — ruff + mypy + pip-audit + detect-secrets + bandit + trivy.
- AC:
web-nextjsrepo — ESLint +tsc --noEmit+pnpm audit+ detect-secrets + trivy. - AC:
gitops-apprepo —kustomize buildvalidation +kubeconform+ detect-secrets + opa/conftest if policies are present. - AC (P1):
service-javarepo — Spotless/Checkstyle + Maven build + OWASP Dependency-Check + detect-secrets + trivy. - AC (P1):
service-gorepo —gofmt+go vet+staticcheck+govulncheck+ detect-secrets + trivy.
E2 (P1). Observability agent for web shape.
- The
webplugin’sobservabilityagent wires OpenTelemetry for browser + server, structured logging on the server side, and a/api/metricsendpoint if requested. - AC: produces a wired-up Next.js repo where
/api/health,/api/ready, and/api/metricsall respond.
E3 (P2). Security agent extensions.
- AC: web-shape security agent runs SCA against
package.json, checks for known-vulnerable React/Next versions, runs trivy on the built image.
Epic F — Documentation and onboarding
Section titled “Epic F — Documentation and onboarding”F1 (P0). ADOPTING.md covers every shape.
- AC: existing doc adds sections for “Migrating a web repo” and “Migrating a gitops-app repo.”
F2 (P0). AGENTS.md lists the new agents.
- AC: each new agent (web coder, web tester, web deployment, web observability, gitops compose) appears in the table with model selection rationale.
F3 (P1). Per-shape CLAUDE.md content is templated.
- AC: each Copier template ships a
CLAUDE.mdtailored to its shape (devbox recipes, conventions, branch rules) so consumers don’t write that file by hand.
7. Acceptance signal for “platform is done”
Section titled “7. Acceptance signal for “platform is done””A new user can, from scratch, in under one working day:
/component:new my-saas --gitops— creates the application repo./component:new my-saas-api— creates a backend service./component:new my-saas-web --web— creates the frontend.- In each service repo:
/component:build "ping endpoint"//component:build "landing page"— feature lands with tests, CI passes, image pushed. - From the gitops-app repo:
/component:add add my-saas-api && /component:add add my-saas-web— application now declares both services. /instance:promote my-saas-api dev staging && /instance:promote my-saas-web dev staging— staging pinned to the new images, Argo reconciles, app is live.
No hand-edited YAML, no copy-pasted boilerplate, no out-of-band npm/pip/docker commands.
8. Constraints & assumptions
Section titled “8. Constraints & assumptions”- Every shape uses
devboxas the canonical task runner — even web.devbox.jsonrecipes wrappnpm/npmthe same way they wrappytest/uv. (Agent orchestration §“Golden rule”) - All shapes’ deploys go through Kustomize + ArgoCD. We do not add Helm, Terraform, or raw
kubectl applypaths in this PRD. - The marketplace stays GitHub-based (
ika100/claude-platform). No private registries. - Python version policy stays at 3.12+ (consumer-overridable). Node version policy: TBD in §11.
9. Out of scope (revisit later)
Section titled “9. Out of scope (revisit later)”- Mobile (iOS/Android) shape.
- Worker-only shape distinct from
service-python(today’s template already handles workers viadevbox run worker). - Multi-cluster routing logic (the platform GitOps repo’s ApplicationSet generator handles single-cluster discovery; multi-cluster is its own design problem).
- Secret management — assumed to be External Secrets Operator + a cloud KMS, configured at cluster bootstrap, not by this platform.
10. Risks
Section titled “10. Risks”| Risk | Impact | Mitigation |
|---|---|---|
| TypeScript ecosystem churn (Next.js major versions, app router changes) | High — template rots faster than Python | Pin Next.js major in template, copier update flow handles bumps, write a TS upgrade ADR per major |
Cross-repo orchestration complexity (/system:plan) |
High — partial failure modes are nasty | Start with /system:plan as a plan-only command (Epic C2 in P1, not P0); execution lands later once we trust the planning |
Architect plan format changing to support shape field |
Medium — breaks existing plans | Make shape optional with service-python as the default; old plans still work |
Two gitops notions (platform-wide vs per-app) confuse users |
Medium | Rename: platform-wide repo stays “platform gitops”; per-app repos are “application repos” / gitops-app shape. Update docs accordingly |
| Web tester agent flakiness (Playwright in CI) | Medium | Default to Vitest only; Playwright is opt-in per repo via a Copier prompt |
11. Resolved decisions
Section titled “11. Resolved decisions”Resolved on 2026-05-22. Each becomes an ADR under docs/adr/ before implementation; the rationale here is the short form.
- Web testing stack — Vitest + Playwright opt-in. Vitest is on by default for unit/component tests. Copier prompt
needs_e2e?toggles a Playwright scaffold (e2e/dir,devbox run e2erecipe). Rationale: cheap default for libraries and simple UIs, opt-in for products that actually need browser flows. → ADR-002. - Web package manager — pnpm. Strict lockfile, content-addressed store (fast CI), workspace-ready. Rationale: the serious-TS default for 2026; npm is slower with worse hoisting; bun is still ecosystem-young. → ADR-003.
- Next.js router — App Router only. Template scaffolds App Router; Pages Router is not supported. Rationale: new Vercel docs assume it; supporting both doubles the surface agents must reason over. → ADR-004.
- Node version policy — pin current LTS in template, bump via
copier update. Template pins one Node major (current LTS at template release); platform PRs bump it; consumers pull viacopier update. Rationale: reproducibility parity with how we handle Python. → ADR-005. gitops-appoverlay structure — env-only (dev/staging/prod). No region nesting in v1. Rationale: matches every upstream Argo example; multi-region is a real but separate problem to design later, and pre-building it bloats single-region products. → ADR-006.- Cross-repo orchestration — plan-only in v1, execution in v2.
/system:planv1 produces a multi-repo plan (“repo A needs X, repo B needs Y, gitops-app pins both after merge”); user runs/component:buildper repo. Execution promotes to v2 once the planner is trusted. Rationale: partial-failure recovery across multiple PRs is the hard problem; plan-only delivers ~80% of the leverage with ~10% of the risk. → ADR-007. - Shape detection —
.copier-answers.ymlwith sniffing fallback. Primary: parse_src_pathfrom.copier-answers.yml(e.g.gh:ika100/claude-platform/templates/web-nextjs). Fallback for pre-Copier repos: sniff (next.config.*→ web;pyproject.toml+Dockerfile→ service-python;applications/*/applicationset.yaml→ gitops-app;pyproject.tomlwithoutDockerfile→ library-python). Rationale: uses existing artifacts, no extra config file to maintain. → ADR-008.
12. References
Section titled “12. References”- Architecture — why the platform looks the way it does today.
- Agent orchestration — orchestration model the new shapes plug into.
- Adopting and troubleshooting — onboarding flow that the new shapes extend.