Repository navigation
Conversation
Step 4's last box was diagnostic evidence, and it needed two harnesses because one binary cannot answer both questions. check_eshiview_host.sh builds the texture adapter twice from its real method-channel entry points and drives it from a platform thread against a stand-in raster queue, with no engine present: once under `leaks --atExit`, once under ThreadSanitizer. 24 cycles and 408 raster borrows report zero leaked bytes and no races. Both passes fail when they should — deleting LarimarTexture's surface lock produces a race report at the resize that swaps the buffer out from under an in-flight copy, and dropping the CVPixelBufferRelease produces one rooted CVPixelBuffer per cycle. check_eshiview_lifecycle.sh runs the same loop inside a real Flutter engine and snapshots `leaks` from outside the App Sandbox, because a sandboxed process cannot open its own task port. Twelve cycles end with every surface reclaimed and no growth in leaked bytes between the first cycle and the last. The host now accounts for what it allocates — surfaces created, resized, presented, disposed, still registered, still alive — and counts the engine's borrows separately. That last counter is the only instrument that separates "frames are being produced" from "frames are being composited", and captureSurface reads a view's surface back to a PNG without going through the compositor at all. The visual half of the gate uses both: RepaintBoundary.toImage does not reliably include an external texture layer, so a capture that can come back blank while everything works is not evidence when it comes back bright either. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
examples/pong/pong.mat was a hand transliteration of pong.gpu.cpp — same
sdBox, same glow, same constants, same score loop — and two copies of one
material agree right up until somebody edits one of them. It is gone. The
build now runs eshi-matgen over the shader source and pipes the result to
matc, so the Filament material is a *representation* of the file every
other tier already reads. Ripple gets the same treatment, which is what
lets a gallery shader reach Filament at all; it previously failed with
"material has no package_path".
The emitter is a third target in transpile.cpp beside GLSL and MSL, and
running it over the whole corpus is what taught us what the material
domain cannot express. 18 of the 20 programs compile through matc. The
other two refuse, loudly:
- warp.cpp samples iChannel0, and the material declares no sampler.
- rainforest.cpp opens its march loop inside #ifdef LOWQUALITY and
again inside the #else. Every compiler in the chain handles that;
matc splits a .mat into blocks by counting braces *before*
preprocessing, so the fragment block ran past its own closing brace
and matc reported an unexpected character on an innocent line.
A third finding was fixable rather than fatal: Filament's prelude defines
PI and HALF_PI, which lunar.cpp and seascape.cpp also use, so the
material target renames them the way the GLSL target already renames the
reserved noise builtins.
check_tier_conformance.sh turns the 1-LSB claim from a table in
ARCHITECTURE.md into a command: it renders both scenes on every tier the
host offers and compares raw frames, refusing to pass a tier that quietly
fell back to Ink. check_materials.sh holds the refusal list, which cannot
grow without someone editing it.
SHADER_SUBSET.md writes the subset down, answering ARCHITECTURE §9's
fifth open question. PLAN.md folds in the material pipeline as Step 6 and
the hero asset as Step 8, with S2L following in 6b as a frontend that
emits this subset rather than replacing it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
zig-out/bin/pong --grade paper, run from any directory but the repository root, rendered pure black frames, printed one line about a missing shader source, and exited zero — while the banner still announced backend=gl. The GPU tiers read their shader at runtime through a path relative to the working directory, and pong.cpp threw away the ESHI_ERR_UNSUPPORTED that eshi_material_set correctly returned. So: the shader sources install to zig-out/share/eshi/shaders and resolve from there or from ESHI_SHADER_DIR, pong::build returns its material result, and the host refuses to run a tier that cannot bind, naming the grade and the override rather than presenting an empty window. `zig build demo` renders both scenes on every tier the machine offers into build/demo, as video, beside the Flutter application and a note on what each file should show. Every other gate in this repository answers a machine's question; none of them answers "does it look right", and that question is not optional for a renderer. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Three defects, all of them found by running the application rather than by any gate: The paddles were outside the window. The material works in uv = (fragCoord * 2 - iResolution) / iResolution.y, so the horizontal extent of the scene *is* the view's aspect ratio and only the vertical one is fixed. The game placed its paddles at the 16:9 arena's edges, which is off screen in the 4:3 window Flutter opens by default — and the demo videos are 16:9, so they showed nothing wrong. The session now takes its arena width from the view, and the visual gate runs at 4:3 and requires something bright at each edge. Pinning the constant back fails it. There was no input at all, and the keys that did nothing also beeped: KeyboardListener never marks an event handled, so every keystroke walked the responder chain to AppKit. Both paddles now take the keyboard — W/S for cyan, the arrows for magenta, matching the SDL host — through a Focus that claims what it uses. And a match never ended. Neither host has a win condition; the score ran past the nine dots the material can draw and kept counting. The application plays to nine, announces the winner, and starts again, with an integration test that plays a one-point match and requires the announcement to appear and then clear. The C++ Pong keeps its endless scoring for now — its digests are what several other gates compare. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Step 5's first bullet, and the one the rest of it waits on. Filament is a large CMake project with its own toolchain expectations, so consumers get the official prebuilt release: scripts/vendor_filament.sh fetches v1.75.0, verifies its SHA-256, and extracts it to third_party/filament/<version>. The checksum is what makes the pin mean anything — pointing the script at a different version's archive is refused rather than quietly installed, which is the control that proves it. That path is now -Dfilament-path's default, replacing a local source build under resources/. A renderer that links a different Filament than the one its materials were compiled by is a debugging afternoon nobody needs, and the old default made that the easy case. It also closes the hole Step 6a had to leave open. matc is a build-time tool and needs no GPU, so both the Linux and macOS jobs now *compile* every material the emitter produces — 18 of them, with the two documented refusals still refusing — and the macOS job renders Pong and ripple through Filament and compares them against Ink, within 1 LSB, on the same Metal probe the shader validation uses. Attribution and the Apache-2.0 obligations are recorded in third_party/NOTICE.md; the build already installs the distribution's LICENSE beside any binary that links it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Step 5's substantive half. EshiAsset is an opaque uint32_t and eshi_asset_load/_instance/_release/_count route to four *optional* vtable entries, so the capability ladder lives in the backend table rather than in a grade comparison: Ink, Paper and direct Metal leave them null and every asset call answers ESHI_ERR_UNSUPPORTED. No Filament type appears in the public header. The ABI minor moves to 1.1.0 — additive, so a package built against 1.0 still loads — and the Dart bindings are regenerated. The Filament backend gains a real scene. gltfio parses and uploads; assets are created instanced from the start, so three copies of the logo report `instances=3 assets=1` rather than three uploads. A world may now hold geometry and no fullscreen material at all, which is why filament_create no longer requires a package. Three things only a rendered frame exposed. Filament was never told to clear, so the 3D frame came back over a magenta field with staircase blocks of stale tile memory around the silhouette — the fullscreen quad had been covering the question. glTF asset conventions had to be stated rather than inherited: right-handed Y-up metres, 45° vertical FOV, photographic exposure, one daylight directional light. And a textured model rendered as a black silhouette, because gltfio drops every image it has no decoder for, says so once on stderr, and carries on — the greybox has no textures, so only a real asset showed it. The stb and KTX2 providers are registered now, and the gate fails on that stderr line. Image-based lighting is still missing, so the reference material is a dielectric; a metal would render dark and read as a bug rather than as the absent feature it is. The reference asset is generated by eshi-gemgen — an icosahedron with flat facets and a PBR material, written straight out as a GLB — for the same reason the materials are generated rather than checked in. PLAN Step 8 replaces it with a Blender-authored gem at the same path. check_asset_render.sh is the gate, and it does not trust a successful load: it renders the asset with no instances placed and with one, and fails if the two frames match. It also requires a missing file, a corrupt file, and the Ink tier each to be refused by name. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`zig build demo` aborted with a Zig panic and a stack trace — `pkg-config failed for library SDL2_ttf` — on a machine where every dependency is installed. The cause is that devkitpro ships its own pkg-config, and on PATH it wins: its built-in search path contains only devkitpro's packages. Setting PKG_CONFIG_PATH fixes it, which is why this never appeared in a session that exported it. build.zig now probes pkg-config once and, only when that probe fails, points PKG_CONFIG_PATH at the Homebrew prefix — including Library/Homebrew/os/mac/pkgconfig, where SDL2_ttf's transitive freetype and zlib entries actually live. A machine whose pkg-config already works is left untouched, and a machine that still cannot find SDL gets a sentence instead of a stack trace. Two more things that command surfaced. The Flutter build inside the demo failed with `library 'gltfio' not found`: a release macOS app is universal, the pinned Filament distribution ships lib/arm64 only, and the x86_64 slice had nothing to link. The native-asset hook now builds that slice without the Filament backend rather than failing the whole app — it keeps Ink and Metal, which is what a host without a tier is supposed to do. And the skipped 3D clip now names the flag that would produce it instead of blaming the host. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
eshi.hunchangedEshiView, source-backed material uniforms, animated Pong, and serialized resize/lifecycle/disposalVerified locally
zig build test(238 checks)zig build abi-test(187 checks)flutter analyze && flutter testinbindings/dart/larimar(11 tests)flutter analyze && flutter testinexamples/larimar_flutterflutter test integration_test/eshiview_smoke_test.dart -d macosflutter build macos --releaseRemaining Step 4 gate
PLAN.mdkeeps Step 4 in progress until those two evidence items are complete.