CreatorTrack Tier 1 , Parallel Component Fan-Out (Wave 1)¶
URL: https://mkdocs.justinsforge.com/memory/handoffs/creatortrack-tier1-fanout-2026-06-18/
Pre-staged: 2026-06-18, home-base session. Do not launch until the Section 0
foundation is built AND committed to forge-suite main (worktrees branch off that
commit; launching earlier means workers lack the shared primitives they depend on).
Repo: /home/justinwieb/forge-suite. Worktrees go to /home/justinwieb/forge-suite-wt/<branch>/.
Launcher: forge/scripts/forge_suite_tier1_fanout.sh (cuts worktrees + spawns one Opus per component).
Pre-launch gate (verify ALL before running the launcher)¶
- Section 0 done:
COMPONENT_BACKLOG.mdSection 0 primitives exist (floating, portal/ z-index, focus-trap, dismiss, shortcut registry, motion, Form/Field, DnD, virtualization) and the existing overlays were refit onto them. - The gallery auto-discovery refactor is in (a component registers via
studioEntryfrom its own folder; no Tier 1 worker should need to editComponentsGallery.tsx). - forge-suite
mainis COMMITTED and clean (git -C /home/justinwieb/forge-suite status). tscclean +/studio200.
Wave 1 assignments (one folder = one worker = one worktree)¶
| Branch | Component | Folder | Leans on (Section 0) |
|---|---|---|---|
| t1-datagrid | DataGrid / Table | components/DataGrid/ |
virtualization |
| t1-drawer | Drawer / Slide-over | components/Drawer/ |
portal, focus, motion, dismiss |
| t1-topbar | Topbar / App header | components/Topbar/ |
, |
| t1-layout | Stack/Grid/Flex/Divider | components/layout/ |
, |
| t1-datepicker | DatePicker + range | components/DatePicker/ |
floating, date-fns |
| t1-charts | Charts (bar/line/donut) | components/Charts/ |
Recharts |
| t1-accordion | Accordion / Collapsible | components/Accordion/ |
motion |
| t1-combobox | Combobox / Autocomplete | components/Combobox/ |
floating, dismiss |
(Wave 2 later: search field, number/stepper, segmented, multi-select, tree, list, stat card, progress, empty state, breadcrumbs, command palette, alert/banner, pagination, app-shell auth/settings/error pages. Edit the COMPONENTS array in the launcher to run it.)
The contract every worker gets (boot prompt points here + COMPONENT_AUTHORING.md)¶
- Build ONLY your assigned folder. Never touch shared files (barrel, gallery shell,
routing,
theme.css, the token manifest). Register viastudioEntryfrom your folder. var(--token)only, never hardcode. If a token is missing, flag it, do not inline a value.- Reuse the Section 0 primitives (floating/dismiss/focus/motion/Form/DnD/virtualization). Do NOT re-roll positioning, click-outside, focus-trap, etc. If a primitive is missing or insufficient, STOP and write a note, do not fork it locally.
- Verify before claiming done:
tscclean + your component renders in the/studioComponents tab. Paste real output. - Medium thinking (these are well-scoped builds on a frozen foundation).
- When done: write a one-line status to this file under your branch name and stop.
Worker status¶
- t1-topbar: DONE.
components/Topbar/(Topbar + TopbarAction + index.ts + studio.tsx). Generic data-agnostic 44px header: leading sidebar toggle, breadcrumb trail with overflow-collapse "…" dropdown, actions slot; var(--token) only (--topbar-h/surfaces/text/radii), reuses ui Icon/DropdownMenu/Tooltip, no re-rolled primitives, no shared files touched (registry self-test reverted).tsc --noEmit0 errors;/studiorenders it (HTTP 200, SSR shows "Topbar / App header" + ct-topbar markup + page content, no dev errors). Integrator:import { studioEntry as topbarEntry } from "@/components/Topbar/studio";+ addtopbarEntryto tier1Entries in registry.tsx. - t1-datagrid: DONE.
components/DataGrid/(DataGrid.tsx + index.ts + studio.tsx). Sortable/resizable/selectable/sticky + virtualized via shareduseVirtualList, var(--db-*) tokens only, no shared files touched (registry self-test reverted).tsc --noEmit0 errors;/studiorenders it (HTTP 200, no compile errors). - t1-drawer: DONE.
components/Drawer/(Drawer.tsx + index.ts + studio.tsx). Slide-over from any edge (right/left/top/bottom) over a scrim, built on shared Portal+Z (z-index Z.drawer), useFocusTrap, useDismiss (Esc/scrim), usePresence slide transition; var(--token) only, no shared files touched (registry self-test reverted).tsc --noEmit0 errors;/studiorenders it (HTTP 200, H2 "Drawer / Slide-over" + "Open drawer" trigger, no compile errors). - t1-combobox: DONE.
components/Combobox/(Combobox.tsx + index.ts + studio.tsx). Search-as-you-type single-select on Section 0 primitives: useAnchoredFloating (trigger=focus, role=listbox) for positioning + outside-click/Esc dismiss, FloatingPortal at Z.dropdown, usePresence enter/exit motion, Field for label/hint/error aria; keyboard nav (Arrow/Enter/Esc), filter, clear, empty state, optional allowCustom + descriptions; var(--token) only, no raw hex, no shared files touched (registry self-test reverted).tsc --noEmit0 errors;/studiorenders it (HTTP 200, SSR shows "Combobox / Autocomplete" + note + "Favorite fruit" label + "Search fruit..." placeholder). Integrator:import { studioEntry as comboboxEntry } from "@/components/Combobox/studio";+ addcomboboxEntryto tier1Entries in registry.tsx. - t1-layout: DONE.
components/layout/(Stack + Flex + Grid + Divider + space.ts + index.ts + studio.tsx). Token-spaced layout primitives, no Section 0 deps: gap maps to the frozen--space-Nscale (localspace.ts), Divider uses--line, all surfacesvar(--token)only (no raw hex). Flex (direction/gap/align/justify/wrap/inline), Stack (1-axis convenience), Grid (fixed cols or responsive auto-fill viaminColWidthlocal px prop), Divider (h/v + optional label). OnestudioEntrydemoing all four; no shared files touched (registry self-test reverted).tsc --noEmitclean (only known.next/types/validator.tsartifact);/studiorenders it (HTTP 200, SSR shows "Layout , Stack / Flex / Grid / Divider"). NOTE: worktree shipped withoutnode_modules; rannpm installin it (cross-root symlink breaks Turbopack). Integrator:import { studioEntry as layoutEntry } from "@/components/layout/studio";+ addlayoutEntryto tier1Entries in registry.tsx. - t1-charts: DONE.
components/Charts/(Charts.tsx + index.ts + studio.tsx). One token-styled Recharts wrapper covering bar/line/area/donut with a shared axis/tooltip/legend family; default categorical palette from--opt-*-ink/--accent2(allvar(), zero raw hex), demo data so it renders propless. No Section 0 primitive needed (Recharts owns its rendering); no shared files touched (registry self-test reverted, git diff empty). NOTE: worktree shipped withoutnode_modules; rannpm installin it.tsc --noEmitexit 0 (fully clean);/studioHTTP 200 + headless-Chrome post-JS DOM confirms it paints (1 recharts-wrapper, 14 bar-rectangles, axes, 4 legend items). Integrator:import { studioEntry as chartsEntry } from "@/components/Charts/studio";+ addchartsEntryto tier1Entries in registry.tsx. - t1-datepicker: DONE.
components/DatePicker/(DatePicker.tsx + index.ts + studio.tsx). Single-date and start/end range picker on Section 0 primitives: useAnchoredFloating (role=dialog, click) for positioning + outside-click/Esc dismiss, FloatingPortal + FloatingFocusManager for the overlay + focus trap, usePresence scale enter/exit, Field for label/hint/error aria; date-fns for all math. Features: controlled/uncontrolled, 1-or-2 month view (auto 2 for range), weekStartsOn, min/max + per-dayisDateDisabled, today dot, in-range wash with hover preview, clearable, full keyboard nav (arrows/PageUp-Down/Home/End/Enter). var(--token) only (--accent/--accent-ink/--accent-soft/--panel/--card2/--line/--elev-3/radii), no raw hex, local px metrics only (CELL=34). No shared files touched (registry self-test reverted, git diff of registry.tsx empty; onlycomponents/DatePicker/shows in status). NOTE: worktree shipped withoutnode_modules(cross-root symlink crashes Turbopack); hardlink-copied it from main repo for the build, removed after.tsc --noEmitexit 0 (fully clean);/studiorenders it , confirmed visually in Chrome at the LAN URL (HTTP 200): "DatePicker , single + range" heading + note + "Due date" label + "Select dates" trigger with calendar icon + full controls panel (mode/months/week-start/label/placeholder/clearable/disabled). FLAG for integrator: sharedFieldprimitive generates ids from a module-level counter (ct-field-${++fieldSeq}via useMemo), which is NOT SSR-stable, so any Field consumer (this + the grandfathered Input entry) logs a dev-only hydration-mismatch warning; harmless at runtime. Frozen-primitive, did not edit; suggest Field switch toReact.useId(). Integrator:import { studioEntry as datePickerEntry } from "@/components/DatePicker/studio";+ adddatePickerEntryto tier1Entries in registry.tsx. - t1-accordion: DONE.
components/Accordion/(Accordion.tsx + index.ts + studio.tsx). Multi-item collapsible:typesingle|multiple,collapsible(single), controlled/uncontrolled (value/defaultValue/onValueChange), disabled items, optional leading icon. Reuses Section 0 motion primitiveusePresencefor the open/closed state machine + exit timing; height collapse is the grid-rows 0fr↔1fr idiom (Transition's fade/scale/slide presets don't do height). WAI-ARIA accordion pattern:<button>headers with aria-expanded/aria-controls,role=regionpanels with aria-labelledby, roving ArrowUp/Down/Home/End focus across enabled headers. var(--token) only (--card/--panel/--line/--txt/--mut/--hover/radii/font/fs), no raw hex; chevron via shared ui Icon. No shared files touched (registry + next.config self-test reverted,git statusshows onlycomponents/Accordion/).tsc --noEmitexit 0 (fully clean)./studiorender NOT verified in-worktree: Turbopack roots its virtual FS at the git repo root and this worktree lives OUTSIDE the main tree (.gitis a gitdir pointer to /home/justinwieb/forge-suite), so it panics "Symlink [project]/node_modules is invalid, it points out of the filesystem root" even with real node_modules; per Justin, visual check happens at merge in the main checkout, not in the worktree. Integrator:import { studioEntry as accordionEntry } from "@/components/Accordion/studio";+ addaccordionEntryto tier1Entries in registry.tsx.
WAVE 1 COMPLETE + RETRO (2026-06-18) , read before launching Wave 2¶
All 8 components merged to main (0a1a312): 8 component merges + 1 registry-wiring commit.
All render in /studio (verified in server HTML), tsc clean, worktrees/branches cleaned up,
dev.creatortrack.ai stable on :3060 in tmux -L ct-dev. The run thrashed Console hard;
root causes + fixes for Wave 2:
- Per-worktree
npm installis the killer. Worktrees do NOT sharenode_modules, so each worker ran a full ~756 MB install. 5 installs + 5next devservers drove Console to 250 MB free / OOM. FIX: pre-seed ONE sharednode_modules, or have workers verify withtsc --noEmitONLY and never boot a dev server in a worktree. - Never run
next dev/ Turbopack inside a git worktree. Turbopack roots its virtual FS at the git repo root; a linked worktree lives outside it, so it panics "symlink out of root" even with real node_modules. Accordion burned ~12 min on this. Verify withtsc; visual/studiocheck happens at MERGE on the single main:3060server. - Dev server must be durable. It OOM-died 3x because hand-started. Now in persistent tmux; better: give it a systemd unit so it auto-restarts.
- 8 Opus workers ≈ 3.5 GB resident. On the 12 GB Console that leaves no room for a dev server. Until the Finn 64 GB upgrade lands, cap concurrency at ~3-4 workers per wave.
- Banner-fail is a false alarm (confirmed): every "REMOTE CONTROL FAILED" session was alive
and building. Patch the launcher to treat it as a warning, not a
set -eabort, + widen spacing. - Workers did not self-commit (left work as untracked files; integrator committed + merged). Tell Wave 2 workers to commit on their own branch.
Section 0 bug to fix (flagged by datepicker worker)¶
The shared Field primitive generates ids from a module-level counter (ct-field-${++fieldSeq}),
which is NOT SSR-stable, so every Field consumer logs a dev-only hydration-mismatch warning
(harmless at runtime). FIX: switch Field to React.useId().
Integrator (Justin + home-base) merge step , serialized, after workers finish¶
For each branch: review, git -C /home/justinwieb/forge-suite merge t1-<x>, resolve the
only-ever-trivial conflicts (each just adds its own files), confirm /studio shows it.
Do this one branch at a time, not all at once.