Build Log
Alloy — Real Data Model and First Writable Vertical Slice
July 19, 2026
Gave Alloy its first database and a real write path (Workpiece -> Arc -> Charge -> Command Ledger -> Strike -> Bank), corrected a real architecture mistake mid-session after Zeb's review, and stopped short of building a fake 'live session' — no runner/execution bridge exists yet, and that's stated honestly in the product, not hidden.
Timeline
What shipped
products/alloy/lib/db/schema.ts — corrected canonical model: workpieces, arcs (with Charge fields inline), executions, arc_events (append-only)
products/alloy/lib/db/index.ts — createDb(schema) from forgekit-core, CANONICAL reuse
products/alloy/lib/db/queries.ts — owner-scoped reads + computeIndicators() (real arc_events aggregates, no fake tickers, isManualData disclosure)
products/alloy/lib/db/ids.ts — newId()/newWorkpieceId() helpers
products/alloy/lib/db/README.md — the ADR: identity model, why the first draft was wrong, explicit statement that no runner/execution bridge exists yet
products/alloy/lib/actions.ts — Server Actions: createWorkpiece, startArc (single-active-arc rule), saveCharge/finalizeCharge, postArcEvent, proposeStrike/resolveStrike, bankArc — all Clerk-auth-gated and owner-scoped
products/alloy/drizzle.config.ts + drizzle/migrations/0000_tranquil_nova.sql — generated, reviewed, NOT pushed (no DATABASE_URL provisioned)
products/alloy/components/{RealWorkpiecesPanel,WorkpiecesTabs,ChargeForm,LiveArcPanel}.tsx — real, writable UI
products/alloy/app/workpieces/page.tsx — tabbed: real ForgeKit Sessions (unchanged, read-only) + real Workpieces (new, writable)
products/alloy/app/{charge,forge,bank}/page.tsx — branch on ?arc= to show real writable state; fall back to the existing honest read-only ArcPhaseShell otherwise
package.json — added products/alloy to root npm workspaces (was missing entirely, blocking forgekit-core resolution)
Removed products/alloy/package-lock.json — redundant now that Alloy is a root workspace member