ForgeKitFORGEKIT

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.

AlloyForgeKit OSSchemaArchitecture Correction
4
real tables (workpieces, arcs, executions, arc_events) — canonical identity model after mid-session correction
1
architecture mistake caught and corrected mid-session via Zeb's live review, before anything was committed
0
TypeScript errors, 17/17 routes compiled in the final production build
0
fabricated live indicators shipped — Forge Energy/Cold Flame/Scale-Heat-Loss are real arc_events aggregates with visible derivation and an isManualData disclosure banner

Timeline

Start
Oriented against prior Alloy sessions, ran the Crucible council (architect+engineer+qe) solo on the Option A/B/C execution-model question
Council converged on Option B (self-contained DB-backed control plane) with one hard constraint: no fake live tickers
+45m
Built first-draft schema, queries, actions, migration — separate 'workpiece' identity for anything Alloy-created
Passed tsc and generated a clean migration, but was architecturally wrong
+1h
Zeb returned mid-session, reviewed the diff, and delivered a detailed written architecture correction
Identified the split-identity mistake, specified the correct Workpiece->Arc->Execution->ArcEvent model, flagged 'persisted != real telemetry' as the sharper version of the Crucible's honesty constraint, and explicitly named 'buildable tonight' as the wrong optimization target
+1.5h
Rewrote schema.ts, queries.ts, actions.ts against the corrected model; wrote lib/db/README.md as the durable ADR
Cleared stale drizzle/ metadata, regenerated a clean migration (4 tables), tsc clean
+2h
Wired one honest vertical slice: Workpieces page (tabbed, real vs. real-ForgeKit-history), Charge form, live Command Ledger + Anvil + indicators on Forge, Bank close
Every indicator shows its real derivation string, not just a percentage; isManualData banner shown whenever no real execution exists
+2.5h
Verified: tsc --noEmit clean, next build clean (17/17 routes), brief dev-server route smoke test
Confirmed package-lock.json diff was purely additive before committing
End
Committed, pushed (44 commits including this session's), wrote the next-session Charge for the runner/execution-bridge work
Retro written

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