Build Log · August 2, 2026

Build Log Ingest API — All 5 Charge Phases

Implemented the full v9-approved Build Log Ingest API design end to end: a shared contract package, forgekit-website's ingest endpoints, Alloy's delivery outbox, a real backfill of all 210 historical sessions, and the database-backed read-path cutover — so a Bank-closed Arc appears on forgekits.build/build-log with zero redeploy.

  • ForgeKit OS
  • Alloy
  • forgekit-website
  • Platform
  • Database
Charge phases completed (Contract Inventory, Shared Package, Website API, Alloy Delivery, Backfill+Cutover)
5/5

Charge phases completed (Contract Inventory, Shared Package, Website API, Alloy Delivery, Backfill+Cutover)

real-DB tests written this session, all passing, zero mocks
38

real-DB tests written this session, all passing, zero mocks

historical sessions backfilled successfully through the fail-closed projector
210/210

historical sessions backfilled successfully through the fail-closed projector

legacy static URLs verified still resolving after cutover
171

legacy static URLs verified still resolving after cutover

content regressions against the 84/78 Council-Review/Crucible-Wrap sessions named in design §2.5
0

content regressions against the 84/78 Council-Review/Crucible-Wrap sessions named in design §2.5

Timeline

  1. Start

    Charge written against the v9-approved design

    docs/platform/build-log-ingest-api-charge.md — 5 phases, each with acceptance criteria/tests/rollback/evidence

  2. Phase 0

    Real field-bound scan across all 210 real session JSONs

    forgekit-os/scripts/build-log-phase0-scan.mjs — replaced every design-doc placeholder number with an observed-data-backed limit

  3. Phase 1

    packages/forgekit-retro-contract built and tested

    Fail-closed projector, canonical content hash, shared Zod schemas — 12 tests, including a test that plants disqualifying markers in every excluded field and asserts none survive

  4. Phase 2

    Dedicated Neon project provisioned; ingest API built

    5 endpoints (publish/withdraw/restore/status/status-batch), hashed API-key auth, rate limiting — 15 real-DB tests, live-curled end to end, caught a real Turbopack .js-extension bundling bug tsc/vitest both missed

  5. Phase 3

    Alloy's outbox pipeline wired into bankArc

    12-step crash-safe sequence, publisherRef credential resolution at send time — genuine E2E publish proven against the live ingest API

  6. Phase 4

    All 210 sessions backfilled; exception manifest built

    First manifest run found 64 false UNEXPECTED entries, all traced to bugs in the comparison script itself (em-dash splitting, HTML-entity decoding) and fixed — final result: 0 real defects, 664 approved differences

  7. Phase 5

    Read-path cutover: database-backed index + [slug] route

    build-session.mjs no longer writes public static HTML; live-verified a DB insert appears on the running site with zero restart

  8. +

    Added the missing Phase 5 regression test on Zeb's explicit request

    read.test.ts — proves the Lifecycle Consistency Gate check (withdrawn sessions never surface) and legacy-file preservation as committed test coverage, not just a one-time manual check

  9. Close

    Full suite re-verified green, committed as one Charge-scoped commit

    9355d07 — 61 files, 5518 insertions

What shipped

  • packages/forgekit-retro-contract — public-retro.schema.ts, ingest-request/response schemas, project-public-retro.ts (fail-closed projector), content-hash.ts (canonical semantic hash), 12 tests

  • A dedicated Neon Postgres project for forgekit-website (id shy-thunder-87278705), separate from Alloy's own database per design §14

  • forgekit-website's ingest API: 6 DB tables (publishers, publisher_api_keys, retro_sessions, retro_session_revisions, retro_ingest_receipts, retro_ingest_security_events), 5 route handlers, hashed API-key auth with a non-reversible credentialFingerprint, rate limiting via forgekit-ai's createRateLimiter

  • Alloy's retro-publication-outbox.ts — the exact 12-step sequence from design §6, wired into bankArc as an additive step after the existing local retro pipeline

  • forgekit-os/scripts/build-log-phase0-scan.mjs, backfill-retro-sessions.mjs, backfill-exception-manifest.mjs, verify-no-content-regression.mjs — real, re-runnable migration tooling, not one-off scripts

  • The database-backed /build-log index (app/build-log/page.tsx, rewritten) and new /build-log/[slug] detail route

  • Retired build-session.mjs's updateIndex() source-text-splice mechanism and its public static HTML write, keeping only the internal full-chapter HTML generation

  • forgekit-website/lib/retro-ingest/read.test.ts — the Phase 5 regression test Zeb explicitly asked for after the manual verification pass, proving withdrawn-session exclusion and legacy-file preservation as committed coverage

  • Fixed a real forgekit-website/.gitignore gap found during commit staging — .env* was blanket-ignoring .env.example too, unlike every other app's .gitignore (which has an explicit !.env.example exception)