Archilyzer · Source

archilyzer

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

commit b17245851c63e34ed68f24c45644d171c427717e
parent 04c88cc460f7fcde5d632d5021884e2de6c6b0f2
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date:   Fri, 11 Sep 2026 12:28:39 -0400

e2e: the first tier click seeds from the legacy trees and keeps their order

The fixture is the live shape in miniature — a hand-made lane order that
disagrees with alphabetical, which is the only way to tell a preserved order
from a re-derived one — plus no channelPriority document at all, which is
every corpus before the migration runs. One click on one row, and both
channels come back ranked in the order the stored trees had them.

The second half asserts the seed is ONCE: the trees are compiled after the
first save, so a second edit must not read them back as legacy.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

Diffstat:
Meditor/e2e/channel-priority.spec.ts | 100++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 99 insertions(+), 1 deletion(-)

diff --git a/editor/e2e/channel-priority.spec.ts b/editor/e2e/channel-priority.spec.ts @@ -1,5 +1,5 @@ import { test, expect } from "@playwright/test"; -import { readJson, resetData, writeSite } from "./helpers"; +import { readJson, resetData, writeSettings, writeSite } from "./helpers"; // THE /channels PRIORITY CONTROLS, asserted against what lands on disk. // @@ -278,3 +278,101 @@ test("a row selection focuses those channels and bulk-sets their tier", async ({ ); expect(children).toEqual(["prio-focus", "prio-low", "prio-all"]); }); + +// --- THE FIRST CLICK ON A CORPUS THAT HAS NEVER SET A PRIORITY -------------- +// +// The hazard the seed exists for (the S2/S3 review, findings 3 and 8). The +// dispatched tree is all-or-nothing on the document: the moment it says +// ANYTHING, the stored trees stop being dispatched from and compiled ones take +// over. A hand-made lane order lives ONLY in those stored trees, so the first +// click of a tier — on a corpus whose operator never ran the migration — +// would compile a tree in which nothing has a rank, and the order would be +// gone with the trees it lived in. +// +// So the writer seeds from `channelPriorityFromLegacy` when the stored +// document says nothing AND the stored trees are not already compiled. The +// fixture below is the live shape in miniature: a hand-made order that +// DISAGREES with alphabetical, which is the only way to tell a preserved order +// from a re-derived one. + +const LEGACY_ROOT = (lane: string) => ({ + id: `${lane}-root`, + mode: "strict", + children: [ + { id: `${lane}-1`, match: { type: "channel", value: "slow-b" } }, + { id: `${lane}-2`, match: { type: "channel", value: "slow-a" } }, + { id: `${lane}-all`, match: { type: "all" } }, + ], +}); + +test("the first tier click seeds from the legacy trees and keeps their order", async ({ + page, +}) => { + await resetData("two-slow-channels"); + // A hand-made order, slow-b ahead of slow-a, in both ranked lanes — and no + // channelPriority document at all, which is every corpus before the + // migration script runs. + await writeSettings({ + adminTitle: "Test Admin", + minFreeDiskGB: 0, + syncScheduler: { fullSweepIntervalMinutes: 0 }, + autoQueue: { + transcription: { root: LEGACY_ROOT("transcription") }, + download: { root: LEGACY_ROOT("download") }, + }, + }); + await page.goto(ALL); + expect((await settings()).channelPriority?.channels ?? {}).toEqual({}); + + // One click, on one channel. Everything else about the corpus is untouched. + await page.getByLabel("tier for slow-a", { exact: true }).selectOption("low"); + + await expect + .poll(async () => (await settings()).channelPriority?.channels) + .toEqual({ + // THE ORDER SURVIVED. slow-b was first in the hand-made lists and is + // rank 0; slow-a is rank 1. Re-derived from nothing — or read back out + // of a compiled tree — both channels would be unranked and the compiler + // would fall through to slug order, putting slow-a first. + "slow-b": { tier: "normal", rank: 0 }, + "slow-a": { tier: "low", rank: 1 }, + }); + + // And the click itself still landed: slow-a is in the low group. + { + const root = (await settings()).autoQueue?.download.root; + expect(root?.children.map((c) => c.id)).toEqual([ + "prio-normal", + "prio-low", + "prio-all", + ]); + expect( + root?.children + .find((c) => c.id === "prio-low") + ?.children?.map((c) => c.id), + ).toEqual(["prio-low-slow-a"]); + } + + // THE SEED IS ONCE. The trees are compiled now, so a second edit must not + // re-read them as legacy — which would rank the channels by their position + // in the compiled tree rather than by the order that produced it. + await page.reload(); + await page.getByLabel("tier for slow-a", { exact: true }).selectOption("normal"); + + await expect + .poll(async () => (await settings()).channelPriority?.channels) + .toEqual({ + "slow-b": { tier: "normal", rank: 0 }, + "slow-a": { tier: "normal", rank: 1 }, + }); + { + const normal = (await settings()).autoQueue?.download.root.children.find( + (c) => c.id === "prio-normal", + ); + // Rank order, not slug order. + expect(normal?.children?.map((c) => c.id)).toEqual([ + "prio-normal-slow-b", + "prio-normal-slow-a", + ]); + } +});