The analysis
05 — The adversarial review: what was attacked, what survived, what broke
Scope: the third and last honesty problem — the one that was not caught during planning. This file documents the adversarial lane: its stance, its verdicts, the defects it found, the systemic finding that both headline verification numbers are blind to the same class of defect, and the remediation state at the time of writing.
Source root: as 01-premise-and-reaim.md §0. The review is verification/ADVERSARIAL-REVIEW.md (740 lines), written by the adversary lane on 2026-10-29.
Method: reading the review in full, plus independent re-runs of the three harnesses during the writing of this file. The remediation status in §10 was observed directly from the source tree at 2026-10-29 17:38 PT (2026-10-30T00:38Z) and is timestamped because the tree was being edited concurrently.
1. The review's stance
The review states its own rules of engagement:
"Stance: falsify, not confirm. A review that finds nothing is a failed review." —
verification/ADVERSARIAL-REVIEW.md:4
"Write scope: this file only. Nothing under
app/or any top-level.mdwas modified. All mutation testing was done on a throwaway copy at/tmp/adv-cine; the working tree was verified unchanged afterwards." —verification/ADVERSARIAL-REVIEW.md:5-7
That second line matters for the integrity of the exercise: the reviewer did not fix what it found, and it did not mutate the artefact it was reviewing. Every defect it reports is reproducible against the tree as it stood.
The review ran 24 falsification attempts (verification/ADVERSARIAL-REVIEW.md:630-657), of which 13 succeeded in falsifying or materially qualifying a claim.
2. The verdicts
The review's verdict table (verification/ADVERSARIAL-REVIEW.md:31-40), reproduced in full:
| # | Claim | Verdict | One line |
|---|---|---|---|
| A | 289-check differential result | PARTIALLY CONFIRMED | The number reproduces exactly and the check is real, but it is blind to threshold regressions and silently skips fields that do diverge. "Value-for-value" is false. |
| B | 69 unit tests, hand-computed expected values | PARTIALLY CONFIRMED | 69 pass; the values are genuinely first-principles (I re-derived them). But 11/24 injected defects survive, and one hand-computed constant is itself wrong. |
| C | Solver convergence honesty | CONFIRMED | 1800 solver calls: converged never disagrees with report.overall_pass. No counterexample found. |
| 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. |
| E | Workflow graphs | PARTIALLY CONFIRMED | The validator is a real check (6/6 injected structural defects caught) and 32/33 slot counts are right. One is wrong, which falsifies a provenance claim. |
| F | Licence-clean / no trademark | CONFIRMED | No Higgsfield in filenames or app strings; no MiniMax H3, no closed API, no partner nodes, no network calls in the engine. |
| G | README setup works from a clean clone | REFUTED | The ComfyUI install path is broken. The pytest path works. |
| H | Honesty about measured vs. guessed | PARTIALLY CONFIRMED | The workflow _READMEs and app/web/README.md are exemplary. Four claims stated as fact are not backed by a runnable check, and one is contradicted by one. |
Two CONFIRMED, four PARTIALLY CONFIRMED, one REFUTED. The distribution is the honest shape of the result: the entry's engineering held up; its documentation did not.
2.1 The bottom line
"Not safe to submit as-is. One CRITICAL defect breaks the entry's headline deliverable: installed exactly as
app/README.mddocuments, the ComfyUI nodes do not load at all. A judge who follows the README gets an empty category, not six nodes." —verification/ADVERSARIAL-REVIEW.md:13-15
"Do not submit as-is. Fix defect #1 first — without it the entry's primary artefact does not install, and that is the failure a judge is most likely to hit first and remember." —
verification/ADVERSARIAL-REVIEW.md:719-720
3. The CRITICAL defect: the install path is broken
3.1 The claim
app/README.md:33-41 documents the install as:
cd ComfyUI/custom_nodes
git clone <this-repo> ComfyUI-Cinematographer
# no dependencies — the engine is pure stdlib
"Restart ComfyUI. The nodes appear under the Cinematographer category." —
app/README.md:41
3.2 What actually happens
The review simulated the documented clone exactly:
$ ls -a /tmp/fakecomfy/custom_nodes/ComfyUI-Cinematographer
. .. 00-BREAKDOWN.md 01-SPEC.md 02-DEMO-SCRIPT.md 03-SUBMISSION.md
analysis app raw-articles verification
$ test -f .../ComfyUI-Cinematographer/__init__.py && echo YES || echo NO
NO
— verification/ADVERSARIAL-REVIEW.md:489-494
The pack root has no __init__.py. ComfyUI's loader requires one.
3.3 The loader evidence
The review read ComfyUI's own loader rather than assuming:
# ComfyUI nodes.py:2261-2276, quoted at verification/ADVERSARIAL-REVIEW.md:499-508
elif os.path.isdir(module_path):
sys_module_name = module_path.replace(".", "_x_")
...
module_spec = spec_from_file_location(sys_module_name, os.path.join(module_path, "__init__.py"))
module_dir = module_path
module = importlib.util.module_from_spec(module_spec)
module_spec.loader.exec_module(module)
Two facts from that source, both load-bearing:
- The directory branch resolves
<pack_root>/__init__.pyviaspec_from_file_location(:504). init_external_custom_nodesiteratesos.listdir(custom_node_path)— top level only, no recursion (verification/ADVERSARIAL-REVIEW.md:512-513).
The second fact is why app/cinematographer/__init__.py does not save it. ComfyUI never looks two levels down.
Reproducing the loader's directory branch:
entry file: .../ComfyUI-Cinematographer/__init__.py exists: False
LOAD FAILED: FileNotFoundError [Errno 2] No such file or directory:
'.../ComfyUI-Cinematographer/__init__.py'
— verification/ADVERSARIAL-REVIEW.md:516-519
3.4 The secondary and tertiary defects
Secondary: app/README.md:47 documents python -m pytest tests/ -q but never says to install pytest. requirements.txt lists it only as a commented-out optional, and pyproject.toml puts it behind [project.optional-dependencies] dev. On a clean machine:
$ python3 -m pytest tests/ -q
No module named pytest
EXIT=1
— verification/ADVERSARIAL-REVIEW.md:536-538
Tertiary: acceptance criterion 1 (python -c "import cinematographer") works from app/ but not from the repo root, which is where the README's install section leaves the reader (verification/ADVERSARIAL-REVIEW.md:541-542).
Quaternary: there is no pyproject.toml at the pack root, so ComfyUI's config_parser.extract_node_configuration finds nothing — the [tool.comfy] block is at app/pyproject.toml (verification/ADVERSARIAL-REVIEW.md:523-524).
3.5 Why this defect is the most damaging one
"Impact: acceptance criterion 8 ('README setup works from a clean clone') fails, and the entry's primary artefact — a ComfyUI custom node pack — is not installable by the documented route. The panel and the tests work, so a judge who only runs those will not notice." —
verification/ADVERSARIAL-REVIEW.md:526-528
That last sentence is the crux. The entry's three verification harnesses all pass, and all three pass without ever loading the pack into ComfyUI. The verification story is strong precisely in the places that cannot see this defect.
This is the single most important structural lesson in the whole build: the entry verified everything it could verify without ComfyUI, and the one thing it could not verify is the one thing that was broken.
4. What the review falsified
4.1 Attempt 1 — can the differential check fail at all? (FAILED to falsify)
| 1 | Reproduce the 289-check baseline | FAILED to falsify — 289, exit 0, exactly as claimed | —
verification/ADVERSARIAL-REVIEW.md:634
The check is real. It was re-run during the writing of this file and reproduced exactly:
$ PYTHONDONTWRITEBYTECODE=1 python3 verification/differential_check.py verification/go-reference-dump.json
differential checks run: 289
ALL FIXTURES AGREE with the original Go implementation.
4.2 Attempt 2 — what does it miss? (SUCCEEDED)
11 of 30 injected defects were missed, and they are all the same kind:
"11 of 30 injected defects were MISSED, and they are all the same kind: a threshold or a boundary constant moved slightly, where no fixture sits near the boundary." —
verification/ADVERSARIAL-REVIEW.md:134-135
The full table (verification/ADVERSARIAL-REVIEW.md:137-153):
| Injected defect | Differential | pytest | Verdict |
|---|---|---|---|
medium shot_size lower bound 0.4 → 0.41 | MISSED | MISSED | unconstrained |
closeup shot_size 0.7 → 0.71 | MISSED | MISSED | unconstrained |
wide shot_size lower bound 0.15 → 0.16 | MISSED | MISSED | unconstrained |
rule_of_thirds tolerance 0.12 → 0.13 | MISSED | MISSED | unconstrained |
lead_room pass -0.05 → -0.04 | MISSED | MISSED | unconstrained |
level tolerance < 1 → < 2 deg | MISSED | MISSED | unconstrained |
MIN_DISTANCE 0.3 → 0.31 | MISSED | MISSED | unconstrained |
in_frame |ndcX| <= 1 → <= 2 | MISSED | MISSED | unconstrained |
rule_of_thirds third line 1/3 → 1/4 | MISSED | MISSED | unconstrained |
rule_of_thirds centre tolerance 0.12 → 0.5 | MISSED | MISSED | unconstrained |
continuity axis_side sign flip | MISSED | MISSED | unconstrained |
continuity ang_delta > 180 → > 179 | MISSED | MISSED | unconstrained |
OVERALL_PASS_WEIGHT 0.8 → 0.9 | MISSED | caught | pytest-only |
in_frame drops e_in | MISSED | caught | pytest-only |
level always True | MISSED | caught | pytest-only |
Root cause, measured:
"The fixture set has near-zero boundary diversity. For the 9 framing fixtures,
in_framehas exactly one distinct value (True) andlevelhas exactly one distinct value (0/True). No fixture exercises a boundary, so moving a boundary is invisible. The check is strong on arithmetic and blind to thresholds." —verification/ADVERSARIAL-REVIEW.md:155-158
And why it matters:
"This matters because thresholds are where the cinematography actually lives.
0.4 <= frac <= 0.75is the entire medium-shot rule;0.12is the entire rule-of-thirds tolerance. Both can be wrong and the entry's strongest claim still prints289 / ALL FIXTURES AGREE." —verification/ADVERSARIAL-REVIEW.md:160-162
4.3 Attempt 3 — does it compare everything it says it compares? (SUCCEEDED)
No. Three surfaces are compared only partially, and the skipped fields really do differ (verification/ADVERSARIAL-REVIEW.md:164-201).
SceneFramingExtras — differential_check.py:233-246 compares rule, pass, and (except for size_importance) value. It never compares target, weight, or correction:
Go extras_big[0].correction = "a prop out-sizes the key subject — resize/reposition so the subject dominates"
Python extras_big[0].correction = "a prop out-sizes the key subject - resize/reposition so the subject dominates"
— verification/ADVERSARIAL-REVIEW.md:173-174
Em dash vs hyphen. The framing rules get this right (geometry.py:368-371 uses \u2014); the scene rules were rewritten to ASCII and nothing notices (verification/ADVERSARIAL-REVIEW.md:177-179).
EvaluateContinuity — differential_check.py:203-210 compares rule, pass, shot_a, shot_b. It never compares detail:
Go 30_degree: "camera angle changed 3° (need ≥30° to avoid a jump cut)"
Python 30_degree: "camera angle changed 3 deg (need >=30 deg to avoid a jump cut)"
Go 180_axis: "axis crossed — the subject's screen direction flips between the cuts"
Python 180_axis: "axis crossed - the subject's screen direction flips between the cuts"
— verification/ADVERSARIAL-REVIEW.md:185-189
Three of the four continuity_go_test details differ (app/cinematographer/continuity.py:121, :140-141).
size_importance — the slot is counted in the 289, then the value is skipped (differential_check.py:243-244). So 2 of the 289 headline checks compare pass and nothing else (verification/ADVERSARIAL-REVIEW.md:194-196).
The consequence:
"
verification/README.md:12-13claims the port 'reproduces the original Go cinematography implementation value-for-value'. For the numeric values, that is true and well-evidenced. For the report's user-facing strings — which are what the panel and the ComfyUI nodes actually display — it is false for 2 of the 14 rules and for both continuity rules." —verification/ADVERSARIAL-REVIEW.md:198-201
4.4 Attempt 4 — is eyeline verified at all? (SUCCEEDED — it is not)
"
eyeline(rule 12 of 14) is emitted only whenlen(scene.characters) >= 2(app/cinematographer/scene.py:231). Both differential extras fixtures have exactly one character, soeyelineis never produced on the Go side and never compared" —verification/ADVERSARIAL-REVIEW.md:205-207
The dump confirms it:
extras_big -> [('size_importance', False, 10.125), ('foreground_occlusion', True, 0)]
extras_ok -> [('size_importance', True, 0), ('foreground_occlusion', True, 0)]
— verification/ADVERSARIAL-REVIEW.md:210-211
One of the fourteen rules is not differentially verified at all, and the entry lists it among the fourteen without disclosing that. The README counts it (app/README.md:78), the spec counts it (01-SPEC.md:81), and the UNVERIFIED table does not mention it (verification/README.md:117-126).
4.5 Attempt 5 — the combined mutation matrix (SUCCEEDED)
| 5 | Combined mutation matrix (both checks) | SUCCEEDED — 12 constants unconstrained by either | —
verification/ADVERSARIAL-REVIEW.md:638
This is the systemic finding, developed in §6.
4.6 Attempt 8 — the 1800-call solver sweep (FAILED to falsify)
| 8 | 1800-call solver invariant sweep | FAILED to falsify — zero anomalies | —
verification/ADVERSARIAL-REVIEW.md:641
The convergence claim survived the strongest attack in the review. See 04-convergence-and-build.md §1.5.
4.7 Attempt 17 — structural mutations against the validator (FAILED to falsify)
| 17 | 6 structural mutations vs the workflow validator | FAILED to falsify — all 6 caught | —
verification/ADVERSARIAL-REVIEW.md:650
| Injected defect | Result |
|---|---|
| link to an out-of-range output slot | CAUGHT |
| link to a non-existent node id | CAUGHT |
unknown class_type | CAUGHT |
| cycle (two nodes referencing each other) | CAUGHT |
| orphan node not reachable from SaveVideo | CAUGHT |
no SaveVideo at all | CAUGHT |
— verification/ADVERSARIAL-REVIEW.md:390-397
The validator is a real check.
4.8 Attempt 21 — the trademark grep (FAILED to falsify)
| 21 | Grep the whole tree for Higgsfield / MiniMax H3 / closed APIs | FAILED to falsify — clean | —
verification/ADVERSARIAL-REVIEW.md:654
4.9 Attempt 20 — simulating the install (SUCCEEDED)
| 20 | Simulate ComfyUI's
load_custom_nodeagainst a clean clone | SUCCEEDED —FileNotFoundError; the install path is broken | —verification/ADVERSARIAL-REVIEW.md:653
4.10 The discarded findings
The review records its own false positives, which is a mark of a careful reviewer:
"Note on discarded findings. My first workflow-input audit reported ~15 'UNDECLARED inputs' (
clip,text,device,codec,audio_vae, and theCrossViewWarpoptional block). These were artifacts of a crude regex extractor that ignored"optional"blocks and old-styleINPUT_TYPES. I re-verified each against the real sources: every one is declared. No input-name defect exists. They are recorded here only so a later reader does not rediscover the false positives and report them." —verification/ADVERSARIAL-REVIEW.md:659-664
That paragraph is worth as much as the defect register. It prevents a future reviewer from re-reporting a non-defect, and it documents the reviewer's own error rate.
5. The workflow graph findings
5.1 The validator passes
$ PYTHONDONTWRITEBYTECODE=1 python3 app/workflows/validate_graphs.py
PASS reshoot_ltx_crossview.json (35 nodes, 49 links)
PASS reshoot_wan22_fun_control.json (25 nodes, 33 links)
All structural checks passed. This does NOT mean the graphs run: they have never been executed.
EXIT=0
— verification/ADVERSARIAL-REVIEW.md:381-385; re-run during the writing of this file with the same result.
5.2 The slot-count audit
The review did not trust the table. It downloaded the real upstream sources and parsed every class_type with ast, handling both RETURN_TYPES = (...) and the new io.Schema(outputs=[...]) form (verification/ADVERSARIAL-REVIEW.md:401-402).
Result: 32 of 33 slot counts match upstream exactly. All 33 class types exist. (verification/ADVERSARIAL-REVIEW.md:404)
5.3 The one that does not — and the provenance claim it falsifies
app/workflows/validate_graphs.py:72: "SamplerCustomAdvanced": 1,
comfy_extras/nodes_custom_sampler.py:1033-1035:
outputs=[
io.Latent.Output(display_name="output"),
io.Latent.Output(display_name="denoised_output"),
],
— verification/ADVERSARIAL-REVIEW.md:411-418
The table said 1; upstream declares 2.
The count is not the important part. The claim is. The validator's docstring says:
"The output-slot table is the load-bearing part. Each count was read from the node source named in the graph's own `
_READMEPROVENANCE block, **not guessed**." —app/workflows/validate_graphs.py:22-24`
Both graphs' _READMEs repeat the claim. One entry is a guess. The review's verdict:
| H4 | "every class_type is in a table of output-slot counts read from the node sources" / "not guessed" |
validate_graphs.py:23-25, both graphs'_README| False forSamplerCustomAdvanced(table 1, upstream 2). | —verification/ADVERSARIAL-REVIEW.md:575
And it made the reviewer's top-three list:
"2.
validate_graphs.py:72— a 'read from the node sources, not guessed' table with one guess in it." —verification/ADVERSARIAL-REVIEW.md:738
This is the most interesting defect in the register, because of what it is a defect in. The entry's differentiator is honesty about measured vs. guessed. The one place it guessed, it claimed not to have guessed — and the claim was in a docstring whose entire purpose was to assert the opposite.
5.4 The graphs are honestly marked
"### The graphs are honestly marked" —
verification/ADVERSARIAL-REVIEW.md:431
The review's verdict on the _README discipline is positive, and it is the one place the review calls the entry's work exemplary:
"The workflow
_READMEs andapp/web/README.mdare exemplary." —verification/ADVERSARIAL-REVIEW.md:40
6. The systemic finding: 12 unconstrained constants
6.1 The finding
"The residual risk is concentrated in one place: the entry's two headline numbers both measure value fidelity and neither measures threshold fidelity. Twelve constants — including the entire medium-shot size band and the entire rule-of-thirds tolerance — can be wrong while
289 / ALL FIXTURES AGREEand69 passedboth print green." —verification/ADVERSARIAL-REVIEW.md:727-730
The defect register entry:
| 5 | MAJOR | 12 engine constants are unconstrained by the differential check, the unit suite, and the parity check. Both headline verification numbers miss the same class of defect. |
geometry.py:368-371,framing.py:104,116,125,164,192,autoframe.py:48,continuity.pyaxis sign +180clamp | —verification/ADVERSARIAL-REVIEW.md:614
6.2 Why "both headline numbers" is the finding
The entry has three independent verification harnesses:
| Harness | What it proves | Fixtures |
|---|---|---|
| Differential check | Python port ≡ Go original | 29 fixtures / 289 checks |
| Unit suite | The engine is self-consistent | 69 tests |
| Panel parity | JS mirror ≡ Python engine | 28 fixtures |
All three are blind to the same class of defect. They all compare values at points, and none of them places a point on a boundary.
The review states the mechanism:
"The fixture set has near-zero boundary diversity. For the 9 framing fixtures,
in_framehas exactly one distinct value (True) andlevelhas exactly one distinct value (0/True). No fixture exercises a boundary, so moving a boundary is invisible." —verification/ADVERSARIAL-REVIEW.md:155-158
6.3 Why it looks worse than it is
"A judge who mutates one constant will find that, and it will look worse than it is, because the entry has spent so much credibility claiming otherwise. Adding boundary fixtures is a two-hour fix that removes the whole class." —
verification/ADVERSARIAL-REVIEW.md:730-732
That is the sharpest sentence in the review. The entry's credibility investment in its verification story raises the cost of the gap, because the gap is in the same dimension the entry claims strength in.
6.4 The fix, and its cost
"Add boundary fixtures. One fixture per threshold, sitting exactly on the boundary. This closes the 12-constant hole in both the differential check and the parity check, and it is the highest-value verification work available." —
verification/ADVERSARIAL-REVIEW.md:706-708
Two hours of work, not done. The 12 constants are still unconstrained as of the time of writing.
7. The honesty findings
The review's harshest section, because honesty is the entry's differentiator:
"This is the entry's differentiator, so it gets the harshest treatment. Verdict: PARTIALLY CONFIRMED." —
verification/ADVERSARIAL-REVIEW.md:548-549
7.1 What is genuinely excellent
"This is well above the norm. The defects below are therefore more damaging, not less — they are inconsistencies in a document set that otherwise earns its credibility." —
verification/ADVERSARIAL-REVIEW.md:565-566
The review names the good parts explicitly (verification/ADVERSARIAL-REVIEW.md:551-563):
- The workflow
_READMEs app/web/README.md's "what is real, and what is mocked" section03-SUBMISSION.md:133-145— the explicit honesty ledger, including"38 cinematography rules" ⛔ falseand"Beats Higgsfield's Cinema Studio" ⛔ unfalsifiableframing.py:102-103— documenting thatin_framechecks the face, not the feet
7.2 The ten claims that a runnable check contradicts or does not back
| # | Claim | Where | Reality |
|---|---|---|---|
| H1 | "The check command is python verification/panel_parity_check.py" | verification/README.md:122 | The file does not exist. The real command is python app/web/parity_check.py. This is in the file whose stated rule is "a claim lives here only if a command in this file reproduces it." |
| H2 | "reproduces the original Go cinematography implementation value-for-value" | verification/README.md:12-13 | False for the skipped fields, which do diverge |
| H3 | "289 differential checks, zero disagreements" | verification/README.md:15 | The number is exact, but 2 of the 289 slots compare pass only, and 12 constants are unconstrained |
| H4 | "read from the node sources" / "not guessed" | validate_graphs.py:23-25 | False for SamplerCustomAdvanced |
| 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 |
| H6 | Panel parity listed as UNVERIFIED | verification/README.md:122 | Contradicted by app/web/README.md:136 and by the reviewer's own run. The verification README is stale |
| H7 | eyeline (rule 12) counted among the 14 verified rules | app/README.md:78, 01-SPEC.md:81 | Never differentially verified and not listed in the UNVERIFIED table |
| H8 | Demo: "a second run showing NOT CONVERGED · still failing: shot_size" | 02-DEMO-SCRIPT.md:79-80 | Reachable, but the script does not say how. Only 3 of 54 button-only states produce it; the default state converges |
| H9 | Demo: "180_axis FAIL — axis crossed · 30_degree PASS — changed 53°" | 02-DEMO-SCRIPT.md:95 | The panel's actual default strip shows 30_degree 1→2 FAIL (18 deg), 180_axis 2→3 FAIL, 30_degree 2→3 PASS (55 deg). The angle is 55°, not 53°, and there is an extra failing cut the script omits |
| 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 |
— verification/ADVERSARIAL-REVIEW.md:570-581
7.3 The pattern in the ten
They are not ten unrelated mistakes. They cluster:
| Cluster | Findings | What it is |
|---|---|---|
| Stale documentation | H1, H6 | The verification README was written before the parity check existed and never updated |
| Overclaimed precision | H2, H3, H5 | A number or a phrase that is true of a subset presented as true of the whole |
| Unverified item counted as verified | H4, H7 | A rule or a constant inside the "verified" set that no check touches |
| Script not reconciled to the artefact | H8, H9 | The demo script describes panel states the panel does not produce |
| True but undemonstrated | H10 | A claim about the Go source with no fixture behind it |
The third cluster is the dangerous one, because it is the failure mode the entry was built to avoid. H4 and H7 are both cases of something sitting inside the verified set that no check reaches.
7.4 The spec-vs-code divergence
A separate finding, not in the H-series:
"
01-SPEC.md:229says yellow is45° < |azimuth| ≤ 60°, **or |elevation| > 30°**, and01-SPEC.md:230says red is 'beyond both'.app/cinematographer/reliability.py:75-102requires both axes to be out for red only when azimuth exceeds 60; an elevation-only violation falls through to red" —verification/ADVERSARIAL-REVIEW.md:585-588
| azimuth | elevation | code | spec §6.1 |
|---|---|---|---|
| 0 | 31 | red | yellow |
| 0 | 40 | red | yellow |
| 50 | 40 | red | yellow |
| 70 | 40 | red | red |
— verification/ADVERSARIAL-REVIEW.md:590-595
The review's judgement is fair to both sides:
"The code's behaviour is arguably the more useful one (a 40° elevation is outside the trained envelope), but the spec and the code disagree, and
app/web/README.md:118describes the constants as 'taken from the spec'." —verification/ADVERSARIAL-REVIEW.md:597-599
8. The defect register
The review's full register, 17 defects (verification/ADVERSARIAL-REVIEW.md:608-626):
| # | Sev | Defect | Location |
|---|---|---|---|
| 1 | CRITICAL | Documented ComfyUI install produces a pack with no root __init__.py; ComfyUI raises FileNotFoundError and the nodes never appear. Acceptance criterion 8 fails | app/README.md:33-41 |
| 2 | MAJOR | Dead command: verification/panel_parity_check.py does not exist | verification/README.md:122 |
| 3 | MAJOR | "Value-for-value" is false — the check skips correction (scene) and detail (continuity), and those fields diverge from Go | verification/README.md:12-13; differential_check.py:233-246, :203-210; scene.py:203; continuity.py:121,140-141 |
| 4 | MAJOR | SamplerCustomAdvanced slot count 1 vs upstream 2; falsifies the "read from the node sources, not guessed" provenance claim | validate_graphs.py:72 (claim at :23-25) |
| 5 | MAJOR | 12 engine constants are unconstrained by the differential check, the unit suite, and the parity check | geometry.py:368-371, framing.py:104,116,125,164,192, autoframe.py:48, continuity.py axis sign + 180 clamp |
| 6 | MAJOR | eyeline (rule 12 of 14) is never differentially verified and is not disclosed as unverified | scene.py:231; verification/README.md:117-126 |
| 7 | MINOR | Hand-computed constant F = 3.4567701 is wrong (correct 3.4567901) | app/tests/test_framing.py:13 |
| 8 | MINOR | Reliability zone: elevation-only violations return red where the spec says yellow | reliability.py:75-102 vs 01-SPEC.md:229-230 |
| 9 | MINOR | Demo script's continuity on-screen state does not match the panel (53° vs 55°, plus an omitted failing cut) | 02-DEMO-SCRIPT.md:95 |
| 10 | MINOR | Demo script's NOT CONVERGED shot is reachable but the script gives no controls to reach it | 02-DEMO-SCRIPT.md:79-80 |
| 11 | MINOR | pytest required by the README but never listed as an install step | app/README.md:47; requirements.txt |
| 12 | MINOR | import cinematographer works only from app/, not the repo root | app/README.md:43-48 |
| 13 | MINOR | size_importance slots are counted in the 289 while only pass is compared | differential_check.py:243-244 |
| 14 | MINOR | Verification README lists panel parity as UNVERIFIED while app/web/README.md reports PASS | verification/README.md:122 |
| 15 | MINOR | Weights table has 8 rows for 9 rules; direct_address is absent (code gives it weight 0.0, so behaviour is consistent) | 01-SPEC.md:60-71 |
| 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 |
| 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 |
1 CRITICAL · 5 MAJOR · 11 MINOR.
8.1 The severity distribution is the story
| Severity | Count | Where they live |
|---|---|---|
| CRITICAL | 1 | The install path — a build defect |
| MAJOR | 5 | 3 documentation claims, 1 provenance claim, 1 verification-coverage gap |
| MINOR | 11 | 4 documentation/script, 3 coverage, 2 code-vs-spec, 2 packaging |
The engine's arithmetic is not in the register. Not one defect is a wrong measurement. The defects are in the claims about the measurements, the packaging, and the coverage.
That is the honest summary of this build: the code is better than the documentation around it.
9. What survived
Worth stating explicitly, because a defect register alone misrepresents the result.
| Claim | Verdict | Evidence |
|---|---|---|
| The 289-check number reproduces exactly | CONFIRMED | Attempt 1 failed to falsify; re-run during this file's writing |
| The differential check is a real check | CONFIRMED | It catches 19 of 30 injected defects |
| The solver's convergence flag never lies | CONFIRMED | 1800 calls, zero anomalies |
| The panel parity check is not circular | CONFIRMED | Leg [3] is a live two-engine comparison |
| The workflow validator is a real check | CONFIRMED | 6/6 structural mutations caught |
| 32 of 33 slot counts are right | CONFIRMED | Parsed from upstream with ast |
| The licence/trademark position is clean | CONFIRMED | Grep clean; no network calls in the engine |
| The unit tests' values are first-principles | CONFIRMED | 3 re-derived, arithmetic correct |
The _README provenance discipline is exemplary | CONFIRMED | Named as exemplary by the reviewer |
| The panel's "what is mocked" disclosure is exemplary | CONFIRMED | Same |
"After that, this is a strong entry with an unusually honest verification story. The differential check, the parity check and the workflow validator are all real and all re-runnable; I attacked each of them and they held up far better than I expected." —
verification/ADVERSARIAL-REVIEW.md:722-725
10. Remediation status
Observed directly from the source tree at 2026-10-29 17:38 PT (2026-10-30T00:38Z). The tree was being edited concurrently by another lane while this file was written, so this section is a snapshot, not a final state.
10.1 Fixed
| Defect | Evidence of the fix |
|---|---|
| #2 — dead parity command | verification/README.md:122 now reads: "VERIFIED — python app/web/parity_check.py → RESULT: PASS — 28 fixtures, 0 mismatches" |
#4 — SamplerCustomAdvanced slot count | app/workflows/validate_graphs.py:72 now reads "SamplerCustomAdvanced": 2, # output, denoised_output |
#7 — the wrong F constant | app/tests/test_framing.py:13 now reads F = 3.45679012345679 |
| #14 — parity listed as UNVERIFIED | Same edit as #2; the row moved out of the UNVERIFIED table |
10.2 Partially fixed
| Defect | State |
|---|---|
| #1 — CRITICAL install path | A shim now exists at app/__init__.py (created 17:32 PT), which re-exports NODE_CLASS_MAPPINGS and NODE_DISPLAY_NAME_MAPPINGS from the cinematographer package and documents both supported layouts. But the documented install path is still broken: app/README.md:33-41 still says git clone <this-repo> ComfyUI-Cinematographer, which puts the pack root at the repo root — and there is still no __init__.py at the repo root. ComfyUI's loader does not recurse (verification/ADVERSARIAL-REVIEW.md:512-513), so it will not find app/__init__.py. |
The CRITICAL defect is not yet closed. The shim is necessary but not sufficient: either the README's clone target must change, or a repo-root __init__.py must be added, or cinematographer/ must move to the repo root. The review listed all three options (verification/ADVERSARIAL-REVIEW.md:696-700).
10.3 Not fixed
| Defect | State at 17:38 PT |
|---|---|
| #3 — "value-for-value" is false | verification/README.md:12-13 unchanged |
| #5 — 12 unconstrained constants | No boundary fixtures added |
#6 — eyeline unverified | No two-character fixture added; not disclosed |
| #8 — reliability zone vs spec | Unchanged |
| #9, #10 — demo script mismatches | Unchanged |
| #11 — pytest not an install step | Unchanged |
| #12 — import from repo root | Unchanged |
#13 — size_importance counted then skipped | Unchanged |
#15 — weights table missing direct_address | Unchanged |
| #16 — Go failure mode undemonstrated | Unchanged |
#17 — converged=True with off-frame feet | Unchanged |
10.4 The verification harnesses still pass after the edits
Re-run at 17:38 PT:
$ PYTHONDONTWRITEBYTECODE=1 python3 verification/differential_check.py verification/go-reference-dump.json
differential checks run: 289
ALL FIXTURES AGREE with the original Go implementation.
$ PYTHONDONTWRITEBYTECODE=1 python3 app/workflows/validate_graphs.py
PASS reshoot_ltx_crossview.json (35 nodes, 49 links)
PASS reshoot_wan22_fun_control.json (25 nodes, 33 links)
All structural checks passed. This does NOT mean the graphs run: they have never been executed.
The three edits did not break anything. But the CRITICAL defect is invisible to all three harnesses, which is exactly the point of §3.5.
11. What the review could not verify
The review's own list (verification/ADVERSARIAL-REVIEW.md:668-690), which is the most important section for anyone relying on this package:
| Not verified | Why it matters |
|---|---|
| No live ComfyUI | The graphs' runtime behaviour is unknown, and the fixed install layout was never tested against a running instance — only against the loader source |
| No Magieva Go checkout | go-harness/zz-cine-dump.go could not be re-run. "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." |
| No render | LTX 2.3 + CrossView-Warp + MoGe-2 output quality is unverified |
| The CrossView-Warp ±45° range | Taken from the spec and the node pack's docs; not measured |
| Licence terms | "I did not read the LTX-2.x Community licence, the Wan 2.2 licence, or the MoGe-2 licence to confirm the revenue caps and territory exclusions quoted in the README." |
| The competition rubric | Unpublished; nothing can be verified against it |
| Browser coverage | One viewport, Chrome, local http.server. No three.js CDN-offline fallback, no Firefox/Safari, no mobile |
| Input names beyond the flagged set | Slot counts verified for all 33 class types; input names only for the flagged nodes |
AutoFrameGroup | Not ported; the entry says so (verification/README.md:66) |
The second row is the one to carry forward. The entry's strongest claim — 289 checks against the original Go implementation — reduces to agreement with a JSON file whose provenance is asserted, not audited. The harness source is preserved, so the claim is auditable, but nobody audited it.
12. The three claims the reviewer would least like a judge to find
"The three claims I would least like a judge to find first, in order:
verification/README.md:122— a verification README that tells you to run a script that does not exist.validate_graphs.py:72— a 'read from the node sources, not guessed' table with one guess in it.app/README.md:41— 'Restart ComfyUI. The nodes appear under the Cinematographer category.' They do not."—
verification/ADVERSARIAL-REVIEW.md:734-740
Two of the three are now fixed (§10.1). The third is the CRITICAL one, and it is only half fixed (§10.2).
The ordering is itself informative. The reviewer ranked a dead command in a verification README above a broken install, because the dead command is the one that most directly contradicts the document's own stated rule:
"The rule for this directory: a claim lives here only if a command in this file reproduces it. Anything else is marked UNVERIFIED." —
verification/README.md:5-6
A verification README that violates its own rule is a worse look than a packaging bug, because the README's rule is the entry's whole thesis in miniature.
13. Decision register — the adversarial phase
| # | Decision | Evidence |
|---|---|---|
| A1 | Review adversarially; a review that finds nothing is a failure | verification/ADVERSARIAL-REVIEW.md:4 |
| A2 | Do not modify the artefact under review | verification/ADVERSARIAL-REVIEW.md:5-7 |
| A3 | Mutate on a throwaway copy | verification/ADVERSARIAL-REVIEW.md:6-7 |
| A4 | Reproduce every claim before judging it | verification/ADVERSARIAL-REVIEW.md:44-77 |
| A5 | Parse upstream sources rather than trust the table | verification/ADVERSARIAL-REVIEW.md:401-402 |
| A6 | Record discarded false positives | verification/ADVERSARIAL-REVIEW.md:659-664 |
| A7 | Rank the dead command above the broken install | verification/ADVERSARIAL-REVIEW.md:734-740 |
| A8 | Recommend boundary fixtures as the highest-value fix | verification/ADVERSARIAL-REVIEW.md:706-708 |
| A9 | Do not fix the defects; report them | verification/ADVERSARIAL-REVIEW.md:5 |
A9 is worth noting: the review lane's write scope was this file only (verification/ADVERSARIAL-REVIEW.md:5). The fixes were a separate lane's work. That separation is why the defect register and the remediation status can be read independently.
14. Evidence index for this file
| Claim | Primary source |
|---|---|
| The review's stance | verification/ADVERSARIAL-REVIEW.md:4-7 |
| The verdict table | verification/ADVERSARIAL-REVIEW.md:31-40 |
| The bottom line | verification/ADVERSARIAL-REVIEW.md:13-15, :719-720 |
| The install defect | verification/ADVERSARIAL-REVIEW.md:475-528 |
| The loader source | verification/ADVERSARIAL-REVIEW.md:499-513 |
| The pytest secondary defect | verification/ADVERSARIAL-REVIEW.md:530-539 |
| The import tertiary defect | verification/ADVERSARIAL-REVIEW.md:541-542 |
| The 11 missed mutations | verification/ADVERSARIAL-REVIEW.md:134-158 |
| The skipped fields | verification/ADVERSARIAL-REVIEW.md:164-201 |
eyeline unverified | verification/ADVERSARIAL-REVIEW.md:203-211 |
| The validator's 6/6 | verification/ADVERSARIAL-REVIEW.md:388-397 |
| The slot-count audit | verification/ADVERSARIAL-REVIEW.md:399-418 |
| The 12 unconstrained constants | verification/ADVERSARIAL-REVIEW.md:614, :727-732 |
| The H-series | verification/ADVERSARIAL-REVIEW.md:570-581 |
| The spec-vs-code divergence | verification/ADVERSARIAL-REVIEW.md:583-599 |
| The defect register | verification/ADVERSARIAL-REVIEW.md:608-626 |
| The falsification log | verification/ADVERSARIAL-REVIEW.md:630-657 |
| The discarded false positives | verification/ADVERSARIAL-REVIEW.md:659-664 |
| What the review could not verify | verification/ADVERSARIAL-REVIEW.md:668-690 |
| The fix order | verification/ADVERSARIAL-REVIEW.md:694-713 |
| The top-three list | verification/ADVERSARIAL-REVIEW.md:734-740 |
| The remediation state | Observed from the source tree at 2026-10-29 17:38 PT; see §10 |