Docs

Guide 12

Build record

12. Build record

This plan ran. It is not a queue. Every wave it named has a package in this repository. Read it to see why the tree looks like this, not to pick a next task.

The leftover names are follow-ups, not items waiting in this schedule. create-avelon is not in the repository. Vigil, Peal, Moot, Banner, and Lantern are named and not built. The first public npm line is a human action. See docs/16-releases.md.

The schedule was 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, and the docs voice decide whether anyone loves this. That work does not parallelize.

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 was the human. Output is docs/02-decisions.md with chosen answers and runner-ups, and the umbrella name Avelon.

This blocked everything. The name blocked the scope, which blocked every package name.

S2. Contract freeze

Owner was the human plus an adversarial review loop. This was the gate.

Frozen and published in @avelonjs/core at s2-contract-freeze:

  • 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 that landed: @avelonjs/core typechecks, every contract has a doc comment, and the capability narrowing spike passes with every @ts-expect-error firing.

Nothing downstream started before this landed. A contract edited later to unblock one package still silently breaks every package built against the original. That rule did not expire.

S3. Conformance suites

Landed in @avelonjs/conformance before the drivers. One suite per contract. These were the acceptance criteria that let Wave A run without a human reading each driver.

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

S4. Integration

Landed in @avelonjs/s4. 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.

Gazette later proved the same slice inside a real application. The failure mode this milestone existed to catch was twenty green packages that do not compose.


M0 spike

Ran before S2 and informed it. Prove what can kill the design, build no features. The findings live in .avelon/checkpoints/checkpoint-1.md. D25 through D28 closed the escalations. Bun as the Vercel function runtime stayed unverified and is still opt-in. See docs/11-runtime.md.

#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 ran against a live database. No mocks.


Wave A: drivers

Landed after S3. Acceptance was conformance green.

PackageImplementsNotes
@avelonjs/supabase databasedatabaseincludes the ward-to-RLS compiler
@avelonjs/supabase identityidentity
@avelonjs/supabase socialsocial
@avelonjs/supabase tokenstokens
@avelonjs/supabase storagestorage
@avelonjs/supabase queuequeuepgmq plus the drain worker
@avelonjs/postgresdatabasetransactions, deep relations, window functions
@avelonjs/neondatabase, identity, social, tokens, storage, queueNeon Auth + S3; database wraps @avelonjs/postgres
@avelonjs/resendmail
fakesall sixteenone agent, mechanical, in @avelonjs/conformance

Wave B: core subsystems

Landed in @avelonjs/core and @avelonjs/orm, 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

Landed after S4.

PackageScope
@avelonjs/nextroute codegen, action dispatch, page wrapper, middleware bridge
hono spikethrowaway, proved the contract, never shipped. D26 revised write routes and views.
@avelonjs/cliTUI, every generator, stubs, doctor, tinker
@avelonjs/bailiffevery rule with reasons and autofixes
assaytest harness, HTTP helpers, factories, seeds

Wave D: launch

Landed in this repository.

ItemScope
docs sitethe Avelon vocabulary and command map is the landing page, not a sub-page
example appIsle Gazette, a complete application, not a todo list
docs appthe same Markdown, served as an Avelon app
docs:checkREADME linting for packages
driver authoring guidehow to write and certify a driver
npm publishlockstep pack of @avelonjs/*. First public line is still a human 0.1.0.

What did not land

  • create-avelon. D19 said the framework is a dependency. Copy examples/gazette until the scaffolder exists.
  • Vigil, Peal, Moot, Banner, Lantern. Named. Not built.
  • Bun as the Vercel function runtime. Local Bun serving passed. Live Vercel did not run.

How work was accepted

Every package used this bar. New work still uses it. See AGENTS.md.

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 required a human to exercise judgment about whether the result was correct, it was not a package task. It was a design decision and it belongs in docs/02-decisions.md.


Estimate

Historical. Do not re-estimate from this page.

Two to three weeks wall clock was the figure, and almost none of it was typing.

  • S1 and S2 were a day or two of focused human attention.
  • M0 was wall-clock bound by live service verification.
  • Waves A and B were compute plus review queue depth.
  • S4 is where the estimate lived.
  • Waves C and D were 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 collapsed.