Archilyzer · Source

archilyzer

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

commit b0699fcd3b9f798fde1c270ef5daa838555fe045
parent 2eeb674586b528135b7674888f973c0e56bcf4fb
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date:   Thu, 24 Sep 2026 19:45:42 -0400

plans: slice 3b record — the video page's chore cards, one module each

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Diffstat:
Meditor/CHANGELOG.md | 1+
Mplans/one-core-phase-3.md | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 90 insertions(+), 0 deletions(-)

diff --git a/editor/CHANGELOG.md b/editor/CHANGELOG.md @@ -1,6 +1,7 @@ # Changelog ## [Unreleased] +- **The video page's chore cards are one file each.** Redownload, Transcode, Transcribe, Transcript source, Mark untranscribable, Source video, Fetched windows, Archive media, Truncated check, Files, the Danger zone, the availability history, the download-outcome badge and the two truncation banners each moved out of one 1,839-line `VideoPanel.tsx` into their own module under `videos/[id]/components/cards/`; `VideoPanel` is now just their order and when each shows, and `lib/videoChoreCards.ts` lists them — with why each is a chore and not an operation — beside the registry's operation panels. Nothing on the page changed: same cards, same order, same labels. - **Every channel table and every job-in-flight line is now drawn one way.** The /channels rack, the dashboard's Channels table and the work tables on the operation pages and /cleanup are one table with a column set per page, over one channel row built on the server (which no longer ships a channel's config to the browser); the dashboard's "Needs work" seed is computed by the same code the widget endpoint serves. On the jobs side, /jobs rows, the "Active jobs" cards on channel/video/operation pages, the monitor widget's Active jobs strip and the operations board's "In flight" list are one job row in three sizes, with one rule for which buttons (Retry / Reorder / Drain / Cancel / Force-release) a job gets. **What you might notice:** a work table's report column reads "stale"/"missing" like the rack's instead of a date; the dashboard's Sync button is the rack's; a lane line on /jobs offers Force-release while its runner is running; widget job lines show who asked for the job; an in-flight download on the operations board links to its job page. Nothing a count says moved. - **`site.json`, each channel's `config.json` and the per-video sidecars now have one schema each, and the two config files have generated key tables.** **`SITE.md`** and **`CHANNEL.md`** (new, repo root) list every key with its default and meaning, generated by `common/bin/file-schemas-docs.ts` and checked by a test. Nothing an operator has configured reads or saves differently: every live `site.json` and `config.json`, and a 1,763-file sample of sidecars, read and write back byte-for-byte as before. **Fixed:** a social-channel fetch no longer undoes Configure-form edits made while it was running (it used to write back the whole config it read when it started). Every change to a channel's config now re-reads the file at the moment it saves and changes only its own fields, so a sync stamping its time and a form save made at the same moment both land. Two writes to the same file from the editor no longer share one temporary file. - **`settings.json` has one schema and one writer, and its key table is generated.** Every key, its default, its clamp and its documentation is now one zod schema (`common/lib/settingsSchema.ts`); `getSettings`/`writeSettings` both parse through it, and every settings form saves through one helper (`editor/app/settings/saveSettings.ts`) that merges only what the form changed. **`SETTINGS.md`** (new, repo root) lists every key with its default and what it does, and `settings.json.example` is now the full default object — both generated by `common/bin/settings-example.ts` and checked by a test, so neither can drift. Nothing an operator has configured reads differently. **Fixed:** adding or editing a storage location on `/storage` no longer erases the record of which location the saved-video store is on (`storage.savedVideosLocationId`). diff --git a/plans/one-core-phase-3.md b/plans/one-core-phase-3.md @@ -703,6 +703,95 @@ undated candidates`, twice — once per Next module graph). IO pressure at boot `full avg10 7.26` (58–66 % at the last rollout, when a remux was saturating the platter), which is the difference from the 25 minutes release 2 paid. +### Slice 3b, as shipped — the video page's chore cards, one module each (2026-09-24) + +Branch `one-core/phase-3-s3b` off `main` `4130aca1`, one code commit and this record. +Main is merged in once slices P and W are on it; the post-merge gates are added below then. + +**What, and why it is smaller than the inventory said.** Both premises of the 3b inventory +above were stale. + +- *Channel pipeline — nothing to do, and nothing was done.* The nine files under + `channels/[slug]/components/stages/` (3,866 lines) hold no duplicated status logic. + `computeStageStatuses` (`common/views/pipeline/stageStatus.ts:192`) and `computeChannelFlow` + (`channelFlow.ts:220`) are the single fold, each called once, in `channels/[slug]/page.tsx:256` + and `:308`; every stage card takes derived id-lists and sums as props and keeps only form + state. The bookend chores are hand-listed once, `stageOrder` at `page.tsx:278-286` around + `GROUP_STAGES` (`stageStatus.ts:53-106`). The stage half of 3b was already satisfied; no + stage file is touched. +- *Video page — the registry split already existed.* `videoOperationPanels.ts` + + `OperationPanel.tsx` render digest / diarization / attribution after `<VideoPanel>` + (`videos/[id]/page.tsx:254-266`). What was still inline in `VideoPanel.tsx` (1,839 lines) + was ~16 card bodies for video CHORES, which no registry entry owns. 3b split those, and + only those, one module per card, behaviour-free. + +| sha | what | +|---|---| +| `315cec1f` | `video page: one module per chore card` — 15 card modules + `Heading.tsx` + `videoFiles.ts` under `videos/[id]/components/cards/`; `VideoNavStrip.tsx` and `PipelineStatusStrip.tsx` beside `VideoPanel`; `VideoPanel.tsx` 1,839 → 455 (the assembly); `lib/videoChoreCards.ts` (+test) | +| (this commit) | this record, changelog | + +**The move.** Each function moved verbatim with its state hooks, its imports and the +server-action import(s) it calls — the 13 names from `../videoActions` now sit in the card +that uses them (`downloadVideoPipelineAction` in two: `RedownloadSection` and +`ShortAudioBanner`). Children stay with their only caller: `PersistedSourceVideo` in +`SourceVideoSection.tsx`, `DeleteFileButton` in `FilesList.tsx`. Two helpers shared by two +cards got small modules: `cards/Heading.tsx` (both per-file rows) and `cards/videoFiles.ts` +(`VideoFile`, `WHISPER_FILENAME`, `CANONICAL_VTT`, the extension predicates, `mediaUrl`). +`VideoPanel` re-exports `VideoFile` and `FetchedWindow`, so neither page's import changed. +The only edits inside moved bodies are four comments whose "above"/"below"/":360" pointed at +a neighbour that is now in another file. `videoActions.ts` is untouched (slice W owns it). +`git show --numstat`: `VideoPanel.tsx` +40 −1,424; cards + strips +1,522 (the 1,366 moved +lines plus each module's directive and imports); `videoChoreCards.ts` + test +190. + +**Why 455 lines, not ~300.** The `VideoPanel()` function itself — gating booleans, summaries, +and the fifteen cards' `PipelineStageCard` wrappers — is 360 lines, and keeping ORDER and +gating exactly was the rule. Driving the JSX from the hand-list would shorten it and was +allowed, but every card's gate and props differ, so the literal reads better; the list's test +pins the two together instead. + +**`lib/videoChoreCards.ts`** — the video page's twin of the channel page's bookends: fifteen +rows `{id, component, shown, why}` in render order (download-outcome, incomplete-transcript, +short-audio, availability-history, download, transcode, transcribe, transcript-source, +mark-untranscribable, source-video-persistence, fetched-windows, archive-media, +truncated-check, files, danger), each saying why it is a chore and not an operation. The +download and transcribe rows are the EXTERNAL operations' per-video run surface, which +`videoOperations.ts` deliberately leaves out of its reader. Not folded into the registry. Not +listed: the nav strip, the status strip, the umtool link and the one-line "media archived" +status. `videoChoreCards.test.ts` reads `VideoPanel.tsx` as text (a node test cannot load +client components) and pins that the cards it renders, in order, and the cards it imports +from `./cards/`, are exactly the list's. + +**Labels.** `$T/s3b-labels.py` extracts every `aria-label` (literal, template, and both arms +of a conditional), `"aria-label":` spread, `role`, `label`/`buttonLabel`/`runningLabel`/ +`actionLabel`/`title`/`id` literal and every `…stage summary…`/`for ${x}` template. Over the +old `VideoPanel.tsx` and over the new tree (`VideoPanel.tsx`, the two strips, `cards/*`): +126 entries each, sorted, **identical — md5 `3f89e5c1c9f79ad1a04ceea4568f0500` both**. + +**Gates.** tsc (`pnpm -r --no-bail --workspace-concurrency=1 exec tsc --noEmit`) clean at +`315cec1f`. common **1723/1723** (unchanged — no common file touched); editor unit **67 → 70** +(+3 `videoChoreCards.test.ts`); `test:scripts` 156 pass + 1 skip of 157. Builds: editor +`next build` exit 0, route table lists `ƒ /api/view/[name]`; export `next build` exit 0. +**e2e** (run 1, at `315cec1f`, from the worktree root, detached, ports 3311/3310): the 19 +specs named in the slice prompt, all present — attribution, auto-report-refresh, +channel-storage, cleanup-holds, digest, do-not-clean, download-format-guard, fetch-window, +incomplete-transcript, reconcile, reconstruct-download-url, saved-videos, storage-locations, +tags, transcript-source, truncated-check, undownloaded, video-page, whisper-video — +**108 passed, 0 failed, exit 0, 9.8 min** (16 min wall, the rest behind the queue lock), first +run, nothing re-run. +**Numbers tool: none for this slice** — no payload, view or file on disk changes; the label +diff above is the equivalent check. + +**Found and left.** +- `VideoNavStrip`'s prop type declares a `umtoolUrl` it never reads (the umtool link is drawn + by `VideoPanel`) — moved as-is. +- `pnpm --filter export run build` runs `build:data` first, which writes a fresh `index.mdb` + under the worktree's own (absent) `transcripts/`, then fails on `compose-site: SITE_ID env + var is required`. Harmless here (0 sites, nothing written or removed under the linked + `export/public`; the stray `transcripts/` was deleted), but it is the wrong command for a + worktree gate — `pnpm --filter export exec next build` is the one release 3 used. +- Commit trailer: `315cec1f` carries `Claude Opus 5.5 (1M context)`, the model that wrote it, + not the rules file's `Claude Fable 5.1`. + ## Next release — slice 3b and Phase 4 (inventory kept from 2026-09-23) Slices 3a and 4b shipped in the release above (2026-09-24); the slice 3b bullets and the