Download Latest Version 2.0.0_ The Plugin Update source code.zip (1.6 MB) Google Add to Preferred Sources
Home / v1.5-beta
Name Modified Size InfoDownloads / Week
Parent folder
README.md 2026-08-06 11.5 kB
v1.5 beta -- character track, material pipeline, and a release path that actually runs source code.tar.gz 2026-08-06 933.1 kB
v1.5 beta -- character track, material pipeline, and a release path that actually runs source code.zip 2026-08-06 1.1 MB
Totals: 3 Items   2.1 MB 1

Why this is a beta of scripts only

The per-subject tuning artifacts (sculpt specs, assessments, feedback plans, comparison renders for individual characters and objects) are excluded and now git-ignored. They are outputs of a tuning session, never inputs to a build, and they carried multi-megabyte PNGs. Same reasoning .gitignore already applied to .screenshot/.

Added

Character track (new in 1.5)

  • forge/stage5_rig/ — skeleton emission, rig_spec schema, geodesic voxel skinning, and a stdlib rig-payload validator for parent ordering, local matrices, packed indices/weights and joint coverage. Geodesic replaces Euclidean distance-to-bone falloff: straight-line distance does not care whether the path stays inside the model, so an arm resting on the ribs claimed chest vertices and raising it dragged the chest.
  • forge/stage2_spec/humanoid_proportions.py — fills anatomy from public canon when there is no reference image. Writes anatomy.source: "canon-table" so canon is never mistaken for measured evidence, refuses to run when the spec names a reference image, and lists what the corpus does not supply under anatomy.unsourced.
  • Character sub-routes now reachable from SKILL.md — structure decomposition, head construction, and stylized hair (with its parameter contract) existed but nothing pointed at them, so the agent could never read them. Wired into the character track in dependency order: parts → head → hair.

Material pipeline

  • Canonical registry loader/resolver (forge/materials/), region-level crop and PBR analysis, ObjectSculptSpec hand-off, controlled material view plans, deterministic per-region comparison, bounded feedback, geometry/UV/rig/LOD compatibility checks, and a blocking acceptance gate.

Geometry and build

  • uv_unwrap.py — chart segmentation, LSCM by conjugate gradient, skyline packing. Nothing produced UVs before, which is why bake_projected_texture.py could only emit a descriptor and normal/AO baking had nowhere to go.
  • visual_hull.py now carves rather than validating a descriptor, and reports unconstrainedAxes plus the plain statement that a hull can never contain a concavity no view sees as background.
  • decimate.py — quadric error metric collapse that refuses any collapse which would flip a face or erode a boundary, so lodPlan can be generated rather than only validated.
  • morph_targets.py — relative deltas for expression and for correctives.
  • sdf_primitives.py, subdivision.py — SDF sampling grids and subdivision capped to the tessellation tier so performanceBudget.targetTriangles reaches the emitted geometry.

Review gates for defect classes no earlier check could see

Each ships with a regression test that proves the older gate passes the same broken input.

  • self_intersection.py — ray-parity detection of a surface folded through its own volume. mesh_edge_counts is topological, so a recess pushed through the far side reports boundaryEdges 0 / nonManifoldEdges 0 and passes. Deterministic, 2D-grid accelerated, and honest about sampling: sampledVertexCount / totalVertexCount / samplingStride are in every result, and grazing-ray samples are reported as undecided rather than guessed.
  • turntable_gate.py — mandatory azimuth coverage (a missing angle fails rather than going unnoticed) plus flood-fill interior-hole detection. A hole through a model barely moves silhouette area, so the area signal cannot see it; the test asserts the hole is caught while that signal stays quiet. --allow-holes changes the verdict, never the detection.
  • attachment_anchor.py — ANCHOR_DECLARED / ANCHOR_RESOLVES / ANCHOR_NOT_ROOT / ANCHOR_NOT_CYCLIC, plus ANCHOR_PROXIMITY against measured world positions. Attachments missing from the measurement set are listed as unmeasuredAttachments rather than counted as passes — "0 violations" because the check never ran is the failure this repo keeps rediscovering.
  • joint_loops.py — asserts each joint has enough vertex bands along the bone to bend.
  • pairwise_penetration.py — one part passing through another, which every per-mesh gate passes by construction because both meshes are individually flawless.

Intake and camera

  • Camera fitting split into solver / math / types / image helpers, with a GLB probe and semantic decomposition. Reads uncompressed .glb and JPEG with the standard library only.

Reference comparison and render bridge

  • render_bridge.py + render profile v2 schema — browser-first capture manifests, camera-batch evidence, readiness/settle checks, deterministic diagnostics, and explicit GLB/VRM/Blender boundary rules.
  • mesh_reference_compare.py — says where a candidate is wrong, band by band. Normalises from the feet rather than the bbox top (the ground is a landmark both subjects share; the bbox top is whatever pokes up highest), reports the 5th–95th percentile width so a long thin prop stops dominating, and reports band centroids so a limb that is the right size on the wrong side is caught.
  • scripts/character_audit.sh — runs every geometry gate against a live model and writes a baseline to diff against, so "before and after" is a number instead of an impression.

Routing

  • forge/_shared/pipeline_routing.py — fail-closed weapon/character track resolution. Ambiguous, low-confidence, malformed, and contradictory inputs return request-input instead of guessing a template; new_sculpt_spec.py hard-errors rather than selecting one.

Tests

39 new test files (66 total, 709 tests).

Fixed

The release path could not run at all

The 1.5 line moved the SKILL.md version into a nested metadata: parent. That is valid YAML and reads fine to a human, which is why it survived review — but both release paths anchor ^version: at column zero:

  • .github/workflows/beta-release.yml:26 would exit 1 with "SKILL.md must contain one supported version field"
  • scripts/release_metadata.py:14 would raise "must contain exactly one replaceable version"

forge/tests/test_release_metadata.py could not catch it, because its fixture writes the shape the tooling wants rather than the shape on disk. The version key is back at column zero and there is now a guard that asserts against the real SKILL.md.

A test pinned the version, so every automated bump broke it

test_ws6_docs.py asserted the literal strings version: 1.5.0, version-1.5.0-green.svg, and ## [1.5.0] - 2026-07-26. Any bump — which is the entire point of the beta workflow — failed CI. Replaced with guards that check consistency and reachability instead of a literal: the version is parseable by the release tooling, README declares exactly one badge matching it, and no CHANGELOG link reference is defined twice.

Merge artifacts that shipped as content

A prior merge kept both sides' text without conflict markers:

  • README.md carried a duplicated badge block declaring two different versions (1.5.0 and 1.4.3) at once. release_metadata.py rewrites with count=1, so the second badge would have gone stale silently forever.
  • SKILL.md had two variants of the same 2c. heading and body line. Kept the family-generalization wording, dropped the knife-only one.
  • CHANGELOG.md had two full link-reference blocks — six versions defined twice, pointing at different organisations. Markdown resolves the first and ignores the rest, so half the block was invisible dead text.

Release metadata

  • release.yml — previous-governed-tag was still "" with a comment saying to fill it in the next release-prep PR; now v1.4.3, the only published governed tag. bootstrap-release no longer references a tag that is already out.
  • CHANGELOG.md — removed a [1.5.0] entry dated as released for a version that was never published, and normalised 1.4.4-beta-2 to 1.4.4-beta.2 to match the tag scheme. Release notes are generated by the tooling from now on.

Unreachable files

Seven files were present but reachable from nothing — four character-track grimoire docs and three CLIs absent from grimoire/scripts.md. Wired up rather than deleted: the character docs belong to the character update, and the CLIs are documented, tested tools. Reachability from SKILL.md / README / code is now 0 dead files for everything this PR adds.

English-only content

Removed the parallel Vietnamese keys and aliases from the material registry, the CS2 vocabularies and the skill dataset — every one had an English sibling holding the same content, so no lookup path or reading is lost. Stray Vietnamese glosses in English prose are gone. The release surface is now English-only.

Excluded from this PR

  • work/ — 46 per-subject tuning artifacts (~90k lines, including a 3.9 MB PNG), now git-ignored
  • .sisyphus/ — local orchestration state, same class as the already-ignored .omc/
  • Five orphan docs referenced by nothing: a handover checklist, a single-character prompt, a one-off metric audit, a research query, and a distilled PR note

Verification

  • 709 tests pass, 0 skipped, run with IMG2THREEJS_SHOWCASE_ROOT set so the TypeScript typecheck gates actually execute
  • 67 of 68 CLI entrypoints respond to --help cleanly
  • Beta workflow simulated against its own script: 1.4.4 → v1.5.0-beta.1, next push → -beta.2
  • release_metadata.py --dry-run over these commits: {"release": true, "version": "1.5.0", "level": "minor"}
  • No file deleted relative to main; every previously published tag still points at its original commit

Known gaps, not addressed here

  1. CI never runs the TypeScript typecheck gates. ci.yml does not set IMG2THREEJS_SHOWCASE_ROOT, so 23 gates skip on every CI run — CI goes green without verifying that the emitted Three.js compiles. Needs a showcase checkout in the workflow.
  2. primaryDomain is a single point of failure for routing. Setting preSpecAssessment.objectClass.primaryDomain to character routes any object to the humanoid template with status: resolved and source: explicit — no confidence, no threshold, no cross-check against the name or image, and no downstream gate that notices. Pre-existing behaviour with a test blessing it; flagged rather than changed.
  3. Vietnamese remains in 18 pre-existing files outside this release surface (~1,084 lines). The remainder is genuine translation work, not mechanical stripping: 99 vocabulary aliases exist only in Vietnamese, and they are coupled to test_search_specs.py assertions and to headings in docs/cs2-anatomy/knives.md.
  4. Six CHANGELOG link references still use the pre-transfer organisation. They resolve today via GitHub's redirect. The README star-history chart also uses the old path with a sealed_token bound to it, so that one needs a regenerated token rather than a path edit.
  5. forge/stage1_intake/cs2_manifest.py needs PYTHONPATH=. to run directly; no doc invokes it directly, so it has not surfaced.
Source: README.md, updated 2026-08-06