Skip to content

34 E2: tools/kit-build — one pack build tool + required pack CI checks - #13

Merged
AlexZ005 merged 4 commits into
mainfrom
feat/34-pack-ci
Oct 3, 2026
Merged

AlexZ005 merged 4 commits into
mainfrom
feat/34-pack-ci

Conversation

@AlexZ005

@AlexZ005 AlexZ005 commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

Roadmap 34, item R7 (packs half) — proposal §2 E2: one pack build tool instead of the per-kit forks, and pack CI checks on every PR.

What changes

tools/kit-build — one CLI for every step after a kit's recipe:
build (recipe → pass → judged defight → LOD1/LOD2 → thumbnails → check) · post (the one post step) · pass (emissive policy, texture cap per pack, opaque PNG → JPEG over the share cap, decimate LOD0 to its category budget; dry run unless --write, compliant files never rewritten) · lod · thumbs · flicker · report (budget report) · check (the CI).

  • The architecture / sci-fi / town kit-post.mjs forks and the nature / props / interior copies of the grade, emissive, base-cut, repair and flat-for-sync helpers now live once in tools/kit-build/lib/post.mjs. The kit-post files are re-export shims.
  • Byte-stable: the old code (main) and the new code rebuilt the architecture, nature, props, interior and sci-fi kits from the same staged Meshy raws: 159 / 159 GLBs byte-identical.
  • Every tool now loads gltf-transform through one loader, because the library checks instanceof and the forks had mixed its CommonJS and ES builds.

.github/workflows/pack-checks.yml (job pack-checks) runs the pack tools' unit tests and kit-build check over every pack. Its checks:

  • the manifest schema, including P1 lods and P2 behavior
  • GLB ≤ 5 MiB (warn > 2 MiB)
  • triangle budgets per category
  • texture caps
  • emissive policy
  • scale sanity (bbox in metres)
  • pivot rule
  • LOD files present for items > 2 000 tris: they must have fewer triangles, the measured ratio, LOD0's node names and its clips
  • behavior clips present
  • the static flicker probe (coplanar / double-sided)
  • thumbnails present

The full run covers 222 items in about 15 s and needs no browser.

Run on every existing pack

  • 0 errors, 5 size warnings (cube_diorama, SvelteRune > 2 MiB).
  • Fixed: default/SvelteRune was 5.09 MiB, over the share cap (it could never reach a peer). Its PNG normal map was re-encoded as JPEG (the material is OPAQUE): 3.53 MiB, render difference mean 0.5 / 255.
  • Fixed: the architecture and sci-fi recipes now run defight after the cut / kitbash. Before, a rebuild shipped 300–3 000 cm² of coplanar overlap on every wall (check: 18 and 9 errors); after, 0 and 0, and WallStone / WallPlaster rebuild byte-identical to the shipped files.
  • Allow-listed (with reasons), tools/kit-build/allow.json:
    • 15 items that tools/lod builds no level for (its visual gate refuses every candidate: foliage, straw, fine detail)
    • nature-kit PondSet's render flicker (404 px, the same value 33-pack-fix-lod measured)
  • Z-fight baseline, tools/kit-build/flicker-baseline.json: 118 files are over the static limit. Each was rendered headless at ≤ 400 px (median 37 px), and the CI holds each to its recorded overlap area.

For the integrator: make the check required

After merge, add the status check pack-checks to main: Settings → Branches → protection rule (or Rules → Rulesets) → Require status checks → pack-checks. Or run:

gh api -X PUT repos/theprototype-app/packs/branches/main/protection --input - <<'JSON'
{"required_status_checks": {"strict": false, "contexts": ["pack-checks"]},
 "enforce_admins": false, "required_pull_request_reviews": null, "restrictions": null}
JSON
  • The other open pack PRs need a policy row in tools/kit-build/packs.json for any new pack (the check says so) and must pass node tools/kit-build/kit-build.mjs check.
  • Retag format-1 + purge jsDelivr after merge (SvelteRune changed).

Tests: node --test tools/kit-build/test/*.test.mjs 22/22 (a counterfactual per check). All pack-tool suites 107/107, tools/meshy 30/30.

🤖 Generated with Claude Code

AlexZ005 and others added 4 commits October 2, 2026 15:17
… the kit forks

The architecture, sci-fi and town kits each carried a kit-post.mjs fork (pre-rotate,
meshy-post, seam clamp, offset, emissive drop, albedo grade, recolor, glow mask, defight);
nature-kit's finalize.mjs, props-kit's and interior-kit's build.mjs carried their own
emissive drop, colour grades, base cut, normal/texel repairs and flat-for-sync. All of it
now lives once in tools/kit-build/lib/post.mjs (each function the fork's code, unchanged);
the three kit-post.mjs files are re-export shims (town keeps its own judged defight) and
the three builds import the helpers.

- tools/kit-build/lib/deps.mjs: ONE loader for tools/meshy's packages. gltf-transform checks
  instanceof, so props/interior (which hand Documents to the shared helpers) now load it
  through the same CommonJS build as kit-build instead of the ES build by path.
- every default MESHY_TOOLS / MESHY_TOOL that pointed at another lane's worktree
  (packs-lane-30c-tools) now points at this repo's tools/meshy.
- tools/kit-build/lib/inspect.mjs: the measured facts of a GLB (drawn tris, bbox, textures,
  materials, clips) for the checks and the budget report.

PROOF (byte-stable): the OLD code (origin/main b79d32c) and the NEW code rebuilt the
architecture, nature, props, interior and sci-fi kits from the same staged Meshy raws
(--no-thumbs): 159 / 159 GLBs (every LOD0 + the internal .build pieces) are byte-identical
(sha256), and all 159 were rewritten by the new run. Unit suites unchanged: arch 6/6,
scifi 6/6 + 7/7, town 6/6, lod 10/10, anim 4/4, interior 46/46, tools/meshy 30/30.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…are cap; defight after cut

tools/kit-build/kit-build.mjs — one entry point for every step after a kit's recipe:
build (recipe → pass → judged defight → LOD1/LOD2 → thumbs → check), post (the one post
step), pass (emissive policy, texture cap per pack, opaque PNG → JPEG over the 5 MiB share
cap, decimate LOD0 to its category budget — dry run unless --write, a compliant file is never
rewritten), lod, thumbs, flicker (static probe; --record renders and writes the baseline),
report (the budget report), check (the CI).

check — over every pack in index.json: index + model-list schema (incl. P1 `lods` and P2
`behavior`, strict where core silently normalises), GLB <= 5 MiB (warn > 2), LOD0 tris <=
category budget, texture cap, emissive policy, scale (metres), pivot rule, LOD files for items
> 2 000 tris (exist, coarser, measured ratio, LOD0's node names and clips), behavior clips in
every file, the static z-fight probe (<= 1 cm², or <= the file's RENDER-judged baseline), and
thumbnails. 222 items in ~15 s, no browser.

Policy: tools/kit-build/packs.json (8 categories with budgets/extents; per pack textureCap,
emissive none|allowed, category, pivot; per-item overrides — 35 declared pivots: windows on
the wall origin, wall-face trims, hanging lights, hinges, signpost feet).
allow.json: 16 accepted failures, each with its reason — 15 items tools/lod builds no level for
(its visual gate refuses every candidate; reasons from tools/lod/report.json and a --dry-run on
town/interior), and nature-kit PondSet's render flicker (404 px, the same 404 33-fix-lod measured).
flicker-baseline.json: 118 files over the static limit, each RENDERED headless (judge.flicker,
512², 12 poses) at <= 400 px (median 37) — the CI holds each to its recorded area.

FIX default/SvelteRune: 5 342 308 bytes was over the 5 MiB share cap (it could never reach a
peer). `kit-build pass default --write` re-encoded its 2 MB PNG normal map as JPEG (the material
is OPAQUE, alpha unused): 3 704 300 bytes; render before/after mean |Δ| 0.5 / 255
(after-34/34-pack-ci/sveltrune-before-after.png).

FIX architecture-kit / scifi-kit recipes: defight AFTER kit-cut (and after a sci-fi kitbash).
The post step's defight ran before the mortar core / opening / lining existed, so a REBUILD
shipped 300-3 000 cm² of coplanar overlap on every wall that the shipped files do not have.
Counterfactual: `kit-build build architecture-kit` before this fix → check 18 errors,
scifi-kit → 9; after → 0 and 0, and WallStone / WallPlaster rebuild byte-identical to the
shipped files. (The forks' own output is unchanged: the previous commit's byte proof.)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…al per check + docs

.github/workflows/pack-checks.yml — on every PR to main (and pushes to main): npm ci in
tools/meshy (no browser, no Meshy key), the pack tools' unit tests (kit-build, lod, arch,
scifi, town, anim, interior, meshy) and `kit-build check` over every pack; the findings go to
the job summary, the JSON + budget report to an artifact. Job name `pack-checks` — the status
check to make REQUIRED on main (tools/kit-build/README.md has the click path and the gh api call).

tools/kit-build/test — a fixture pack that passes every check, then each check RED on the one
thing it exists to catch: index (no source / missing value), manifest (a typo'd key, a duplicate),
size, tris, textures, emissive, scale (cm export), pivot (and the declared exception passing),
lods (required, missing, wrong ratio, foreign node names, missing clips), behavior (missing
clip, autoplaying door), flicker (a decal on a face; its baseline passes; worse fails), thumb,
allow-list (accepted + stale); pass fixes cap/emissive/share-cap/budget and is byte-stable after.
rules.test: behavior/lods/rows/index/pivot/scale. 22/22; all suites 107/107 + meshy 30/30.

Docs: tools/kit-build/README.md (commands, checks, policy, allow-list, baseline, making the
check required); README.md (layout + Checks); tools/lod/README.md (who runs defight).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…time)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@AlexZ005

AlexZ005 commented Oct 2, 2026

Copy link
Copy Markdown
Contributor Author

CI proof: run 37006853596 / 37007101455 green on this branch. Counterfactual (throwaway draft #14, closed, branch deleted): run 37007384778 — unit tests green, kit-build check RED on exactly the two planted breaks (behavior.trigger 'clik' on interactive-kit/DoorWood, a deleted architecture-kit/Block thumbnail). An earlier variant with a wrong LOD ratio was already caught by tools/lod's own SHIPPED test (run 37007160494).

@AlexZ005
AlexZ005 merged commit 74b77d5 into main Oct 3, 2026
1 check passed
@AlexZ005
AlexZ005 deleted the feat/34-pack-ci branch October 3, 2026 09:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant