Skip to content

fix: water-trough third quality pass; exit-pre-sidecar finding - #250

Merged
TMHSDigital merged 2 commits into
mainfrom
fix/water-trough-third-pass
Sep 25, 2026
Merged

TMHSDigital merged 2 commits into
mainfrom
fix/water-trough-third-pass

Conversation

@TMHSDigital

Copy link
Copy Markdown
Owner

A quality pass on water-trough (Track A). It was the weakest showcase piece in #249's report. The run's second pick was exit-pre-sidecar (Track C). Its re-verification found a wrong documented claim, so per the runbook it is not changed here; the finding is at the end.

Binaries:

  • .scratch/blender-4.5.11-windows-x64 (reports Blender 4.5.11 LTS)
  • blender-5.1.2-windows-x64 (Blender 5.1.2)
  • blender-5.2.1-windows-x64 (Blender 5.2.1 LTS)

The hero was rendered on 5.2.1 through scripts/render_hero.py. The inspection renders stayed in .scratch/.

water-trough (Track A)

Inspection sheet: six orthographic views, two three-quarter views, clay, wireframe, eight joint close-ups and a ground-contact view. The geometry was largely sound:

  • The hull is a D-section of lengthwise staves on two braced trestles, with every joint closed.
  • The squares that stand outside the rim in the top and bottom orthos are the splayed legs' shoes, not tabs.

Defects (round 0):

  1. One-slab ends. Each end was one D-shaped slab: one board from rim to rim, one tone, no joint. This is the case the showcase's "a head or bottom is boards, not a slab" rule exists for. Seen in the end orthos, joint_end_cap_left/right and the hero.
  2. The water read as a painted slab. The hero looks across the surface near grazing, where the water shader's facing tint takes over. That tint was a pale grey-blue (0.20, 0.27, 0.29), so the water rendered as a flat matte panel and the trough read as a table.

Generator changes, and why each is structural:

  1. Board-built ends. Each end is three vertical boards of uneven width (END_BOARD_FRACS), each with its own seeded tone and grain.
    • Each board's bottom is computed from the hull's outer arc under its own span, so the ends follow the hull if its radius changes.
    • Neighbours lap 1 mm into each other (END_BOARD_LAP), so the joint is tight: a through seam would leak water and let a containment ray through. The bevel on each board's face edges shows the joint as a groove.
    • The rim-span audit is now read on the union of an end's boards. Otherwise a board's inner edge at a joint is taken for the end's rim.
  2. Water tint. The grazing tint is now a deep teal (0.055, 0.105, 0.115). The lighting is unchanged; the first pass had already found that a reflection light floods the stage.

New budget. Identical on 4.5.11, 5.1.2 and 5.2.1:

Budget Declared Measured
End boards per end ≥ 3 3

Existing budgets, re-measured:

  • Hygiene is 0 on every axis.
  • Four shoes at z 0.
  • End rim span: 20.8 mm, read on the union of an end's boards, against an 80 mm ceiling.
  • Strap gap: 0.
  • Water-hull gap: 2.6 mm.
  • Water containment: 0 misses of 66 rays, so the lapped joints hold.
  • Hull: 1.0448 × 0.4661 m.

Triangles: base 3124 → 3316, inside the unchanged 2800–3500 band. Four arc samples per board cost 3556 triangles, over the ceiling, so each board uses three. The collider went from 64 to 68, against a ceiling of 80.

Falsifier: --slab-ends restores the one-piece board and violates only the new budget, measuring 1 board. The older falsifiers still land on their own gates:

  • --box-ends on the rim span (160.7 mm).
  • --open-ends on containment (62 of 66 rays miss).
default --skip-decimate --stray-vert --lift-z --short-legs --box-ends --float-strap --narrow-hull --open-ends --slab-ends --output
4.5.11 0 9 15 16 16 17 18 19 18 20 0
5.1.2 0 9 15 16 16 17 18 19 18 20 0
5.2.1 0 9 15 16 16 17 18 19 18 20 0

Inspection rounds: 2. Round 1 fixed the ends; round 2 fixed the water tint.

Framing: fill 0.794, minimum margin 0.044, with no deviation=.

Determinism: the default and --output runs on 5.2.1 report identical measured lines. Across binaries, only the export byte count differs, by 16 B.

Contact sheet: water-trough.

before after
luma 0.187 0.182
stage 0.180 0.180
warmth +0.071 +0.068
sat 0.132 0.136

It sits inside the band and is legible at card size.

Asset sheet: water-trough. Verdict: passes. Rendered alone and neutrally, the staved hull, straps, dark water and braced trestles read clearly. It sits mid-pack: above the rocket and the arm, below the hydrant and the jerry can.

Convention change (its own commit): "A head or bottom is boards, not a slab" now covers any end that closes a vessel. Watertight boards are lapped rather than seamed, and rim tests are read on the union of an end's boards.

exit-pre-sidecar (Track C): stopped, correctness finding

I re-verified every claim through the real harness (tests/smoke/run_example.py --expect-sidecar --sidecar-contains exit_pre-ok) on all three binaries.

The mechanics hold:

4.5.11 5.1.2 5.2.1
exit_pre in bpy.app.handlers no yes, and the only exit-related name yes, and the only exit-related name
default SKIP (77) PASS, sidecar exit_pre-ok PASS
--no-handler, --silent-handler SKIP FAIL, no sidecar FAIL, no sidecar
--wrong-text, --write-in-main, --atexit-instead SKIP FAIL on contents (nope / from-main / atexit-ok) FAIL on contents
--force-run exit 2 on AttributeError PASS PASS

The rationale is wrong. The README says exit_pre "is the difference between a callback that runs and one that silently never does", and that code relying on atexit "is the class of bug this example exists to catch".

A probe registered both callbacks and read bpy.data in each:

  • atexit does run on all three binaries. The --atexit-instead sidecar above is its own output.
  • But by then the scene is gone. In atexit, bpy.data.objects is empty (0 objects) without any error.
  • exit_pre still sees the scene on 5.1.2 and 5.2.1 (3 objects, first Camera).

The real hazard is an exit callback that runs after Blender has freed its data and silently writes an empty manifest, not one that never runs. The assertions don't witness this either: --atexit-instead fails only on the marker text, so the example would pass an exit_pre handler that reads nothing, and fail an atexit that "works".

Correcting this means rewriting the README's contract paragraph. It probably also means strengthening the sidecar to carry scene data (for example an object count), with --atexit-instead then failing on the content. That changes what the example witnesses, so it is left for a decision rather than folded into a polish pass.

Checks

Run locally and passing:

  • check_exit_code_readme.py
  • check_gallery_images.py
  • check_falsifier_targets.py (230 falsifiers across 28 pieces)

build_gallery.py was run last. I read the generated alt text in docs/gallery/index.html and on the water-trough detail page.

🤖 Generated with Claude Code

TMHSDigital and others added 2 commits September 25, 2026 12:49
Each end was one D-shaped slab, the case the "a head or bottom is boards"
rule exists for. Each end is now three vertical boards of uneven width,
each with its own tone, its bottom following the hull arc under its own
span, lapped 1 mm into its neighbours so the joint is tight (no seam for
water or a containment ray) and the bevel shows it as a groove. The rim
span is read on the union of an end's boards. New budget: end boards per
end >= 3 (exit 20, --slab-ends restores the one-piece board, measures 1).
The water's grazing tint went from a pale grey-blue that read as a painted
slab to a deep teal. Tris 3124 -> 3316 (four arc samples per board cost
3556, over the unchanged 3500 ceiling; three are used). Same codes and
values on 4.5.11, 5.1.2 and 5.2.1. Asset sheet added.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com>
Extends "a head or bottom is boards, not a slab" to any end that closes a
vessel: lap watertight boards a millimetre rather than leaving a through
seam, and read rim tests on the union of an end's boards.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: TMHSDigital <154358121+TMHSDigital@users.noreply.github.com>
@TMHSDigital TMHSDigital added the needs-5.1 Opt-in Blender 5.1 smoke on this PR. Default matrix stays 4.5 + 5.2. Auto-label will not apply this. label Sep 25, 2026
@github-actions github-actions Bot added showcase Budget-conformance props under showcase/ documentation Improvements or additions to documentation labels Sep 25, 2026
@TMHSDigital
TMHSDigital merged commit c78462f into main Sep 25, 2026
13 checks passed
@TMHSDigital
TMHSDigital deleted the fix/water-trough-third-pass branch September 25, 2026 16:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation needs-5.1 Opt-in Blender 5.1 smoke on this PR. Default matrix stays 4.5 + 5.2. Auto-label will not apply this. showcase Budget-conformance props under showcase/

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant