commit df86e89f789a560a2bbf3ec188c972829900133f
parent 0bac8912a74c74a1eecbf39e2ec6acd240efa01c
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date: Sat, 22 Aug 2026 18:45:47 -0400
registry: declare an operation's group and what one unit costs
Three surfaces each kept their own hardcoded idea of which operations belong
together — the transit line, the /channels columns, the lane card — and the last
time a kind was added, one of them kept summing three unrelated operations into
a single station. `group` makes that one declaration; operationsGroupLabel
derives a set's name so a lane holding a mix falls back to "Derived data"
instead of advertising one member's label.
`costBasis` is the fact that hid. attribution-text is armed, reachable on 11,337
videos of one channel, and its unit is the transcript CHUNK, not the video —
roughly 194,000 model calls corpus-wide against one completed video. No screen
could say so, because every screen said "Backfill". Stating the unit beside the
backlog is what makes the number legible; there is deliberately no threshold and
no editorialising, because a "this is a lot" cutoff is a magic number the next
operation gets wrong.
Additive and declarative. Nothing reads either field yet.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diffstat:
2 files changed, 153 insertions(+), 0 deletions(-)
diff --git a/common/lib/backfillKinds.test.ts b/common/lib/backfillKinds.test.ts
@@ -10,7 +10,10 @@ import {
resolveBackfillKinds,
orderByDependencies,
operationCatalog,
+ operationCostBasis,
+ operationGroup,
operationLabel,
+ operationsGroupLabel,
digestLaneFor,
diarizationLaneFor,
laneYieldsToTranscription,
@@ -1193,6 +1196,62 @@ test("the catalog covers every operation, dispatched here or not", () => {
}
});
+test("every catalogued operation declares a group and a cost basis", () => {
+ // Both are read unconditionally by the UI — the transit line groups stations
+ // by `group`, and every armed operation prints `costBasis` beside its
+ // backlog. An entry missing either renders a blank where a fact should be,
+ // which is the failure mode that let attribution-text sit armed at ~194,000
+ // model calls while every screen called it "Backfill".
+ for (const op of operationCatalog()) {
+ assert.ok(op.group, `${op.id} has no group`);
+ assert.ok(op.costBasis.length > 0, `${op.id} has no costBasis`);
+ }
+});
+
+test("the three speaker operations share one group; digest does not", () => {
+ assert.equal(operationGroup("diarization"), "speakers");
+ assert.equal(operationGroup("attribution-diarized"), "speakers");
+ assert.equal(operationGroup("attribution-text"), "speakers");
+ assert.equal(operationGroup("digest"), "digest");
+ assert.equal(operationGroup("download"), "media");
+ assert.equal(operationGroup("transcription"), "transcript");
+ // An id the catalog does not know is null, NOT filed under the first group.
+ assert.equal(operationGroup("no-such-operation"), null);
+});
+
+test("a set's label is derived, so a mixed lane cannot claim one member's name", () => {
+ // The whole reason this is derived: the backfill lane holds three speaker
+ // operations today and its station can honestly say "Speakers". Add a kind
+ // from another group and it degrades to the generic name rather than
+ // continuing to advertise a label that now describes two thirds of it.
+ assert.equal(
+ operationsGroupLabel([
+ "diarization",
+ "attribution-diarized",
+ "attribution-text",
+ ]),
+ "Speakers",
+ );
+ assert.equal(
+ operationsGroupLabel(["diarization", "digest"]),
+ "Derived data",
+ );
+ assert.equal(operationsGroupLabel([]), "Derived data");
+ // Unknown ids contribute nothing rather than poisoning a single-group set.
+ assert.equal(operationsGroupLabel(["digest", "no-such-op"]), "Digest");
+});
+
+test("attribution-text's cost basis states the CHUNK unit, not the video", () => {
+ // The measured fact that hid behind the word "backfill": this lane's unit is
+ // the transcript chunk, so its 11,337 reachable videos are on the order of
+ // 194,000 model calls. Every other lane in the table is per-video, and a
+ // reader who assumes that of this one is wrong by ~17x.
+ assert.match(operationCostBasis("attribution-text"), /chunk/);
+ assert.match(operationCostBasis("attribution-diarized"), /per video/);
+ assert.match(operationCostBasis("diarization"), /per video/);
+ assert.equal(operationCostBasis("no-such-operation"), "");
+});
+
// The accounting rule the whole feature turns on: reachable work and
// needs-re-acquiring are never added together.
test("counts keep reachable work and needs-re-acquiring apart", () => {
diff --git a/common/lib/backfillKinds.ts b/common/lib/backfillKinds.ts
@@ -243,11 +243,55 @@ export type BackfillRunOutcome =
| "disabled"
| "failed";
+// WHICH PIPELINE THIS OPERATION BELONGS TO, as a declared field rather than a
+// list somebody maintains in a component.
+//
+// Three surfaces need this same grouping and each used to hardcode its own copy:
+// the channel transit line (which station does this operation live under), the
+// /channels table (which columns sit together), and the lane card (which
+// operations does this queue actually hold). Three hardcoded lists is three
+// places to forget when a kind is added — and the last time one was added, the
+// transit line kept summing three unrelated operations into one station because
+// nobody updated its list.
+//
+// Deriving the label from the group also means a lane holding a MIX cannot go
+// stale: it falls back to "Derived data" rather than naming two of its three
+// members.
+export type OperationGroup = "media" | "transcript" | "digest" | "speakers";
+
+export function groupLabel(group: OperationGroup): string {
+ switch (group) {
+ case "media":
+ return "Media";
+ case "transcript":
+ return "Transcript";
+ case "digest":
+ return "Digest";
+ case "speakers":
+ return "Speakers";
+ }
+}
+
export type BackfillKind = {
id: string;
label: string;
// One line of UI copy: what this backfill is, in the operator's terms.
hint: string;
+ // The pipeline this operation belongs to. See OperationGroup.
+ group: OperationGroup;
+ // WHAT ONE UNIT OF THIS OPERATION COSTS, as a phrase — "one audio pass per
+ // video", "~1 model call per transcript chunk".
+ //
+ // The fact this exists to surface: an operation can be armed at enormous cost
+ // and read as a quiet row. attribution-text is reachable on 11,337 videos of
+ // one channel and roughly 194,000 model calls corpus-wide, it has completed
+ // ONE video, and every screen that mentioned it said only "Backfill". Printing
+ // the unit beside the backlog is what makes 11,337 legible.
+ //
+ // Deliberately NO threshold and no editorialising. A "this is a lot" cutoff
+ // would be a magic number the next operation gets wrong, and the operator is
+ // the one who decides what is too expensive.
+ costBasis: string;
// What a `deferred` video of THIS kind is waiting for, and what an operator
// can do about it. Belongs to the kind, not to the card: BackfillStage used to
// hardcode "too long to diarize under the current limit", which was correct
@@ -322,6 +366,8 @@ const diarization: BackfillKind = {
id: "diarization",
label: "Speaker diarization",
hint: "Speaker turns captured from the audio, written to diarization.json beside the transcript.",
+ group: "speakers",
+ costBasis: "one pass over the audio per video",
// The wording BackfillStage used to hardcode for every kind at once.
deferredHint:
"too long to diarize under the current limit — raise or clear Max audio hours in Settings to include them",
@@ -491,6 +537,10 @@ const attributionText: BackfillKind = {
id: "attribution-text",
label: "Speaker names (from the transcript)",
hint: "Speakers reconstructed from the transcript alone, for videos with no diarization. Cheaper to reach, worse than the diarized lane, and it never overwrites one.",
+ group: "speakers",
+ // The expensive one, and the reason costBasis is a field. A transcript is
+ // many chunks; this is the only lane in the table whose unit is not the video.
+ costBasis: "~1 model call per transcript chunk",
tier: "lane",
lane: { queueKey: BACKFILL_QUEUE, contendsFor: "network" },
enabled: (settings) =>
@@ -540,6 +590,8 @@ const attributionDiarized: BackfillKind = {
id: "attribution-diarized",
label: "Speaker names (from the audio)",
hint: "Names put to the speaker clusters in diarization.json — about one model call per video, and better than the text-only lane. Needs diarization to have run first.",
+ group: "speakers",
+ costBasis: "~1 model call per video",
tier: "lane",
// The dependency the hint has always stated in prose. Declaring it is what
// turns "needs diarization to have run first" from a sentence an operator
@@ -672,6 +724,8 @@ const digest: BackfillKind = {
id: "digest",
label: "Digest",
hint: "Chapters and tags generated from the transcript by a local or metered model. Needs a transcript first.",
+ group: "digest",
+ costBasis: "~1 model call per transcript chunk",
// See the `deferred` branch in state() below for the measurement behind this
// wording. It says "run the normalize pass" and NOT "it clears itself",
// because nothing automatic ever will.
@@ -881,6 +935,8 @@ export type ExternalOperation = {
id: string;
label: string;
hint: string;
+ group: OperationGroup;
+ costBasis: string;
lane: BackfillLane;
dependsOn?: readonly string[];
dispatch: "external";
@@ -891,6 +947,8 @@ export const EXTERNAL_OPERATIONS: readonly ExternalOperation[] = [
id: "download",
label: "Download",
hint: "Fetching the media. Dispatched by the auto-download runner and the per-channel pipeline actions.",
+ group: "media",
+ costBasis: "one fetch per video, over the network",
// Really one queue per platform (downloadQueueKey), not a single key. Named
// here as the shape rather than the exact key, because the catalog's job is
// the dependency graph, not dispatch.
@@ -901,6 +959,8 @@ export const EXTERNAL_OPERATIONS: readonly ExternalOperation[] = [
id: "transcription",
label: "Transcription",
hint: "Turning audio into a transcript. Dispatched by the auto-transcribe runner across the worker pool.",
+ group: "transcript",
+ costBasis: "one pass over the audio per video, on a worker",
lane: { queueKey: TRANSCRIPTION_QUEUE, contendsFor: "gpu" },
dependsOn: ["download"],
dispatch: "external",
@@ -913,6 +973,8 @@ export type OperationDescriptor = {
id: string;
label: string;
hint: string;
+ group: OperationGroup;
+ costBasis: string;
lane: BackfillLane;
dependsOn?: readonly string[];
dispatch: BackfillDispatch;
@@ -925,6 +987,8 @@ export function operationCatalog(): OperationDescriptor[] {
id: k.id,
label: k.label,
hint: k.hint,
+ group: k.group,
+ costBasis: k.costBasis,
lane: k.lane,
dependsOn: k.dependsOn,
dispatch: "backfill" as const,
@@ -939,6 +1003,36 @@ export function operationLabel(id: string): string {
return operationCatalog().find((o) => o.id === id)?.label ?? id;
}
+// The group an operation belongs to, or null for an id the catalog does not
+// know. Null rather than a fallback group: a caller grouping by this must be
+// able to tell "unknown" from "media", and silently filing a dangling id under
+// the first group would put it on the wrong station.
+export function operationGroup(id: string): OperationGroup | null {
+ return operationCatalog().find((o) => o.id === id)?.group ?? null;
+}
+
+// What one unit of an operation costs, in words. Empty string for an unknown
+// id, so a surface can print it unconditionally without a placeholder.
+export function operationCostBasis(id: string): string {
+ return operationCatalog().find((o) => o.id === id)?.costBasis ?? "";
+}
+
+// The label for a SET of operations — a lane card, a transit-line station, a
+// column group. One group means that group's name; a mix means "Derived data".
+//
+// DERIVED, never hardcoded, which is the point: a lane that gains a kind from a
+// different group degrades to the honest generic name instead of continuing to
+// advertise a label that now describes two thirds of what it holds.
+export function operationsGroupLabel(ids: ReadonlyArray<string>): string {
+ const groups = new Set<OperationGroup>();
+ for (const id of ids) {
+ const group = operationGroup(id);
+ if (group) groups.add(group);
+ }
+ if (groups.size !== 1) return "Derived data";
+ return groupLabel([...groups][0]);
+}
+
// The digest operation's id, named once. Surfaces that read one specific
// operation off a snapshot (the digest stage card, the dashboard's coverage
// instrument) need this string, and a typo in it fails the way a missing