feat(topdata): parts autogen from CDN part.yml channel (Phase 2) #25

Merged
archvillainette merged 1 commits from feat/parts-autogen-cdn-channel into main 2026-06-26 12:12:06 +00:00
Owner

Phase 2 of the parts-row autogen design — Crucible (sow-tools) side only.

Resolves parts 2DA rows from the immutable `part.yml` published with the asset HAK release, over the anonymous Bunny CDN channel, with the parts consumer required (no fail-open).

Changes

  • Resolver (T3): generalize `resolveCDNChannelManifest` — derive manifest basename + provenance label from config; drop hardcoded `assets/vfxs.yml` so `part.yml` resolves through the same path. VFX behavior unchanged.
  • Parts filter (T4): `filterCDNChannelEntries` dispatches on consumer mode; new `filterPartsCDNChannelEntries` implements the inventory contract — `restype: mdl` under `part//`, row id from trailing digits, dedup l/r/race/gender variants by (category,rowID), sort by source, zero accepted rows = hard fail, reject row id 0 / non-numeric / malformed / no-assets.
  • Category (T5): add `hand` + `parts/hand` mapping (12 datasets; `leg→legs` already present).
  • Pipeline (T6): native build runs one explicit augment → normalize → override sequence under the configured `parts_rows` policy; overrides may update an existing/discovered row but never synthesize one (orphan override now errors).
  • Validation (T7): reject more than one `parts_rows` consumer.

Tests

9 new tests: parts filter contract, 12-dataset coverage, offline manifest-basename, orphan-override reject + discovered-row update, and a parity guard proving a bare CDN-only parts build needs no wrapper/token/NWN_ROOT/checkout.

Gate green: `go test ./internal/topdata/... ./internal/project/...` + full `go build ./... && go test ./...`.

Scope / ordering

Phase 2 is inert until Phase 1 (sow-assets-manifest publishes `part.yml`) ships and the operational Gate (release publish/promote) runs, then Phase 3 enables the sow-topdata consumer. Do not enable the consumer against a channel whose current release predates `part.yml`.

Plan: `sow-topdata/docs/superpowers/plans/2026-06-25-topdata-parts-autogen-channel.md`

🤖 Generated with Claude Code

Phase 2 of the parts-row autogen design — Crucible (sow-tools) side only. Resolves parts 2DA rows from the immutable \`part.yml\` published with the asset HAK release, over the anonymous Bunny CDN channel, with the parts consumer **required** (no fail-open). ## Changes - **Resolver (T3):** generalize \`resolveCDNChannelManifest\` — derive manifest basename + provenance label from config; drop hardcoded \`assets/vfxs.yml\` so \`part.yml\` resolves through the same path. VFX behavior unchanged. - **Parts filter (T4):** \`filterCDNChannelEntries\` dispatches on consumer mode; new \`filterPartsCDNChannelEntries\` implements the inventory contract — \`restype: mdl\` under \`part/<supported-cat>/\`, row id from trailing digits, dedup l/r/race/gender variants by (category,rowID), sort by source, **zero accepted rows = hard fail**, reject row id 0 / non-numeric / malformed / no-assets. - **Category (T5):** add \`hand\` + \`parts/hand\` mapping (12 datasets; \`leg→legs\` already present). - **Pipeline (T6):** native build runs one explicit augment → normalize → override sequence under the configured \`parts_rows\` policy; overrides may update an existing/discovered row but **never synthesize** one (orphan override now errors). - **Validation (T7):** reject more than one \`parts_rows\` consumer. ## Tests 9 new tests: parts filter contract, 12-dataset coverage, offline manifest-basename, orphan-override reject + discovered-row update, and a parity guard proving a bare CDN-only parts build needs no wrapper/token/NWN_ROOT/checkout. Gate green: \`go test ./internal/topdata/... ./internal/project/...\` + full \`go build ./... && go test ./...\`. ## Scope / ordering Phase 2 is inert until **Phase 1** (sow-assets-manifest publishes \`part.yml\`) ships and the operational **Gate** (release publish/promote) runs, then **Phase 3** enables the sow-topdata consumer. Do not enable the consumer against a channel whose current release predates \`part.yml\`. Plan: \`sow-topdata/docs/superpowers/plans/2026-06-25-topdata-parts-autogen-channel.md\` 🤖 Generated with [Claude Code](https://claude.com/claude-code)
archvillainette added 1 commit 2026-06-26 11:21:00 +00:00
feat(topdata): parts autogen from CDN part.yml channel
build-binaries / build-binaries (pull_request) Successful in 2m15s
test-image / build-image (pull_request) Successful in 37s
test / test (pull_request) Successful in 1m24s
2586b9193e
Phase 2 of the parts-row autogen design: Crucible resolves parts 2DA rows
from the immutable part.yml published with the asset HAK release, over the
anonymous Bunny CDN channel, with the parts consumer required (no fail-open).

- generalize resolveCDNChannelManifest: derive manifest basename + provenance
  label from config; drop hardcoded assets/vfxs.yml so part.yml resolves too
- add filterPartsCDNChannelEntries + mode dispatch implementing the inventory
  contract (restype mdl under part/<cat>/, trailing-digit row id, dedup
  l/r/race/gender variants, sort by source, zero accepted rows = hard fail)
- support hand category + parts/hand dataset mapping (12 datasets total)
- native pipeline: single augment -> normalize -> override sequence with the
  configured parts_rows policy; overrides may update but never synthesize a row
- reject multiple parts_rows consumers in project validation
- tests: parts filter contract, category coverage, offline basename, orphan
  override reject, and a parity guard proving a bare CDN-only parts build

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
archvillainette merged commit 06e5893734 into main 2026-06-26 12:12:06 +00:00
archvillainette deleted branch feat/parts-autogen-cdn-channel 2026-06-26 12:12:06 +00:00
Sign in to join this conversation.