From 20a824118c09af15d6c338db4c9480ffe5cbcdb6 Mon Sep 17 00:00:00 2001 From: Christophe Besson Date: Sat, 19 Sep 2026 02:12:47 +0200 Subject: docs: cite MESHBAY_DESIGN.md and a section instead of the merged notes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The per-feature design notes were merged into docs/MESHBAY_DESIGN.md and deleted from the tree on 2026-09-11, but ~230 comments across the three packages still named them — usually written `docs/musicbay.md §3.2`, as though the file were still in docs/. A reader had to know §16 existed to resolve any of them. They now name the section directly. Every mapping comes from §16, the concordance, which already records where each old section landed: musicbay -> §9.8, mediacenter -> §9.7 for the Videos app and §6.5 where the subject is derived data, photos -> §9.9, auth-confirm -> §3.6, refactoring-search -> §9.11, invite-pairing-v1 -> §3.4, per-node-identity-v1 -> §3.2, captcha -> §7.7, chat-sender-keys -> §4.5, apps/refactor-groups -> §9.1–§9.4, desktop-client-v1 per section. Bare citations of the same documents (`draft-v6 §2.11`, `§4.8`, `§3.4`) are retargeted too: those collide with real section numbers in the design document, so leaving them would have been worse than the named form. Four cases the concordance does not cover, each decided rather than guessed: Sub-item references into documents that no longer exist — mediacenter's `§3.3 row 4`, `§3.4b/c`, `apps.md §3b` — name rows and sub-items §9.7 and §9.2 do not reproduce. The module-level citation stays; the sub-item pointer is dropped. The V-findings keep their labels but lose the dead `§10.1/` prefix. §13.8 lists V1–V13 as per-application open items, which is not what the labels mean in these comments, so pointing them at §13.8 would have been a false citation. `apps.md §5`'s virtualization requirement has no counterpart anywhere in the design document. The requirement is stated in the comment itself, so the citation is dropped rather than aimed at a section that does not say it. Comments that attributed a *sentence* to an old note — musicbay's "several thousand files" example, its "what got measured" note, its measured ~11%/~26% cover-art figures, the "original no root, whole shared tree" call — state the fact without attribution now. §9.8 does not contain those sentences and citing it for them would have been wrong. CLAUDE.md's "a reference to a document that no longer exists" row now says the concordance is for git history and out-of-tree material; the code cites sections directly. Verified: 2851 passed, 4 skipped. The 12 errors in the run are the Firefox leg of test_sticky_header.py's browser harness, which is broken at the browser level on this machine — headless Firefox (snap) dies with `[GFX1-]: RenderCompositorSWGL failed mapping default framebuffer`, renders nothing, and the probe exits `{"error": "no measurement"}` after its full 90s wait. Chrome runs the same 12 assertions in 3.2s and passes. Nothing here can affect it: every changed line in style.css is inside a comment. Also checked: ast.parse on every changed .py, `node --check` on every changed .js, the /* */ balance in style.css, and that no changed line exceeds the width its file already used. Co-Authored-By: Claude Opus 5 --- .../src/meshbay_node/indexer/title_parse.py | 31 +++++++++++----------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'packages/meshbay-node/src/meshbay_node/indexer/title_parse.py') diff --git a/packages/meshbay-node/src/meshbay_node/indexer/title_parse.py b/packages/meshbay-node/src/meshbay_node/indexer/title_parse.py index beb0d3f..14728ff 100644 --- a/packages/meshbay-node/src/meshbay_node/indexer/title_parse.py +++ b/packages/meshbay-node/src/meshbay_node/indexer/title_parse.py @@ -1,18 +1,18 @@ """ Filename -> title/year/season/episode parsing for the Videos group app. -Wraps `guessit` and layers the fixes from docs/mediacenter.md §3.3/§3.4 on +Wraps `guessit` and layers the fixes from docs/MESHBAY_DESIGN.md §9.7 on top of it: none of them are per-title hacks, each is a generic rule found by validating guessit's raw output against real TMDB search results over a ~1950-file library (movies, TV shows, and a small franchise set). -Scope is deliberately narrow (§3.5): title, year, season, episode. Technical +Scope is deliberately narrow: title, year, season, episode. Technical facts (resolution, codec, duration) come from ffprobe, never the filename — a mislabeled `1080p` tag is a real, observed failure mode. This module never touches the filesystem or the network. The orchestration that decides *which* file supplies a show's title (a representative episode -filename, not the folder name — §3.4) lives in the indexer, which has the +filename, not the folder name) lives in the indexer, which has the directory listing; this module only parses strings it's handed. """ @@ -91,7 +91,7 @@ _YEAR_RE = re.compile(r"(? int | None: """First 19xx/20xx in `text`, or None — used to lift a year off a show - folder name ("Some.Show.2022.S01") for the search fallback (§10.1/V8).""" + folder name ("Some.Show.2022.S01") for the search fallback (V8).""" m = _YEAR_RE.search(text or "") return int(m.group(0)) if m else None @@ -102,7 +102,7 @@ def clean_query(s: str) -> str: parenthesized-year stripping `naive_title` does. `naive_title` assumes a real filename; a show's `display_title` is a folder basename ("Some.Show.Name" — `rsplit('.', 1)` would eat ".Name"), so it needs a - gentler normaliser (§10.1/V8). + gentler normaliser (V8). """ s = re.sub(r"[._-]+", " ", s or "") s = _strip_editions(s) @@ -115,7 +115,7 @@ def _strip_editions(title: str) -> str: def naive_title(filename: str) -> str: """ - The mandated fallback (§3.6, §4.1): strip the extension, replace every + The mandated fallback: strip the extension, replace every `.`/`_`/`-` with a space, drop a trailing parenthesized year, collapse whitespace. Always computable, never fails, used both as the flat-mode display name of last resort and as a second TMDB query candidate. @@ -150,14 +150,14 @@ def sequel_variants(title: str) -> list[str]: A trailing sequel index often has no exact match in the real TMDB title: the file has a digit where TMDB uses a Roman numeral (or the reverse), spells the number out, or wraps it as "Part N" / "Chapitre N" - (§3.3 row 4, §10.1/V10). Returns extra candidate titles to try — the + (V10). Returns extra candidate titles to try — the index re-rendered as digit and as Roman numeral, plus (only when there is no "Part"/"Episode"/… keyword) the bare base. The bare base is withheld for a keyword'd index — " Chapter III" → "" — because a franchise's bare name is very often a real, *different* film (the series' first entry), and that variant matched - every later entry to it (§10.1/V14). Without the keyword (" + every later entry to it (V14). Without the keyword (" 3") the number is decoration and the bare base is the right thing to try. """ @@ -190,7 +190,7 @@ def sequel_variants(title: str) -> list[str]: def season_from_folder_name(name: str) -> int | None: """ - §3.4: a season-like ancestor folder, vocabulary-driven rather than + A season-like ancestor folder, vocabulary-driven rather than assuming a numeric convention everywhere. A specials/bonus/extras folder maps to season 0 (matching TMDB's own `season_number: 0`). Returns None if `name` doesn't look like a season folder at all. @@ -212,7 +212,8 @@ def season_from_folder_name(name: str) -> int | None: @dataclass class ParsedName: display_title: str | None # None => caller must supply from elsewhere (e.g. a sibling file) - alt_title: str | None = None # guessit's alternative_title, a second query candidate (§3.3 row 1) + alt_title: str | None = None # guessit's alternative_title, a second + # query candidate naive_title: str = "" # always available, fully punctuation-normalized fallback year: int | None = None season: int | None = None @@ -249,7 +250,7 @@ def parse_movie_filename(filename: str) -> ParsedName: -# ── Music app (docs/musicbay.md §2.1) ──────────────────────────────────────── +# ── Music app (docs/MESHBAY_DESIGN.md §9.8) ──────────────────────────────────────── # # Filename parsing is the *fallback* here, not the primary source (unlike # Videos, where guessit does all the work): embedded ID3/Vorbis tags are read @@ -307,7 +308,7 @@ def strip_track_prefix(text: str) -> str: # "Season 1"/"Saison 1". guessit will also invent a season+episode from a # bare 3-4 digit run ("1080p" truncated to "108" -> S01E08; "1280" -> # S12E80), which is how a plain movie ends up shelved as a series -# (§10.1/V14). The indexer uses this to tell a real flat-library episode +# (V14). The indexer uses this to tell a real flat-library episode # from that hallucination. _EPISODE_MARKER_RE = re.compile( r"s\d{1,2}[\s._-]*e\d{1,3}" @@ -326,9 +327,9 @@ def has_episode_marker(filename: str) -> bool: def parse_episode_filename(filename: str) -> ParsedName: """ Parse an episode filename. `display_title` may come back None (e.g. - `S08E02.SUBFRENCH.720p.mkv` carries no show name at all, §3.2) — the + `S08E02.SUBFRENCH.720p.mkv` carries no show name at all) — the indexer then supplies the show title from a representative sibling - filename in the same folder rather than the folder name itself (§3.4). + filename in the same folder rather than the folder name itself. """ g = guessit(filename) title = g.get("title") @@ -351,7 +352,7 @@ def parse_episode_filename(filename: str) -> ParsedName: ) -# A bare leading episode number, no show name attached (§3.4c) — the same +# A bare leading episode number, no show name attached — the same # shape as music's _TRACK_PREFIX_RE, capped at 3 digits for the same reason: # a leading year ("2010 - Episode.mkv") is 4 digits and must not match. # guessit's own `episode` is not a substitute here: given exactly 3 digits it -- cgit v1.2.3