A passive ledger of what shipped on reabal.ai. Newest at the top. Short. Honest. No marketing voice.
This doc is the source for /changelog. Append a new entry when a meaningful change ships. Old versioned rebuild history was removed from the working tree during the Studio OS reset; use git history for archaeology.
2026-05-13 — Homepage scroll scaffold cleanup
Missing assets stopped showing their scaffolding.
Production placeholders retired. Deleted the chapter placeholder component and CSS. Asset-gap chapters now keep invisible render-layer contracts and documented asset slots, but no labeled route scaffolds render on the public homepage.
Portal prompts gated. Route affordances now stay inert for asset-gap chapters until the focal object is promoted. The DOM still carries canonical route links for contract coverage, but visitors cannot click prompts that do not have a real threshold object.
Scroll continuity added. Added a shared continuity layer for horizon veiling, lower-depth shade, and chapter-boundary shading using existing light and scroll signals. It improves the foundation without inventing fake route scenery.
2026-05-13 — Overlook lookdev and source-scene foundation
The lookout got a source table.
Lookdev gate. Added pnpm validate:overlook-lookdev for the ignored Poly Haven source pack: two CC0 sunset HDRIs and six CC0 PBR material sets, each with the expected source URLs, local asset-cache/ paths, and texture maps.
Overlook source contract. Added docs/asset-briefs/overlook-scene-foundation.md and wired the active homepage scene data to the expected HDRIs, textures, Fab roles, and canvas overlay passes.
Fab list tightened. The Overlook Fab intake now requires seven object families: telescope, bench, signpost, map kiosk, trash bin, safety fence, and small-junk scatter. The fence was missing; without it, the cliff edge has no believable depth wedge.
Ambient overlay foundation. The shared homepage canvas now gives the Overlook a source-aligned overlay family: dust motes, low fireflies, a rare meteor scratch, and basin heat-haze lines. These are ambient proof layers, not a replacement for Blender render passes.
2026-05-13 — Sky proof gates: forced events and Fab intake
The rare weather can now be inspected on purpose.
Session-only event preview. The skyline has a QA override at reabal_skyline_event_preview_v1, with a matching reabal-skyline-event-preview event. Storm, eclipse, aurora, comet, and meteor-shower modes can be forced for screenshots without making a public control. The event overlays now expose stable test hooks, and comet, eclipse, and meteor-shower visibility follows the same shift-hour override as the shader.
Desktop sky-spine matrix. Added a production-homepage Playwright matrix for the first viewport across all eight time-of-day modes plus all five forced rare events. This is separate from the older /dev/skyline baselines; it guards the active HomeExperience path.
Fab intake gate. Added an Overlook Fab intake template plus pnpm validate:overlook-fab-pack. Fab props now have a source-side manifest gate before Blender staging: license file, source URL file, preview, model, notes, no baked text, no complete scene, no public paths, no versioned final slugs.
2026-05-13 — Sky spine proof: event air and eight-mode visual gate
The sky stopped treating rare weather as an overlay sticker.
Atmospheric event uniforms are active. SkylineShell now passes the picked atmospheric event into SkyCanvas; the single WebGL shader consumes uStormFlash, uEclipseProgress, and uAuroraPhase. Storms darken and flash inside the air mass, eclipses chill daylight around the sun, and auroras fold into the upper sky. DOM overlays still provide readable event objects, but the sky itself now changes.
Eight-mode desktop visual proof. The homepage visual smoke suite now pins the skyline through deep-night, predawn, morning, midday, afternoon, golden-hour, evening, and night using the existing shift-hour override. Each mode verifies the WebGL canvas is mounted and nonblank.
Rot cleanup. Deleted untracked retired signal/handoff docs, old skipped tests aimed at the removed public inbox lane, and unledgered public staging asset folders. Tracked homepage-asset-gaps.md remains the active asset-gap source because it matches the Fab/Blender 2.5d pipeline.
Audit chain: skyline-foundation / home-experience / source-asset hygiene / typecheck / lint / assets / canonical / desktop Playwright visual suite / production build all green.
2026-05-10 — Skyline weather coupling: real Canberra sky in the scene
The visitor's actual sky shows up on screen.
Live weather feed. lib/skyline/weather.ts + lib/skyline/use-weather.ts pull Open-Meteo current conditions for Canberra Parliament House (-35.28, 149.13) on a 10-minute cache (matches BoM update cadence). No per-visitor lat/lon collected — fixed coords, no API key, no analytics; localStorage cache survives reloads. WMO weather code → categorical condition (clear / partly-cloudy / cloudy / overcast / rain / thunderstorm / snow / fog).
Cumulus density buckets bound to weather. clear → 9 clouds (3 per band × 3 bands), partly-cloudy → 15, overcast → 24, rain / thunderstorm → 36 (new heavy bucket — 12 per band, properly saturated storm front). Tone hour-keyed on top of bucket; visibility multiplier pushes silhouettes darker on overcast / rain / fog.
Wind-driven cloud drift. Open-Meteo wind_direction_10m flips drift sign (clouds blow eastward when wind is from the west, vice versa). wind_speed_10m (km/h) scales drift duration via --cloud-wind-factor: calm = ~320s per band, gale ≈ ~80s. The visitor's actual sky's drift pattern shows up.
Sun rays weather-dimmed. New uSunObscured shader uniform distinct from uCloudCover — thunderstorm 0.95, rain 0.85, fog 0.55, overcast 0.35, others 0. Multiplied with cloud-cover dim so storm conditions push rays to ~5% (sun trying to break through), overcast keeps a soft glow, clear day rays stay sharp. Always-on baseline kept (rays never zero — a hint of light always reaches through atmosphere).
Rain overlay. `atmospheric/rain-overlay.tsx` — canvas-2D streaks. Density scales with precipitation (mm/hr): light rain 120 streaks, downpour 360. Wind direction tilts streak angle. Self-gates on condition === "rain" || "thunderstorm". Reduced motion → unmounted.
Fog overlay. `atmospheric/fog-overlay.tsx` — two cool-gray gradient bands drifting laterally over the lower 60vh. Pure CSS, no canvas, no rAF. Self-gates on condition === "fog". Reduced motion freezes the drift but keeps the gradient.
Audit chain: typecheck / audit:design / audit:skyline-drift / audit:asset-treatment / audit:assets / audit:canonical all green.
2026-05-10 — Skyline immersion pass: dramatic scroll dolly, atmospheric haze, lit windows, curated tree, firefly cluster
The camera pulls forward; the night fills in.
Dramatic scroll-depth camera dolly — bumped multipliers ~3× across the parallax stack so the scene reads as cinematic, not nudged.
- Mountains: near -22vw + 1.12× scale (was -8vw + 1.0×), mid -14vw + 1.08× (was -5vw), far -8vw + 1.04× (was -3vw), distant -4vw + 1.02× (was -1.4vw). Both procedural + curated bands track in lockstep.
- Cityscape: mid band -10vw + 1.06× (was -4vw + 1.0×), far -6vw + 1.04× (was -2.4vw), distant -3vw + 1.02× (was -1.2vw).
- Cliff outcrop: 1 → 1.14× scale (was 1.06×) + -5vw push (was -2vw).
- Billboard: 1 → 1.10× (was 1.04×) + +4vw push.
- Lone tree: +12vw drift + -3vh lift + 0.78× scale (the across-the-gap tree pulls visibly into the distance with scroll).
Atmospheric haze on far/distant bands — filter: blur(0 → 1.4–2.4 px) + saturate(1 → 0.68) keyed to --scroll-depth. Far + distant mountain ranges + far + distant cityscape bands all participate. Reads as the camera dollying forward through deepening haze, not a flat 2D pan.
Procedural mountain fade-on-scroll — .range opacity scales 1 → 0.58 with scroll so curated hand-drawn peaks dominate as the camera pulls forward. Procedural ridgeline supplies horizon texture + load-state fallback; curated supplies the hero silhouette character.
Curated tree silhouette over the lone tree — `foreground-vantage.tsx` overlays a deterministic curated tree from CURATED_TREES (picked via pickCuratedAsset(pool, 'foreground-vantage-tree')) on top of the procedural <LoneTree> fallback. Procedural paints during the brief curated-fetch window; curated overlays once resolved. Same silhouette family, hand-drawn character.
Lit windows ambient layer — new `lit-windows.tsx` renders 32 deterministic warm-yellow pinpricks at 12–28vh from bottom across 0–100vw. Each twinkles on a 4–11s independent period with a per-window phase offset and per-window warmth (cool LEDs → incandescent amber via OKLCH). Self-gates on hour: full intensity at deep-night + night, fades up through evening, off during the day. Reduced motion freezes the twinkle but keeps the lit mask visible. Mounts inside <CityscapeLayer> between the curated city silhouette behind and the procedural downtown in front so the windows read as embedded in the silhouette, not floating over it.
Firefly cluster near the billboard hill — `firefly-band.tsx` distribution biased 70% toward the left side (x ∈ [4, 28]vw, y ∈ [10, 24]vh — exactly where the billboard plants on the BL cliff) with 30% scattered across the remaining viewport. Reads as "fireflies on the hill near the billboard, plus a few drifting across the meadow at the edges". Spawn rule unchanged — still summer evening / night / deep-night, high-quality tier only.
uSeason warning fix superseded — uSeason now earns its place. The runtime binds it again and the shader consumes it through seasonal sky, haze, and cloud tint helpers, so the documented uniform contract matches the shipped WebGL program instead of leaving a declared-but-unused uniform.
Audit chain: typecheck / audit:design / audit:skyline-drift / audit:motion / audit:assets / audit:asset-treatment / audit:canonical / audit:audit-discoverability / audit:hydration → all green. Spawn-rules 51 + skyline-foundation 137 + light-discipline 20 = 208 tests passing.
2026-05-10 — Skyline composition pass: GTA-Vinewood layout, cloud lighting, curated silhouettes, canvas stars
The horizon learned to be lit. The billboard moved where it always belonged.
Round 1 + 2 of rey's curation drop graduated 211 illustrations through scripts/trace-png-potrace.mjs (alpha-mask + sharp + potrace fallback when vtracer isn't available), scripts/split-svg-pack.mjs (bbox-proximity union-find clustering — viewBox-cropped per cluster), scripts/treat-svg.mjs (the four-layer pipeline per docs/asset-pipeline.md: oklch / filter / overlay / asymmetry-rotation), and scripts/.svgo-aggressive.config.mjs (post-treatment compression to the 50 KB per-file budget). Surface map: skyline (horizon, foreground, clouds, cityscape, ambient-life), arcade (cabinets, controllers, neon-signs), lab (glassware, signage, instruments), cottage (misc).
Family lockdown. /arcade/cabinets locked to isometric only; the 16 face-on slot-machine cabinets that initially graduated were dropped post-curation per docs/asset-pipeline.md "one style family per surface" rule (sources sit in gitignored asset-cache/inbox/illustrations-rejected/). Six corporate-observation lab packs rejected at curation per the lab register being "skunkworks, not corporate observation theater." Total kept: 124 round-2 graduations across 7 surfaces.
Wired into the homepage: mountain-backdrop adds curated <CuratedMountainRange> per depth band beside the procedural <MountainRange> (5 hero peaks: distant-left, far-center, mid-right Hollywood-sign bearer, near-left + near-right). Cityscape adds <CuratedCityscapeBand> repeated at three atmospheric depths behind the procedural downtown. Live in `mountain-backdrop.tsx` + `cityscape-layer.tsx`.
Image-2 GTA-Vinewood layout. Billboard mirrored from right to left (billboard.module.css left-anchored). Cliff outcrop + wooden fence mirrored to BL. Lone tree stays right (the "across the gap" tree). Wooden fence extended to 10 posts with depth taper — post height drops 60% across the line, thickness drops 32%, opacity drops 28% — reads as a parallax-foreshortened leading line out toward the city sprawl. Hollywood sign repositioned from left: 12vw to right: 18vw so it rides the right-anchored curated mid-mountain silhouette.
Cloud lighting story in the shader. `sky.frag.ts` cloud band extended with three-tone vertical lighting: warm-rim where the cloud cap faces the sun (top-edge probe), neutral body fill on dense regions, cool desaturated-purple underbelly where the lower edge sits in shadow. Warmth gaussian peaks at hours 6.5 + 18.5 (sunrise / sunset) — midday clouds stay neutral cream, deep-night clouds stay flat dim. Adds the "painted clouds" feel of the GTA reference image 3 without introducing a second shader pass; samples the same fbm field at vertical offsets for the lighting probe.
Billboard rebuild per rey's plank-and-post structure. `weathered-billboard-frame.tsx` — 4 planks with per-plank rotation in [-3°, +3°] from asymmetryRotation(seed), per-plank width variation (510–516 px), per-plank xOffset jitter (-2..+1), unique <clipPath> per plank with chipped/dented bottom edge, per-plank <g transform="scale(...) skewX(...)"> so the shared filter-grain-coarse samples a different region of its noise field per plank (distinct grain without inline filter defs). Inter-plank gap shadow as hairline at the bottom of each plank. Two crossbeams (top + bottom) where there was one. Knot-hole imperfection per plank.
Canvas `<StarField>` particle. `star-field.tsx` — 180 procedural stars in the upper 65% of the viewport with twinkle phase + period + warmth + base radius per star. Brighter stars (radius >1.4) get a subtle 4-point glint cross. OKLCH warm-cool color continuum across the field. Wired into the spawn-rules system as a new starField habitat — gates on quality tier + time-of-day (deep-night = 1.0, night = 0.85, predawn = 0.55, evening = 0.45, golden-hour and day = 0). Reduced-motion freezes at first paint. Additive to the shader's procedural starfield, so the two layers complement rather than duplicate.
Cleanup. Deleted components/rehaul-flight-ribbon.tsx (Wave R artifact, no imports anywhere) and the empty app/dev/home-signal/ directory (the SUPERSEDED stub lives in docs/home-signal-system.md per the salvage ledger, but the empty Next route directory was dead). Asset audit allowlist updated to allow public/illustrations/ as a graduation directory.
Audit chain. typecheck / audit:design / audit:skyline-drift / audit:motion / audit:assets / audit:canonical / spawn-rules tests (51 passed) all green.
2026-05-10 — Skyline light-pass discipline
The whole scene reads under one global light now.
Lane: light-and-atmosphere v2 — established the platform's first global per-hour light discipline as a five-channel CSS-variable contract on :root, plus two signature overlays mounted in BAND-HAZE.
Light discipline. lib/skyline/light-discipline.ts exports lightDisciplineForHour(hour) returning OKLCH strings for --light-ambient / --light-rim / --light-shadow plus scalars for --light-fog / --light-key. Smoothstep boundaries across 13 anchor hours including the golden-hour 18:24 peak and blue-hour 5:45 + 19:25 beats; shortest-arc hue interpolation so hue crossings (e.g., 350° → 10°) don't sweep the long way. lib/skyline/use-light-discipline.ts publishes the variables on :root every 90s and honors the dial shift-hour override.
Golden-hour overlay. src/features/home/skyline/light-pass/golden-hour-overlay.tsx — single full-screen linear-gradient sweep with a sun-direction-aware rake angle (100° → 112° → 100° across 17:00..19:30), peaks at 18:24 (opacity 0.92), mix-blend-mode: soft-light. Two-layer composition using --light-rim for the orange ember and --light-ambient for the lower wash.
Blue-hour overlay. src/features/home/skyline/light-pass/blue-hour-overlay.tsx — compressed cool wash anchored to the bottom 42% of the viewport, mix-blend-mode: hue so the upper sky stays as the shader paints it and only the hue shifts cool. Same component handles both beats (predawn 5:45 + dusk 19:25); data-blue-hour distinguishes them for future beat-specific tuning.
Shader retunes. sky.frag.ts predawn / dusk horizon stops nudged toward blue for clean hand-off into the overlays; sun bloom pushed to a hotter raking-orange matching the rim signature; deep-night moon picks up a silver-rim halo (silverFactor-gated, h<5 ∪ h≥22) with a 4% disc-edge softening so the rim has something to bloom against; midday gains the doctrinal cool-white haze; sunrise/sunset glow emphasis lifted to hold hero strength under the overlay sweep; new dawn cool-blue under-line at the lowest 6vh of the horizon glow band, lives 4.6..7.0.
Act vignette tinting. acts/act-vignette.module.css consumes the discipline additively — readout color absorbs ~18% of --light-shadow (cools at golden, deepens at night), artifact wrap accepts a brightness trim from --light-fog so it embeds in the haze, and a static drop-shadow(0 0 1px var(--light-rim) at 30%) rim hairline picks up the global rake.
Tests. tests/unit/light-discipline.test.ts — 20 tests pinning anchor-hour values, smoothness invariant across the day, wrap-at-24 continuity, golden-hour + blue-hour intensity envelopes, monotone non-decreasing 5..12 + non-increasing 12..22 key intensity. tests/unit/skyline-foundation.test.ts adds 13 pins for the new shader features and shell mount.
Docs. docs/the-skyline-system.md adds a "light-pass discipline" section; docs/the-skyline-tech-stack.md registers the new files in the canonical naming convention; docs/storage-keys.md updates the reabal-dial-v1.shift-hour consumer list; CLAUDE.md Composition section points agents at the canonical doc; README.md and docs/current.md add the light-pass to the homepage surface description.
2026-05-10 — Skyline handcrafted SVG detail
The horizon got its hand-drawn body.
Lane: handcrafted-svg-detail — added a procedural SVG library at src/features/home/skyline/svg-library/ composing into the existing BAND-zone markers without touching other lanes' zones.
Clouds. Three parallax cumulus bands at hi/mid/lo depths via cumulus-shapes.tsx (10 hand-crafted silhouettes with separate body/rim/shadow paths), cumulus-band.tsx (5 clouds per band, per-hour rim-light from rimLightForHour()), cloud-layer.tsx (composes the three at distinct atmospheric perspective levels, polls lib/atmosphere/atmosphere.ts on 90s cadence). (min-width: 1024px) gates dense extras on desktop.
Mountains. mountain-range.tsx generates an asymmetric ridgeline via seeded RNG — sharp peaks for ridges, quadratic saddles between, scree-streak slope marks, notched-summit imperfection. mountain-backdrop.tsx composes four ranges at distant / far / mid / near depths with atmospheric perspective (0.32 → 0.95 saturation). Moonlit ridgeline accent uses stoneFace instead of silhouetteDeep so the silhouette reads against the shader sky at deep-night.
Cityscape. downtown-silhouette.tsx (56 procedural buildings dense in the core, hero radio-tower with pulsing antenna tip, window flicker only at hour <7 || >=18), suburb-sprawl.tsx (220 scattered houses with optional pitched roofs), winding-roads.tsx (3 quadratic-bezier paths weaving toward a central vanishing point with sampled headlight pricks at night). Seeds canonicalized in lib/skyline/cityscape-seed.ts.
Foreground. cliff-outcrop.tsx (hero rocky silhouette at bottom-right with stratification + chip-corner imperfection), wooden-fence.tsx (8 weathered posts with broken-rail imperfection between posts 3 and 4), lone-tree.tsx (importable primitive, 3 variants — windswept / spruce / deciduous, configurable scale + lean), foreground-vantage.tsx composes the three.
Billboard upscale. weathered-billboard-frame.tsx extracts the inline 320×240 SVG into a hero-scale 640×480 primitive with diagonal back-bracing struts (X-pattern behind the planks) and three discrete per-bulb halos rather than one merged glow. billboard.tsx refactored to consume it; the useBillboardToday hook contract stays intact.
Hollywood-sign re-anchor. Moved from the now-deleted BAND-HORIZON-SIGN zone into BAND-MOUNTAINS, positioned on the mid-range silhouette at smaller scale (9.5rem desktop, was 14rem). Parallax-tracks the cursor field at the same rate as the mid mountain range.
New shared utilities. src/features/home/skyline/svg-library/treatment.ts exports SKYLINE_FILTERS (filter id namespace), SKYLINE_TONE (OKLCH palette tokens), rimLightForHour(), shadowToneForHour(), asymmetryRotation() (deterministic ±3°), pickImperfection(), makeSeededRng() (xorshift32). lib/skyline/use-desktop-density.ts exports a hook for the (min-width: 1024px) matchMedia pattern.
New audit gate. pnpm audit:bandzones (script in scripts/bandzones-audit.mjs) verifies all 14 BAND-zone markers exist in skyline-shell.tsx. Wired into prebuild.
Tests. tests/unit/handcrafted-svg-detail.test.ts adds 63 file-shape contracts covering the four-layer treatment compliance: OKLCH-only enforcement, global filter id usage, asymmetry rotation, imperfection presence, reduced-motion bails, atmospheric perspective tiers.
2026-05-10 — Skyline ambient life rebuild
Three solo birds got tired of carrying the whole sky.
Eleven-habitat particle system replaces the legacy <AmbientLife /> (three solo birds + three solo bats + two mist bands) with a habitat-driven layer at BAND-AMBIENT-LIFE. Pure spawn rules in `lib/skyline/spawn-rules.ts` (48 unit tests) map (timeOfDay, season, quality, reduced-motion, activeAct) to a per-habitat enable matrix; the composition root at `src/features/home/skyline/particles/ambient-life-layer.tsx` mounts only what fires.
Habitats — bird-flock (3 V-formations, 5+7+9 birds, day modes), bat-swarm (14 erratic bats, evening), firefly-band (28 warm-amber points, summer evening/night), mist (predawn, any season), dust-motes (14 around foundation lamps), moths-around-light (6 per active scroll-act lamp), falling-leaves (6 autumn leaves with fall+sway+twirl), pollen-haze (36 chartreuse points, spring predawn/morning), owl-swoop (one-per-session deep-night silhouette pass), distant-train-smoke (40% per-visit far-horizon plume), cursor-breath (12px idle ring at cursor, Henry-Heffernan-tier diegetic).
Discipline — pure CSS-keyframe animations only (no rAF unless gated to high tier), OKLCH colors only, pointer-events: none on every layer root, reduced-motion still composition for every habitat that has one. Quality-tier gating: low → only cursorBreath; medium drops fireflyBand + pollenHaze + owlSwoop + distantTrainSmoke; high enables everything its time/season window allows.
New storage — reabal-owl-swoop-v1 and reabal-train-smoke-v1 (sessionStorage) registered in `docs/storage-keys.md`.
Legacy retired — src/features/home/skyline/ambient-life.tsx and its module CSS deleted. Single occupant of BAND-AMBIENT-LIFE is now <AmbientLifeLayer />.
2026-05-10 — Skyline promoted to /
The doctrine becomes the door.
Phase 4 promotion shipped. app/page.tsx now mounts <SkylineShell /> directly. The homepage is the skyline: WebGL2 fragment shader earthward sky across eight lib/atmosphere/atmosphere.ts modes, six rooms as horizon landmarks, scroll-pinned per-act vignettes (worlds glasshouse, arcade marquee, lab structure, archive outbuilding, cottage), Phase 7 cinematic moments (storm, eclipse, aurora, comet, meteor-shower) when the picker fires, billboard with daily AI-rotated poster + previous-poster continuity flash, hilltop sign, and visit-pattern-aware caption.
Legacy migration. <HomeScene /> and the legacy home-shell scene tree it composed are no longer imported anywhere shippable. Salvage-ledger row carries a delete date one deploy cycle out (target ≥ 2026-05-12) with the four pre-deletion checks documented inline.
Phases shipped end-to-end this run. Phase 1 (sky foundation), Phase 2 (alive billboard + hilltop sign), Phase 3 (scroll foundation, letterbox cuts), Phase 4 (act vignettes), Phase 6 (interaction polish), Phase 7 (five cinematic moments), Phase 8 (a11y substrate + canvas-2d fallback + scene-description aria-label + forced-colors + prefers-contrast), Phase 9 (memory primitives + caption variants + signature seed + previous-poster flash). Audio bed integration (Phase 5) lands as substrate ready for scene wiring.
2026-05-10 — Skyline takes the homepage
Signal lost the argument. The sky earned the room.
Homepage doctrine — docs/the-skyline-system.md lands as canonical. The homepage is now an earthward sky dynamic by visitor's local hour (eight lib/atmosphere/atmosphere.ts modes), with rey's six rooms visible as architectural landmarks scattered across the horizon and starfield. Kinetic-typography rotating headlines (name-reveal.tsx restored, lib/hero-headlines.ts as the canonical line list) anchor act 1. Scroll-pinned cinema cuts via existing reabal.linger/reabal.cut easings drive the act sequence.
Signal direction superseded — docs/home-signal-system.md retired with a SUPERSEDED header pointing to the skyline. The signal-machine direction failed because it positioned the visitor as someone receiving a transmission from outside an interior the doctrine spends fifteen documents calling rey's. The desk-as-homepage-hero direction (briefly explored, never shipped) also retired — desks don't change. The sky does.
Cottage doctrine — docs/the-cottage.md lands as canonical for /about. The desk metaphor moves there: fifteen interactive objects in three depth bands (lamp, journal, book with wax seal, drawer, terrarium, cork board, mug, headphones, clock, typewriter, photo frame, poster, chair, window). Window pulls live atmosphere from the homepage skyline. Existing page-wide eggs anchor onto cottage objects; retired desk eggs (Dune mug, Bat-Signal lamp, OBLIVIATE post-it, etc.) re-home from docs/easter-eggs.md.
Asset pipeline doctrine — docs/asset-pipeline.md lands as canonical. GetIllustrations Lifetime ($599 one-time) is the single source for site illustrations across all five tier registers and the cottage. The four-layer treatment is mandatory: oklch override + svg filter pass + canvas animation overlay + asymmetry rotation with imperfection. Two new audits (audit:asset-treatment, audit:asset-cohesion) join the prebuild chain.
Lab register correction — /lab shifts from "behavioral observation theater × Severance" to "top-secret skunkworks, off the books, lived-in." Materials stay (cold steel, wired glass, CCTV, caution stripes); the condition changes from pristine to used. References: X-Files Mulder's basement, Annihilation Area X, Primer garage.
Doctrine sweep — CLAUDE.md, AGENTS.md, docs/current.md, docs/studio-os.md, docs/themes.md, DESIGN.md, PRODUCT.md, docs/audits.md, docs/asset-ledger.md, docs/salvage-ledger.md, docs/easter-eggs.md, docs/storage-keys.md updated to reference the new doctrine and retire the old.
Headline #11 exception — PRODUCT.md adds a narrow exception for lib/hero-headlines.ts line 11 (this is where my brain leaks. mind your step.). The "my brain" trigger remains banned everywhere else.
New storage — reabal_cottage_v1 (cottage interior state), reabal-dial-v1.shift-hour (sessionStorage visitor override of skyline time-of-day), GETILLUSTRATIONS_API_KEY (env var, never committed).
2026-05-09 — Archive gets the keys
The essays stop pretending the old route name was the place.
Archive route — Promoted /archive as the canonical public home for interactive cinematic essays. /essays now exists only as a compatibility redirect.
Registry language — Retiered essay content to archive while preserving artifactKind: "essay" so the place and the format stop fighting.
2026-05-06 — Foundation routes get a spine
Public shell work moved ahead of artifact work. The route foundation now has a machine-readable contract.
Foundation contract — Added lib/foundation-routes.ts and audit:foundation so the public shell routes stay declared in one place. Superseded on 2026-05-09 when /archive replaced the old essays path.
Sitemap — app/sitemap.ts now derives static public routes from the foundation contract, including /map.
Map — Rebuilt /map from a generic link grid into a Studio OS orientation wall backed by the foundation contract and the public registry.
Studio logs — Rebuilt /now as a live studio-status surface and /changelog as a cinematic ledger reader while keeping docs/changelog.md as the source.
Route rail — Added a subtle desktop foundation route rail backed by lib/foundation-routes.ts, so public shell navigation is contract-derived instead of hand-written per page.
Catalog landings — Promoted /worlds into the Glass Garden and the long-form writing surface into a dedicated landing guarded by the foundation route contract. The old projection-booth metaphor was retired.
Homepage mobile — Fixed catalog horizontal overflow and removed the desktop-only dial from touch/mobile viewports so the home catalog no longer has a floating control sitting over the rows.
Homepage threshold — Replaced the rejected machined-console first viewport with a procedural space threshold: deep parallax atmosphere, vector route paths, four room beacons, and no gold dashboard machinery.
Docs — Updated Studio OS, roadmap, and audit docs so /now is no longer contradicted by stale roadmap language.
2026-05-06 — Studio OS becomes canonical
The current direction is no longer a numbered rebuild. `docs/studio-os.md` is the route/product authority; old versioned implementation plans were deleted from the working tree.
Governance — Added the Studio OS source-of-truth doc, salvage ledger, and storage/event registry. Cleanup now starts by classifying systems as keep, merge, incubate, archive, or delete-only-after-proof.
Rot purge — Deleted obsolete docs/plans, historical render/primitives docs, tracked coverage output, and old visual baseline specs named after retired directions.
Routing — /dev/* is explicitly admin-only in the request matcher. Registry access remains enforced by canViewExperiment().
Registry — Completionist route tracking now derives public live slugs from lib/experiments.ts, so trophies follow the registry instead of a stale hardcoded list.