Archilyzer · Source

archilyzer

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

commit 0d8a6f276d4faefb5a2f7b0b8d9fdbea0cc223fb
parent 798301c505b49a6e673161b2dc2674d15c3a503a
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date:   Sat, 12 Sep 2026 02:48:58 -0400

plans: the S2b record — what the cue guard refuses, and the tsx list for Phase 5

Appended at the end of the Record section, so S2a and S3 can append theirs
without a conflict.

Carries the gate numbers (tsc clean, scripts 78/1 from 71/1, common 1077, cues
21/1), the Phase 5 tsx change list with three of the brief's paths corrected by
grep, the four divergences, and the umtool e2e result: 129 passed / 40 failed /
2 skipped on the branch AND the same 40 names at the base commit, so the suite
moved by nothing. The 40 are the heavy song fixtures this machine does not have.

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

Diffstat:
Mplans/one-core-phase-2.md | 125+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 125 insertions(+), 0 deletions(-)

diff --git a/plans/one-core-phase-2.md b/plans/one-core-phase-2.md @@ -382,3 +382,128 @@ client chunk. The prerender is the only step that fails, and it fails at base. `plans/tools/jeralyzer-corpus-2026-09-12.json` was not re-fetched; the live diff is S3's gate, after the search pipeline lands. + +### S2b — shipped 2026-09-12 + +Branch `one-core/phase-2-s2b`, off `7f86aef` (the `integrate/2026-09-storage-priority` +tip with S1 merged). Two commits, `745677f` → `RECSHA` (this note), unmerged. Nothing +outside `umtool/report-to-video/` moved except one comment in `common/lib/channelMedia.ts` +and this note. **No URL shape, no `corpus.json` byte, no CONTRACT version, no +architecture allow-list entry.** + +| commit | what | +|---|---| +| `745677f` | `checkChannelReachable` in `cues.mjs` + 7 test cases; the cross-reference comment | +| `RECSHA` | this note | + +#### What the guard actually refuses, and what it deliberately does not + +`fromLocal` now calls `checkChannelReachable(slug)` before reading the cue file. It +replicates `inspectChannelMedia` / `assertChannelMediaReachable`'s statuses in plain +`.mjs` — `dataDir` read straight out of `config.json`, `.relocating.json` marker, +`lstat` on `data/`, `readlink` compared against the configured target, `stat` on the +deep `<root>/<slug>/data` path — and throws a `CueLookupError` naming the slug and the +path. A `CueLookupError` carries no `code`, so `load`'s `ENOENT`/`ENOTDIR` fallback +rethrows it instead of reaching for the archive; the test asserts **zero** fetches. +Checked once per channel per run, memoised as a promise so a rejection replays for +every clip of that channel. + +Throws: a symlinked `data/` whose target is missing (the unmounted drive — the bug), +or is not a directory, or disagrees with `config.json`; a `dataDir` in `config.json` +with no `data/` at all; a real `data/` directory with a `dataDir` recorded anyway; a +`.relocating.json` marker. + +Does **not** throw, and this is the deliberate line: a channel whose `data/` is simply +absent with no configured target. That covers both "no `channels/` dir at all" (a clone +with no corpus — a first-class way to use this repo) and "a corpus that does not mirror +this channel", and it is exactly what the editor's `inspectChannelMedia` calls +`in-place` and `assertChannelMediaReachable` passes. Deciding otherwise would have hard- +failed every clip of a non-mirrored channel for any operator who has a corpus at all, +and it would have made the twin a near-copy rather than a copy. A reachable channel that +merely lacks THIS video still falls through to HTTP, as before — two tests pin both. + +`--cue-source local` is untouched: it still refuses to fall back, with its own message, +and a test pins that the guard does not swallow it. `pageFileName` / `pageUrlFrom` +untouched. + +`common/lib/channelMedia.ts` gains a comment above `assertChannelMediaReachable` +pointing at the copy and saying why it is a copy (umtool's bins run under bare node). +The function is not changed. + +#### The `tsx` change list for Phase 5 + +Every entry re-grepped at `745677f`; three paths in the S2b brief were wrong and are +corrected here. + +| what | where | note | +|---|---|---| +| six shebangs | `umtool/report-to-video/{build-video,check-availability,compose-chrome,render-cards,resolve-windows,verify-build}.mjs:1` | all `#!/usr/bin/env node`. 40 MORE node shebangs live under `umtool/` (`bin/umtool.mjs`, `e2e/fixtures/make-fixture.mjs`, 38 under `song/`) — the "six" is report-to-video only | +| six spawn argv | `umtool/lib/report/driver.mjs:70,93,99,105,140,167` | **not** `umtool/report-to-video/driver.mjs` — there is no such file | +| one printed hint | `umtool/bin/umtool.mjs:516` | **not** `umtool/umtool.mjs`; prints `node umtool/report-to-video/resolve-windows.mjs …` | +| one `execFileSync` | `umtool/e2e/clip-bench.spec.ts:145` (script path on `:146`) | | +| the test runner | root `package.json:24` — `test:scripts` = `node --test scripts/*.test.mjs umtool/report-to-video/*.test.mjs` | | +| the missing deps | `umtool/report-to-video/package.json` | it has NO `dependencies` and no `devDependencies` at all, so `tsx` has nothing to be declared in. `umtool/package.json` does have `dependencies` — the brief named the wrong file | + +Not made here, per the brief. + +#### One thing this slice did not close + +`fromLocal` is not the only place that joins `channels/<slug>/data/<id>/transcript.cues.json` +by hand and treats a failure as "no cues": `umtool/report-to-video/check-availability.mjs:54` +(`cueMeta`) and `umtool/lib/projects/report.mjs:124` (`cuePathFor`) do the same, and an +unmounted relocated channel still reads to them as an absent file. Neither answers a cue +WINDOW — they feed availability rows and the project index — so neither can cut a clip in +the wrong place, which is why they are out of this slice. They want the same guard when +umtool's local-corpus access is next touched. + +#### Gates + +- `pnpm -r exec tsc --noEmit` — **clean** in all eight packages. +- `pnpm test:scripts` — **78 passed / 1 skipped** (baseline 71/1; +7, the new cases). + This is where the cues tests are collected; `umtool/package.json` has **no `test` + script** of its own (only `dev`/`build`/`start`/`typecheck`/`e2e`), which is the one + divergence from the brief's "umtool's own test command". +- `pnpm --filter yt-dlp-transcript-common test` — **1077 passed / 0 failed**, unchanged. +- `node --test umtool/report-to-video/cues.test.mjs` alone — **21 passed / 1 skipped** + (the LIVE network case is the skip, as before). +- umtool e2e, behind the queue lock from worktree #11 (`UMTOOL_E2E_PORT=4151`, + via `pnpm wt run`), with `SONG_DIR=/home/user/reports/quartering-uh-song/data`: + **129 passed / 40 failed / 2 skipped** — and the SAME numbers with the SAME 40 + test names at the base commit `7f86aef`, diffed line for line (`git switch + --detach 7f86aef` in this worktree, same command, same env). This slice moves + nothing in that suite. The 40 are environmental and were already recorded: + the heavy song fixtures are not on this machine + (`$SONG_DIR/{wav48,asr,media}` do not exist, only `cand2/` does, and + `make-fixture.mjs` symlinks those three only `if (existsSync)`), so every spec + that needs audio, ASR or the face detector fails — `find` 11, `triage` 9, + `faces` 6, `usage` 5, `browse` 3, `undo` 3, `deck` 2, `projects` 1, with + `no media for v1`, `detect v1@60.00 -> 404` and a missing `every note (N)` + table. What DID run, and passes on both: the whole of `build.spec.ts`, + `clip-bench.spec.ts` (which shells `resolve-windows.mjs` with `CHANNELS_DIR` + pointed at the fixture corpus — the one spec that exercises the changed path + end to end) and `report-longform.spec.ts`. + + +Not run, and deliberately: the export `next build`, the mcp bench, the compose-site +fixture diff and the export/hub/2origin e2e suites that §Verification asks of every +slice. Nothing in S2b is reachable from any of them — the diff is one `.mjs` file +under `umtool/`, its test file, and a comment. `pnpm -r exec tsc --noEmit` covers the +one TypeScript file touched. + +#### Divergences from the S2b brief + +1. **`umtool` has no `test` script.** The brief said to run "umtool's own test + command"; `umtool/package.json` has `dev`, `build`, `start`, `typecheck` and `e2e` + only. The cues tests are collected by the ROOT `test:scripts`, which is the number + quoted above, and were also run directly with `node --test`. +2. **Three paths in the Phase 5 `tsx` list were wrong** — `driver.mjs`, + `umtool.mjs` and the package missing `dependencies`. Corrected in the table above, + each re-grepped. +3. **A missing channel dir does not throw.** The brief's "missing, or `dataDir` set but + not mounted" reads as if an absent channel dir should also fail. It does not, for the + reason given above: the editor's twin calls that `in-place`, and throwing would break + the archive-only workflow this repo advertises. The case that motivated the slice — + a relocated channel whose drive is gone — throws. +4. **Test fixtures use `tmpdir()`, not the agent scratch dir.** A test that hard-coded a + job scratch path would not survive the job. `CUES_TEST_DIR` overrides the root, and + that is what the scratch-dir runs used.