Skip to content

feat: attribute-domain-shear example + count/numeric-contract housekeeping#111

Merged
TMHSDigital merged 3 commits into
mainfrom
feat/attribute-domain-shear
Jul 23, 2026
Merged

feat: attribute-domain-shear example + count/numeric-contract housekeeping#111
TMHSDigital merged 3 commits into
mainfrom
feat/attribute-domain-shear

Conversation

@TMHSDigital

Copy link
Copy Markdown
Owner

Attribute domain shear + two housekeeping commits

New example witnessing POINT vs CORNER semantics on Mesh.color_attributes — plus the two housekeeping commits that opened the branch (count-prose fix, numeric-contract exception codified).

Housekeeping

  1. docs: count-prose fix. AGENTS.md and CLAUDE.md said "23 examples" while README, the manifest, and CI all agree on 38 (derived from .cursor-plugin/plugin.json; every other count in both files verified correct as written). Example-shipping commits keep the lines current — this PR moves them to 39.
  2. docs: numeric-contract exception in VISUAL-STYLE Layer 1. Codifies what vertex-weight-limit (pose-preserving prune) and triangulate-tangents (mikktspace field) already declared honestly: a contract with no visual signature is declared numeric in the README, the render depicts subject and setup legibly, and falsification names why. Anchored to those two precedents so the exception stays narrow.

The example

examples/attribute-domain-shear/ — an 8-wedge pinwheel around one raised hub vertex shared by every wedge (plus a shared outer ring). The contract, all closed form:

  • Storage sizes: CORNER attr data == len(loops) == 3K; POINT attr == len(vertices) == K+1.
  • CORNER authoring exact: hub corner of wedge i reads palette[i], err ≤ 2.6e-08 — K faces may disagree at one vertex.
  • Naive POINT authoring shears by construction: a per-wedge "paint each wedge its color" loop rewrites every shared vertex once per neighbor; last write wins — hub reads palette[K−1], ring vert i reads palette[i] except the wrap-around vert 0 (also palette[K−1]). Measured shear 0.751031 == palette closed form 0.751031.

Companion to color-attribute-wheel (domain sizing, active_color, shader Attribute node) — this covers the meaning of the domains on shared topology, not a repackage.

Falsification evidence

probe expected observed
wedge 3 miscolored in CORNER pass exit 4 exit 4 (hub corners fail exact color)
naive writes reversed → hub reads palette[0] exit 5 exit 5 (last-write-wins broken)
ring vert 2 corrupted exit 6 exit 6 (overwrite-ordering witness)
constant palette → shear collapses exit 7 exit 7 ("shear is ~0 — cannot distinguish naive from correct")

All restored; final check exits 0 with attribute-domain-shear OK corner_exact point_shear=0.751031.

Framing (measured, gallery_framing silhouette)

fill 0.837x / 0.478y, margins L0.081 R0.081 B0.089 T0.133 — in band on 5.1.2 and identical on 4.5.11. Gate wired via check_framing (exit 10). Draft 1 was gate-rejected (fill 1.000, margins 0) — the gate caught it before any artifact shipped.

Visual-pass log (4 render iterations)

  1. Full size + helper numbers: d1 gate-rejected (over-fill); d2 edge-on camera hid the pinwheel pattern; d3 good but 0.887x near the ceiling; d4 final (camera pull-back + thicker/lighter stems).
  2. Contract visible: the dual panel carries working and broken in one frame — CORNER fan crisp, naive POINT fan smeared. The right fan is the falsification variant, generated from the same closed-form palette the check asserts.
  3. Thumbnail (preview webp at 400 px): crisp-vs-smeared distinction and both placards read in under a second.
  4. Playwright (full-page captures): index at 1280 and 390 plus the detail page — new card, teaches, witnesses callout, and detail page all render correctly; generated HTML read character by character. One real finding: the alt guard correctly rejected my first teaches draft (a bare decimal "0.751031" sat past the 160-char cap, tripping the dotted-path assert — exact numbers moved to README per the WITNESSES-one-claim rule).
  5. Contact sheet: composite vs armature-bend 70.8 / damped-track-aim 44.5 / bmesh-gear 77.7 — candidate 73.6, inside the calibration range (not a fourth bright card). Stage darkness ✓, wedge warmth ✓, fill comparable ✓, saturation is the palette data by design ✓, thumbnail legibility ✓.

Runtime

Local binaries: .scratch/blender-5.1.2-windows-x64/blender.exe (reports Blender 5.1.2), .scratch/blender-4.5.11-windows-x64/blender.exe (reports Blender 4.5.11 LTS). Check-only: exit 0 on both, byte-identical output, sub-second runtime (new smoke step is check-only, so smoke runtimes are unaffected). CI floats within series per CLAUDE.md.

Live-run vs inspection-only

  • Live run (5.1.2): check runs, 4 falsification probes, 4 render iterations + gate, webp conversion, contact sheet, gallery regen, Playwright captures.
  • Live run (4.5.11): check-only + render path (identical numbers).
  • Inspection only: none beyond the standard assumption that CI smoke runtimes track local timings.

Test plan

  1. blender --background --python examples/attribute-domain-shear/attribute_domain_shear.py -- → exit 0, point_shear measured=0.751031 closed_form=0.751031 (4.5 LTS and 5.1).
  2. -- --output out.png → framing lines print framing_ok, exit 0, artifact written.
  3. Break any of the four probed paths → the documented exit code.

Both files' prose said 23 examples while README, the plugin manifest,
and CI all agree on 38 (derived from .cursor-plugin/plugin.json: 12
skills, 6 rules, 2 templates, 17 snippets, 38 examples — every other
count in the two files verified correct as written). Example-shipping
commits keep these lines current from here.

Signed-off-by: fOuttaMyPaint <TMhospitalitystrategies@gmail.com>
Two shipped examples have contracts with no visual signature:
vertex-weight-limit's pose-preserving prune and triangulate-tangents'
mikktspace field both falsify pixel-identical, and both declared it
honestly. Layer 1 now makes that an explicit, narrow exception: the
README declares the contract numeric, the render depicts subject and
setup legibly rather than a break that cannot exist, and falsification
is satisfied by naming why. Anchored to the two precedents by name so
the exception stays narrow — where a visual witness is possible, it is
still required.

Signed-off-by: fOuttaMyPaint <TMhospitalitystrategies@gmail.com>
Witnesses what POINT vs CORNER means on Mesh.color_attributes once a
mesh has shared vertices: an 8-wedge pinwheel around one raised hub.
CORNER authoring holds each wedge's exact color at the hub (err <=
1e-6); the naive per-wedge POINT loop rewrites every shared vertex once
per neighbor and the last write wins — hub reads palette[K-1], ring
verts read palette[i] except the wrap-around vert 0, and the measured
shear equals the palette closed form (0.751031) exactly. Storage sizes
asserted per domain (3K loops vs K+1 verts). Byte-identical on 4.5.11
and 5.1.2. Falsified: corner corruption (exit 4), reversed write order
(exit 5), ring corruption (exit 6), constant palette collapsing the
shear (exit 7). Companion to color-attribute-wheel, not a repackage:
that one covers domain sizing and active_color; this one covers what
the domains mean on shared topology. Render path gated with
check_framing (0.837x/0.478y, margins >= 0.081); dual pinwheel still
carries the broken state in-frame — the POINT fan is the falsification
variant. Count prose bumped to 39 across README/CLAUDE/AGENTS.

Signed-off-by: fOuttaMyPaint <TMhospitalitystrategies@gmail.com>
@github-actions github-actions Bot added documentation Improvements or additions to documentation ci labels Jul 23, 2026
@TMHSDigital
TMHSDigital merged commit 9e9e7ce into main Jul 23, 2026
9 checks passed
@TMHSDigital
TMHSDigital deleted the feat/attribute-domain-shear branch July 23, 2026 23:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant