Fensalir/state/evidence.jsonl
2026-05-23 18:54:26 +01:00

214 lines
172 KiB
JSON

{"timestamp":"2026-05-09T04:42:00+01:00","topic":"debug-ui-control-grammar","lesson":"Aquarium debug UI uses a code-first Direct2D/DirectWrite overlay with explicit bound controls. Rect math must distinguish edges from width/height, controls need base/hover/active feedback, tooltips live in declarations, and long mode selectors should be named option rows instead of numeric sliders.","files":["src/Aquarium.Engine/Render/Ui/DebugUi.cs","src/Aquarium.Engine/Render/D3D12Renderer.cs","state/memory.json"]}
{"timestamp":"2026-05-09T05:20:00+01:00","topic":"graphics-settings-cultcache","lesson":"Renderer presentation knobs belong in a typed CultCache graphics settings document, not process folklore. Current durable knobs are render debug mode, exposure, bloom intensity, and bloom veil.","files":["src/Aquarium.Engine.Contracts/GraphicsSettings.cs","src/Aquarium.Epiphany/State/AquariumGraphicsSettingsState.cs","state/memory.json"]}
{"timestamp":"2026-05-12T00:00:00+01:00","topic":"engine-client-boundary","lesson":"Aquarium.Engine is the native D3D12/window/render graph layer and must not accrete Epiphany frontend semantics. Aquarium.Epiphany is the client/runtime layer behind Aquarium.Engine.Contracts and should configure engine abstractions for cameras, targets, shaders, resources, and passes.","files":["docs/engine-client-boundary.md","src/Aquarium.Epiphany/Aquarium.Epiphany.csproj","src/Aquarium.Engine/Runtime/ClientRuntimeLoader.cs","state/memory.json","state/map.yaml"]}
{"timestamp":"2026-05-12T00:00:00+01:00","topic":"epiphany-extraction-render-api-plan","lesson":"The next purification path is a small render graph API, not more renderer knobs: clients declare resources and passes, Aquarium owns D3D12 execution. Migrate in slices: freeze boundary, add Vortice-free descriptors, compile a minimal graph, convert presentation/bloom, move Epiphany body shaders and Grid policy to Aquarium.Epiphany, then replace AquariumFrame.","files":["docs/epiphany-extraction-render-api-plan.md","README.md","state/map.yaml","state/memory.json"]}
{"timestamp":"2026-05-12T03:40:00+01:00","topic":"epiphany-render-policy-extraction","lesson":"Epiphany body shaders, Grid brush construction, body visual/light tables, and cursor projection moved behind Aquarium.Engine.Contracts. Aquarium.Engine now consumes AquariumRenderPlan and AquariumSceneState data and passes scripts/verify-boundaries.ps1 with no Epiphany role/client names in engine source.","files":["src/Aquarium.Engine.Contracts/Render/AquariumApp.cs","src/Aquarium.Engine.Contracts/Render/AquariumRenderPlan.cs","src/Aquarium.Epiphany/EpiphanyRenderPlan.cs","src/Aquarium.Epiphany/EpiphanySceneBuilder.cs","src/Aquarium.Engine/Render/D3D12Renderer.cs","scripts/verify-boundaries.ps1","state/memory.json","state/map.yaml"]}
{"timestamp":"2026-05-12T03:50:00+01:00","topic":"graph-target-allocation","lesson":"The render graph compiler now validates declared targets/passes and D3D12Renderer allocates non-legacy client-declared render targets through engine resource/descriptors, including resize rebuild. This is allocation only; full graph pass execution remains the next cut.","files":["src/Aquarium.Engine/Render/Graph/D3D12RenderGraphCompiler.cs","src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Engine.Contracts/Render/AquariumApp.cs","state/memory.json"]}
{"timestamp":"2026-05-12T04:00:00+01:00","topic":"minimal-non-epiphany-client","lesson":"Aquarium now includes src/Aquarium.Sample.Minimal, a non-Epiphany client that references only Aquarium.Engine.Contracts, declares a minimal render plan, and boots through the same host/client assembly loader. Keep it as a boundary proof while the graph executor replaces legacy fixed passes.","files":["src/Aquarium.Sample.Minimal/MinimalRuntime.cs","src/Aquarium.Sample.Minimal/Aquarium.Sample.Minimal.csproj","README.md","state/map.yaml"]}
{"timestamp":"2026-05-12T04:05:00+01:00","topic":"grid-brush-gpu-packing","lesson":"GridHeightBrushConstants is D3D12 GPU packing for the height-field brush pass, not scene policy. Keep brush authoring in the client, keep packing in engine feature code, and keep D3D12Renderer limited to upload/command recording until the height-field pass moves fully into the graph executor.","files":["src/Aquarium.Engine/Render/Features/D3D12GridHeightBrushConstants.cs","src/Aquarium.Engine/Render/D3D12Renderer.cs","state/evidence.jsonl"]}
{"timestamp":"2026-05-10T07:47:46+01:00","topic":"cursor-teardrop-sdf","lesson":"Use the MathWorld teardrop curve for the cursor profile with m=6, revolved into an SDF locator. Keep ripples as geometry, material as brass GGX metal, and avoid ambient fill.","files":["src/Aquarium.Engine/Render/Shaders/D3D12Scene.hlsl","state/memory.json"],"source":"https://mathworld.wolfram.com/TeardropCurve.html"}
{"timestamp":"2026-05-11T00:00:00+01:00","topic":"aquarium-focus-cut","lesson":"Runtime volumetrics, cloud/fog research, and the D3D11 scene renderer are shelved because they distract from Aquarium's Epiphany-client mission. Git history holds the experiment; live repo state should not preserve compatibility husks or dead guidance for removed medium settings.","files":["src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Engine.Contracts/GraphicsSettings.cs","state/map.yaml","state/memory.json","state/scratch.md"]}
{"timestamp":"2026-05-11T04:20:00+01:00","topic":"medium-froxel-purge","lesson":"Medium/froxel render targets, structured buffers, shader bindings, scene outputs, post history lanes, and medium debug paths were removed from the live D3D12 renderer. Future atmospheric or field transport work needs a new explicit pass contract rather than reviving shelved scaffolding.","files":["src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Engine/Render/Shaders/D3D12Scene.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12Post.hlsl","state/map.yaml","state/memory.json"]}
{"timestamp":"2026-05-11T05:32:00+01:00","topic":"body-light-lane","lesson":"Blue-noise assets are retained for future dithering. Self and future other Selves emit through an explicit body light buffer; generic field instances are not the lighting authority.","files":["src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Engine/Render/Shaders/D3D12Scene.hlsl","state/map.yaml","state/memory.json"]}
{"timestamp":"2026-05-11T06:18:00+01:00","topic":"pmrem-cubemap-bake","lesson":"Studio HDR reflection lighting is baked as a PMREM DDS cubemap: roughness selects higher mips, and the bake samples the source latlong by output direction so cubemap faces are generated from one continuous domain instead of filtered as isolated square images.","files":["scripts/bake-pmrem-cubemap.py","src/Aquarium.Engine/Assets/Textures/studio3_pmrem.dds","state/map.yaml","state/memory.json"],"source":"E:\\Projects\\EpiphanyAquarium\\public\\textures\\studio3.hdr"}
{"timestamp":"2026-05-11T06:28:00+01:00","topic":"pmrem-scene-binding","lesson":"The Studio3 PMREM asset is live in the scene as a D3D12 TextureCube bound at t22. The renderer owns a narrow RGBA16F DX10 DDS cubemap loader, keeps upload resources alive until the copy fence completes, and the scene shader uses roughness-scaled SampleLevel for specular material reflections only.","files":["src/Aquarium.Engine/Render/D3D12CubeTexture.cs","src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Engine/Render/Shaders/D3D12Scene.hlsl","state/map.yaml","state/memory.json"]}
{"timestamp":"2026-05-11T06:42:00+01:00","topic":"grid-mirror-surface","lesson":"Grid linework was replaced with a terminating perfect mirror surface. Grid hits now write the primary scene packet with FIELD_ID_GRID, terrain normal, full coverage, and Studio3 PMREM mip 0 reflection instead of using the transparent event lane.","files":["src/Aquarium.Engine/Render/Shaders/D3D12Scene.hlsl","state/map.yaml","state/memory.json"]}
{"timestamp":"2026-05-11T06:50:00+01:00","topic":"pmrem-world-basis","lesson":"Aquarium world space is Z-up while the baked Studio3 PMREM cubemap is sampled as Y-up. Every PMREM lookup must convert world directions with (x, z, y) before TextureCube sampling, or the HDRI appears sideways.","files":["src/Aquarium.Engine/Render/Shaders/D3D12Scene.hlsl","state/memory.json"]}
{"timestamp":"2026-05-11T07:00:00+01:00","topic":"studio2-pmrem-probe","lesson":"Active reflection probe switched to Studio2 from E:\\Projects\\Aetheria-Economy\\Assets\\Textures\\studio2.hdr. The renderer loads Assets/Textures/studio2_pmrem.dds through the existing D3D12 TextureCube PMREM path, and the unused Studio3 DDS was cut from live assets.","files":["src/Aquarium.Engine/Assets/Textures/studio2_pmrem.dds","src/Aquarium.Engine/Assets/Textures/studio3_pmrem.dds","src/Aquarium.Engine/Render/D3D12Renderer.cs","state/map.yaml","state/memory.json"],"source":"E:\\Projects\\Aetheria-Economy\\Assets\\Textures\\studio2.hdr"}
{"timestamp":"2026-05-11T07:14:00+01:00","topic":"grid-brush-cpu-mirror","lesson":"Self's Grid gravity bowl now uses a 17-world-unit radius and an Aetheria-style radial cosine wave. The brush equation is mirrored across D3D12Grid, CPU body-light placement, D3D12Scene body centers, and D3D12Post temporal reprojection; body centers sit at Grid height plus 2x radius.","files":["src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Engine/Render/Shaders/D3D12Grid.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12Scene.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12Post.hlsl","state/map.yaml","state/memory.json"],"source":"E:\\Projects\\Aetheria-Economy\\Assets\\Shaders\\Brushes\\RadialWaveBrush.shader"}
{"timestamp":"2026-05-11T07:22:00+01:00","topic":"grid-flatness-roughness","lesson":"Grid reflection roughness is now slope-driven: flat regions sample higher Studio2 PMREM mips to avoid an over-literal HDRI mirror, while sloped or waved regions sharpen toward mip 0.","files":["src/Aquarium.Engine/Render/Shaders/D3D12Scene.hlsl","state/memory.json"]}
{"timestamp":"2026-05-11T07:28:00+01:00","topic":"pmrem-background-mip","lesson":"Flat Grid reflection now tops out at Studio2 PMREM mip 3, and ray misses use Studio2 PMREM mip 3 as the soft background so the reflective Grid is not contrasted against black void. Low-resolution mip texels are hidden with a small multi-direction cone average rather than one magnified TextureCube sample.","files":["src/Aquarium.Engine/Render/Shaders/D3D12Scene.hlsl","state/memory.json"]}
{"timestamp":"2026-05-11T07:36:00+01:00","topic":"studio2-pmrem-resolution","lesson":"Studio2 PMREM was rebaked at 512px per cubemap face with 10 mips, so mip 3 is 64px per face instead of 32px. Shader roughness LOD max moved to 9 to match the chain.","files":["src/Aquarium.Engine/Assets/Textures/studio2_pmrem.dds","src/Aquarium.Engine/Render/Shaders/D3D12Scene.hlsl","state/memory.json"],"source":"E:\\Projects\\Aetheria-Economy\\Assets\\Textures\\studio2.hdr"}
{"timestamp":"2026-05-11T07:45:00+01:00","topic":"diffuse-ibl-irradiance","lesson":"Diffuse IBL is not GGX PMREM with a softer mip. Studio2 diffuse lighting now uses a separate irradiance cubemap baked by cosine-weighted hemisphere convolution, stores the Li*cos(theta) irradiance integral, and shades non-metal bodies with Fresnel-gated albedo/PI diffuse response.","files":["scripts/bake-pmrem-cubemap.py","src/Aquarium.Engine/Assets/Textures/studio2_irradiance.dds","src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Engine/Render/Shaders/D3D12Scene.hlsl","state/map.yaml","state/memory.json"],"source":"E:\\Projects\\Aetheria-Economy\\Assets\\Textures\\studio2.hdr"}
{"timestamp":"2026-05-11T08:10:00+01:00","topic":"rider-solution-compatibility","lesson":"Rider may open Aquarium.Engine.slnx with empty project trees even though dotnet can build it. Keep Aquarium.Engine.sln as the Rider-facing classic solution while Aquarium.Engine.slnx remains the compact CLI solution.","files":["Aquarium.Engine.sln","Aquarium.Engine.slnx","README.md","state/map.yaml"]}
{"timestamp":"2026-05-11T08:35:00+01:00","topic":"epiphany-agent-sdf-visual-language","lesson":"Epiphany agent bodies should be role-specific SDF organs driven by published CultNet surfaces: identity from epiphany.agent_memory, motion from epiphany.agent_heartbeat, posture from surface roles/coordinator/role_result, Face output from surface.face, and continuity pressure from pressure/reorient surfaces. Body and Imagination are the first implementation pair because they exercise grounded graph mass and generative harmonic bloom against the same AgentVisualState contract.","files":["docs/epiphany-agent-sdf-visual-language.md","state/map.yaml","state/memory.json"],"source":"E:\\Projects\\EpiphanyAgent\\schemas\\README.md"}
{"timestamp":"2026-05-11T08:48:00+01:00","topic":"agent-expression-placement","lesson":"Agent orbit lanes are home anchors, not cages. Role bodies may wander a bounded distance from their designated orbit slots for expression, and vertical animation should come from CPU-visible gravity-well pulses so Grid height, body centers, shadows, and temporal reprojection share the same placement truth.","files":["docs/epiphany-agent-sdf-visual-language.md","state/map.yaml","state/memory.json"]}
{"timestamp":"2026-05-11T09:02:00+01:00","topic":"agent-visual-spec-specificity","lesson":"The Epiphany agent visual-language doc must specify spatial derivation, not describe role bodies with directionless vibes. Agent SDF orientation now has a world coordinate contract, fixed home orbit slots, named anchors, fallback chains, normalized state scalars, and concrete workDirection derivation for Hands.","files":["docs/epiphany-agent-sdf-visual-language.md"],"source":"user review"}
{"timestamp":"2026-05-11T09:14:00+01:00","topic":"aquarium-owned-agent-spatial-layout","lesson":"Do not push Aquarium spatial authority onto Epiphany. Epiphany publishes semantic surfaces; Aquarium owns world placement. Agent visual anchors such as evidenceAnchor, artifactAnchor, workAnchor, reviewAnchor, and continuityAnchor are deterministic Aquarium-local projections from semantic state, not CultNet world coordinates emitted by Epiphany.","files":["docs/epiphany-agent-sdf-visual-language.md","state/memory.json"],"source":"user review"}
{"timestamp":"2026-05-11T09:26:00+01:00","topic":"decisive-agent-visual-language","lesson":"The Epiphany agent SDF visual spec should avoid presentation uncertainty. Remove slash-pairs and standalone 'or' alternatives from the visual-language document; choose one mathematical form per organ, favor sphere intersections, torus arcs, trefoil and lemniscate tubes, superquadrics, geodesic ribs, logarithmic spirals, rounded octahedra, and cardioid seeds over generic ellipsoid/capsule placeholders.","files":["docs/epiphany-agent-sdf-visual-language.md"],"source":"user review"}
{"timestamp":"2026-05-11T09:40:00+01:00","topic":"agent-sdf-realtime-rendering-plan","lesson":"Agent role SDFs should render as bounded per-agent implicit objects, not one scene-global mega-SDF. Use conservative sphere-tracing distances, proxy rasterization, one role SDF selected after proxy hit, local bounds for expensive features, post-hit normals, cheap shadows, pixel-footprint hit epsilon, LOD tiers, and debug views for step count, proxy hits, material id, LOD, and SDF cost.","files":["docs/epiphany-agent-sdf-visual-language.md","state/memory.json"],"source":"Hart sphere tracing, Enhanced Sphere Tracing, Inigo Quilez SDF bounding, CTSS, NVIDIA SDF grids"}
{"timestamp":"2026-05-11T16:18:00+01:00","topic":"agent-visual-state-first-slice","lesson":"The fixed orbit bodies are now backed by an AgentVisualGpu buffer carrying current center, previous center, role id, state scalars, and LOD. D3D12Scene uses the buffer for bounded agent SDF hits; D3D12Post uses the same buffer for agent temporal reprojection. Body and Imagination are the first LOD 1 role SDFs, with debug modes for role, material, step count, LOD, and cost.","files":["src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Engine/Render/Shaders/D3D12Scene.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12Post.hlsl","src/Aquarium.Engine.Contracts/GraphicsSettings.cs","docs/hlsl-renderer.md","state/map.yaml","state/memory.json"]}
{"timestamp":"2026-05-11T16:39:00+01:00","topic":"agent-sdf-domain-discipline","lesson":"Early role-body experiments showed that decorative pseudo-distance fields, raw atan2 lobes, and stitched ellipsoid petals create seams, gaps, and view-dependent fixes. For role SDFs, choose a continuous spatial domain or anatomical parameterization that owns the silhouette, then make the marcher conservative enough for that field; do not preserve old scene-pass LOD 1 blob recipes as future guidance.","files":["state/memory.json","state/evidence.jsonl"],"source":"consolidated early agent-body artifact review"}
{"timestamp":"2026-05-11T21:40:00+00:00","topic":"bounded-body-proxy-pass","lesson":"The fullscreen scene pass should own only background and Grid. Self, cursor, and role bodies now render through AgentVisualGpu-driven bounded proxy draws: one instanced conservative screen rectangle per object, object-local raymarching, and travel-derived depth writes so Grid and body occlusion stay honest.","files":["src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Engine/Render/Shaders/D3D12Scene.hlsl","docs/hlsl-renderer.md","state/map.yaml","state/memory.json"],"source":"user architecture correction"}
{"timestamp":"2026-05-11T22:07:07+01:00","topic":"shader-boundary-body-pass","lesson":"D3D12Scene is now environment/Grid only. Bounded body proxy draws compile from D3D12Bodies.hlsl, reusable SDF math lives in D3D12SdfMath.hlsli, current agent character organs live in D3D12AgentCharacters.hlsli, and D3D12Renderer expands local includes before D3DCompile because the Vortice convenience compile path does not provide a usable include handler here. The cursor is now a luminous three-lobed hibiscus anchored on XY with its contact tip at Grid z=0.","files":["src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Engine/Render/Shaders/D3D12Scene.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12Bodies.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12SdfMath.hlsli","src/Aquarium.Engine/Render/Shaders/D3D12AgentCharacters.hlsli","docs/hlsl-renderer.md","state/map.yaml","state/memory.json"],"source":"user architecture correction"}
{"timestamp":"2026-05-11T22:17:28+01:00","topic":"per-body-shader-boundary","lesson":"Body proxy rendering now uses one shader file and one proxy pipeline per visible body slot: Face, Imagination, Eyes, Body, Hands, Self, and Cursor. Shared proxy plumbing lives in D3D12BodyCommon.hlsli and D3D12BodyProxy.hlsli, but body identity SDF and material code should stay split by body rather than collapsing into a single role or Self bucket.","files":["src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Engine/Render/Shaders/D3D12BodyCommon.hlsli","src/Aquarium.Engine/Render/Shaders/D3D12BodyProxy.hlsli","src/Aquarium.Engine/Render/Shaders/D3D12FaceAgent.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12ImaginationAgent.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12EyesAgent.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12BodyAgent.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12HandsAgent.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12SelfBody.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12CursorBody.hlsl","docs/hlsl-renderer.md","state/map.yaml","state/memory.json"],"source":"user architecture correction"}
{"timestamp":"2026-05-11T22:18:54+01:00","topic":"eight-agent-body-table","lesson":"The visible Epiphany agent body table is Self, Face, Imagination, Eyes, Body, Hands, Soul, and Life. Cursor remains a separate non-agent body. Renderer constants, body shader paths, proxy pipelines, and post reprojection counts should track seven role agents plus Self plus cursor, not the older five-role provisional slice.","files":["src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Engine/Render/Shaders/D3D12Post.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12SoulAgent.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12LifeAgent.hlsl","docs/hlsl-renderer.md","state/map.yaml","state/memory.json"],"source":"user role table correction"}
{"timestamp":"2026-05-11T22:29:04+01:00","topic":"per-body-proxy-indexing","lesson":"Per-body proxy shaders must not rely on DrawInstanced StartInstanceLocation reaching SV_InstanceID for body identity. Each body shader now declares a shader-local BODY_INDEX constant, and shared proxy VS/PS use that constant for AgentVisualGpu lookup, proxy rectangle placement, and raymarch selection. This keeps per-body shader files transform-locked to their own visual row.","files":["src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Engine/Render/Shaders/D3D12BodyCommon.hlsli","src/Aquarium.Engine/Render/Shaders/D3D12FaceAgent.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12ImaginationAgent.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12EyesAgent.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12BodyAgent.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12HandsAgent.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12SoulAgent.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12LifeAgent.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12SelfBody.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12CursorBody.hlsl"],"source":"visible transform bug report"}
{"timestamp":"2026-05-11T22:32:12+01:00","topic":"canonical-agent-visual-order","lesson":"AgentVisualGpu row order is canonical and must match shader BODY_INDEX constants, body pipeline order, Grid brush indexing, and temporal reprojection: 0 Self, 1 Face, 2 Imagination, 3 Eyes, 4 Body, 5 Hands, 6 Soul, 7 Life, 8 Cursor. Roles-first buffer ordering breaks transforms even if each shader has its own file.","files":["src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Engine/Render/Shaders/D3D12BodyCommon.hlsli","src/Aquarium.Engine/Render/Shaders/D3D12Post.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12SelfBody.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12FaceAgent.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12ImaginationAgent.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12EyesAgent.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12BodyAgent.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12HandsAgent.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12SoulAgent.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12LifeAgent.hlsl"],"source":"visible transform bug report"}
{"timestamp":"2026-05-11T23:17:40+01:00","topic":"body-proxy-screen-space-convention","lesson":"Body proxy quads and body proxy ray construction must use the same screen-space Y convention as the fullscreen scene pass. Clip-space proxy center should use projected.y directly, and the proxy pixel shader must convert SV_Position top-left pixel coordinates to the bottom-left pixel coordinates expected by rayDirectionForPixel. If they disagree, bodies appear to swim in camera space instead of staying grounded in world space.","files":["src/Aquarium.Engine/Render/Shaders/D3D12BodyCommon.hlsli","src/Aquarium.Engine/Render/Shaders/D3D12BodyProxy.hlsli"],"source":"visible transform bug report"}
{"timestamp":"2026-05-11T23:23:04+01:00","topic":"cursor-hibiscus-anatomy","lesson":"The cursor hibiscus needs recognizable flower anatomy, not just three glossy petals. The cursor SDF now includes curled ruffled petals, a throat, a protruding staminal column with pollen beads, and a green calyx/contact stem, with a larger proxy bound to prevent clipping the expanded silhouette.","files":["src/Aquarium.Engine/Render/Shaders/D3D12SdfMath.hlsli","src/Aquarium.Engine/Render/Shaders/D3D12CursorBody.hlsl","src/Aquarium.Engine/Render/D3D12Renderer.cs"],"source":"visual reference comparison"}
{"timestamp":"2026-05-11T23:35:00+01:00","topic":"thin-structure-body-marching","lesson":"All role bodies are expected to carry thin visible structure, so conservative body SDF tracing is the shared default rather than a cursor-specific exception. Body proxy tracing now uses tighter hit epsilon, more steps, and smaller step scale through shared macros; faster tracing should only reappear through explicit LOD policy after it proves it preserves filaments, ribs, rings, petals, and other narrow organs.","files":["src/Aquarium.Engine/Render/Shaders/D3D12BodyProxy.hlsli","src/Aquarium.Engine/Render/Shaders/D3D12CursorBody.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12SdfMath.hlsli","state/memory.json"],"source":"user visual artifact review"}
{"timestamp":"2026-05-11T23:39:00+01:00","topic":"sheet-sdf-petals-and-guarded-marching","lesson":"Do not represent petals and other thin organs as fat ellipsoids with decorative displacement. The recursive lotus reference preserves delicate structure by using slab/intersection fields and scaling the distance estimate after its log-spherical mapping; Aquarium cursor petals now use thin clipped sheet SDFs, and the shared body marcher caps step length plus refines positive-to-negative sign crossings instead of trusting pseudo-distance composites blindly.","files":["src/Aquarium.Engine/Render/Shaders/D3D12BodyProxy.hlsli","src/Aquarium.Engine/Render/Shaders/D3D12SdfMath.hlsli","state/memory.json"],"source":"https://github.com/pac-dev/notes/blob/master/content/logspherical/recursive_lotus.glsl"}
{"timestamp":"2026-05-11T23:47:00+01:00","topic":"pseudo-distance-near-miss-hits","lesson":"The cursor stamen and angled petals disappeared because the body proxy marcher accepted abs(distance) < epsilon as a hit on a pseudo-distance composite. Rays that passed near a petal sheet could terminate before reaching the actual stamen or petal intersection. The proxy marcher now requires distance <= 0 entry, refines positive-to-negative brackets, and uses a larger step budget to survive capped steps across the proxy volume.","files":["src/Aquarium.Engine/Render/Shaders/D3D12BodyProxy.hlsli","state/memory.json"],"source":"user visual artifact review"}
{"timestamp":"2026-05-11T23:52:00+01:00","topic":"cursor-hibiscus-organ-primitives","lesson":"The cursor hibiscus shape should be built from organ-appropriate SDF primitives instead of ellipsoid paste. Petals now use upward-curving tapered sheets with lens footprints and tapered thickness, the staminal column uses a curved tapered tube, and the green contact anatomy uses a connected tapered stem plus calyx bulb so the stem visibly reaches the flower.","files":["src/Aquarium.Engine/Render/Shaders/D3D12SdfMath.hlsli","src/Aquarium.Engine/Render/Shaders/D3D12CursorBody.hlsl","state/memory.json"],"source":"user visual artifact review"}
{"timestamp":"2026-05-11T23:59:00+01:00","topic":"cursor-hibiscus-reference-target","lesson":"The closer cursor objective is the pale pink five-petal hibiscus reference: broad translucent cupped petals, a folded central throat, a curved staminal column with side pollen filaments, and a green tapered calyx/stem ending at the XY contact point. The SDF now uses five tapered sheet petals, a simplified three-segment quadratic tube helper to keep shader compile time sane, side filament tubes, pollen bead spheres, and a curved tapered calyx core with sepals.","files":["src/Aquarium.Engine/Render/Shaders/D3D12SdfMath.hlsli","src/Aquarium.Engine/Render/Shaders/D3D12CursorBody.hlsl","state/memory.json"],"source":"user reference images"}
{"timestamp":"2026-05-12T00:12:00+01:00","topic":"cursor-petal-single-formula","lesson":"The hibiscus cursor petal should not be assembled from piecewise vertical panels and horizontal blades. Model each petal from one longitudinal coordinate: radial displacement grows quadratically so the root starts vertical, height follows a smooth cubic center curve, width and thickness grow from thin root to broad distal blade, and decorative ruffles stay out until the core SDF is stable and cheap.","files":["src/Aquarium.Engine/Render/Shaders/D3D12SdfMath.hlsli","state/memory.json"],"source":"user visual/math review"}
{"timestamp":"2026-05-12T00:17:00+01:00","topic":"cursor-hibiscus-reset","lesson":"When the hibiscus cursor starts turning into SDF Jenga, reset the function around anatomical parameters instead of stapling on fixes. The current reset keeps five petals as one cheap graph-style ribbon formula each: u comes from height, radial displacement is quadratic so roots start vertical, width and thickness grow with u, and decorative trig/filament swarms are cut until the core form is stable and fast.","files":["src/Aquarium.Engine/Render/Shaders/D3D12SdfMath.hlsli","state/memory.json"],"source":"user architecture correction"}
{"timestamp":"2026-05-12T00:26:00+01:00","topic":"agent-sdf-form-discipline","lesson":"Carry the cursor hibiscus lesson into agent bodies: start every role SDF from a coherent anatomical/form model with a small set of parameters that explain the silhouette across views. Prefer one governing coordinate, profile, width, thickness, symmetry, and material-region model over stitched primitives. Add ornament only after the core form is readable, fast, and stable; fine veins, glitter, filaments, and state pulses should begin as shading or LOD-gated overlays, not traced geometry.","files":["state/memory.json","state/map.yaml"],"source":"cursor hibiscus iteration review"}
{"timestamp":"2026-05-12T00:34:00+01:00","topic":"shader-include-ownership","lesson":"Keep shader include ownership strict before role bodies multiply. D3D12SdfMath.hlsli should hold reusable SDF primitives and generic form helpers, not cursor-specific hibiscus anatomy. Body-specific SDF structure belongs in the owning body shader. Shared lighting equations belong in D3D12BodyCommon.hlsli as material-parameterized helpers so cursor, agents, and future bodies do not duplicate GGX/body-light loops.","files":["src/Aquarium.Engine/Render/Shaders/D3D12BodyCommon.hlsli","src/Aquarium.Engine/Render/Shaders/D3D12CursorBody.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12SdfMath.hlsli","state/memory.json"],"source":"user architecture correction"}
{"timestamp":"2026-05-12T00:51:00+01:00","topic":"body-distance-surface-shading-split","lesson":"Body SDF passes should be a bounded-cost machine: ray steps and normal samples evaluate only scalar bodyDistance; bodySurface is evaluated once after the hit is refined and returns the PBR material packet. Avoid second-pass SDF component scans such as cursorEmissionRadiance; material choice belongs in the hit surface packet and lighting belongs in shared material-parameterized functions.","files":["src/Aquarium.Engine/Render/Shaders/D3D12BodyCommon.hlsli","src/Aquarium.Engine/Render/Shaders/D3D12BodyProxy.hlsli","src/Aquarium.Engine/Render/Shaders/D3D12CursorBody.hlsl","state/memory.json","state/map.yaml"],"source":"user architecture correction"}
{"timestamp":"2026-05-12T01:04:00+01:00","topic":"body-surface-packet-minimalism","lesson":"Do not let diagnostic identity fields squat in BodySurface. The hot surface packet now carries only PBR material values. Distance belongs to bodyDistance and the marcher; field identity is emitted by the proxy for temporal ownership; role/material/LOD/cost ids and the common shadeRoleAgentBody router were cut because per-role shader files should own their own material decisions directly.","files":["src/Aquarium.Engine/Render/Shaders/D3D12BodyCommon.hlsli","src/Aquarium.Engine/Render/Shaders/D3D12BodyProxy.hlsli","src/Aquarium.Engine/Render/Shaders/D3D12AgentCharacters.hlsli","src/Aquarium.Engine/Render/Shaders/D3D12Post.hlsl","src/Aquarium.Engine/Render/D3D12Renderer.cs","state/memory.json","state/map.yaml"],"source":"user architecture correction"}
{"timestamp":"2026-05-12T01:58:00+01:00","topic":"temporal-event-lane-cut","lesson":"Dormant full-frame lanes are architectural debt, not preparedness. Aquarium had scene event color/metadata targets plus event history targets even though every producer wrote zero coverage. The event lane, dead AgentVisual LOD/index vector, dead reactive control channel, and one-field AgentSurface wrapper were cut; temporal resolve now carries only scene color, metadata, and coverage/step control history.","files":["src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Engine/Render/Shaders/D3D12Post.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12Scene.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12BodyCommon.hlsli","src/Aquarium.Engine/Render/Shaders/D3D12BodyProxy.hlsli","src/Aquarium.Engine/Render/Shaders/D3D12AgentCharacters.hlsli","docs/hlsl-renderer.md","state/memory.json","state/map.yaml"],"source":"purification pass"}
{"timestamp":"2026-05-12T04:30:00+01:00","topic":"engine-client-boundary-vocabulary","lesson":"Aquarium.Engine and Aquarium.Engine.Contracts must speak renderer vocabulary, not Epiphany policy vocabulary. Engine contracts expose ViewFrame, height-field brushes, SDF objects, SDF lights, generic shader manifests, and generic proxy passes. Epiphany may call its own things grid, agents, bodies, or roles, but the engine only consumes declared rendering data. Enforce this with scripts/verify-boundaries.ps1 before every architectural pass.","files":["scripts/verify-boundaries.ps1","src/Aquarium.Engine.Contracts","src/Aquarium.Engine","src/Aquarium.Epiphany","state/memory.json","state/map.yaml"],"source":"engine-client extraction correction"}
{"timestamp":"2026-05-12T05:30:00+01:00","topic":"client-ui-composition-contract","lesson":"Keep the engine debug panel as engine-owned UI, but expose a separate AquariumUiDocument contract for client overlay panels. Clients compose controls through Vortice-free panel builders; Aquarium.Engine translates those declarations into its DirectWrite/Direct2D overlay and owns input dispatch. Do not let Epiphany depend on DebugUi internals.","files":["src/Aquarium.Engine.Contracts/Ui/AquariumUi.cs","src/Aquarium.Engine/Render/Ui/DebugUi.cs","src/Aquarium.Engine/Render/DirectWriteOverlay.cs","src/Aquarium.Epiphany/AquariumRuntime.cs","state/memory.json"],"source":"client UI abstraction pass"}
{"timestamp":"2026-05-12T12:35:00+01:00","topic":"unified-debug-panel","lesson":"F2 should open one Aquarium debug panel, not separate engine and client windows. Client AquariumUiDocument panels are folded into the same tabbed debug surface, clients can register terminal commands through AquariumUiDocument.Command, and future debug UI should extend this shared composition surface instead of spawning parallel panels.","files":["src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Engine/Render/Ui/DebugUi.cs","src/Aquarium.Engine.Contracts/Ui/AquariumUi.cs","src/Aquarium.Epiphany/AquariumRuntime.cs","state/memory.json","state/map.yaml"],"source":"debug UI consolidation pass"}
{"timestamp":"2026-05-12T13:00:00+01:00","topic":"debug-tab-chrome","lesson":"Debug tabs are navigation chrome, not document content. The unified F2 panel title is Debug, with a row of tab buttons directly below it and visible active highlighting. Future debug surfaces should add tabs through the same chrome path instead of creating fake Tabs sections or parallel panels.","files":["src/Aquarium.Engine/Render/Ui/DebugUi.cs","src/Aquarium.Engine/Render/D3D12Renderer.cs","state/memory.json"],"source":"user UI correction"}
{"timestamp":"2026-05-12T13:20:00+01:00","topic":"debug-text-box-control","lesson":"Long editable UI buffers need real text box controls, not row-value text fields. AquariumUiTextBox carries line count, return behavior, and optional submit action through the contract; DirectWrite debug UI renders it as a boxed editable region. Use row Text only for compact scalar strings.","files":["src/Aquarium.Engine.Contracts/Ui/AquariumUi.cs","src/Aquarium.Engine/Render/Ui/DebugUi.cs","src/Aquarium.Engine/Render/D3D12Renderer.cs","state/memory.json"],"source":"debug UI improvement pass"}
{"timestamp":"2026-05-12T13:27:00+01:00","topic":"multiline-debug-terminal","lesson":"The debug terminal should be one multiline session surface: recent log lines plus the live prompt at the end. Typing updates only the trailing prompt, Enter submits that prompt and appends the command/output to the log. Avoid separate output readouts plus detached command rows for terminal UI.","files":["src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Engine/Render/Ui/DebugUi.cs","state/memory.json"],"source":"user terminal correction"}
{"timestamp":"2026-05-12T13:42:00+01:00","topic":"terminal-textbox-polish","lesson":"Terminal text boxes need terminal typography and prompt-safe editing. Bundle Ubuntu Sans Mono for DirectWrite monospace surfaces, let AquariumUiTextBox opt into monospace and bottom alignment, and guard empty trailing prompts so backspace cannot collapse the prompt sentinel and reclassify the log as command input.","files":["src/Aquarium.Engine/Assets/Fonts/UbuntuSansMono.ttf","src/Aquarium.Engine.Contracts/Ui/AquariumUi.cs","src/Aquarium.Engine/Render/DirectWriteOverlay.cs","src/Aquarium.Engine/Render/Ui/DebugUi.cs","src/Aquarium.Engine/Render/D3D12Renderer.cs","state/memory.json"],"source":"user terminal polish correction"}
{"timestamp":"2026-05-12T13:55:00+01:00","topic":"terminal-surface-layout","lesson":"Terminal surfaces should not display ordinary text-box labels or fake corner carets. A terminal prompt is already the affordance. Use label-less text boxes for terminal sessions, use a near-aligned monospace text format, and bottom-align by drawing the terminal line list against the box bottom rather than relying on centered DirectWrite paragraph layout.","files":["src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Engine/Render/DirectWriteOverlay.cs","src/Aquarium.Engine/Render/Ui/DebugUi.cs","state/evidence.jsonl"],"source":"user visual correction"}
{"timestamp":"2026-05-12T14:05:00+01:00","topic":"terminal-bottom-line-layout","lesson":"DirectWrite multiline layout can still make a terminal body feel vertically floating even when the containing bounds are bottom-biased. For terminal-style text boxes, draw visible lines individually from the bottom of the text bounds using explicit line height; do not rely on padded blank lines or paragraph layout for bottom alignment.","files":["src/Aquarium.Engine/Render/Ui/DebugUi.cs","state/evidence.jsonl"],"source":"user screenshot correction"}
{"timestamp":"2026-05-12T14:25:00+01:00","topic":"debug-text-editing-capture","lesson":"Debug text boxes need real editing ownership: persistent caret index, selection anchor, mouse placement, drag selection, arrow/Home/End movement, Backspace/Delete, selected-text replacement, and input capture while focused. When a text box owns the keyboard, host-level debug hotkeys and client camera controls must receive a non-interactive input snapshot instead of the live key/mouse state.","files":["src/Aquarium.Engine.Contracts/Input/InputState.cs","src/Aquarium.Engine/AquariumHost.cs","src/Aquarium.Engine/Platform/Win32Window.cs","src/Aquarium.Engine/Render/IAquariumRenderer.cs","src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Engine/Render/Ui/DebugUi.cs","state/memory.json"],"source":"user text editing requirement"}
{"timestamp":"2026-05-12T14:35:00+01:00","topic":"directwrite-text-editing-metrics","lesson":"Do not position text-box caret or selection with guessed monospace character widths. Use DirectWrite text layout hit-test positions for the same font and layout used to draw text, cache those positions for mouse placement, and keep text boxes focus-only visually rather than filling like active buttons on click.","files":["src/Aquarium.Engine/Render/Ui/DebugUi.cs","state/evidence.jsonl"],"source":"user screenshot correction"}
{"timestamp":"2026-05-12T14:42:00+01:00","topic":"directwrite-text-editing-vertical-metrics","lesson":"Horizontal caret alignment is not enough. Caret height and selection top/bottom should also come from DirectWrite hit-test metrics for the active glyph run; using the UI line box makes editing visuals droop below the text even when x positions are correct.","files":["src/Aquarium.Engine/Render/Ui/DebugUi.cs","state/evidence.jsonl"],"source":"user screenshot correction"}
{"timestamp":"2026-05-12T14:50:00+01:00","topic":"text-edit-commit-state","lesson":"After a text box writes a new bound value, preserve caret and selection against the committed local value immediately. If edit state waits for the next read/sync cycle, the first typed character can leave stale caret state and subsequent input inserts at the wrong position, corrupting commands.","files":["src/Aquarium.Engine/Render/Ui/DebugUi.cs","state/evidence.jsonl"],"source":"terminal input corruption fix"}
{"timestamp":"2026-05-12T14:51:00+01:00","topic":"terminal-prompt-edit-boundary","lesson":"A terminal text box displays immutable log text plus a mutable prompt tail, so its editing model must clamp caret, selection, insertion, deletion, Home, and mouse placement to the prompt input region. Local text edits must clamp against the in-flight edited value, not the stale bound read value, or the first character on an empty prompt snaps the caret behind itself.","files":["src/Aquarium.Engine/Render/Ui/DebugUi.cs","src/Aquarium.Engine/Render/D3D12Renderer.cs","state/evidence.jsonl"],"source":"user terminal caret/backspace correction"}
{"timestamp":"2026-05-12T19:57:28+01:00","topic":"debug-dropdown-overlay-ownership","lesson":"Dropdown option lists are transient overlay panels, not row layout. Keep the field row's layout height constant, align the popup to the value field bounds, flip above the field when viewport space below is worse, scroll long lists inside the popup, and close the modal on outside click before other controls can react.","files":["src/Aquarium.Engine/Render/Ui/DebugUi.cs","state/evidence.jsonl"],"source":"user dropdown layout correction"}
{"timestamp":"2026-05-12T20:04:11+01:00","topic":"debug-ui-mouse-input-capture","lesson":"Renderer input capture must include both keyboard ownership and mouse ownership. If Debug UI consumes wheel or mouse interaction but the renderer only reports keyboard capture, the same wheel event leaks into client camera/runtime controls after the overlay handles it.","files":["src/Aquarium.Engine/Render/D3D12Renderer.cs","state/evidence.jsonl"],"source":"user dropdown scroll capture correction"}
{"timestamp":"2026-05-12T21:28:22+01:00","topic":"single-solution-authority","lesson":"Keep one solution inventory for Aquarium. Maintaining both Aquarium.Engine.sln and Aquarium.Engine.slnx created duplicate project authority, Rider confusion, and verification races when both were built against shared obj/bin outputs. Aquarium.Engine.sln is the canonical solution for IDE and CLI work.","files":["Aquarium.Engine.sln","AGENTS.md","README.md","scripts/dev-watch.ps1","state/map.yaml","state/evidence.jsonl"],"source":"user solution authority cleanup"}
{"timestamp":"2026-05-12T23:08:00+01:00","topic":"synth-test-ownership","lesson":"Aquarium must not own synth reference truth. Engine tests may smoke-test the runtime synth host boundary, but synth correctness belongs in AquariumSynthCSharp so Aquarium can keep iterating while the synth library is under construction.","files":["tests/Aquarium.Engine.Tests/SynthPlaybackTests.cs","tests/Aquarium.Engine.Tests/Aquarium.Engine.Tests.csproj","state/evidence.jsonl"],"source":"user questioned synth testing ownership"}
{"timestamp":"2026-05-13T00:26:00+01:00","topic":"synth-package-boundary","lesson":"Aquarium must not build against the live AquariumSynthCSharp project while a synth agent is mutating it. Consume AquariumSynth.Dsl as a pinned repo-local NuGet package and update that package only by deliberate version bump.","files":["NuGet.config","packages/AquariumSynth.Dsl.0.1.0-aquarium.1.nupkg","src/Aquarium.Engine/Aquarium.Engine.csproj","scripts/update-synth-package.ps1","state/map.yaml","state/memory.json","state/scratch.md","state/evidence.jsonl"],"source":"user asked whether synth-agent work can break Aquarium builds"}
{"timestamp":"2026-05-17T15:15:00+01:00","topic":"aquasynth-native-audio-ownership","lesson":"Aquarium should host completed synth products, not own AquaSynth parsing, Faust emission, native libfaust factory creation, render duration estimation, compile keys, DSP source artifacts, or sample-buffer rendering. Those responsibilities now live in AquaSynth.Faust through AquaSynthNativeCompiler; AquariumSynthHost keeps scheduling, debounce/status, cache playback, and WASAPI output.","files":["src/Aquarium.Engine/Audio/AquariumSynthHost.cs","src/Aquarium.Engine/Aquarium.Engine.csproj","scripts/update-synth-package.ps1","scripts/publish-win-x64.ps1","state/map.yaml","state/memory.json"],"source":"user asked to finish taking over Aquarium's current audio rendering ownership so the engine does not concern itself with synth internals"}
{"timestamp":"2026-05-17T15:45:00+01:00","topic":"aquasynth-package-split","lesson":"Aquarium consumes AquaSynth.Faust, not a catch-all AquaSynth.Dsl package. AquaSynth.Faust carries the runtime/toolchain surface and pulls AquaSynth.Core transitively for the built-in patch editor's parser/model/built-in script needs.","files":["src/Aquarium.Engine/Aquarium.Engine.csproj","packages/AquaSynth.Core.0.1.0-alpha.3.nupkg","packages/AquaSynth.Faust.0.1.0-alpha.3.nupkg","scripts/update-synth-package.ps1","scripts/publish-win-x64.ps1","state/map.yaml","state/memory.json","state/scratch.md"],"source":"user pointed out .Dsl no longer described the package and confirmed Aquarium still needs DSL through the Faust dependency"}
{"timestamp":"2026-05-18T10:35:00+01:00","topic":"aquasynth-render-session-boundary","lesson":"AquariumSynthHost does not deserve to hold a live AquaSynthRenderSession. AquaSynth.Faust owns live patch compilation through AquaSynthPatchCompiler; Aquarium owns only debounce, trigger scheduling, rendered-buffer caching, and WASAPI playback.","files":["src/Aquarium.Engine/Audio/AquariumSynthHost.cs","tests/Aquarium.Engine.Tests/SynthPlaybackTests.cs","src/Aquarium.Engine/Aquarium.Engine.csproj","packages/AquaSynth.Core.0.1.0-alpha.3.nupkg","packages/AquaSynth.Faust.0.1.0-alpha.3.nupkg"],"source":"user challenged the host's remaining Faust authority after AquaSynth already owned patch meaning and native render proof"}
{"timestamp":"2026-05-17T16:15:00+01:00","topic":"aquasynth-semver","lesson":"Aquarium pins AquaSynth packages on the `0.1.0-alpha.N` prerelease line. Keep AquaSynth package versions as normal SemVer prereleases; do not use repo-name suffixes such as `0.1.0-aquasynth.2`.","files":["src/Aquarium.Engine/Aquarium.Engine.csproj","packages/AquaSynth.Core.0.1.0-alpha.3.nupkg","packages/AquaSynth.Faust.0.1.0-alpha.3.nupkg","state/map.yaml"],"source":"user noted that 0.1.0-aquasynth.2 was an exciting new take on semantic versioning"}
{"timestamp":"2026-05-13T00:40:00+01:00","topic":"generic-sdf-field-ids","lesson":"Aquarium shared SDF code must not special-case Epiphany object identities. SDF field ids are generic base-plus-object-index metadata; Self, Cursor, and role meaning stay in Epiphany's object table and shaders, while temporal reprojection uses uploaded AquariumSdfObject current/previous centers for every SDF object.","files":["src/Aquarium.Engine/Render/Shaders/D3D12SdfCommon.hlsli","src/Aquarium.Engine/Render/Shaders/D3D12SdfProxy.hlsli","src/Aquarium.Engine/Render/Shaders/D3D12Post.hlsl","src/Aquarium.Epiphany/EpiphanySceneBuilder.cs","docs/epiphany-agent-sdf-visual-language.md","state/memory.json"]}
{"timestamp":"2026-05-13T01:05:00+01:00","topic":"sdf-metallic-roughness-pbr","lesson":"SDF surfaces now use the industry-standard metallic-roughness material language: baseColor, metallic, roughness, and emission. The shared shader derives dielectric F0, metal-tinted specular F0, non-metal diffuse color, direct Cook-Torrance GGX specular, Fresnel-gated Lambert diffuse, diffuse irradiance IBL, and roughness-mip PMREM specular from those fields.","files":["src/Aquarium.Engine/Render/Shaders/D3D12SdfCommon.hlsli","src/Aquarium.Engine/Render/Shaders/D3D12SdfProxy.hlsli","src/Aquarium.Epiphany/Shaders","docs/epiphany-agent-sdf-visual-language.md","state/memory.json"],"source":"Khronos glTF 2.0 metallic-roughness material model; Google Filament material model notes"}
{"timestamp":"2026-05-13T01:45:00+01:00","topic":"imagination-topology-spec","lesson":"Imagination's visual spec needs topology, not just evocative nouns. The target is a luminous opal seed wrapped by broad translucent curling ribbon-sheets with traced raised rims, visible interior apertures, vertical fountain bias, sparse candidate filaments/sparks, and cool backlog shadow. Trefoil/tube curves may define rim paths, but tubes alone do not satisfy the petal form.","files":["docs/epiphany-agent-sdf-visual-language.md","state/memory.json"],"source":"user supplied imagegen reference and noted current output did not match the imagined impossible flower"}
{"timestamp":"2026-05-13T01:58:00+01:00","topic":"imagination-sheet-pair-sdf","lesson":"The compile-bounded Imagination implementation should model topology first: three mirrored sheet-pair SDF fields produce six broad ribbon sheets, while separate film/rim/tendril/spark/shadow distances preserve material classification for translucent petals, glowing raised rims, candidate filaments, and backlog shadow. This keeps the impossible-flower form legible without reverting to trefoil-only tubes or decorative polar fields.","files":["src/Aquarium.Epiphany/Shaders/D3D12ImaginationAgent.hlsl","state/memory.json","state/evidence.jsonl"],"source":"implementation pass after topology spec correction"}
{"timestamp":"2026-05-13T02:04:00+01:00","topic":"imagination-dead-code-cut","lesson":"User visual review caught dead implementation carryover: the polar-lobed Imagination seed was not in the spec, and the traced half-torus labeled shadow did not read as backlog shadow. Cut both instead of explaining them. Keep petal tips tapered through width/rim endpoints, avoid vertical rim columns, and only add shadow geometry when it has a readable visual contract.","files":["src/Aquarium.Epiphany/Shaders/D3D12ImaginationAgent.hlsl","state/memory.json","state/evidence.jsonl"],"source":"user screenshot correction"}
{"timestamp":"2026-05-13T02:08:00+01:00","topic":"imagination-continuous-ribbon-field","lesson":"The hibiscus cursor lesson applies to Imagination: use a continuous sheet parameterization when it can own the form. Replacing piecewise rim capsule chains with one pair-space field for film and raised edge distance removed straight posts, made the ribbon silhouette more coherent, and reduced headless reload time instead of adding compensating geometry.","files":["src/Aquarium.Epiphany/Shaders/D3D12ImaginationAgent.hlsl","state/memory.json","state/evidence.jsonl"],"source":"user challenged piecewise construction after visual review"}
{"timestamp":"2026-05-13T02:13:00+01:00","topic":"continuous-form-first-rule","lesson":"Carve this into local practice: when a spec describes a continuous visual, physical, or simulation form, start with continuous field math or a coherent parameterization that owns the form. Piecewise capsules, boxes, slabs, helper organs, adapters, and compensators are not acceptable lazy shortcuts; use them only when the form is actually piecewise or measured constraints force a documented cut.","files":["AGENTS.md","state/memory.json","state/evidence.jsonl"],"source":"user instruction after Imagination correction"}
{"timestamp":"2026-05-13T04:32:09+01:00","topic":"self-orbital-grammar","lesson":"Self's orrery form should arise from one compact spherical/log-shell coordinate grammar: stable radial strata crossed with continuous angular harmonic bands. Visible rails must use continuous direction-vector or harmonic fields, not raw atan2/fract longitude branch cuts; phase may rotate angular frames but must not animate radial zero crossings or grow rings from points. Do not rebuild Self as independent hoops, one-radius ornament layers, or repeated trigonometry piles.","files":["src/Aquarium.Epiphany/Shaders/D3D12SelfBody.hlsl","docs/epiphany-agent-sdf-visual-language.md","state/memory.json","state/evidence.jsonl"],"source":"consolidated Self iteration lessons"}
{"timestamp":"2026-05-13T04:32:10+01:00","topic":"self-body-material-contract","lesson":"Self's live body is a black void command core with sharp golden Fresnel, one gold core band, and nested PBR rail bands. Rails should be readable bands, not hairline emitters; bloom-driving rail emission rides a narrow inner-surface strip derived from the same shell/band field; gates are compact triple-band crossings, not pairwise shallow-intersection slabs. Literal loose eyes and dead diagnostic shapes do not belong in the contract.","files":["src/Aquarium.Epiphany/Shaders/D3D12SelfBody.hlsl","docs/epiphany-agent-sdf-visual-language.md","state/memory.json","state/evidence.jsonl"],"source":"consolidated Self visual review"}
{"timestamp":"2026-05-13T04:32:11+01:00","topic":"self-lighting-boundary","lesson":"Self may be the scene light, but visible Self surfaces must not add full primitive light radiance to themselves. Use the standard metallic-roughness PBR path for non-core surfaces, attenuate same-field direct lighting in shared PBR, and keep emission as controlled accents plus the custom void-core Fresnel. Diagnostic matte/flat material changes should be cut once the light-feedback source is isolated.","files":["src/Aquarium.Engine/Render/Shaders/D3D12SdfCommon.hlsli","src/Aquarium.Epiphany/Shaders/D3D12SelfBody.hlsl","state/memory.json","state/evidence.jsonl"],"source":"consolidated Self lighting/firefly work"}
{"timestamp":"2026-05-13T04:41:09+01:00","topic":"temporal-jitter-specular-fireflies","lesson":"Projection jitter was disabled because an earlier implementation made the whole frame visibly wobble. Re-enable it as a small sub-half-pixel Halton sequence with previous-jitter tracking, give the resolver a narrow SDF hot-current path so validated history can damp transient specular fireflies without relaxing travel/field/normal/coverage validation, and attenuate bloom when resolved scene luminance is lower than the raw current spike so current-frame bloom does not bypass TAA.","files":["src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Engine/Render/Shaders/D3D12Post.hlsl","docs/hlsl-renderer.md","docs/tsr-inspired-taa-spec.md","state/memory.json","state/evidence.jsonl"],"source":"user asked to give TAA teeth for Self rail highlights"}
{"timestamp":"2026-05-13T04:51:17+01:00","topic":"bloom-prefilter-firefly-clamp","lesson":"If a specular firefly exists for only one frame, resolving the source pixel after bloom is too late: the current-frame bloom pyramid has already spread the spike to neighbors. Clamp unsupported single-pixel HDR spikes in the bloom prefilter against local neighborhood luminance, then let temporal resolve and bloom attenuation handle the remaining supported highlights.","files":["src/Aquarium.Engine/Render/Shaders/D3D12Post.hlsl","docs/hlsl-renderer.md","docs/tsr-inspired-taa-spec.md","state/memory.json","state/evidence.jsonl"],"source":"user screenshot showed one-frame glowy fireflies after temporal resolve change"}
{"timestamp":"2026-05-13T05:42:00+01:00","topic":"self-orthonormal-orbital-frame","lesson":"Self rail bands should not be oriented by three independently normalized phase vectors. That can make lattice axes collapse into a shared plane, causing bands to stack before diverging again. Build each shell frame as a real orthonormal basis from a precessing pole, projected tangent seed, cross-product tangent, and spin around the pole so all three axes keep participating.","files":["src/Aquarium.Epiphany/Shaders/D3D12SelfBody.hlsl","state/memory.json","state/evidence.jsonl"],"source":"user screenshot showed Self bands temporarily stacking along one plane"}
{"timestamp":"2026-05-13T06:02:00+01:00","topic":"agent-organ-spec-domain-elaboration","lesson":"Role body specs should name each organ's governing spatial domain before listing features. Face uses mouth-flow aperture coordinates; Eyes uses lens-hemisphere/tangent-disk evidence directions; Body uses superellipsoid surface stress paths; Hands uses prolate tool coordinates around workDirection; Soul uses constraint-plane half-spaces; Life uses a cardioid shell plus logarithmic spiral continuity grammar. This keeps future implementations from falling back to vague primitives and decorative attachments.","files":["docs/epiphany-agent-sdf-visual-language.md","state/evidence.jsonl"],"source":"user requested elaboration pass after Self and Imagination raised the visual standard"}
{"timestamp":"2026-05-13T17:40:00+01:00","topic":"soul-crystal-local-shading","lesson":"Soul's first real shader uses constraint-plane/octahedral domain math for the verdict crystal and keeps crystal refraction/inner oath light as Soul-local shading: PMREM-based pseudo-refraction, facet/risk/finding material regions, and an inner glow. Do not expand the shared SdfSurface material packet for transmission until the renderer owns an actual scene-refraction or thickness contract; fake generic material fields are just costumes for missing architecture.","files":["src/Aquarium.Epiphany/Shaders/D3D12SoulAgent.hlsl","state/evidence.jsonl"],"source":"Soul implementation pass"}
{"timestamp":"2026-05-13T17:52:00+01:00","topic":"soul-geometry-before-material-tuning","lesson":"When Soul's octahedral constraint-plane geometry reads better than a later material experiment, restore the geometry instead of preserving churn. Make risk and finding features serve the crystal silhouette, then push crystal feel with stronger local caustic/rim/inner-light shading; if it still cannot read refractive, the next coherent step is a real renderer transmission/scene-sampling contract, not more ad hoc shared material flags.","files":["src/Aquarium.Epiphany/Shaders/D3D12SoulAgent.hlsl","state/evidence.jsonl"],"source":"user visual correction after Soul crystal material pass"}
{"timestamp":"2026-05-13T18:08:00+01:00","topic":"soul-organic-cut-plane-domain","lesson":"Soul's durable domain is not a rigid octahedron. It is a living crystal governed by an organic family of cutting planes: silhouette, panes, grooves, finding edges, risk seams, fractures, and inner light should read from the same warped plane field so the object feels grown and faceted, not decorated with axis-aligned octahedral markings.","files":["src/Aquarium.Epiphany/Shaders/D3D12SoulAgent.hlsl","state/evidence.jsonl"],"source":"user corrected the octahedral-domain interpretation using imagegen crystal reference"}
{"timestamp":"2026-05-13T18:18:00+01:00","topic":"soul-distance-material-authority","lesson":"Soul's raymarch distance must stay owned by the crystalline body silhouette. Cutting-plane seams, pane grooves, finding edges, and risk fractures are surface-domain material/light masks unless they intentionally change the silhouette; smooth-unioning those masks into the trace distance turns cracks into slabs and is SDF Jenga.","files":["src/Aquarium.Epiphany/Shaders/D3D12SoulAgent.hlsl","state/evidence.jsonl"],"source":"user screenshot showed escaped seam planes and called out SDF Jenga risk"}
{"timestamp":"2026-05-13T18:34:00+01:00","topic":"soul-facet-relief-not-decals","lesson":"Soul finding seams need real facet-domain relief, not flat decals. Use the organic cutting-plane field to displace the body surface: active facets lift outward along their plane normals, strongest around the equator, while finding/risk/fracture seams cut into that relief. Keep this as bounded body displacement, not smooth-unioned freestanding seam geometry.","files":["src/Aquarium.Epiphany/Shaders/D3D12SoulAgent.hlsl","state/evidence.jsonl"],"source":"user compared current Soul to reference art and identified extruded facets/fractured adjacent faces"}
{"timestamp":"2026-05-13T18:58:00+01:00","topic":"soul-seams-follow-facet-edges","lesson":"Soul seams must be measured against the facet edge graph, not raw cut-plane coordinates or free risk planes. Derive finding/risk/fracture distances from pairwise differences of the same offset face distances that define the crystal body; auxiliary risk planes may gate which edge segments light up, but they must not draw independent paths across facet interiors.","files":["src/Aquarium.Epiphany/Shaders/D3D12SoulAgent.hlsl","state/evidence.jsonl"],"source":"user screenshot showed real relief seams drifting across faces instead of following facet edges"}
{"timestamp":"2026-05-13T19:12:00+01:00","topic":"soul-edge-graph-selectivity","lesson":"Soul facet-edge seams need both active-face gating and restraint. A pairwise face equality is not a crystal edge unless both faces are jointly dominant at the surface; otherwise inactive planes create a wireframe lattice across faces. Promote only a small role-bearing subset of the active edge graph, and keep seam masks narrow so relief reads as crisp cut crystal rather than gummy tubing.","files":["src/Aquarium.Epiphany/Shaders/D3D12SoulAgent.hlsl","state/evidence.jsonl"],"source":"user screenshot showed all-over gummy seam lattice after edge snapping"}
{"timestamp":"2026-05-13T19:34:00+01:00","topic":"soul-crystal-domain-reset","lesson":"When Soul starts reading as warped packaging or a seam lattice, delete the clever cut-field tangle. The live model is a balanced faceted oath crystal: octahedral half-space silhouette, barycentric face coordinates for restrained relief, a small set of role-bearing seams, and local glass shading with transmission/reflection/inner oath light. Expressiveness belongs in face-domain relief and material, not in uncontrolled silhouette ownership.","files":["src/Aquarium.Epiphany/Shaders/D3D12SoulAgent.hlsl","state/evidence.jsonl"],"source":"user compared Soul against reference art and called the current code a lesson rather than sacred"}
{"timestamp":"2026-05-13T19:45:00+01:00","topic":"soul-facet-normal-authority","lesson":"Soul must shade like cut crystal, not thermoformed plastic. If relief participates in ray distance, do not let the finite-difference relief normal dominate broad facets; shade from the governing facet normal and blend the traced normal only near cuts. Transmission should support dark glass depth and inner oath light, not wash every face into milky white.","files":["src/Aquarium.Epiphany/Shaders/D3D12SoulAgent.hlsl","state/evidence.jsonl"],"source":"user screenshot showed Soul still reading as vacuum-formed packaging after domain reset"}
{"timestamp":"2026-05-13T20:00:00+01:00","topic":"soul-plane-intersection-crystal","lesson":"Soul seams are not unreasonable as geometry: build the crystal from explicit signed half-space planes, derive edges from adjacent active plane intersections, then extrude face interiors and cut narrow V-grooves on selected edge chains. Auxiliary gates may choose which edges glow, but the edge itself must come from the plane intersection graph. Broad shading uses the active plane normal; cut normals are secondary.","files":["src/Aquarium.Epiphany/Shaders/D3D12SoulAgent.hlsl","state/evidence.jsonl"],"source":"user asked for organic plane intersections with extruded faces and glowing groove centers"}
{"timestamp":"2026-05-13T20:18:00+01:00","topic":"soul-organic-plane-family","lesson":"Soul's plane-intersection crystal should not default back to symmetric octahedral sign pairs. Keep the half-space/active-edge architecture, but use an irregular family of constraint planes with varied offsets plus a few smaller trimming planes so the crystal reads as a living verdict object instead of an octahedron with minor perturbations.","files":["src/Aquarium.Epiphany/Shaders/D3D12SoulAgent.hlsl","state/evidence.jsonl"],"source":"user noted the plane-intersection model was right but the cutting planes still looked too octahedral"}
{"timestamp":"2026-05-13T20:56:00+01:00","topic":"isolated-agent-preview-loop","lesson":"Agent SDF iteration needs a renderer-owned visual feedback loop. Use the real D3D12 renderer to render one selected Epiphany SDF subject across several isolated camera views, then save final-frame PNGs for reference-art comparison. Preview-only isolation belongs in the preview render plan/shader, not in regular scene frame controls; do not duplicate SDF shader logic in a separate toy renderer.","files":["src/Aquarium.Epiphany.AgentPreview/Program.cs","src/Aquarium.Epiphany.AgentPreview/Shaders/D3D12AgentPreviewScene.hlsl","scripts/render-agent-preview.ps1","src/Aquarium.Engine/Render/D3D12Renderer.cs","state/map.yaml","state/evidence.jsonl"],"source":"user requested self-directed visual iteration, then caught preview isolation leaking into the normal client"}
{"timestamp":"2026-05-14T01:50:00+01:00","topic":"life-shell-domain","lesson":"Life reads as a nautilus only when the shell footprint, aperture, and ornament share one log-polar grammar. A plain ellipsoid volume with spiral material masks reads as wallpaper; a raw spiral-band volume tears the form apart. Use the log-polar footprint for the silhouette, round it into depth, and let ribs, seam glow, cracks, bowl, ember, and rim pearls sample that same domain.","files":["src/Aquarium.Epiphany/Shaders/D3D12LifeAgent.hlsl","state/life-agent-sdf-notes.md","state/map.yaml","state/evidence.jsonl"],"source":"self-directed Life SDF iteration against imagegen reference and user build screenshots"}
{"timestamp":"2026-05-14T02:55:00+01:00","topic":"life-no-detached-ornament","lesson":"Life's nautilus shell must be one connected shell domain. Detached hoops, bead trails, and separate ember spheres are a sign that ornament escaped the governing field. The aperture lip is the shell's opened edge; pearls must be relief/material on that lip field, and inner light should be chamber shading, not freestanding geometry.","files":["src/Aquarium.Epiphany/Shaders/D3D12LifeAgent.hlsl","state/life-agent-sdf-notes.md","state/evidence.jsonl"],"source":"user called out disconnected elements as lazy spatial-domain construction"}
{"timestamp":"2026-05-14T04:10:00+01:00","topic":"life-aperture-authority","lesson":"Life's aperture is not a boolean cut face. Render it as a concave inner shell surface integrated into the same log-polar/aperture domain, with the nacre lip owning the boundary and the warm chamber sitting behind it. If chamber material has priority over lip material, the shell reads as a flat sliced object.","files":["src/Aquarium.Epiphany/Shaders/D3D12LifeAgent.hlsl","state/life-agent-sdf-notes.md","state/evidence.jsonl"],"source":"user build screenshots showed the aperture as a flat segmented golden cut"}
{"timestamp":"2026-05-14T04:55:00+01:00","topic":"life-swept-whorl-field","lesson":"Life must not preserve the ellipsoid-plus-aperture lineage. Build the shell from a swept whorl field: log-polar phase defines the growing spiral sweep, radial growth thickens the tube until whorls overlap into a continuous mass, and lip/ribs/cracks/pearls/chamber light are masks on that same domain. A welded disc or separate cup is a failed model, not a feature to polish.","files":["src/Aquarium.Epiphany/Shaders/D3D12LifeAgent.hlsl","state/life-agent-sdf-notes.md","state/evidence.jsonl"],"source":"user supplied supershape shell reference and called out failure enshrinement"}
{"timestamp":"2026-05-14T05:55:00+01:00","topic":"life-nautilus-source-port","lesson":"For Life, the durable model is the Nautilus.glsl logarithmic shell solve: find the nearest exponential spiral boundary in cylindrical space, use its u/v/w section coordinates for wall thickness, septa, ribs, aperture/cut, pearls, cracks, and materials. A loose phase field plus welded opening is not a coherent shell."}
{"timestamp":"2026-05-14T13:38:00+01:00","topic":"life-spec-over-reference-port","lesson":"Do not recreate a reference shader when the task is to learn its spatial-domain mapping. For Life, Nautilus.glsl is a coordinate lesson; the spec authority is a protective revolved seed/cardioid shell with a visible ember, logarithmic seam, and memory beads sharing one spiral domain."}
{"timestamp":"2026-05-14T14:38:00+01:00","topic":"life-shell-authority","lesson":"Life's shell silhouette must be a filled protective mass; letting the logarithmic spiral own body distance creates hollow coils, fins, or mechanical mouths. Use the spiral domain for raised ribs, beads, seam, and scar material only. Check front plus oblique previews against the concept before accepting a pass."}
{"timestamp":"2026-05-14T15:32:00+01:00","topic":"life-balanced-whorl-domain","lesson":"Life needs both sides of the nautilus grammar: a log-spiral whorl solve must physically shape the shell, but it cannot be the only body authority or the form collapses into a hollow C-shell. Union the whorl with a smaller same-domain backing mass, then derive aperture lip, chamber gold, ember reveal, raised ribs, and pearl beads from the shared spiral/aperture fields.","files":["src/Aquarium.Epiphany/Shaders/D3D12LifeAgent.hlsl","state/life-agent-sdf-notes.md","state/evidence.jsonl"],"source":"user rejected the egg lineage and required repeated restart until the spiral shell manifests as geometry"}
{"timestamp":"2026-05-14T16:31:00+01:00","topic":"life-curve-first-build","lesson":"When rebuilding Life, do not start by tuning the full organ. First make the log-spiral domain read as a naked curve: ember at the core, roughly two revolutions, and the wide mouth-side lip termination. Only after that curve reads should shell inflation, aperture carving, ember reveal, ribs, and pearl beads be layered back on the same solved domain.","files":["src/Aquarium.Epiphany/Shaders/D3D12LifeAgent.hlsl","state/life-agent-sdf-notes.md","state/evidence.jsonl"],"source":"user corrected the iteration process: build the log spiral one step at a time instead of doing everything at once"}
{"lesson":"Shader hot reload edits must update the running process slot Render/Shaders files so D3D12Renderer can rebuild pipelines from its existing shader source root. Client assembly live reload does not change renderer shaderSourceRoot, so treating .hlsl/.hlsli edits as assembly reloads leaves the renderer watching stale slot files.","timestamp":"2026-05-15T17:48:35.6220956+01:00","files":["scripts/dev-watch.ps1","src/Aquarium.Engine/Render/D3D12Renderer.cs"],"topic":"shader-hot-reload-slot-transport"}
{"timestamp":"2026-05-17T23:28:00+01:00","topic":"non-epiphany-demo-client","lesson":"A reusable Aquarium engine boundary needs a real non-Epiphany client, not only a minimal smoke sample. Zyphos exercises the same host, reload transport, UI, bloom, and SDF proxy path with its own planetary scene and shader domain, while dev-reload/dev-watch accept -ClientProject so client selection stays tooling-owned instead of hardcoded Epiphany lore.","files":["src/Aquarium.Zyphos/Aquarium.Zyphos.csproj","src/Aquarium.Zyphos/ZyphosRuntime.cs","scripts/dev-reload.ps1","scripts/dev-watch.ps1","README.md"],"source":"user asked for a real planetary-scale demo named Zyphos to support the Aquarium/Epiphany split"}
{"timestamp":"2026-05-17T23:58:00+01:00","topic":"zyphos-eusocial-sync","lesson":"Zyphos simulates the neighboring Eusocial Interbeing setting, but canon authority stays in the vault. Aquarium may record render constraints and demo questions in docs/zyphos-eusocial-sync.md; worldbuilding answers should flow through the vault's Zyphos Simulation Brief before shader or terrain choices become setting claims.","files":["docs/zyphos-eusocial-sync.md","state/map.yaml","state/scratch.md","E:\\Projects\\Eusocial Interbeing\\Eusocial Interbeing\\World\\Zyphos Simulation Brief.md"],"source":"user asked to start a conversation with the Eusocial Interbeing neighbor repo for Zyphos worldbuilding"}
{"timestamp":"2026-05-17T23:32:49+01:00","topic":"cube-sphere-fractal-brush-research","lesson":"Planetary terrain should use a cube-sphere/QSC-family six-face quadtree domain instead of lat-long; projection candidates should be measured rather than assumed, with tangent, fifth-order odd polynomial, and COBE/QSC-style bivariate warps as the first comparison set. Multiscale terrain and agent/body detail should converge on bounded IFS brush grammars with compact-support anisotropic shaped Gaussian-style envelopes, borrowing covariance/binning/LOD discipline from EWA and 3D Gaussian splatting without importing unbounded Gaussian cost or radiance-field machinery by default.","files":["research/rendering/cube-sphere-fractal-brushes.md","state/map.yaml","state/memory.json","state/scratch.md"],"sources":["https://proj.org/en/stable/operations/projections/qsc.html","https://ntrs.nasa.gov/citations/19810002572","https://jcgt.org/published/0007/02/01/paper.pdf","https://arxiv.org/abs/2308.04079","https://experts.illinois.edu/en/publications/sphere-tracing-a-geometric-method-for-the-antialiased-ray-tracing/","https://vcg.seas.harvard.edu/publications/20011001-ewa-volume-splatting"]}
{"timestamp":"2026-05-17T23:48:00+01:00","topic":"vibegeometry-ifs-csg-dsl-distillation","lesson":"VibeGeometry's spatial-mapping work says Aquarium's IFS brush DSL should emit semantic claims and preserve an ownership tree before backend lowering. The useful CSG-tree pattern is grammar/rules -> semantic solid/void/material claims with frames/tags/seeds/captures -> boolean ownership tree with union/subtract/common and node bounds -> flattened brush tables, SDF shader code, splat batches, or offline summaries as compiled verdicts. Local frames, named fields, baton outputs, scatter layers, authoring handles, deterministic variation, and demand frontiers should be first-class; anonymous brush bags and early shader flattening would destroy the meaning needed for project-wide terrain and agent-body migration.","files":["research/rendering/cube-sphere-fractal-brushes.md","state/map.yaml","state/memory.json","state/scratch.md"],"sources":["E:\\Projects\\VibeGeometry\\docs\\research\\procedural-doctrine.md","E:\\Projects\\VibeGeometry\\docs\\research\\dream-machine-grammar.md","E:\\Projects\\VibeGeometry\\docs\\research\\realtime-csg-doctrine.md","E:\\Projects\\VibeGeometry\\crates\\vg_grammar\\src","E:\\Projects\\VibeGeometry\\crates\\vg_csg\\src\\tree.rs","E:\\Projects\\VibeGeometry\\crates\\vg_csg\\src\\frontier.rs"]}
{"timestamp":"2026-05-18T00:05:00+01:00","topic":"ifs-lod-contribution-cache","lesson":"Aquarium's fractal brush LOD should choose a stable hierarchy cut from cached node summaries, not score every leaf every frame. Use clipmap-style nested caches for terrain fields, Nanite-style projected-error cuts for form hierarchy, and Gaussian/octree-style projected anisotropic footprint scoring for brush envelopes. Each IFS node should cache bounds, max form/material error, coverage or gradient bounds, estimated cost, previous contribution score, residency state, and summary/child payload handles; parent summaries must remain renderable fallbacks while child payloads stream or fade in. Fade payload contribution, not signed-distance safety, and require debug views for projected error, score, selected depth, residency, fade, and cost before recursive detail grows.","files":["research/rendering/cube-sphere-fractal-brushes.md","state/map.yaml","state/memory.json","state/scratch.md"],"sources":["https://hhoppe.com/proj/gpugcm/","https://hhoppe.com/geomclipmap.pdf","https://hhoppe.com/gpugcm.pdf","https://advances.realtimerendering.com/s2021/Karis_Nanite_SIGGRAPH_Advances_2021_final.pdf","https://arxiv.org/abs/2403.17898"]}
{"timestamp":"2026-05-18T00:14:00+01:00","topic":"ifs-lod-online-estimator","lesson":"The IFS contribution cache must refresh weights probabilistically under a per-frame update budget, not recompute every branch or greedily update only current winners. Treat node scores as online estimates with mean contribution, variance/uncertainty, sample count, sample age, confidence, and decay; visible, near-threshold, stale, high-uncertainty, and exploratory nodes must all retain nonzero update probability so the cache converges instead of freezing wrong beliefs. A later learned predictor can rank expected contribution, uncertainty, and update priority from projected footprint, view state, history, cost, and occasional high-quality probes, but conservative node summaries remain the non-negotiable safety authority for SDF marching and visibility.","files":["research/rendering/cube-sphere-fractal-brushes.md","state/map.yaml","state/memory.json","state/scratch.md"],"source":"user clarified that contribution weights need probabilistic per-frame updates and convergence, entering machine-learning territory for maximum fidelity"}
{"timestamp":"2026-05-18T00:32:00+01:00","topic":"fractal-brush-architecture-plan","lesson":"The research is now consolidated into an architecture: client intent feeds domain roots, semantic IFS brush grammar, an ownership tree, node summaries, a contribution cache/residency scheduler, backend packets, renderer passes, and debug/evidence. The design explicitly trades CPU scheduling, RAM summaries/estimator state, SSD payload pages/probe history, and GPU selected-cut evaluation. Its job-interview-grade credibility comes from module boundaries and test seams: contracts, pure CPU fractal core, D3D12 backend, client adapters, deterministic mocks for clocks/random/probes/payload stores/budgets/debug sinks, shader parity tests, and performance fixtures. The first implementation slice is cube-face projection harness, shaped 2D brush envelope, semantic claim/tree structs, flattening to the current height brush pass, and debug overlays before recursive detail is allowed to expand.","files":["research/rendering/fractal-brush-architecture-plan.md","research/rendering/cube-sphere-fractal-brushes.md","state/map.yaml","state/memory.json","state/scratch.md"],"source":"user asked to consolidate the research into an architecture plan and then clarified that interview-grade means maintainable modularity tied to extensive unit testing and mock boundaries"}
{"timestamp":"2026-05-18T01:05:00+01:00","topic":"fractal-brush-implementation-roadmap","lesson":"The fractal brush architecture now has an actionable execution roadmap separate from the architecture essay. The roadmap names module targets, mock seams, phase-by-phase tasks, tests, exit gates, and cut lines. The first work packet is intentionally small: create Aquarium.Engine.Fractal plus tests, add cube-face/tile key types, implement identity and tangent projection candidates, add an area distortion sampler, face-edge tests, and a projection report before any recursive detail, streaming, or learned scoring work begins.","files":["research/rendering/fractal-brush-implementation-roadmap.md","state/map.yaml","state/memory.json","state/scratch.md"],"source":"user asked whether an actionable roadmap existed and requested one if not"}
{"timestamp":"2026-05-18T02:46:00+01:00","topic":"fractal-cube-sphere-projection-default","lesson":"The first executable fractal slice chooses tangent cube-sphere projection as the initial default over direct normalize projection. Both are seam-compatible with the shared cube-face orientation, but the checked sampler at 16x16 per face reports tangent mean absolute relative area error around 0.076 and RMS around 0.089 versus normalize mean absolute relative area error around 0.316 and RMS around 0.378. Keep the projection harness as the authority before adding polynomial or QSC candidates.","files":["src/Aquarium.Engine.Fractal/Projection/TangentCubeSphereProjection.cs","src/Aquarium.Engine.Fractal/Projection/ProjectionDistortionSampler.cs","research/rendering/fractal-projection-report.md","tests/Aquarium.Engine.Fractal.Tests/ProjectionTests.cs"],"source":"first fractal implementation slice measured cube-sphere projection distortion and committed the report as a test-pinned artifact"}
{"timestamp":"2026-05-18T03:04:00+01:00","topic":"fractal-brush-envelope-reference","lesson":"The shaped 2D brush envelope now has a pure CPU reference before renderer integration. `FractalBrushEnvelope2D` owns compact elliptical support, anisotropic radii, rotation, truncated Gaussian-style falloff, shape power, conservative axis-aligned bounds, and a packed packet row. Future HLSL and height-field lowering should match this evaluator instead of redefining envelope semantics in shader code.","files":["src/Aquarium.Engine.Fractal/Brushes/FractalBrushEnvelope2D.cs","src/Aquarium.Engine.Fractal/Brushes/FractalBrushEnvelope2DPacket.cs","tests/Aquarium.Engine.Fractal.Tests/FractalBrushEnvelope2DTests.cs","research/rendering/fractal-brush-implementation-roadmap.md"],"source":"second fractal implementation slice established the shaped brush envelope math and support tests"}
{"timestamp":"2026-05-18T03:31:00+01:00","topic":"height-field-shaped-envelope-lowering","lesson":"The live height-field brush contract now carries shaped-envelope fields without breaking legacy circular brush callers: Radius remains X radius and support fallback, RadiusY opts into anisotropy, RotationRadians rotates the local ellipse, EnvelopeFalloff switches the renderer from legacy power pulse to compact Gaussian-style support, and Power becomes the shaped envelope exponent in that mode. The D3D12 height-field shader and Epiphany CPU height evaluator now share the same compact-envelope formula; keep future terrain brush lowering on this path until semantic claims replace direct brush authoring.","files":["src/Aquarium.Engine.Contracts/Render/AquariumRenderPlan.cs","src/Aquarium.Engine/Render/Shaders/D3D12HeightField.hlsl","src/Aquarium.Engine/Render/Features/D3D12HeightFieldBrushConstants.cs","src/Aquarium.Epiphany/EpiphanySceneBuilder.cs","tests/Aquarium.Engine.Fractal.Tests/FractalBrushEnvelope2DTests.cs"],"source":"third fractal implementation slice lowered shaped envelope fields into the existing height-field brush path while preserving old circular brush defaults"}
{"timestamp":"2026-05-18T03:55:00+01:00","topic":"fractal-semantic-contracts-first-slice","lesson":"The fractal system now has portable semantic rows before backend lowering: stable keys, domains, brush claims, operation nodes, summaries, contribution state, and selected-cut rows live in contracts, while the pure fractal core owns deterministic cube-tile grammar keys and a flat-union ownership tree builder. This is deliberately not a full CSG kernel yet; it is the first authority boundary that keeps authored claims visible before renderer packets flatten them.","files":["src/Aquarium.Engine.Contracts/Fractal/AquariumFractalContracts.cs","src/Aquarium.Engine.Fractal/Grammar/FractalStableKeyBuilder.cs","src/Aquarium.Engine.Fractal/Grammar/FractalOwnershipTreeBuilder.cs","tests/Aquarium.Engine.Fractal.Tests/FractalGrammarContractTests.cs"],"source":"fourth fractal implementation slice established semantic claim and ownership-tree contract rows"}
{"timestamp":"2026-05-18T02:36:48+01:00","topic":"face-realtime-voice-first-slice","lesson":"Aquarium's first Face voice slice keeps ownership narrow: the engine owns a generic queued PCM playback lane, while Epiphany owns a native Face realtime session controller and persists only loopback URI, thread id, voice, and prompt in CultCache live state. The current transport is explicitly a Codex app-server WebSocket JSON-RPC compatibility edge for text input and streamed audio output, not full microphone/WebRTC capture yet. Speech remains an ephemeral Face surface and must not mutate durable memory, evidence, project state, or code authority automatically.","files":["src/Aquarium.Engine.Contracts/Audio/AquariumAudio.cs","src/Aquarium.Engine.Contracts/AquariumRuntimeContracts.cs","src/Aquarium.Engine/Audio/AquariumSynthHost.cs","src/Aquarium.Epiphany/Voice/RealtimeFaceVoiceSession.cs","src/Aquarium.Epiphany/AquariumRuntime.cs","src/Aquarium.Epiphany/State/AquariumLiveState.cs","state/map.yaml"],"source":"user asked to start Aquarium-Engine work on Codex realtime voice for talking to Faces inside Aquarium"}
{"timestamp":"2026-05-18T04:07:00+01:00","topic":"fractal-height-claim-lowering","lesson":"Semantic height claims now lower into the live shaped height-field brush contract through `FractalHeightBrushCompiler`. This keeps the current renderer path useful without making the renderer own grammar semantics: claims remain authored meaning, height brushes remain backend output, and non-height payloads fail fast instead of sneaking through a height-only adapter.","files":["src/Aquarium.Engine.Fractal/Brushes/FractalHeightBrushCompiler.cs","tests/Aquarium.Engine.Fractal.Tests/FractalHeightBrushCompilerTests.cs","research/rendering/fractal-brush-implementation-roadmap.md"],"source":"fifth fractal implementation slice added the first semantic-claim-to-renderer-packet lowering path"}
{"timestamp":"2026-05-18T04:22:00+01:00","topic":"fractal-node-summary-first-slice","lesson":"Flat semantic ownership trees now produce conservative node summaries. The first summary builder carries node bounds, sum-of-absolute height amplitude as max height error, a material-delta placeholder, estimated claim cost, and descendant count. This is intentionally conservative rather than clever, giving future LOD/cache work a renderable parent fallback before child refinement or eviction exists.","files":["src/Aquarium.Engine.Fractal/Grammar/FractalSummaryBuilder.cs","tests/Aquarium.Engine.Fractal.Tests/FractalSummaryBuilderTests.cs","research/rendering/fractal-brush-implementation-roadmap.md"],"source":"sixth fractal implementation slice established parent summary rows for semantic brush trees"}
{"timestamp":"2026-05-18T04:36:00+01:00","topic":"fractal-contribution-score-first-slice","lesson":"Contribution scoring now has a stable-keyed state table and a projected-error scorer. The first score is intentionally simple: conservative height error times projected pixels per world unit divided by estimated node cost. This gives LOD selection a deterministic, testable pressure signal before hysteresis, selected cuts, residency, or online estimation are layered in.","files":["src/Aquarium.Engine.Fractal/Lod/FractalContributionTable.cs","src/Aquarium.Engine.Fractal/Lod/FractalProjectedErrorScorer.cs","tests/Aquarium.Engine.Fractal.Tests/FractalContributionTests.cs"],"source":"seventh fractal implementation slice started the LOD contribution cache with deterministic scoring tests"}
{"timestamp":"2026-05-18T04:50:00+01:00","topic":"fractal-selected-cut-first-slice","lesson":"Projected contribution scores now compile into budgeted selected-cut rows. The first builder sorts summaries by score, clamps against estimated cost, emits fade weights, and requests children only when score crosses a threshold. This gives later residency and stochastic estimation a small deterministic target instead of mixing traversal policy into renderer code.","files":["src/Aquarium.Engine.Fractal/Lod/FractalSelectedCutBuilder.cs","tests/Aquarium.Engine.Fractal.Tests/FractalSelectedCutBuilderTests.cs","research/rendering/fractal-brush-implementation-roadmap.md"],"source":"eighth fractal implementation slice added selected-cut planning under a simple cost budget"}
{"timestamp":"2026-05-18T05:06:00+01:00","topic":"fractal-stochastic-cache-first-slice","lesson":"The contribution cache now has online estimator updates and a stochastic update scheduler. Estimator state updates mean, variance, confidence, sample count, sample age, and residency; scheduler probability keeps baseline exploration, adds pressure for visible, near-threshold, stale, uncertain, and low-confidence nodes, and remains deterministic under `IFractalRandom` for tests. This is the first bounded convergence mechanism before learned scoring is allowed anywhere near the renderer.","files":["src/Aquarium.Engine.Fractal/Lod/FractalContributionEstimator.cs","src/Aquarium.Engine.Fractal/Lod/FractalStochasticUpdateScheduler.cs","tests/Aquarium.Engine.Fractal.Tests/FractalStochasticUpdateTests.cs"],"source":"ninth fractal implementation slice added probabilistic contribution updates with deterministic mock boundaries"}
{"timestamp":"2026-05-18T05:20:00+01:00","topic":"fractal-residency-simulation-first-slice","lesson":"Selected cuts now pass through a residency planner with an `IFractalPayloadStore` mock boundary. Resident nodes render directly; missing nodes render their parent summary fallback and enqueue payload requests only when the selected cut asks for children. This keeps frame traversal nonblocking and makes SSD/GPU residency a replaceable resource policy instead of hidden renderer state.","files":["src/Aquarium.Engine.Fractal/Lod/IFractalPayloadStore.cs","src/Aquarium.Engine.Fractal/Lod/FractalResidencyPlanner.cs","tests/Aquarium.Engine.Fractal.Tests/FractalResidencyPlannerTests.cs","research/rendering/fractal-brush-implementation-roadmap.md"],"source":"tenth fractal implementation slice simulated missing/resident payload behavior before real streaming"}
{"timestamp":"2026-05-18T05:31:00+01:00","topic":"fractal-pipeline-fixture","lesson":"The first fractal architecture spine now composes end to end in a test fixture: cube tile stable key -> semantic domain/claim -> ownership tree -> conservative summary -> selected cut -> residency fallback/request -> shaped height brush compiler. Keep extending this fixture as the interview-grade proof that module boundaries are real and not prose taped to unrelated helpers.","files":["tests/Aquarium.Engine.Fractal.Tests/FractalPipelineFixtureTests.cs"],"source":"eleventh fractal implementation slice added an end-to-end composition test for the new module network"}
{"timestamp":"2026-05-18T05:49:00+01:00","topic":"fractal-dsl-first-slice","lesson":"Aquarium now has a first line-oriented fractal DSL that compiles into semantic ownership trees instead of renderer packets. The DSL declares a cube tile domain, direct shaped `height` claims, and recursive `ifs` emitters with deterministic seeded branching. Keep this syntax small until Zyphos proves it visually; the language authority is semantic claims, not shader-side brush bags.","files":["src/Aquarium.Engine.Fractal/Grammar/FractalDslCompiler.cs","tests/Aquarium.Engine.Fractal.Tests/FractalDslCompilerTests.cs","research/rendering/fractal-brush-implementation-roadmap.md"],"source":"user explicitly wanted to express a fractal world in Aquarium's own DSL and see it rendered"}
{"timestamp":"2026-05-18T06:04:00+01:00","topic":"zyphos-fractal-dsl-render-proof","lesson":"Zyphos now renders its height field from Aquarium's fractal DSL instead of a hand-authored circular brush. `ZyphosFractalTerrain` owns the demo grammar, compiles it through `FractalDslCompiler` into a semantic ownership tree, and lowers claims to shaped height brushes through `FractalHeightBrushCompiler`. This is the first visible proof path for authoring a fractal world in Aquarium's own DSL and seeing it inside the engine.","files":["src/Aquarium.Zyphos/ZyphosFractalTerrain.cs","src/Aquarium.Zyphos/ZyphosSceneBuilder.cs","src/Aquarium.Zyphos/ZyphosRuntime.cs","tests/Aquarium.Engine.Fractal.Tests/ZyphosFractalTerrainTests.cs"],"source":"user emphasized wanting to express a fractal world in the DSL and see it rendered in engine"}
{"timestamp":"2026-05-18T06:18:00+01:00","topic":"fractal-debug-dump","lesson":"Fractal worlds now have a text debug dump that reports domain, nodes, claims, summaries, and selected cuts. Zyphos exposes this through the `zyphos-fractal` command so the rendered DSL terrain can be inspected as authored semantic rows and LOD decisions instead of inferred from pixels alone.","files":["src/Aquarium.Engine.Fractal/Debug/FractalDebugDump.cs","src/Aquarium.Zyphos/ZyphosFractalTerrain.cs","src/Aquarium.Zyphos/ZyphosRuntime.cs","tests/Aquarium.Engine.Fractal.Tests/FractalDebugDumpTests.cs"],"source":"observability pass after wiring Zyphos to the fractal DSL renderer path"}
{"timestamp":"2026-05-18T06:29:00+01:00","topic":"zyphos-height-brush-table-budget","lesson":"Zyphos' first DSL terrain grammar must currently emit no more than eight height brushes because `D3D12HeightFieldBrushConstants.MaxBrushCount` is still 8. Do not let the demo silently author more claims than the renderer draws; either keep the visible grammar within the fixed table or make the height brush table dynamic before increasing recursive density.","files":["src/Aquarium.Zyphos/ZyphosFractalTerrain.cs","tests/Aquarium.Engine.Fractal.Tests/ZyphosFractalTerrainTests.cs","src/Aquarium.Engine/Render/Features/D3D12HeightFieldBrushConstants.cs"],"source":"runtime proof pass noticed the DSL emitted 12 claims while the current height brush constant table renders only 8"}
{"timestamp":"2026-05-18T06:43:00+01:00","topic":"height-brush-table-sixteen","lesson":"The fixed D3D12 height-field brush table now carries 16 brushes, so Zyphos can render its 12-claim DSL terrain without silent truncation. This is still a bounded interim table, not the final streaming brush backend; before raising recursive density further, move height brush packets to a structured buffer or selected-cut page stream.","files":["src/Aquarium.Engine/Render/Features/D3D12HeightFieldBrushConstants.cs","src/Aquarium.Engine/Render/Shaders/D3D12HeightField.hlsl","src/Aquarium.Zyphos/ZyphosFractalTerrain.cs","tests/Aquarium.Engine.Fractal.Tests/ZyphosFractalTerrainTests.cs"],"source":"follow-up after detecting the fixed eight-brush table clipped the first Zyphos DSL terrain"}
{"timestamp":"2026-05-18T06:58:00+01:00","topic":"aquageo-world-patch-files","lesson":"Aquarium fractal world DSL patches should be authored as `.aquageo` content files, copied into the client output, and loaded from disk at runtime. Zyphos' first terrain proof now loads `Worlds/zyphos-first-fractal-terrain.aquageo`; do not keep demo grammars embedded as fallback strings because that hides asset pipeline failures.","files":["src/Aquarium.Zyphos/Worlds/zyphos-first-fractal-terrain.aquageo","src/Aquarium.Zyphos/ZyphosFractalTerrain.cs","src/Aquarium.Zyphos/Aquarium.Zyphos.csproj","tests/Aquarium.Engine.Fractal.Tests/ZyphosFractalTerrainTests.cs"],"source":"user asked to load the world DSL patch via file and call it .aquageo"}
{"timestamp":"2026-05-18T07:16:00+01:00","topic":"zyphos-nested-domains-and-umbros-authority","lesson":"Zyphos' `.aquageo` patch now declares solar, orbital, planetary, and lat/long domains before terrain tiles, giving fractal DSL nodes explicit nested reference frames. The Zyphos/Umbros binary constants live in `ZyphosUmbrosSystem`: Umbros is a fixed-sky 0.9-radius twin at 8 Zyphos radii, while the dim primary star phase moves through the Zyphos-local frame for first-pass eclipse cadence. Do not reintroduce moon language or hidden orbital constants in shader files.","files":["src/Aquarium.Zyphos/Worlds/zyphos-first-fractal-terrain.aquageo","src/Aquarium.Zyphos/ZyphosUmbrosSystem.cs","src/Aquarium.Zyphos/Shaders/D3D12ZyphosPlanet.hlsl","src/Aquarium.Zyphos/Shaders/D3D12ZyphosUmbros.hlsl","tests/Aquarium.Engine.Fractal.Tests/ZyphosUmbrosSystemTests.cs","tests/Aquarium.Engine.Fractal.Tests/ZyphosFractalTerrainTests.cs"],"source":"user asked to express nested solar/orbital/planetary/lat-long domains and verify Zyphos/Umbros/parent-star modeling against worldbuilding docs"}
{"timestamp":"2026-05-18T07:31:00+01:00","topic":"fractal-domain-graph-validation","lesson":"Nested fractal domains are now validated by `FractalDomainGraph`, which owns duplicate-key checks, parent existence, cycle detection, and root-to-leaf path queries. Keep domain topology in this grammar-layer boundary until real transform math exists; do not scatter parent lookup or reference-frame assumptions through render code.","files":["src/Aquarium.Engine.Fractal/Grammar/FractalDomainGraph.cs","src/Aquarium.Engine.Fractal/Grammar/FractalOwnershipTree.cs","src/Aquarium.Engine.Fractal/Debug/FractalDebugDump.cs","tests/Aquarium.Engine.Fractal.Tests/FractalDslCompilerTests.cs","tests/Aquarium.Engine.Fractal.Tests/FractalDebugDumpTests.cs"],"source":"follow-up slice after `.aquageo` gained solar/orbital/planetary/lat-long domains"}
{"timestamp":"2026-05-18T08:03:00+01:00","topic":"zyphos-camera-composer-and-space-view","lesson":"Zyphos should not render the legacy height-field Grid in the space view. Aquarium frames now carry a 3D camera target and scene flags so clients can disable the height-field trace and request a starfield background. `ZyphosCameraComposer` separates tracked subject from parent composition anchor, borrowing the Cinemachine idea of composer-owned framing rather than embedding camera aim in world objects.","files":["src/Aquarium.Engine.Contracts/AquariumFrame.cs","src/Aquarium.Engine.Contracts/Render/AquariumRenderPlan.cs","src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Engine/Render/Shaders/D3D12Scene.hlsl","src/Aquarium.Zyphos/ZyphosCameraComposer.cs","src/Aquarium.Zyphos/ZyphosRuntime.cs","src/Aquarium.Zyphos/ZyphosSceneBuilder.cs"],"source":"user saw the Zyphos screenshot, rejected the visible Grid, asked for starry background and camera locks informed by Cinemachine composer behavior"}
{"timestamp":"2026-05-18T08:22:00+01:00","topic":"debug-ui-panel-scrolling","lesson":"DebugUi panels now own body scrolling, body clipping, and a visible scrollbar when controls exceed the viewport. Individual controls can still own local scrolling for text boxes and option popups, but panel overflow is an engine-level invariant so client panels cannot spill out of their frame.","files":["src/Aquarium.Engine/Render/Ui/DebugUi.cs"],"source":"user reported Zyphos UI did not fit its panel and expected all panels to have scrollbars"}
{"timestamp":"2026-05-18T04:09:10+01:00","topic":"face-voice-proximity-routing","lesson":"Face voice is now routed through typed endpoint rows instead of one global session. `FaceVoiceRouter` selects the active endpoint by cursor/listener proximity when auto-route is enabled, while each `FaceVoiceEndpoint` owns its thread id, voice, prompt, enabled state, and XY anchor before delegating transport to `RealtimeFaceVoiceSession`. This keeps multi-Face speech routing explicit and spatial, while the next impurity to cut is manual XY placement: endpoint anchors should bind to real Face/body visual projections once those projections are exposed as a CPU-visible contract.","files":["src/Aquarium.Epiphany/Voice/FaceVoiceRouter.cs","src/Aquarium.Epiphany/Voice/FaceVoiceEndpoint.cs","src/Aquarium.Epiphany/AquariumRuntime.cs","src/Aquarium.Epiphany/State/AquariumLiveState.cs","state/map.yaml"],"source":"user asked to hook the voice path up while keeping in mind several Faces selected by spatial proximity"}
{"timestamp":"2026-05-18T04:32:00+01:00","topic":"face-rumination-output-spatialization","lesson":"Face voice proximity is an addressing rule, not a speech-permission rule. Enabled Face endpoints can now run concurrently via `StartAll`, so active rumination loops may emit speech regardless of listener proximity; proximity updates only output gain and stereo pan. AquariumAudioDocument now carries per-chunk left/right gains and WasapiAudioDevice mixes stereo when the output device supports it, degrading to mono by averaging channels.","files":["src/Aquarium.Engine.Contracts/Audio/AquariumAudio.cs","src/Aquarium.Engine/Audio/WasapiAudioDevice.cs","src/Aquarium.Epiphany/Voice/RealtimeFaceVoiceSession.cs","src/Aquarium.Epiphany/Voice/FaceVoiceEndpoint.cs","src/Aquarium.Epiphany/Voice/FaceVoiceRouter.cs","src/Aquarium.Epiphany/AquariumRuntime.cs","state/map.yaml"],"source":"user clarified Faces should speak from active rumination loops regardless of proximity, using spatial audio only to indicate distance"}
{"timestamp":"2026-05-18T08:32:00+01:00","topic":"client-floating-navigation-panels","lesson":"Client UI panels are folded into the renderer debug tab strip by default; only panels that opt into proximity fading render as positioned floating overlays. Floating overlays support optional right anchoring via negative left offsets and proximity fade to 10% opacity. Zyphos uses this to expose a right-side Navigation panel without spawning ordinary client debug tabs as extra windows.","files":["src/Aquarium.Engine.Contracts/Ui/AquariumUi.cs","src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Engine/Render/DirectWriteOverlay.cs","src/Aquarium.Engine/Render/Ui/DebugUi.cs","src/Aquarium.Zyphos/ZyphosRuntime.cs"],"source":"user expected a right-side fading navigation panel with a foldout hierarchy of spatial domains, then rejected normal debug tabs appearing as floating panels"}
{"timestamp":"2026-05-18T04:50:36+01:00","topic":"zyphos-domain-navigation","lesson":"The Zyphos navigation panel must be a real domain navigator, not toggles masquerading as hierarchy. AquariumUiTreeItem provides generic selectable disclosure rows; Zyphos owns a spatial domain catalog keyed to solar/orbital/planetary/surface/tile domains; the camera composer derives tracked center, parent pivot, and effective distance from the selected domain key. Mouse drag/wheel now drives orbit/zoom for the active spatial frame.","files":["src/Aquarium.Engine.Contracts/Ui/AquariumUi.cs","src/Aquarium.Engine/Render/Ui/DebugUi.cs","src/Aquarium.Zyphos/ZyphosSpatialDomainCatalog.cs","src/Aquarium.Zyphos/ZyphosCameraComposer.cs","src/Aquarium.Zyphos/ZyphosRuntime.cs","tests/Aquarium.Engine.Fractal.Tests/ZyphosCameraComposerTests.cs","state/map.yaml","state/memory.json"],"source":"user rejected undercooked Zyphos navigation panel and demanded selectable domain camera modes plus mouse navigation"}
{"timestamp":"2026-05-18T05:13:27+01:00","topic":"zyphos-umbros-fractal-stress-domains","lesson":"Zyphos and Umbros should both be first-class selectable fractal bodies. The `.aquageo` patch now declares Umbros lat/long plus multiple cube-tile children for both bodies and emits 31 shaped brush claims. D3D12 height-field brush constants were expanded to a deliberate 32-entry fixed table so stress data is not silently clipped at 16. Planet and Umbros SDF shaders also add cheap bounded quadtree-style object-space relief for layered geometry independent of the flattened 2D brush backend.","files":["src/Aquarium.Zyphos/Worlds/zyphos-first-fractal-terrain.aquageo","src/Aquarium.Zyphos/ZyphosSpatialDomainCatalog.cs","src/Aquarium.Engine/Render/Features/D3D12HeightFieldBrushConstants.cs","src/Aquarium.Engine/Render/Shaders/D3D12HeightField.hlsl","src/Aquarium.Zyphos/Shaders/D3D12ZyphosPlanet.hlsl","src/Aquarium.Zyphos/Shaders/D3D12ZyphosUmbros.hlsl","tests/Aquarium.Engine.Fractal.Tests/ZyphosFractalTerrainTests.cs","tests/Aquarium.Engine.Fractal.Tests/ZyphosSpatialDomainCatalogTests.cs"],"source":"user asked for Zyphos and Umbros selectable sub-domains plus more quadtree SDF fractals and layered geometry for stress testing"}
{"timestamp":"2026-05-18T09:45:34+01:00","topic":"everything-is-a-fractal-recursive-domains","lesson":"The Zyphos world patch now expresses the 'everything is a fractal' idea as explicit recursive domains: planet -> lat/long -> continent -> forest -> tree -> leaf and continent -> coast -> pebble field, plus Umbros -> crater province -> boulder field -> pebble field. The flattened stress backend emits 58 shaped brush claims into a 64-entry D3D12 table, while SDF shaders add bounded leaf/pebble material-relief clusters so the recursion is visible even before true recursive residency and LOD caching exist.","files":["src/Aquarium.Zyphos/Worlds/zyphos-first-fractal-terrain.aquageo","src/Aquarium.Zyphos/ZyphosSpatialDomainCatalog.cs","src/Aquarium.Zyphos/ZyphosRuntime.cs","src/Aquarium.Engine/Render/Features/D3D12HeightFieldBrushConstants.cs","src/Aquarium.Engine/Render/Shaders/D3D12HeightField.hlsl","src/Aquarium.Zyphos/Shaders/D3D12ZyphosPlanet.hlsl","src/Aquarium.Zyphos/Shaders/D3D12ZyphosUmbros.hlsl","tests/Aquarium.Engine.Fractal.Tests/ZyphosCameraComposerTests.cs","tests/Aquarium.Engine.Fractal.Tests/ZyphosFractalTerrainTests.cs","tests/Aquarium.Engine.Fractal.Tests/ZyphosSpatialDomainCatalogTests.cs"],"source":"user asked to see recursive domains everywhere, from continent-scale detail down to pebble, forests down to leaf"}
{"timestamp":"2026-05-18T09:58:37+01:00","topic":"zyphos-visible-sun-and-domain-zoom","lesson":"The primary star cannot remain only an SDF light if users need spatial orientation; it is now a rendered SDF object with emission/corona and a Solar navigation target. Camera zoom limits are now derived from the selected domain pose instead of a global 8-unit floor, so leaf and pebble domains can be inspected at their own scale while broad orbital domains still retain safe maximum framing.","files":["src/Aquarium.Zyphos/ZyphosRenderPlan.cs","src/Aquarium.Zyphos/ZyphosSceneBuilder.cs","src/Aquarium.Zyphos/Shaders/D3D12ZyphosStar.hlsl","src/Aquarium.Zyphos/ZyphosCameraComposer.cs","src/Aquarium.Zyphos/ZyphosRuntime.cs","src/Aquarium.Zyphos/ZyphosSpatialDomainCatalog.cs","tests/Aquarium.Engine.Fractal.Tests/ZyphosCameraComposerTests.cs"],"source":"user asked where the sun is and why zoom cannot reach the cool small features"}
{"lesson":"The first live bridge from the fractal architecture into Zyphos SDF rendering is material/detail, not traced form: .aquageo now preserves multiple tile roots, height brush packets carry cube-tile face/level/x/y metadata, D3D12 binds that packet table into the SDF pass, and the planet shader evaluates authored brushes in cube-face tile space after hit. Evaluating all authored brushes inside sdfDistance was tested and cut because it pushed the live frame toward 50-100 ms; traced geometry needs selected-cut/resident packet policy first.","timestamp":"2026-05-18T11:28:00+01:00","files":["src/Aquarium.Engine.Fractal/Grammar/FractalDslCompiler.cs","src/Aquarium.Engine.Fractal/Brushes/FractalHeightBrushCompiler.cs","src/Aquarium.Engine.Contracts/Render/AquariumRenderPlan.cs","src/Aquarium.Engine/Render/Features/D3D12HeightFieldBrushConstants.cs","src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Engine/Render/Shaders/D3D12SdfCommon.hlsli","src/Aquarium.Zyphos/Shaders/D3D12ZyphosPlanet.hlsl","research/rendering/fractal-brush-implementation-roadmap.md"],"source":"user pointed out the renderer was only a pile of legos and ordered the real machine to be built","topic":"zyphos-aquageo-tile-packet-sdf-bridge"}
{"timestamp":"2026-05-18T12:22:00+01:00","topic":"fractal-temporal-detail-control","lesson":"Fractal cache influence now has a first TAA-facing lane. SdfSurface carries temporalDetail, SDF proxy writes it into scene-control.z, D3D12Post validates history continuity against the current and previous temporalDetail signal, and history-control.z preserves it across frames. Zyphos feeds this from authored cube-face brush material influence; other SDFs explicitly emit zero until they gain cache-owned detail.","files":["src/Aquarium.Engine/Render/Shaders/D3D12SdfCommon.hlsli","src/Aquarium.Engine/Render/Shaders/D3D12SdfProxy.hlsli","src/Aquarium.Engine/Render/Shaders/D3D12Post.hlsl","src/Aquarium.Zyphos/Shaders/D3D12ZyphosPlanet.hlsl","src/Aquarium.Epiphany/Shaders"],"source":"user said to weave the stochastic fractal cache into TAA buffers"}
{"timestamp":"2026-05-18T18:09:50+01:00","topic":"temporal-sdf-gaussian-renderer-boundary","lesson":"Live sensor-fusion splats now enter Aquarium through an engine-owned temporal SDF Gaussian field instead of client-side renderer folklore. The contract carries stable keyed world-space Gaussians; `TemporalGaussianAccumulator` buffers observations with presentation delay and history weights; D3D12 uploads structured packets and renders an instanced compact-kernel splat pass into the existing scene/metadata/control targets. Scaling beyond 4096 splats belongs to Aquarium residency/binning, not LocalCastBridge.","files":["src/Aquarium.Engine.Contracts/Render/AquariumRenderPlan.cs","src/Aquarium.Engine.Fractal/Temporal/TemporalGaussianAccumulator.cs","src/Aquarium.Engine/Render/Shaders/D3D12TemporalGaussian.hlsl","src/Aquarium.Engine/Render/D3D12Renderer.cs","docs/temporal-sdf-gaussian-field.md"],"source":"user directed the point-cloud/TAA renderer feature to be implemented on the Aquarium side for clean client consumption"}
{"timestamp":"2026-05-19T13:38:00+01:00","topic":"fractal-resource-budget-and-flame-dsl","lesson":"The fractal DSL now has a compact `flame` primitive for deterministic curled recursive brush emission, and Zyphos exercises it in a leaf microdetail domain without exceeding the 64-brush stress table. Fractal render planning now coordinates CPU stochastic update count, GPU selected-cut estimated cost, RAM resident payload budget, and SSD request budget before packet compilation. This budget vocabulary should remain compatible with Mimir-style sensor fusion because both pipelines accumulate confidence-weighted spatial samples into temporal reservoirs before rendering a resolved field.","files":["src/Aquarium.Engine.Fractal/Grammar/FractalDslCompiler.cs","src/Aquarium.Engine.Fractal/Lod/FractalResourceBudget.cs","src/Aquarium.Engine.Fractal/Lod/FractalResourceBudgetPlanner.cs","src/Aquarium.Engine.Fractal/Lod/FractalResidencyPlanner.cs","src/Aquarium.Zyphos/ZyphosFractalTerrain.cs","src/Aquarium.Zyphos/Worlds/zyphos-first-fractal-terrain.aquageo","tests/Aquarium.Engine.Fractal.Tests/FractalResourceBudgetPlannerTests.cs"],"source":"user demanded full fractal SDF rendering and noted Mimir sensor fusion shares the same temporal spatial evidence shape"}
{"timestamp":"2026-05-19T14:04:00+01:00","topic":"temporal-spatial-evidence-reservoir","lesson":"Temporal Gaussian accumulation now uses `TemporalSpatialEvidenceReservoir`, which owns stable-keyed spatial tracks, smoothing, delayed presentation, velocity prediction, confidence-weighted history, expiry, and max-track eviction. This pulls the common reservoir shape out from under Gaussian rendering so fractal SDF probes and Mimir sensor-fusion features can converge through the same evidence machinery before backend lowering.","files":["src/Aquarium.Engine.Fractal/Temporal/TemporalSpatialEvidenceObservation.cs","src/Aquarium.Engine.Fractal/Temporal/TemporalSpatialEvidenceReservoir.cs","src/Aquarium.Engine.Fractal/Temporal/TemporalGaussianAccumulator.cs","tests/Aquarium.Engine.Fractal.Tests/TemporalSpatialEvidenceReservoirTests.cs","docs/temporal-sdf-gaussian-field.md"],"source":"user pointed out fractal rendering and Mimir sensor fusion both accumulate surface/volume confidence into temporal reservoirs"}
{"timestamp":"2026-05-19T14:20:00+01:00","topic":"zyphos-fractal-resource-observability","lesson":"Zyphos exposes `zyphos-fractal-plan`, a command-level dump of the current fractal selected cut and resource plan. Keep this kind of budget/cut observability alongside renderer work: pixels alone are not enough to validate stochastic LOD, residency, or cache behavior.","files":["src/Aquarium.Zyphos/ZyphosFractalTerrain.cs","src/Aquarium.Zyphos/ZyphosRuntime.cs","tests/Aquarium.Engine.Fractal.Tests/ZyphosFractalTerrainTests.cs"],"source":"third implementation slice after adding resource planning; the machine needs to explain itself without screenshot divination"}
{"timestamp":"2026-05-19T14:43:00+01:00","topic":"fractal-contribution-cache-live-loop","lesson":"Fractal contribution planning now has a live cache loop. `FractalContributionCache` builds a resource plan from current summaries and cached states, stochastically observes only budgeted update nodes, updates estimator confidence, and lets Zyphos reuse compiled brush packets by selected-cut key instead of freezing the whole render plan by camera bucket. Static plan caches are not acceptable for stochastic LOD because they stop learning.","files":["src/Aquarium.Engine.Fractal/Lod/FractalContributionCache.cs","src/Aquarium.Zyphos/ZyphosFractalTerrain.cs","tests/Aquarium.Engine.Fractal.Tests/FractalContributionCacheTests.cs"],"source":"follow-up after resource observability revealed the old bucket plan cache prevented continual cache updates"}
{"timestamp":"2026-05-19T15:12:00+01:00","topic":"localcast-shared-temporal-reservoir","lesson":"LocalCast fallback GPU fusion history now delegates to `TemporalSpatialEvidenceReservoir`. `LocalCastGpuFusionAccumulator` maps LocalCast GPU fusion seeds into shared evidence observations and lowers reservoir samples back into `AquariumGpuFusionSeed`; it no longer owns separate stable-key history, smoothing, expiry, or max-count logic. This is the first consumer-side takeover of duplicated temporal reservoir code.","files":["src/Aquarium.LocalCast/LocalCastGpuFusionAccumulator.cs","src/Aquarium.Engine.Fractal/Temporal/TemporalSpatialEvidenceReservoir.cs","docs/temporal-sdf-gaussian-field.md"],"source":"user made Aquarium responsible for resolving temporal reservoir sampling architecturally and taking over consumer half-versions"}
{"timestamp":"2026-05-19T15:29:00+01:00","topic":"temporal-evidence-lowering-boundary","lesson":"Shared temporal evidence now has named lowering helpers. `TemporalSpatialEvidenceLowering` converts Gaussian observations and GPU fusion seeds to/from reservoir samples, so consumer adapters do not privately pack Payload0/Payload1 conventions. Keep new reservoir consumers on this lowering seam unless they need a genuinely new payload contract.","files":["src/Aquarium.Engine.Fractal/Temporal/TemporalSpatialEvidenceLowering.cs","src/Aquarium.Engine.Fractal/Temporal/TemporalGaussianAccumulator.cs","src/Aquarium.LocalCast/LocalCastGpuFusionAccumulator.cs","tests/Aquarium.Engine.Fractal.Tests/TemporalSpatialEvidenceLoweringTests.cs"],"source":"follow-up after moving LocalCast history onto the shared reservoir; adapter payload packing needed to become a tested engine boundary"}
{"timestamp":"2026-05-19T15:46:00+01:00","topic":"temporal-reservoir-ownership-contract","lesson":"The temporal spatial evidence reservoir now has an explicit architecture contract. Raw sample reservoirs keep capture-time handles and ordering; Aquarium's `TemporalSpatialEvidenceReservoir` owns stable resolved spatial history; `TemporalSpatialEvidenceLowering` owns backend packet conversion; TAA owns pixel history. This prevents consumer repos from growing parallel half-reservoirs while preserving LocalCastBridge's lower-level raw rolling reservoir authority.","files":["docs/temporal-spatial-evidence-reservoir.md","state/map.yaml","state/memory.json"],"source":"user made Aquarium responsible for resolving temporal reservoir sampling architecturally across consumer repos"}
{"timestamp":"2026-05-19T16:11:00+01:00","topic":"zyphos-budgeted-fractal-geometry","lesson":"Authored fractal packets now affect Zyphos traced planet geometry, but only through a hard-budgeted top-influence subset. Selected height brushes are sorted by abs(amplitude)*max(radius), `sdfDistance` samples the first four, and `sdfSurface` still evaluates the full selected packet table for material/detail. A 12-brush geometry loop was tested and cut after pushing the live frame to about 33 ms; the four-brush budget returns the live view to about 16.4 ms after shader pipelines are ready.","files":["src/Aquarium.Zyphos/ZyphosFractalTerrain.cs","src/Aquarium.Zyphos/Shaders/D3D12ZyphosPlanet.hlsl","tests/Aquarium.Engine.Fractal.Tests/ZyphosFractalTerrainTests.cs"],"source":"runtime proof after moving authored fractal packet evaluation into the hot SDF distance path"}
{"timestamp":"2026-05-19T16:27:00+01:00","topic":"zyphos-fractal-domain-debug-mode","lesson":"Render debug mode 11 now exposes a client fractal-domain view. Zyphos colors cube faces, draws an 8x8 tile grid, and overlays authored brush material influence so face/tile/material packet mapping can be inspected from the renderer instead of inferred from final beauty shading.","files":["src/Aquarium.Engine.Contracts/GraphicsSettings.cs","src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Zyphos/Shaders/D3D12ZyphosPlanet.hlsl","research/rendering/fractal-brush-implementation-roadmap.md"],"source":"roadmap called for face/tile/LOD/cache debug modes; this is the first renderer-visible face/tile/material influence slice"}
{"timestamp":"2026-05-19T17:35:00+01:00","topic":"restir-reservoir-core","lesson":"The previous stable-key temporal smoother was not ReSTIR. Aquarium now treats `ResampledImportanceReservoir<TSample>` as the RIS/ReSTIR math authority: selected sample, target value, weight sum, represented candidate count, merge, and contribution weight. `TemporalSpatialEvidenceReservoir` is a stable resolved-track layer, while fractal contribution scoring should become a candidate generator feeding reservoir resampling with temporal/spatial/domain validation and TAA guide-buffer integration.","files":["src/Aquarium.Engine.Fractal/Temporal/ResampledImportanceCandidate.cs","src/Aquarium.Engine.Fractal/Temporal/ResampledImportanceReservoir.cs","tests/Aquarium.Engine.Fractal.Tests/ResampledImportanceReservoirTests.cs","docs/temporal-spatial-evidence-reservoir.md","research/rendering/fractal-brush-implementation-roadmap.md","state/map.yaml","state/memory.json"],"source":"user corrected the architecture toward NVIDIA ReSTIR/GRIS rather than invented spatiotemporal reservoir sampling"}
{"timestamp":"2026-05-19T18:03:00+01:00","topic":"fractal-contribution-candidates","lesson":"FractalContributionCache now frames scheduled update nodes as weighted `ResampledImportanceReservoir<FractalContributionCandidate>` candidates and exposes a per-frame reservoir snapshot for debug/tests. This is the handoff from heuristic LOD scoring into reservoir evidence; temporal/spatial reuse and domain shift validation still need to be built explicitly before calling the fractal path ReSTIR-complete.","files":["src/Aquarium.Engine.Fractal/Lod/FractalContributionCandidate.cs","src/Aquarium.Engine.Fractal/Lod/FractalContributionCache.cs","tests/Aquarium.Engine.Fractal.Tests/FractalContributionCacheTests.cs","docs/temporal-spatial-evidence-reservoir.md","research/rendering/fractal-brush-implementation-roadmap.md","state/memory.json"],"source":"continued Perfect Machine work after adding the ReSTIR-style reservoir core"}
{"timestamp":"2026-05-19T18:24:00+01:00","topic":"fractal-probe-reservoir-samples","lesson":"Fractal SDF/detail reservoir candidates now have a typed probe sample: domain key, node key, local center, bound radius, target contribution, source PDF, material delta, and payload handle. `FractalProbeReuseValidator` rejects unknown domains, sibling-domain reuse, invalid bounds, and excessive local shift. This starts the GRIS-style domain-shift boundary; renderer inputs for camera motion, disocclusion, material compatibility, and visibility still need to be wired before reuse is complete.","files":["src/Aquarium.Engine.Fractal/Lod/FractalProbeSample.cs","tests/Aquarium.Engine.Fractal.Tests/FractalProbeSampleTests.cs","docs/temporal-spatial-evidence-reservoir.md","research/rendering/fractal-brush-implementation-roadmap.md"],"source":"continued Perfect Machine work after connecting fractal contribution updates to reservoir candidates"}
{"timestamp":"2026-05-19T18:46:00+01:00","topic":"taa-reservoir-guide-lane","lesson":"SDF surfaces now publish `reservoirConfidence`; the SDF proxy writes it to current scene-control.w, and D3D12Post folds that value into history validation with debug mode 12 showing reservoir confidence, temporal detail, and history weight. This is the first cache/reservoir signal woven into TAA buffers. History-control.w still owns history age, so previous-frame reservoir confidence/sample age/invalidation reason require an expanded guide layout before full ReSTIR-style TAA integration.","files":["src/Aquarium.Engine/Render/Shaders/D3D12SdfCommon.hlsli","src/Aquarium.Engine/Render/Shaders/D3D12SdfProxy.hlsli","src/Aquarium.Engine/Render/Shaders/D3D12Post.hlsl","src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Zyphos/Shaders/D3D12ZyphosPlanet.hlsl"],"source":"user explicitly asked to weave the cache into TAA buffers"}
{"timestamp":"2026-05-19T19:22:00+01:00","topic":"perfect-machine-waterfall-architecture","lesson":"The Perfect Machine architecture is now mapped before further implementation. The design authority is `docs/perfect-machine-architecture.md`: authored domains and sensor inputs lower into evidence candidates, target evaluation, ReSTIR/GRIS reservoirs, heuristic occupancy graph updates, residency/page scheduling, 2D/3D/projected SDF splat packets, and TAA guide buffers. The public article `perfect-machine-fractal-reservoir-architecture.md` defends the architecture in Void's interview-thesis voice with research footnotes.","files":["docs/perfect-machine-architecture.md","E:/Projects/gamecult-site/GameCult/Blog/perfect-machine-fractal-reservoir-architecture.md","state/map.yaml","state/memory.json"],"source":"user requested a waterfall design pass and public job-interview style architecture article before more implementation"}
{"timestamp":"2026-05-19T20:10:00+01:00","topic":"explicit-reservoir-guide-targets","lesson":"Phase B of the Perfect Machine architecture is implemented: the renderer now owns explicit current and history reservoir guide targets instead of packing previous reservoir validity into scene-control/history-control. Guide schema is x=reservoir confidence, y=sample age, z=domain validity, w=invalidation code. SDF and temporal Gaussian passes write the current guide; D3D12Post validates against current/previous guide data and persists the next guide while history-control.w remains pixel history age.","files":["src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Engine/Render/Shaders/D3D12Scene.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12SdfCommon.hlsli","src/Aquarium.Engine/Render/Shaders/D3D12SdfProxy.hlsli","src/Aquarium.Engine/Render/Shaders/D3D12TemporalGaussian.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12Post.hlsl","docs/perfect-machine-architecture.md","docs/temporal-spatial-evidence-reservoir.md"],"source":"Perfect Machine marching orders after architecture note became the design authority"}
{"timestamp":"2026-05-19T20:39:00+01:00","topic":"fractal-occupancy-graph","lesson":"FractalContributionCache now routes through `FractalOccupancyGraph`, the first explicit occupancy memory organ from the Perfect Machine architecture. The graph owns contribution estimates plus visibility/update-probability telemetry; observations update mean/variance/confidence through the existing estimator, and unobserved nodes lose confidence while stale uncertainty grows. This keeps cache convergence state in one authority instead of growing side tables.","files":["src/Aquarium.Engine.Fractal/Lod/FractalOccupancyGraph.cs","src/Aquarium.Engine.Fractal/Lod/FractalContributionCache.cs","tests/Aquarium.Engine.Fractal.Tests/FractalOccupancyGraphTests.cs","tests/Aquarium.Engine.Fractal.Tests/FractalContributionCacheTests.cs","docs/perfect-machine-architecture.md","research/rendering/fractal-brush-implementation-roadmap.md"],"source":"Perfect Machine Phase D implementation after explicit reservoir guide targets"}
{"timestamp":"2026-05-19T21:01:00+01:00","topic":"structural-probe-generator","lesson":"IFS structure can now enter the reservoir path as typed evidence. `FractalStructuralProbeGenerator` lowers `AquariumFractalSummary` rows into `FractalProbeSample` candidates with local center, bound radius, projected target contribution, clamped source PDF, material delta, and payload handle. This gives structural `.aquageo` summaries a real producer boundary before renderer-facing temporal validation and GPU reservoir reuse are added.","files":["src/Aquarium.Engine.Fractal/Lod/FractalStructuralProbeGenerator.cs","tests/Aquarium.Engine.Fractal.Tests/FractalStructuralProbeGeneratorTests.cs","docs/perfect-machine-architecture.md","research/rendering/fractal-brush-implementation-roadmap.md","state/memory.json"],"source":"Perfect Machine Phase C implementation after occupancy graph promotion"}
{"timestamp":"2026-05-19T21:18:00+01:00","topic":"zyphos-structural-probe-reservoir","lesson":"Zyphos now exposes a structural probe reservoir beside its selected cut and resource plan. `FractalStructuralProbeReservoir` builds a selected-cut `FractalProbeSample` reservoir from the ownership tree, summaries, node domains, and projected pixels per world unit; `ZyphosFractalRenderPlan` carries the snapshot and the debug dump reports selected probe weight/candidate count. This connects the pure IFS structural-probe producer to a live client path before GPU reservoir buffers are introduced.","files":["src/Aquarium.Engine.Fractal/Lod/FractalStructuralProbeReservoir.cs","src/Aquarium.Zyphos/ZyphosFractalTerrain.cs","tests/Aquarium.Engine.Fractal.Tests/FractalStructuralProbeReservoirTests.cs","tests/Aquarium.Engine.Fractal.Tests/ZyphosFractalTerrainTests.cs","docs/perfect-machine-architecture.md","research/rendering/fractal-brush-implementation-roadmap.md"],"source":"continuing Perfect Machine Phase C after adding structural probe generation"}
{"timestamp":"2026-05-19T21:42:00+01:00","topic":"fractal-probe-temporal-validation","lesson":"Fractal probe reuse now has a CPU temporal validation contract before GPU reuse exists. `FractalProbeReuseValidator.ValidateTemporal` composes domain/local-shift validation with renderer-facing gates for camera motion, disocclusion confidence, material delta, and visibility confidence, returning explicit rejection reasons. This keeps future ReSTIR/GRIS probe reuse from becoming private shader folklore.","files":["src/Aquarium.Engine.Fractal/Lod/FractalProbeSample.cs","tests/Aquarium.Engine.Fractal.Tests/FractalProbeSampleTests.cs","docs/perfect-machine-architecture.md","research/rendering/fractal-brush-implementation-roadmap.md","state/memory.json"],"source":"Perfect Machine Phase C validation contract work"}
{"timestamp":"2026-05-19T22:03:00+01:00","topic":"fractal-surface-page-contract","lesson":"Phase E has a portable page contract before renderer lowering. `AquariumFractalSurfacePageKey` gives height, 2D signed-distance, material, and confidence pages stable domain/node/kind/mip identity; `AquariumFractalSurfacePage` carries bounds, dimensions, payload handle, and max error without D3D12 types. This lets the residency/page store evolve without treating current height brushes as the page model.","files":["src/Aquarium.Engine.Contracts/Fractal/AquariumFractalContracts.cs","tests/Aquarium.Engine.Fractal.Tests/FractalSurfacePageContractTests.cs","docs/perfect-machine-architecture.md","research/rendering/fractal-brush-implementation-roadmap.md","state/memory.json"],"source":"Perfect Machine Phase E groundwork after fractal probe validation"}
{"timestamp":"2026-05-19T22:31:00+01:00","topic":"fractal-surface-page-planner","lesson":"Phase E now has a CPU page-planning boundary. `FractalSurfacePagePlanner` lowers selected IFS cuts into stable height, 2D signed-distance, material, and confidence page metadata; `ZyphosFractalRenderPlan` carries those pages beside brushes, resource planning, and structural probe reservoirs. This proves page identity and inspection before adding a page store, eviction policy, D3D12 atlas, or GPU lowering.","files":["src/Aquarium.Engine.Fractal/Lod/FractalSurfacePagePlanner.cs","src/Aquarium.Zyphos/ZyphosFractalTerrain.cs","tests/Aquarium.Engine.Fractal.Tests/FractalSurfacePagePlannerTests.cs","tests/Aquarium.Engine.Fractal.Tests/ZyphosFractalTerrainTests.cs","docs/perfect-machine-architecture.md","research/rendering/fractal-brush-implementation-roadmap.md","state/memory.json","state/map.yaml"],"source":"Perfect Machine Phase E CPU page planning"}
{"timestamp":"2026-05-19T22:48:00+01:00","topic":"fractal-residency-eviction-policy","lesson":"Residency planning now has an explicit score-per-cost eviction decision. `FractalResidencyPlanner` can receive node summaries, retain resident payloads with the best contribution per estimated cost under RAM budget, place evicted residents on summary fallback, and report evicted node keys without mutating a real store. This keeps eviction testable until a page/payload store owns storage changes.","files":["src/Aquarium.Engine.Fractal/Lod/FractalResidencyPlanner.cs","src/Aquarium.Engine.Fractal/Lod/FractalResidencyPlan.cs","src/Aquarium.Engine.Fractal/Lod/FractalResourceBudgetPlanner.cs","tests/Aquarium.Engine.Fractal.Tests/FractalResidencyPlannerTests.cs","src/Aquarium.Zyphos/ZyphosFractalTerrain.cs","tests/Aquarium.Engine.Fractal.Tests/ZyphosFractalTerrainTests.cs","docs/perfect-machine-architecture.md","research/rendering/fractal-brush-implementation-roadmap.md","state/memory.json","state/map.yaml"],"source":"Perfect Machine Phase D/E residency pressure slice"}
{"timestamp":"2026-05-19T23:10:00+01:00","topic":"fractal-surface-page-residency","lesson":"Surface page residency now has a separate mockable boundary from node payload residency. `IFractalSurfacePageStore` owns page-key resident/request/evict calls, and `FractalSurfacePageResidencyPlanner` turns planned pages into resident, missing, requested, evicted, and resident-byte rows using a max-error-per-byte heuristic. Zyphos carries this page residency plan for inspection before any real atlas or SSD-backed page store exists.","files":["src/Aquarium.Engine.Fractal/Lod/IFractalSurfacePageStore.cs","src/Aquarium.Engine.Fractal/Lod/FractalSurfacePageResidencyPlan.cs","src/Aquarium.Engine.Fractal/Lod/FractalSurfacePageResidencyPlanner.cs","tests/Aquarium.Engine.Fractal.Tests/FractalSurfacePageResidencyPlannerTests.cs","src/Aquarium.Zyphos/ZyphosFractalTerrain.cs","tests/Aquarium.Engine.Fractal.Tests/ZyphosFractalTerrainTests.cs","docs/perfect-machine-architecture.md","research/rendering/fractal-brush-implementation-roadmap.md","state/memory.json","state/map.yaml"],"source":"Perfect Machine Phase E page-store boundary slice"}
{"timestamp":"2026-05-19T23:35:00+01:00","topic":"fractal-surface-page-rasterizer","lesson":"Resident surface pages now produce CPU payloads instead of only metadata. `FractalSurfacePageRasterizer` lowers ownership-tree claims into height, 2D signed-distance support, material, and confidence sample arrays using `FractalBrushEnvelope2D`; Zyphos caches resident page payloads by stable page key. This gives Phase E a renderer-agnostic payload producer before D3D12 atlas/upload work begins.","files":["src/Aquarium.Engine.Fractal/Brushes/FractalBrushEnvelope2D.cs","src/Aquarium.Engine.Fractal/Lod/FractalSurfacePagePayload.cs","src/Aquarium.Engine.Fractal/Lod/FractalSurfacePageRasterizer.cs","tests/Aquarium.Engine.Fractal.Tests/FractalBrushEnvelope2DTests.cs","tests/Aquarium.Engine.Fractal.Tests/FractalSurfacePageRasterizerTests.cs","src/Aquarium.Zyphos/ZyphosFractalTerrain.cs","tests/Aquarium.Engine.Fractal.Tests/ZyphosFractalTerrainTests.cs","docs/perfect-machine-architecture.md","research/rendering/fractal-brush-implementation-roadmap.md","state/memory.json","state/map.yaml"],"source":"Perfect Machine Phase E CPU page payload slice"}
{"timestamp":"2026-05-19T23:55:00+01:00","topic":"fractal-3d-sdf-splat-contract","lesson":"Phase F has its first stable packet shape. `AquariumFractalSdfSplat3DKey` and `AquariumFractalSdfSplat3D` define domain/node/payload-keyed compact 3D SDF splats; `FractalSdfSplat3DCompiler` lowers structural `FractalProbeSample` evidence into splats, and `FractalSdfSplat3DKernel` owns CPU compact-weight/signed-distance parity math. Zyphos exposes a structural splat from its probe reservoir before renderer lowering.","files":["src/Aquarium.Engine.Contracts/Fractal/AquariumFractalContracts.cs","src/Aquarium.Engine.Fractal/Lod/FractalSdfSplat3DCompiler.cs","src/Aquarium.Engine.Fractal/Lod/FractalSdfSplat3DKernel.cs","src/Aquarium.Engine.Fractal/Lod/FractalStructuralProbeReservoir.cs","src/Aquarium.Zyphos/ZyphosFractalTerrain.cs","tests/Aquarium.Engine.Fractal.Tests/FractalSdfSplat3DContractTests.cs","tests/Aquarium.Engine.Fractal.Tests/FractalSdfSplat3DCompilerTests.cs","tests/Aquarium.Engine.Fractal.Tests/FractalStructuralProbeReservoirTests.cs","tests/Aquarium.Engine.Fractal.Tests/ZyphosFractalTerrainTests.cs","docs/perfect-machine-architecture.md","research/rendering/fractal-brush-implementation-roadmap.md","state/memory.json","state/map.yaml"],"source":"Perfect Machine Phase F compact 3D SDF splat groundwork"}
{"timestamp":"2026-05-19T23:59:00+01:00","topic":"fractal-projected-sdf-splat-compiler","lesson":"Phase G now has a pure 2D-projected-to-3D lowering seam. `FractalProjectedSdfSplatCompiler` takes resident SignedDistance2D page payload samples, an explicit page-to-world mapper, a surface normal, support radii, and a splat budget, then emits compact `AquariumFractalSdfSplat3D` packets ordered by near-surface distance. Zyphos caches a bounded first set of projected surface splats using a flat local mapping until cube-sphere and torus mappings are implemented.","files":["src/Aquarium.Engine.Fractal/Lod/FractalProjectedSdfSplatCompiler.cs","tests/Aquarium.Engine.Fractal.Tests/FractalProjectedSdfSplatCompilerTests.cs","src/Aquarium.Zyphos/ZyphosFractalTerrain.cs","tests/Aquarium.Engine.Fractal.Tests/ZyphosFractalTerrainTests.cs","docs/perfect-machine-architecture.md","research/rendering/fractal-brush-implementation-roadmap.md","state/memory.json","state/map.yaml"],"source":"Perfect Machine Phase G projected SDF splat groundwork"}
{"timestamp":"2026-05-19T21:03:19+00:00","topic":"gpu-resident-fractal-splat-receipt","lesson":"The first honest performance receipt is GPU-resident compute, not CPU object population. `tools/Aquarium.Fractal.Receipt` allocates an 80-byte packed `AquariumPackedFractalSdfSplat3D` UAV, populates it entirely in a D3D12 compute shader, measures GPU timestamp queries, and reads back only 64 splats for checksum. On the local NVIDIA GTX 1070, `2,000,000` splats over `120` measured frames ran at `3.362 ms/frame`, `297.5 FPS` equivalent, and about `594.9M` splats/sec. This proves compute-side population throughput; final shaded rendering still has to consume the packed buffer.","files":["src/Aquarium.Engine.Contracts/Fractal/AquariumFractalContracts.cs","src/Aquarium.Engine.Fractal/Lod/FractalNativeBuffer.cs","tests/Aquarium.Engine.Fractal.Tests/FractalNativeBufferTests.cs","tools/Aquarium.Fractal.Receipt/Aquarium.Fractal.Receipt.csproj","tools/Aquarium.Fractal.Receipt/Program.cs","scripts/fractal-splat-receipt.ps1","docs/perfect-machine-architecture.md","research/rendering/fractal-brush-implementation-roadmap.md","state/memory.json","state/map.yaml"],"source":"user demanded a receipt showing millions of splats at hundreds of FPS and rejected CPU-resident architecture"}
{"timestamp":"2026-05-19T21:29:26+00:00","topic":"gpu-resident-layered-reservoir-receipt","lesson":"The layered temporal cache is not one generic reservoir with a layer enum. SDF envelope splats, PBR material splats, and radiosity splats are three different sampled measures, so the GPU receipt now uses three distinct 64-byte reservoir packet types and three independent compute passes. Full rewrites of all three 2,000,000-entry reservoir layers every frame missed the target on the GTX 1070; the coherent architecture is stochastic budgeted refresh over resident reservoirs. With 50,000 updates per reservoir layer per frame, 2 candidates/update, and 2,000,000 resident splats/reservoirs, the receipt measured 4.471 ms/frame and 223.7 FPS equivalent over 120 frames, with full reservoir coverage in 40 frames.","files":["src/Aquarium.Engine.Contracts/Fractal/AquariumFractalContracts.cs","tests/Aquarium.Engine.Fractal.Tests/FractalSdfSplat3DContractTests.cs","tools/Aquarium.Fractal.Receipt/Program.cs","scripts/fractal-splat-receipt.ps1","docs/perfect-machine-architecture.md","research/rendering/fractal-brush-implementation-roadmap.md","state/memory.json","state/map.yaml"],"source":"user corrected that SDF splats, PBR splats, and radiosity splats are sampled independently in different shader passes"}
{"timestamp":"2026-05-20T01:24:49+01:00","topic":"fractal-reservoir-shader-asset","lesson":"The fractal GPU reservoir compute path must live as an engine shader asset, not as embedded receipt-tool text. `src/Aquarium.Engine/Render/Shaders/D3D12FractalReservoirCompute.hlsl` now owns the splat population pass plus the independent SDF envelope, PBR material, and radiosity reservoir update passes. `tools/Aquarium.Fractal.Receipt` compiles that shader file directly, keeping the receipt and future renderer pass on one source of truth.","files":["src/Aquarium.Engine/Render/Shaders/D3D12FractalReservoirCompute.hlsl","tools/Aquarium.Fractal.Receipt/Program.cs","state/map.yaml"],"source":"continued Perfect Machine build after the GPU receipt proved the pass should become reusable renderer architecture"}
{"timestamp":"2026-05-20T01:31:00+01:00","topic":"fractal-reservoir-render-contract","lesson":"The render contract now exposes `AquariumFractalReservoirField` on `AquariumSceneState`: clients request a GPU-resident fractal reservoir field by resident splat count, depth, seed, reservoir candidates/update, and updates/pass. This keeps million-instance splat population inside GPU compute instead of making clients publish CPU splat lists.","files":["src/Aquarium.Engine.Contracts/Render/AquariumRenderPlan.cs","tests/Aquarium.Engine.Fractal.Tests/FractalReservoirFieldContractTests.cs","state/map.yaml"],"source":"continued Perfect Machine build: the shared shader needed a client-to-renderer contract surface"}
{"timestamp":"2026-05-20T01:57:56+01:00","topic":"renderer-owned-fractal-reservoir-pass","lesson":"D3D12Renderer now owns the first live fractal reservoir compute pass instead of leaving it in the receipt tool. The renderer creates a separate fractal reservoir root signature, compiles four compute pipelines from `D3D12FractalReservoirCompute.hlsl`, lazily allocates GPU UAV buffers for splats plus SDF/PBR/radiosity reservoirs, inserts a UAV barrier after splat population, and dispatches the three independent reservoir passes when `AquariumFractalReservoirField` is present. Zyphos now requests the 2,000,000-splat, 50,000-updates/pass field by default. The pass still needs a shaded consumption path before it produces visible terrain pixels.","files":["src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Engine/Render/D3D12StructuredBuffer.cs","src/Aquarium.Engine.Contracts/Render/AquariumApp.cs","src/Aquarium.Engine.Contracts/Render/AquariumRenderPlan.cs","src/Aquarium.Zyphos/ZyphosSceneBuilder.cs","tests/Aquarium.Engine.Fractal.Tests/ZyphosFractalTerrainTests.cs","tools/Aquarium.Fractal.Receipt/Program.cs","state/map.yaml"],"source":"continued Perfect Machine build: turn the GPU reservoir receipt into a renderer-owned frame pass"}
{"timestamp":"2026-05-20T02:08:12+01:00","topic":"visible-fractal-splat-consumption","lesson":"The first visible GPU-resident fractal consumption path is now a capped debug draw, not a CPU readback. `D3D12FractalSplatRender.hlsl` reads the computed `AquariumPackedFractalSdfSplat3D` buffer as an SRV and draws up to 131,072 splat instances into the scene. This proves the renderer can consume the compute-populated splat buffer directly; final terrain, material, and radiosity integration still need domain-correct shading over the same buffers. A Zyphos shader compile bug also surfaced here: `line` was treated as an HLSL token, so the planet debug variable is now `gridLine`.","files":["src/Aquarium.Engine/Render/Shaders/D3D12FractalSplatRender.hlsl","src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Engine.Contracts/Render/AquariumApp.cs","src/Aquarium.Engine.Contracts/Render/AquariumRenderPlan.cs","src/Aquarium.Zyphos/Shaders/D3D12ZyphosPlanet.hlsl","state/map.yaml"],"source":"continued Perfect Machine build: make the GPU-resident fractal splat buffer visible in the renderer"}
{"timestamp":"2026-05-20T07:47:00+01:00","topic":"layered-fractal-reservoir-consumption","lesson":"The visible fractal splat draw must consume the same independent reservoir layers produced by compute. Reusing the temporal Gaussian descriptor slot for raw splats hid the SDF/PBR/radiosity contract. The renderer now binds raw splats plus SDF envelope, PBR material, and radiosity reservoirs as separate graphics SRVs; the debug draw uses SDF reservoirs for support, PBR reservoirs for color, radiosity reservoirs for energy, and writes per-layer confidence into the reservoir guide MRT. This is still a capped debug view, but it proves the three-layer reservoir machine reaches visible pixels without CPU readback or buffer collapse.","files":["src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Engine/Render/Shaders/D3D12FractalSplatRender.hlsl","state/map.yaml","state/memory.json"],"source":"user insisted SDF splats, PBR splats, and radiosity splats are different sampled types and the Perfect Machine must not flatten them"}
{"timestamp":"2026-05-20T08:04:00+01:00","topic":"authored-ifs-program-gpu-splat-population","lesson":"The GPU splat producer now has a compact authored-program path. `FractalGpuProgramCompiler` lowers selected `.aquageo` claims into `AquariumPackedFractalIfsTransform` rows, Zyphos passes those rows through `AquariumFractalReservoirField.ProgramTransforms`, and D3D12 uploads them as a small compute SRV before dispatch. `D3D12FractalReservoirCompute.hlsl` uses those transforms when present and keeps the old hash fractal only as fallback/receipt mode. This keeps million-splat population GPU-resident while making the source fractal structure come from the DSL instead of private shader folklore.","files":["src/Aquarium.Engine.Contracts/Fractal/AquariumFractalContracts.cs","src/Aquarium.Engine.Contracts/Render/AquariumRenderPlan.cs","src/Aquarium.Engine.Fractal/Lod/FractalGpuProgramCompiler.cs","src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Engine/Render/Shaders/D3D12FractalReservoirCompute.hlsl","src/Aquarium.Zyphos/ZyphosFractalTerrain.cs","src/Aquarium.Zyphos/ZyphosSceneBuilder.cs","tests/Aquarium.Engine.Fractal.Tests/FractalGpuProgramCompilerTests.cs"],"source":"continued Perfect Machine build: replace hardcoded GPU splat generation with a DSL-driven program seam"}
{"timestamp":"2026-05-20T08:16:00+01:00","topic":"authored-ifs-program-gpu-receipt","lesson":"The receipt harness now has a nonzero authored-program mode via `-ProgramTransforms`. On the GTX 1070, 2,000,000 splats plus 2,000,000 SDF, PBR, and radiosity reservoirs per layer with 4 IFS transforms, depth 1, 20,000 stochastic updates per reservoir layer, and 2 candidates/update measured 4.438 ms/frame, 225.3 FPS equivalent, with full reservoir coverage in 100 frames. Depth 2 and 4 are below the hundreds-FPS bar at this budget, so deeper authored IFS generation needs a better shader strategy or adaptive depth/cut scheduling instead of pretending the simple receipt covers all fractal detail depths.","files":["tools/Aquarium.Fractal.Receipt/Program.cs","scripts/fractal-splat-receipt.ps1","src/Aquarium.Engine/Render/Shaders/D3D12FractalReservoirCompute.hlsl","state/map.yaml","state/memory.json"],"source":"user demanded a receipt showing millions of splats populating a simple fractal at hundreds of FPS"}
{"timestamp":"2026-05-20T08:32:00+01:00","topic":"precomposed-selected-cut-splat-generation","lesson":"Nested domain ancestry must not be replayed inside the million-splat compute kernel. Authored program mode now treats `AquariumPackedFractalIfsTransform` rows as precomposed selected-cut support packets and samples one row per splat in O(1); the CPU/compiler/planner owns collapsing planetary/cave/mushroom/rib ancestry into selected supports before GPU dispatch. A depth-48 receipt with 2,000,000 splats, 2,000,000 reservoirs per SDF/PBR/radiosity layer, 4 program rows, 15,000 updates per layer, and 2 candidates/update measured 4.908 ms/frame, 203.7 FPS equivalent on the GTX 1070. Depth is now semantic lineage/planner pressure, not a hot-loop multiplier.","files":["src/Aquarium.Engine/Render/Shaders/D3D12FractalReservoirCompute.hlsl","src/Aquarium.Engine/Render/D3D12Renderer.cs","tools/Aquarium.Fractal.Receipt/Program.cs","state/map.yaml","state/memory.json"],"source":"user pointed out real scenes will regularly render nested domains dozens of layers deep"}
{"timestamp":"2026-05-20T09:39:00+01:00","topic":"zyphos-fractal-reservoir-primary-terrain","lesson":"The Zyphos demo must test the fractal reservoir renderer as the terrain path, not as a debug layer over direct SDF planets. `AquariumFractalReservoirField` now carries `WorldCenterRadius`; Zyphos binds it to the planet frame, reduces live reservoir updates to 20,000/pass, and removes the direct planet/Umbros SDF proxy shaders from its render plan. `D3D12FractalReservoirCompute.hlsl` emits normalized spherical support for authored selected-cut program rows, and `D3D12FractalSplatRender.hlsl` maps SDF/PBR/radiosity reservoir rows into the world frame with SDF support/depth/normal, PBR material, and radiosity illumination. The remaining direct SDF body is the parent star. Future visual problems in Zyphos terrain should be fixed in reservoir lowering/shading, not hidden behind direct SDF terrain.","files":["src/Aquarium.Engine.Contracts/Render/AquariumRenderPlan.cs","src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Engine/Render/Shaders/D3D12FractalReservoirCompute.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12FractalSplatRender.hlsl","src/Aquarium.Zyphos/ZyphosRenderPlan.cs","src/Aquarium.Zyphos/ZyphosSceneBuilder.cs","tests/Aquarium.Engine.Fractal.Tests/ZyphosFractalTerrainTests.cs"],"source":"user correctly pointed out that Zyphos fractal domains should be the pipeline test and should replace direct SDF rendering"}
{"timestamp":"2026-05-20T13:45:00+01:00","topic":"zyphos-fractal-surface-legibility","lesson":"The live Zyphos reservoir path was fast but visually incoherent because the GPU program packet discarded cube tile X/Y and the camera targeted parent pivots instead of selected domains. `AquariumPackedFractalIfsTransform.TileAddress` now preserves face/level/x/y, D3D12FractalReservoirCompute maps authored supports onto cube-sphere faces, D3D12FractalSplatRender projects tangent-frame surface patches from world space, and ZyphosCameraComposer targets the selected domain while keeping the parent as orbit anchor. The result still reads too abstractly; the next coherent renderer cut is a clustered/ray-query surface resolve for reservoir splats rather than more camera-facing billboard cosmetics.","files":["src/Aquarium.Engine.Contracts/Fractal/AquariumFractalContracts.cs","src/Aquarium.Engine.Fractal/Lod/FractalGpuProgramCompiler.cs","src/Aquarium.Engine/Render/Shaders/D3D12FractalReservoirCompute.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12FractalSplatRender.hlsl","src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Zyphos/ZyphosCameraComposer.cs","tests/Aquarium.Engine.Fractal.Tests/FractalGpuProgramCompilerTests.cs","tests/Aquarium.Engine.Fractal.Tests/ZyphosCameraComposerTests.cs"],"source":"user asked whether the current view looked like anything; answer was no, so the packet/domain/camera lies had to be cut before more rendering claims"}
{"timestamp":"2026-05-20T14:05:00+01:00","topic":"apophysis-reference-first-fractal-parity","lesson":"Zyphos is too entangled to be the first correctness oracle for the fractal DSL. Aquarium now has a tiny Apophysis/FLAM3-shaped reference gate: `.flame` linear Sierpinski is parsed by an independent test helper, `.aquageo` expresses the same affine IFS through `affineifs`/`affinemap`, and tests compare exact fixed-transform sequence points plus chaos-game moment bounds. This follows the AquaSynth pattern: open-source/reference systems are external pressure and receipts, not runtime organs or copied code. Next parity gates should parse more `.flame` semantics and compare against FLAM3/Apophysis-compatible rendered histograms before feeding the GPU reservoir renderer.","files":["src/Aquarium.Engine.Fractal/Grammar/FractalAffineIfsDefinition.cs","src/Aquarium.Engine.Fractal/Grammar/FractalAffineIfsChaosGame.cs","src/Aquarium.Engine.Fractal/Grammar/FractalDslCompiler.cs","src/Aquarium.Engine.Fractal/Grammar/FractalOwnershipTree.cs","tests/Aquarium.Engine.Fractal.Tests/ApophysisReferenceParityTests.cs","tests/Aquarium.Engine.Fractal.Tests/Fixtures/Apophysis/linear-sierpinski.flame","tests/Aquarium.Engine.Fractal.Tests/Fixtures/Apophysis/linear-sierpinski.aquageo","research/rendering/fractal-reference-oracles.md"],"source":"user redirected from visual Zyphos debugging to reference-rendered IFS parity and suggested Apophysis 7x"}
{"timestamp":"2026-05-20T14:20:00+01:00","topic":"flame-subset-parser-histogram-receipts","lesson":"The reference path now parses and evaluates a small Apophysis/FLAM3 flame subset in runtime code: xform weight, color, affine coefficients, and `linear`, `spherical`, and `bubble` variation weights. Tests cover parser fields, independent variation formulas, and a deterministic 64x64 histogram checksum for a mixed linear/spherical/bubble fixture. This is still not external renderer parity, but it gives Aquarium a stable CPU receipt before GPU lowering and keeps Zyphos out of the correctness loop.","files":["src/Aquarium.Engine.Fractal/Grammar/FractalFlameDefinition.cs","src/Aquarium.Engine.Fractal/Grammar/FractalFlameFileParser.cs","src/Aquarium.Engine.Fractal/Grammar/FractalFlameChaosGame.cs","src/Aquarium.Engine.Fractal/Grammar/FractalPointHistogram.cs","tests/Aquarium.Engine.Fractal.Tests/ApophysisReferenceParityTests.cs","tests/Aquarium.Engine.Fractal.Tests/Fixtures/Apophysis/linear-spherical-bubble.flame","research/rendering/fractal-reference-oracles.md"],"source":"continued after adopting Apophysis/FLAM3 as the fractal reference family"}
{"timestamp":"2026-05-20T14:30:00+01:00","topic":"flame-histogram-receipt-cli","lesson":"The receipt tool now has a non-GPU `--flame` mode that loads a `.flame` fixture, runs FractalFlameChaosGame, bins points through FractalPointHistogramBuilder, and writes a JSON checksum receipt. `scripts/fractal-flame-receipt.ps1` runs the default mixed linear/spherical/bubble fixture with seed 0x0BADC0DE and emits checksum 0xAEB1C81B. This creates a cheap local receipt path before wiring external FLAM3/Apophysis renderer parity or GPU lowering.","files":["tools/Aquarium.Fractal.Receipt/Program.cs","scripts/fractal-flame-receipt.ps1","research/rendering/fractal-reference-oracles.md"],"source":"continued reference-first fractal pipeline build"}
{"timestamp":"2026-05-21T00:25:00+01:00","topic":"gpu-resident-flame-iteration-state","lesson":"Flame splat generation now has a real GPU-resident iteration cache. `AquariumPackedFractalFlameState` is a 32-byte UAV row per resident splat storing point/support/material plus RNG/step; D3D12FractalReservoirCompute advances touched rows instead of replaying chaos-game ancestry from zero. The receipt harness separates full-population acquisition from steady stochastic maintenance: on the GTX 1070, JWildfire FARender selftest.flame with 2,000,000 splats/states, 8 full acquisition frames, then 50,000 splat updates/frame plus 15,000 reservoir updates/pass/frame at depth 8 measured 1.011 ms/frame / 988.8 FPS equivalent and 84.85% CPU-slice distribution parity. The same steady budget without acquisition scored 32.64%, so persistent caches must report cold-start versus maintenance explicitly.","files":["src/Aquarium.Engine.Contracts/Fractal/AquariumFractalContracts.cs","src/Aquarium.Engine.Contracts/Render/AquariumRenderPlan.cs","src/Aquarium.Engine/Render/Shaders/D3D12FractalReservoirCompute.hlsl","src/Aquarium.Engine/Render/D3D12Renderer.cs","tools/Aquarium.Fractal.Receipt/Program.cs","scripts/fractal-splat-receipt.ps1","research/rendering/fractal-reference-oracles.md","state/map.yaml","state/memory.json"],"source":"user demanded the Perfect Machine stop replaying crayon flames and keep building toward GPU-resident stochastic fractal rendering"}
{"lesson":"The flame parity gate now has an external image-density reference instead of only Aquarium CPU self-agreement. tools/Aquarium.Fractal.Receipt accepts --reference-density-ppm, loads a binary PPM rendered by JWildfire/FARender, converts luminance into the reference histogram, and compares Aquarium GPU splat density against it. scripts/new-jwildfire-baby-fixture.ps1 derives a smaller FARender-compatible julian-disc-baby.flame from FARender selftest while preserving boilerplate FARender requires. First GTX 1070 receipt: FARender 768x768 quality 2000 reference, Aquarium 2M splats/states, 8 acquisition frames, 50k steady splat updates/frame, depth 8, 1.145 ms/frame, but only 15.33% external density score in 256x256 bounds -2..2; a 128x128 bounds sweep peaked at 32.95% for -4..4 while Aquarium-vs-CPU scored 89.94%. This proves the next failure is dialect/camera/render filtering, not GPU sampling count.","timestamp":"2026-05-21T01:05:00+01:00","files":["tools/Aquarium.Fractal.Receipt/Program.cs","scripts/fractal-splat-receipt.ps1","scripts/new-jwildfire-baby-fixture.ps1","research/rendering/fractal-reference-oracles.md","state/map.yaml","state/memory.json"],"source":"user asked to ditch the shitty oracle and get proper ground truth that gives Aquarium useful exercise","topic":"external-flame-density-oracle"}
{"lesson":"The external FARender density oracle exposed two concrete JWildfire import/math bugs: Aquarium transposed JWildfire coefs off-diagonal terms even though FARender applies a,b,c,d,e,f as x=a*x+b*y+c and y=d*x+e*y+f, with JWildfire XML effectively a b d e c f; Aquarium also used atan2(y,x) for disc while FARender jwf_disc uses atan2(x,y)/PI. Fixing both moved the julian-disc-baby external-density receipt from 15.33% to 26.87% at 256x256 bounds -2..2. The remaining visible spray is raw splat occupancy versus FARender camera/filter/gamma density, not proof that the GPU sampler is simply exploding.","timestamp":"2026-05-21T01:18:00+01:00","files":["src/Aquarium.Engine.Fractal/Grammar/FractalFlameFileParser.cs","src/Aquarium.Engine.Fractal/Grammar/FractalFlameDefinition.cs","src/Aquarium.Engine/Render/Shaders/D3D12FractalReservoirCompute.hlsl","tests/Aquarium.Engine.Fractal.Tests/ApophysisReferenceParityTests.cs","research/rendering/fractal-reference-oracles.md","state/map.yaml","state/memory.json"],"source":"user asked why Aquarium explodes while the reference stays bounded","topic":"jwildfire-flame-import-coordinate-lies"}
{"timestamp":"2026-05-21T01:32:00+01:00","topic":"sdf-reservoir-density-parity","lesson":"The external flame parity candidate now comes from Aquarium's SDF envelope reservoir layer, not raw splat-center occupancy. tools/Aquarium.Fractal.Receipt stamps populated AquariumPackedSdfEnvelopeReservoir rows into shaped density histograms and reports the candidate source explicitly. PBR and radiosity remain separate reservoir layers: PBR should score appearance later, while radiance is out of this gate for now. With full 2M-row reservoir refresh on the GTX 1070, julian-disc-baby scored 22.14% against the FARender PPM at 256x256 bounds -2..2 and cost 42.053 ms/frame; the contact sheet shows a sparse, shape-shifted Aquarium SDF density rather than a valid rendered flame. The next work is dialect/camera/filter parity plus target-density and view-conditioned reservoir feedback, not raw occupancy scoring.","files":["tools/Aquarium.Fractal.Receipt/Program.cs","research/rendering/fractal-reference-oracles.md","state/map.yaml","state/memory.json"],"source":"user corrected the metric: SDF reservoirs express form density, PBR reservoirs express surface appearance, and raw occupancy is the wrong comparison"}
{"timestamp":"2026-05-21T01:52:00+01:00","topic":"jwildfire-normal-is-not-linear","lesson":"JWildfire FARender does not treat `variationGroup normal=\"1\"` as an explicit linear variation. A normal-only FARender diagnostic collapsed to a constant point, proving Aquarium's `normal -> linear` approximation was inventing geometry. The importer now ignores JWildfire `normal` as variation-group metadata while preserving explicit `linear` for Apophysis/FLAM3 fixtures. The SDF-density receipt also enforces a minimum one-bin reconstruction footprint for subpixel envelopes so density parity no longer degenerates into point occupancy. The julian-disc-baby external score moved from 22.14% to 31.36% with full 2M-row reservoir refresh; remaining mismatch is compactness/weighting, not the previous fake affine contribution.","files":["src/Aquarium.Engine.Fractal/Grammar/FractalFlameFileParser.cs","tests/Aquarium.Engine.Fractal.Tests/ApophysisReferenceParityTests.cs","tools/Aquarium.Fractal.Receipt/Program.cs","research/rendering/fractal-reference-oracles.md","state/map.yaml","state/memory.json"],"source":"continued flame external parity push after discovering FARender normal-only behavior"}
{"timestamp":"2026-05-21T02:00:00+01:00","topic":"flame-camera-bounds-receipt","lesson":"FARender maps flame points through camera bounds derived from flame `size / (scale * cam_zoom)` around `center`; using an ad hoc square histogram window was distorting external density parity. tools/Aquarium.Fractal.Receipt now accepts `--histogram-bounds flame-camera` after `--program-flame` and derives those bounds from the flame XML. On julian-disc-baby this moved the SDF-reservoir-density score from 31.36% in manual -2..2 bounds to 43.13% with 68.01% occupancy overlap. Remaining loss is now less camera-window stupidity and more exact variation/filter weighting plus reservoir targeting.","files":["tools/Aquarium.Fractal.Receipt/Program.cs","research/rendering/fractal-reference-oracles.md","state/map.yaml","state/memory.json"],"source":"continued flame external parity push after FARender source showed the camera size/scale mapping"}
{"timestamp":"2026-05-21T08:40:00+01:00","topic":"direct-full-reservoir-refresh","lesson":"The reservoir shader used the stochastic hash indexer even when ReservoirUpdatesPerPass equaled SplatCount, so a claimed full refresh was random-memory coupon-collector work. D3D12FractalReservoirCompute now maps full-refresh updates directly to updateIndex % SplatCount and keeps the hash path only for under-budget stochastic passes. On julian-disc-baby with flame-camera bounds, the visual score stayed essentially the same (43.09%, 67.99% occupancy overlap) but full SDF/PBR/radiosity reservoir refresh dropped to 7.508 ms/frame / 133.2 FPS equivalent instead of roughly 41 ms/frame.","files":["src/Aquarium.Engine/Render/Shaders/D3D12FractalReservoirCompute.hlsl","research/rendering/fractal-reference-oracles.md","state/map.yaml","state/memory.json"],"source":"continued hill climb after identifying the full-coverage reservoir pass as randomized memory confetti"}
{"timestamp":"2026-05-21T09:05:00+01:00","topic":"form-appearance-transport-fields","lesson":"The Perfect Machine architecture now treats SDF/PBR/radiosity as the first opaque backend packet slice, not the conceptual layer split. The durable split is Form, Appearance, and Transport. SDF/level-set is one Form encoding for opaque solids; density/extinction/confidence is the Form encoding for flames, smoke, transparent gradients, and uncertain sensor-fusion volumes. PBR is one Appearance encoding; participating media need albedo/emission/phase/absorption/scattering, with Transport owning radiance, emission, and scattering reuse. Do not force flames or Mimir confidence volumes to become fake surfaces before they can enter reservoirs.","files":["docs/perfect-machine-architecture.md","docs/temporal-sdf-gaussian-field.md","docs/temporal-spatial-evidence-reservoir.md","research/rendering/fractal-brush-implementation-roadmap.md","state/map.yaml","state/memory.json"],"source":"user reframed flame IFS and sensor fusion as field-density evidence rather than opaque SDF surfaces"}
{"timestamp":"2026-05-21T09:40:00+01:00","topic":"shared-form-reservoir-code","lesson":"The code now matches the Form/Appearance/Transport architecture at the reservoir seam. AquariumFieldLayer and AquariumFieldEncoding live in contracts; TemporalSpatialEvidenceObservation/Sample and FractalProbeSample carry layer/encoding; TemporalSpatialEvidenceReservoir keys tracks by layer+encoding+stable key; FractalProbeReuseValidator rejects mismatched encodings before spatial reuse; Form/SignedDistance lowers through FractalSdfSplat3DCompiler while Form/Density or Form/Extinction lowers through FractalDensitySplat3DCompiler. The packed transparent density splat is 80 bytes to stay stride-aligned with the opaque SDF splat. Do not add a parallel transparent reservoir; extend encodings and lowerings under the same sample/reservoir contract.","files":["src/Aquarium.Engine.Contracts/Fractal/AquariumFractalContracts.cs","src/Aquarium.Engine.Fractal/Lod/FractalProbeSample.cs","src/Aquarium.Engine.Fractal/Lod/FractalDensitySplat3DCompiler.cs","src/Aquarium.Engine.Fractal/Lod/FractalSdfSplat3DCompiler.cs","src/Aquarium.Engine.Fractal/Temporal/TemporalSpatialEvidenceObservation.cs","src/Aquarium.Engine.Fractal/Temporal/TemporalSpatialEvidenceReservoir.cs","src/Aquarium.Engine.Fractal/Lod/FractalGpuReservoirBudgetPlanner.cs","docs/perfect-machine-architecture.md","state/map.yaml","state/memory.json"],"source":"user asked to fix code so one reservoir handles transparent and opaque fields with defensible architecture"}
{"timestamp":"2026-05-21T10:05:00+01:00","topic":"aquageo-transparent-form-claims","lesson":"The `.aquageo` DSL now has first-class `density` and `extinction` field claims, and the recursive `flame` primitive emits Density payloads instead of pretending to be height. FractalSummaryBuilder scores Height, SignedDistance, Density, and Extinction as Form contribution. FractalHeightBrushCompiler filters mixed trees to Height payloads for height-field lowering, preserving the invariant that backend compilers lower only the payloads they own.","files":["src/Aquarium.Engine.Contracts/Fractal/AquariumFractalContracts.cs","src/Aquarium.Engine.Fractal/Grammar/FractalDslCompiler.cs","src/Aquarium.Engine.Fractal/Grammar/FractalSummaryBuilder.cs","src/Aquarium.Engine.Fractal/Brushes/FractalHeightBrushCompiler.cs","tests/Aquarium.Engine.Fractal.Tests/FractalDslCompilerTests.cs","tests/Aquarium.Engine.Fractal.Tests/FractalHeightBrushCompilerTests.cs","tests/Aquarium.Engine.Fractal.Tests/ZyphosFractalTerrainTests.cs","docs/perfect-machine-architecture.md","state/map.yaml","state/memory.json"],"source":"continued code migration after density claims exposed height lowering as a hidden payload router"}
{"timestamp":"2026-05-21T10:20:00+01:00","topic":"gpu-field-encoding-tag","lesson":"D3D12FractalReservoirCompute now tags flame-mode splats as Density in an existing material/confidence lane, preserving the 80-byte hot splat stride. D3D12FractalSplatRender branches on the encoding tag for a softer transparent-field visualization while opaque SDF splats keep the existing surface resolve. The receipt harness now reports Form/Appearance/Transport reservoir layers while keeping backend slice names in parentheses. This is field-aware GPU consumption, not full participating-media integration.","files":["src/Aquarium.Engine/Render/Shaders/D3D12FractalReservoirCompute.hlsl","src/Aquarium.Engine/Render/Shaders/D3D12FractalSplatRender.hlsl","tools/Aquarium.Fractal.Receipt/Program.cs","state/map.yaml","state/memory.json"],"source":"continued runtime migration after shared CPU reservoir and DSL field claims were in place"}
{"timestamp":"2026-05-21T10:45:00+01:00","topic":"summary-form-encoding-mask","lesson":"AquariumFractalSummary now carries a FormEncodingMask. FractalSummaryBuilder records Height, SignedDistance, Density, and Extinction form encodings from claims; FractalStructuralProbeGenerator derives density or extinction probes from density-only or extinction-only summaries unless a caller explicitly overrides the encoding. This prevents selected-cut structural probes from silently defaulting transparent form nodes back into SDF.","files":["src/Aquarium.Engine.Contracts/Fractal/AquariumFractalContracts.cs","src/Aquarium.Engine.Fractal/Grammar/FractalSummaryBuilder.cs","src/Aquarium.Engine.Fractal/Lod/FractalStructuralProbeGenerator.cs","src/Aquarium.Engine.Fractal/Lod/FractalStructuralProbeReservoir.cs","tests/Aquarium.Engine.Fractal.Tests/FractalSummaryBuilderTests.cs","tests/Aquarium.Engine.Fractal.Tests/FractalStructuralProbeGeneratorTests.cs","tests/Aquarium.Engine.Fractal.Tests/FractalStructuralProbeReservoirTests.cs","state/memory.json"],"source":"continued after noticing summaries had no authority to describe which field encodings they summarized"}
{"timestamp":"2026-05-21T11:20:00+01:00","topic":"fractal-resolve-pass-split","lesson":"The first visible field-aware splat renderer now splits output-merge authority instead of hiding opaque and transparent Form encodings behind one pixel shader branch. D3D12Renderer compiles separate surface and transparent fractal splat pipelines over the same GPU-resident splat/SDF/PBR/radiosity buffers. Surface splats use D3D12FractalSurfaceSplatPS with depth enabled for SignedDistance claims; density/extinction splats use D3D12FractalTransparentSplatPS with depth disabled and additive color-only blending while metadata/control/reservoir guide remain owned by opaque surfaces. This preserves the shared reservoir and 80-byte hot packet invariant while making the future volumetric target boundary honest.","files":["src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Engine/Render/Shaders/D3D12FractalSplatRender.hlsl","state/map.yaml","state/memory.json","state/scratch-fractal-resolve-split.md"],"source":"continued Perfect Machine build after the user rejected stopping before the renderer could distinguish transparent fields from opaque surfaces"}
{"timestamp":"2026-05-21T11:35:00+01:00","topic":"view-conditioned-reservoir-priority","lesson":"The first camera-conditioned reservoir pressure input is live. AquariumFractalReservoirField.PriorityFocus carries focus XY, radius, and strength from client/domain planning into D3D12 root constants. D3D12FractalReservoirCompute keeps full-refresh row sweeps direct, but under budget it samples four stochastic candidate row indices and prefers candidates near the focus while retaining exploration noise. Zyphos derives the focus from the selected spatial-domain camera target, and tools/Aquarium.Fractal.Receipt exposes --priority-focus; the local GTX 1070 smoke with 65,536 flame splats, 4,096 steady splat updates, 4,096 reservoir updates/pass, and focus 0,0,0.35,0.85 ran at 0.158 ms/frame / 6,331 FPS equivalent. The focus constants are four scalar cbuffer values, not a float4, so root constant offsets 9-12 remain unambiguous.","files":["src/Aquarium.Engine.Contracts/Render/AquariumRenderPlan.cs","src/Aquarium.Engine/Render/D3D12Renderer.cs","src/Aquarium.Engine/Render/Shaders/D3D12FractalReservoirCompute.hlsl","src/Aquarium.Zyphos/ZyphosFractalTerrain.cs","src/Aquarium.Zyphos/ZyphosSceneBuilder.cs","tools/Aquarium.Fractal.Receipt/Program.cs","tests/Aquarium.Engine.Fractal.Tests/FractalReservoirFieldContractTests.cs","tests/Aquarium.Engine.Fractal.Tests/ZyphosFractalTerrainTests.cs","state/map.yaml","state/memory.json"],"source":"continued after global flame parity showed the real challenge is maintaining smooth images under movement and zoom by spending work on underrepresented visible regions"}
{"timestamp":"2026-05-21T11:45:00+01:00","topic":"residual-to-focus-analyzer","lesson":"Visual parity now produces a tested reservoir-pressure suggestion. FractalHistogramResidualFocus estimates focus XY/radius/strength from positive reference-minus-candidate histogram residuals; matching histograms return zero focus. tools/Aquarium.Fractal.Receipt reports SuggestedPriorityFocus for each visual parity view. A GTX 1070 smoke receipt with 65,536 flame splats and 50k CPU reference samples in -2..2 scored 67.07% and suggested focus 0.544,-0.284,1.824,0.988, proving the diagnostic can emit a concrete next-frame pressure window instead of only a score.","files":["src/Aquarium.Engine.Fractal/Grammar/FractalHistogramResidualFocus.cs","tests/Aquarium.Engine.Fractal.Tests/FractalHistogramResidualFocusTests.cs","tools/Aquarium.Fractal.Receipt/Program.cs","state/map.yaml","state/memory.json"],"source":"continued after adding PriorityFocus so parity residuals could become actionable cache pressure instead of human-only visual diagnosis"}
{"timestamp":"2026-05-21T11:55:00+01:00","topic":"adaptive-focus-receipt-loop","lesson":"The receipt harness can now close the first residual feedback loop over the same GPU-resident resources. --adaptive-focus requires warmup and readback, runs the warmup epoch, builds visual parity, applies the first view's suggested priority focus to subsequent measured frames, then reports the adaptive focus in the JSON/console receipt. On the local GTX 1070 mixed flame smoke, the previous non-adaptive setup scored 67.07%; adaptive focus suggested 0.516,-0.302 radius 1.794 strength 1 and measured 70.89% at 0.160 ms/frame. This is not final runtime architecture because it uses a blocking readback between epochs, but it proves feedback improves the cache target before building the delayed/GPU-side path.","files":["tools/Aquarium.Fractal.Receipt/Program.cs","state/map.yaml","state/memory.json"],"source":"continued from residual-to-focus analyzer into a measurable adaptive reservoir control loop"}
{"timestamp":"2026-05-21T12:05:00+01:00","topic":"fractal-splat-taa-guide-schema","lesson":"D3D12FractalSplatRender now writes the shared reservoir/TAA guide schema instead of leaking backend layer validation into resolver fields. The guide is x combined reservoir confidence, y sample age in frames from the oldest resident Form/Appearance/Transport row update, z domain validity, w invalidation code. This matches D3D12Post.hlsl expectations and docs/temporal-spatial-evidence-reservoir.md; the previous x/y/z = SDF/PBR/radiosity validation mapping made the resolver interpret PBR validation as sample age and radiosity validation as domain validity.","files":["src/Aquarium.Engine/Render/Shaders/D3D12FractalSplatRender.hlsl","state/map.yaml","state/memory.json"],"source":"continued TAA/reservoir integration after noticing the live guide buffer violated its own documented schema"}
{"timestamp":"2026-05-21T12:10:00+01:00","topic":"reservoir-guide-debug-view","lesson":"Render debug mode 12 now visualizes the reservoir/TAA guide schema directly: red is current reservoir confidence, green is normalized guide sample age, and blue is domain validity. The previous debug view mixed confidence, temporal detail, and history weight, which made the labeled guide mode unable to diagnose guide-buffer bugs.","files":["src/Aquarium.Engine/Render/Shaders/D3D12Post.hlsl","state/map.yaml","state/memory.json"],"source":"continued after fixing the fractal guide producer and checking whether the visible debug mode matched the schema"}
{"timestamp":"2026-05-21T11:42:16+01:00","topic":"fensalir-splash-ripple-scene","lesson":"The first Fensalir art-target client proves a cleaner scene reproduction boundary than more abstract splat demos: the .aquageo patch owns the marsh surface and ripple brushes, FensalirSceneBuilder publishes those brushes plus one bounded SDF spine proxy, and client shaders own the dark reflective water/mist and luminous stacked-diamond hall silhouette. Aetheria's transferable primitive is the compact radial wave splat: envelope * powered cosine, not a bespoke water mesh. Missing future work is now visible at the right boundary: richer material/page DSL for water color/roughness, transparent fog density fields, and an IFS-owned spine/pillar grammar instead of a hand-authored first proxy shader.","files":["src/Aquarium.Fensalir/Worlds/fensalir-spine-emblem.aquageo","src/Aquarium.Fensalir/FensalirRuntime.cs","src/Aquarium.Fensalir/FensalirSceneBuilder.cs","src/Aquarium.Fensalir/Shaders/D3D12FensalirScene.hlsl","src/Aquarium.Fensalir/Shaders/D3D12FensalirSpine.hlsl","src/Aquarium.Engine.Fractal/Grammar/FractalDslCompiler.cs","src/Aquarium.Engine.Fractal/Brushes/FractalHeightBrushCompiler.cs","src/Aquarium.Engine.Contracts/Fractal/AquariumFractalContracts.cs","tests/Aquarium.Engine.Fractal.Tests/FensalirFractalSceneTests.cs","state/map.yaml","state/memory.json"],"source":"user pivoted from abstract Perfect Machine work to reproducing the documented Fensalir splash art as an actual DSL/rendering target"}
{"timestamp":"2026-05-22T01:20:00+01:00","topic":"fensalir-fixed-headless-capture","lesson":"Fensalir now has a repeatable headless frame-capture lane for art-target iteration. AquariumHost accepts --capture-frame plus headless width/height, suppresses overlay debug UI while headless, waits for ready frames, and saves the last presented backbuffer through IAquariumRenderer.SaveFramePng. scripts/capture-fensalir-frame.ps1 builds disposable engine/client slots and uses Start-Process with a timeout because Aquarium.Engine is a Windows GUI exe and plain PowerShell invocation can return before rendering is complete. The latest capture, artifacts/fensalir-captures/fixed-cathedral-forward.png, proves the current gap honestly: the cathedral silhouette is now visible and DSL patch claims drive surface/cathedral fields, but the spine/pillar grammar is still partly shader-authored and needs a real IFS-owned structural lowering before the splash reproduction stops being a hand-guided proxy.","files":["src/Aquarium.Engine/AquariumHost.cs","scripts/capture-fensalir-frame.ps1","src/Aquarium.Fensalir/FensalirRuntime.cs","src/Aquarium.Fensalir/FensalirSceneBuilder.cs","src/Aquarium.Fensalir/Shaders/D3D12FensalirScene.hlsl","src/Aquarium.Fensalir/Shaders/D3D12FensalirSpine.hlsl","src/Aquarium.Fensalir/Worlds/fensalir-spine-emblem.aquageo","tests/Aquarium.Engine.Fractal.Tests/FensalirFractalSceneTests.cs","state/map.yaml","state/memory.json"],"source":"user asked to exercise the cathedral through the DSL and set up fixed-camera headless capture for unattended renderer iteration"}
{"timestamp":"2026-05-22T01:32:00+01:00","topic":"fensalir-cathedral-guide-is-scaffolding","lesson":"The fixed capture made the visual failure impossible to dodge: Fensalir's previous shader/SDF mix had the nouns of the splash but not the image. A temporary screen-space cathedral guide now exposes the target composition more clearly in artifacts/fensalir-captures/fixed-cathedral-guide-clean.png, while SDF authority is cut back to the central spine/reeds instead of traced pillar rods fighting atmospheric glass. This guide is not final architecture. The next coherent slice is a separate `.aquageo`-lowered transparent pane/rune/material field target, distinct from the marsh height texture, so the cathedral glass, waterline glow, rune dust, and material confidence are authored field claims rather than hardcoded screen composition.","files":["src/Aquarium.Fensalir/Shaders/D3D12FensalirScene.hlsl","src/Aquarium.Fensalir/Shaders/D3D12FensalirSpine.hlsl","src/Aquarium.Fensalir/FensalirSceneBuilder.cs","state/map.yaml","state/memory.json"],"source":"user correctly mocked the prior receipt as visually nowhere near the provided splash reference"}
{"timestamp":"2026-05-23T00:00:00+01:00","topic":"fensalir-repo-split","lesson":"Fensalir now has its own adjacent repo at E:\\Projects\\Fensalir and owns the native host, renderer, contracts, fractal machinery, audio host, reload scripts, and engine demos. Epiphany Aquarium moved out to E:\\Projects\\Aquarium-Engine as a client repo that references Fensalir source projects until packaging exists. Keep dependency direction one-way: client repos may depend on Fensalir; Fensalir must not depend on client policy nouns.","files":["Fensalir.sln","README.md","AGENTS.md","state/map.yaml","state/memory.json"],"source":"user directed Fensalir and engine demos into a new adjacent repo while Aquarium-Engine remains only the Epiphany Aquarium client"}