commit 9f2bbf9157363914a962680c972560d6b548264d
parent 1b519f390172d964cefff5cc9d4574f83cd60504
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date: Tue, 8 Sep 2026 01:14:30 -0400
editor: a band is folded once, and the new snapshot entries stop doubling two of them
/channels passes [...EXTERNAL_BAND_IDS, ...allOperations] as operationIds, so
once slice 1.5 wrote backfill.download and backfill.transcription,
addRegistryEntry folded them on top of addExternalBands and a three-video
channel read "6 done of 6". The registry fold now skips the two ids
addExternalBands owns.
This is the trap backfillLaneOperationEntriesOf exists for, at the one surface
that does not go through it: the moment the snapshot map stopped being one
lane, "every id in this map is mine" stopped being true. Caught by the e2e band
assertion; pinned by a unit test that fails without the filter.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Diffstat:
2 files changed, 67 insertions(+), 1 deletion(-)
diff --git a/editor/app/components/pipelines/buildBands.test.ts b/editor/app/components/pipelines/buildBands.test.ts
@@ -376,3 +376,53 @@ test("StateBand.tsx exports only components, never callable helpers", () => {
);
}
});
+
+test("a download/transcription entry in the snapshot is NOT folded twice", () => {
+ // Slice 1.5 gave the two bucket lanes a snapshot entry, and `/channels` passes
+ // `[...EXTERNAL_BAND_IDS, ...allOperations]` as operationIds — so without the
+ // filter in buildOperationBands the entry lands on top of addExternalBands and
+ // a three-video channel reads "6 done of 6". backfill.spec.ts caught it in the
+ // browser; this is the unit that pins it.
+ //
+ // The entries here are the ones generateChannelSnapshot writes: ids = the
+ // lane's default bucket union, eligible = present + the work counts.
+ const snapshot = snapshotOf({
+ totals: { videos: 3, transcribed: 0, downloaded: 3 },
+ buckets: {
+ downloadedNoTranscript: ["vidA", "vidB", "vidC"],
+ failedListed: [],
+ partialDownloads: [],
+ noTranscript: [],
+ untranscribable: [],
+ } as unknown as ChannelSnapshot["buckets"],
+ undownloadedIds: [],
+ backfill: {
+ download: entryOf({ missing: 0, ids: [], eligible: 3 }),
+ transcription: entryOf({
+ missing: 3,
+ ids: ["vidA", "vidB", "vidC"],
+ eligible: 3,
+ }),
+ },
+ });
+ const bands = buildOperationBands({
+ snapshots: [snapshot],
+ operationIds: ["download", "transcription", "diarization"],
+ });
+ const dl = bandOf(bands, "download");
+ assert.equal(dl.eligible, 3, "eligible must be the playlist, counted once");
+ assert.equal(dl.present, 3);
+ assert.equal(dl.reachable, 0);
+ const tr = bandOf(bands, "transcription");
+ assert.equal(tr.eligible, 3);
+ assert.equal(tr.present, 0);
+ assert.equal(tr.reachable, 3);
+ // And the band is still the BUCKET definition, not the entry's: the same
+ // numbers come back with the entries absent, which is every live snapshot.
+ const stripped = buildOperationBands({
+ snapshots: [snapshotOf({ ...snapshot, backfill: {} })],
+ operationIds: ["download", "transcription", "diarization"],
+ });
+ assert.deepEqual(bandOf(stripped, "download"), dl);
+ assert.deepEqual(bandOf(stripped, "transcription"), tr);
+});
diff --git a/editor/app/components/pipelines/buildBands.ts b/editor/app/components/pipelines/buildBands.ts
@@ -199,11 +199,27 @@ export function buildOperationBands({
for (const id of operationIds) {
if (!bands.has(id)) bands.set(id, emptyBand(id, true));
}
+ // EXACTLY ONE FOLD PER BAND, and the two external ids are addExternalBands'.
+ //
+ // `/channels` passes `[...EXTERNAL_BAND_IDS, ...allOperations]` in — it wants
+ // a column for every band — and until slice 1.5 that was harmless here
+ // because `snapshot.backfill.download` did not exist and addRegistryEntry
+ // returned early. Now it does exist, and folding it on top of
+ // addExternalBands DOUBLES a channel's Download and Transcribe coverage.
+ // (Caught by backfill.spec.ts, which read the row as "6 done of 6" on a
+ // three-video channel.)
+ //
+ // This is the same trap backfillLaneOperationEntriesOf was written for, at
+ // the one surface that does not go through it: the moment the snapshot map
+ // stopped being one lane, "every id in this map is mine" stopped being true.
+ const registryIds = operationIds.filter(
+ (id) => !EXTERNAL_BAND_IDS.includes(id),
+ );
for (const snapshot of snapshots) {
if (!snapshot) continue;
addExternalBands(bands, snapshot);
- for (const id of operationIds) {
+ for (const id of registryIds) {
const band = bands.get(id);
if (!band) continue;
// Digest is a plain registry entry here, like every other operation: a