/* voltgrid */ → spec

Spec-Driven with AI

This is how I work: requirements and technical design get written first, as files in the project repo, not as a Word attachment in an email. An agent loop harness then works against that spec: implement, test, fix, until every criterion is green. The result is a project that documents itself. On the left the spec of SPEC-042, on the right the loop. Watch the checkboxes get ticked.

requirements + technical designagent loop until greencode · tests · openapidavid.review()fully documented project
specs/SPEC-042-start-charging-session.md

# SPEC-042 · Start Charging Session

status: approved · owner: david · agents: enabled

## Goal

Drivers start a charging session from the app; pricing is estimated upfront and billing can never drift from the live estimate.

## Acceptance Criteria

  • AC-1available station + supported connector → 201 + receipt
  • AC-2station in maintenance → 422 (stationId)
  • AC-3occupied station → 422 (stationId)
  • AC-4unsupported connector → 422 (connectorType)
  • AC-5estimatedKwh outside 1–150 → 422 (estimatedKwh)
  • AC-6receipt contains estimated cost (price/kwh × kwh + base fee)

## API Contract

POST /api/v1/sessions {'{'} stationId, connectorType, estimatedKwh {'}'} → 201 | 422

## Technical Design

layers: controller → action → TariffCalculator (single pricing source, reused by billing worker) · SessionStarted event → realtime hub · errors as dedicated exceptions → 422 field errors

~/voltgrid · agent-harness · loop

// the spec is the source, every artifact in this sandbox derives from it

// the result: a project that documents itself

~/voltgrid · repo
voltgrid/
├── docs/
│   ├── specs/                    ← requirements, versioned
│   │   ├── SPEC-041-station-filtering.md   ✓ implemented
│   │   ├── SPEC-042-start-charging.md      ✓ implemented
│   │   └── SPEC-043-invoice-pdf.md         ○ in progress
│   ├── design/                   ← technical design + ADRs
│   │   ├── architecture.md
│   │   └── adr/0007-queue-based-billing.md
│   └── api/openapi.json          ← always in sync
├── app/ · server/ · tests/          ← the code, right next to it
└── README.md
  • Requirements live as versioned specs in the repo, every requirement has a file, a status and a history.
  • The technical design sits right next to it: architecture docs and ADRs record what was decided and why.
  • The loop keeps everything in sync: when a spec changes, code, tests and OpenAPI follow. The docs cannot go stale, they are the source.
  • Onboarding and handover: reading docs/ is enough. New developers, clients or an audit find the complete project knowledge in one place.

// why spec-driven, especially with ai

Docs come first, and never go stale

Requirements, API contract and technical docs exist before the first line of code. When requirements change, the spec changes, and the loop pulls code, tests and OpenAPI along. There is no second, outdated truth.

Requirements become testable

Acceptance criteria are written so agents can derive tests from them directly. What the client signed off is literally what CI verifies, no translation loss between domain and code.

AI becomes productive instead of risky

Agents are fast, but only as good as their target. Against a precise spec with a loop harness they work until the criteria are green, a hallucination fails at the test gate instead of in production.

Review at the right level

I review the spec and the final diff, not every keystroke. Architecture and domain decisions stay with the human, the loop does the legwork. That's the speed gain without losing control.

// This portfolio site was built exactly this way, by the way: concept spec first, then iterative implementation with AI agents · every line reviewed.