commit c905fc26f0df3abc382d086a308f9953204eda81
parent b7fd46a8d2c66804cbec1839259d67cc1cfcfa20
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date: Mon, 7 Sep 2026 23:59:45 -0400
common+editor: reach dies with the sweeps that were its only axis
`AutoQueueReach`, `AUTO_QUEUE_REACHES` and `sanitizeAutoQueueReach` lost their
last reader when slice 1.3 retired the sweeps, and `OrderReach` had been
rendering a branch every caller passed `null` to; it is `LaneOrder` now, with the
select, `REACH_LABEL` and two of its four sentences gone. A runner has no reach
axis — a rule already orders every video it claims across every channel and
bucket, and which rule goes first is the tree.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Diffstat:
5 files changed, 89 insertions(+), 172 deletions(-)
diff --git a/common/jobs/autoQueuePolicy.ts b/common/jobs/autoQueuePolicy.ts
@@ -13,7 +13,6 @@ import type {
AutoQueueNode,
AutoQueueOrder,
AutoQueuePolicy,
- AutoQueueReach,
AutoQueueSettings,
} from "../lib/autoQueueTypes";
import { LANES, isGroup } from "../lib/autoQueueTypes";
@@ -27,7 +26,6 @@ export type {
AutoQueueNode,
AutoQueueOrder,
AutoQueuePolicy,
- AutoQueueReach,
AutoQueueSettings,
};
export { LANES, isGroup };
@@ -62,15 +60,6 @@ export const AUTO_QUEUE_ORDERS: ReadonlyArray<AutoQueueOrder> = [
];
-export const AUTO_QUEUE_REACHES: ReadonlyArray<AutoQueueReach> = [
- "channel",
- "corpus",
-];
-
-export function sanitizeAutoQueueReach(value: unknown): AutoQueueReach {
- return value === "corpus" ? "corpus" : "channel";
-}
-
// Coerce a stored/raw value to a legal order. Anything unrecognised — including
// a missing field on a settings file written before the field existed — means
// "listed", i.e. today's behaviour. One sanitizer, because the same enum is
diff --git a/common/lib/autoQueueTypes.ts b/common/lib/autoQueueTypes.ts
@@ -33,24 +33,6 @@ export type AutoQueueMatchType = "channel" | "platform" | "all";
// which is what makes it safe to name here before anything computes it.
export type AutoQueueOrder = "listed" | "newest" | "oldest" | "cheapest";
-// How far an order REACHES.
-//
-// "channel" — sort each channel's own candidates (today, and the default). A
-// corpus-wide sweep still visits channels heaviest-first, so a video
-// uploaded this morning waits for its channel's turn.
-// "corpus" — additionally order the CHANNELS by their freshest (or oldest)
-// pending video, so the channel holding the newest work goes first.
-//
-// It is a separate axis from AutoQueueOrder rather than two more enum members
-// because it is meaningless without one: reach only says how widely an order
-// applies, and "listed" has no order to apply. The console disables the control
-// while "listed" is selected for exactly that reason.
-//
-// This deliberately does NOT interleave individual videos across channels —
-// that would break one-job-per-channel, and 77,000 single-video jobs would evict
-// the registry's 100 records.
-export type AutoQueueReach = "channel" | "corpus";
-
export type AutoQueueMatch = {
type: AutoQueueMatchType;
// Channel slug (type=channel) or platform name (type=platform). Ignored for
diff --git a/editor/app/operations/components/LaneOrder.tsx b/editor/app/operations/components/LaneOrder.tsx
@@ -0,0 +1,86 @@
+"use client";
+
+import { useId } from "react";
+import type { AutoQueueOrder } from "yt-dlp-transcript-common/jobs/autoQueuePolicy";
+import { ORDER_LABEL, RECENCY_ORDERS, SELECT_CLASS } from "./dispatch";
+
+// ORDER, at the foot of the lane where the decision lives.
+//
+// Not in /settings. An operator asking "why is it working on a 2019 video" is
+// looking at this lane, and the answer is one control away or it is nowhere.
+//
+// IT WAS `OrderReach`, AND REACH IS GONE. Reach was a second axis — sort within
+// each channel, or order the channels too — and it belonged to the corpus
+// sweeps, which visited channels heaviest-first and therefore had a channel
+// order to argue about. A RUNNER has no such axis: a rule already orders every
+// video it claims across every channel and bucket, and which RULE goes first is
+// the tree's job. Slice 1.3 retired the sweeps and every caller passed
+// `reach={null}`; slice 1.4 deleted the branch, the enum and its sanitizer
+// rather than leaving a control nothing could reach.
+//
+// Native <select>, like every other policy control on this page. That is
+// load-bearing, not stylistic — see the note at the foot of dispatch.ts.
+
+export function LaneOrder({
+ order,
+ // The trade-off sentence for this particular lane, or null when there is
+ // none. Supplied rather than derived so each lane keeps its own copy verbatim.
+ tradeoff,
+ busy,
+ // Pinned by the e2e suite for every lane ("video order for auto-transcribe").
+ // Optional because the visible <label> already names the control.
+ orderAriaLabel,
+ // WHICH ORDERS THIS LANE OFFERS. Defaults to the three date-keyed ones, which
+ // is every order that existed before the lanes did — so no console gains an
+ // option it has no comparator for. A lane whose runner supplies one passes
+ // its own list.
+ orders = RECENCY_ORDERS,
+ onChange,
+}: {
+ order: AutoQueueOrder;
+ tradeoff: string | null;
+ busy: boolean;
+ orderAriaLabel?: string;
+ orders?: ReadonlyArray<AutoQueueOrder>;
+ onChange: (next: { order: AutoQueueOrder }) => void;
+}) {
+ const orderId = useId();
+ const listed = order === "listed";
+
+ return (
+ <div className="flex flex-col gap-2 rounded-md border border-border bg-card px-3 py-2">
+ <p className="font-mono text-xs uppercase tracking-[0.14em] text-muted-foreground">
+ Order
+ </p>
+ <div className="flex flex-wrap items-center gap-x-6 gap-y-2 text-sm">
+ <span className="flex items-center gap-2">
+ <label htmlFor={orderId} className="text-muted-foreground">
+ Order
+ </label>
+ <select
+ id={orderId}
+ aria-label={orderAriaLabel}
+ className={SELECT_CLASS}
+ value={order}
+ disabled={busy}
+ onChange={(e) =>
+ onChange({ order: e.target.value as AutoQueueOrder })
+ }
+ >
+ {orders.map((o) => (
+ <option key={o} value={o}>
+ {ORDER_LABEL[o]}
+ </option>
+ ))}
+ </select>
+ </span>
+ </div>
+ <p className="text-xs text-muted-foreground">
+ {listed
+ ? "Listed order is whatever order the work list already had — bucket order, then channel order."
+ : "A rule orders every video it claims, across every channel and bucket. Which RULE goes first is still the rule list's job; for a pure newest-first archive, use one catch-all rule."}
+ </p>
+ {tradeoff && <p className="text-xs text-warning">{tradeoff}</p>}
+ </div>
+ );
+}
diff --git a/editor/app/operations/components/OrderReach.tsx b/editor/app/operations/components/OrderReach.tsx
@@ -1,139 +0,0 @@
-"use client";
-
-import { useId } from "react";
-import type {
- AutoQueueOrder,
- AutoQueueReach,
-} from "yt-dlp-transcript-common/jobs/autoQueuePolicy";
-import { ORDER_LABEL, RECENCY_ORDERS, SELECT_CLASS } from "./dispatch";
-
-// ORDER AND REACH, at the foot of the lane where the decision lives.
-//
-// Not in /settings. An operator asking "why is it working on a 2019 video" is
-// looking at this lane, and the answer is one control away or it is nowhere.
-//
-// TWO AXES, NOT ONE ENUM. Order says WHICH video; Reach says HOW WIDELY that
-// applies — within each channel (the sweep still visits channels heaviest-
-// first) or across all channels (the channel holding the freshest work goes
-// first). Reach is meaningless without an order, so it is DISABLED while
-// "Listed" is selected rather than being silently ignored.
-//
-// Native <select>, like every other policy control on this page. That is
-// load-bearing, not stylistic — see the note at the foot of dispatch.ts.
-
-export const REACH_LABEL: Record<AutoQueueReach, string> = {
- channel: "Within each channel",
- corpus: "Across all channels",
-};
-
-export function OrderReach({
- order,
- reach,
- // The trade-off sentence for this particular lane, or null when there is
- // none. Supplied rather than derived so the runner lanes keep using the
- // existing orderTradeoff() copy verbatim.
- tradeoff,
- busy,
- // Pinned by the e2e suite for the two runner lanes
- // ("video order for auto-transcribe"). Optional because the sweep lanes have
- // no such contract and the visible <label> already names the control.
- orderAriaLabel,
- // WHICH ORDERS THIS LANE OFFERS. Defaults to the three date-keyed ones, which
- // is every order that existed before the lanes did — so no console gains an
- // option it has no comparator for. A lane whose runner supplies one passes
- // its own list.
- orders = RECENCY_ORDERS,
- onChange,
-}: {
- order: AutoQueueOrder;
- // NULL for the two RUNNER lanes, and that is a statement rather than a gap:
- // a runner's order already applies across every channel and bucket a rule
- // claims, so its reach is fixed at corpus-wide and there is no axis to offer.
- // Rendering a disabled Reach dropdown there would imply a setting that does
- // not exist; the fixed sentence below says what is actually true.
- reach: AutoQueueReach | null;
- tradeoff: string | null;
- busy: boolean;
- orderAriaLabel?: string;
- orders?: ReadonlyArray<AutoQueueOrder>;
- onChange: (next: { order: AutoQueueOrder; reach: AutoQueueReach }) => void;
-}) {
- const orderId = useId();
- const reachId = useId();
- const listed = order === "listed";
-
- return (
- <div className="flex flex-col gap-2 rounded-md border border-border bg-card px-3 py-2">
- <p className="font-mono text-xs uppercase tracking-[0.14em] text-muted-foreground">
- Order
- </p>
- <div className="flex flex-wrap items-center gap-x-6 gap-y-2 text-sm">
- <span className="flex items-center gap-2">
- <label htmlFor={orderId} className="text-muted-foreground">
- Order
- </label>
- <select
- id={orderId}
- aria-label={orderAriaLabel}
- className={SELECT_CLASS}
- value={order}
- disabled={busy}
- onChange={(e) =>
- onChange({
- order: e.target.value as AutoQueueOrder,
- reach: reach ?? "corpus",
- })
- }
- >
- {orders.map((o) => (
- <option key={o} value={o}>
- {ORDER_LABEL[o]}
- </option>
- ))}
- </select>
- </span>
- {reach !== null && (
- <span className="flex items-center gap-2">
- <label
- htmlFor={reachId}
- className={
- listed ? "text-muted-foreground/50" : "text-muted-foreground"
- }
- >
- Reach
- </label>
- <select
- id={reachId}
- className={SELECT_CLASS}
- value={reach}
- // Disabled, not hidden: the control staying in place is what
- // tells you the axis exists and what turns it on.
- disabled={busy || listed}
- onChange={(e) =>
- onChange({ order, reach: e.target.value as AutoQueueReach })
- }
- >
- {(Object.keys(REACH_LABEL) as AutoQueueReach[]).map((r) => (
- <option key={r} value={r}>
- {REACH_LABEL[r]}
- </option>
- ))}
- </select>
- </span>
- )}
- </div>
- <p className="text-xs text-muted-foreground">
- {reach === null
- ? listed
- ? "Listed order is whatever order the work list already had — bucket order, then channel order."
- : "A rule orders every video it claims, across every channel and bucket. Which RULE goes first is still the rule list's job; for a pure newest-first archive, use one catch-all rule."
- : listed
- ? "Listed order is whatever order the work list already had. Pick an order to enable Reach."
- : reach === "corpus"
- ? "Channels are visited by the freshest work each is holding, and each channel's own videos follow the same order. Heaviest-first is still the tiebreak."
- : "Each channel's own videos are ordered. Which channel goes first is unchanged — heaviest first."}
- </p>
- {tradeoff && <p className="text-xs text-warning">{tradeoff}</p>}
- </div>
- );
-}
diff --git a/editor/app/operations/components/PolicyTreeEditor.tsx b/editor/app/operations/components/PolicyTreeEditor.tsx
@@ -13,7 +13,7 @@ import { saveAutoQueueAction, type SaveResult } from "../actions";
import type { AutoQueueKindStatus } from "../status";
import { ClaimLadder } from "./ClaimLadder";
import type { RungOps } from "./LadderRung";
-import { OrderReach } from "./OrderReach";
+import { LaneOrder } from "./LaneOrder";
import { SaveBar } from "./SaveBar";
import {
type Channel,
@@ -330,12 +330,11 @@ export function PolicyTreeEditor({
sitting inside a dirty form would be the one thing on the page that
did not mean what the Save button says.
- Reach is null here, and that is a statement rather than a gap — a
+ There is no Reach axis, and that is a statement rather than a gap — a
runner's order already applies across every channel and bucket a rule
claims, so there is no second axis to offer. */}
- <OrderReach
+ <LaneOrder
order={form.order}
- reach={null}
tradeoff={tradeoff}
busy={saving}
orderAriaLabel={`video order for auto-${kindWord}`}