commit 6b0036ad5458903604812f7e7e85c65d1e55a056
parent 15903309f0b72c5385b0006d39f6875aa3a8b157
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date: Sun, 20 Sep 2026 19:49:03 -0400
e2e: the editor-fetch fixtures need their own SOURCES, not just their own project
A clip window lands in the corpus, which is keyed by video and shared by every
project — that is the feature. So "this clip is not fetched yet" cannot be
asserted about a video another spec fetches: clip-bench pulls vid1, and the
editor-fetch spec then found its window already cached and never made a
request (409 "already cached to −3 s / +8 s"). Project isolation is not enough
one level down; vid3 and vid4 are cited by nothing else.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Diffstat:
2 files changed, 26 insertions(+), 7 deletions(-)
diff --git a/umtool/e2e/fixtures/make-fixture.mjs b/umtool/e2e/fixtures/make-fixture.mjs
@@ -663,6 +663,25 @@ const CUES = {
[9, 12, "and widening has nothing to find"],
[12, 15, "which is a thing to say out loud"],
],
+ // TWO SOURCES NOBODY ELSE TOUCHES, for the editor-fetch specs.
+ //
+ // A clip window now lands in the CORPUS, which is keyed by VIDEO and shared
+ // by every project — that is the feature. So a spec asserting "this window
+ // is not fetched yet" cannot cite a video another spec fetches: clip-bench's
+ // own fetch tests pull vid1, and the editor-fetch spec then found its window
+ // already cached and never made a request. Project isolation is not enough
+ // any more; source isolation is.
+ vid3: [
+ [0, 3, "The editor fetch fixture speaks."],
+ [3, 6, "And this is the sentence it cites."],
+ [6, 9, "Then it carries on for a while."],
+ [9, 12, "Before finally stopping here."],
+ ],
+ vid4: [
+ [0, 3, "The sweep fixture opens."],
+ [3, 6, "It has a second clip to fetch."],
+ [6, 9, "And nothing else cites it."],
+ ],
};
for (const [vid, rows] of Object.entries(CUES)) {
const dir = path.join(CHANNELS, "testchan", "data", vid);
@@ -885,7 +904,7 @@ const WALK = writeProject(
writeProject(
"editor-fetch-fixture",
manifest("editor-fetch-fixture", "The Editor Fetch Fixture", { siteOrigin: "https://archive.example" }, [
- { type: "clip", id: "e01", video: "vid1", start: 3.0, end: 6.0, cite: 3, section: 0, lock: true, quote: "and because", note: "the speaker names the number here" },
+ { type: "clip", id: "e01", video: "vid3", start: 3.0, end: 6.0, cite: 3, section: 0, lock: true, quote: "and this is the sentence", note: "the speaker names the number here" },
]),
);
@@ -897,8 +916,8 @@ writeProject(
writeProject(
"editor-fetch-many-fixture",
manifest("editor-fetch-many-fixture", "The Editor Fetch Sweep Fixture", { siteOrigin: "https://archive.example" }, [
- { type: "clip", id: "f01", video: "vid2", start: 0.0, end: 3.0, cite: 0, section: 0, lock: true, quote: "no punctuation" },
- { type: "clip", id: "f02", video: "vid2", start: 3.0, end: 6.0, cite: 3, section: 0, lock: true, quote: "never emitted a full stop" },
+ { type: "clip", id: "f01", video: "vid4", start: 0.0, end: 3.0, cite: 0, section: 0, lock: true, quote: "the sweep fixture opens" },
+ { type: "clip", id: "f02", video: "vid4", start: 3.0, end: 6.0, cite: 3, section: 0, lock: true, quote: "a second clip to fetch" },
]),
);
@@ -1177,7 +1196,7 @@ console.log(` SONG_CODE_DIR=${path.join(dest, "code")}`);
console.log(` SONG_DIR=${path.join(dest, "data")}`);
console.log(` SONG_REPORTS_DIR=${reports}`);
console.log(` YTDLP_BIN=${path.join(BIN, "yt-dlp")} QRENCODE_BIN=${path.join(BIN, "qrencode")}`);
-console.log(` CHANNELS_DIR=${CHANNELS} (testchan/vid1 punctuated, vid2 not)`);
+console.log(` CHANNELS_DIR=${CHANNELS} (testchan/vid1 punctuated, vid2 not; vid3/vid4 for the editor fetch)`);
console.log(` projects: report-fixture (4 clips, 1 mid-sentence), no-origin-fixture,`);
console.log(` localhost-fixture, bike-fixture (sweep), find/ (shadowed),`);
console.log(` deep/nested/solo-fixture (collapse case), bench-fixture (writable),`);
diff --git a/umtool/e2e/report-fetch-via-editor.spec.ts b/umtool/e2e/report-fetch-via-editor.spec.ts
@@ -108,7 +108,7 @@ test("the fetch route asks the editor, carries the provenance, and runs no yt-dl
const ask = asks[0];
expect(ask.authorization).toBe("Bearer umtool-e2e-token");
expect(ask.channelSlug).toBe("testchan");
- expect(ask.videoId).toBe("vid1");
+ expect(ask.videoId).toBe("vid3");
expect(ask.requestedBy).toBe("umtool");
expect(ask.manifest).toBe("editor-fetch-fixture");
expect(ask.clipId).toBe("e01");
@@ -119,7 +119,7 @@ test("the fetch route asks the editor, carries the provenance, and runs no yt-dl
expect(ask.to).toBe(8);
// In the CORPUS, not in this project's out/.
- const file = path.join(clipsDir("vid1"), "1.00-8.00.mp4");
+ const file = path.join(clipsDir("vid3"), "1.00-8.00.mp4");
expect(existsSync(file)).toBe(true);
expect(statSync(file).size).toBeGreaterThan(0);
@@ -172,7 +172,7 @@ test("the project page fetches the unfetched clips one at a time, and Stop halts
const asks = stubRequests().filter((a) => a.manifest === "editor-fetch-many-fixture");
expect(asks.map((a) => a.clipId)).toEqual(["f01"]);
// f01 is 0–3 s with the route's default ±20 s of pad.
- expect(existsSync(path.join(clipsDir("vid2"), "0.00-23.00.mp4"))).toBe(true);
+ expect(existsSync(path.join(clipsDir("vid4"), "0.00-23.00.mp4"))).toBe(true);
// AND f02 IS NOW FETCHED TOO, without anybody asking for it. A window is
// deliberately generous and the predicate is containment, so one fetch is