Build Log · July 17, 2026

Closing the duplication sweep — and finding Hearth's real severity

Fixed both wiring gaps and extracted the two threshold-crossed patterns (org-auth, rate limiter) from last session's sweep, then investigated Hearth's flagged rate-limiting gap and found it was a real cross-tenant IDOR affecting ~26 files, not a missing rate limiter.

  • ForgeKit OS
  • Extraction
  • Security
  • Hearth
  • Known
  • Leashline
  • Forge
  • PilotLight
duplication findings from last session, all resolved
4

duplication findings from last session, all resolved

new package modules extracted (org-auth, rate-limit), both tested
2

new package modules extracted (org-auth, rate-limit), both tested

Hearth files migrated off a hardcoded single-tenant ID
30

Hearth files migrated off a hardcoded single-tenant ID

additional zero-ownership-check IDOR bugs found and fixed beyond the simple hardcode swap
9

additional zero-ownership-check IDOR bugs found and fixed beyond the simple hardcode swap

Timeline

  1. Start

    Zeb asks to continue from last session's duplication sweep backlog

    4 items: 2 wiring gaps, 2 threshold-crossed extraction decisions

  2. +20m

    Wiring gaps fixed — Known's DB connection, Leashline's UI primitives

    Both re-verified via direct file read before touching, not trusted from last session's snapshot

  3. +50m

    Auth-guard extraction — found Known's shape was a superset, not a duplicate

    Forge's getTenantId() vs Known's requireOrgId()/requireOrgIdApi() — extracted to match the superset

  4. +1.5h

    Rate-limiter extraction — found the real consumer count differed from the backlog's claim

    Arcade copy was stale (0 matches), real count was PilotLight + Happenstance + Medina-square (3 routes)

  5. +2h

    Hearth investigation reveals the real severity

    A real multi-member access system existed (lib/access.ts) but ~26 files bypassed it; some server actions had zero ownership check at all

  6. +2.2h

    Fixed week/actions.ts by hand as the reference pattern

    moveWeekItem had no ownership check whatsoever — any signed-in user could move any household's item

  7. +2.5h

    Background agent dispatched for the remaining 24 files

    Worktree isolation

  8. +3.7h

    Agent returns — Claude initially misjudges it as untrustworthy

    Checked a stale, unrelated leftover worktree directory instead of the real repo; corrected within minutes via direct verification

  9. +4h

    Independent verification confirms the agent's work was real and correct

    Spot-checked 5+ files' diffs directly, ran tsc --noEmit and a full production build personally, found 2 additional client-side hardcodes the agent missed

  10. Close

    Registry updated with grep evidence, verify:reuse shows 0 broken claims across 53 rows

    Crucible post-build audit run before retro

What shipped

  • Known's lib/db/index.ts now imports createDb from forgekit-core/db instead of duplicating the lazy-proxy pattern

  • Leashline's Button/Card/Badge now re-export from forgekit-ui instead of carrying byte-identical local copies

  • packages/forgekit-core/src/org-auth.ts — requireOrgId(redirectTo) + requireOrgIdApi(), extracted from Forge's getTenantId() and Known's requireOrgId()/requireOrgIdApi(), built to Known's superset shape. Tested: 5 passing tests.

  • packages/forgekit-ai/ — first real module in a previously-empty planned package. createRateLimiter(windowMs?, max?) factory extracted from 3 real duplicate implementations. Tested: 5 passing tests.

  • PilotLight and Happenstance added to root package.json workspaces (were standalone Vercel projects outside the monorepo build) — required to safely consume forgekit-ai without breaking their production builds

  • Stray per-app package-lock.json files removed from PilotLight and Happenstance now that root lockfile governs them

  • products/hearth/app/(dashboard)/week/actions.ts fixed by hand as the reference pattern — moveWeekItem, markWeekItemDone, hideFromLookahead, updateWeekItem, addToTodayRoute all had zero or hardcoded-only household scoping

  • products/hearth/lib/calendar-token-manager.ts — getValidAccessToken() changed from a zero-arg function using a hardcoded constant to taking householdId as a required parameter

  • 24 additional Hearth files migrated from HOUSEHOLD_ID = 'household-1' to real Clerk-derived household scoping via lib/access.ts's getHouseholdForUser()

  • 9 additional zero-ownership-check bugs found and fixed beyond the simple constant swap, including a cross-household data-loss bug (meals/grocery/route.ts was deleting every household's grocery items for a week, not just the caller's) and a client-supplied-householdId IDOR in curriculum/import/route.ts

  • 2 more household-1 literals found and fixed after the agent's pass (GroceryList.tsx, RecipeBook.tsx — client-side optimistic-UI placeholders, not a real security gap but worth correcting)

  • forgekit-os/patterns.md and extraction-backlog.md updated with grep evidence for every status change — npm run verify:reuse shows 0 broken claims across all 53 registry rows

“ok. all good for now. where are we at with the duplication check. is that all resolved?”
— Zeb, checking whether the session's stated goal was actually complete before closing