Files
agentic-dev/docs/guides/infrastructure-work-shape.md
Danijel Martinek 9576987637 docs(architecture): agent-first workflow design + work-shape guides
Captures the design from the brainstorm session on agent-first development
in this template. Architecture doc covers the four interlocking pillars:

- Conformance engine (manifest + brands + ESLint + boot + CI gate)
- Agent workflow (PRD -> Epic -> Story -> Task; manifest-first ordering;
  TDD per slice; in/out scope at every level)
- Local task system at docs/work/ (filesystem markdown, derived committed
  _state.json, single-writer orchestrator rule)
- Sandcastle orchestrator (implementer + reviewer loop, DAG-respecting,
  configurable retry cap)

Work-shape guides extend the architecture doc with operational detail for
frontend work (atomic design, Storybook-as-spec, component + Playwright
screenshot test gates, Storybook MCP reviewer integration) and
infrastructure work (ADR-first flow, dedicated ADR elicitation skill,
optional core packages vs. new infrastructure layers).

Phasing is conformance-first: build the enforcement system manually, then
build the dispatch substrate, then migrate remaining features through it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 21:08:44 +02:00

155 lines
7.2 KiB
Markdown

# Infrastructure work shape
How infrastructure work — new core packages, new external services, new database backends, new build/deploy primitives — flows through the agent-first workflow. For the broader workflow context see [`docs/architecture/agent-first-workflow-and-conformance.md`](../architecture/agent-first-workflow-and-conformance.md).
## When this guide applies
You're proposing or implementing:
- A new optional core package (`core-cache`, `core-email`, `core-feature-flags`, …)
- A new external service or layer (Redis, CDN, alternative CMS, additional message bus, …)
- A change to bootstrap, build, or CI infrastructure
- A swap of an existing infrastructure component
If you're working on backend feature code or frontend, this is not your guide.
## Two categories
| Category | Example | Path |
|---|---|---|
| **A. New optional core package** | `core-cache`, `core-email` | `pnpm turbo gen core-package <name>` |
| **B. New infrastructure layer** | Redis, CDN, deploy target, CI image swap | ADR → integration PRD → epic + stories |
Category A is well-trodden: the generator emits a canonical core-package shape; the conformance system already handles optional cores via `requiredCores` in manifests. No new conformance rules required.
Category B is the one that needs the ADR-first dance described below.
## ADRs precede infrastructure work
ADRs (Architecture Decision Records) live at `docs/adr/NNN-<slug>.md`. The pattern is established in this repo (ADR-018 captured the audit-and-compliance system, for example).
ADRs are to infrastructure what PRDs are to features: decision documents, written first, providing the rationale that downstream PRDs and stories implement. An ADR documents *what was decided and why*; a PRD documents *what to build*.
## ADR authoring flow
```
1. Human runs `pnpm work adr-new "<one-line proposal>"`
2. Dedicated ADR elicitation skill interviews the human:
- Context (what's the situation today?)
- Drivers (what's forcing a decision?)
- Considered options (what alternatives are on the table?)
- Trade-offs (what does each option cost?)
- Decision (which option, and why?)
- Consequences (what changes downstream?)
3. Agent drafts ADR at docs/adr/NNN-<slug>.md with status: proposed
4. Human reviews, edits, flips to status: accepted (or rejected / superseded)
5. Accepted ADR(s) trigger one or more integration PRDs
6. PRDs flow through the normal decompose → dispatch loop
```
The ADR elicitation skill is distinct from the PRD elicitation skill. Same interview shape, different template and pushiness:
- PRD eliciter focuses on **problem framing** and **success criteria**
- ADR eliciter focuses on **alternatives** and **trade-offs** — it actively pushes back if only one option is articulated
## ADR template
```markdown
---
id: NNN
title: <decision title>
status: proposed | accepted | rejected | superseded
date: YYYY-MM-DD
supersedes: []
superseded-by: null
related-prds: []
---
## Context
What's the situation? What's broken or about to break? Who is affected?
## Drivers
What's forcing this decision now?
## Considered options
- Option 1: ...
- Pros / Cons
- Option 2: ...
- Pros / Cons
- Option 3: ...
- Pros / Cons
## Decision
We chose Option X because ...
## Consequences
### Positive
- ...
### Negative / accepted trade-offs
- ...
### Follow-up work
- PRD: ...
- PRD: ...
```
## Path A: new optional core package
When the new infrastructure is *small enough to be a single package* (cache, email, feature flags, etc.):
1. ADR (if the decision is non-trivial — for "add core-cache because we need response caching", a short ADR is still worthwhile)
2. `pnpm turbo gen core-package <name>` — generator emits canonical shape
3. Implement package contents (interface, impls, tests) — flows through normal story-and-task decomposition
4. Add `<name>` to manifests' `requiredCores` in features that adopt it
5. Wire into `BindContext` in `core-shared/di/`
6. Wire into each app's `bindAll()` aggregator
7. Update generator templates if features need to scaffold differently when this core is present (e.g., `core-events` causes `turbo gen feature` to emit event-handler stubs)
The conformance system catches forgotten wiring automatically:
- `required-cores-installed` ESLint rule flags manifests declaring `requiredCores: ["<name>"]` when the package isn't in `pnpm-workspace.yaml`
- Boot assertion `assertConformance(ctx)` fails on missing bind-context entries
- CI's `pnpm conformance` aggregates the cross-feature view
## Path B: new infrastructure layer
When the new infrastructure is bigger than one package — a new external service, a swap of an existing component, a deploy-target change:
1. **ADR** captures the decision and trade-offs
2. **Integration PRD(s)** specify what to build/wire/migrate; one PRD per integration concern is common
3. PRDs decompose into the normal Epic → Story → Task hierarchy
4. Stories typically include: a new core package (if one fits), configuration plumbing, bootstrap wiring, feature adoption, documentation updates, and (often) a deprecation/removal of the prior approach
Examples of category B work:
- "Add Redis for response caching" — ADR + core-cache package + bind-context wiring + adoption stories per feature
- "Replace Payload with Sanity" — ADR + repository implementation swap + migration scripts + docs rewrite
- "Move from Vercel to Cloudflare Workers" — ADR + new deploy target stories per app + CI workflow updates
## Conformance for infrastructure
Two rules extend the conformance system for infra concerns:
| Rule | Layer | What it catches |
|---|---|---|
| `required-cores-in-workspace` | ESLint + CI | manifest declares a core that isn't in `pnpm-workspace.yaml` |
| `core-package-shape-conforms-to-generator` | CI | a core package's structure has drifted from what `pnpm turbo gen core-package <name>` would produce today |
These extend the existing milestone iv work; no new tooling required.
## Common pitfalls
- **Skipping the ADR for "small" infra changes.** A swap of a single dependency is still a decision worth recording. The ADR doesn't have to be long — but it should exist.
- **Implementing before the ADR is accepted.** Don't decompose an integration PRD into stories until the ADR is `accepted`. The work-system orchestrator can refuse to dispatch tasks whose epic's ADR is still `proposed`.
- **Manifest drift after infra adoption.** A new core is added but features that use it don't declare it in `requiredCores`. The ESLint rule catches the inverse (declared-but-not-installed); CI's full conformance run also checks the other direction.
- **Bootstrap wiring forgotten.** A new core package is created but never bound in `apps/*/server/bind-production.ts`. Boot assertion catches this on first `pnpm dev`.
- **Documentation lag.** New infra is shipped but `docs/guides/` and `CLAUDE.md` aren't updated. Make documentation a required story under any integration epic.
## Open items (filled in as we ship)
- ADR elicitation skill — exact prompt shape and heuristics
- ADR ↔ PRD linkage — how an accepted ADR fans out into one or more PRDs (frontmatter `related-prds`?)
- Refusal logic — should the work-system refuse to decompose a PRD whose triggering ADR is still proposed?