Archilyzer · Source

archilyzer

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

commit 662f950e1de1bcbfd59cf9e2e9152b1e1fd298f7
parent a4f77c30bee93e9a25ede8b5082516408813b494
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date:   Mon, 21 Sep 2026 13:32:12 -0400

plans: curated tags — no schema bump, site layer is presentation-only, four ops

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

Diffstat:
Mplans/curated-tags.md | 16++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/plans/curated-tags.md b/plans/curated-tags.md @@ -21,7 +21,9 @@ with her in chat. (re-evaluated at index build; operator pins/suppresses exceptions), by **import from a umtool project**. 2. **One tag per kind**: `eva-collab` (on mic), `eva-in-chat`, `eva-topic`; filter is OR across chips. 3. **Vocabulary both corpus-wide and per site, like aliases** — corpus file authoritative for - definitions AND assignments; the site file is presentation (relabel/hide/order/colour) + site-only rules. + definitions AND assignments; the site file is presentation ONLY (relabel/hide/order/colour). **Amended + 2026-09-21 during S1**: a site-layer rule can never tag a record — a record is shared by every site carrying + its channel — so rules bind only from the corpus file and the site tab offers no rule editor. 4. **Surfaces — all four**: export lists (channel + all-videos), export search, MCP filter, editor lists. 5. **Universal + flexible, three writers**: free-form tag ids for any subject, optional `group` so chips read "Eva: Collab · In chat · Discussed"; operator UI, `pnpm ops` (agents; MCP stays read-only per @@ -90,7 +92,8 @@ scope and date range are applied before compiling; each kind compiles once per b video from the `cues`/`subs` sub-DBs (no disk re-read). Returns the changed `indexKey`s, which are unioned into the dirty-channel set so transcript/subs/summaries pages rewrite — `common/lib/channelSignature.ts` hashes only mtimes (FACTS ~:203-207), so this explicit dirtying is what keeps compose from skipping them. - `SCHEMA_VERSION` 13 → 14 (`:143`). Build log prints `curated tags: rules <hash8> (changed), re-derived N`. + `SCHEMA_VERSION` stays **13** (amended during S1: an absent `curatedRulesHash` can never match, so the first + build re-derives every record from LMDB in ~80 s; a bump would re-read 76k video dirs for the same state). Build log prints `curated tags: rules <hash8> (changed), re-derived N`. - **Counts**: while streaming `sums` into per-site summaries pages (`:1712`) accumulate per-tag totals and per-channel breakdown → `tag-counts.json` in `siteIndexDir(paths, siteId)` (`common/lib/site.ts:138`). - **Compose** (`common/bin/compose-site.ts:744-753`, beside aliases): `effectiveSiteTags(paths, siteId)` + @@ -109,16 +112,16 @@ scope and date range are applied before compiling; each kind compiles once per b `export/e2e/fixtures/data.ts` emits `curatedTags` on two summaries and a `/tags.json` fixture. Merge to main immediately — S2 and S3 branch from it. 2. `common/lib/curatedTagsStore.ts` (mirror `common/lib/aliasesStore.ts`): `readGlobalTags/writeGlobalTags/ - readSiteTags/writeSiteTags/effectiveSiteTags` + **`applyTagAssignments(paths, {op: add|remove|replace, tag, + readSiteTags/writeSiteTags/effectiveSiteTags` + **`applyTagAssignments(paths, {op: add|remove|suppress|unsuppress, tag, videos, source, at})`**; `paths.globalTagsFile` (`common/lib/paths.ts:105,219`), `siteTagsFile` (`common/lib/site.ts:132`); tests: sanitize, layering, both-lists conflict, provenance. 3. `curatedTagsIndex.ts` + `buildIndex.ts` hook at `:697`, meta hashes, `reapplyCuratedTags`, - `SCHEMA_VERSION` 14, per-site counts at `:1712`; `toDisplaySummary`. Measure rule cost on legal-mindset + NO schema bump (see Derivation), per-site counts at `:1712`; `toDisplaySummary`. Measure rule cost on legal-mindset (478 chat streams) and record it in FACTS. 4. Contract + compose: `contract.ts` spec 4 + `ROOT_FILES`; `corpus.ts:204,:320`; `compose-site.ts:744-753` writes `/tags.json`; `corpus.test.ts`. 5. `plans/FACTS.md` (the three meanings of "tags" in the naming-hazards table; chat-author prefix contract; - the two meta hashes; SCHEMA_VERSION 14) + `AGENTS.md` (tags.json is curated data; never hand-edit). + the two meta hashes; SCHEMA_VERSION unchanged) + `AGENTS.md` (tags.json is curated data; never hand-edit). ### S2 — export UI + MCP (branch `tags/site`, needs only S1.1) 6. `common/lib/search/evalTree.ts`: `curatedTags?` on `SearchFilters` (`:311`) and `FilterableRecord` @@ -146,7 +149,8 @@ scope and date range are applied before compiling; each kind compiles once per b `previewTagRuleAction` = dry-run `evaluateTagRules` over LMDB `sums/cues/subs`, listing title/date/channel with Pin all / Pin / Unpin, `applyTagAssignmentsAction`) — pattern `editor/app/sites/[siteId]/aliases/`. Nav entry (twelve → thirteen; `editor/scripts/measure-nav.mjs`). -13. Per-site overlay tab `editor/app/sites/[siteId]/tags/page.tsx` (presentation fields + site-only rules). +13. Per-site overlay tab `editor/app/sites/[siteId]/tags/page.tsx` (presentation fields only — no rule editor, + see decision 3 as amended). 14. Video page `videos/[id]/components/TagsPanel.tsx` beside `OperationPanel` (`page.tsx:251`); `toggleVideoTagAction` in `videoActions.ts` (shows each tag's provenance). 15. `VideoListPane.tsx`: `tag`/`untag` in `BULK_ACTION_OPTIONS` (`:38-49`) with a tag picker via