Cross-repo rollup : items from this tracker that block other repos or carry external deadlines are mirrored in Cross-repo critical path (#33) .
End-of-day triage of all 165 open issues in this repo. Entry point for any contributor or agent picking up the work: where to start, what blocks what, which proposals overlap.
This tracker is intended to be edited in place , not appended to. When triage state changes, update the relevant section. Don't add a new "Updates YYYY-MM-DD" block.
Org-level entry point: WXYC/wiki#5 (cross-repo P0 sequencing + patterns). Active org Projects: Post-launch service hardening (#32) with sequencing tracker #1279 ; June 2026 action plan (#35) via WXYC/wiki#77; Cross-repo critical path (#33) .
State as of 2026-06-13
One-day delta since the 2026-06-12 tick: 5 issues closed (#605 , #1288 , #1318 , #1393 , #1395 ), 4 PRs merged (#1394 PII source fix + remediation, #1399 hot-fix DJ_HANDLE truncation, #1396 auth OIDC loginPage delegation, #1403 LATERAL JOIN → UNION ALL rewrite + cleanup commits c22a9f6 / e83bbc1 ). Net 165 open: 5 closures, 2 new (#1400 defensive PII contract for tubafrenzy DJ_NAME write site, #1402 sibling dashboard inventory for #1381 ).
(1) CRITICAL #1393 PII leak CLOSED. PR #1394 (source fix at three ETL writers — fetch-legacy.ts, job.ts bulk-load tuple position, backfill-legacy-ids.ts — plus one-shot jobs/legacy-dj-name-remediation/) merged 2026-06-12T23:20Z; PR #1399 hot-fix (DJ_HANDLE truncation to 128 chars) merged 2026-06-13T00:40Z. The public v2 marker wire no longer surfaces real names. Follow-up #1400 filed (defensive contract for the upstream http.mirror.ts:362-364 write site that still sends dj.realName || dj.name into tubafrenzy's DJ_NAME column — the leak source from the opposite direction, not active today because no BS code path reads back from tubafrenzy's DJ_NAME, but the contract is brittle to a future engineer reaching for it). Distinct follow-up PR #1401 is the docs-only schema invariant.
(2) #1318 LATERAL JOIN regression CLOSED — #1274 alias flag flip is now fully unblocked. PR #1403 replaced the alias-aware LATERAL JOIN with a precomputed alias_hits CTE + UNION ALL form (verified at apps/backend/services/library-search.service.ts:139-242); follow-up commit c22a9f6 dropped the now-dead aliasActive parameter chain through buildWhereClause / buildConditionFragment / buildAllFieldMatch, and e83bbc1 wrapped the UNION ALL in a subquery so the outer expression ORDER BY behaves under PG's parse rules. #1274 's three native blockedBy edges (#1318 , #1382 , #1383 ) are all CLOSED — the substrate is clean, the perf regression is gone, the flag is ready to flip. Outstanding preconditions on #1274 itself: (a) discogs-cache rebuild since 2026-05-13, (b) consumer #1266 first-tick observation via #1276 , (c) substrate-populated SQL, (d) canonical demo-artist chain verification. All are operator-side checks, not engineering work.
(3) Rotation identity migration — one more precondition filled. #1402 filed 2026-06-13 as the sibling dashboard-migration inventory issue. #1381 's acceptance criteria explicitly require dashboard cutover BEFORE the metric-shape switch ships (otherwise saved discover queries and alert rules on backfill.releases_* / backfill.artists_* go silently dead). Native blockedBy already wired: #1381 ← {LML#525 (open), BS#1380 (open, unblocked), BS#1402 (open, ≥99% coverage prerequisite still standing)}. #1402 fills one of three preconditions the tracker called out 2026-06-12 as missing; LML#525 + BS#1380 ≥99% remain. LML decomposed #525 into 5 sub-issues today (LML#547 musicbrainz_release, #548 bandcamp, #549 spotify_album, #550 apple_music_album, #551 discogs_master legs) — still upstream-blocked.
(4) Closures roundup since 2026-06-12:
New work filed since 2026-06-12 (both open):
P0 sequencing changes: #1393 removed from slot 1 (closed). #1318 removed from slot 3 (closed). #1274 promoted to a near-top slot — fully unblocked operator gate , no longer a code-side concern. #1322 caveat refreshed. #1402 takes a slot near #1381 as part of the rotation-identity chain.
Verified against tree HEAD 2026-06-14:
apps/backend/services/library-search.service.ts:139 confirmed — aliasActive gates the CTE + UNION ALL branch; aliasOff branch is the byte-identical pre-alias-aware LATERAL JOIN: GIN trigram index unused; 3-6.5x p95 regression on selective queries #1318 path. Cleanup commit c22a9f6 verified the inner buildAllFieldMatch no longer references the LATERAL alias_hit.max_sim alias.
jobs/flowsheet-etl/fetch-legacy.ts:78 confirmed — SELECTs IFNULL(rs.DJ_HANDLE, '') (was DJ_NAME). PII leak: flowsheet ETL writes DJ_NAME (real name) into shows.legacy_dj_name, surfaced on v2 marker wire #1393 source fix landed.
jobs/flowsheet-etl/job.ts:200 confirmed — legacy_dj_name: truncate(tuple[4] != null ? String(tuple[4]) : null, 128) (was tuple[2]). Schema comment at job.ts:191-194 documents the swap with explicit PII rationale.
apps/backend/middleware/legacy/http.mirror.ts:362-364 confirmed — djName: dj.realName || dj.name still active. Legacy mirror writes real names to tubafrenzy DJ_NAME — defensive contract for write-only PII #1400 's premise holds.
shared/lml-client/src/index.ts — single chokepoint via lookupMetadata confirmed (BS#906/G4 invariant). refactor(rotation-artist-backfill): switch to lml_identity_id fan-out; drop Discogs-specific carving #1381 will add refreshForIdentities here.
Resilience cluster (enrichment-worker SIGTERM tears down DB before in-flight LML writes #1108 , CDC liveness probe wedges permanently after first echo timeout #1116 , CDC trigger silently drops events for rows exceeding 8000 bytes #1120 , MirrorCommandQueue stays dead after fatalStop; enqueue returns null silently #1123 , FK ON DELETE drifted: flowsheet, rotation, reviews mismatch schema vs DB #1126 , SSE registerClient races client.id insertion vs close handler #1128 , Drizzle journal has two entries at idx 47, making snapshot path ambiguous #1131 , playlist-proxy stopPlaylistProxy doesn't prevent queued reconnects #1132 , nextPlayOrder() index misaligned with per-show query post-#693 #1133 , CDC WebSocket lacks back-pressure check and native ping/pong #1134 , cta_unique_idx allows duplicate (library_id, artist_name) when track_title NULL #1135 , CDC WebSocket auth uses non-constant-time compare; secret in URL #1136 ) all still present.
apps/backend/app.ts:68 origin: process.env.FRONTEND_SOURCE || '*' + credentials: true — cors: '*' fallback combined with credentials:true when FRONTEND_SOURCE unset #1107 CORS fail-open still present.
P0 sequencing — recommended order
Cron jobs' Sentry spans never reach Sentry (tracesSampleRate=0 default, org-wide) #1299 — Set SENTRY_TRACES_SAMPLE_RATE=1.0 on EC2 .env (Option A). Org-wide observability outage on seven cron paths today; unblocks verification of First-cron-tick observation: artist-search-alias-consumer #1276 acceptance criteria + Slot 6 (Complete historical drain at last_id=14603, then retire the daily flowsheet-metadata-backfill cron #1011 historical drain monitoring) + Slot 7 ([C6] Retune flowsheet-metadata-backfill cron as safety-net (hourly, 15-min grace) #895 cron retune). One-config fix; backend/auth/enrichment-worker init already sets own rates. Reinforced by Sentry SDK setupExpressErrorHandler isn't capturing bare exceptions on POST /flowsheet #1367 — the broader observability concern (bare-exception capture gap) makes the tracing fix more urgent. Now the top of the queue with PII leak: flowsheet ETL writes DJ_NAME (real name) into shows.legacy_dj_name, surfaced on v2 marker wire #1393 closed.
Sentry SDK setupExpressErrorHandler isn't capturing bare exceptions on POST /flowsheet #1367 — Diagnose POST /flowsheet bare-TypeError gap. Root-cause hypothesis refocused 2026-06-12: PR auth: pass explicit shouldHandleError predicate to Sentry.setupExpressErrorHandler #1388 's audit verified shouldHandleError IS honored on @sentry/node ^10.53.1. Suspect Express 5 + async-handler boundary. HIGH severity: any 5xx code path without explicit Sentry.captureException is currently invisible. Pairs with Cron jobs' Sentry spans never reach Sentry (tracesSampleRate=0 default, org-wide) #1299 as the observability hardening pair.
PR 6 — flip CATALOG_SEARCH_ALIAS_ENABLED=true on prod (deploy-only) #1274 alias flag flip — NEWLY FULLY UNBLOCKED 2026-06-14. All three native blockers (alias-aware LATERAL JOIN: GIN trigram index unused; 3-6.5x p95 regression on selective queries #1318 , Tighten artist_search_alias substrate: drop no-op variants + distinguish discogs_member matches #1382 , Distinguish discogs_member matches from in-library matches in artist_search_alias consumers #1383 ) closed. Remaining work is operator-side T-1 verification: discogs-cache rebuild ≥ 2026-05-13, feat(artist-search-alias-consumer): daily ETL populating artist_search_alias from LML + alternate_artist_name #1266 first-cron-tick observation per First-cron-tick observation: artist-search-alias-consumer #1276 , substrate-populated SQL, canonical demo-artist chain. No code change. Set CATALOG_SEARCH_ALIAS_ENABLED=true on prod after the checks.
feat(schema): add rotation.lml_identity_id; mint LML identities on dj-site paste #1380 — Rotation identity migration schema + dual-write. Newly unblocked 2026-06-10 (LML#526 closed). Schema migration adds rotation.lml_identity_id integer NULL; dj-site paste flow mints via POST /api/v1/identity/resolve (NULL-on-LML-outage fallback). Dual-write, never null-out existing discogs_release_id. Acceptance: ≥99% backfill coverage on active rotation rows before signaling BS#1381 to proceed.
chore(sentry): migrate rotation-artist-backfill dashboards to identity-shape metrics #1402 — Sentry dashboard inventory + cutover. Must complete BEFORE refactor(rotation-artist-backfill): switch to lml_identity_id fan-out; drop Discogs-specific carving #1381 's metric-shape switch deploys. Operator-side audit; no BS code change. New alert: backfill.not_found / backfill.identities_scanned > 1% rolling 24h (the corruption signal — invisible without this counter).
[C5-cleanup] Delete orphaned enrichment + linkage services after #894 callsite removal #1322 — Delete orphaned enrichment.service.ts + flowsheet-linkage.service.ts + linkage-metrics.service.ts + four orphan tests + app.ts drain wiring. Mechanical, single PR, ~30 min. Caveat (per Reconcile SEARCH_TYPE_CONFIDENCE table with BS#1351 rotation-picker trust policy #1356 correction): flowsheet-linkage.service.ts is still active — verify before deletion. The C5-cleanup scope may be narrower than the issue states.
CDC WebSocket auth uses non-constant-time compare; secret in URL #1136 — CDC WebSocket auth: switch to Authorization: Bearer header + crypto.timingSafeEqual; remove secret from URL query string. Carried; one-deploy-window backward-compat shim.
cors: '*' fallback combined with credentials:true when FRONTEND_SOURCE unset #1107 , auth: /admin/create-user after-hook matches by body email — race/case-fold risk #1118 , auth: OIDC trusted client may register with literal 'undefined' when WIKIJS_* env vars missing #1122 , ILIKE wildcards in user input unescaped in suggest/labels services #1124 , auth: Bearer parsing case-sensitive in prod path — inconsistent with bypass branch and RFC 6750 #1125 — remaining security audit batch. cors: '*' fallback combined with credentials:true when FRONTEND_SOURCE unset #1107 (CORS '*' fallback + credentials: true) is the priority of the five because it fails open.
Consolidate ArtistSearchAliasSource type and partition into a single source of truth #1390 — Consolidate ArtistSearchAliasSource type into shared/database/src/artist-search-alias-sources.ts with compile-time exhaustiveness assertion + close (string & {}) union at wire-shape projection. S complexity, unblocked, removes a recurring drift hazard before catalog-search-alias formalization (BS#1275 / wxyc-shared codegen) lands.
Legacy mirror writes real names to tubafrenzy DJ_NAME — defensive contract for write-only PII #1400 — Defensive contract for http.mirror.ts:362-364. Doc-only code comment + scheduled rename of shows.legacy_dj_name → shows.legacy_dj_handle. Not active leak; brittle to future engineer reaching for DJ_NAME as identifier.
FK ON DELETE drifted: flowsheet, rotation, reviews mismatch schema vs DB #1126 , schema.ts declares three dropped trigram indexes; next generate will recreate #1129 , Drizzle journal has two entries at idx 47, making snapshot path ambiguous #1131 , nextPlayOrder() index misaligned with per-show query post-#693 #1133 , cta_unique_idx allows duplicate (library_id, artist_name) when track_title NULL #1135 — schema-drift cluster (5 issues, carried).
enrichment-worker SIGTERM tears down DB before in-flight LML writes #1108 , CDC liveness probe wedges permanently after first echo timeout #1116 , CDC trigger silently drops events for rows exceeding 8000 bytes #1120 , MirrorCommandQueue stays dead after fatalStop; enqueue returns null silently #1123 , SSE registerClient races client.id insertion vs close handler #1128 , playlist-proxy stopPlaylistProxy doesn't prevent queued reconnects #1132 , CDC WebSocket lacks back-pressure check and native ping/pong #1134 — resilience cluster (7 issues, carried).
flowsheet-metadata-backfill: per-row retry cap to drain lml_error residual #1199 — per-row retry cap on flowsheet-metadata-backfill. Subsumes flowsheet-metadata-backfill-cron: ~21% LML timeout rate persists post-LML#337/#359 fixes; investigate per-call budget vs cold-cache reality #1064 when shipped.
Complete historical drain at last_id=14603, then retire the daily flowsheet-metadata-backfill cron #1011 — historical drain past last_id=14603. Promoted: LML#504/Repair Drizzle migrations metadata (missing snapshots, broken prevId chain) #505 /ETL to populate artists reconciled-identity columns from LML's entity.identity #506 wrong-data cluster mostly settled (only Bound legacy mirror queue disk reports and add Sentry breadcrumbs #507 perf-only remains). Still gated on Slot 5.5 (Flip PROXY_METADATA_SINGLE_LOOKUP=true in prod once G2 ships #917 ) + Cron jobs' Sentry spans never reach Sentry (tracesSampleRate=0 default, org-wide) #1299 observability. Re-read Drain enriched_match rows with NULL artwork_url stranded by LML _resolve_fallback_artwork bug (LML#408) #1209 deferral rationale before re-kicking off.
Reconcile SEARCH_TYPE_CONFIDENCE table with BS#1351 rotation-picker trust policy #1356 — decide whether flowsheet-linkage should gate at the coordinator (drop gray-zone-review cohort) or keep the SEARCH_TYPE_CONFIDENCE bands. Standalone policy question post-PR feat(lml): coordinator requireSearchType opt; migrate librarian writes (BS#1355) #1363 . metadata.service.ts: define track-context trust policy for LML search_type (compilation-accept) #1359 is the parallel decision for metadata.service.ts:68-77 (track-context surface; compilation is legitimate there). Rotation-picker tier-3: emit Sentry span attribute / breadcrumb for reject reason #1357 will close itself once wxyc-shared#172 step 3 ships.
Project Simplifies the logic surrounding the USE_CI env variable flag and adds default values #32 Slot 5.5 — Flip PROXY_METADATA_SINGLE_LOOKUP=true in prod once G2 ships #917 flag flip PROXY_METADATA_SINGLE_LOOKUP=true. Sequenced to fire ~1 week after [Epic G] Capture enrichment-outcome quality (all-null result), not just LML client throws #969 has baseline ([Epic G] Capture enrichment-outcome quality (all-null result), not just LML client throws #969 shipped 2026-06-03 via PR feat(enrichment-worker): empty-outcome capture with stable Sentry fingerprint #1304 ).
refactor(rotation-artist-backfill): switch to lml_identity_id fan-out; drop Discogs-specific carving #1381 — rotation identity cron refactor. Still blocked on LML#525 (source-agnostic refresh endpoint; LML#547-551 are the per-source sub-tasks filed 2026-06-13 — none merged yet) + BS#1380 ≥99% coverage + BS#1402 dashboard cutover. Refactors PR feat(rotation-artist-backfill): daily cron to refresh LML artist rows for active rotation #1376 's discogs_release_id two-tier walk → lml_identity_id one-tier batched call.
Critical / high severity
CRITICAL (immediate, security or data corruption):
HIGH (correctness, observability, narrower blast radius):
Cron jobs' Sentry spans never reach Sentry (tracesSampleRate=0 default, org-wide) #1299 — org-wide Sentry traces=0 default on 7 cron loggers; observability is OFF on cron paths.
Sentry SDK setupExpressErrorHandler isn't capturing bare exceptions on POST /flowsheet #1367 — POST /flowsheet bare-exception capture gap. Root-cause hypothesis refocused 2026-06-12 (PR auth: pass explicit shouldHandleError predicate to Sentry.setupExpressErrorHandler #1388 audit verified shouldHandleError IS honored on v10); now suspect Express 5 + async-handler boundary.
Legacy deleteEntry mirror deletes wrong tubafrenzy show via MAX(ID) #1101 , Legacy entryIdMap keyed by play_order collides across shows #1103 , POST /flowsheet/end mirror runs endShow on leaveShow responses #1119 — legacy mirror correctness (deletes wrong tubafrenzy show; entryIdMap collides; endShow on leaveShow).
auth: /admin/create-user after-hook matches by body email — race/case-fold risk #1118 , auth: OIDC trusted client may register with literal 'undefined' when WIKIJS_* env vars missing #1122 , auth: Bearer parsing case-sensitive in prod path — inconsistent with bypass branch and RFC 6750 #1125 — auth fragilities.
FK ON DELETE drifted: flowsheet, rotation, reviews mismatch schema vs DB #1126 , schema.ts declares three dropped trigram indexes; next generate will recreate #1129 , Drizzle journal has two entries at idx 47, making snapshot path ambiguous #1131 , nextPlayOrder() index misaligned with per-show query post-#693 #1133 , cta_unique_idx allows duplicate (library_id, artist_name) when track_title NULL #1135 — schema-drift cluster.
enrichment-worker SIGTERM tears down DB before in-flight LML writes #1108 , setupMetadataBroadcast silently no-ops when CDC_SECRET unset #1111 , CDC liveness probe wedges permanently after first echo timeout #1116 , CDC trigger silently drops events for rows exceeding 8000 bytes #1120 , MirrorCommandQueue stays dead after fatalStop; enqueue returns null silently #1123 , SSE registerClient races client.id insertion vs close handler #1128 , playlist-proxy stopPlaylistProxy doesn't prevent queued reconnects #1132 , CDC WebSocket lacks back-pressure check and native ping/pong #1134 — resilience cluster.
flowsheet-dj-name + library-artist-name backfills: verifyComplete raises on orphan FK rows #1140 , backfill-legacy-ids: process.exit(1) skips cleanup; overcounts shows backfill #1141 , flowsheet-etl bulk-load reads entire dump into memory; OOM risk on EC2 #1142 , MirrorSQL.sendLocal: 50MB execSync buffer cap can truncate first-run incremental sync #1143 , library-identity-consumer SELECT re-fetches all resolved rows on every run #1144 — ETL/backfill correctness.
void startCdcDispatcher() swallows DB-unreachable startup errors silently #1222 — fire-and-forget void startCdcDispatcher().
fuzzySearchLibrary doesn't honor n cap on trigram-OR queries #1162 — fuzzySearchLibrary returns 5,134 rows for n=10 on V/A queries (sibling to dj-site#657).
Drain enriched_match rows with NULL artwork_url stranded by LML _resolve_fallback_artwork bug (LML#408) #1209 — LML#408 NULL-artwork drain DEFERRED; LML#408 itself closed 2026-05-29, but the stability gate decision is independent — re-read needed.
Complete historical drain at last_id=14603, then retire the daily flowsheet-metadata-backfill cron #1011 — paused historical drain; gated on Slot 5.5 + Cron jobs' Sentry spans never reach Sentry (tracesSampleRate=0 default, org-wide) #1299 + LML#504/Repair Drizzle migrations metadata (missing snapshots, broken prevId chain) #505 /ETL to populate artists reconciled-identity columns from LML's entity.identity #506 .
/proxy/metadata/album returns wrong-artist matches for ambiguous tracks (v1 path) #1051 — wrong-artist matches via v1 proxy.
EC2 host wedge 2026-05-17 (~15h outage): unbounded semantic-index uvicorn OOM-killed via global host OOM #937 — EC2 host wedge.
Persist LML-only enrichment fields on album_metadata so cache-first /proxy/metadata/album doesn't shed artist+release detail #1336 — silent UI degradation on cache-hit (iOS V1 + dj-site decode-compat but render-incomplete) follow-up to Make /proxy/metadata/album cache-first off album_metadata (skip LML when row is locally resolved) #1331 's cutover.
Reconcile SEARCH_TYPE_CONFIDENCE table with BS#1351 rotation-picker trust policy #1356 — policy decision: gate flowsheet-linkage at coordinator vs. keep gray-zone bands. The cross-callsite asymmetry BS-wide search_type gate proliferation: gate at LML coordinator or response shape, not per-callsite #1355 closed at fireAndForgetCanonicalEntity is gone; this is now about gray-zone review-queue behaviour.
metadata.service.ts: define track-context trust policy for LML search_type (compilation-accept) #1359 — metadata.service.ts:68-77 track-context trust policy decision (accept compilation? reject? expose as opt?).
Audit cleanDiscogsBio: iOS and dj-site parse Discogs markup, so backend strip is lossy #1360 — V2 flowsheet pays cleanDiscogsBio cost (link info destroyed) with no offsetting benefit — V2 endpoint serves no bioTokens. iOS + dj-site both have full parsers.
Cross-cluster conflicts (decide once before starting)
Artist-search-alias flip (#1274 ) — FULLY UNBLOCKED 2026-06-14
PR #1403 closed #1318 (LATERAL JOIN → UNION ALL) with two follow-up cleanup commits (c22a9f6 drops the dead aliasActive chain; e83bbc1 wraps the UNION in a subquery for outer ORDER BY). Combined with #1382 (PR #1389 , writer-side reject + one-shot DELETE) and #1383 (PR #1384 , resolver discogs_member filter) closing earlier in the cycle, all three native blockers on #1274 are CLOSED. The substrate is clean and the perf regression is gone. Remaining work is operator-side T-1 verification only — no engineering blocker. Sequence: run the substrate-populated SQL + canonical demo-artist chain on prod, then CATALOG_SEARCH_ALIAS_ENABLED=true. The catalog-search formalization arm of #1383 (option b — propagate source through ArtistMatchHint) is tracked via BS#1275 + BS#1390 (type consolidation); UX-shaped harm, not data-shaped, so it can chase the flag flip.
Rotation identity migration (#1380 → #1402 → #1381 ) — two of three preconditions filled
LML#526 (CLOSED 2026-06-10) — release-identity schema + POST /api/v1/identity/resolve for kind:'release'. Done.
LML#525 (open; decomposed 2026-06-13 into 5 per-source sub-tasks LML#547-551) — POST /api/v1/cache/refresh-for-identities source-agnostic endpoint. Still upstream-blocked.
BS#1380 (open, UNBLOCKED 2026-06-10) — schema migration adds rotation.lml_identity_id; dj-site paste flow dual-writes; backfill cron populates existing rows. Acceptance: ≥99% backfill coverage.
BS#1402 (open, filed 2026-06-13) — Sentry dashboard inventory + cutover. Operator-side audit; no BS code change. Must complete BEFORE refactor(rotation-artist-backfill): switch to lml_identity_id fan-out; drop Discogs-specific carving #1381 ships.
BS#1381 (open, blocked on LML#525 + BS#1380 ≥99% coverage + BS#1402 cutover) — refactors PR feat(rotation-artist-backfill): daily cron to refresh LML artist rows for active rotation #1376 's cron from two-tier Discogs walk → one-tier batched identity-refresh call. Native blockedBy correctly wired to all three.
This remains the canonical example of dependency direction across the BS↔LML boundary: BS owns rotation, LML owns identity, BS calls LML at the dj-site paste boundary AND at the cron-refresh boundary.
#1336 vs #1331 — cache-hit shape parity
PR #1332 shipped #1331 's cache-first cutover but cache-hit responses now omit discogsArtistId, genres, styles, label, fullReleaseDate, tracklist, artistImageUrl, bioTokens — fields LML returns but album_metadata doesn't carry. dj-site AlbumDetailPanel and iOS V1 PlaycutMetadataService.swift:109 use discogsArtistId to gate the artist sub-panel; both silently degrade on cache-hit. #1336 extends album_metadata schema + writer to persist these fields; cutover is gradual as enrichment-worker UPSERTs land. Schedule before the cache-hit rate climbs further.
#1280 "Not on Discogs" epic — sequence vs Project #32
#1280 introduces a new gating surface across lml-client, library controller, three jobs, one new cron. Slot ordering: 1a (schema + PATCH) → 1b (lml-client gate) → 1c (caller wiring) → 2 (library-artwork-url-backfill migration) → 3 (recheck cron). PR #1154 (Jackson's catalog edit endpoints) is a soft prerequisite for 1a; fallback per plan §10.4 lets 1a land directly if #1154 stalls past 2026-06-15. #1285 tracks deferred surface (library-identity-consumer, library-canonical-entity-backfill, six ungated lml-client exports). Joined to Project #32 board.
Cross-org staging epic (BS#1335 + peers)
New cross-repo workstream surfaced 2026-06-04. Phases:
Phase 1 wxyc-shared#165 — E2E runner EC2 + GHA self-hosted runner registration. Gates BS#1335.
Phase 2 dj-site#739 — dj-site staging gate via CF Pages prod branch + staging-gate.yml.
Phase 3 LML#496 — LML staging env on Railway watching main.
Phase 4 BS#1335 — BS staging containers + Postgres on wxyc-ec2 + deploy-staging.yml + prod trigger flip. Highest blast-radius phase (shares prod box).
Phase 5 wxyc-shared#166 — bs-lml-gate coordinator workflow.
Parent: WXYC/wiki#80. Sequence is enforced by Phase 1 (E2E runner) being a hard prereq.
Audit cluster vs Epic F (#880 ) — #1106 re-scope still pending
Epic F closed 2026-06-02. #1106 's "drift forward" half is obsolete; the "bypass" half is still live. Rescope #1106 to the bypass concern only.
Audit cluster vs Epic E (cache hierarchy, #879 )
Unchanged. #1089 + #1105 ship standalone; fold their tests into Epic E child #988 .
#1199 vs #1064 — supersession question
Unchanged. Close #1064 as superseded once #1199 ships.
Epic C C5 (#894 ) vs Epic B B3 (#886 ) — RESOLVED
Both closed 2026-06-02/03. C5 shipped (PR #1323 ); B3 closed as superseded.
#990 / #991 / #962 — LML timeout & limiter shape
Unchanged. Sequence: #990 → #991 → revisit #962 later.
#917 PROXY_METADATA_SINGLE_LOOKUP flip — #969 baseline accruing
#969 shipped 2026-06-03 via PR #1304 . Slot 5.5 of #1279 schedules the flip to fire ~mid-Slot-5 after #969 has accrued ~1 baseline week. Roll back if enrichment-empty-outcome alert or canary EnrichmentLag fires.
#644 (linkage SSE re-emit) — path (b) chosen
F1 (#902 ) shipped 2026-06-02; recommend close unless sub-3s SSE-level latency on rotation_bin is required for iOS.
#1030 — blocked on #1195 decision
Unchanged.
#1262 — anonymous_devices removal — unblocked
Still unblocked, low-priority cleanup.
search_type trust-policy cluster — #1355 SHIPPED, dependents are now policy decisions
#1355 closed 2026-06-08 via PR #1363 . Approach implemented: gate moved to the LmlLookupCoordinator via a requireSearchType: 'direct' opt (with companion lml.coordinator.trust_reject_reason Sentry span attribute, sliceable as caller × hit × trust_reject_reason). Librarian writes (addAlbum, fireAndForgetCanonicalEntity, enrichWithArtwork) now flow through the gated coordinator.
The three "blocked by #1355 " follow-ups remain open but are no longer dependent bugs:
cleanDiscogsBio audit (#1360 ) — premise questioned
PR #1358 shipped BS#1354 (strip numeric-id tokens like [a8390436]). BS#1360 audits the strip premise: iOS (DiscogsMarkupParser.swift) and dj-site (<DiscogsMarkup tokens=...>) both have full parsers. iOS V1 receives bioTokens pre-parsed from the proxy; V2 flowsheet serves only the stripped artist_bio string. So the strip is destroying link information V2 clients are equipped to render, with no offsetting fallback benefit (V2 has no rawless fallback path).
Three options outlined in #1360 body: (1) serve bioTokens everywhere (long-term right answer, needs @wxyc/shared DTO change + coordinated client migration), (2) stop stripping (minor cosmetic regression for fallback paths in exchange for restored link info), (3) document the trade-off + status quo. Needs decision.
Touring-events feature — substrate complete; cleanup follow-ups closed
All four substrate PRs (#1348 schema, #1345 RHP scraper, #1376 rotation-artist-backfill, #1375 concerts-artist-resolver) merged by 2026-06-10. #1368 Path A audit shipped → #1382 + #1383 spawned and BOTH CLOSED 2026-06-10 (via PR #1389 writer-side reject + one-shot DELETE; PR #1384 resolver-arm discogs_member filter). PR #1386 added concerts.first_scraped_at for scraper-stability clock (closed #1385 ).
Remaining open follow-ups:
Catalog-search formalization arm of #1383 still waits on BS#1275. Bandsintown explicitly excluded as a concerts source — Data Applications Terms forbid persistent caching. iOS / dj-site / submission-form surfaces are still deferred until #1368 memo lands a decision.
Yenbett incident close-out — wrong-data cluster mostly settled
The original Yenbett picker incident (BS#1351) had two upstream contributors: BS's missing search_type gate (closed via PR #1352 ) AND LML's lack of streaming-source probing for non-catalog albums (LML#487, closed 2026-06-07). LML#487's fix in enrich_artwork_results introduced new wrong-data risk; all three correctness items now CLOSED : LML#504 (artist-scoped field gate, 2026-06-09), LML#505 (Deluxe/Remaster pairing, 2026-06-09), LML#506 (MB tracklist rescue, 2026-06-09). LML#507 (wasted prefetch — perf, not correctness) remains open. BS#1209 + BS#1011 drain gate is largely clear — re-read deferral rationale and verify, then re-kick off if appropriate.
Obsolete / needs-revision (recommend close)
Open hold-for-decision
Open PRs
PR
State
Status
#794
Open since 2026-05-09
Narrowed-scope spike memo; likely mergeable as docs-only
#967
Open since 2026-05-20
Closes #966 (better-auth session pin)
#975
Open since 2026-05-20
Defensive logging fix for library-identity-consumer
#1153
Open since 2026-05-25
Closes #1152 (CLAUDE.md extraction)
#1154
Open since 2026-05-26
Library endpoints + MD catalog editing; soft prerequisite for #1280 sub-issue 1a
#1346
Open since 2026-06-05
chore(format): prettier on ADR 0005; MERGE_STATE=BEHIND
#1369
Open since 2026-06-08
Dependabot better-auth bump (1.6.14 → 1.6.18)
#1397
Open since 2026-06-12
Dependabot dev-deps batch (8 updates)
#1398
Open since 2026-06-12
Dependabot production-deps batch (9 updates)
#1401
Open since 2026-06-13
docs(schema): document shows.legacy_dj_name DJ_HANDLE invariant (#1393 follow-up)
Cross-repo dependencies (native + body prose)
Issue
Blocked by
Method
#250 , #251
#249
Unchanged
#655
tubafrenzy#496, docs#13, docs#16
All still open
#895
#1011 , #892
Unchanged
#917
#969 (shipped)
Schedule per Slot 5.5
#1030
#1195
Encoded in #1195 body
#1064
(none — superseded by #1199 )
Recommend close-as-superseded
#1093
LML#355 (now closed)
Body prose — re-check
#1199
(none — #1180 closed)
Unblocked
#1209
LML stability gate (LML#408 closed; re-read)
Body prose
#1262
(none)
Unblocked
#1274
NEWLY FULLY UNBLOCKED 2026-06-14 — all three native blockers (#1318 , #1382 , #1383 ) closed
Native + body prose
#1280 epic
PR #1154 (soft prerequisite for 1a)
Plan §10.4 fallback
#1281 / #1293 / #1294
parent #1280
Native sub-issue
#1285
parent #1280 (deferred follow-up)
Native sub-issue
#1328
wxyc-shared api.yaml bump (rename record_label → label)
Body prose
#1335
wxyc-shared#165 (Phase 1 E2E runner)
Body prose
#1336
(none — schema + writer extension)
Body prose; pairs with closed #1331
#1356 / #1357 / #1359
#1355 closed; native blocked-by will resolve
(no action needed)
#1357
additionally awaits wxyc-shared#172 step 3 before close
Body prose
#1373
#1372 closed + ≥30 days concerts data
Body prose
#1380
UNBLOCKED 2026-06-10 (LML#526 closed)
Body prose; cross-repo
#1381
LML#525 (decomposed into LML#547-551) + BS#1380 ≥99% coverage + BS#1402 dashboard cutover
Native (3 edges) + body prose
#1390
(none — unblocked); follow-up to #1384 review
Body prose
#1400
(none — defensive contract follow-up to #1393 )
Body prose
#1402
(none — must precede #1381 deploy)
Body prose
#845
(none — wxyc-canary#17 closed)
All cleared
Cross-repo runtime risks
library-metadata-lookup#525 — still open; upstream blocker for BS#1381 (POST /api/v1/cache/refresh-for-identities source-agnostic endpoint). Decomposed 2026-06-13 into per-source sub-tasks: LML#547 (musicbrainz_release), LML#548 (bandcamp), LML#549 (spotify_album), LML#550 (apple_music_album), LML#551 (discogs_master). All still open. Consumes the release-identity IDs from LML#526 (closed).
library-metadata-lookup#543 — filed 2026-06-13: bound the orchestrator fallback cascade when track+artist returns 0 results. Touches the matching pipeline that BS#1051's class hits; soft-related to BS picker reliability.
library-metadata-lookup#537 — filed 2026-06-13: Discogs cache hit ratio plateaued at ~50% (search_releases_by_track at 34%) after write_release fix. Investigation; perf-shaped impact on BS proxy/metadata callers.
library-metadata-lookup#526 — CLOSED 2026-06-10 (release-identity schema + endpoint shipped). BS#1380 now unblocked.
library-metadata-lookup#504, Repair Drizzle migrations metadata (missing snapshots, broken prevId chain) #505 , ETL to populate artists reconciled-identity columns from LML's entity.identity #506 — ALL CLOSED 2026-06-09. Wrong-data correctness items from the LML#487 fallout are settled. BS#1209 + BS#1011 historical drain gate is largely clear; only need to re-read BS#1209 deferral rationale + verify before kicking off.
library-metadata-lookup#507 — wasted top-1 Discogs prefetch on every LML#487-trigger request. Perf-only; doesn't block correctness work. Only remaining open item from the LML#487 cluster.
library-metadata-lookup#497 — populate api_fetch-only artist columns during cache rebuild. Yetsuby (BS#1353) verified the chain end-to-end after LML#499 (?refresh=true) merged 2026-06-07.
library-metadata-lookup#490 — search-aliases/bulk returns empty variants[] with sources_present populated. Was directly relevant to BS#1319 substrate fill; less pressing now that alias-aware LATERAL JOIN: GIN trigram index unused; 3-6.5x p95 regression on selective queries #1318 closed via UNION ALL rewrite (alias query shape is no longer bottlenecked).
library-metadata-lookup#488 — Apple Music observability + outage; affects _fetch_apple_music_url path used by BS proxy.
library-metadata-lookup#487 — Closed 2026-06-07. Probe external streaming sources for album artwork when library catalog has no matching album. Cluster spawned (LML#504/Repair Drizzle migrations metadata (missing snapshots, broken prevId chain) #505 /ETL to populate artists reconciled-identity columns from LML's entity.identity #506 /Bound legacy mirror queue disk reports and add Sentry breadcrumbs #507 ) — see above.
library-metadata-lookup#357 — per-request httpx + racy lazy-pool-init.
library-metadata-lookup#220 — /lookup matching pipeline correctness; touches BS#1051's class.
tubafrenzy#496 — blocks BS#655 (artist canonicalization rollout). Per memory: tubafrenzy on life support (2026-05-10 turndown decision); this should not be a long-lived state.
tubafrenzy#408 — webhook listener not firing after Tomcat restart; related to BS#1083 framing.
dj-site#657 — sibling of BS#1162 (fuzzySearchLibrary n-cap).
dj-site#693 — sibling of BS#1280 (MD Discogs gating UI).
dj-site#709 — root divergence behind BS#1328 (record_label vs label field name).
dj-site#750 — rotation badge regression (100%→0% cliff at 2026-06-04 20:00 UTC); per memory's rotation badge architecture note, dj-site uses BS rotation_bin JOIN; trace into BS rotation read endpoint.
wxyc-shared#156 — sub-issue of BS#1280 (api.yaml Album type extension).
wxyc-shared#165 — blocks BS#1335 (Phase 1 E2E runner).
wxyc-shared#166 — peer of BS#1335 (Phase 5 coordinator workflow).
wxyc-shared#169 — api: lift /flowsheet/join requestBody (relevant to dj_name_override path that just shipped).
wxyc-shared#172 — discriminated result_kind on LookupResponse; closes Rotation-picker tier-3: emit Sentry span attribute / breadcrumb for reject reason #1357 when step 3 ships.
wxyc-ios-64#390 — known v1 gap follow-up to BS#1280.
Cluster map (165 open)
Active cross-repo epics + trackers
[Tracker] artist-search-alias plan — PRs 1-5 shipped, PR 6 + follow-ups outstanding #1273 Artist-search-alias plan — PRs 1-5 shipped; PR 6 (PR 6 — flip CATALOG_SEARCH_ALIAS_ENABLED=true on prod (deploy-only) #1274 ) NEWLY FULLY UNBLOCKED 2026-06-14 (alias-aware LATERAL JOIN: GIN trigram index unused; 3-6.5x p95 regression on selective queries #1318 , Tighten artist_search_alias substrate: drop no-op variants + distinguish discogs_member matches #1382 , Distinguish discogs_member matches from in-library matches in artist_search_alias consumers #1383 all closed); Artist-search-alias v2 backlog — deferred optimizations + cleanup #1290 v2 backlog; Consolidate ArtistSearchAliasSource type and partition into a single source of truth #1390 type consolidation follow-up
[Tracker] Project #32 close-out sequencing #1279 Project Simplifies the logic surrounding the USE_CI env variable flag and adds default values #32 close-out sequencing — Slots 1-5 DONE; Slot 5.5 (Flip PROXY_METADATA_SINGLE_LOOKUP=true in prod once G2 ships #917 ) → Slot 6 (Complete historical drain at last_id=14603, then retire the daily flowsheet-metadata-backfill cron #1011 , now mostly cleared) → Slot 7 ([C6] Retune flowsheet-metadata-backfill cron as safety-net (hourly, 15-min grace) #895 ) next
[Epic] MD-set "Not on Discogs" flag for catalog releases #1280 [Epic] MD-set "Not on Discogs" flag — 5 BS sub-issues + wxyc-shared#156 + dj-site#693 + ios#390; [Tracker] Follow-up: extend gate to library-identity-consumer, library-canonical-entity-backfill, six ungated lml-client exports #1285 deferred surface
#631 Historical flowsheet-metadata-backfill epic — Drain enriched_match rows with NULL artwork_url stranded by LML _resolve_fallback_artwork bug (LML#408) #1209 drain deferred (LML#408 + LML#487 + LML#504/Repair Drizzle migrations metadata (missing snapshots, broken prevId chain) #505 /ETL to populate artists reconciled-identity columns from LML's entity.identity #506 ALL CLOSED upstream as of 2026-06-09); Complete historical drain at last_id=14603, then retire the daily flowsheet-metadata-backfill cron #1011 paused at last_id=14603, now mostly unblocked
Cross-org staging epic (no parent BS issue) — Phase 4: BS staging containers + Postgres on EC2 + deploy-staging.yml + prod trigger flip #1335 + wxyc-shared#165/#166 + dj-site#739 + LML#496; parent WXYC/wiki#80
search_type trust-policy cluster (no parent BS issue) — BS-wide search_type gate proliferation: gate at LML coordinator or response shape, not per-callsite #1355 SHIPPED via PR feat(lml): coordinator requireSearchType opt; migrate librarian writes (BS#1355) #1363 ; Reconcile SEARCH_TYPE_CONFIDENCE table with BS#1351 rotation-picker trust policy #1356 /Rotation-picker tier-3: emit Sentry span attribute / breadcrumb for reject reason #1357 /metadata.service.ts: define track-context trust policy for LML search_type (compilation-accept) #1359 remain open as policy decisions
Touring-events feature (no parent BS issue) — substrate LIVE (PRs feat(venue-events-scraper): RHP venue scraper job #1345 + feat(schema): add venues + concerts tables for touring-events #1348 + feat(concerts-artist-resolver): backfill headlining_artist_id via local artist + alias resolver #1375 + feat(rotation-artist-backfill): daily cron to refresh LML artist rows for active rotation #1376 merged by 2026-06-10); cleanup follow-ups SHIPPED (PRs fix(concerts-artist-resolver): exclude discogs_member from alias arm (BS#1383) #1384 , feat(concerts): add first_scraped_at INSERT-only column for scraper-stability clock #1386 , Reject no-op discogs_name_variation rows in artist_search_alias writer (BS#1382) #1389 closed Tighten artist_search_alias substrate: drop no-op variants + distinguish discogs_member matches #1382 /Distinguish discogs_member matches from in-library matches in artist_search_alias consumers #1383 /Add concerts.first_scraped_at (INSERT-only) for scraper-stability measurement #1385 ). Remaining: Frequency analysis: how often will the venue-events scraper surface a WXYC-relevant artist? #1368 (memo + Path A audited), Path B re-run: forward-look frequency analysis after 30 days of concerts data #1373 (Path B forward-look, earliest 2026-07-10), Consolidate ArtistSearchAliasSource type and partition into a single source of truth #1390 (type consolidation post-fix(concerts-artist-resolver): exclude discogs_member from alias arm (BS#1383) #1384 review); future iOS/dj-site/submission-form surfaces TBD.
Rotation identity migration (no parent BS issue) — feat(schema): add rotation.lml_identity_id; mint LML identities on dj-site paste #1380 (UNBLOCKED) + chore(sentry): migrate rotation-artist-backfill dashboards to identity-shape metrics #1402 (new, dashboard cutover) + refactor(rotation-artist-backfill): switch to lml_identity_id fan-out; drop Discogs-specific carving #1381 (still blocked on LML#525). LML#526 release-identity precursor CLOSED 2026-06-10; LML#525 decomposed into LML#547-551 sub-tasks 2026-06-13. Migration completes when ≥99% of active rotation rows carry lml_identity_id AND the BS#1402 dashboard cutover lands AND LML#525 sub-tasks merge.
Audit batch — 2026-05-25 residue
Security / authz residue (8) — cors: '*' fallback combined with credentials:true when FRONTEND_SOURCE unset #1107 , auth: /auth/test/expire-session has no auth check — force-logout of arbitrary userId #1112 , auth: /auth/test/verification-token returns reset/verification tokens unauthenticated #1115 , auth: /admin/create-user after-hook matches by body email — race/case-fold risk #1118 , auth: OIDC trusted client may register with literal 'undefined' when WIKIJS_* env vars missing #1122 , ILIKE wildcards in user input unescaped in suggest/labels services #1124 , auth: Bearer parsing case-sensitive in prod path — inconsistent with bypass branch and RFC 6750 #1125 , CDC WebSocket auth uses non-constant-time compare; secret in URL #1136
Schema drift (5) — FK ON DELETE drifted: flowsheet, rotation, reviews mismatch schema vs DB #1126 , schema.ts declares three dropped trigram indexes; next generate will recreate #1129 , Drizzle journal has two entries at idx 47, making snapshot path ambiguous #1131 , nextPlayOrder() index misaligned with per-show query post-#693 #1133 , cta_unique_idx allows duplicate (library_id, artist_name) when track_title NULL #1135
Resilience (7) — enrichment-worker SIGTERM tears down DB before in-flight LML writes #1108 , setupMetadataBroadcast silently no-ops when CDC_SECRET unset #1111 , CDC liveness probe wedges permanently after first echo timeout #1116 , CDC trigger silently drops events for rows exceeding 8000 bytes #1120 , MirrorCommandQueue stays dead after fatalStop; enqueue returns null silently #1123 , SSE registerClient races client.id insertion vs close handler #1128 , playlist-proxy stopPlaylistProxy doesn't prevent queued reconnects #1132 , CDC WebSocket lacks back-pressure check and native ping/pong #1134
ETL value-aware UPSERT follow-ups (2) — #1083, #1084
Cross-cache-identity follow-ups (3) — #1086, #1087, library_identity_source: add per-source attempted_at + nullable confidence (unblocks LML#355) #1093
Backfill/LML hardening (5) — #1095, #1117, #1137, #1139, library-identity-consumer SELECT re-fetches all resolved rows on every run #1144
Mojibake / Unicode (2) — #1090, #1091
Observability / docs (2) — #1081, Extract reference-depth sections from CLAUDE.md to docs/ #1152
Catalog / library small-surface (12) — Legacy deleteEntry mirror deletes wrong tubafrenzy show via MAX(ID) #1101 , Legacy entryIdMap keyed by play_order collides across shows #1103 , enrichPlaycuts returns non-deterministic artwork for split-format albums #1105 , Conditional-GET 304s stale: ETL/worker bypass updateLastModified; clock drifts forward #1106 , #1110, #1113, POST /flowsheet/end mirror runs endShow on leaveShow responses #1119 , #1121, #1127, #1138, flowsheet-dj-name + library-artist-name backfills: verifyComplete raises on orphan FK rows #1140 , backfill-legacy-ids: process.exit(1) skips cleanup; overcounts shows backfill #1141 , flowsheet-etl bulk-load reads entire dump into memory; OOM risk on EC2 #1142 , MirrorSQL.sendLocal: 50MB execSync buffer cap can truncate first-run incremental sync #1143
Filed 2026-06-13
Filed 2026-06-11 → 2026-06-12
Filed 2026-06-09 → 2026-06-10
Rotation identity migration — feat(schema): add rotation.lml_identity_id; mint LML identities on dj-site paste #1380 (schema, UNBLOCKED 2026-06-10), refactor(rotation-artist-backfill): switch to lml_identity_id fan-out; drop Discogs-specific carving #1381 (cron refactor, still blocked on LML#525); spawned from PR feat(rotation-artist-backfill): daily cron to refresh LML artist rows for active rotation #1376 code-review (rotation layer should not carry Discogs IDs)
artist_search_alias substrate cleanup — Tighten artist_search_alias substrate: drop no-op variants + distinguish discogs_member matches #1382 (no-op discogs_name_variation rows, CLOSED via PR Reject no-op discogs_name_variation rows in artist_search_alias writer (BS#1382) #1389 ), Distinguish discogs_member matches from in-library matches in artist_search_alias consumers #1383 (discogs_member distinction, CLOSED via PR fix(concerts-artist-resolver): exclude discogs_member from alias arm (BS#1383) #1384 resolver arm only — catalog-search arm tracked via BS#1275); spawned from Frequency analysis: how often will the venue-events scraper surface a WXYC-relevant artist? #1368 Path A audit
Type consolidation — Consolidate ArtistSearchAliasSource type and partition into a single source of truth #1390 (ArtistSearchAliasSource drift across four sites); spawned from PR fix(concerts-artist-resolver): exclude discogs_member from alias arm (BS#1383) #1384 round-2 review
Auth + scraper cleanup — Add concerts.first_scraped_at (INSERT-only) for scraper-stability measurement #1385 (concerts.first_scraped_at, CLOSED via PR feat(concerts): add first_scraped_at INSERT-only column for scraper-stability clock #1386 ), #1387 (auth shouldHandleError predicate, CLOSED via PR auth: pass explicit shouldHandleError predicate to Sentry.setupExpressErrorHandler #1388 — audit confirmed v10 honors shouldHandleError, refocusing Sentry SDK setupExpressErrorHandler isn't capturing bare exceptions on POST /flowsheet #1367 root-cause hypothesis), #1391 (auth flowsheet OIDC trustedClient + helper extraction, CLOSED via PR #1392)
Filed 2026-06-07 → 2026-06-09
Filed 2026-06-06 → 2026-06-07
Filed 2026-06-04 → 2026-06-05
Filed 2026-06-03
Trackers + epics — [Tracker] artist-search-alias plan — PRs 1-5 shipped, PR 6 + follow-ups outstanding #1273 , [Tracker] Project #32 close-out sequencing #1279 , [Epic] MD-set "Not on Discogs" flag for catalog releases #1280 , [Tracker] Follow-up: extend gate to library-identity-consumer, library-canonical-entity-backfill, six ungated lml-client exports #1285 , Artist-search-alias v2 backlog — deferred optimizations + cleanup #1290
Discogs-unavailable sub-issues — 1a: Schema migration + PATCH /library/:id extension for discogs_unavailable #1281 (1a), 1b: Extend @wxyc/lml-client lookupMetadata + bulkLookupMetadata with discogsUnavailable gate #1293 (1b), 1c: Wire discogsUnavailable through callers + album-level-backfill candidate filter #1294 (1c), #1282 (2), #1283 (3)
Artist-search-alias — PR 6 — flip CATALOG_SEARCH_ALIAS_ENABLED=true on prod (deploy-only) #1274 (flag flip; NOW FULLY UNBLOCKED), #1275 (api.yaml codegen), First-cron-tick observation: artist-search-alias-consumer #1276 (first cron tick), #1277 (jest.mock envInt sweep), alias-aware LATERAL JOIN: GIN trigram index unused; 3-6.5x p95 regression on selective queries #1318 (perf regression, CLOSED 2026-06-14)
Observability — Cron jobs' Sentry spans never reach Sentry (tracesSampleRate=0 default, org-wide) #1299 (org-wide Sentry traces=0)
Incident follow-ups — #1271 (POST /flowsheet error burst)
Cleanup — [C5-cleanup] Delete orphaned enrichment + linkage services after #894 callsite removal #1322 (C5-cleanup orphan services)
Filed 2026-05-29 → 2026-06-02
Pre-audit clusters (carried)
Unchanged: Post-launch service hardening 8 epics (#876 closed-in-effect, #877, #878, #879 , #880 closed, #881, #882, #969 closed); LML coordinator + timeouts (#885 closed, #886 closed, #990 , #991 , #962 , #1011 , #1053); rotation picker plan-shape revert (#1030 gated on #1195 ); cross-cache-identity (#663, #664, #521, #801, #974); catalog search (#233, #670, #871); graph chain (#249 , #250 , #251 ); ETL/data integrity (#516, #939, #961); mojibake (#655 ); operational/incidents (#937 , #1009, #1041); refactor/chore (#610, #611, #613, #614, #615, #650, #651 , #681, #979, #980, #981); auth/permissions (#275, #393, #671, #966 ); search (#233, #938, #871, #1162 ); stability (#1051 ); CI/chore (#133).
How to find work
PR 6 — flip CATALOG_SEARCH_ALIAS_ENABLED=true on prod (deploy-only) #1274 alias flag flip is the highest-leverage unblocked item as of 2026-06-14. Operator-side T-1 verification (substrate-populated SQL + canonical demo-artist chain), then CATALOG_SEARCH_ALIAS_ENABLED=true. No code change.
Slot ordering is in [Tracker] Project #32 close-out sequencing #1279 . That tracker is the canonical priority for Project Simplifies the logic surrounding the USE_CI env variable flag and adds default values #32 -scope hardening; treat its checklist as the working list.
The audit cluster (Legacy deleteEntry mirror deletes wrong tubafrenzy show via MAX(ID) #1101 -library-identity-consumer SELECT re-fetches all resolved rows on every run #1144 ) is internally well-cross-referenced via ## Related sections in each body — when picking up one, scan the Related list before starting.
Native blockedBy relationships render under the issue's Relationships pill. Cross-cache-identity blockers (#663 → wxyc-shared v0.6.0; Apply artist-name canonicalization in Backend-Service (per WXYC/tubafrenzy#496 M3.3) #655 → tubafrenzy#496 / docs#16) are the main remaining ones. Active cross-repo chains: rotation-identity (refactor(rotation-artist-backfill): switch to lml_identity_id fan-out; drop Discogs-specific carving #1381 → LML#525 + BS#1380 ≥99% coverage + BS#1402 dashboard cutover); artist_search_alias catalog-search arm → BS#1275.
Per-issue triage commentary is on each issue's page (look for "Triage finding" / "Status update" / "Sequencing concern" comments — latest pass dated 2026-06-13).
Closures since the 2026-06-12 tick: 5 issues (Flowsheet ETL: shows.legacy_dj_name occasionally not populated even when tubafrenzy has DJ_NAME #605 , [Epic] Aubrey Hearst on-air incident (2026-06-02) follow-ups #1288 , alias-aware LATERAL JOIN: GIN trigram index unused; 3-6.5x p95 regression on selective queries #1318 , PII leak: flowsheet ETL writes DJ_NAME (real name) into shows.legacy_dj_name, surfaced on v2 marker wire #1393 , OIDC loginPage points at a /sign-in route that doesn't exist; delegate to dj-site #1395 ) via 4 merged PRs (fix(privacy): pull DJ_HANDLE not DJ_NAME into shows.legacy_dj_name (closes #1393) #1394 , feat(auth): delegate OIDC loginPage to dj-site /login #1396 , fix(legacy-dj-name-remediation): truncate DJ_HANDLE to 128 chars (BS#1393 hot-fix) #1399 , fix(library-search): replace alias LATERAL JOIN with UNION ALL (#1318) #1403 ). New: Legacy mirror writes real names to tubafrenzy DJ_NAME — defensive contract for write-only PII #1400 (defensive PII contract), chore(sentry): migrate rotation-artist-backfill dashboards to identity-shape metrics #1402 (dashboard cutover). Net 165 open. Upstream blockers cleared: alias-aware LATERAL JOIN: GIN trigram index unused; 3-6.5x p95 regression on selective queries #1318 (perf regression). Still open: LML#525 (BS#1381; decomposed into LML#547-551), wxyc-shared#165 (BS#1335), BS#1275 (Distinguish discogs_member matches from in-library matches in artist_search_alias consumers #1383 catalog-search arm).
Cross-repo rollup: items from this tracker that block other repos or carry external deadlines are mirrored in Cross-repo critical path (#33).
End-of-day triage of all 165 open issues in this repo. Entry point for any contributor or agent picking up the work: where to start, what blocks what, which proposals overlap.
This tracker is intended to be edited in place, not appended to. When triage state changes, update the relevant section. Don't add a new "Updates YYYY-MM-DD" block.
Org-level entry point: WXYC/wiki#5 (cross-repo P0 sequencing + patterns). Active org Projects: Post-launch service hardening (#32) with sequencing tracker #1279; June 2026 action plan (#35) via WXYC/wiki#77; Cross-repo critical path (#33).
State as of 2026-06-13
One-day delta since the 2026-06-12 tick: 5 issues closed (#605, #1288, #1318, #1393, #1395), 4 PRs merged (#1394 PII source fix + remediation, #1399 hot-fix DJ_HANDLE truncation, #1396 auth OIDC loginPage delegation, #1403 LATERAL JOIN → UNION ALL rewrite + cleanup commits c22a9f6 / e83bbc1). Net 165 open: 5 closures, 2 new (#1400 defensive PII contract for tubafrenzy DJ_NAME write site, #1402 sibling dashboard inventory for #1381).
(1) CRITICAL #1393 PII leak CLOSED. PR #1394 (source fix at three ETL writers —
fetch-legacy.ts,job.tsbulk-load tuple position,backfill-legacy-ids.ts— plus one-shotjobs/legacy-dj-name-remediation/) merged 2026-06-12T23:20Z; PR #1399 hot-fix (DJ_HANDLE truncation to 128 chars) merged 2026-06-13T00:40Z. The public v2 marker wire no longer surfaces real names. Follow-up #1400 filed (defensive contract for the upstreamhttp.mirror.ts:362-364write site that still sendsdj.realName || dj.nameinto tubafrenzy'sDJ_NAMEcolumn — the leak source from the opposite direction, not active today because no BS code path reads back from tubafrenzy'sDJ_NAME, but the contract is brittle to a future engineer reaching for it). Distinct follow-up PR #1401 is the docs-only schema invariant.(2) #1318 LATERAL JOIN regression CLOSED — #1274 alias flag flip is now fully unblocked. PR #1403 replaced the alias-aware LATERAL JOIN with a precomputed
alias_hitsCTE + UNION ALL form (verified atapps/backend/services/library-search.service.ts:139-242); follow-up commit c22a9f6 dropped the now-deadaliasActiveparameter chain throughbuildWhereClause/buildConditionFragment/buildAllFieldMatch, and e83bbc1 wrapped the UNION ALL in a subquery so the outer expression ORDER BY behaves under PG's parse rules. #1274's three nativeblockedByedges (#1318, #1382, #1383) are all CLOSED — the substrate is clean, the perf regression is gone, the flag is ready to flip. Outstanding preconditions on #1274 itself: (a) discogs-cache rebuild since 2026-05-13, (b) consumer #1266 first-tick observation via #1276, (c) substrate-populated SQL, (d) canonical demo-artist chain verification. All are operator-side checks, not engineering work.(3) Rotation identity migration — one more precondition filled. #1402 filed 2026-06-13 as the sibling dashboard-migration inventory issue. #1381's acceptance criteria explicitly require dashboard cutover BEFORE the metric-shape switch ships (otherwise saved discover queries and alert rules on
backfill.releases_*/backfill.artists_*go silently dead). NativeblockedByalready wired: #1381 ← {LML#525 (open), BS#1380 (open, unblocked), BS#1402 (open, ≥99% coverage prerequisite still standing)}. #1402 fills one of three preconditions the tracker called out 2026-06-12 as missing; LML#525 + BS#1380 ≥99% remain. LML decomposed #525 into 5 sub-issues today (LML#547 musicbrainz_release, #548 bandcamp, #549 spotify_album, #550 apple_music_album, #551 discogs_master legs) — still upstream-blocked.(4) Closures roundup since 2026-06-12:
shows.legacy_dj_nameoccasionally not populated. Closed 2026-06-13 (decision; sibling to the PII leak: flowsheet ETL writes DJ_NAME (real name) into shows.legacy_dj_name, surfaced on v2 marker wire #1393 fix work — coverage gap closed-as-resolved alongside the PII fix).New work filed since 2026-06-12 (both open):
DJ_NAMEwrite site (http.mirror.ts:362-364). Not an active leak today — PII leak: flowsheet ETL writes DJ_NAME (real name) into shows.legacy_dj_name, surfaced on v2 marker wire #1393 sealed the read path. Recommended posture: (1) doc-only code comment onmapShowToTubafrenzy:364calling out the write-only-PII contract, plus (4) eventual renameshows.legacy_dj_name→shows.legacy_dj_handleonce tubafrenzy is fully sunset. Skip (3) stop-writing-it until then. Labelledtubafrenzy.backfill.releases_*/backfill.artists_*with the new identity-shape attribute names; addnot_found / identities_scanned > 1%rolling 24h alert (the corruption signal). Must complete BEFORE refactor(rotation-artist-backfill): switch to lml_identity_id fan-out; drop Discogs-specific carving #1381 deploys. Labelledcross-cache-identity.P0 sequencing changes: #1393 removed from slot 1 (closed). #1318 removed from slot 3 (closed). #1274 promoted to a near-top slot — fully unblocked operator gate, no longer a code-side concern. #1322 caveat refreshed. #1402 takes a slot near #1381 as part of the rotation-identity chain.
Verified against tree HEAD 2026-06-14:
apps/backend/services/library-search.service.ts:139confirmed —aliasActivegates the CTE + UNION ALL branch;aliasOffbranch is the byte-identical pre-alias-aware LATERAL JOIN: GIN trigram index unused; 3-6.5x p95 regression on selective queries #1318 path. Cleanup commit c22a9f6 verified the innerbuildAllFieldMatchno longer references the LATERALalias_hit.max_simalias.jobs/flowsheet-etl/fetch-legacy.ts:78confirmed — SELECTsIFNULL(rs.DJ_HANDLE, '')(wasDJ_NAME). PII leak: flowsheet ETL writes DJ_NAME (real name) into shows.legacy_dj_name, surfaced on v2 marker wire #1393 source fix landed.jobs/flowsheet-etl/job.ts:200confirmed —legacy_dj_name: truncate(tuple[4] != null ? String(tuple[4]) : null, 128)(wastuple[2]). Schema comment atjob.ts:191-194documents the swap with explicit PII rationale.apps/backend/middleware/legacy/http.mirror.ts:362-364confirmed —djName: dj.realName || dj.namestill active. Legacy mirror writes real names to tubafrenzy DJ_NAME — defensive contract for write-only PII #1400's premise holds.shared/lml-client/src/index.ts— single chokepoint vialookupMetadataconfirmed (BS#906/G4 invariant). refactor(rotation-artist-backfill): switch to lml_identity_id fan-out; drop Discogs-specific carving #1381 will addrefreshForIdentitieshere.apps/backend/app.ts:68 origin: process.env.FRONTEND_SOURCE || '*'+credentials: true— cors: '*' fallback combined with credentials:true when FRONTEND_SOURCE unset #1107 CORS fail-open still present.P0 sequencing — recommended order
SENTRY_TRACES_SAMPLE_RATE=1.0on EC2.env(Option A). Org-wide observability outage on seven cron paths today; unblocks verification of First-cron-tick observation: artist-search-alias-consumer #1276 acceptance criteria + Slot 6 (Complete historical drain at last_id=14603, then retire the daily flowsheet-metadata-backfill cron #1011 historical drain monitoring) + Slot 7 ([C6] Retune flowsheet-metadata-backfill cron as safety-net (hourly, 15-min grace) #895 cron retune). One-config fix; backend/auth/enrichment-worker init already sets own rates. Reinforced by Sentry SDK setupExpressErrorHandler isn't capturing bare exceptions on POST /flowsheet #1367 — the broader observability concern (bare-exception capture gap) makes the tracing fix more urgent. Now the top of the queue with PII leak: flowsheet ETL writes DJ_NAME (real name) into shows.legacy_dj_name, surfaced on v2 marker wire #1393 closed.shouldHandleErrorIS honored on@sentry/node ^10.53.1. Suspect Express 5 + async-handler boundary. HIGH severity: any 5xx code path without explicitSentry.captureExceptionis currently invisible. Pairs with Cron jobs' Sentry spans never reach Sentry (tracesSampleRate=0 default, org-wide) #1299 as the observability hardening pair.CATALOG_SEARCH_ALIAS_ENABLED=trueon prod after the checks.rotation.lml_identity_id integer NULL; dj-site paste flow mints viaPOST /api/v1/identity/resolve(NULL-on-LML-outage fallback). Dual-write, never null-out existingdiscogs_release_id. Acceptance: ≥99% backfill coverage on active rotation rows before signaling BS#1381 to proceed.backfill.not_found / backfill.identities_scanned > 1%rolling 24h (the corruption signal — invisible without this counter).enrichment.service.ts+flowsheet-linkage.service.ts+linkage-metrics.service.ts+ four orphan tests +app.tsdrain wiring. Mechanical, single PR, ~30 min. Caveat (per Reconcile SEARCH_TYPE_CONFIDENCE table with BS#1351 rotation-picker trust policy #1356 correction):flowsheet-linkage.service.tsis still active — verify before deletion. The C5-cleanup scope may be narrower than the issue states.Authorization: Bearerheader +crypto.timingSafeEqual; remove secret from URL query string. Carried; one-deploy-window backward-compat shim.'*'fallback +credentials: true) is the priority of the five because it fails open.ArtistSearchAliasSourcetype intoshared/database/src/artist-search-alias-sources.tswith compile-time exhaustiveness assertion + close(string & {})union at wire-shape projection. S complexity, unblocked, removes a recurring drift hazard before catalog-search-alias formalization (BS#1275 / wxyc-shared codegen) lands.http.mirror.ts:362-364. Doc-only code comment + scheduled rename ofshows.legacy_dj_name→shows.legacy_dj_handle. Not active leak; brittle to future engineer reaching forDJ_NAMEas identifier.flowsheet-metadata-backfill. Subsumes flowsheet-metadata-backfill-cron: ~21% LML timeout rate persists post-LML#337/#359 fixes; investigate per-call budget vs cold-cache reality #1064 when shipped.last_id=14603. Promoted: LML#504/Repair Drizzle migrations metadata (missing snapshots, broken prevId chain) #505/ETL to populate artists reconciled-identity columns from LML's entity.identity #506 wrong-data cluster mostly settled (only Bound legacy mirror queue disk reports and add Sentry breadcrumbs #507 perf-only remains). Still gated on Slot 5.5 (Flip PROXY_METADATA_SINGLE_LOOKUP=true in prod once G2 ships #917) + Cron jobs' Sentry spans never reach Sentry (tracesSampleRate=0 default, org-wide) #1299 observability. Re-read Drainenriched_matchrows with NULL artwork_url stranded by LML _resolve_fallback_artwork bug (LML#408) #1209 deferral rationale before re-kicking off.flowsheet-linkageshould gate at the coordinator (drop gray-zone-review cohort) or keep theSEARCH_TYPE_CONFIDENCEbands. Standalone policy question post-PR feat(lml): coordinator requireSearchType opt; migrate librarian writes (BS#1355) #1363. metadata.service.ts: define track-context trust policy for LML search_type (compilation-accept) #1359 is the parallel decision formetadata.service.ts:68-77(track-context surface;compilationis legitimate there). Rotation-picker tier-3: emit Sentry span attribute / breadcrumb for reject reason #1357 will close itself once wxyc-shared#172 step 3 ships.PROXY_METADATA_SINGLE_LOOKUP=true. Sequenced to fire ~1 week after [Epic G] Capture enrichment-outcome quality (all-null result), not just LML client throws #969 has baseline ([Epic G] Capture enrichment-outcome quality (all-null result), not just LML client throws #969 shipped 2026-06-03 via PR feat(enrichment-worker): empty-outcome capture with stable Sentry fingerprint #1304).discogs_release_idtwo-tier walk →lml_identity_idone-tier batched call.Critical / high severity
CRITICAL (immediate, security or data corruption):
'*'fallback combined withcredentials: true.NODE_ENVfence breaks.HIGH (correctness, observability, narrower blast radius):
shouldHandleErrorIS honored on v10); now suspect Express 5 + async-handler boundary.void startCdcDispatcher().fuzzySearchLibraryreturns 5,134 rows forn=10on V/A queries (sibling to dj-site#657).enriched_matchrows with NULL artwork_url stranded by LML _resolve_fallback_artwork bug (LML#408) #1209 — LML#408 NULL-artwork drain DEFERRED; LML#408 itself closed 2026-05-29, but the stability gate decision is independent — re-read needed.flowsheet-linkageat coordinator vs. keep gray-zone bands. The cross-callsite asymmetry BS-wide search_type gate proliferation: gate at LML coordinator or response shape, not per-callsite #1355 closed atfireAndForgetCanonicalEntityis gone; this is now about gray-zone review-queue behaviour.metadata.service.ts:68-77track-context trust policy decision (acceptcompilation? reject? expose as opt?).bioTokens. iOS + dj-site both have full parsers.Cross-cluster conflicts (decide once before starting)
Artist-search-alias flip (#1274) — FULLY UNBLOCKED 2026-06-14
PR #1403 closed #1318 (LATERAL JOIN → UNION ALL) with two follow-up cleanup commits (c22a9f6 drops the dead
aliasActivechain; e83bbc1 wraps the UNION in a subquery for outer ORDER BY). Combined with #1382 (PR #1389, writer-side reject + one-shot DELETE) and #1383 (PR #1384, resolverdiscogs_memberfilter) closing earlier in the cycle, all three native blockers on #1274 are CLOSED. The substrate is clean and the perf regression is gone. Remaining work is operator-side T-1 verification only — no engineering blocker. Sequence: run the substrate-populated SQL + canonical demo-artist chain on prod, thenCATALOG_SEARCH_ALIAS_ENABLED=true. The catalog-search formalization arm of #1383 (option b — propagatesourcethroughArtistMatchHint) is tracked via BS#1275 + BS#1390 (type consolidation); UX-shaped harm, not data-shaped, so it can chase the flag flip.Rotation identity migration (#1380 → #1402 → #1381) — two of three preconditions filled
POST /api/v1/identity/resolveforkind:'release'. Done.POST /api/v1/cache/refresh-for-identitiessource-agnostic endpoint. Still upstream-blocked.rotation.lml_identity_id; dj-site paste flow dual-writes; backfill cron populates existing rows. Acceptance: ≥99% backfill coverage.blockedBycorrectly wired to all three.This remains the canonical example of dependency direction across the BS↔LML boundary: BS owns rotation, LML owns identity, BS calls LML at the dj-site paste boundary AND at the cron-refresh boundary.
#1336 vs #1331 — cache-hit shape parity
PR #1332 shipped #1331's cache-first cutover but cache-hit responses now omit
discogsArtistId,genres,styles,label,fullReleaseDate,tracklist,artistImageUrl,bioTokens— fields LML returns butalbum_metadatadoesn't carry. dj-siteAlbumDetailPaneland iOS V1PlaycutMetadataService.swift:109usediscogsArtistIdto gate the artist sub-panel; both silently degrade on cache-hit. #1336 extendsalbum_metadataschema + writer to persist these fields; cutover is gradual as enrichment-worker UPSERTs land. Schedule before the cache-hit rate climbs further.#1280 "Not on Discogs" epic — sequence vs Project #32
#1280 introduces a new gating surface across lml-client, library controller, three jobs, one new cron. Slot ordering: 1a (schema + PATCH) → 1b (lml-client gate) → 1c (caller wiring) → 2 (library-artwork-url-backfill migration) → 3 (recheck cron). PR #1154 (Jackson's catalog edit endpoints) is a soft prerequisite for 1a; fallback per plan §10.4 lets 1a land directly if #1154 stalls past 2026-06-15. #1285 tracks deferred surface (
library-identity-consumer,library-canonical-entity-backfill, six ungatedlml-clientexports). Joined to Project #32 board.Cross-org staging epic (BS#1335 + peers)
New cross-repo workstream surfaced 2026-06-04. Phases:
main.wxyc-ec2+ deploy-staging.yml + prod trigger flip. Highest blast-radius phase (shares prod box).Audit cluster vs Epic F (#880) — #1106 re-scope still pending
Epic F closed 2026-06-02. #1106's "drift forward" half is obsolete; the "bypass" half is still live. Rescope #1106 to the bypass concern only.
Audit cluster vs Epic E (cache hierarchy, #879)
Unchanged. #1089 + #1105 ship standalone; fold their tests into Epic E child #988.
#1199 vs #1064 — supersession question
Unchanged. Close #1064 as superseded once #1199 ships.
Epic C C5 (#894) vs Epic B B3 (#886) — RESOLVED
Both closed 2026-06-02/03. C5 shipped (PR #1323); B3 closed as superseded.
#990 / #991 / #962 — LML timeout & limiter shape
Unchanged. Sequence: #990 → #991 → revisit #962 later.
#917 PROXY_METADATA_SINGLE_LOOKUP flip — #969 baseline accruing
#969 shipped 2026-06-03 via PR #1304. Slot 5.5 of #1279 schedules the flip to fire ~mid-Slot-5 after #969 has accrued ~1 baseline week. Roll back if
enrichment-empty-outcomealert or canaryEnrichmentLagfires.#644 (linkage SSE re-emit) — path (b) chosen
F1 (#902) shipped 2026-06-02; recommend close unless sub-3s SSE-level latency on rotation_bin is required for iOS.
#1030 — blocked on #1195 decision
Unchanged.
#1262 — anonymous_devices removal — unblocked
Still unblocked, low-priority cleanup.
search_type trust-policy cluster — #1355 SHIPPED, dependents are now policy decisions
#1355 closed 2026-06-08 via PR #1363. Approach implemented: gate moved to the
LmlLookupCoordinatorvia arequireSearchType: 'direct'opt (with companionlml.coordinator.trust_reject_reasonSentry span attribute, sliceable ascaller × hit × trust_reject_reason). Librarian writes (addAlbum,fireAndForgetCanonicalEntity,enrichWithArtwork) now flow through the gated coordinator.The three "blocked by #1355" follow-ups remain open but are no longer dependent bugs:
flowsheet-linkage.service.tscallsmapLookupToCanonicalEntitydirectly (no coordinator) and uses the non-direct confidence bands (fallback: 0.5,alternative/compilation/song_as_artist: 0.3) to route tolow_confidencereview-queue status — the bands are load-bearing there. Open question: shouldflowsheet-linkagealso gate at the coordinator (dropping the gray-zone-review cohort entirely)?trust_reject_reasonattribute. Pending close once LookupResponse: discriminated result_kind on synthesized vs Discogs-matched results wxyc-shared#172 migration step 3 ships (renames opt torequireResultKind: 'discogs').metadata.service.ts:68-77track-context surface wherecompilationis legitimate. Open as policy decision on its own timeline; not blocked.cleanDiscogsBio audit (#1360) — premise questioned
PR #1358 shipped BS#1354 (strip numeric-id tokens like
[a8390436]). BS#1360 audits the strip premise: iOS (DiscogsMarkupParser.swift) and dj-site (<DiscogsMarkup tokens=...>) both have full parsers. iOS V1 receivesbioTokenspre-parsed from the proxy; V2 flowsheet serves only the strippedartist_biostring. So the strip is destroying link information V2 clients are equipped to render, with no offsetting fallback benefit (V2 has no rawless fallback path).Three options outlined in #1360 body: (1) serve
bioTokenseverywhere (long-term right answer, needs@wxyc/sharedDTO change + coordinated client migration), (2) stop stripping (minor cosmetic regression for fallback paths in exchange for restored link info), (3) document the trade-off + status quo. Needs decision.Touring-events feature — substrate complete; cleanup follow-ups closed
All four substrate PRs (#1348 schema, #1345 RHP scraper, #1376 rotation-artist-backfill, #1375 concerts-artist-resolver) merged by 2026-06-10. #1368 Path A audit shipped → #1382 + #1383 spawned and BOTH CLOSED 2026-06-10 (via PR #1389 writer-side reject + one-shot DELETE; PR #1384 resolver-arm
discogs_memberfilter). PR #1386 addedconcerts.first_scraped_atfor scraper-stability clock (closed #1385).Remaining open follow-ups:
concertsdata #1373 — Path B re-run gated on ≥30 days ofconcertsdata + Backfillconcerts.headlining_artist_idvia local artist + alias resolver #1372 resolver having run (now done). Earliest 2026-07-10.ArtistSearchAliasSourcedeclaration sites).Catalog-search formalization arm of #1383 still waits on BS#1275. Bandsintown explicitly excluded as a
concertssource — Data Applications Terms forbid persistent caching. iOS / dj-site / submission-form surfaces are still deferred until #1368 memo lands a decision.Yenbett incident close-out — wrong-data cluster mostly settled
The original Yenbett picker incident (BS#1351) had two upstream contributors: BS's missing
search_typegate (closed via PR #1352) AND LML's lack of streaming-source probing for non-catalog albums (LML#487, closed 2026-06-07). LML#487's fix inenrich_artwork_resultsintroduced new wrong-data risk; all three correctness items now CLOSED: LML#504 (artist-scoped field gate, 2026-06-09), LML#505 (Deluxe/Remaster pairing, 2026-06-09), LML#506 (MB tracklist rescue, 2026-06-09). LML#507 (wasted prefetch — perf, not correctness) remains open. BS#1209 + BS#1011 drain gate is largely clear — re-read deferral rationale and verify, then re-kick off if appropriate.Obsolete / needs-revision (recommend close)
trust_reject_reasonattribute; pending close once wxyc-shared#172 step 3 ships.Open hold-for-decision
enriched_matchrows with NULL artwork_url stranded by LML _resolve_fallback_artwork bug (LML#408) #1209 — re-read deferral rationale; LML#408 + LML#487 both closed but LML#487 spawned LML#504/Repair Drizzle migrations metadata (missing snapshots, broken prevId chain) #505/ETL to populate artists reconciled-identity columns from LML's entity.identity #506 wrong-data cluster. Drain blocked until that cluster settles.flowsheet-linkageat the coordinator (drop cohort) or keep theSEARCH_TYPE_CONFIDENCEbands?metadata.service.ts:68-77(compilationis legitimate UX; need decision on a track-context helper or coordinator opt).Open PRs
library-identity-consumershows.legacy_dj_nameDJ_HANDLE invariant (#1393 follow-up)Cross-repo dependencies (native + body prose)
record_label→label)concertsdataCross-repo runtime risks
POST /api/v1/cache/refresh-for-identitiessource-agnostic endpoint). Decomposed 2026-06-13 into per-source sub-tasks: LML#547 (musicbrainz_release), LML#548 (bandcamp), LML#549 (spotify_album), LML#550 (apple_music_album), LML#551 (discogs_master). All still open. Consumes the release-identity IDs from LML#526 (closed).variants[]withsources_presentpopulated. Was directly relevant to BS#1319 substrate fill; less pressing now that alias-aware LATERAL JOIN: GIN trigram index unused; 3-6.5x p95 regression on selective queries #1318 closed via UNION ALL rewrite (alias query shape is no longer bottlenecked)._fetch_apple_music_urlpath used by BS proxy.record_labelvslabelfield name).rotation_binJOIN; trace into BS rotation read endpoint.result_kindon LookupResponse; closes Rotation-picker tier-3: emit Sentry span attribute / breadcrumb for reject reason #1357 when step 3 ships.Cluster map (165 open)
Active cross-repo epics + trackers
enriched_matchrows with NULL artwork_url stranded by LML _resolve_fallback_artwork bug (LML#408) #1209 drain deferred (LML#408 + LML#487 + LML#504/Repair Drizzle migrations metadata (missing snapshots, broken prevId chain) #505/ETL to populate artists reconciled-identity columns from LML's entity.identity #506 ALL CLOSED upstream as of 2026-06-09); Complete historical drain at last_id=14603, then retire the daily flowsheet-metadata-backfill cron #1011 paused at last_id=14603, now mostly unblockedconcerts.first_scraped_at(INSERT-only) for scraper-stability measurement #1385). Remaining: Frequency analysis: how often will the venue-events scraper surface a WXYC-relevant artist? #1368 (memo + Path A audited), Path B re-run: forward-look frequency analysis after 30 days ofconcertsdata #1373 (Path B forward-look, earliest 2026-07-10), Consolidate ArtistSearchAliasSource type and partition into a single source of truth #1390 (type consolidation post-fix(concerts-artist-resolver): exclude discogs_member from alias arm (BS#1383) #1384 review); future iOS/dj-site/submission-form surfaces TBD.lml_identity_idAND the BS#1402 dashboard cutover lands AND LML#525 sub-tasks merge.Audit batch — 2026-05-25 residue
Filed 2026-06-13
http.mirror.ts:362-364upstream write to tubafrenzy'sDJ_NAME; doc-only + eventual schema rename; not active leak — PII leak: flowsheet ETL writes DJ_NAME (real name) into shows.legacy_dj_name, surfaced on v2 marker wire #1393 sealed the read path)Filed 2026-06-11 → 2026-06-12
Filed 2026-06-09 → 2026-06-10
discogs_name_variationrows, CLOSED via PR Reject no-op discogs_name_variation rows in artist_search_alias writer (BS#1382) #1389), Distinguish discogs_member matches from in-library matches in artist_search_alias consumers #1383 (discogs_memberdistinction, CLOSED via PR fix(concerts-artist-resolver): exclude discogs_member from alias arm (BS#1383) #1384 resolver arm only — catalog-search arm tracked via BS#1275); spawned from Frequency analysis: how often will the venue-events scraper surface a WXYC-relevant artist? #1368 Path A auditArtistSearchAliasSourcedrift across four sites); spawned from PR fix(concerts-artist-resolver): exclude discogs_member from alias arm (BS#1383) #1384 round-2 reviewconcerts.first_scraped_at(INSERT-only) for scraper-stability measurement #1385 (concerts.first_scraped_at, CLOSED via PR feat(concerts): add first_scraped_at INSERT-only column for scraper-stability clock #1386), #1387 (authshouldHandleErrorpredicate, CLOSED via PR auth: pass explicit shouldHandleError predicate to Sentry.setupExpressErrorHandler #1388 — audit confirmed v10 honorsshouldHandleError, refocusing Sentry SDK setupExpressErrorHandler isn't capturing bare exceptions on POST /flowsheet #1367 root-cause hypothesis), #1391 (auth flowsheet OIDC trustedClient + helper extraction, CLOSED via PR #1392)Filed 2026-06-07 → 2026-06-09
concerts.headlining_artist_idvia local artist + alias resolver #1372 (concerts-artist-resolver — CLOSED via PR feat(concerts-artist-resolver): backfill headlining_artist_id via local artist + alias resolver #1375), Path B re-run: forward-look frequency analysis after 30 days ofconcertsdata #1373 (Path B re-run, gated)setupExpressErrorHandlerskipping bare TypeErrors; discovered diagnosing #1271)Filed 2026-06-06 → 2026-06-07
Filed 2026-06-04 → 2026-06-05
record_label→labelalias rename)Filed 2026-06-03
Filed 2026-05-29 → 2026-06-02
enriched_matchrows with NULL artwork_url stranded by LML _resolve_fallback_artwork bug (LML#408) #1209) — LML#408 residue, drain deferred (LML#408 closed upstream; deferral rationale re-read pending)enriching_sinceprojectionvoid startCdcDispatcherstartup-error swallowPre-audit clusters (carried)
Unchanged: Post-launch service hardening 8 epics (#876 closed-in-effect, #877, #878, #879, #880 closed, #881, #882, #969 closed); LML coordinator + timeouts (#885 closed, #886 closed, #990, #991, #962, #1011, #1053); rotation picker plan-shape revert (#1030 gated on #1195); cross-cache-identity (#663, #664, #521, #801, #974); catalog search (#233, #670, #871); graph chain (#249, #250, #251); ETL/data integrity (#516, #939, #961); mojibake (#655); operational/incidents (#937, #1009, #1041); refactor/chore (#610, #611, #613, #614, #615, #650, #651, #681, #979, #980, #981); auth/permissions (#275, #393, #671, #966); search (#233, #938, #871, #1162); stability (#1051); CI/chore (#133).
How to find work
CATALOG_SEARCH_ALIAS_ENABLED=true. No code change.## Relatedsections in each body — when picking up one, scan the Related list before starting.blockedByrelationships render under the issue's Relationships pill. Cross-cache-identity blockers (#663 → wxyc-shared v0.6.0; Apply artist-name canonicalization in Backend-Service (per WXYC/tubafrenzy#496 M3.3) #655 → tubafrenzy#496 / docs#16) are the main remaining ones. Active cross-repo chains: rotation-identity (refactor(rotation-artist-backfill): switch to lml_identity_id fan-out; drop Discogs-specific carving #1381 → LML#525 + BS#1380 ≥99% coverage + BS#1402 dashboard cutover); artist_search_alias catalog-search arm → BS#1275.