Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 20 additions & 14 deletions dancer/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
# The dancer

**Current producer mesh declaration:** `config.json` carries the owner-selected smear50 bottomwear as an explicit payload at parts 1.64.0, with `bottomwear` still in `turn.depths`. Its setup seam is zero. This is separate from the immutable accepted dance replay below. Producer reproduction and the remaining motion/preservation blockers are recorded under `provenance/smear50-producer.json`.

**Current accepted dance: owner v3, 2026-10-24.** Run `sh build-accepted-dance.sh` from this directory. The corpus stores the accepted rig/motion once and replays them with released core; no trial checkout, acquisition, generation, retarget or hand authoring is needed. [V3 source and commands](accepted-dance/v3/README.md) and `declared-repairs-v3.json` bind the exact native-frame target. The setup keeper below is separate base provenance. The corpus-only v3 default replay exited 0: all three compiled hashes and native 391-PNG concatenation `b75fc5696ac468f3ea9f58cc892d79389d66bf6ce7aeb31428f95350b9121029` match the accepted target exactly; gate 23 PASS / 0 FAIL / 13 SKIP / 14 excluded. [Actual v3 proof](accepted-dance/v3/reproduction-evidence.json).

| Dance version | Source date | Record / selection |
| --- | --- | --- |
| v1 | 2026-10-24 | Accepted R3/v5, [trial #52](https://github.com/rig-c/examples/pull/52) and [corpus #53](https://github.com/rig-c/examples/pull/53); original declarations/evidence retained; explicit `sh build-accepted-dance.sh --version v1 work/accepted-v1` |
| v2 | 2026-10-24 | Intermediate generated holds and lifted-jacket strip, [#38](https://github.com/rig-c/examples/issues/38); recorded, not promoted |
| v3 | 2026-10-24 | Owner-named final, [#56](https://github.com/rig-c/examples/issues/56), [trial #57](https://github.com/rig-c/examples/pull/57); permanent hip waist, generated chest holds, compensated +17u chest lift and front-slot lowering; current default |
| v4 | 2026-10-25 | Explicit smear50 mesh-only candidate, [#71](https://github.com/rig-c/examples/issues/71); original eval 20/4, bottomwear folds 0; [source, reproduction and evidence](accepted-dance/v4/README.md); opt in with `sh build-accepted-dance.sh --version v4 work/accepted-v4`; owner eye acceptance pending |

Generated painting and saved rig inputs accepted on 2026-10-22. Origin:
accepted dance-skirt v3/v5; original painting and See-through runs, 2026-10-13.
Expand All @@ -20,7 +23,7 @@ Each input's origin is recorded in `source-manifest.json`.
`layers/full/` and `layers/head/` each contain 29 tagged parts and saved
metadata. Each `layers.json` retains original server filename/depth
provenance; exported parts are addressed by `parts/<tag>.png`.
- `config.json` preserves the v3 keeper producer values with 11 physics constraints; its added `x-repairs` metadata pins the declared hand record.
- `config.json` states the explicit smear50 producer mesh with the original 11 physics declarations. `provenance/keeper-config-before-smear50.json` preserves the exact previous keeper for historical replay. `x-repairs` still pins the unchanged historical hand record.
`config-base.json` is the historical 9-constraint input, not the active
keeper. `under/`, `stress.json` and `requirements.json` close the declared
build dependencies.
Expand All @@ -38,24 +41,28 @@ No reference video, audio, picture-in-picture, installed dependency tree or priv
log is included. The current accepted dance payload is explicitly stored once under accepted-dance/v3/. Generation model names are source records; model binary hashes
are not available in those records.

## Reproduce the keeper-config build
## Reproduce the current producer build

From this directory, with Bun and Python 3:

```sh
sh build.sh
```

This command builds `config.json`; it does not build `accepted/rig.json`.
**It may exit 1: the recorded current run below did so at the seam check.**
Output is ignored under `work/`. The accepted rig has the separate core build described below.
This command builds `config.json`; the explicit producer passes the unchanged setup seam at mean 0 and 0 pixels over 40. Output is ignored under `work/`. The saved accepted rig has the separate core build described below.

The adopted canonical producer bytes are in `producer/rig/`. A fresh rebuild and byte/RGBA inventory comparison runs as:

```sh
bun tools/verify-producer.mjs --out work/fresh-producer
```

Choose a new output directory for each rebuild. The verifier refuses changed/missing files, changed decoded PNG pixels, a red check, or changed active config/package pins. It verifies all 31 producer files; it does not claim the original accepted dance can be played on this different producer rig.

Direct package pins are `@rig-c/parts` 1.60.0, `rig-c` 2.67.2 and the official
round-trip runtime `@esotericsoftware/spine-core` 4.3.13. The recorded Nova run
used Bun 1.4.2, Node v24.21.0 and Python 3.12.3. `check-inputs.py` checks file
The current frozen producer install pins `@rig-c/parts` 1.64.0, direct `rig-c` 2.67.2 and official `@esotericsoftware/spine-core` 4.3.13. Parts resolves its own compatible rig-c 2.70.0, recorded in `bun.lock`; that is the compiler its build/check invokes. The new Nova producer runs use Bun 1.4.4. Historical dance replay keeps its separate frozen package pins. `check-inputs.py` checks file
hashes and config/map closure; it does not render or establish rig correctness.

## Recorded current build, 2026-10-23
## Historical keeper-config build, 2026-10-23

One targeted closure and keeper-config build ran on Nova. Inputs were unchanged
through the run. No fallback build or rig modification was performed.
Expand All @@ -80,15 +87,14 @@ The documented diagnostic is to inspect the `seam pair` lines and
No corrective config, art, geometry, limit or gate changes were made. This
config-build refusal does not establish a regression or a failure of the
separate accepted hand-built rig. The config gap is recorded for a separate parts issue and does not block use
of the saved accepted rig. No producer fix is included.
of the saved accepted rig. This historical refusal is retained as provenance; the current explicit producer above resolves its setup seam.

## Input integrity

`source-manifest.json` lists repository-relative input paths, byte counts,
SHA-256 hashes, source hashes and origins. `path-normalization.json` records the
two See-through metadata image-path changes. Keeper producer values and historical base config bytes are preserved exactly.
The keeper adds only `x-repairs` metadata; removing that field and writing
two-space JSON with one trailing LF recovers its original recorded hash.
two See-through metadata image-path changes. Historical base config bytes and the archived pre-smear50 keeper are preserved exactly.
Removing only `x-repairs` from the archived keeper and writing two-space JSON with one trailing LF recovers its original recorded hash. The active config additionally declares the explicit skirt; its canonical producer inventory has a separate config hash.
Accepted image bytes and map values are preserved.

## Build the accepted rig
Expand All @@ -97,7 +103,7 @@ The accepted v3 source is the hand-built transplant recorded by
`replace_shins.py`, using the weighted-shins output from the parts 1.57 source
build. `port_config.py` writes the keeper producer-input config and port ledger;
it does not write the accepted rig. Its external historical dependencies were
not followed or executed for this package. Keeper geometry and producer values remain unchanged; only the declared-record metadata pin is added.
not followed or executed for this package. The archived keeper geometry and producer values remain unchanged. Historical replay readers explicitly use that archive for their original config preimage; they do not substitute the new active producer mesh.

From this directory:

Expand Down
57 changes: 57 additions & 0 deletions dancer/accepted-dance/v4/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Mesh-only dance candidate v4

V4 replaces only `skins.default.bottomwear.bottomwear` in immutable v3 with the
owner-selected smear50 payload. Motion bytes, all other attachments, bones,
constraints, slots and skeleton remain identical. `provenance.json` binds the
sources and payload. V3 remains the default pending owner video acceptance.

From `dancer/`, select this replay explicitly:

```sh
sh build-accepted-dance.sh --version v4 work/accepted-v4
```

The frozen runtime installs from the dancer lockfile: released core 2.67.2,
Spine runtime 4.3.13. Python 3 and Bun are required. The real compile reader runs
before the build; the unchanged gate runs before render. A fresh output path is
required. Numbered PNGs are deleted after their ordered-byte receipt is written.
For staged measurement, `tools/reproduce-smear50.py` also supports `--build-only`,
`--render-only` and explicit `--keep-frames`. Measurement tools need retained
frames until the sheet/video verdict; delete them after recording the receipt.

The separate config producer uses parts 1.64.0 and its resolved core 2.70.0.
It is not the accepted dance rig and cannot consume its missing control bones.
These dance measurements apply only to this v4 replay.

| Original instrument / fixed viewport | V3 | V4 |
| --- | ---: | ---: |
| Left share >= .60, rounded to three decimals, original eval.py | 31 | 20 |
| Right share >= .60, same instrument | 13 | 4 |
| Bottomwear fold frames, all 391 samples | 0 | 0 |
| Known shins fold frames, reported separately | 269 | 269 |
| f254 left share | .860 | .745 |
| f266 right share | .799 | .671 |
| Worst minimum singular value, f278 | .119286 | .196432 |

These are a reduction, not elimination of the visible stair artifact. M1 tip
trajectory deviation is 0 units. Maximum silhouette deviation against accepted
v3 is 15.425046 pixels at f279, including 14.164224 pixels of setup shift. The
older 4.6-pixel figure used a different bind baseline and is not this comparison.

The gate reports 23 PASS, 0 FAIL, 13 SKIP, 14 excluded for each version. V3's three
compiled hashes and 391-frame native concatenation reproduce its accepted
record exactly. The new render receipts bind source/build hashes, commands,
viewport, geometry/folds and all ordered native PNG bytes in `evidence/`.
Original private measurement scripts remain outside this repository; their exact
hashes and actual outputs are recorded in `evidence/measurement.json`.

![Fixed f254 and f266 comparison](evidence/smear50-f254-f266.jpg)

Owner review receives the f240–290 H.264 video privately: full figure plus both
flanks at 4x nearest, v3 left and v4 right; 3072x1600, 51 frames at 30 fps,
SAR 1:1, 1,367,689 bytes. The stream and SHA-256 are in the video receipt.
`tools/smear50-preview.py` reproduces that layout from retained v3/v4 frames;
provide Pillow and explicit ffmpeg/ffprobe executables. Original PNGs were
hash-checked and deleted after the sheet was read (391 per version). The small
sheet, video receipt and native render receipts remain. Owner eye acceptance is
pending; this record does not promote v4 or change the default.
89 changes: 89 additions & 0 deletions dancer/accepted-dance/v4/evidence/measurement.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
{
"spec": "dancer-smear50-measurement/1",
"scripts": {
"crops.py": "9dc426f90200d5e685f4ce79b9fdab4cdd3ec3220caf49c6dd11f98e247a398b",
"measure.py": "926889c5d0de5f95dafa31cbf49a9a223a33c4f137ec68c5ee50291fb763f509",
"meshlib.py": "caa05921a79905cdbcc0d9f5e430453889e08db879e1b830cf211b7c0ea77ded",
"stats.py": "b1307685be5a706d26cf19589f4635305c361f04e69f5cdfac01292b3280f69c",
"eval.py": "2aab0abce78e67ed498e428b6b9e485783a0cacd51cb32215041c28f4ad8b1c8",
"rawworld.py": "eee098da469935e36106ee3ecaac8a4da99fe5b10dfeab732d187fae794f4f20"
},
"Pillow": "12.2.0",
"v3": {
"left60": 31,
"right60": 13,
"maxL": [
0.978,
278
],
"maxR": [
0.799,
266
],
"f0": [
0.235,
0.101
],
"f254L": 0.86,
"f266R": 0.799
},
"v4": {
"left60": 20,
"right60": 4,
"maxL": [
0.839,
278
],
"maxR": [
0.678,
265
],
"f0": [
0.2,
0.073
],
"f254L": 0.745,
"f266R": 0.671
},
"bottomwearFoldFrames": {
"v3": 0,
"v4": 0
},
"v4Motion": {
"tipDevUnits": 0,
"tipDevFrame": 0,
"tipDevPx": 0.0,
"silDevPxMax": [
15.425045979525779,
279
],
"silDevPxMean": 2.8935517237246833,
"f254dev": 14.665617879656104,
"f266dev": 13.067361493953495,
"peaks": {
"leftPeak": 253,
"rightPeak": 319,
"lowPeak": 230
},
"basePeaks": {
"leftPeak": 253,
"rightPeak": 319,
"lowPeak": 230
},
"setupShiftPx": 14.164224029640692,
"ampL": -79.80469511064244,
"baseAmpL": -65.2551616610527,
"ampR": 112.5421740000642,
"baseAmpR": 103.84880163626102
},
"bar3": true,
"framesDeletedAfterSheetReview": {
"v3": 391,
"v4": 391
},
"ownerVideoAcceptance": "pending; v3 remains default",
"knownShinsFoldFrames": {
"v3": 269,
"v4": 269
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"spec": "dancer-smear50-video/1",
"window": [
240,
290
],
"fps": 30,
"left": "v3",
"right": "v4",
"cropBoxes": {
"left": [
220,
380,
420,
580
],
"right": [
420,
380,
620,
580
]
},
"scale": 4,
"filter": "nearest",
"stream": {
"codec_name": "h264",
"width": 3072,
"height": 1600,
"sample_aspect_ratio": "1:1",
"duration": "1.700000",
"nb_frames": "51"
},
"bytes": 1367689,
"sha256": "47660797dcc7f765e8fc22cbc978db627fa7969f89b3ee25c9f391d4ffd53d35",
"ffmpeg": "ffmpeg version 8.0.1-essentials_build-www.gyan.dev Copyright (c) 2000-2025 the FFmpeg developers",
"captionSHA256": "d8fa309a95ced3e6fb9ac4716155b77f9d92040b53453898c5a89cad0e923158"
}
81 changes: 81 additions & 0 deletions dancer/accepted-dance/v4/evidence/v3-render-receipt.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
{
"spec": "dancer-smear50-render/1",
"version": "v3",
"sourceRigSHA256": "a1860937f20890818a206a2b15318eaf2bf9e253d58584976b8aa9697f73e135",
"sourceMotionSHA256": "46189464040b3ef8b42357399e1c8b0c1c4cbf6feedeabb24927eb09242f5aa7",
"build": {
"skeleton.json": "4e6024989f06a15525bf5cb32a47bb7aa55a75d8adf58505ce6b1a12efb49f77",
"skeleton.atlas": "bd9d9414f016e94407a61685455888a7aad6781acdd9d634a0a9f3c0c432cdf1",
"skeleton.model.json": "a94c7cbee992acaf87c0e283efc1bbd44766441f791776064e929bd59a2f0e81"
},
"commands": [
{
"label": "readers",
"command": [
"bun",
"<corpus>/tools/read-smear50.ts",
"<corpus>/node_modules/rig-c",
"<workspace>/hand/v3/rig.json",
"<workspace>/hand/v3/motion.json",
"<workspace>/build"
]
},
{
"label": "build",
"command": [
"bun",
"<corpus>/node_modules/rig-c/cli.ts",
"build",
"--rig",
"hand/v3/rig.json",
"--motion",
"hand/v3/motion.json",
"--out",
"build",
"--profile",
"spine"
]
},
{
"label": "render",
"command": [
"bun",
"<corpus>/node_modules/rig-c/cli.ts",
"render",
"--candidate",
"build",
"--animation",
"zero-two-r3-hand",
"--fps",
"30",
"--viewport-from",
"<corpus>/accepted-dance/viewport.json",
"--geometry",
"--folds",
"--out",
"render"
]
}
],
"frames": 391,
"fps": 30,
"viewport": {
"x": -575.1001332056925,
"y": -22.832002283065037,
"width": 1038.3634465496543,
"height": 1353.8478314199037,
"scale": 0.7090900304454161,
"pixelWidth": 736,
"pixelHeight": 960
},
"background": [
232,
232,
232,
255
],
"sha256": "b75fc5696ac468f3ea9f58cc892d79389d66bf6ce7aeb31428f95350b9121029",
"deleted": false,
"geometrySHA256": "c64ec1d79ae5a62f09a67a9fed5d0aeef9b6b73a5989b57ef123ebefb3a3ee4a",
"foldsSHA256": "ccdba93c059893fb854cad12aff9b73e7cf6ed8d50822df420dc3927c59fec3a"
}
Loading
Loading