Archilyzer · Source

archilyzer

Archilyzer
git clone https://archilyzer.pages.dev/source/archilyzer.git
Log | Files | Refs | README | LICENSE

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:
Mcommon/jobs/autoQueuePolicy.ts | 11-----------
Mcommon/lib/autoQueueTypes.ts | 18------------------
Aeditor/app/operations/components/LaneOrder.tsx | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Deditor/app/operations/components/OrderReach.tsx | 139-------------------------------------------------------------------------------
Meditor/app/operations/components/PolicyTreeEditor.tsx | 7+++----
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}`}