AvelonDocs

Guide 12

Build plan

12. Build plan

Structured for fleet execution. The schedule is not set by labor, it is set by three things that do not compress:

1. Contract freeze. Parallel agents cannot negotiate interfaces mid-flight. Twenty agents building against an unfrozen QueryIR produce twenty incompatible packages that each pass their own tests. 2. Verification against live services. RLS enforcement, PostgREST embed depth, pgmq visibility timeouts, Bun on Vercel. Wall-clock bound regardless of how many agents run. 3. Review bandwidth. Agents produce competent-average by default. The TUI feel, the error message wording, the docs voice: that is what decides whether anyone loves this, and it is not parallelizable.


Dependency graph

S1 decisions ──▶ S2 contract freeze ──┬──▶ S3 conformance suites ──▶ Wave A (drivers)
                                      │                                    │
                                      └──▶ Wave B (core subsystems) ───────┤
                                                                           ▼
                                                                    S4 integration
                                                                           │
                                                                           ▼
                                                                    Wave C (surface)
                                                                           │
                                                                           ▼
                                                                    Wave D (launch)

Serial spine

S1. Decisions locked

Owner: human. Output: 02-decisions.md with no open items, and a chosen umbrella name.

Blocks everything. The name blocks the scope, which blocks every package name.

S2. Contract freeze

Owner: human plus an adversarial review loop. This is the gate.

Freeze and publish:

  • QueryIR and Predicate
  • Adapter
  • All sixteen driver contracts and their capability shapes
  • The error taxonomy
  • The capability narrowing type machinery
  • HttpRequest, ActionResult, ViewResult
  • The event and listener contracts

Acceptance: @avelon/core typechecks, every contract has a doc comment, and the capability narrowing spike passes with every @ts-expect-error firing.

Nothing downstream starts before this lands. A contract edited later to unblock one package silently breaks every package built against the original.

S3. Conformance suites

Fans out one agent per contract, but must land before any implementation. These are the acceptance criteria that let Wave A run without human review.

Acceptance: each suite runs green against its fake and red against a deliberately broken stub.

S4. Integration

Owner: human plus a small team. The vertical slice end to end: a Post resource with routes, controller, request, model, ward, policy, views, one event with a queued listener, running on both database drivers.

This is where the estimate actually lives. The failure mode of fleet execution is twenty green packages that do not compose.


M0 spike

Runs before S2 and informs it. One week. Prove what can kill the design, build no features.

#AssumptionFails ifFalls back to
1Domain directories colocated inside Next's app/ survive next build and never routeany domain directory becomes reachable as a URLsrc/app router, domain code renamed
2Generated server actions dispatch to a controller class and return validation stateaction serialization rejects the patternroute handlers plus _method
3Bun runtime on Vercel serves Next with ISR and middlewareany of the three breaksNode runtime, Bun for tooling only
4A ward compiles to RLS and the same predicate scopes a query identicallyresults diverge on any fixturewards become client-side only, RLS documented as manual
5Throwaway Hono adapter serves the same controllersthe contract needs Next-shaped conceptsadapter abstraction dropped, Next-only
6The query IR compiles for both Supabase and Postgres with identical resultsthe IR cannot express one driver's needsIR redesigned before S2, not after

Assumptions 4 and 6 must run against a live database. No mocks.


Wave A: drivers

Parallel after S3. Acceptance is conformance green, no human read required.

PackageImplementsNotes
@avelon/supabase databasedatabaseincludes the ward-to-RLS compiler
@avelon/supabase identityidentity
@avelon/supabase socialsocial
@avelon/supabase tokenstokens
@avelon/supabase storagestorage
@avelon/supabase queuequeuepgmq plus the drain worker
@avelon/postgresdatabasetransactions, deep relations, window functions
@avelon/resendmail
fakesall sixteenone agent, mechanical

Wave B: core subsystems

Parallel with Wave A, gated only on S2.

PackageScope
query IR builderpredicate construction, relation planning
Scrivenermodels, relations, scopes, casts, timestamps, soft deletes, lifecycle hooks
ward compilerpredicate to SQL policy, predicate to IR injection, drift detection
eventsdispatch, priority ordering, propagation halt, afterCommit, until
errandsjob contract, three delivery modes, retry, failure table
policies and gateregistration, authorize, can
requestsZod integration, error shaping, authorize hook
config resolutiondriver wiring, environment merge, capability matrix
error taxonomybase classes, cause chaining, adapter mapping

Wave C: surface

After S4.

PackageScope
@avelon/nextroute codegen, action dispatch, page wrapper, middleware bridge
hono spikethrowaway, proves the contract, never shipped
@avelon/cliTUI, every generator, stubs, doctor, tinker
@avelon/bailiffevery rule with reasons and autofixes
assaytest harness, HTTP helpers, factories, seeds

Wave D: launch

ItemScope
docs sitethe Avelon vocabulary and command map is the landing page, not a sub-page
example appone complete application, not a todo list
docs:checkREADME linting for packages
driver authoring guidehow to write and certify a driver
npm publishlockstep pack of @avelon/*; first public line is a human 0.1.0

Work package format

Every package, without exception:

Title
Scope: what is in, what is explicitly out
Depends on: contract or package names, never "the other agent's work"
Acceptance:
  - bun test green, including conformance for any contract implemented
  - tsc --noEmit clean under strict
  - reeve bailiff clean
  - named integration test passes
  - reeve docs:check clean
Escalate if: the specific conditions that mean stop and ask

If acceptance requires a human to exercise judgment about whether the result is correct, it is not a work package. It is a design decision and it belongs in S2.


Estimate

Two to three weeks wall clock, and almost none of it is typing.

  • S1 and S2 are a day or two of focused human attention.
  • M0 is wall-clock bound by live service verification.
  • Waves A and B are compute plus review queue depth.
  • S4 is where the estimate lives.
  • Waves C and D are fast but taste-bound, and taste does not parallelize.

The previous seventeen-week figure assumed human implementation. Roughly twelve of those weeks were implementation and five were judgment. Only the twelve collapse.