Archilyzer · Source

archilyzer

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

commit d788707a13fcc083287e84da4555d7833fd1cfbf
parent 5058856f248595473c880e16c1322314ab2d8e27
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date:   Thu, 24 Sep 2026 19:50:27 -0400

plans: slice P record — review fixes F1–F5

The station queues by id (and why a scan over-transcribed), the
refused-half log, the mobile panel/deck margin; the layers spec is 3/3
and its baseline ran the first two-test revision; the popover-vs-thead
tie is held by the unit test, not the spec; three cosmetic shot notes
recorded; the changelog names all five stations.

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

Diffstat:
Meditor/CHANGELOG.md | 4++--
Mplans/one-core-phase-3.md | 35++++++++++++++++++++++++++++-------
2 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/editor/CHANGELOG.md b/editor/CHANGELOG.md @@ -1,8 +1,8 @@ # Changelog ## [Unreleased] -- **Channel rows no longer scroll over a group's controls on `/channels`.** Scrolled down and to the right, the pinned Slug column of every row painted over the pinned group header and its Sync / Download / Transcribe / Digest buttons, and took the clicks. The pinned Slug cell and the group header sat at the same stacking level, and the later rows won. The rack now has one named layer order, kept in one file: the Advanced panel, then the column header, then the group header, then the pinned checkbox and Slug cells. Nothing ties any more. The screenshot audit found four more problems, fixed as well. A group header's name and buttons now stay on screen however far the columns scroll across (they used to scroll off to the left). An Advanced panel opened near the bottom or the right edge scrolls itself into view instead of being cut off. The rule above a pinned group header moves with it instead of leaving a gap the rows showed through. On a phone, the column header no longer paints over the selection bar pinned to the bottom of the screen. -- **A group's Transcribe works for YouTube channels, and it counts what it queues.** The station used to be disabled for every `youtube`-handling channel with the message "a youtube-handling channel never runs whisper". That was wrong. A YouTube video that came down with no captions is transcription work like any other, and the automatic runner already treats it that way. Transcribe now counts two kinds of video, after the usual members-only, deleted and private exclusions: downloaded videos with no transcript at all, and downloaded videos whose only transcript is YouTube's auto-captions. Pressing it queues those two kinds as the channel page does, as up to two jobs per channel on the transcription queue. Pressing it again while either job runs says *already running*. The wording names no method ("…has downloaded audio to transcribe", "…each takes minutes"). **This figure can now be higher than the Transcription band in the same rack on channels with many auto-caption-only videos.** The band counts videos with no transcript at all, while the station counts everything its button would queue. That is intended. +- **Channel rows no longer scroll over a group's controls on `/channels`.** Scrolled down and to the right, the pinned Slug column of every row painted over the pinned group header and its five station buttons (Sync, Download, Transcribe, Digest and the speaker lane), and took the clicks. The pinned Slug cell and the group header sat at the same stacking level, and the later rows won. The rack now has one named layer order, kept in one file: the Advanced panel, then the column header, then the group header, then the pinned checkbox and Slug cells. Nothing ties any more. The screenshot audit found four more problems, fixed as well. A group header's name and buttons now stay on screen however far the columns scroll across (they used to scroll off to the left). An Advanced panel opened near the bottom or the right edge scrolls itself into view instead of being cut off. The rule above a pinned group header moves with it instead of leaving a gap the rows showed through. On a phone, the column header no longer paints over the selection bar pinned to the bottom of the screen. +- **A group's Transcribe works for YouTube channels, and it counts what it queues.** The station used to be disabled for every `youtube`-handling channel with the message "a youtube-handling channel never runs whisper". That was wrong. A YouTube video that came down with no captions is transcription work like any other, and the automatic runner already treats it that way. Transcribe now counts two kinds of video, after the usual members-only, deleted and private exclusions: downloaded videos with no transcript at all, and downloaded videos whose only transcript is YouTube's auto-captions. Pressing it queues exactly those videos, by id, as the channel page does: up to two jobs per channel on the transcription queue. A video downloaded before it went private, members-only or deleted is no longer transcribed by the group button, because it was never in the figure. Pressing it again while either job runs says *already running*. The wording names no method ("…has downloaded audio to transcribe", "…each takes minutes"). **This figure can now be higher than the Transcription band in the same rack on channels with many auto-caption-only videos.** The band counts videos with no transcript at all, while the station counts everything its button would queue. That is intended. - **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 @@ -705,7 +705,7 @@ is the difference from the 25 minutes release 2 paid. ### Slice P, as shipped — /channels rack polish (2026-09-24) -Branch `one-core/phase-3-p` off `4130aca1`, nine commits (the eight below and this record), +Branch `one-core/phase-3-p` off `4130aca1`, eleven commits (the ten below and this record, amended after review), not merged — the parent merges; slice W merges after it (W folded nothing under `editor/app/channels/components`). The operator's ask: fix every table and z-index problem on /channels ("channel rows scroll OVER the group-based controls"). Also, the group Transcribe @@ -720,6 +720,8 @@ station must stop refusing youtube-handling channels with a whisper-specific sen | `53bbd482` | audit fix B: an opened Advanced panel scrolls itself into view (`nearest`) | | `476c8470` | audit fix D: the section rule is the th's inset shadow, not the `<tr>`'s collapsed border | | `6ff63cbf` | audit fix C: the scroll region is `isolate` (its own stacking context); both rack specs wait for hydration | +| `e0f731fa` | review F1/F2: the no-transcript half is queued BY ID (`transcribeBucketAction`, `downloadedNoTranscript`); the scan only with no snapshot; `KIND_FOR.transcribe` gains `whisper-bucket-downloaded-no-transcript`; a refused half is logged | +| `4f951ecc` | review F3/F5: below md an opened Advanced panel keeps a `scroll-mb-48` so it stops above the screen-pinned deck; the region comment names layers by key | **Root cause 1 — rows over the group controls.** It was a z-index TIE, broken by DOM order. The group header (`ChannelGroupHeaderRow`, `md:sticky … md:z-20`) holds the five station @@ -745,7 +747,14 @@ batch cannot cover both, so the button queues two jobs: - `whisper-all` when there are captionless videos, or when the channel has no report. Both jobs run on `TRANSCRIPTION_QUEUE`. The dedupe spans both kinds. `queued` counts channels, -and `jobIds` carries the whisper-all id when both jobs were queued. A combined job kind was +and `jobIds` carries the whisper-all id when both jobs were queued. **By id, after review:** with a snapshot, the no-transcript half is +`transcribeBucketAction` over exactly `transcribeStationIds(…).missing` +(`whisper-bucket-downloaded-no-transcript`, replayable as `downloadedNoTranscript`), not the +`whisper-all` scan. `downloadedNoTranscript` does not filter excluded ids, so a scan would also +transcribe a video downloaded before it went private: 2 on the label, 3 transcribed. The scan +remains only for a channel with no report. The dedupe now spans all three kinds, including the +channel page's own bucket job. If one half is refused while the other queues, the refusal is +logged (`console.warn`): the ok arm of `StreamActionResult` has no message field to carry it. A combined job kind was rejected: it would need a replay spec and a /jobs label, and it would mirror nothing, since the channel page runs two jobs. A social account is still ineligible (`"social account"`), and that is now the only way `notEligible` can be reached. @@ -772,16 +781,27 @@ the testid only). Fix C's before-shot is in `$T/p-shots-c-before/`. The final se | mobile-* | below md the thead never pins. The region scrolls on both axes, so `sticky top-0` pins to the region and not to the document | recorded, not fixed — the documented trade-off (`ChannelsRack.tsx:152-155`, `channels/page.tsx:332-336`) | | mobile-deck-open | the deck at the end of the scroll sits in flow after the last row and covers nothing; while scrolling, it covers what passes under it, as a pinned bar does | recorded, no defect — no padding needed | | every shot | the Next dev-tools badge at the bottom left | recorded, dev-only | +| desktop/mobile-popover-open (after) | while a panel is open, the region's scroll extent grows and a blank band shows under the last row | recorded, not fixed (see "Left") | +| mobile-deck-over-thead (after) | the region's `-mx-4` edge shows the thead checkbox and the row edge in the 16 px gutter beside the deck | recorded, not fixed — cosmetic, predates the slice | +| mobile-grouped-* | "Derived data off" wraps under the station line | recorded, not fixed — a wrap at 390 px, not a defect | +| mobile popover under the deck (review) | with the rack isolated, the deck paints over an overlapping panel, and the scroll-into-view stopped the panel under it | `4f951ecc` | | desktop/mobile-*-scrolled | the Build/Tier columns show as a sliver under the pinned slug band | recorded, no defect — columns scroll under a pinned identity column | -**The layers spec fails on the pre-fix code.** The run on `4130aca1` components plus the -testid only: the header hit-test failed at step (1), with the point inside the slug band -landing on the slug cell. The popover test failed because the last row's panel was clipped, -which became finding B. After the fixes: 4/4. +**The layers spec fails on the pre-fix code.** The run was the spec's first revision, with two +tests: the header case and a popover case on `slow-a`. It ran on the `4130aca1` components plus +the testid only. The header hit-test failed at step (1): the point inside the slug band landed +on the slug cell. The popover case failed because the last row's panel was clipped. That became +finding B. The final spec has three tests: +- the header case, with the Sync station check added by fix A; +- the popover case, moved to `rack-03`; +- a `slow-a` scroll-into-view case, added by fix B. + +After the fixes: **3/3**. The spec does NOT exercise the popover-vs-thead tie: `rack-03`'s panel +opens below the thead. That order is held by `rackLayout.test.ts`'s token check only. **Gates.** - tsc: clean after every commit. -- common: **1727** (1723 − 1 rewritten + 5 new in `channelGroupSections.test.ts`). +- common: **1727** (1723 − 1 rewritten + 5 new in `channelGroupSections.test.ts`); **1728** after review (the reviewer's walk). - editor unit (`tsx --test "app/**/*.test.ts"`): **69** (67 + 2 `rackLayout.test.ts`). - `test:scripts`: 156 + 1 skip. @@ -791,6 +811,7 @@ which became finding B. After the fixes: 4/4. - mid 2 (audit + layers): 13 passed, 2 failed. Both were clicks and measures before hydration. Fixed in the specs (`6ff63cbf`). - fix-C before-shot (isolate removed): 2/2, 0.3 min. - after (audit + layers): **15 passed, 0 failed**, 0.9 min. +- after review (`channel-groups`, `channels-rack-layers`, `channel-priority`): **19 passed, 0 failed**, 1.1 min. - full list (`$T/p-specs.txt`, 24 files, every named file present, none dropped): **146 passed, 0 failed, 0 flaky, exit 0, 11.8 min**. **Numbers.** `phase3-view-numbers.ts`, primary's `transcripts/` and `settings.json`,