Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
261 commits
Select commit Hold shift + click to select a range
b41bfaa
fix(terrain): a landform cook plants the biome's tree with the art th…
jonit-dev Nov 5, 2026
89068d4
docs(strata): PR chain for the open terrain work, with the noise and …
jonit-dev Nov 8, 2026
4d61d25
docs(strata): PR-5 makes one terrain request decide the landform, wat…
jonit-dev Nov 8, 2026
0d5b417
docs(strata): PR-5 estimate follows its wider scope
jonit-dev Nov 8, 2026
9000247
test(terrain): the forest golden world.glb hash follows the E46 float…
jonit-dev Nov 8, 2026
ce0ef10
docs(PRD-854..856): file the three new Strata chain items (request de…
jonit-dev Nov 8, 2026
e1ba845
docs(strata): the README records the EPIC merge and points at the PR …
jonit-dev Nov 8, 2026
4d899bd
feat(terrain): a terrain_generate request's words also pick the landf…
jonit-dev Nov 8, 2026
d554712
Revert "fix(native-engine): a draw that wrote no depth keeps its cust…
jonit-dev Nov 8, 2026
468ad31
docs(PRD-806): E46 and E56 land on PR #635; E73 is reverted after its…
jonit-dev Nov 8, 2026
0a51131
docs(PRD-585, PRD-595): the Strata web playtest passes every function…
jonit-dev Nov 8, 2026
8c1c969
Reapply "fix(native-engine): a draw that wrote no depth keeps its cus…
jonit-dev Nov 8, 2026
4025c1e
docs(PRD-806): the alpine shadow loss was run-to-run flake on an upst…
jonit-dev Nov 8, 2026
c478ccd
docs(PRD-806): status line follows the boxes
jonit-dev Nov 8, 2026
d35415e
feat(terrain): a landform cook grounds on a real survey with its attr…
jonit-dev Nov 8, 2026
389c82b
fix(strata): the horizon walk-band collider leaves enter, built in pe…
jonit-dev Nov 8, 2026
396bfe9
docs(PRD-806): E73 passes the owned-engine judge NEUTRAL
jonit-dev Nov 8, 2026
4cc88d6
fix(strata): the backdrop's rock beds dip, vary and break instead of …
jonit-dev Nov 8, 2026
7b4313a
docs(PRD-762): the MCP terrain starts on the default engine in a fres…
jonit-dev Nov 8, 2026
3af7962
docs(PRD-856): the warped fbm box already holds; cite the code and th…
jonit-dev Nov 8, 2026
4a60df2
fix(three-native): the web engine's glTF loader returns every scene, …
jonit-dev Nov 8, 2026
743dddf
style: biome format the LOD loader spec mock
jonit-dev Nov 8, 2026
c5c9484
refactor(three-native): name the glTF handle split
jonit-dev Nov 8, 2026
1668c0b
feat(terrain): gully and scree erosion passes ported from heightmap-l…
jonit-dev Nov 8, 2026
5848612
docs(PRD-762): the remaining main-pass cost is the CPU world path; th…
jonit-dev Nov 8, 2026
6bd2210
docs(PRD-857): the GPU world scene runs on the owned engine, from the…
jonit-dev Nov 8, 2026
331a1f3
feat(three-native,runtime-native): hasFeature, IndirectStorageBufferA…
jonit-dev Nov 8, 2026
a106416
fix(runtime-native): hold the indirect-first-instance request until t…
jonit-dev Nov 8, 2026
139fff2
feat(runtime-native): draw a geometry's own indirect record on every …
jonit-dev Nov 8, 2026
86b19dd
feat(core,runtime-native): cull kernels read placements as vec4 rows,…
jonit-dev Nov 8, 2026
9724a55
fix(runtime-native): stop requesting indirect-first-instance, the GPU…
jonit-dev Nov 8, 2026
bc1a85d
fix(PRD-857): the GPU world scene runs on the owned engine: planes fr…
jonit-dev Nov 8, 2026
023106f
fix(PRD-857): an indirect draw reads its instances where the GPU wrot…
jonit-dev Nov 8, 2026
e415146
fix(PRD-857): the web facade sends an updateRanges record edited in p…
jonit-dev Nov 8, 2026
59d654e
fix(PRD-857): the GPU world scene grades levels and maxDistance from …
jonit-dev Nov 8, 2026
5be2a92
feat(PRD-857): the Wasm host requests indirect-first-instance when th…
jonit-dev Nov 8, 2026
2d8ac4a
docs(PRD-857): phases done, judge NEUTRAL after the shared LOD eye, a…
jonit-dev Nov 8, 2026
a3dc5ae
docs(PRD-762): the default engine selects the threejs arm's own trian…
jonit-dev Nov 8, 2026
b91bb54
fix(PRD-762): Frustum.intersectsObject and intersectsSprite on the ow…
jonit-dev Nov 8, 2026
c899764
fix(PRD-762): a TSL join cuts an input that runs past the vector's le…
jonit-dev Nov 8, 2026
1f17fc5
fix(PRD-762): the world's visible-draw gate counts a main draw on an …
jonit-dev Nov 8, 2026
e2ab24b
fix(PRD-762): VirtualShadowNode's stats and settled follow the owned …
jonit-dev Nov 8, 2026
7bad7d9
docs(PRD-762, PRD-858): the kit's gaps closed on the default engine; …
jonit-dev Nov 8, 2026
b706de1
style(PRD-762): the shadow frame report takes the web host module's o…
jonit-dev Nov 8, 2026
969c24b
fix(PRD-762): the playtest worker probe is bounded, so the owned engi…
jonit-dev Nov 8, 2026
357d37a
feat(PRD-858): an array render target draws the layer setRenderTarget…
jonit-dev Nov 8, 2026
4731d36
feat(PRD-858): a material's diffuseColor and its output/normal MRT no…
jonit-dev Nov 8, 2026
b67e3e3
feat(PRD-858): the impostor surface draws on the owned engine: elemen…
jonit-dev Nov 8, 2026
1c7c375
fix(PRD-858): a failed impostor bake or surface reports its error on …
jonit-dev Nov 8, 2026
dd3ecca
fix(PRD-858): three's mat3(mat4) lowers to the upper-left 3x3 on the …
jonit-dev Nov 8, 2026
2472fe9
fix(PRD-858): a shadow caster's alphaTestNode samples the node's own …
jonit-dev Nov 8, 2026
f0e06fb
docs(PRD-858): impostors bake on the default engine; overview wideTri…
jonit-dev Nov 8, 2026
2641bef
fix(PRD-762): the starter kit verifier refuses to pack a package whos…
jonit-dev Nov 8, 2026
9053899
docs(PRD-858): record the drawRange engine gap and the paired overvie…
jonit-dev Nov 8, 2026
0d6fb6f
perf(PRD-858): a node the normalNode shares with the other slots lowe…
jonit-dev Nov 8, 2026
74ccf22
perf(PRD-858): a hoisted TSL variable is declared after the variables…
jonit-dev Nov 8, 2026
0520b4f
docs(PRD-858): the overview presents at 60 fps on the engine; record …
jonit-dev Nov 8, 2026
e5c4323
perf(PRD-858): an opaque material's program carries no alphaTest discard
jonit-dev Nov 8, 2026
1283fac
fix(PRD-762): a frozen world draw follows a moved world root
jonit-dev Nov 8, 2026
3e0aa0c
fix(PRD-762): the terrain snippet seats the cooked world on the game'…
jonit-dev Nov 8, 2026
0e12db1
fix(PRD-762): a moved world root culls and grades in its own frame
jonit-dev Nov 8, 2026
5bed1f3
test(PRD-762): assign onto a varying and a swizzle lane, as SkyMesh w…
jonit-dev Nov 8, 2026
e86898c
docs(PRD-762): the kit verifier at HEAD fails only on frame time
jonit-dev Nov 8, 2026
77d2a25
docs(PRD-859): the game thread wins the CPU against everything else o…
jonit-dev Nov 8, 2026
7eea0e3
perf(PRD-858): the far impostor tier draws after the nearer tiers
jonit-dev Nov 8, 2026
06f4615
fix(strata): far mountains keep their surveyed ridges
jonit-dev Nov 8, 2026
2c3b9b5
feat(strata): pnpm dev cooks the Fab forest itself
jonit-dev Nov 8, 2026
ccc8018
refactor(strata): the Fab cook drops the zero-normal repair the impor…
jonit-dev Nov 8, 2026
44e3507
fix(engine): colorNode foliage bakes impostors on the default engine
jonit-dev Nov 8, 2026
d46e628
style(core): format the impostor surface fix
jonit-dev Nov 8, 2026
ef3c56a
fix(engine): MRT attachments after the first clear to (0, 0, 0, 1), a…
jonit-dev Nov 9, 2026
7f111c0
feat(strata): the ground's ambient reads the relief's sky visibility …
jonit-dev Nov 9, 2026
e57a6e2
feat(terrain): a river row with no layer runs down the ground's own d…
jonit-dev Nov 9, 2026
ecd2a1a
docs(PRD-860): the first scene plays before the game finishes downloa…
jonit-dev Nov 9, 2026
071fc65
docs(PRD-855): Unreal 5.8.3 grass and layer-blend defaults, each line…
jonit-dev Nov 9, 2026
ec2ddbb
style(terrain): format the river routing cases
jonit-dev Nov 9, 2026
7ebb335
docs(PRD-790): biome rows and their refusals shipped in #483, proven …
jonit-dev Nov 9, 2026
d4a727e
docs(PRD-583): the layered cook spec holds at HEAD; the judge stays open
jonit-dev Nov 9, 2026
1ed7319
docs(PRD-856): Unreal 5.8.3 erosion and landscape LOD defaults, each …
jonit-dev Nov 9, 2026
980a8bd
docs(PRD-762): reveal time and presented FPS of the MCP forest on a r…
jonit-dev Nov 9, 2026
db30b18
perf(native-engine): a draw refreshed every frame keys its sort depth…
jonit-dev Nov 9, 2026
5bace73
perf(native-engine): a morphed draw reuses its packed targets until a…
jonit-dev Nov 9, 2026
de18730
perf(native-engine): a morphed caster's shadow box holds every influe…
jonit-dev Nov 9, 2026
4c88c3a
docs(PRD-762): three per-vertex walks named and removed from the fore…
jonit-dev Nov 9, 2026
9280b48
docs(PRD-856): the far rings are cooked from same-site USGS surveys, …
jonit-dev Nov 9, 2026
2f317c9
fix(strata): the sand band follows each world's water level
jonit-dev Nov 9, 2026
8870e79
docs(PRD-594): the pre-#381 parent draws no virtual shadow on the fix…
jonit-dev Nov 9, 2026
dd6e8d4
docs(PRD-856): the mountain defect list from the 2f317c907 frames
jonit-dev Nov 9, 2026
d565737
docs(PRD-762): the default engine judges NEUTRAL against the threejs …
jonit-dev Nov 9, 2026
6f5bf56
docs(PRD-583): the cooked forest renders headed and passes the engine…
jonit-dev Nov 9, 2026
eeac85b
feat(core): a whole-file load after the reveal reports TN_ASSET_LATE …
jonit-dev Nov 9, 2026
6a62ad1
fix(strata): the forest's bare earth reads as humus, L* 53 to 35 at t…
jonit-dev Nov 9, 2026
8bbade2
docs(PRD-855, PRD-856): the forest walk logs no scene warning, and th…
jonit-dev Nov 9, 2026
2e49e10
fix(strata): each forest grass clump takes its own hue and a shaded root
jonit-dev Nov 9, 2026
ecbc0e0
docs(PRD-855): the loop shows the same late-pipeline flake with and w…
jonit-dev Nov 9, 2026
3c945cf
docs(PRD-856): the horizon ring measures no seam gap on three worlds
jonit-dev Nov 9, 2026
a7abee0
docs(PRD-860): execution measures 136.4 MB before first play and four…
jonit-dev Nov 9, 2026
64e82ed
docs(PRD-583): the game has no first-layer arm for the layered judge
jonit-dev Nov 9, 2026
825bd19
perf(strata): the sky LUT and the river build run in load, not in the…
jonit-dev Nov 9, 2026
36cfb27
docs(PRD-856): the forest backdrop squiggles are lit normals, not snow
jonit-dev Nov 9, 2026
ecebc2f
docs(PRD-806): E49 red-green on the V8 texture test; chain step 0 rev…
jonit-dev Nov 9, 2026
3817a95
test: impostor surface and river routing specs typecheck under TS 7 s…
jonit-dev Nov 9, 2026
7abe7d4
docs(strata): chain step 0 gates ran green on the PR head
jonit-dev Nov 9, 2026
feaf012
fix(terrain): alpine, desert and tundra dress the mid boulder their a…
jonit-dev Nov 9, 2026
019fbbc
docs(PRD-806): every low finding answered: 43 fixed in the EPIC, E57 …
jonit-dev Nov 9, 2026
b17da1d
docs(PRD-858): the near-fir census gap is resident instances; the GPU…
jonit-dev Nov 9, 2026
b615fd0
test(strata): the build-package fixture carries each world's sky visi…
jonit-dev Nov 9, 2026
fab0e73
docs(native): regenerate the coverage record for the chain's engine s…
jonit-dev Nov 9, 2026
2c92629
fix(runtime-native): the WebGPU facade imports IndirectStorageBufferA…
jonit-dev Nov 9, 2026
1cea8cd
docs(PRD-806): AC-1 ticked from the green board on 2c9262966
jonit-dev Nov 9, 2026
9bef498
docs(PRD-584): the forest walk is GPU-bound at 20 ms on 13.6 M near-f…
jonit-dev Nov 9, 2026
53dc4df
docs(PRD-806): E57 judged NEUTRAL on the alpine kit; every low findin…
jonit-dev Nov 9, 2026
20fd01f
fix(terrain): a landform cook keeps its trees out of the starter aren…
jonit-dev Nov 9, 2026
5f89f1e
docs(PRD-806): E62 judged IMPROVEMENT once the landform cook clears t…
jonit-dev Nov 9, 2026
779aafd
docs(PRD-806): done — every medium and low epic-review finding is fix…
jonit-dev Nov 9, 2026
871ac00
docs(PRD-806): status DONE, links and the strata index row follow the…
jonit-dev Nov 9, 2026
01f6b37
feat(strata): one height joins the square to the collar with no step …
jonit-dev Nov 9, 2026
7db499c
docs(PRD-861): the owned engine's missing decoders get their own PRD
jonit-dev Nov 9, 2026
d413ad0
docs(PRD-860): the runtime measures 139.5 MB awaited, and who waits it
jonit-dev Nov 9, 2026
5d723ea
docs(PRD-580): five-kit art baseline, no rubric row at 4 yet
jonit-dev Nov 9, 2026
e0d4a28
docs(PRD-580): the elevated white void is the missing horizon, which …
jonit-dev Nov 9, 2026
ef85c3f
docs(PRD-790): the streamed-tile design, split by one square around t…
jonit-dev Nov 9, 2026
9c5dac5
feat(strata): stream ground tiles past the square behind ?stream=1 (P…
jonit-dev Nov 9, 2026
d24f7a2
docs(PRD-790): judge NEUTRAL; late pipelines are the lake mirror chur…
jonit-dev Nov 9, 2026
0975f88
docs(PRD-790): the lake pipeline churn keeps one program; the render-…
jonit-dev Nov 9, 2026
8493465
docs(PRD-790): the lake pipeline churn is in the owned engine's cache…
jonit-dev Nov 9, 2026
3580aab
fix(strata): the lake draws both sides in one pass, so a turn rebuild…
jonit-dev Nov 9, 2026
61aeb2c
docs(PRD-790): the four late pipelines left, each named by its first …
jonit-dev Nov 9, 2026
948719e
fix(strata): the curtain waits for the first streamed tiles to draw (…
jonit-dev Nov 9, 2026
6e5ffa4
fix(strata): read groundReady from the meadow's destructured options
jonit-dev Nov 9, 2026
9117d20
docs(PRD-790): a lake warmed behind the curtain fixes the mirror pipe…
jonit-dev Nov 9, 2026
a928d65
docs(PRD-585): the strata job is skipped by TN_CI_STRATA_GPU=false, n…
jonit-dev Nov 9, 2026
f745849
refactor(strata): one world list feeds the bake, the keys and WorldNa…
jonit-dev Nov 9, 2026
0ecc78c
fix(core,strata): build the shadow reset quad and the lake mirror beh…
jonit-dev Nov 9, 2026
43ecdf3
Merge remote-tracking branch 'origin/develop' into prd-860-first-scene
jonit-dev Nov 9, 2026
2fa4814
docs(PRD-790): stream run green on a quiet host; tile seams 0
jonit-dev Nov 9, 2026
1a3a90f
feat(core): KTX2 level index, Unreal wanted-mip rule and coarse-first…
jonit-dev Nov 9, 2026
7d17a33
fix(playtest): the bridge handshake waits the startup window, not 30 …
jonit-dev Nov 9, 2026
74179d4
feat(PRD-863): one river surface for the preview and the kits, drawn …
jonit-dev Nov 9, 2026
9650c1e
feat(PRD-863): the lake surface the swimmer floods is a core mesh
jonit-dev Nov 9, 2026
bfbe5cd
feat(PRD-863): shore distance and open-sea exposure are one core field
jonit-dev Nov 9, 2026
ee3af9c
feat(core): TN_ASSET_UNUSED names the awaited models nothing drew (PR…
jonit-dev Nov 9, 2026
0d59424
style(PRD-863): format the lake coverage spec
jonit-dev Nov 9, 2026
68c2a9c
fix(core): a failed start-scene load answers the runner's describe at…
jonit-dev Nov 9, 2026
fa5ffa1
docs(PRD-860): AC-1 and AC-2 ticked with the 40 Mbps RTX 2080 runs; f…
jonit-dev Nov 9, 2026
0468fc6
feat(PRD-863): streamed ground uses core's budget, settled block and …
jonit-dev Nov 9, 2026
b2fac1a
docs(PRD-863): TerrainTiles names settledHalf's situations for the ca…
jonit-dev Nov 9, 2026
748b742
fix(core): a compile no longer copies the canvas into a refracting ma…
jonit-dev Nov 9, 2026
52d7efd
refactor(PRD-863): the preview's biome bands come from measureBands
jonit-dev Nov 9, 2026
4971a2c
feat(PRD-863): the drawn-surface sampler is core's surfaceSampler
jonit-dev Nov 9, 2026
cdeded4
docs(PRD-863): AC-2, every moved export ranks first for its situation
jonit-dev Nov 9, 2026
78612cd
docs(PRD-790): the dotted line was likely the old river cut; water sp…
jonit-dev Nov 9, 2026
2688e9d
feat(PRD-864): static prop posing is core's staticLowestY, footprintG…
jonit-dev Nov 9, 2026
c5d2ede
perf(web-engine): glTF models parse on a loader thread, not in play (…
jonit-dev Nov 9, 2026
25338d8
feat(PRD-864): model sections, shared base and normal repair are core
jonit-dev Nov 9, 2026
c0b2e2b
feat(PRD-864): the prop bucket decode is the terrain package's decode…
jonit-dev Nov 9, 2026
2bae24e
perf(web-engine): the glTF loader thread decodes on its own two worke…
jonit-dev Nov 9, 2026
c5fb33b
docs(PRD-860): the loader thread and its pool, with the paired frame …
jonit-dev Nov 9, 2026
564804f
feat(PRD-864): fetchAsset is core's one resolve-then-fetch loop
jonit-dev Nov 9, 2026
5454264
docs(PRD-864): why four other fetch loops keep their own walk
jonit-dev Nov 9, 2026
d83ef95
docs(PRD-863): the kits keep their contour-clipped lakes; they run no…
jonit-dev Nov 9, 2026
ab0155c
docs(PRD-863): AC-1, every mechanism moved or kept with a reason
jonit-dev Nov 9, 2026
7a3f9a6
Revert "perf(web-engine): the glTF loader thread decodes on its own t…
jonit-dev Nov 9, 2026
41e54c3
docs(PRD-860): quiet-host paired runs, and why the loader pool was re…
jonit-dev Nov 9, 2026
764c0a5
docs(PRD-595): the preview walk passes after the split; machinefall w…
jonit-dev Nov 9, 2026
6702fc4
docs(PRD-798): the Strata, abyss and judge box closes; its parts are …
jonit-dev Nov 9, 2026
3e614f3
docs(PRD-854): snapshot names the new fields; PRD-854 done
jonit-dev Nov 9, 2026
c813abb
fix(PRD-863): a river cap past an end over falling ground is not draw…
jonit-dev Nov 9, 2026
89372d5
fix(core): addInSlices presents a frame between slices once the world…
jonit-dev Nov 9, 2026
297944c
Merge remote-tracking branch 'origin/develop' into prd-860-first-scene
jonit-dev Nov 9, 2026
f2aaa9a
fix(three-native): an InstancedBufferAttribute is isInstancedBufferAt…
jonit-dev Nov 9, 2026
2e45fb4
fix(web-engine): the loader-thread calls take web host ABI 12 (PRD-860)
jonit-dev Nov 9, 2026
a3f860c
docs(PRD-858): the forest kit's GPU tail is the sun shadows and full …
jonit-dev Nov 9, 2026
b1b2e71
test(three-native): every bound class carries the is* flags three's o…
jonit-dev Nov 9, 2026
c9a1eac
test(three-native): the flag guard covers the JS ports and three/webg…
jonit-dev Nov 10, 2026
a0e2fab
feat(core): a KTX2 texture streams by Range, mip tail first (PRD-860 …
jonit-dev Nov 10, 2026
70ea62e
feat(assets): a LOD-chained model ships a coarse companion with its o…
jonit-dev Nov 10, 2026
9dbe798
fix(core): a LOD level's triangle count is read once, not every frame
jonit-dev Nov 10, 2026
2a8442b
feat(core): a streamed model draws its coarse companion first, then t…
jonit-dev Nov 10, 2026
ba3ba62
fix(assets): the compile cache keys on the coarse companion
jonit-dev Nov 10, 2026
695abec
docs(PRD-860): AC-7 bytes pair and AC-8 web judge evidence
jonit-dev Nov 10, 2026
676352a
docs(PRD-860): tick AC-8, web judge NEUTRAL and native desktop SAME
jonit-dev Nov 10, 2026
99db6b5
feat(PRD-861): the owned web engine cooks and loads meshopt geometry
jonit-dev Nov 10, 2026
79a73a2
test(create-threenative): the native-engine web cook emits meshopt ge…
jonit-dev Nov 10, 2026
e603997
feat(strata-forest): a continuous wood, lit grass and a 60 FPS walk pose
jonit-dev Nov 9, 2026
9f6e7b3
feat(terrain): the understorey is a biome row, and the forest grows f…
jonit-dev Nov 9, 2026
1fbcf58
feat(strata-forest): a look tweak box (?tweak), crown shade on the un…
jonit-dev Nov 10, 2026
0bd75c2
docs(PRD-861): name PRD-860 without a link to a file this tree does n…
jonit-dev Nov 10, 2026
0e6a2ab
feat(PRD-861): the owned engine transcodes a model's KTX2 textures
jonit-dev Nov 10, 2026
c9b1794
wip(PRD-866): surveyed massif placement and 4 m relief
jonit-dev Nov 10, 2026
c8000fa
fix(PRD-861): the owned engine's web cook keeps KTX2 off, by measurement
jonit-dev Nov 10, 2026
4a4c65e
docs(PRD-861): meshopt lands on the owned web engine; KTX2 decodes bu…
jonit-dev Nov 10, 2026
145ac82
test(PRD-861): the hierarchy test stops expecting KHR_texture_basisu …
jonit-dev Nov 10, 2026
5e4a7a1
docs(PRD-861): refresh the native coverage record for the meshopt and…
jonit-dev Nov 10, 2026
54a33dd
docs(PRD-867): plan the owned engine's compressed texture upload and …
jonit-dev Nov 10, 2026
08b7caa
feat(PRD-866): a surveyed mountain with wooded lower slopes stands be…
jonit-dev Nov 10, 2026
a7ae6f8
style(PRD-866): format the massif tile metadata
jonit-dev Nov 10, 2026
c042ce1
feat(PRD-867): the owned engine uploads BC7 and ETC2 textures, and KT…
jonit-dev Nov 10, 2026
b2b312c
fix(PRD-866): the massif's near flank fades over 600 m behind a 650 m…
jonit-dev Nov 10, 2026
dffef46
docs(PRD-866): phase 1 and placeMassif boxes ticked with their results
jonit-dev Nov 10, 2026
2d1c2ae
feat(PRD-866): terrain_generate cooks a far ring with a real massif
jonit-dev Nov 10, 2026
a42b4ce
feat(PRD-867): three's CompressedTexture and KTX2Loader run on the ow…
jonit-dev Nov 10, 2026
36f4db3
Merge develop into prd-860-first-scene
jonit-dev Nov 10, 2026
c93a644
Merge prd-867-compressed-upload (PR #651) into prd-860-first-scene
jonit-dev Nov 10, 2026
faf3d94
feat(PRD-860): a streamed model's KTX2 textures draw their resident m…
jonit-dev Nov 10, 2026
4a711a8
feat(PRD-866): a cooked world bakes into the forest, and a seed moves…
jonit-dev Nov 10, 2026
420f770
docs(PRD-860): the capability manifest names coarse-first model and t…
jonit-dev Nov 10, 2026
d21694e
feat(PRD-867): the web cook keeps a WebP a KTX2 cannot undercut, and …
jonit-dev Nov 10, 2026
22c25e9
fix(PRD-866): a forest under mountains cooks a true-scale valley floo…
jonit-dev Nov 10, 2026
80141f6
style(PRD-866): verify-variations names its env key without a lint su…
jonit-dev Nov 10, 2026
6f8b5e9
fix(PRD-866): the forest's treeline and snow stay in metres above the…
jonit-dev Nov 10, 2026
b70f0e9
fix(PRD-861): the owned web engine reads a meshopt-compressed LOD chain
jonit-dev Nov 10, 2026
02a2a53
wip(PRD-866): far forest near band behind ?farForest=near|on|off (tun…
jonit-dev Nov 10, 2026
421414d
style(PRD-866): biome import order and format
jonit-dev Nov 10, 2026
bbc9332
fix(PRD-867): a KTX2 decoded on a pool worker no longer hangs the thr…
jonit-dev Nov 10, 2026
5586f69
perf(PRD-866): a far spruce draws its coarsest cooked level until its…
jonit-dev Nov 10, 2026
1e8cfca
feat(PRD-866): a cooked forest of another size keeps its camera poses…
jonit-dev Nov 10, 2026
e9eac4a
docs(PRD-870): the procedural forest set reads like the Fab set; ?fab…
jonit-dev Nov 10, 2026
193960d
docs(PRD-867): tick AC-4 and PRD-861 AC-1 with the starter bake, reco…
jonit-dev Nov 10, 2026
fecc288
Merge remote-tracking branch 'origin/prd-860-first-scene' into prd-86…
jonit-dev Nov 10, 2026
b49f6e7
feat(PRD-866): a small or huge forest cooks and bakes; the floor's re…
jonit-dev Nov 10, 2026
b4c90a0
build(PRD-867): the web engine budget is 4 MiB + 64 KiB
jonit-dev Nov 10, 2026
e92ff9c
perf(core): a whole-asset impostor's quad fits its baked box, not its…
jonit-dev Nov 10, 2026
f8fdcc7
docs(PRD-870): phase 1 measured: spruce canopy colour is the largest …
jonit-dev Nov 10, 2026
dd5147c
look(strata): the procedural spruce crown takes the Fab spruce's dark…
jonit-dev Nov 10, 2026
70d24e6
docs(PRD-866): the far band's cost is impostor fragments, mislabelled…
jonit-dev Nov 10, 2026
2d4ff9b
look(strata): a procedural meadow flower is one low stem with a small…
jonit-dev Nov 10, 2026
422dc3f
look(strata): a stand spruce shows its trunk to two fifths of its hei…
jonit-dev Nov 10, 2026
2dad222
docs(PRD-870): the procedural overview cost sits on the far spruce le…
jonit-dev Nov 10, 2026
e7016b3
fix(PRD-860/867): review findings on streamed models and the owned en…
jonit-dev Nov 10, 2026
ba6ddb9
feat(PRD-867): a KTX2 model draws on the owned web engine, proven on …
jonit-dev Nov 10, 2026
2dc084a
Merge remote-tracking branch 'origin/prd-860-first-scene' into prd-86…
jonit-dev Nov 10, 2026
911c7cb
fix(PRD-860): the glTF loader thread parks in the reviewed worker wai…
jonit-dev Nov 10, 2026
995af26
fix(PRD-866): a cooked forest frames its massif and keeps trees on it…
jonit-dev Nov 10, 2026
94b8219
docs(PRD-866): AC-2 passes: three seeded forests share one look with …
jonit-dev Nov 10, 2026
8152420
docs(PRD-866): AC-1 passes; AC-3 fails at 20 -> 15 FPS and waits on t…
jonit-dev Nov 10, 2026
d6ed62e
docs(PRD-866): AC-3 levers measured: draw order and farther impostor …
jonit-dev Nov 10, 2026
fbe10b5
docs(PRD-866): AC-3: atlas reads and empty-path skips are not the far…
jonit-dev Nov 10, 2026
f92f5a2
fix(PRD-860): a host without Range sends each streamed KTX2 once; the…
jonit-dev Nov 10, 2026
f0b6911
fix(PRD-860): a streamed texture's whole file keeps the anisotropy, w…
jonit-dev Nov 10, 2026
0b255c4
test(PRD-861): the web native engine's cook keeps Meshopt and KTX2, w…
jonit-dev Nov 10, 2026
a0533a6
docs(PRD-860): done — Midway plays after 22.4 MB in 10.4 s at 40 Mbps…
jonit-dev Nov 10, 2026
92f7242
docs(PRD-860): every streaming abstraction of #643 answers capability…
jonit-dev Nov 10, 2026
1034491
Merge remote-tracking branch 'origin/develop' into HEAD
jonit-dev Nov 10, 2026
8d383fc
Merge PR #643 (PRD-860/861/867: streamed meshes and textures, async g…
jonit-dev Nov 10, 2026
811f138
fix(strata): the example's 17 red specs pass, and the cooked bake no …
jonit-dev Nov 10, 2026
3d6f3b5
perf(PRD-866): far impostors march the depth atlas once per pixel, no…
jonit-dev Nov 10, 2026
1f5ff6a
style: biome format and import order for the merge's touched files
jonit-dev Nov 10, 2026
4a32743
feat(terrain): terrain_generate cooks a world from any request, and c…
jonit-dev Nov 10, 2026
913c602
style(terrain): biome format for the request words and starter aliases
jonit-dev Nov 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion docs/PRDs/BLOCKED/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ dependency is not ready.
| [`requires-release-credentials/`](requires-release-credentials/) | [PRD-445](requires-release-credentials/PRD-445-public-release-hygiene.md) | An upstream `threenative-sculpt-mcp` release that moves its `sharp` pin off `0.35.3`, and three owner calls on tracked repository junk. Every box in it is ticked; only the `## Blocked on` list is open. Filed here 2026-09-25 under R6. The `CLOUDFLARE_API_TOKEN` item left this list the same day: the owner set both `site-production` secrets and the `site` run on `main` (36063649413) went green |
| [`requires-owner-provider-checkpoint/`](requires-owner-provider-checkpoint/) | [PRD-P2-5](requires-owner-provider-checkpoint/PRD-P2-5-evidence-storage-boundary.md) | An owner checkpoint naming the bulk-evidence provider, credentials source, retention policy, cost bound, and restore owner. Phase 1 (immutable evidence manifests, Git-only) is delivered and green; only provider selection is an owner decision no agent can make |
| [`requires-examples-checkout/`](requires-examples-checkout/) | [PRD-443](requires-examples-checkout/PRD-443-lossless-gltf-flatten-join-instance.md) | A commit in the `ThreeNativeHQ/examples` checkout replacing the five AC-5-verified compacted GLBs, and Midway's own `tools/run-handoff.sh` gates (`check-carrier-cycle`, `check-repair`, `maxPassTriangles`) going green there. No code change is left in this repository: the engine passes, proof and 0.3.4 release all landed. Every box is ticked; only the `## Blocked on` list is open. Filed here 2026-09-25 under R6 |
| [`requires-owner-decision/`](requires-owner-decision/) | [PRD-299](requires-owner-decision/PRD-299-request-decomposition-index.md) | An owner ruling in §0 of the PRD. |
| [`requires-owner-decision/`](requires-owner-decision/) | [PRD-299](requires-owner-decision/PRD-299-request-decomposition-index.md), [PRD-866](requires-owner-decision/PRD-866-a-generated-forest-stands-under-mountains-with-real-shapes.md) | An owner ruling in §0 of the PRD; for PRD-866, its `## Blocked on` line (AC-3 frame cost). |
| [`requires-sky-light-occlusion/`](requires-sky-light-occlusion/) | [PRD-635](requires-sky-light-occlusion/PRD-635-ambient-occlusion-darkens-only-the-light-that-comes-from-around.md) | PRD-662 (sky light occlusion when dynamic GI is off) lands; then a rerun of `pnpm unreal-look:compare --layer L6` for AC-1 and a fresh visual judge on the L9 interior frames |

**A PRD whose only remaining work is `## Blocked on` items lives here** (owner decision,
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ flowchart LR
| Niagara runtime (+ shader, vertex factories) | 255,512 | in C++ | **255,512** | 9 | High | **Partial.** `GPUParticles3D`; PRD-569, 609 done; PRD-610, 611 (`vfx/`) open; graph editor out of scope (the repo rules close editors) |
| Landscape (incl. editor code in runtime) | 86,937 | 2,567 | 89,504 | 8 | High | **Partial.** PRD-566, 567 done; PRD-493 open |
| World Partition and HLOD (incl. editor code) | 70,618 | 0 | 70,618 | 9 | High | **Partial.** `WorldCells`, `streaming.ts`; PRD-456, 459, 460, 606, 607 open |
| Texture and mesh streaming | 20,414 | 0 | 20,414 | 7 | Medium | **Open.** PRD-VQ-10 |
| Texture and mesh streaming | 20,414 | 0 | 20,414 | 7 | Medium | **Partial.** [PRD-860](../../done/assets/PRD-860-the-first-scene-plays-before-the-game-finishes-downloading.md) done on #643, not yet in `develop` (was PRD-VQ-10) |
| Anim budget, sharing, AnimGraphRuntime | 29,104 | 0 | 29,104 | 6 | Medium | **Open.** PRD-570 (prd:75), PRD-486 |
| GPU skinning | 6,782 | 1,207 | 7,989 | 5 | Low | Shipped through three.js and the owned engine |

Expand Down
83 changes: 83 additions & 0 deletions docs/PRDs/done/PRD-806-epic-review-medium-and-low-findings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# PRD-806 — Fix the medium and low findings of the PR #483 epic review

**Status:** DONE 2026-11-09 on PR #635 — every medium and low finding is fixed or rejected with its reason. Scope: the 14 medium findings (13 after one duplicate) and 45 low findings verified on HEAD `21c713b7d` on 2026-11-05. The high findings are in [PRD-805](PRD-805-epic-review-findings.md).
**Priority:** P2 — each open finding below is a real defect, and none makes the board red at HEAD
**Complexity:** 5 (MEDIUM); many small fixes in independent files
**Owner:** ThreeNative maintainers

## Problem

The per-finding facts, the cited `file:line` and a one-line fix sketch are in [the evidence file](../refactoring/strata-refactoring/PRD-805-epic-review-findings.evidence.md). The verifier was a DeepSeek arm, so read each cited line before you fix it. Each fix gets a red-green spec. A fix that changes what reaches the screen (E46, E56, E73) also needs the visual judge.

## Execution Phases

#### Phase 1: Engine and asset pipeline

- [x] E09 and E11 `packages/assets/src/compile.ts`: the pre-scan fails odd GLBs even with `models: "none"` (:339), and the terrain-world cache key ignores `PIPELINE_VERSION` (:584). proof: red-green specs in `packages/assets/__tests__/` — FIXED 2026-11-05: E09 in `32bcc9244`, E11 in `f6bd216f6` (DeepSeek arm, reviewed; red at `b1e89ac2a`, green after). `packages/assets/__tests__` 55 files, 868 tests pass.
- [x] E46 `packages/assets/src/lod/generate.ts:982`: scaled far cards clamp at the quantized POSITION bounds. proof: a red-green spec in `packages/assets/__tests__/` — FIXED 2026-11-07 on PR #635 (`5ba984939`, from `c2a06bdfc`): `card-copies-quantized.spec.ts` 1 failed without the fix, passes with it. The forest golden `world.glb` hash moves with it (`9000247e1`); the 25 MiB budget holds. Visual judge (headed WebGPU, RTX 2080, upstream three build, 2 runs per arm, 5 worlds): NEUTRAL, no visible change at the capture poses; the alpine shadow difference is run-to-run flake (see E73).
- [x] E49 `packages/runtime-native/src/engine/scene/texture.h:138`: a Texture copy copies its listeners. proof: a red-green case in the engine texture test — FIXED (`7d9510f88`, carried into PR #635). 2026-11-09, engine-only V8 player build (`-DTN_ENGINE_ONLY=ON -DTN_ENGINE_PLAYER=ON -DMYSTRAL_USE_V8=ON`): `tn-native-engine-v8-textures-test clone_listeners` FAILS with the copy constructor defaulted (`v8_textures_test.cpp:135` `clone->languageListeners == nullptr`, `:137` `fired == 1`) and PASSES with the fix; `half_float` passes.
- [x] E73 `packages/runtime-native/src/engine/renderer/renderer.cpp:4999`: the custom MRT slot of a `depthWrite=false` draw is not written at 1x. proof: a red-green case in the engine renderer test — FIXED 2026-11-08 on PR #635 (`8c1c9695d`): native `attachment-mask` 3/3, `pnpm wasm:build` 0; owned-engine judge (`TN_ENGINE=threenative`, headed WebGPU, RTX 2080, 2 runs per arm, 5 worlds × 4 poses) NEUTRAL, no lost shadow, halo or colour shift.
History: the fix is on PR #635 (`460f9e5a4`; reverted in `d55471289` and restored in `8c1c9695d`). The Wasm build compiles it (`pnpm wasm:build` exit 0), and the native `attachment-mask` test passes 3/3. The first judge called the alpine boulder shadows lost and blamed E73. That was wrong: the preview's `build` ships upstream three unless `TN_ENGINE=threenative` is set (`examples/strata-terrain-preview/vite.config.ts:129`), so those frames never ran the C++ engine. Two more runs of one unchanged build showed the long boulder shadows in one run and not in the other: the shadow presence at the capture pose is run-to-run flake.

#### Phase 2: Game, editor and scripts

- [x] E17 and E29 (Strata example): a prop restream cancels the in-flight terrain update (`src/render/editorView.ts:251`), and the status line lost `role=status` and `aria-live` (`src/render/selection.ts:57`). proof: red-green specs in `examples/strata-terrain-preview/__tests__/` — E17 FIXED 2026-11-05 in `32829237d` (DeepSeek arm, reviewed; red at `b1e89ac2a`, green after): the drag restream and the terrain update now supersede only their own lane. E29 NOT-REAL: the epic moved every announcement into the single `#editor-announcements` live region on purpose, so the status line needs no own live region.
- [x] E39, E40 and E41 (terrain editor): the ortho extent subtracts `target[0]` from every axis (`cameras.ts:185`), the picker shows `assets[0]` but scatter paints `"pine"` (`tools.ts:112`), and the CSS ids do not match the camera rows (`cameras.ts:158`). proof: red-green specs in `packages/terrain/__tests__/` — FIXED 2026-11-05: E39 in `5b2d7cfdb`, E40 in `1695544a6`, E41 in `5ab0ba340` (DeepSeek arm, reviewed; red at `b1e89ac2a`, green after).
- [x] E52 and E59 (one finding) `scripts/ci-runner-admission.mjs:82`: rain goes to the GPU runner but is admitted as a CPU slot. proof: a red-green spec in `scripts/__tests__/` — FIXED 2026-11-05 in `6c526a522` (DeepSeek arm, reviewed; red at `b1e89ac2a`, green after). The `ci-*` script specs pass: 24 files, 838 tests.
- [x] E56 and E62 (terrain package): `bendCrownNormals` is not idempotent (`starter/forest/world.ts:154`), and the matrix pins 35 empty worlds as success (`__tests__/terrain-mcp.spec.ts:1173`). proof: `pnpm exec vitest run packages/terrain/__tests__/`
Open: E56 FIXED 2026-11-07 on PR #635 (`b8f6c9db0`): `forest-crown-normals.spec.ts` 1 failed without the fix, passes with it; the five preview worlds judge NEUTRAL (upstream three build). E62 is on PR #635 (`b41bfaa61`) and `packages/terrain/__tests__/` passes 531/531, but it changes what a landform cook draws (firs on forest and coastal presets), so it needed a judge on an MCP-cooked world.
E62 judge, 2026-11-09: `scripts/verify-forest-playtest.ts --target web` with `terrain_generate {kit: "forest", landform: "rollingHills"}`, spawn pose, two runs per arm, headed WebGPU nvidia/turing. First verdict REGRESSION (`prd-806/e62-spawn.jpg` on `pr635-screenshots`): firs grew through the spawn pad and inside the arena walls, because a preset's foliage had no keep-out (the kit worlds stay clear only through their own terrain). Fixed in `20fd01f7c`: each landform foliage rule clears a 23 m circle at the world centre, the starter arena's half-diagonal plus a fir crown; `terrain-mcp.spec.ts` `cooks 'rollingHills' under 'forest'|'coastal'` fail without it (nearest tree 3.3 m) and pass with it, `packages/terrain` 605/605. Rejudge IMPROVEMENT (`prd-806/e62-spawn-fixed.jpg`): a fir stand around the arena, none on the pad, floor or walls; the play area meters about 10 % brighter under the canopy, still readable. Judge notes, not regressions: sparkle on near fir branches, uniform trunk lean, a bare floor under the stand.

#### Phase 3: The 45 low findings

- [x] Fix or reject each REAL low finding in the evidence file, with the reason beside each rejection. proof: one line per finding in this box
2026-11-09: 44 fixed, 1 rejected.
- E01 FIXED in the EPIC squash `972d1e371`: fix(core): assert the concurrent spawn waiters clear their deadlines.
- E02 FIXED in the EPIC squash `972d1e371`: fix(strata-terrain-preview): a failed horizon fetch no longer poisons every later world load.
- E03 FIXED in the EPIC squash `972d1e371`: fix(strata-terrain-preview): the kit proof empties a reused artifact directory again.
- E05 FIXED in the EPIC squash `972d1e371`: fix(strata-terrain-preview): the swimmer enters the sea the world draws.
- E06 FIXED in the EPIC squash `972d1e371`: fix(strata-example): name the wildwood stage arm in the comments that list the arms.
- E07 FIXED in the EPIC squash `972d1e371`: fix(wasm-engine-boot): the normal-node scenario fails a run that fell back to the geometric normal.
- E13 FIXED in the EPIC squash `972d1e371`: fix(strata-terrain-preview): run the shared water regressions from the test lane.
- E14 FIXED in the EPIC squash `972d1e371`: fix(strata-terrain-preview): drop the forest skip flag whose false arms its own throw made unreachable.
- E15 FIXED in the EPIC squash `972d1e371`: fix(core): restore the frame-buffer texture name only once, after overlapping compiles.
- E16 FIXED in the EPIC squash `972d1e371`: fix(core): the dither-partition test reads the mask instead of plain JS numbers.
- E18 FIXED in the EPIC squash `972d1e371`: fix(strata-terrain-preview): name ?farForest=on as the override the flag actually reads.
- E19 FIXED in the EPIC squash `972d1e371`: fix(strata-terrain-preview): delete the ?massif=before knob and the survey it swapped in.
- E22 FIXED in the EPIC squash `972d1e371`: fix(create-threenative): stop the terrain-kit symlink walk at the first existing folder.
- E23 FIXED in the EPIC squash `972d1e371`: fix(core): make the bundle row-cap test really cross 1,024 rows.
- E24 FIXED in the EPIC squash `972d1e371`: fix(core): exercise the depth-buffer width check without a resize event.
- E25 FIXED in the EPIC squash `972d1e371`: fix(core): endFrame's doc says a hitch still returns its split.
- E26 FIXED in the EPIC squash `972d1e371`: fix(core): scale a zero-area kept card about its own centre.
- E27 FIXED in the EPIC squash `972d1e371`: fix(playtest): a worker relaunch no longer reports the discarded attempt's cpu profile.
- E28 FIXED in the EPIC squash `972d1e371`: fix(strata-terrain-preview): sway()'s doc says the shadow casts the rest pose, and why.
- E30 FIXED in the EPIC squash `972d1e371`: fix(strata-terrain-preview): delete the ?peaks and ?meadowBase A/B knobs.
- E31 FIXED in the EPIC squash `972d1e371`: fix(engine-mcp): drop a stop word's inflections too, not just the word.
- E32 FIXED in the EPIC squash `972d1e371`: fix(physics): a forced trunk gets a positive capsule radius.
- E33 FIXED in the EPIC squash `972d1e371`: fix(strata): the spruce terminal minimum is taken by the loader, and the gate test drives it.
- E34 FIXED in the EPIC squash `972d1e371`: fix(strata-terrain-preview): bound each invalidated shadow region by the instance's own span.
- E35 FIXED in the EPIC squash `972d1e371`: fix(strata-terrain-preview): river rocks must sit on the river's bank, not just be counted.
- E37 FIXED in the EPIC squash `972d1e371`: fix(core): size the chunk shadow proxy index pool from the shadow ladder.
- E38 FIXED in the EPIC squash `972d1e371`: fix(core): keep a file URL's triple slash when resolving terrain splat layer maps.
- E42 FIXED in the EPIC squash `972d1e371`: fix(runtime-native): a missing MRT slot refuses one read instead of killing the web host.
- E43 FIXED in the EPIC squash `972d1e371`: fix(native): state the parity bound the first-frame shadow row enforces.
- E45 FIXED in the EPIC squash `972d1e371`: fix(terrain): a 409 rebase the external writer already landed settles instead of rejecting.
- E47 FIXED in the EPIC squash `972d1e371`: fix(assets): report a GLB with no JSON chunk where the container shows it.
- E50 FIXED in the EPIC squash `972d1e371`: fix(terrain): wait for the export cook to start instead of a fixed sleep.
- E53 FIXED in the EPIC squash `972d1e371`: fix(three-native): release an object-valued uniform with the value it reads.
- E54 FIXED in the EPIC squash `972d1e371`: fix(terrain): let the example guard see path-string reads, not only imports.
- E55 FIXED in the EPIC squash `972d1e371`: fix(terrain): describe the placement record as position, quaternion and scale.
- E58 FIXED in the EPIC squash `972d1e371`: fix(native-renderer): a mirror's pass is reused only while its reflector lives.
- E60 FIXED in the EPIC squash `972d1e371`: fix(scripts): describe terrain peers as shipped or external.
- E61 FIXED in the EPIC squash `972d1e371`: fix(scripts): resolve the terrain reply only on a newline-terminated line.
- E63 FIXED in the EPIC squash `972d1e371`: fix(terrain): cook both AC-3 arms as tool calls in a fresh process.
- E65 FIXED in the EPIC squash `972d1e371`: fix(scripts): the startup gate compares Three patch digests and records the arm's own patch.
- E66 FIXED in the EPIC squash `972d1e371`: fix(terrain): the cook reports the water it floods, not the rows it was asked for.
- E74 FIXED in the EPIC squash `972d1e371`: fix(native-renderer): accept a legal eight-attachment aux pass.
- E75 FIXED in the EPIC squash `972d1e371`: fix(native-renderer): a volume texture carries the usage a texture copy reads.
- E57 FIXED 2026-11-09 on PR #635 (`feaf012c6`): alpine, desert and tundra set `lighting.lods: true`, so the `boulder-mid.glb` each bakes at 35 m is sky-dressed; coastal bakes no mid level and keeps `false`. `kit-runtime.spec.ts` "dresses the mid level its own assets.json bakes": 3 failed without the fix, 5 passed with it; `packages/terrain/__tests__/` 605/605. Visual judge, 2026-11-09: `KIT=alpine pnpm test:kit` at `feaf012c6^` and `2c9262966`, two runs per arm, headed WebGPU nvidia/turing, sheets `prd-806/e57-{boulders,ground,edge}.jpg` on `pr635-screenshots`: a fresh judge returns NEUTRAL on all three frames, no regression (arm RMSE 0.0010 against run noise 0.0026-0.0035 on `boulders`). It also says the frames do not show the gain: the one far boulder in view draws the same in both arms, so these poses prove no regression, not the sky on the mid level.
- E68 REJECTED: an explicit `kit` over a `biome` argument is the pinned contract (`terrain-mcp.spec.ts:1060` "keeps kit as the explicit override over a biome name"), and a request word that loses to an argument is reported as `decided.biome.source: "argument"` (`tools.ts:474`). A guard that threw on the conflict broke that pinned spec, so it was reverted.

## Acceptance Criteria

- [x] AC-1: `pnpm typecheck` and `pnpm lint` exit 0 after the fixes. proof: command output in the box — 2026-11-09: local `pnpm typecheck` exit 0 at `3817a9529` and `pnpm lint` exit 0 at `ecebc2fe5`; CI run 42609379659 on `2c9262966` (after every fix, E57 included): `typecheck` success, `lint` success, `ci-required` success.
Loading
Loading