Skip to content

Commit 8ad3365

Browse files
committed
Close HIGH-impact parity gaps flagged by audit 2026-04-15 — ranks, verdicts, Pass 3 payload
Browser pipeline was diverging from the Python library on decisions users see: ranks, verdicts, and the signals Pass 3 uses to review structure. - _computeRanks rewritten to mirror postprocess.compute_ranks: runner → null, procedural case_of_the_week → A, hybrid case_of_the_week → B, remaining lines ranked by descending event count with span thresholds A≥75% / B≥50% / C≥25%. Primary + also_affects count equally. Previous share-based formula gave A-rank to runners in procedurals. - _validateRanks ported from Python. Demotes A-rank lines below 25% span to B and flags >50%-dominant lines. Output fed into Pass 3 as diagnostics. Called in both Hollywood and narratology pipelines. - Pass 3 payload now includes weight_per_episode (primary/background/ glimpse/absent per plotline per episode), matching Python. - _applyVerdicts: target-id validation with console.warn on mismatch, DROP guard (abort when redistribute leaves events behind), MERGE now rewrites also_affects lists to replace source → target (with dedup), CREATE propagates the LLM's rank into reviewed_rank. - Narratology: new dedupe_arc_inciting_incidents (Python + JS) enforces one plot_fn=inciting_incident per plotline. Python orchestrator had a pre-existing ordering bug — orphan/dedupe ran after the final compute_ranks, so ranks saw pre-assignment counts; moved ahead of span/rank recompute. - Tests: 118 → 122. Added 3 dedupe_arc_inciting_incidents cases and a procedural-runner regression guard for compute_ranks.
1 parent c785052 commit 8ad3365

5 files changed

Lines changed: 421 additions & 71 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@
1313
- **Synopses draft persistence in the HTML viewer.** Generated synopses (and any in-modal edits) are saved to `localStorage` under `tvplot_synopses_draft` the moment they come back from the LLM — before the Review modal opens and before the pipeline runs. If the tab reloads, the pipeline crashes, or the user hits Cancel by mistake, the welcome screen surfaces a "Resume pending analysis: {show} S{season}?" banner with Resume / Discard buttons; Resume skips regeneration and goes straight into the Review + pipeline flow. Draft is cleared on pipeline success or explicit Cancel/Discard, kept on pipeline failure so the user can retry without paying for a second round of synopsis generation.
1414

1515
### Fixed
16+
- **Browser `_computeRanks` now matches Python.** The JS rank formula previously used event-share thresholds (≥25%/≥10%) and ignored type/format/span, so runners in procedurals routinely got A-rank. Rewritten to mirror `postprocess.compute_ranks`: runners → null, procedural case_of_the_week → A, hybrid case_of_the_week → B, remainder ranked by descending event count with span thresholds A≥75% / B≥50% / C≥25%. Primary and `also_affects` events count equally.
17+
- **Browser pipeline validates ranks and feeds diagnostics to Pass 3.** Ported `validate_ranks` to JS: demotes A-rank lines with span <25% to B (with a `console.warn`) and flags dominant lines (>50% of events). The flag list is now passed into the Pass 3 payload as `diagnostics`, matching Python.
18+
- **Pass 3 payload includes `weight_per_episode`.** The browser Pass 3 review call was omitting per-episode weight labels (`primary`/`background`/`glimpse`/`absent`) that Python sends. Added `_computeWeightPerEpisode` and wired it into the payload, so browser MERGE/DROP/REASSIGN decisions see the same signal Python does.
19+
- **`_applyVerdicts` closes three silent-corruption gaps.** Target ids are now validated against the current plotline set (and pending CREATEs) with a `console.warn` on mismatch; DROP aborts and keeps the plotline when `redistribute` doesn't cover every event (was splicing the plotline out regardless, leaving orphaned `plotline_id` pointers); MERGE now rewrites `also_affects` to replace the source id with the target (dedup if the target was already listed) — previously dangled at the dropped source. CREATE now propagates the LLM-assigned rank into `reviewed_rank` instead of hard-null.
20+
- **Narratology arc inciting-incident invariant.** Pass 5 can emit multiple `inciting_incident` values in `plot_fn` per plotline; new `dedupe_arc_inciting_incidents` (Python + JS) keeps the earliest-episode one and downgrades the rest to `escalation` on `plot_fn`. `event.function` is left alone — this is an arc-level concern.
21+
- **Narratology orphan/dedupe order.** The Python orchestrator was calling `assign_orphan_events` and `dedupe_inciting_incidents` *after* the final `compute_ranks`, so ranks reflected pre-assignment counts. Moved both (plus `dedupe_arc_inciting_incidents`) ahead of the final span/rank recomputation so ranks see the cleaned-up data. JS narratology already had the correct order from the previous release.
1622
- **Browser pipeline now redistributes orphan events.** The in-browser Hollywood and Narratology runners now call `_assignOrphanEvents` before computing span/ranks, matching the Python library. Events with `plotline_id = null` no longer render as an "Unassigned" row in the grid when they can be attributed via character co-occurrence.
1723
- **At most one `inciting_incident` per plotline.** New `dedupe_inciting_incidents` post-processor (Python + JS) keeps the earliest-episode inciting incident per plotline and downgrades duplicates to `escalation`. Runs in both Hollywood and Narratology pipelines before span/rank. Logs a warning when an A-plotline's inciting incident is not at the start of its span (no data rewrite — the warning surfaces in logs/console).
1824
- **Pipeline progress UI no longer looks frozen.** Added a CSS spinner next to the status message, a live `Elapsed MM:SS` counter (updates every second while the overlay is visible), and a `Step N of M` line above the bar. The "Asking Claude for synopses…" text no longer stays visible during the Review-synopses dialog — the progress overlay hides while the review modal is up and reappears with a fresh "Starting pipeline…" message once the user hits Run. Added a grey hint ("Typical run: 2–5 min for a 10-episode season") so long waits don't look like a hang.

0 commit comments

Comments
 (0)