Archilyzer · Source

archilyzer

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

commit 33d71745bac4ad981b724fe0c7bb123c8895221a
parent 6c507ab1b60be2cced0c5ce8b76b9ac724fd5c20
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date:   Tue,  8 Sep 2026 02:08:48 -0400

plans: the Phase 1 record counts to the tip, and STATE.md names the two traps

The totals were 62a1de4..b64af6e, so they omitted 1b519f3 and the band-doubling
fix 9f2bbf9 that the same section describes: 62a1de4..6c507ab is 35 commits,
109 files, 9,956 insertions and 7,341 deletions (102 / 7,510 / 7,199 outside
plans/). The commit count follows in STATE.md, FACTS.md and one-core.md, and
operations/lanes.ts was 368 lines, not 370.

STATE.md now names the deletion condition beside the gates: the four legacy
pause fields go once the live settings.json carries all four held keys, and
backfill.held must then default TRUE, because sanitizeBackfill defaults
enabled: false and legacyGateHeld reads it inverted.

Prose: the transcription lane draws 2,754 today, not 882 — replaceAutoSubs is
true on the live policy and the opt-in bucket rides the tail of the draw; the
entry is the policy-free list. EXTERNAL_BAND_IDS is two because it is derived,
not because it is pinned. Two traps added to the 1.5 record: sanitizeMatch will
accept match.bucket: "transcription", and a regenerated snapshot carries each
bucket-lane id twice — trivial here, playlist-sized on a fresh channel.

One comment-only code edit, no behaviour: ChannelWork.operations still argued
that an operation id in `buckets` would be claimed by a catch-all that never
asked for it, which is now the deliberate design for the two bucket lanes.

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

Diffstat:
Mcommon/jobs/autoQueuePolicy.ts | 18++++++++++++++----
Mplans/FACTS.md | 2+-
Mplans/STATE.md | 16+++++++++++++---
Mplans/one-core-phase-1.md | 48++++++++++++++++++++++++++++++++++--------------
Mplans/one-core.md | 4++--
5 files changed, 64 insertions(+), 24 deletions(-)

diff --git a/common/jobs/autoQueuePolicy.ts b/common/jobs/autoQueuePolicy.ts @@ -285,10 +285,20 @@ export type ChannelWork = { // bucket name -> available video ids in that bucket buckets: Record<string, string[]>; // operation id -> reachable video ids for that operation, from - // snapshot.backfill[op].ids. A SEPARATE map rather than more entries in - // `buckets`, because `buckets` is walked as a priority-ordered union by every - // leaf that names no bucket — an operation folded in there would be claimed - // by a transcription catch-all that never meant to ask for it. + // snapshot.backfill[op].ids. A SEPARATE map for the OPERATION lanes, because + // it is a separate CLAIM SPACE: buildPendingByLeaf claims a video as + // `${operation}\0${id}`, which is what lets one video be pending for + // diarization AND for attribution-diarized at the same time. Folding those + // into `buckets` would collapse them into one claim and silently drop the + // second operation's work. + // + // THE BUCKET LANES DELIBERATELY GO THE OTHER WAY (slice 1.5). Their work list + // is also `snapshot.backfill[op].ids`, but it is projected into `buckets` + // under the operation's id, because on those lanes the operation and the + // bucket union are the SAME work — there is no second operation to keep + // apart, and sharing the bucket claim space is what stops a catch-all leaf + // re-claiming a video an explicit retry-bucket leaf already took. See + // defaultDrawsForPolicy and controller/autoRunner.ts buildChannelWork. // // Optional: every projection written before operations existed omits it, and // a leaf naming an operation simply finds nothing. diff --git a/plans/FACTS.md b/plans/FACTS.md @@ -3379,7 +3379,7 @@ still read `true/false/false/false` through `isGateHeld`. The whole-phase anchors. The slice-1.4 entry above stays as the detail on where a lane's pause lives; this is everything else a session needs before touching dispatch. Branch -`one-core/phase-1`, `7f294df` → head, 33 commits, unmerged, off Phase 0's `af2a360`. The +`one-core/phase-1`, `7f294df` → `81a663f` plus a docs commit, 36 commits, unmerged, off Phase 0's `af2a360`. The record with every divergence is `plans/one-core-phase-1.md`. **The model in one sentence:** the LANE is the dispatch noun (a queue key, a policy tree, a diff --git a/plans/STATE.md b/plans/STATE.md @@ -4,7 +4,7 @@ The working memory for the local-AI derived-corpus work. Rewritten at the end of session, before context is cleared. See [`README.md`](README.md) for the protocol. **Last updated:** 2026-09-08 — **one-core Phase 1 shipped** on branch `one-core/phase-1` -(`7f294df` → HEAD, 33 commits, not merged): **dispatch is one scheduler, and the lane is the +(`7f294df` → `81a663f` plus a docs commit, 36 commits, not merged): **dispatch is one scheduler, and the lane is the noun.** The slice-level record — every sha range, every divergence, both operator gates — is [`one-core-phase-1.md`](one-core-phase-1.md); the umbrella is [`one-core.md`](one-core.md) and the anchors are @@ -40,7 +40,10 @@ scopes migrating into lane trees, both `enabled: false`. `snapshot.backfill[op].ids` is where all four lanes' work lives; the runner reads it and falls back to the same fold, which is the migration (nothing is regenerated). `plans/tools/phase1-worklist-check.ts` checks all 68 live snapshots read-only: **OK**, - download 9, transcription 882, zero already carrying an entry. + download 9, transcription 882, zero already carrying an entry. The 882 is the + POLICY-FREE work list; the transcription lane still draws **2,754** today, because the + live `autoQueue.transcription.replaceAutoSubs` is `true` and `defaultDrawsForPolicy` + appends `downloadedAutoSubsOnly` (1,872) at the tail of the draw. **Two operator gates are outstanding, and one of them gates a merge.** @@ -53,6 +56,11 @@ scopes migrating into lane trees, both `enabled: false`. `backfill.allowRedownload` and the channel scope. As configured today it would re-fetch audio for ~66,540 videos. The migration left the lane disabled; the tree's channel leaves are the scope from now on. +- **The four legacy pause fields go only once the live `settings.json` carries all four + `held` keys** — which happens on its first write through the editor. And when + `sanitizePolicy` finally defaults `held`, **backfill's must default `true`**: + `sanitizeBackfill` defaults `enabled: false` and `legacyGateHeld` reads that field + INVERTED, so a `held: false` default would silently un-hold the very lane Gate B fences. **BLOCKER FOR ANY EDITOR e2e IN THE PRIMARY CHECKOUT, and it is not ours.** `editor/content` is an untracked **symlink to `/home/user/Projects/recipe-content`** (made @@ -415,7 +423,9 @@ nothing renders. 14. ~~**The transcode operation**~~ — **REMOVED 2026-08-30**, `904f1a9` → `f717a36`. Plan: [`editor-transcode-removed.md`](editor-transcode-removed.md); census in FACTS "Verified 2026-08-30 — transcode: what it was, what stayed". The band question is closed by - deletion; `EXTERNAL_BAND_IDS` is two for good. + deletion; `EXTERNAL_BAND_IDS` is two — and since one-core 1.5 it is two because it is + `EXTERNAL_OPERATIONS.map(o => o.id)`, so a third external pipeline would join the rail + by being declared rather than by editing that constant. **Recommended next (editor IA).** The UI slices are done and the transcode band is no longer a candidate. What is left is **Phase 6** and **slice 9**, which is gated on the sweep running in diff --git a/plans/one-core-phase-1.md b/plans/one-core-phase-1.md @@ -1351,14 +1351,17 @@ OK and is never sorted. **Live impact zero — `partialDownloads` sums to 0 across all 68 channels** — which is precisely why nothing but a test would have caught it, and there is one. -- **The transcription total is 882, not the 2,754 the brief expected.** 2,754 is - the union with `replaceAutoSubs` ON: 881 `downloadedNoTranscript` + 1,872 - `downloadedAutoSubsOnly` + 1. The DEFAULT union is `downloadedNoTranscript` ∪ - `failedListed` = 881 + 25, and **24 of those 25 are already in the first list**, - so the deduped answer is 882. The opt-in auto-captions bucket is a policy - switch, not a corpus fact, and folding it into a snapshot entry would make - `replaceAutoSubs` a property of the archive; it enters where it always has, at - the TAIL of `defaultDrawsForPolicy`. +- **The transcription ENTRY is 882, not the 2,754 the brief expected — and the + transcription LANE still draws 2,754 today.** Both numbers are right and they + are different measures. The entry is the policy-free work list: + `downloadedNoTranscript` ∪ `failedListed` = 881 + 25, and **24 of those 25 are + already in the first list**, so the deduped answer is 882. The live + `autoQueue.transcription.replaceAutoSubs` is **`true`**, so + `defaultDrawsForPolicy` appends `downloadedAutoSubsOnly` (1,872) at the TAIL of + the draw and the lane's actual pending set is 2,754 — which is exactly what the + numbers script has always printed and still prints. Folding the opt-in bucket + into a snapshot entry would make `replaceAutoSubs` a property of the ARCHIVE + rather than of the policy, which is why it enters where it always has. - **The lane's work list is projected into `ChannelWork.buckets`, under the operation's id — not into `.operations`.** This is the change that makes "no number moves" true rather than merely intended. `buildPendingByLeaf` claims a @@ -1456,13 +1459,27 @@ than as a re-reading of numbers copied out of an older build. it predates 1.4 and 1.4 did not move it — and named here rather than fixed, because the fix is a decision about what the /jobs strip means when the pool and the file disagree, not a rename. +- **`sanitizeMatch` accepts any bucket string**, so a hand-edited leaf carrying + `match.bucket: "transcription"` (or `"download"`) now draws that lane's WHOLE + work list instead of finding nothing. Unreachable from the UI — the bucket + select offers only `selectableBucketsForKind`, which does not include the + operation ids — and harmless where it is reachable, since the list is what a + bucket-less leaf on that lane draws anyway. Named because "a leaf naming + anything else finds no list" stopped being literally true for two strings. +- **A regenerated snapshot carries each bucket-lane id twice** — once spread + across its buckets, once merged into `backfill.<lane>.ids`. Trivial on this + corpus (9 and 882 ids) and deliberate: the whole point is one array per lane. + It is not trivial for a FRESHLY ADDED channel, whose `undownloadedIds` is the + entire playlist, so a 30,000-video channel's first snapshot grows by 30,000 + duplicated ids. If that ever bites, the fix is for the runner to fold rather + than for the entry to shrink — the entry is what makes the four lanes uniform. - The 1.4 traps above all still stand, including the two greps (`backfill.enabled` needs its own). ## Phase 1, as shipped -`7f294df` → `2133d94` plus this commit, **33 commits on `one-core/phase-1`** off -`af2a360` (Phase 0's head). Five slices: +`7f294df` → `81a663f` plus this docs commit, **35 commits on `one-core/phase-1`** +off `af2a360` (Phase 0's head) — 36 with this one. Five slices: | slice | range | what it did | |---|---|---| @@ -1470,10 +1487,13 @@ than as a re-reading of numbers copied out of an older build. | 1.2 | `83954f1` → `0438a72` | one `operationBatch.ts`; the runner runs operations on all four lanes | | 1.3 | `253826b` → `451c454` | the two sweeps and the arbiter retire; ten settings fields migrate then go | | 1.4 | `0040e39` → `1a4524b` | pause is `autoQueue[lane].held`, with the four legacy fields as a read-time fallback | -| 1.5 | `4cb226e` → this commit | one work list per lane in the snapshot | +| 1.5 | `4cb226e` → `81a663f` | one work list per lane in the snapshot | -**107 files, 9,357 insertions, 7,284 deletions** (101 files / 7,441 / 7,198 -outside `plans/`). **Eighteen files deleted, 5,273 lines**: `backfillBatch.ts` +**109 files, 9,956 insertions, 7,341 deletions** (102 files / 7,510 / 7,199 +outside `plans/`), measured `af2a360..81a663f` — the tip, not `2133d94`, so the +two follow-ups this section describes (`a7922a3` and the band-doubling fix +`d8754d2`) are counted. This docs commit adds one more file's worth of prose to +the first figure and nothing to the second. **Eighteen files deleted, 5,273 lines**: `backfillBatch.ts` 937, `digestBatch.ts` 647, `backfillSweep.ts` 517, `SweepLane.tsx` 422, `arbiter.ts` 416, `digestSweep.ts` 368, `sweepPreview.test.ts` 321, `SweepPlan.tsx` 264, `backfillBatch.test.ts` 231 (renamed to @@ -1482,7 +1502,7 @@ outside `plans/`). **Eighteen files deleted, 5,273 lines**: `backfillBatch.ts` `OrderReach.tsx` 133, `ArbiterBar.tsx` 113, `arbiterWork.ts` 67, `resume-backfill-sweep/route.ts` 35. Plus, in place: three job kinds, two boot resume hooks, ten settings fields with their sanitizers and forms, four sweep -server actions, the arbiter's two actions, and `operations/lanes.ts` at 370 → 131. +server actions, the arbiter's two actions, and `operations/lanes.ts` at 368 → 131. **Tests: common 876 → 908 (+32), mcp 205 → 205, e2e 511 → 515.** `architecture.test.ts`'s allow-list **shrank by one** (`lib/sweepPlan.ts -> diff --git a/plans/one-core.md b/plans/one-core.md @@ -183,8 +183,8 @@ Makes the later deletions safe and cheap. ### Phase 1 — Dispatch: one scheduler (5 slices) -**SHIPPED 2026-09-08** on branch `one-core/phase-1` (`7f294df` → head, 33 commits, -unmerged, off Phase 0's `af2a360`), all five slices. The record — every slice's sha range, +**SHIPPED 2026-09-08** on branch `one-core/phase-1` (`7f294df` → `81a663f` plus a docs +commit, 36 commits, unmerged, off Phase 0's `af2a360`), all five slices. The record — every slice's sha range, every divergence, both operator gates and the totals — is [`one-core-phase-1.md`](one-core-phase-1.md); the anchors are [`FACTS.md`](FACTS.md#one-core-phase-1-verified-2026-09-08). **No live number moved**, and