ComfyUI Higgsfield Opensource Challenge The analysis ← Build log

The analysis

04 — The convergence honesty problem, and the build

Scope: the second honesty problem — the solver that ran 24 iterations with no convergence test — what the port changed and how the change was proved; then the build itself: the engine, the six nodes, the two workflow graphs, the director's panel, and the three verification harnesses.

Source root: as 01-premise-and-reaim.md §0.

Method: static reading of the engine, the nodes, the graphs, the panel and the three harnesses. Three commands were re-run during the writing of this file and their outputs are quoted verbatim: the differential check, the unit suite, and the panel parity check. Nothing was rendered and no ComfyUI instance was started.


1. The convergence honesty problem

1.1 What the Go original does

The port's own docstring states the defect it was written to fix:

"The Go original runs exactly 24 iterations and returns the 24th iterate's report unconditionally. There is no convergence test and no early exit, so nothing guarantees `overall_pass — the prior internal report's claim that it 'solves a compliant camera pose' is overstated." — app/cinematographer/autoframe.py:6-9`

The README states it in the same terms:

"The internal Go solver this pack ports runs exactly 24 iterations and returns the 24th iterate unconditionally — no convergence test, no early exit, no guarantee the result passes." — app/README.md:90-91

The spec's non-goal list makes the correction mandatory:

"Claiming 38 rules, or claiming the solver converges when it does not." — 01-SPEC.md:311

1.2 Why it is a problem worth fixing

The prior teardown sold the solver as a feature:

"AutoFrameCamera solves a compliant camera pose in 24 geometric iterations at no AI cost." — client-reports/higgsfield-cinema-studio-4.0/analysis/00-SYNTHESIS.md:179-180

"Solves a compliant camera pose" is not what the code does. It runs a fixed number of iterations and returns whatever it has. The word "compliant" is doing work the code does not support.

This is the same class of defect as the "38 rules" claim (03-differentiator-and-rule-count.md §4): a number that describes the intent presented as a number that describes the behaviour.

1.3 What the port changed

Four changes, all in auto_frame_camera() (autoframe.py:95-193):

# Change Code
1Early exit as soon as the frame passesautoframe.py:164-166
2converged flag, set from the report's own verdictautoframe.py:190
3iterations — the count actually used, not the budgetautoframe.py:141, :191
4residual — the weighted rules still failing when it does not convergeautoframe.py:184-186

The early exit is three lines:

# app/cinematographer/autoframe.py:164-166
# --- the fix: stop as soon as the frame is actually compliant ---
if early_exit and rep.overall_pass:
    break

The converged flag is not a separate computation. It is the report's verdict:

# app/cinematographer/autoframe.py:187-193
return AutoFrameResult(
    camera=cam,
    report=rep,
    converged=rep.overall_pass,
    iterations=iterations,
    residual=residual,
)

That is the design decision that makes the flag trustworthy: converged cannot disagree with the report, because it is the report. There is no second code path that could drift.

The residual is filtered to the rules that actually gate the verdict:

# app/cinematographer/autoframe.py:184-186
residual = [
    f"{s.rule}={s.value:g}" for s in rep.failures() if s.weight >= 0.8
]

1.4 The escape hatch that makes the proof possible

The port keeps a parameter whose only purpose is verification:

# app/cinematographer/autoframe.py:107-109
Set ``early_exit=False`` to reproduce the original Go behaviour exactly
(always run the full iteration budget). That is used by the differential
test to prove this port is faithful before the fix is applied.

This is the single most important design decision in the verification story. Without it, the port could not be differentially compared to Go at all — the early exit would make every autoframe fixture diverge by construction.

The differential check uses it exactly as documented:

# verification/differential_check.py:141-142
# The Go solver always runs its full budget. Run ours with early_exit=False
# to prove the port is faithful, then separately confirm the fix engages.
# verification/differential_check.py:158-160
faithful = auto_frame_camera(
    to_subject(fx["subject"]), shot_type, intent, early_exit=False
)

And then, in the same loop, separately asserts the fix:

# verification/differential_check.py:175-181
# The fix: with early exit on, we must never do more work than Go.
fixed = auto_frame_camera(to_subject(fx["subject"]), shot_type, intent)
checks += 1
if fixed.iterations > 24:
    failures.append(f"{label}: early-exit ran {fixed.iterations} > 24 iterations")
if fixed.converged != fixed.report.overall_pass:
    failures.append(f"{label}: converged flag disagrees with the report")

So the 289-check run proves two different things in one pass: fidelity (with the fix disabled) and the fix itself (with it enabled). That is a genuinely elegant structure and it is worth naming.

1.5 How the change was proved

Four independent lines of evidence.

1. The unit tests. Four tests pin the behaviour (app/tests/test_autoframe.py):

Test What it pins Line
test_solver_exits_early_rather_than_always_running_24_iterationsiterations < MAX_ITERATIONS on a solvable frame — "the headline behavioural difference":31-39
test_converged_flag_agrees_with_the_reportconverged == report.overall_pass across 9 combinations (3 shot types × 3 intents):48-53
test_unsolvable_intent_is_reported_honestly_not_hiddenA degenerate subject (zero height) returns converged is False with a non-empty residual:64-83
test_solved_pose_reproduces_a_passing_report_when_re_evaluatedThe returned pose actually passes when fed back through the evaluator:125

The early-exit test's docstring states the regression condition:

"This is the headline behavioural difference: if this ever equals MAX_ITERATIONS on a solvable frame, the early exit has regressed." — app/tests/test_autoframe.py:34-35

2. The differential check's early-exit assertion. 18 checks, one per autoframe fixture (differential_check.py:177-181).

3. The adversarial review's 1800-call invariant sweep. This is the strongest evidence, because it was produced by someone trying to falsify the claim:

"C — Solver convergence honesty — CONFIRMED. 1800 solver calls: converged never disagrees with report.overall_pass. No counterexample found." — verification/ADVERSARIAL-REVIEW.md:35

And the falsification log:

| 8 | 1800-call solver invariant sweep | FAILED to falsify — zero anomalies | — verification/ADVERSARIAL-REVIEW.md:641

| 9 | Hunt for converged=True with a failing weighted rule | FAILED to falsify — zero cases | — verification/ADVERSARIAL-REVIEW.md:642

4. The verification README's own statement.

"On the reference fixture the solver converges in 3 iterations; the Go original would run all 24 and return the 24th unconditionally." — verification/README.md:88-89

1.6 The one thing the review found that the entry had not disclosed

The review's attempt #10 succeeded, and the finding is a genuine gap in the entry's own framing:

| 10 | Hunt for converged=True with a failing non-weighted rule | SUCCEEDED — 24 cases; documented as intended | — verification/ADVERSARIAL-REVIEW.md:643

The panel README documents the general case (app/web/README.md:201-202), and the review accepts it as intended. But the review also records the sharper version as defect #17:

| 17 | MINOR | converged=True can coexist with a badly failing 0.7-weight rule and off-frame feet; the panel's success text does not hint at this. | app/web/app.js:676-678; framing.py:104 | — verification/ADVERSARIAL-REVIEW.md:626

"Off-frame feet" is the detail worth pausing on. in_frame checks the subject's face, not their feet (framing.py:102-103), which is correct for a close-up and is documented in the code. But it means a frame can pass with the subject's feet outside the frame and a 0.7-weight rule badly failing, and the panel will say CONVERGED.

The convergence flag is honest about what it measures. It is not a claim that the frame is good. The entry's success text does not make that distinction, and the review flagged it.

1.7 The second-order finding: the Go failure mode is undemonstrated

The entry sells the fix by contrast with the Go original's failure mode. The review checked whether that failure mode is actually demonstrated by any captured fixture:

| 11 | Hunt for a Go fixture whose 24th iterate fails | SUCCEEDED — none exist; the failure mode is undemonstrated | — verification/ADVERSARIAL-REVIEW.md:644

| H10 | "The Go original … returns the 24th iterate unconditionally" | app/README.md:90-91 | True of the Go code, but no fixture demonstrates it failing — all 18 Go autoframe fixtures end on a passing frame. Presented beside measured claims without that distinction. | — verification/ADVERSARIAL-REVIEW.md:581

| 16 | MINOR | The Go solver's failure mode is sold but not demonstrated by any captured fixture. | app/README.md:90-91; go-reference-dump.json | — verification/ADVERSARIAL-REVIEW.md:625

This is the most interesting finding in the whole review, and it is a finding about the entry's rhetoric rather than its code. The claim is true of the Go source. But the entry presents it beside measured claims, and the measured evidence does not contain a single instance of the failure. A judge who asks "show me a Go solve that returned a failing frame" cannot be answered from the captured dump.

The honest fix is one clause: "true of the Go source; no captured fixture exercises it." It was not written.


2. The build

2.1 The frozen spec as the contract

The spec was frozen before the build started (01-SPEC.md:3), and it carries the node API (01-SPEC.md:6), the layout (01-SPEC.md:8), and the acceptance criteria (01-SPEC.md:9). The build was split into parallel lanes against it.

The frozen-spec discipline shows in the artefacts. The node module resolves engine entry points by name with a fallback, so both the spec's CamelCase names and the Pythonic snake_case names work:

"Engine entry points are resolved by name with a fallback, so both the spec's CamelCase names (`EvaluateFraming) and the Pythonic snake_case names the engine actually ships (evaluate_framing) work." — app/cinematographer/nodes.py:18-20`

That is a small piece of defensive engineering that exists because the spec and the implementation were written in parallel.

2.2 The engine — six modules, pure stdlib

Module Lines Role
app/cinematographer/geometry.py388Vectors, CamPose, Subject, ShotIntent, the projector, anchors, shot bands, weights
app/cinematographer/framing.py240The 9 per-shot rules, evaluate_framing(), summary()
app/cinematographer/scene.py250The 3 scene rules, PlacedEntity, SceneGraph, scene_framing_extras()
app/cinematographer/continuity.py155The 2 cross-cut rules, evaluate_continuity()
app/cinematographer/autoframe.py206The solver, mood_to_intent(), autoframe_summary()
app/cinematographer/reliability.py103The reliability zone
Total engine1,342

The engine's hard constraint is stated in three places:

"Everything here is pure stdlib and has no ComfyUI dependency — that is a hard requirement (spec §8), because it is what makes the rules testable and reusable." — app/cinematographer/geometry.py:6-7

"The engine imports with zero ComfyUI dependency — that is a deliberate design constraint, so the geometry is testable and reusable outside ComfyUI." — app/README.md:50-51

"The app/ tree has no Magieva imports and its tests run with zero Magieva dependency — that was a deliberate design constraint, and it pays off exactly here." — 03-SUBMISSION.md:72-73

Three constraints, one decision: the engine must be importable with nothing installed. That is what makes it testable without ComfyUI, publishable without Magieva, and reusable by the panel.

2.3 The six nodes

app/cinematographer/nodes.py (698 lines) is the only module permitted to touch ComfyUI, and even there the dependency is optional:

"This is the only module in the package permitted to touch ComfyUI, and even here the dependency is optional: the probe below is wrapped, so this module -- and every node class in it -- imports cleanly on a machine with no ComfyUI." — app/cinematographer/nodes.py:7-11

The probe:

# app/cinematographer/nodes.py:47-53
try:  # pragma: no cover - only true inside a ComfyUI install
    import comfy.utils as _comfy_utils  # noqa: F401
    COMFYUI_AVAILABLE = True
except Exception:  # noqa: BLE001 - a half-installed ComfyUI can raise anything
    _comfy_utils = None
    COMFYUI_AVAILABLE = False

Note the except Exception with an explicit justification. A half-installed ComfyUI can raise anything, so catching ImportError alone would be wrong.

The six nodes (nodes.py:682-689):

Node What it does README line
CinematographerEvaluateScores a camera + subject against the 9 per-shot rules. Returns a report, an overall pass, and a one-line summaryapp/README.md:59
CinematographerAutoFrameSolves a camera pose for a shot type and intent. Reports whether it actually convergedapp/README.md:60
ChorosContinuityChecks a shot list for 180°-axis breaks and sub-30° jump cutsapp/README.md:61
SceneFramingExtrasThe multi-entity rules: size = story importance, dirty-frame foreground, eyelineapp/README.md:62
CameraReliabilityZoneGrades a requested angle against the view-steering model's trained envelopeapp/README.md:63
CinematographerCorrectionTurns a report into a plain list of correction leversapp/README.md:64

All six are registered in NODE_CLASS_MAPPINGS (nodes.py:682-689) and NODE_DISPLAY_NAME_MAPPINGS (nodes.py:691-698), under the category Cinematographer.

The I/O contract is deliberately dumb: "All JSON in, all JSON out — the nodes compose with anything." (app/README.md:66)

2.4 The engine loader

The engine modules are imported lazily and defensively (nodes.py:60-92), with a subtlety worth recording:

# app/cinematographer/nodes.py:70-79
except ImportError as exc:
    # Only fall back when the *target file* is missing. An ImportError raised
    # from inside the engine module (a real bug, or a missing third-party
    # dependency) must propagate rather than be silently retried.
    if exc.name not in (name, package + "." + name):
        raise

That comment is the difference between a robust loader and a bug-hiding one. A naive except ImportError: retry would swallow a genuine ImportError from inside an engine module and report a misleading "module missing" error.

2.5 The two workflow graphs

The spec requires two graphs (01-SPEC.md:8). Both are ComfyUI API-format JSON — nodes keyed by id, each with class_type and inputs.

Graph Stack Nodes Links
app/workflows/reshoot_ltx_crossview.jsonLTX 2.3 + CrossView-Warp IC-LoRA + MoGe-2——
app/workflows/reshoot_wan22_fun_control.jsonWan 2.2 Fun-Control + CrossView-Warp + MoGe-2——

Both carry a _README node documenting provenance, deliberate deltas, required node packs, required weights, licence, and measured status. The LTX graph's _README is the model for the convention.

The provenance discipline is the most reusable thing in the package. The LTX graph's _README names the exact upstream file it was derived from, with the read date:

"Derived from the CrossView-Warp v2 example workflow shipped by the node pack's own author: cseti007/ComfyUI-CrossViewWarp example_workflows/ltx2.3-ic-lora-crossview-warp-v2.json (Apache-2.0; 119 UI-format nodes; read 2026-10-29)" — app/workflows/reshoot_ltx_crossview.json _README

And it enumerates seven deliberate deltas from that example, each with a reason. The list is worth reproducing in summary because it shows what "documented divergence" looks like:

# Delta Reason given
1Two-stage latent-upscale pass removed; single 1376×768 passFewer moving parts, one fewer weight, and the framing arithmetic is resolution-independent
2Comparison plumbing dropped (SetNode/GetNode/AddLabel/ImageConcatMulti/ReverseImageBatch)It exists to show a side-by-side in the author's demo, not to make a clip
3VHS_LoadVideo/VHS_VideoCombine → core LoadVideo/GetVideoComponents/CreateVideo/SaveVideoOne fewer custom node pack in the critical path
4Camera keyframed inside the green reliability zone (|azimuth| ≤ 40°, elevation 0…+15°) instead of the example's −24.4 → +50.4° swingThe +50.4° endpoint is outside the ±45° range the LoRA was checked on
5keep_source_aim ONThe node's own README says it scores better and it is what a re-shoot wants
6preview_size 384 → 512; frame_index 49 → 1—
7filename_prefix → cinematographer/*Namespace the output

Delta 4 is the interesting one: the graph was authored to stay inside the reliability envelope the entry's own CameraReliabilityZone node grades. The two halves of the entry are consistent with each other.

2.6 The structural validator

app/workflows/validate_graphs.py (236 lines) is the only check the graphs get, and it is explicit about its boundary:

"CHECKED — the file parses as JSON; `_README is a list of strings; every node has class_type and inputs; every class_type` is in the verified output-slot table below; every link resolves to an existing node id and an output slot that node actually declares; the graph is acyclic; every node is reachable from a SaveVideo.

NOT CHECKED — that ComfyUI accepts the prompt, that the node packs and weights are installed, that the graph runs, or that it produces a clip. None of the graphs have ever been executed. Do not read a pass here as 'the workflow works'." — app/workflows/validate_graphs.py:11-20

The load-bearing part is the output-slot table (validate_graphs.py:36-80), which maps 33 class_types to their output-slot counts, each annotated with the upstream source it was read from. The claim is explicit:

"The output-slot table is the load-bearing part. Each count was read from the node source named in the graph's own `_README PROVENANCE block, not guessed." — app/workflows/validate_graphs.py:22-24`

The adversarial review falsified that claim. One entry is wrong — see 05-adversarial-review.md §5.

2.7 The director's panel

app/web/ is a single-page panel with no build step, no framework, and no backend (app/web/README.md:8). It runs the same geometry in the browser.

File Lines Role
app/web/cinematographer.js843A line-by-line JS mirror of the Python engine
app/web/app.js729The panel UI
app/web/panel_state.js121State
app/web/parity_check.py377The three-way parity harness
app/web/tools/gen_fixtures.py466Fixture generator
app/web/parity_fixtures.json2,55428 frozen fixtures

The panel's central claim is that its numbers are real:

"A panel whose numbers disagree with the engine is worse than no panel, so the mirror is proven, not asserted." — app/web/README.md:29-30

The panel README also carries an explicit "What is real, and what is mocked" section (app/web/README.md:89-95), which the adversarial review singled out as exemplary (verification/ADVERSARIAL-REVIEW.md:40).

2.8 The porting notes — a small gem

The panel README documents four Python↔JS semantic mismatches that a naive port would get wrong (app/web/README.md:208-215):

Note The mismatch
pyRoundPython's round() is ties-to-even; JS Math.round is ties-away-from-zero
pyFixedPython's format(x, '.2f') renders negative zero as -0.00; JS toFixed drops the sign
pyGPython's '%g' formatting, used in the Dutch target string
Unicode targetsWritten as \u escapes so transport encoding cannot corrupt them; they are the Go source's strings verbatim (≥, –, ±, ≈, °)

The negative-zero note is the one that matters: "The frame preview's NDC readouts depend on this." (app/web/README.md:212) A port that missed it would show 0.00 where the engine shows -0.00, and the parity check would fail on a formatting difference that looks like a geometry difference.


3. The differential verification — 289 checks

3.1 How the Go side was produced

The original implementation lives in the Magieva monorepo at internal/contentstudio/cinematography*.go (verification/README.md:19-20). A temporary Go harness was compiled inside that module, ran the original Go functions over a fixed fixture set, and dumped the results as JSON (verification/README.md:21-23).

# verification/README.md:26-32
cp verification/go-harness/zz-cine-dump.go cmd/zz-cine-dump/main.go
GOWORK=off go run ./cmd/zz-cine-dump > /tmp/go-cine-dump.json
rm -rf cmd/zz-cine-dump
python verification/differential_check.py /tmp/go-cine-dump.json

The captured output is preserved at verification/go-reference-dump.json, so the comparison can be re-run without the Magieva checkout (verification/README.md:35-36).

3.2 What is compared

Surface Fixtures Compared
EvaluateFraming9rule list, order, pass, value, weight, target, correction, overall_pass (verification/README.md:48)
AutoFrameCamera18 (3 shot types × 6 intents)camera eye, target, fov, roll, and the full report (verification/README.md:49)
EvaluateContinuity2 sequencesrule, shot pair, pass (verification/README.md:50)
SceneFramingExtras2 scenesrule, pass, value (verification/README.md:51)

Tolerance is 1e-6 on every numeric field (verification/README.md:53; differential_check.py:39).

3.3 The decomposition of 289 — never stated by the entry

The counter is incremented at five places in differential_check.py. Decomposing it:

Source Count Line
Framing rule-level field comparisons (9 fixtures × 9 rules)81:66
Autoframe rule-level field comparisons (18 fixtures × 9 rules)162:66 (via :173)
Autoframe camera-pose checks (eye, target, fov, roll)18:163
Autoframe early-exit / convergence checks18:177
Continuity issue checks (4 + 2)6:204
Scene-extras checks (2 + 2)4:234
Total289

The units are not homogeneous. 243 of the 289 are per-rule field comparisons; 46 are whole-object or invariant checks. The entry's phrase "289 differential checks" reads as 289 independent comparisons, and it is not.

This is the adversarial review's attempt #2, and it succeeded:

| 2 | Decompose the 289 counter | SUCCEEDED — heterogeneous units, not field comparisons; 2 slots near-vacuous | — verification/ADVERSARIAL-REVIEW.md:635

3.4 The deliberate skips

Two fields are skipped on purpose, and the code says so.

size_importance's value — because the port uses role-derived half-extents rather than Magieva's dimension resolver:

# verification/differential_check.py:241-244
# size_importance is expected to differ: the port uses role-derived
# half-extents, not Magieva's full dimension resolver. See scene.py.
if r == "size_importance":
    continue

The verification README discloses this (verification/README.md:56-62).

Two more fields are skipped silently — the scene correction and the continuity detail. The review found that these do diverge:

| H2 | "reproduces the original Go cinematography implementation value-for-value" | verification/README.md:12-13 | False for the skipped fields, which do diverge: scene correction (em dash vs hyphen), continuity detail (°/≥/— vs deg/>=/-). | — verification/ADVERSARIAL-REVIEW.md:573

The divergences are cosmetic (em dash vs hyphen, ° vs deg), but the word "value-for-value" is false as written. See 05-adversarial-review.md §4.

3.5 The result, re-run

$ cd higgsfield-comfyui-os
$ PYTHONDONTWRITEBYTECODE=1 python3 verification/differential_check.py verification/go-reference-dump.json
differential checks run: 289
ALL FIXTURES AGREE with the original Go implementation.
exit=0

Reproduced during the writing of this file. The number is exact.

3.6 The hole in the chain

The review is blunt about the largest weakness, and it is inherent to the setup:

"No Magieva Go checkout. I could not re-run go-harness/zz-cine-dump.go. I verified the Python side against the frozen go-reference-dump.json only. The dump's own provenance is unverifiable from here — if it were fabricated or stale, none of my claim-A work would detect it. This is the single largest hole in the verification chain, and it is inherent to the setup." — verification/ADVERSARIAL-REVIEW.md:673-676

The 289-check claim reduces to: the Python port agrees with a JSON file. Whether that JSON file was produced by the Go code it claims to have been produced by is not checkable from inside this package. The harness source is preserved (verification/go-harness/zz-cine-dump.go), so the provenance is auditable — but it was not audited.

This is the honest framing of the entry's strongest claim, and it is developed in 06-unverified-and-method.md §3.


4. The panel parity check — 28 fixtures

4.1 The three-way structure

The panel README states the design:

"It compares three ways: (1) the JS mirror against the frozen fixtures, (2) the Python engine against the same fixtures, (3) the Python engine against the JS mirror, live, field by field." — app/web/README.md:66-70

Leg [3] is what makes the check non-circular. The review tested that explicitly:

| 16 | Test whether parity is circular | FAILED to falsify — leg [3] is a live two-engine comparison | — verification/ADVERSARIAL-REVIEW.md:649

And the verdict:

"D — Panel parity — CONFIRMED — and not circular. Three-way check with a live Python↔JS leg; JS mutations are caught. Same boundary-blindness as A." — verification/ADVERSARIAL-REVIEW.md:36

4.2 The staleness guard

The fixture file records a sha256 over the six engine modules, and the checker recomputes it:

"It exits non-zero on any mismatch, on a structural problem (fewer than five framing fixtures, or a fixture without all nine rules), and on stale fixtures — the fixture file records a sha256 over the six engine modules, and the checker recomputes it, so an engine edit cannot silently invalidate the proof." — app/web/README.md:72-75

That is the right guard. Without it, an engine edit would leave the fixtures proving something about a version of the engine that no longer exists.

4.3 The result, re-run

$ PYTHONDONTWRITEBYTECODE=1 python3 app/web/parity_check.py
Cinematographer parity check
  fixtures      : app/web/parity_fixtures.json
  generated     : 2026-10-30T00:06:38+00:00 (engine rev unknown)
  engine hash   : 24621deb23c66c8f…  (matches live engine)
  JS engine     : app/web/cinematographer.js (node v24.18.0)
  Python engine : app/cinematographer/ (importable)

[1/3] JS vs frozen fixtures
  framing      12/12 OK
  continuity   4/4 OK
  reliability  7/7 OK
  autoframe    5/5 OK

[2/3] Python engine vs frozen fixtures
  framing      12/12 OK
  continuity   4/4 OK
  reliability  7/7 OK
  autoframe    5/5 OK

[3/3] Python engine vs JS (live)
  framing      12/12 OK
  continuity   4/4 OK
  reliability  7/7 OK
  autoframe    5/5 OK

RESULT: PASS — 28 fixtures, 0 mismatches
exit=0

Reproduced during the writing of this file.

4.4 The chain back to Go

Two of the 28 fixtures reproduce poses from the original Go test:

"Two of them (go-test-centered-closeup, go-test-offset-closeup) reproduce the poses in the original Go test cinematography_test.go, so the chain traces back past the Python port to the Go source." — app/web/README.md:83-85

So the verification chain is: Go test → fixture → Python engine → JS mirror → panel. Four links, three of them mechanically checked.

4.5 The same boundary blindness

The review found that the parity check shares the differential check's weakness:

"Same boundary-blindness as A." — verification/ADVERSARIAL-REVIEW.md:36

| 15 | 10 JS mutations vs the parity check | PARTIALLY SUCCEEDED — 6 caught, 4 missed (same boundary blindness) | — verification/ADVERSARIAL-REVIEW.md:648

Both headline numbers measure value fidelity and neither measures threshold fidelity. That is the systemic finding, developed in 05-adversarial-review.md §6.


5. The unit suite — 69 tests

5.1 The distribution

File Tests
app/tests/test_autoframe.py22
app/tests/test_geometry.py18
app/tests/test_framing.py15
app/tests/test_continuity.py14
Total69

5.2 The result, re-run

$ cd app && PYTHONDONTWRITEBYTECODE=1 /tmp/cine-venv/bin/python -m pytest tests/ -q -p no:cacheprovider
.....................................................................    [100%]
69 passed in 0.19s

Reproduced during the writing of this file.

5.3 The hand-computation claim

The verification README claims the expected values are derived from first principles rather than recorded:

"The tests derive their expectations from first principles rather than from a recorded run. For the reference camera (35 mm focal, 36 mm sensor, 16:9):

vfov = 2*atan((36/(16/9)) / (2*35))
f    = (2*focal)/(sensor/aspect) = 70/20.25 = 3.45679012345679

so ndcY(top) = 0.048 * f = 0.1659259 and headroom = 0.8340750. The suite asserts those numbers, not a snapshot." — verification/README.md:104-113

The review re-derived three of them and confirmed the arithmetic:

| 13 | Re-derive 3 test expected values from first principles | FAILED to falsify — arithmetic is correct | — verification/ADVERSARIAL-REVIEW.md:646

But it found one constant wrong:

| 7 | MINOR | Hand-computed constant F = 3.4567701 is wrong (correct 3.4567901); contradicts verification/README.md:109. | app/tests/test_framing.py:13 | — verification/ADVERSARIAL-REVIEW.md:616

And it found the coverage claim misleading:

| H5 | "69 unit tests, every expected value hand-computed" | verification/README.md:98 | True of the values asserted; misleading about coverage. 11/24 injected defects survive, and test_framing.py:13's F constant is itself miscomputed. | — verification/ADVERSARIAL-REVIEW.md:576

The headroom = 0.8340750 figure is the one the demo script puts on screen as 0.834 (02-DEMO-SCRIPT.md:59). So the demo's headline number is traceable to a hand computation, and the hand computation is right — but a different hand-computed constant in the same suite is wrong in the fifth decimal.


6. The publishability constraint

The submission checklist records that the publication decision was still open when it was written (03-SUBMISSION.md:49-51), and that the constraint is that the Magieva monorepo cannot be published (03-SUBMISSION.md:54-55).

The recommended split (03-SUBMISSION.md:70-73):

Item Origin Publishable?
app/cinematographer/*.pynew port, written for this entry✅ yes
app/web/*new✅ yes
app/tests/*new✅ yes
app/workflows/*.jsongraph structure modelled on Magieva's internal graphs⚠️ review
verification/go-harness/zz-cine-dump.gonew harness; calls Magieva internal packages⚠️ review
verification/go-reference-dump.jsonoutput of Magieva internal code⛔ likely not
00-BREAKDOWN.md, 01-SPEC.md, analysis/*internal competitive analysis⛔ no

The recommended publish set is app/ only, as a standalone Apache-2.0 repo (03-SUBMISSION.md:70-71).

6.1 The pre-publication grep

The checklist specifies a mechanical check:

# 03-SUBMISSION.md:77-80
cd app
grep -rn "magieva\|Magieva" . --include=*.py --include=*.js --include=*.json --include=*.md

And it flags the expected hits in advance:

"Any hit needs a decision. (The README and scene.py currently reference Magieva's dimension resolver as the source of a documented simplification — that is a factual attribution, not a code dependency, but confirm you are comfortable with it.)" — 03-SUBMISSION.md:82-84

The two expected hits are app/README.md:130-131 and app/cinematographer/scene.py:15-20. Both are attributions, not dependencies. The distinction is the right one, and the checklist states it before the grep is run rather than after.

6.2 The publishability constraint is why the engine has no imports

This is the payoff of the design decision in §2.2. Because the engine is pure stdlib and has no Magieva imports, the publish set is a directory move rather than a refactor. The constraint was adopted at design time (03-SUBMISSION.md:72-73) and it paid off at publication time.


7. What the build did not do

Not done Consequence
Run ComfyUIThe nodes have never been loaded by ComfyUI. The install path was broken (see 05 §3).
Execute either workflow graphBoth _READMEs say NOT VERIFIED
Produce a renderNo LTX or Wan output exists
Measure VRAM or timing"MEASURED: nothing. No timing, no VRAM figure, no output."
Run --disable-partner-nodesThe open-weights-only property is argued from JSON, not proven by a flag
Re-run the Go harnessThe 289-check claim rests on a frozen JSON file
Add boundary fixturesThe 12-constant hole is open
Differentially verify eyelineNo fixture has two characters
Read any third-party licenceThe licence argument is quoted from the recon
Record the demo video"⛔ not recorded" (03-SUBMISSION.md:39)
Post the social post"⛔ not posted" (03-SUBMISSION.md:40)
Publish the repo"⛔ blocked" (03-SUBMISSION.md:38)
Obtain a comfy.org login"We do not have a comfy.org login." (03-SUBMISSION.md:10)

The last four are submission blockers, not build defects, and they are stated as blockers in the checklist itself (03-SUBMISSION.md:8-30).


8. Decision register — the build phase

# Decision Evidence
B1Freeze the spec before building01-SPEC.md:3
B2Keep the engine pure stdlib with no ComfyUI importgeometry.py:6-7; app/README.md:50-51
B3Keep app/ free of Magieva imports03-SUBMISSION.md:72-73
B4Make the ComfyUI import optional and wrappednodes.py:47-53
B5Resolve engine entry points by name with a fallbacknodes.py:18-20
B6Propagate real ImportErrors rather than retryingnodes.py:70-79
B7Add early_exit=False as a verification escape hatchautoframe.py:107-109
B8Set converged from the report, not a separate computationautoframe.py:190
B9Filter the residual to gating rulesautoframe.py:184-186
B10Author the LTX graph inside the reliability envelopeLTX graph _README, delta 4
B11Document every deliberate delta from upstreamLTX graph _README
B12Mark both graphs NOT VERIFIED in their own _READMEBoth graphs' _README
B13Build a three-way parity check with a live legapp/web/README.md:66-70
B14Hash the engine into the fixture fileapp/web/README.md:72-75
B15Document the Python↔JS semantic mismatchesapp/web/README.md:208-215
B16Disclose the size_importance simplification in code and in the checkscene.py:15-20; differential_check.py:241-244

9. Evidence index for this file

Claim Primary source
The Go solver's 24 unconditional iterationsautoframe.py:6-9; app/README.md:90-91
The prior "solves a compliant pose" claimclient-reports/higgsfield-cinema-studio-4.0/analysis/00-SYNTHESIS.md:179-180
The four changesautoframe.py:164-166, :184-186, :190-191
The early_exit=False escape hatchautoframe.py:107-109; differential_check.py:141-142, :158-160
The early-exit assertiondifferential_check.py:175-181
The four convergence testsapp/tests/test_autoframe.py:31-39, :48-53, :64-83, :125
The 1800-call sweepverification/ADVERSARIAL-REVIEW.md:35, :641-642
The 3-iteration convergenceverification/README.md:88-89
converged=True with a failing 0.7-weight ruleverification/ADVERSARIAL-REVIEW.md:626, :643
in_frame checks the faceframing.py:102-103
The Go failure mode is undemonstratedverification/ADVERSARIAL-REVIEW.md:581, :625, :644
The engine module sizeswc -l over app/cinematographer/*.py
The pure-stdlib constraintgeometry.py:6-7; app/README.md:50-51; 03-SUBMISSION.md:72-73
The optional ComfyUI probenodes.py:47-53
The six nodesnodes.py:682-698; app/README.md:57-66
The engine loader's ImportError disciplinenodes.py:70-79
The LTX graph's provenanceLTX graph _README
The seven deliberate deltasLTX graph _README
The validator's boundaryvalidate_graphs.py:11-20
The output-slot tablevalidate_graphs.py:36-80
The panel's file sizeswc -l over app/web/*
The three-way parity structureapp/web/README.md:66-70
The staleness guardapp/web/README.md:72-75
The porting notesapp/web/README.md:208-215
The 289 decompositionDerived from differential_check.py:66, :163, :177, :204, :234
The deliberate skipdifferential_check.py:241-244
The silent skipsverification/ADVERSARIAL-REVIEW.md:573
The dump's provenance holeverification/ADVERSARIAL-REVIEW.md:673-676
The 69 testsapp/tests/*.py; re-run output in §5.2
The hand-computation claimverification/README.md:104-113
The wrong F constantverification/ADVERSARIAL-REVIEW.md:616
The publishability split03-SUBMISSION.md:49-84
The submission blockers03-SUBMISSION.md:8-30, :38-40