Written by the session that picked up `notes/m08-handoff.md`. **Everything here was read out of the running Blender session, read-only. Nothing in the scene was modified.**
The 31 Aug M-08 build (21 objects) was destroyed by an undo and no file on disk holds it; see `notes/m08-handoff.md` for the full account. That note recorded the numbers one session had measured before the undo. This note records a second, independent source that the handoff did not know about, and that will not survive the next save.
TIME-SENSITIVE. The datablocks below are orphans — zero users, alive only in the running session's memory. Blender purges zero-user datablocks on save/reload. **Save or reopen the file and they are gone for good.** They are transcribed here so that ceases to matter.
| Fact | Value |
|---|---|
| `bpy.ops.ed.redo.poll()` | False — the redo branch is gone, independently confirmed |
| `bpy.ops.ed.undo.poll()` | True (the wrong direction; not touched) |
| Open file | `/home/mabel/blender-checkpoints/printshop-before-relayout-20260831-125143.blend` |
| `bpy.data.is_dirty` | True |
| Objects | 169 · scene frames 1–168 @ 24fps · EEVEE · active camera `CAM_ref_match` |
| M-08 objects present | `CAM_m08_twoshot` + `CAM_m08_twoshot_target` only — the old pre-build camera, 32mm, TRACK_TO. None of the 21 built objects. |
| `PRP_box_01` | (4.3, −1.8, 0.325), scale (0.75, 0.79, 0.65), `PRINTSHOP_FURNITURE`, no material — as the handoff describes. Placement still unconfirmed by Mabel. |
| Counting desk + ledger | all visible again (`hide_render`/`hide_viewport` false on `_top`, `_body`, all three `PRP_ledger_*`) — the M-08 hiding is undone and still an open decision |
| Desk | at (5.025, −1.25); body AABB x 4.7–5.35, y −1.85 to −0.65, z 0–0.98 |
The handoff (and the 31 Aug 16:08 message to Mabel) says the four `CHR_*` have "an empty material slot — no material assigned at all." **That is wrong, and it is a read that went to the wrong place.** `o.data.materials` is empty, but the slot's `link` is `'OBJECT'`, so the material is linked to the object, not the mesh:
| Object | Slot link | Material | Base colour | Renders as |
|---|---|---|---|---|
| `CHR_Apprentice` | OBJECT | `MAT_CHR_Apprentice` | 0.20, 0.35, 0.88 | flat blue |
| `CHR_Lufft` | OBJECT | `MAT_CHR_Lufft` | 0.80, 0.13, 0.10 | flat red |
| `CHR_OldPrinter` | OBJECT | `MAT_CHR_OldPrinter` | 0.92, 0.48, 0.08 | flat orange |
| `CHR_YoungPrinter` | OBJECT | `MAT_CHR_YoungPrinter` | 0.94, 0.83, 0.14 | flat yellow — and this one is hidden, `hide_render` and `hide_viewport` both true |
All four are Principled, roughness 0.7. Confirmed against `m08_v6_C_f110.png`, where the boy reads flat blue and the Old Printer flat orange-cream.
The substantive point stands unchanged: they are 178-vertex capsules and there is no hair, beard, cap or apron anywhere — a search of every object name for hair/beard/cap/apron/ jerkin/shirt returns nothing. They are ID-coloured blocking figures. The correction only changes what a Blender still looks like, not what it is worth.
The rebuild list is 21 objects — rigs, cameras, aims, table, legs, piles, bench. **It does not include where the two men stood**, and they were moved as part of that build, so the undo put them back. Current positions:
Neither can be where he was. The `C_hold` camera sits at (1.7, 1.2, 1.55) aiming at (4.0303, −0.6901, 0.85) — i.e. looking along +x. A figure at x = −1.128 is *behind that lens* and cannot appear in the frame at all, yet `m08_v6_C_f110.png` plainly shows the boy large at the left at his table. So he was standing somewhere around x ≈ 4 and was moved back.
**Rebuild the 21 objects alone and the two men will still be standing in the wrong half of the room.** Inferences available, both to be flagged as such if used:
Camera at f150, world: rig (1.7, 1.2, 1.55) + local (0.4596, −0.3857, −0.08) = **(2.1596, 0.8143, 1.47)**. Aim f150 (3.448, 0.3273, 1.14). 32mm on a 36mm sensor → horizontal half-angle 29.36°, vertical (16:9) 17.56°.
The Old Printer half checks out exactly. Axis yaw at f150 = atan2(−0.487, 1.2884) = −20.71° ✓ (matches the recorded figure). His bearing from that camera position, taken at the bench, = −51.80°. Off-axis = 31.08° against a 29.36° half-angle ✓ — the recorded 31.1°, reproduced. Start likewise: from the f12 camera at (1.7, 1.2, 1.55) his bearing is −50.28° against an axis of −39.05°, so 11.2° off-axis ✓ (recorded 11.1°).
The head-crop half does not. Taking the boy at (3.967, 0.479) with his capsule top at 1.558, the top of his head computes to **16.2° above the axis against a 17.6° half-frame — just inside.** But `m08_v6_B_f150.png` shows the head unmistakably cut by the top edge. The render is the ground truth, so the assumption is what is wrong — which is independent evidence for the gap above: the boy's real stance is not among the recorded numbers.
Consequence for the fix. Trimming the pan can be computed exactly, because it depends only on the bench position, which is recorded. Raising the end position cannot — it depends on the boy's true position, which is not — so that one needs a test render, not arithmetic.
The camera's yaw is not settable directly — TRACK_TO drives it — so the edit is to `AIM_m08_B`'s f150 key, holding its distance (1.3774 m) and z (1.14):
| Pan | End axis yaw | Old Printer off-axis | Margin inside 29.36° | New `AIM_m08_B` f150 x,y |
|---|---|---|---|---|
| 18.34° (as built) | −20.71° | 31.08° | −1.72° — out of frame | (3.4480, 0.3273) |
| 16.6° | −22.44° | 29.36° | 0.00° — exactly on the edge | (3.4276, 0.2790) |
| 15.1° | −23.94° | 27.86° | 1.50° | (3.4098, 0.2373) |
| 14.0° (handoff's suggestion) | −25.05° | 26.75° | 2.61° | (3.3966, 0.2065) |
The handoff's 14° is the conservative pick and I would keep it; 16.6° is where he touches the edge, so anything above that is out.
These are zero-user datablocks still in memory. *They are named `PRP_boy_`, not `PRP_m08_*`, and several of their figures disagree with the destroyed build's recorded ones, so they are an earlier revision of the same staging — a recipe, not a restoration.** Treat every number here as "how it was done before," not "how it was."
No orphan cameras, no orphan objects, and no orphan rig or bench data — the three camera rigs, the three cameras, the three aim empties and the bench left nothing behind.
| Mesh | Size (x, y, z) |
|---|---|
| `PRP_boy_table_top` | 1.2 × 0.7 × 0.08 |
| `PRP_boy_table_leg_nn` / `_np` / `_pn` / `_pp` | 0.07 × 0.07 × 0.74 each |
The handoff flags the destroyed tabletop's width and depth as INFERRED, resting on "the earlier build's note" of 1.2 × 0.7. **Here is that earlier build's actual geometry, and it is 1.2 × 0.7 exactly** — so the note was right and the plan dimensions now rest on measured geometry rather than on a recollection.
But the vertical figures disagree by 2 cm, consistently, and I will not paper over it: the orphan top is 0.08 thick and its legs 0.74 tall, where the destroyed table was recorded as a top surface spanning z 0.72–0.78 (0.06) on legs z 0–0.72. Either these orphans are a revision earlier than the one that was destroyed, or one of the two z readings is off. **The 1.2 × 0.7 plan is corroborated; the 2 cm in section is an open question.**
25 orphan meshes `PRP_boy_sheet_01` … `_25`, each 0.30 × 0.42 m and 0.2 mm thick. Twenty-five is inside Mabel's "20–30 papers" for the row, and 0.2 mm is a real sheet.
Six of them are animated, and the handoff does not mention this animation existed at all. Six orphan actions, one lift-and-lay each, no f-curve modifiers on any of them:
| Action | Frames | Duration |
|---|---|---|
| `PRP_boy_sheet_18Action` | 8 → 15 → 22 | 14 f |
| `PRP_boy_sheet_17Action` | 34 → 41 → 48 | 14 f |
| `PRP_boy_sheet_16Action` | 60 → 67 → 74 | 14 f |
| `PRP_boy_sheet_15Action` | 86 → 93 → 100 | 14 f |
| `PRP_boy_sheet_14Action` | 112 → 119 → 126 | 14 f |
| `PRP_boy_sheet_13Action` | 138 → 145 → 152 | 14 f |
Every one is the same move, three keys per channel:
The cadence: one sheet every 26 frames = 1.083 s at 24fps, six crossing in the 168-frame shot, consumed from the top of the source pile downward by index (18, 17, 16, 15, 14, 13).
The piles settle by exactly one sheet thickness per crossing, which is why this is worth keeping — it was built physically, not faked:
| Sheet | Lifts from z | Lands at z |
|---|---|---|
| `_18` | 0.8235 | 0.8215 |
| `_17` | 0.8233 | 0.8217 |
| `_16` | 0.8231 | 0.8219 |
| `_15` | 0.8229 | 0.8221 |
| `_14` | 0.8227 | 0.8223 |
| `_13` | 0.8225 | 0.8225 |
The source pile drops 0.2 mm and the destination rises 0.2 mm on every crossing — one sheet each way, exactly.
**Two figures that do not reconcile with the destroyed build, and should not be quietly carried over:**
1. Height. These sheets sit at z ≈ 0.8225–0.8235, about 4 cm above the destroyed piles' recorded tops (0.784 and 0.7816). 2. Separation. These move ±0.25 on local x — piles 0.5 m apart. The destroyed piles were recorded at (3.448, 0.127) and (3.448, 0.527) — 0.4 m apart, and on y, not x. A 90° parented rotation would explain the axis but not the 0.5 against 0.4.
So: take the **timing, the arc, the tilt, the cadence and the one-sheet-per-crossing settle from this, and take the positions** from the handoff's measured `PRP_m08_pile_a/b`.
1. Exact, from the handoff — three rigs, three cameras, three aim empties, all 32mm with `dof.use_dof = False` and TRACK_TO; both pile positions and thicknesses; table and bench centres and leg spacing. 2. Corroborated, from the orphans — the tabletop 1.2 × 0.7 plan (2 cm open in section). 3. Recovered here, as a recipe — the boy's sheet business: six crossings, 14 frames each, 26 apart, +60 mm arc, 7° tilt, one-sheet settle. 4. Inferred, and to be flagged in place — the two men's standing positions. 5. Re-made from spec, not restored — the handheld noise (0.112°, 3.5/3.0/4.0 s cycles, on the AIM empties, since TRACK_TO overrides keyed camera rotation). 6. A decision, not a restoration — whether to re-hide the counting desk and ledger, and where `PRP_box_01` finally goes. 7. Fix `B_push` before rolling anything on it — pan trimmed to 14° per the table above, and the end height found by test render rather than arithmetic.
Every object named `_m08_` so the whole reconstruction lifts back out in one selection.
Read as rebuild exactly as it was: the pan trim is a modification, not a reconstruction, so B_push was left at its as-built 18.34 degrees and the defect reproduces on purpose.
`bpy.ops.ed.redo.poll()` was polled again immediately before the first mutating call and was still False. Checkpoint written first — `blender-checkpoints/printshop-before-m08-rebuild-20260901-085823.blend`, 198,649 bytes, `copy=True`, active filepath untouched. **The file was not saved by that session** — but it has been since, and this line was stale by the time anyone read it. The rebuilt objects went to disk on 1 Sep in three later saves (09:57, 10:03 and the 11:00 `printshop-m08-relayout-20260901.blend`), and that 11:00 file also carries a further relayout the session never recorded: the shop's old `PRP_bench` and its three parts plus `PRP_letter` deleted, and two cameras added, `CAM_m08_D_tq` and `CAM_m08_survey`, with their aim empties. The rebuild is not at risk; nothing below needs re-deriving.
| Quantity | Recorded | Rebuilt |
|---|---|---|
| B_push yaw at f12 | −39.05° | −39.045° |
| B_push yaw at f150 | −20.71° | −20.706° |
| B_push net pan | 18.34° | 18.339° |
| B_push dolly | 0.605 m | 0.6053 m |
| B_push sink | 0.08 m | 0.080 m |
| A_drift yaw travel | −11.0° | −11.001° |
| C_hold camera travel | 0 | 0 |
| C_hold aim drift | 2.5° | 2.478° |
| Old Printer off-axis, f12 | 11.1° | 11.23° |
| Old Printer off-axis, f150 | 31.1° | 31.09° |
| A_drift composition frozen | residual 0 | ≤0.002° |
All three cameras start at exactly (1.7, 1.2, 1.55) — A's rig pivot and local offset land its camera on B's and C's start point to within a millimetre. Nothing made that happen except the recorded numbers being right; it is the strongest single check that the reconstruction is faithful.
Structural: 21 objects added, 0 removed, 169 → 190, every added name carries `m08`, no `.001` duplicates, every placement delta exactly 0.000. Engine, resolution, frame range, fps, active camera (`CAM_ref_match`) and current frame all as found.
The handheld noise. Re-making it would have made the rebuild un-checkable against the old stills, and it is the one thing that cannot be restored anyway. **Worth knowing before anyone re-makes it from the spec on the record: that spec cannot do what it says.** "0.112 deg on the AIM empty" has no effect — a TRACK_TO constraint reads only its target's location, so rotating the aim empty moves nothing. Shake has to come from the aim's or the camera's location channels, or from a noise-carrying parent. The number may be right; the channel on the record is not.
1. Neither man is in frame — exactly the gap flagged above. Measured, not guessed: at f110 the Apprentice has 0 of 178 vertices in frame and sits behind the lens; the Old Printer has 0 of 178 and is off the right edge. 2. `PRP_box_01` is now mid-frame in all three, and untextured, so it is the brightest object in the picture. It has not moved — this is this morning's unconfirmed (4.3, −1.8). From C it has crossed the frame: 7.7° off axis at its old spot, 10.0° the other side now. And on the bench's inferred footprint the bench's north-west leg passes through it by about 3.6 cm — the box was placed when the bench did not exist. 3. The counting desk and ledger are in shot again — fully in frame from all three cameras. Hiding them was part of the destroyed build and is still an open decision.