diff --git a/.graphifyignore b/.graphifyignore index 2ade0ae..74cd6a4 100644 --- a/.graphifyignore +++ b/.graphifyignore @@ -45,6 +45,26 @@ cmd/migration-check/testdata/ # Frontend tooling config -- one node per JSON key, no architecture signal web/tsconfig.json web/components.json +web/package.json + +# Tests and generated code: ~60% of graph edges were test plumbing (testing.T, +# NewTestPool) and sqlc output, drowning real architecture. Source is findable by name. +*_test.go +*.test.ts +*.test.tsx +internal/db/sqlc/ + +# Per-plan execution logs for every phase; CONTEXT/RESEARCH/UI-SPEC keep the decisions +.planning/phases/*/*-PLAN.md +.planning/phases/*/*-SUMMARY.md +.planning/phases/*/*-REVIEW.md +.planning/phases/*/*-REVIEW-FIX.md +.planning/phases/*/*-UAT.md +.planning/phases/*/*-PATTERNS.md +.planning/phases/*/*-VERIFICATION.md +.planning/phases/*/*-SECURITY.md +.planning/phases/*/*-VALIDATION.md +.planning/phases/*/*-DISCUSSION-LOG.md # Maintenance: when a milestone completes, add that milestone's phase # directory under .planning/milestones/ to this list before the next diff --git a/.planning/STATE.md b/.planning/STATE.md index af9e337..32a25d3 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -514,6 +514,7 @@ _Closed 2026-09-05: Phase 16 gap G-16-1 (n1-boot guard-adoption skip) — quick | 261007-lc4 | Phase 24 comment cleanup: comment-only trim to 1-3 line why-notes with one doc ref, fixed inaccurate WithTags/merge-trigger/buildTagSuggestions comments, removed plan narration | 2026-10-07 | be98a62 | [261007-lc4-phase-24-comment-cleanup](./quick/261007-lc4-phase-24-comment-cleanup/) | | 261011-gq7 | Amend Phase 26 CONTEXT and UI-SPEC with grill decisions Q1–Q10 (derived selection, outcome-only bulk responses + refresh, ordered-lock bulk tag attach, single-statement remove/preferences, pending-alert disclosure) and add withdraw-pending-events todo | 2026-10-11 | 6408d28 | [261011-gq7-amend-phase-26-docs-with-grill-decisions](./quick/261011-gq7-amend-phase-26-docs-with-grill-decisions/) | | 261011-moj | Amend Phase 26 CONTEXT and UI-SPEC with UI review U1–U4 (route-level confirm + close→clear→focus order, scroll-padding focus clearance, one-row phone bar, remove-tag Undo) | 2026-10-11 | 9ac478c | [261011-moj-amend-phase-26-ui-spec-and-context-with-](./quick/261011-moj-amend-phase-26-ui-spec-and-context-with-/) | +| 261019-jkv | Refactor phase 26 bulk UI: shared preference options, popover and outcome-messages modules, useBulkSelection hook | 2026-10-19 | 66e1990 | [261019-jkv-refactor-phase-26-bulk-ui-preferenceopti](./quick/261019-jkv-refactor-phase-26-bulk-ui-preferenceopti/) | ### Roadmap Evolution diff --git a/.planning/quick/261019-jkv-refactor-phase-26-bulk-ui-preferenceopti/261019-jkv-PLAN.md b/.planning/quick/261019-jkv-refactor-phase-26-bulk-ui-preferenceopti/261019-jkv-PLAN.md new file mode 100644 index 0000000..bca9821 --- /dev/null +++ b/.planning/quick/261019-jkv-refactor-phase-26-bulk-ui-preferenceopti/261019-jkv-PLAN.md @@ -0,0 +1,12 @@ +# Quick 261019-jkv: phase 26 bulk UI cleanup + +Source: architecture review + grilling (candidates 1 and 2). Branch refactor/phase-26-bulk-cleanup. +Each step is one commit; gate = prettier --write/--check, pnpm test (web only, no Go changes). + +1. lib/preferenceOptions.ts: shared option lists + EVENT_TYPE_ORDER; PreferencesDelta defined once in api.ts. +2. BulkPreferencesPopover.tsx + lib/useBarClearance.ts extracted from BulkActionBar.tsx. +3. lib/bulkOutcomeMessages.ts: pure toast data + table tests; route switched over. +4. lib/useBulkSelection.ts: selection, remove-confirm, handlers, Undo, focus out of routes/watchlist.tsx. +Comments in touched files: 1-3 lines, one design-doc ref, no opaque tags. +CONTEXT.md: add bulk selection, effective selection, bulk outcome. +Existing integration tests stay unedited and green. diff --git a/.planning/quick/261019-jkv-refactor-phase-26-bulk-ui-preferenceopti/261019-jkv-SUMMARY.md b/.planning/quick/261019-jkv-refactor-phase-26-bulk-ui-preferenceopti/261019-jkv-SUMMARY.md new file mode 100644 index 0000000..428592f --- /dev/null +++ b/.planning/quick/261019-jkv-refactor-phase-26-bulk-ui-preferenceopti/261019-jkv-SUMMARY.md @@ -0,0 +1,14 @@ +--- +status: complete +--- +# Quick 261019-jkv: phase 26 bulk UI cleanup + +Four refactor commits on refactor/phase-26-bulk-cleanup, no behavior change; all 793 web tests pass, existing integration tests unedited. + +- preferenceOptions.ts shared by the card and bulk bar; PreferencesDelta defined once in api.ts. +- BulkPreferencesPopover and useBarClearance extracted (BulkActionBar 585 -> 330 lines). +- bulkOutcomeMessages.ts: pure toast data with table tests. +- useBulkSelection.ts: selection, remove confirm, handlers, Undo, focus (watchlist.tsx 1065 -> 711 lines). +- CONTEXT.md: bulk selection, effective selection, bulk outcome. + +Not done: embedded SPA bundle (internal/webassets) not rebuilt; integration cases duplicated by the new pure tests were kept, not deleted. diff --git a/CONTEXT.md b/CONTEXT.md index b7c61a1..b3a70f9 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -95,3 +95,15 @@ _Avoid_: filter (that narrows the existing watchlist) **Note**: The single plain-text annotation on a watchlist entry. It goes away when the artist is removed from the watchlist, and the remove toast's Undo restores it. _Avoid_: notes (there is only one), comment, memo + +**Bulk selection**: +The set of watchlist entries the user has checked for one bulk action (add or remove tag, change preferences, remove). It is never trimmed when a filter hides an entry, so it can hold entries that are not currently shown. +_Avoid_: multi-select, batch + +**Effective selection**: +The bulk selection restricted to the entries currently visible. Every bulk action, the bar's count and Undo work on this set, so a hidden entry is never changed by accident. +_Avoid_: visible selection, active selection + +**Bulk outcome**: +What a bulk request reports back: the entries it **applied** to, and the entries it **skipped** with a reason (the artist is at the tag cap, or the entry is already gone). A skip is a result, not an error; the whole request only fails if nothing could be attempted. +_Avoid_: partial failure, result set diff --git a/graphify-out/GRAPH_REPORT.md b/graphify-out/GRAPH_REPORT.md index 50eb5dc..5baaa91 100644 --- a/graphify-out/GRAPH_REPORT.md +++ b/graphify-out/GRAPH_REPORT.md @@ -1,652 +1,475 @@ -# Graph Report - drop-tracker (2026-10-06) +# Graph Report - drop-tracker (2026-10-19) ## Corpus Check -- 332 files · ~451,884 words +- 226 files · ~242,404 words - Verdict: corpus is large enough that graph structure adds value. ## Summary -- 3075 nodes · 9590 edges · 173 communities (110 shown, 25 thin omitted) -- Extraction: 89% EXTRACTED · 11% INFERRED · 0% AMBIGUOUS · INFERRED: 1060 edges (avg confidence: 0.85) +- 1784 nodes · 3773 edges · 128 communities (75 shown, 17 thin omitted) +- Extraction: 94% EXTRACTED · 6% INFERRED · 0% AMBIGUOUS · INFERRED: 212 edges (avg confidence: 0.83) - Token cost: 0 input · 0 output ## Community Hubs (Navigation) -- Watchlist & Detector DB Tests -- Poller Tests -- Watchlist HTTP Tests -- HTTP Handlers & JSON Helpers (3) -- shadcn UI Primitives -- Frontend API Client & Watchlist Route -- Status Endpoint & Server -- MusicBrainz Client Tests -- DB Migration Runner -- System Page & Source Panels -- Coverage-Report Tool -- Login Throttle Tests (11) -- Notifier Integration Tests (12) -- Auth Gate Tests -- History Route & Event Cards -- Tags sqlc Queries -- Tag Chips & Combobox UI -- MusicBrainz Detection -- Tags HTTP Tests -- Shared Test Fakes & Types -- Migration-Check Tests -- Notifier Integration Tests (21) -- Artist Matcher Tests -- sqlc Models & Watchlist Queries -- Deezer Client Tests (24) -- Dialogs, Auth Store & App Shell (25) -- Artist Note & Preference Toggles -- Watchlist Service -- Notifier Integration Tests (28) -- Digest Chunking Tests (29) -- SQL Schema Parser -- HTTP Server Wiring Tests -- Notifier Integration Tests (32) -- Discord Digest Formatting -- Tags Service -- Deezer-MusicBrainz Matcher -- Digest Scheduler Tests -- MusicBrainz Recordings -- CI Pipeline & Local Gates -- Settings HTTP Tests -- Notifier Core -- Query Column Reference Analysis -- Search UI Components -- Web Runtime Dependencies (43) -- Migration-Check Scanner -- Config Loading Tests -- Notifier Integration Tests (46) -- Events Service Tests (47) -- Dialogs, Auth Store & App Shell (48) -- Web Dev Dependencies (49) -- Events sqlc Queries -- Digest Chunking Tests (51) -- Tag Schema Tests -- SQL Lexer (Dollar Quoting) -- Readiness Endpoint Tests -- Discord Embed Formatting Tests -- ConfirmDialog & AlertDialog -- HTTP Handlers & JSON Helpers (57) -- Tags & Notes Migration -- Artist Backfill -- Notifier DB Timeout Tests -- Phase 25 Tag Filter Plans -- Deezer Client Tests (62) -- Notification Settings Service -- DB Pool Config -- Phase 24 Optimistic UI & Notes -- Phase 25 Release-Date Enrichment -- Artist Search Stubs -- Digest Chunk Builder -- Phase 24 UI Contract Concepts -- Events Service Tests (70) -- MusicBrainz Releases -- Phase 25 URL State & Name Filter -- Server Entrypoint -- v1.6 Phases & Requirements (74) -- Discord Webhook Client -- Discord Client Retry Tests -- Activity Gate -- v1.6 Phases & Requirements (78) -- Phase 24 Pattern Map Concepts -- Phase 24 Postgres Research Findings -- Phase 24 Review, UAT & Verification -- Phase 25 History Tag Filter Plans -- Web package.json Scripts -- Search Cancellation Stubs -- Migration-Check Git Diff -- Codebase Architecture Map -- MusicBrainz Artist Lookup -- MusicBrainz Artist Search -- Per-Artist Tag Cap Decisions -- Phase 24 Security Threats -- Release Detector -- Single-Instance ADRs (92) -- Query Refs Tests -- SPA Embed Handler -- End-to-End Boot Tests -- Single-Instance ADRs (96) -- Status Snapshot & Ring Buffer (97) -- Digest Ack Split -- Tag Cap Locking & Merge -- Migration Rollback Rules -- Status Snapshot & Ring Buffer (101) -- Web Template & Status Client -- Login Throttle Tests (103) -- Build Info -- Combobox Interaction -- Digest Mode Concepts -- Digest Slot & Watermark -- Deezer Client -- v1.4 Observability Milestone (109) -- Comment Discipline Convention -- Graph-First & GSD Conventions -- clsx Dependency -- Migration Safety & Passphrase Gate -- Issue Tracker Conventions -- Health Endpoint -- Notification Settings Migration -- Raw SQL Statement -- Milestone Log & Retrospective -- Feature Options (Sinks, Digest) -- v1.4 Observability Milestone (121) -- React Dependency -- React Router Dev -- Tailwind Vite Plugin -- Web Dev Dependencies (125) -- Web Runtime Dependencies (126) -- React Types -- Web Dev Dependencies (128) -- Vitest Dependency -- Domain Glossary -- Watched Artist vs Credited Artist +- writeError +- 26 RESEARCH doc +- .HandleLogin +- watchlistView.ts +- main.go +- parse.go +- github.com/danielrpof/drop-tracker/internal/db/sqlc.Event +- 24 CONTEXT doc +- combobox.tsx +- deezer/client.go +- format.ts +- Phase 25 Research +- In-process poll-run ring buffer +- useBulkSelection.ts +- notifier.go +- DigestSettings.tsx +- migrate.go +- BulkPreferencesPopover.tsx +- match.go +- service.go +- TagChips.tsx +- history.tsx +- system.tsx +- api.ts +- 25 UI SPEC doc +- SearchResultsColumns.tsx +- root.tsx +- poller.go +- TESTING doc +- EventCard.tsx +- ManageTagsDialog +- service.go (2) +- ROADMAP doc +- TagChips.tsx (2) +- artist_tags +- full-pipeline.yml +- CONCERNS doc +- dialog.tsx +- alert-dialog.tsx +- server.go +- CONTEXT doc +- detector.go +- settings.go +- search.go +- STRUCTURE doc +- v1.0 MILESTONE AUDIT doc +- ROADMAP doc (2) +- musicbrainz.go +- REQUIREMENTS doc +- useBulkSelection.ts (2) +- INTEGRATIONS doc +- status.go +- musicbrainz.go (2) +- STATE doc +- STACK doc +- WatchlistBulkStore +- bulk.go +- tags.go +- recordings.go +- logging.go +- releases.go +- CONTEXT doc (2) +- artist_lookup.go +- terraform always on env doc +- activity.go +- backfill.go +- alerter.go +- CONTEXT doc (3) +- schema_version.go +- server.go (2) +- settings.go (2) +- releasegroups.go +- HistoryFilters.tsx +- pnpm workspace doc +- CONTEXT doc (4) +- CLAUDE doc +- CLAUDE doc (2) +- issue tracker doc +- health.go +- 000008_notification_settings.up.sql +- parse.go (2) +- MILESTONES doc +- 2026 09 08 feature module doc +- docker-compose.yml - github.com/danielrpof/drop-tracker -- 2026-09-08-feature-module-ideas-post-v1.3.md -- Soft-delete Event Retention -- v1.0 Milestone Audit +- Feature/Module Ideas Post-v1.3 +- Option C: Operator Status Panel + +- Option E: Watchlist Organization +- Phase 25 External API Coverage Declaration +- In-process poll-run ring buffer (2) +- Design Grilling Before Planning +- Don't Roadmap Phases Gated on Uncontrolled ## God Nodes (most connected - your core abstractions) -1. `New()` - 228 edges -2. `NewIsolatedTestPool()` - 146 edges -3. `NewTestPool()` - 137 edges -4. `New()` - 116 edges -5. `cn()` - 104 edges -6. `discardLogger()` - 97 edges -7. `New()` - 79 edges -8. `NewService()` - 78 edges -9. `newTestLogger()` - 77 edges -10. `newTestLogger()` - 64 edges +1. `cn()` - 115 edges +2. `run()` - 45 edges +3. `Watchlist()` - 36 edges +4. `Phase 26 Bulk Edit and Remove Research` - 30 edges +5. `Phase 26 UI Design Contract` - 28 edges +6. `WatchlistEntry` - 26 edges +7. `Phase 25 UI Design Contract` - 26 edges +8. `writeError()` - 24 edges +9. `Phase 24: Artist Tags & Notes` - 24 edges +10. `Testing Patterns` - 21 edges ## Surprising Connections (you probably didn't know these) -- `handleHealth (internal/httpserver/health.go)` --shares_data_with--> `NewPool()` [INFERRED] - .planning/codebase/ARCHITECTURE.md → internal/db/pool.go - `Comment Discipline Rule` --semantically_similar_to--> `Coding Conventions` [INFERRED] [semantically similar] .claude/CLAUDE.md → .planning/codebase/CONVENTIONS.md -- `Tag merge via UPDATE tag_id (never insert)` --semantically_similar_to--> `Expand / backfill / contract pattern (000006, 000007)` [INFERRED] [semantically similar] - docs/adr/0004-per-artist-tag-cap-trigger.md → internal/db/migrations/README.md -- `G7: keep both comboboxes` --references--> `Combobox()` [EXTRACTED] - .planning/phases/25-find-filter-watchlist-and-history/25-CONTEXT.md → web/app/components/history/HistoryFilters.tsx - `pre-commit config (gitleaks, golangci-lint --fix, prettier --write)` --semantically_similar_to--> `gitleaks job` [EXTRACTED] [semantically similar] .pre-commit-config.yaml → .github/workflows/full-pipeline.yml +- `scanFile()` --calls--> `Parse()` [EXTRACTED] + cmd/migration-check/main.go → internal/sqlscan/parse.go +- `crossReferenceFinding()` --references--> `RefSet` [EXTRACTED] + cmd/migration-check/main.go → internal/sqlscan/queryrefs.go +- `run()` --calls--> `NewActivityGate()` [EXTRACTED] + cmd/server/main.go → internal/artistart/activity.go ## Import Cycles - None detected. ## Hyperedges (group relationships) +- **Bulk tag add cap-safety mechanism** — docs_adr_0004_per_artist_tag_cap_trigger_cap_trigger, docs_adr_0004_per_artist_tag_cap_trigger_bulk_prelock, planning_phases_26_bulk_edit_remove_26_context_apply_where_fits [EXTRACTED 0.95] +- **Digest scheduling vocabulary** — context_digest_slot, context_slot_record, context_grace_window, context_digest_window, context_watermark [EXTRACTED 0.95] +- **Tag data model** — context_tag, context_tag_vocabulary, context_tag_link, context_carrier, context_merge [EXTRACTED 0.95] +- **Bulk selection and action UI** — planning_phases_26_bulk_edit_remove_26_ui_spec_derived_selection_effective_selection, planning_phases_26_bulk_edit_remove_26_ui_spec_select_all_visible_tri_state, planning_phases_26_bulk_edit_remove_26_ui_spec_sticky_bulk_action_bar, planning_phases_26_bulk_edit_remove_26_ui_spec_success_focus_order_and_fallback_chain [EXTRACTED 1.00] +- **Bulk tag add safe-insert flow** — planning_phases_26_bulk_edit_remove_26_research_bulk_tag_add_apply_where_it_fits_d_01, planning_phases_26_bulk_edit_remove_26_research_ordered_pre_lock_then_guarded_insert, planning_phases_26_bulk_edit_remove_26_research_adr_0004_tag_cap_trigger, planning_phases_26_bulk_edit_remove_26_research_tag_orphan_on_all_capped_create [EXTRACTED 1.00] - **Release-path gate jobs feeding build-scan then release** — github_workflows_full_pipeline_lint, github_workflows_full_pipeline_test, github_workflows_full_pipeline_gitleaks, github_workflows_full_pipeline_trivy_fs, github_workflows_full_pipeline_frontend_test, github_workflows_full_pipeline_migration_check, github_workflows_full_pipeline_n1_boot, github_workflows_full_pipeline_build_scan, github_workflows_full_pipeline_release [EXTRACTED 1.00] -- **Digest scheduling domain model** — context_digest_mode, context_outbox, context_digest_window, context_digest_slot, context_slot_record, context_watermark, context_grace_window, context_flush [EXTRACTED 1.00] +- **Phase 28 safety work: inert seam, escaping, fixture preconditions** — planning_roadmap_tagsreader, planning_roadmap_escapemd, planning_roadmap_chunkfixture, planning_roadmap_phase28 [EXTRACTED 1.00] - **N-1 rollback safety enforcement** — internal_db_migrations_readme_n1_invariant, internal_db_migrations_readme_n1_boot_job, internal_db_migrations_readme_ahead_of_source_test, internal_db_migrations_readme_migration_check, internal_db_migrations_readme_expand_backfill_contract [EXTRACTED 1.00] -- **History tag filter (HIST-02) end to end** — planning_phases_25_find_filter_watchlist_and_history_25_02_plan, planning_phases_25_find_filter_watchlist_and_history_25_06_plan, planning_phases_25_find_filter_watchlist_and_history_25_09_plan, planning_phases_25_find_filter_watchlist_and_history_25_context_d11_history_single_tag, planning_phases_25_find_filter_watchlist_and_history_25_research_pattern_tag_filter_retention [EXTRACTED 1.00] -- **Single-query latest/next release enrichment** — planning_phases_25_find_filter_watchlist_and_history_25_01_plan, planning_phases_25_find_filter_watchlist_and_history_25_context_latest_release_date, planning_phases_25_find_filter_watchlist_and_history_25_context_next_release_date, planning_phases_25_find_filter_watchlist_and_history_25_context_g1_no_retention, planning_phases_25_find_filter_watchlist_and_history_25_context_g2_upcoming_utc, planning_phases_25_find_filter_watchlist_and_history_25_research_pattern_lateral_enrichment [EXTRACTED 1.00] - **Single-instance in-process coordination decisions** — docs_adr_0001_in_process_ring_buffer_for_poll_run_history_ring_buffer, docs_adr_0002_one_outbox_one_sender_lock_notifier_notifying_lock, docs_adr_0001_in_process_ring_buffer_for_poll_run_history_single_instance_constraint, docs_adr_0002_one_outbox_one_sender_lock_postgres_advisory_lock [EXTRACTED 1.00] +- **v1.6 tags-first dependency chain (Phases 24-26)** — planning_roadmap_phase24, planning_roadmap_phase25, planning_roadmap_phase26, planning_roadmap_phase27, planning_roadmap_phase28 [EXTRACTED 1.00] +- **Watchlist filter toolbar composition** — planning_phases_25_find_filter_watchlist_and_history_25_ui_spec_name_filter, planning_phases_25_find_filter_watchlist_and_history_25_ui_spec_sort_select_six_options, planning_phases_25_find_filter_watchlist_and_history_25_ui_spec_tag_filter_any_of_combobox, planning_phases_25_find_filter_watchlist_and_history_25_ui_spec_preference_toggles_filter, planning_phases_25_find_filter_watchlist_and_history_25_ui_spec_clear_filters [EXTRACTED 1.00] - **Local hooks mirroring CI gates** — pre_commit_config, golangci, claude_claude_definition_of_done, github_workflows_full_pipeline [INFERRED 0.85] -- **Watchlist find/filter composition (search, sort, tags, toggles)** — planning_phases_25_find_filter_watchlist_and_history_25_04_plan, planning_phases_25_find_filter_watchlist_and_history_25_05_plan, planning_phases_25_find_filter_watchlist_and_history_25_07_plan, planning_phases_25_find_filter_watchlist_and_history_25_08_plan, planning_phases_25_find_filter_watchlist_and_history_25_research_pattern_selectvisible, planning_phases_25_find_filter_watchlist_and_history_25_context_d10_three_empty_states [INFERRED 0.85] +- **Watchlist find/filter composition (search, sort, tags, toggles)** — planning_phases_25_find_filter_watchlist_and_history_25_research_pattern_selectvisible [INFERRED 0.85] - **Manage tags rename/merge/delete UI flow** — planning_phases_24_artist_tags_notes_24_ui_spec_managetagsdialog, planning_phases_24_artist_tags_notes_24_ui_spec_confirmdialog, planning_phases_24_artist_tags_notes_24_context_d_09_rename_merge_confirm, planning_phases_24_artist_tags_notes_24_context_d_16_reusable_alert_dialog, planning_phases_24_artist_tags_notes_24_context_d_22_vocabulary_api, planning_phases_24_artist_tags_notes_24_ui_spec_focus_management_r5 [INFERRED 0.85] -- **Per-artist 10-tag cap enforcement** — planning_phases_24_artist_tags_notes_24_context_d_18_cap_trigger, planning_phases_24_artist_tags_notes_24_context_d_19_merge_never_inserts, planning_phases_24_artist_tags_notes_24_context_adr_0004_cap_trigger, planning_phases_24_artist_tags_notes_24_research_before_insert_trigger_before_on_conflict, planning_phases_24_artist_tags_notes_24_research_for_no_key_update_lock, planning_phases_24_artist_tags_notes_24_security_t_24_01_02_cap_tampering, planning_phases_24_artist_tags_notes_24_security_migrations_000011_000012 [INFERRED 0.85] +- **Per-artist 10-tag cap enforcement** — planning_phases_24_artist_tags_notes_24_context_d_18_cap_trigger, planning_phases_24_artist_tags_notes_24_context_d_19_merge_never_inserts, planning_phases_24_artist_tags_notes_24_context_adr_0004_cap_trigger, planning_phases_24_artist_tags_notes_24_research_before_insert_trigger_before_on_conflict, planning_phases_24_artist_tags_notes_24_research_for_no_key_update_lock [INFERRED 0.85] - **Poll-run history to /status to SPA flow** — docs_adr_0001_in_process_ring_buffer_for_poll_run_history_runrecorder_seam, docs_adr_0001_in_process_ring_buffer_for_poll_run_history_ring_buffer, docs_api_status_contract_pollruns_snapshot, docs_api_status_contract_handlestatus, docs_api_status_contract_spa_api_client [INFERRED 0.85] +- **Tag integrity: normalization, unique index, cap trigger** — planning_roadmap_tagidentity, planning_roadmap_migration10, planning_roadmap_captrigger, planning_roadmap_migration1112 [INFERRED 0.85] -## Communities (173 total, 25 thin omitted) +## Communities (128 total, 17 thin omitted) -### Community 0 - "Watchlist & Detector DB Tests" -Cohesion: 0.05 -Nodes (160): fakeReleaseDetailSource, insertEventFailingQuerier, ExpectedSchemaVersion(), TestExpectedSchemaVersion(), TestSchemaVersion_Integration(), TestSchemaVersionReader_Delegates(), New(), TestSQLCPing() (+152 more) - -### Community 1 - "Poller Tests" -Cohesion: 0.06 -Nodes (103): cron.Cron, sync/atomic.Bool, New(), runOneArtist(), decodeLogRecords(), deezerID(), eightEntries(), failFirstThree() (+95 more) - -### Community 2 - "Watchlist HTTP Tests" -Cohesion: 0.06 -Nodes (82): errorBody, healthBody, noteEntryBody, SearchSource, watchlistEntryBody, TestHandleListEvents_CursorRejection(), TestHandleListEvents_EmptyReturnsEmptyArrayAndNullCursor(), TestHandleListEvents_HappyPathReturns200WithEnvelope() (+74 more) - -### Community 3 - "HTTP Handlers & JSON Helpers (3)" -Cohesion: 0.05 -Nodes (47): globalCounter, ipLimiter, loginRequest, loginThrottle, Cursor, cursorWireForm, net/http.Request, net/http.ResponseWriter (+39 more) - -### Community 4 - "shadcn UI Primitives" -Cohesion: 0.05 -Nodes (64): AboutInstanceProps, Cadence, CADENCE_LABELS, SaveStatus, Alert(), AlertAction(), AlertDescription(), AlertTitle() (+56 more) - -### Community 5 - "Frontend API Client & Watchlist Route" -Cohesion: 0.06 -Nodes (47): Phase 25 Pattern Map, mockDeleteTag, mockListTags, mockMergeTag, mockRenameTag, openCollisionConfirm(), renderDialog(), SearchBox() (+39 more) +### Community 0 - "writeError" +Cohesion: 0.07 +Nodes (51): Cursor, cursorWireForm, ListParams, Page, Service, github.com/danielrpof/drop-tracker/internal/db/sqlc.ListEventsRow, net/http.Request, net/http.ResponseWriter (+43 more) -### Community 6 - "Status Endpoint & Server" +### Community 1 - "26 RESEARCH doc" Cohesion: 0.06 -Nodes (56): chi.Router, net/http.Handler, attachTagRequest, deleteTagResponse, fakeStatusStore, mergeTagRequest, Option, Pinger (+48 more) - -### Community 7 - "MusicBrainz Client Tests" -Cohesion: 0.08 -Nodes (62): TestLookupArtist_DecodesFixture(), TestLookupArtist_EmptyMBID(), TestLookupArtist_MalformedJSON(), TestLookupArtist_NonOKStatus(), TestLookupArtist_NoRelationsNoAliasesYieldsNonNilZeroLengthSlices(), TestLookupArtist_RequestShape(), TestReleasesForRecording_DecodesFixture(), TestReleasesForRecording_EmptyMBID() (+54 more) +Nodes (66): ADR 0004 tag cap trigger, Bulk remove-tag by tag id (D-22), Bulk tag add apply-where-it-fits (D-01), ConfirmDialog close-order pitfall, Deadlock-free lock ordering, Derived selection (D-11), Grill amendments Q1-Q10, Id count and body bounds (+58 more) -### Community 8 - "DB Migration Runner" +### Community 2 - ".HandleLogin" Cohesion: 0.07 -Nodes (54): Atomic CAS overlap-guard pattern (poll cycles), main(), run(), highestMigrationVersion(), scratchSchemaDSN(), TestRun_AppliesHeadSchema(), TestRun_MissingDatabaseURL(), retryConfig (+46 more) +Nodes (38): globalCounter, ipLimiter, loginRequest, loginThrottle, Token, sync.Mutex, sync.Once, time.Ticker (+30 more) -### Community 9 - "System Page & Source Panels" +### Community 3 - "watchlistView.ts" Cohesion: 0.07 -Nodes (47): AboutInstance(), DigestSettings(), handleCadenceChange(), handleDigestModeChange(), save(), DigestSettingsProps, mockUpdateDigestSettings, classifyOutcome() (+39 more) - -### Community 10 - "Coverage-Report Tool" -Cohesion: 0.08 -Nodes (56): appendFile(), backendTotalPct(), formatDelta(), frontendLinesPct(), main(), parseBlockLine(), readBackend(), readFrontend() (+48 more) +Nodes (55): addWatchlist(), removeWatchlist(), sortTagsByName(), anchorCandidates(), useScrollAnchor(), rewriteTags(), byId(), canonicalWatchlistParams() (+47 more) -### Community 11 - "Login Throttle Tests (11)" -Cohesion: 0.11 -Nodes (46): discordAlerter, noopAlerter, recordingAlerter, golang.org/x/time/rate.Limit, time.Duration, Alerter, NoOpAlerter(), SelectAlerter() (+38 more) +### Community 4 - "main.go" +Cohesion: 0.07 +Nodes (54): appendFile(), backendTotalPct(), formatDelta(), frontendLinesPct(), main(), parseBlockLine(), readBackend(), readFrontend() (+46 more) -### Community 12 - "Notifier Integration Tests (12)" -Cohesion: 0.15 -Nodes (50): bytes.Buffer, github.com/jackc/pgx/v5/pgxpool.Pool, decodeLogRecords(), decodeModeTransitionRecords(), erroringFrom(), erroringSettings(), flippingSettings(), insertPendingEvent() (+42 more) +### Community 5 - "parse.go" +Cohesion: 0.07 +Nodes (41): buildPrevReleaseRefs(), strings.Builder, NormalizeIdent(), StripIdent(), StripSchemaQualifier(), copyDollarQuoted(), copySingleQuoted(), dollarTagAt() (+33 more) -### Community 13 - "Auth Gate Tests" -Cohesion: 0.11 -Nodes (43): fakeAlerter, stubPinger, syncBuffer, Token, net/http.Cookie, net/http.Response, deleteSession(), discardLogger() (+35 more) +### Community 6 - "github.com/danielrpof/drop-tracker/internal/db/sqlc.Event" +Cohesion: 0.09 +Nodes (43): discordAlerter, allowedMentions, EmbedImage, retry429Body, webhookPayload, github.com/danielrpof/drop-tracker/internal/db/sqlc.Event, golang.org/x/text/collate.Collator, Client (+35 more) -### Community 14 - "History Route & Event Cards" +### Community 7 - "24 CONTEXT doc" Cohesion: 0.06 -Nodes (29): CoverArt(), CoverArtProps, EmptyState(), EmptyStateProps, EVENT_BADGE, EventCard(), EventCardProps, GuestFeatureBody() (+21 more) +Nodes (48): Phase 24 Context: Artist Tags & Notes, ADR 0004: Per-artist tag cap trigger, D-03: Optimistic chip add/remove with rollback, D-05: Note clamped to 2 lines with more expander, D-06: Note edited in place with Save/Cancel and counter, D-07: Manage tags dialog from Watchlist header, D-09: Inline rename; collision opens merge confirmation, D-10: Notes on watchlist row, tags on artists.id (+40 more) -### Community 15 - "Tags sqlc Queries" +### Community 8 - "combobox.tsx" Cohesion: 0.08 -Nodes (20): context.Context, fakeWatchlistCounter, noopPinger, stubPinger, Artist, Queries, Queries, Queries (+12 more) +Nodes (31): Button(), buttonVariants, ComboboxChip(), ComboboxChips(), ComboboxChipsInput(), ComboboxClear(), ComboboxContent(), ComboboxEmpty() (+23 more) -### Community 16 - "Tag Chips & Combobox UI" +### Community 9 - "deezer/client.go" Cohesion: 0.07 -Nodes (30): CollisionTarget, ManageTagsDialogProps, FocusRequest, nextPendingId(), PendingTag, TagActions, TagChips(), attachErrorMessage() (+22 more) +Nodes (28): Artist, AlbumLister, APIError, artistAlbumsResponse, errorProbe, context.CancelFunc, golang.org/x/time/rate.Limiter, io.ReadCloser (+20 more) -### Community 17 - "MusicBrainz Detection" -Cohesion: 0.08 -Nodes (30): log/slog.Logger, Detector, newNotifyGate(), nullableString(), deluxeDetectionEnabled(), eventTypeMuted(), releaseTypeAllowed(), TestFilter_DeluxeIsAGateNotAType() (+22 more) +### Community 10 - "format.ts" +Cohesion: 0.10 +Nodes (37): EventCard(), DigestSettings(), handleCadenceChange(), handleDigestModeChange(), save(), classifyOutcome(), OutcomeBadge(), OutcomeTier (+29 more) -### Community 18 - "Tags HTTP Tests" -Cohesion: 0.12 -Nodes (41): testing.T, tagsServerOpts, tagSummaryWire, tagWire, watchlistTagsEntryBody, TestMigrationsReadme_ContainsRequiredPhrases(), TestMigrationsReadme_IsNonTrivial(), TestSearchArtist_WireShapeKeySet() (+33 more) - -### Community 19 - "Shared Test Fakes & Types" -Cohesion: 0.07 -Nodes (22): stubAlbumLister, stubGroupLister, syncBuf, artistAlbumsResponse, net/http.RoundTripper, sync.Mutex, capturingRoundTripper, Album (+14 more) +### Community 11 - "Phase 25 Research" +Cohesion: 0.06 +Nodes (38): Bulk outcome, Bulk selection, Effective selection, Filter, Search, ADR 0004: per-artist tag cap trigger, Ordered pre-lock for bulk attach, Locking skip-existing tag cap trigger (artist_tags) (+30 more) -### Community 20 - "Migration-Check Tests" -Cohesion: 0.11 -Nodes (41): main(), run(), readPrevReleaseFixture(), runCapture(), runScanCapture(), stubQueriesGitShow(), TestChangedFiles_AddedAndModified(), TestChangedFiles_NothingUnderGlobIsFalseAndEmpty() (+33 more) +### Community 12 - "In-process poll-run ring buffer" +Cohesion: 0.06 +Nodes (40): ADR 0001: In-process ring buffer for poll-run history, poll_runs table (rejected option), In-process poll-run ring buffer (pollruns.Store), poller.RunRecorder seam, Single-instance constraint (no leader election in robfig/cron), httpserver.StatusStore seam, ADR 0002: One outbox, one sender lock, CAS-skip on held lock (+32 more) -### Community 21 - "Notifier Integration Tests (21)" -Cohesion: 0.20 -Nodes (40): TestDigestScheduler_NotDue_Quiet_NoLogsNoWrites(), countNotified(), digestSettingsReader(), flippingDigestSettings(), insertPendingEventsForChunking(), snapshotSettings(), TestNoOp_SendDigestIfDue_ReturnsNilTouchesNothing(), TestSendDigestIfDue_AllSuppressed_ZeroSendAckedSlotAdvancesSentAtStaysNull() (+32 more) +### Community 13 - "useBulkSelection.ts" +Cohesion: 0.12 +Nodes (35): BulkActionBarProps, RemoveTagPicker(), BulkPreferencesPopoverProps, DISMISS_REASONS, BulkAddTagOutcome, BulkAxisDelta, BulkOutcome, BulkRemoveTagOutcome (+27 more) -### Community 22 - "Artist Matcher Tests" +### Community 14 - "notifier.go" Cohesion: 0.13 -Nodes (37): stubSearcherFunc, NewMatcher(), TestMatch_EmptyNameFailsClosedWithoutOutboundCall(), TestMatch_MatchedCandidateWithEmptyPictureYieldsNilImageURL(), TestMatch_NoCloseNameCandidateFailsClosed(), TestMatch_SearchErrorSurfaces(), TestMatch_SingleCandidateIssuesNoTieBreakFetch(), TestMatch_SingleCloseNameCandidate() (+29 more) +Nodes (24): Cadence, context.Context, github.com/danielrpof/drop-tracker/internal/db/sqlc.Querier, log/slog.Logger, NewClient(), ackDigestBatch(), ackEventsOnly(), Notifier (+16 more) -### Community 23 - "sqlc Models & Watchlist Queries" -Cohesion: 0.08 -Nodes (19): stubStore, notifyGate, github.com/jackc/pgx/v5/pgtype.Timestamptz, UpsertArtistParams, Artist, NotificationSetting, Queries, Queries (+11 more) +### Community 15 - "DigestSettings.tsx" +Cohesion: 0.12 +Nodes (28): Cadence, CADENCE_LABELS, DigestSettingsProps, SaveStatus, Avatar(), AvatarBadge(), AvatarFallback(), AvatarGroup() (+20 more) -### Community 24 - "Deezer Client Tests (24)" -Cohesion: 0.14 -Nodes (35): buildArtistAlbumsPageJSON(), pagedArtistAlbumsServer(), TestArtistAlbums_CancellationBetweenPagesAborts(), TestArtistAlbums_DecodesFixture(), TestArtistAlbums_EmptyArtistIDReturnsErrorWithZeroRequests(), TestArtistAlbums_MidFetchErrorStopsWithNoRetry(), TestArtistAlbums_NonexistentArtistReturnsEmptyNonNilNoError(), TestArtistAlbums_PacingAppliesAcrossPages() (+27 more) +### Community 16 - "migrate.go" +Cohesion: 0.12 +Nodes (30): main(), run(), retryConfig, RetryOption, github.com/golang-migrate/migrate/v4/source.Driver, github.com/jackc/pgx/v5/pgxpool.Config, github.com/jackc/pgx/v5/pgxpool.Pool, testing.T (+22 more) -### Community 25 - "Dialogs, Auth Store & App Shell (25)" -Cohesion: 0.08 -Nodes (16): PassphraseScreen(), handleSubmit(), Input(), Toaster(), createSession(), deleteSession(), authStore, gateActive (+8 more) +### Community 17 - "BulkPreferencesPopover.tsx" +Cohesion: 0.10 +Nodes (27): Popover(), PopoverContent(), PopoverDescription(), PopoverHeader(), PopoverTitle(), PopoverTrigger(), BulkPreferencesPopover(), changeOpen() (+19 more) -### Community 26 - "Artist Note & Preference Toggles" -Cohesion: 0.09 -Nodes (21): Button(), buttonVariants, Checkbox(), ArtistNote(), handleSave(), ArtistNoteProps, FocusRequest, saveErrorMessage() (+13 more) +### Community 18 - "match.go" +Cohesion: 0.17 +Nodes (20): AlbumLister, ArtistDetailLookup, ArtistFetcher, ArtistSearcher, Matcher, Option, ReleaseGroupLister, Result (+12 more) -### Community 27 - "Watchlist Service" +### Community 19 - "service.go" Cohesion: 0.11 -Nodes (17): stubStore, fullEntryBody, stubStore, ListWatchlistRow, TestNormalizeSet(), entryFromRow(), AddParams, Entry (+9 more) - -### Community 28 - "Notifier Integration Tests (28)" -Cohesion: 0.21 -Nodes (34): NewService(), countArtistTagsByTagID(), countTagsByLowerName(), seedEntry(), TestService_Attach_AtCapReturnsErrTagCapReachedAndRollsBackOrphan(), TestService_Attach_CreatesAndLinksNewTag(), TestService_Attach_ExistingLinkReturnsCreatedFalse(), TestService_Attach_UnknownEntryReturnsErrEntryNotFound() (+26 more) - -### Community 29 - "Digest Chunking Tests (29)" -Cohesion: 0.16 -Nodes (32): buildDigestGroups(), chunkDigest(), containsID(), makeSyntheticGroup(), stripChunkMarkers(), syntheticInvariantBatch(), TestBuildDigestChunks_CapTotalReflectsKeptChunksNotUncapped(), TestBuildDigestChunks_CapTruncatesAndReportsDeferred() (+24 more) +Nodes (17): github.com/danielrpof/drop-tracker/internal/db/sqlc.DBTX, github.com/danielrpof/drop-tracker/internal/db/sqlc.Queries, tagCollisionResponse, BulkSkip, Service, goneIDs(), NormalizeName(), Service (+9 more) -### Community 30 - "SQL Schema Parser" -Cohesion: 0.08 -Nodes (21): Parse(), SchemaColumns(), TestParse_AddCheckNeverAddColumn(), TestParse_AddColumnNotNullAndDefaultAreIndependent(), TestParse_AlterTableActionsInClauseOrder(), TestParse_CreateTableColumnsExcludeConstraintClauses(), TestParse_DropTableNormalizesAndKeepsRaw(), TestParse_EachActionTypeFromItsClauseForm() (+13 more) - -### Community 31 - "HTTP Server Wiring Tests" -Cohesion: 0.11 -Nodes (25): log/slog.Level, syncBuffer, Config, assertInert(), newCapturingServer(), newGatedServer(), requestIDsInLog(), TestGatedServer_TrustProxyHeaders_RealIPWiring() (+17 more) +### Community 20 - "TagChips.tsx" +Cohesion: 0.12 +Nodes (23): Textarea(), ArtistNote(), handleChange(), handleSave(), openEditor(), ArtistNoteProps, FocusRequest, saveErrorMessage() (+15 more) -### Community 32 - "Notifier Integration Tests (32)" -Cohesion: 0.18 -Nodes (26): time.Time, insertPendingEventTypedRaw(), mustLoadDigestZone(), newManualTickSource(), newMutableClock(), newSignalingSink(), seedNotificationSettings(), sweep() (+18 more) +### Community 21 - "history.tsx" +Cohesion: 0.13 +Nodes (22): EmptyState(), EmptyStateProps, ComboboxOption, ComboboxProps, EVENT_TYPE_OPTIONS, HistoryFilters(), HistoryFiltersProps, HistoryFiltersValue (+14 more) -### Community 33 - "Discord Digest Formatting" -Cohesion: 0.15 -Nodes (27): golang.org/x/text/collate.Collator, Event, artistKey(), digestLine(), escapeMarkdown(), lineLabel(), sortDigestGroup(), TestArtistKey() (+19 more) +### Community 22 - "system.tsx" +Cohesion: 0.13 +Nodes (23): AboutInstance(), AboutInstanceProps, Alert(), AlertAction(), AlertDescription(), AlertTitle(), alertVariants, Card() (+15 more) -### Community 34 - "Tags Service" -Cohesion: 0.11 -Nodes (13): fakeTagStore, DBTX, Queries, NormalizeName(), TestNormalizeName(), AttachResult, Summary, Tag (+5 more) +### Community 23 - "api.ts" +Cohesion: 0.13 +Nodes (22): ApiError, apiFetch(), BulkRemoveOutcome, bulkRemoveTag(), bulkRemoveWatchlist(), BulkSkip, bulkUpdatePreferences(), deleteTag() (+14 more) -### Community 35 - "Deezer-MusicBrainz Matcher" +### Community 24 - "25 UI SPEC doc" Cohesion: 0.15 -Nodes (20): AlbumLister, ArtistDetailLookup, ArtistFetcher, ArtistSearcher, Matcher, Option, ReleaseGroupLister, aliasQueryNames() (+12 more) +Nodes (26): 24px dense target exception, Accent and case folding match, Clear filters, Click-to-filter tag chips, Client-side filtering over single payload, Combobox hardening max-h-72, ComboboxChip vendored edit, Dark-only design system base-maia (+18 more) -### Community 36 - "Digest Scheduler Tests" -Cohesion: 0.17 -Nodes (20): defaultTickSource(), DigestScheduler, NewDigestScheduler(), newFakeSink(), newSyncTestLogger(), TestDigestScheduler_CheckError_LoggedAndLoopContinues(), TestDigestScheduler_ChecksReceiveInjectedClockValue(), TestDigestScheduler_ContextCancelled_LoopExitsWithoutStop() (+12 more) +### Community 25 - "SearchResultsColumns.tsx" +Cohesion: 0.12 +Nodes (21): SearchBox(), handleChange(), runSearch(), SearchBoxProps, DEEZER_ADD_HINT, SearchResultRow(), SearchResultRowProps, SearchResultsColumns() (+13 more) -### Community 37 - "MusicBrainz Recordings" -Cohesion: 0.11 -Nodes (13): datedRecordingSource, erroringRecordingSource, fakeRecordingSource, noRecordingSource, Client, RecordingRelease, ArtistCreditEntry, Client (+5 more) +### Community 26 - "root.tsx" +Cohesion: 0.10 +Nodes (10): PassphraseScreen(), handleSubmit(), Toaster(), createSession(), deleteSession(), authStore, gateActive, listeners (+2 more) -### Community 38 - "CI Pipeline & Local Gates" -Cohesion: 0.09 -Nodes (27): Definition of Done (local CI gates), No AI Attribution in Commits/PRs, Recommended Tech Stack (chi, sqlc, pgx, golang-migrate, robfig/cron, caarlos0/env, slog, httplog), Full Pipeline GitHub Actions Workflow, build-scan job (image build, provenance check, tz boot check, Trivy image scan), coverage-comment job (report-only sticky PR comment), frontend-test job (prettier --check + Vitest), gitleaks job (+19 more) +### Community 27 - "poller.go" +Cohesion: 0.19 +Nodes (16): cron.Cron, sync/atomic.Bool, New(), runOneArtist(), WithDeezerWorkers(), WithMusicBrainzWorkers(), WithRunRecorder(), AlbumSource (+8 more) -### Community 39 - "Settings HTTP Tests" -Cohesion: 0.20 -Nodes (26): net/http/httptest.Server, settingsBody, settingsServerOpts, WithSettings(), SettingsStore, assertSettingsDefaults(), getSettingsRaw(), loginForSettings() (+18 more) +### Community 28 - "TESTING doc" +Cohesion: 0.14 +Nodes (22): Co-located _test package convention, Concurrent testing with WaitGroup, Error sanitization test, Frontend test framework absent, Func-field stubs, Go stdlib testing runner, httptest.Server API mocking, Inline string-constant fixtures (+14 more) -### Community 40 - "Notifier Core" +### Community 29 - "EventCard.tsx" Cohesion: 0.13 -Nodes (18): Querier, ackDigestBatch(), ackEventsOnly(), Notifier, Notifier, listUnnotified(), logSettingsReadFailure(), markNotified() (+10 more) +Nodes (14): CoverArt(), CoverArtProps, EVENT_BADGE, EventCardProps, GuestFeatureBody(), guestFeatureHref(), UNKNOWN_EVENT_BADGE, watchlistNote() (+6 more) -### Community 41 - "Query Column Reference Analysis" -Cohesion: 0.18 -Nodes (19): NormalizeIdent(), StripIdent(), StripSchemaQualifier(), SplitTopLevelCommas(), createTableColumns(), parseAlterAction(), classifyBareColumn(), expandStar() (+11 more) - -### Community 42 - "Search UI Components" -Cohesion: 0.12 -Nodes (21): SearchResultRow(), SearchResultRowProps, SearchResultsColumns(), SearchResultsColumnsProps, SOURCE_LABELS, SourceColumn(), SourceColumnProps, sourceLabel() (+13 more) - -### Community 43 - "Web Runtime Dependencies (43)" -Cohesion: 0.08 -Nodes (25): @base-ui/react, class-variance-authority, @fontsource-variable/inter, isbot, lucide-react, next-themes, react-dom, react-router (+17 more) +### Community 30 - "ManageTagsDialog" +Cohesion: 0.13 +Nodes (14): BulkActionBar(), commitAddTag(), commitRemoveTag(), exitInline(), openAddTag(), ManageTagsDialog(), handleConfirmDelete(), handleConfirmMerge() (+6 more) -### Community 44 - "Migration-Check Scanner" -Cohesion: 0.18 -Nodes (20): buildPrevReleaseRefs(), buildReport(), classifyAction(), crossReferenceFinding(), newFinding(), parseAnnotation(), pathAllowedForGitShow(), readAtTag() (+12 more) +### Community 31 - "service.go (2)" +Cohesion: 0.21 +Nodes (14): github.com/danielrpof/drop-tracker/internal/db/sqlc.ListWatchlistRow, entryFromRow(), Entry, Service, NewService(), NormalizeNote(), normalizeSet(), WithArtistArt() (+6 more) -### Community 45 - "Config Loading Tests" -Cohesion: 0.18 -Nodes (24): Load(), configEnvKeys(), envExampleKeys(), repoRoot(), setDiff(), setRequired(), TestDockerComposeWiresGateEnvVars(), TestDotEnvIsNotTracked() (+16 more) +### Community 32 - "ROADMAP doc" +Cohesion: 0.14 +Nodes (20): Notes requirement NOTE-01, Bulk endpoints (delete, tags add/remove, preferences), Per-artist 10-tag cap trigger, Chunk fixture precondition todo, Deviation from research: vertical Phase 24 slice, latest_release_date lateral join, Migrations 000011/000012 tag cap trigger fixes, Confirm-step timeout trap (matchTimeout 8s) (+12 more) -### Community 46 - "Notifier Integration Tests (46)" -Cohesion: 0.17 -Nodes (21): Cadence, time.Location, NewService(), TestService_FreshSchemaSeedsOneRowWithDefaults(), TestService_LastSentWatermarkUntouched(), TestService_SecondRowRejectedByCheckConstraint(), TestService_UpdateIsIdempotent(), TestService_UpdateLeavesSlotUntouched() (+13 more) +### Community 33 - "TagChips.tsx (2)" +Cohesion: 0.13 +Nodes (16): nextPendingId(), TagActions, TagChips(), attachErrorMessage(), handleCommit(), handleRemove(), TagComboboxProps, WatchlistRowProps (+8 more) -### Community 47 - "Events Service Tests (47)" -Cohesion: 0.28 -Nodes (22): NewService(), datePtr(), insertTestArtist(), insertTestEvent(), insertTestEventAt(), insertTestEventTyped(), insertTestEventWithDate(), TestHandleListEvents_CursorRoundTripsThroughHTTP() (+14 more) +### Community 34 - "artist_tags" +Cohesion: 0.12 +Nodes (13): artists, watchlist, events, artist_tags, artist_tags_cap_trigger, check_artist_tags_max_per_artist(), check_artist_tags_max_per_artist, tags (+5 more) -### Community 48 - "Dialogs, Auth Store & App Shell (48)" +### Community 35 - "full-pipeline.yml" Cohesion: 0.14 -Nodes (17): Dialog(), DialogContent(), DialogDescription(), DialogFooter(), DialogHeader(), DialogOverlay(), DialogTitle(), FocusRequest (+9 more) - -### Community 49 - "Web Dev Dependencies (49)" -Cohesion: 0.09 -Nodes (23): jsdom, prettier, prettier-plugin-tailwindcss, tailwindcss, @testing-library/dom, @testing-library/react, @testing-library/user-event, @types/node (+15 more) +Nodes (18): Definition of Done (local CI gates), No AI Attribution in Commits/PRs, Recommended Tech Stack (chi, sqlc, pgx, golang-migrate, robfig/cron, caarlos0/env, slog, httplog), Full Pipeline GitHub Actions Workflow, build-scan job (image build, provenance check, tz boot check, Trivy image scan), coverage-comment job (report-only sticky PR comment), frontend-test job (prettier --check + Vitest), gitleaks job (+10 more) -### Community 50 - "Events sqlc Queries" +### Community 36 - "CONCERNS doc" Cohesion: 0.13 -Nodes (10): Event, recordingQuerier, HasOlderEventsParams, InsertEventParams, ListEventsParams, ListEventsRow, Queries, AdvanceGroupTrackCountBaselineParams (+2 more) +Nodes (18): docker-compose vs .env.example port drift, CONCERNS.md (codebase concerns), DSN password redaction, decodeJSONBody helper fragility, Migration ordering and idempotency, Non-root container user UID 10001, Notifier DB timeout bounds (fixed in 479c781), Poll cycle hangs without upstream timeouts (+10 more) -### Community 51 - "Digest Chunking Tests (51)" +### Community 37 - "dialog.tsx" Cohesion: 0.15 -Nodes (22): buildDigestChunks(), digestWindowHeader(), remainderMarker(), syntheticEvents(), TestBuildDigestChunks_CapLastChunkCarriesRemainderMarker(), TestBuildDigestChunks_DeluxeTrackCountSuffix(), TestBuildDigestChunks_DuplicateSourcesRenderAsTwoLines(), TestBuildDigestChunks_EmptyGroupOmitsHeadingEntirely() (+14 more) - -### Community 52 - "Tag Schema Tests" -Cohesion: 0.28 -Nodes (20): detachRaceResult, assertDetachRaceRefused(), insertTag(), linkTag(), runDetachRace(), seedArtist(), seedArtistNamed(), TestSchema_Migration000011_DownUpRoundTrip() (+12 more) - -### Community 53 - "SQL Lexer (Dollar Quoting)" -Cohesion: 0.16 -Nodes (17): strings.Builder, TestCopyDollarQuoted_NoClosingTagCopiesRemainder(), TestDollarTagAt(), TestFindFromJoinTables_AdjacentFromJoinBothFound(), copyDollarQuoted(), copySingleQuoted(), dollarTagAt(), RawStatement (+9 more) - -### Community 54 - "Readiness Endpoint Tests" -Cohesion: 0.28 -Nodes (18): fakeSchemaVersioner, readyBody, getReady(), schemaAt(), TestReady_AheadOfSource(), TestReady_DBUnreachable(), TestReady_EmptySchemaMigrations(), TestReady_ExactPathOnly() (+10 more) - -### Community 55 - "Discord Embed Formatting Tests" -Cohesion: 0.19 -Nodes (19): TestDigestLine_RendersLabelURLAndDeluxeSuffix(), formatEmbed(), emojiPrefix(), i32Ptr(), TestFormatEmbed_AllNilOptionalFields_NoEmptyFieldsNoThumbnail(), TestFormatEmbed_DeluxeChange_BothCountsPresent(), TestFormatEmbed_DeluxeChange_NilBothCounts(), TestFormatEmbed_DeluxeChange_NilPreviousTrackCount() (+11 more) +Nodes (12): Dialog(), DialogContent(), DialogDescription(), DialogFooter(), DialogHeader(), DialogOverlay(), DialogTitle(), Skeleton() (+4 more) -### Community 56 - "ConfirmDialog & AlertDialog" -Cohesion: 0.15 +### Community 38 - "alert-dialog.tsx" +Cohesion: 0.18 Nodes (12): ConfirmDialog(), ConfirmDialogProps, AlertDialog(), AlertDialogAction(), AlertDialogCancel(), AlertDialogContent(), AlertDialogDescription(), AlertDialogFooter() (+4 more) -### Community 57 - "HTTP Handlers & JSON Helpers (57)" -Cohesion: 0.17 -Nodes (12): deezerSource, musicBrainzSource, searchResponse, searchResponseBody, sourceResult, stubSearchSource, ArtistSearcher, SearchArtist (+4 more) +### Community 39 - "server.go" +Cohesion: 0.23 +Nodes (12): chi.Router, net/http.Handler, Pinger, SearchSource, Store, echoRequestID(), Server, New() (+4 more) -### Community 58 - "Tags & Notes Migration" -Cohesion: 0.12 -Nodes (13): artists, watchlist, events, artist_tags, artist_tags_cap_trigger, check_artist_tags_max_per_artist(), check_artist_tags_max_per_artist, tags (+5 more) +### Community 40 - "CONTEXT doc" +Cohesion: 0.13 +Nodes (15): Digest, Digest mode, Digest window, Flush, Outbox, Pending event, Detection engine (internal/detection), Idempotent event recording (ON CONFLICT DO NOTHING) (+7 more) -### Community 59 - "Artist Backfill" -Cohesion: 0.26 -Nodes (15): Stats, Store, Backfill(), matchingCandidate(), TestBackfill_ActivityGate_DelaysThenProceeds(), TestBackfill_AllMatch_WritesUpsertAndRecordsAttemptForEach(), TestBackfill_ContextCancelledPartway_StopsPromptly(), TestBackfill_ListArtistsMissingImageErrors_ReturnsErrNoWrites() (+7 more) +### Community 41 - "detector.go" +Cohesion: 0.21 +Nodes (10): notifyGate, Option, RecordingSource, ReleaseDetailSource, github.com/danielrpof/drop-tracker/internal/db/sqlc.InsertEventParams, github.com/jackc/pgx/v5/pgtype.Timestamptz, Detector, New() (+2 more) -### Community 60 - "Notifier DB Timeout Tests" -Cohesion: 0.17 -Nodes (13): sync/atomic.Int32, callNotifyPending(), discardLogger(), shrinkDBOpTimeout(), TestNotifyPending_ParentCancellationStillPropagates(), TestNotifyPending_RecoversAfterUnresponsiveDatabase(), TestNotifyPending_SettingsReadUnresponsive_ReturnsInsteadOfWedgingLock(), TestNotifyPending_UnresponsiveDatabase_ReturnsInsteadOfWedging() (+5 more) +### Community 42 - "settings.go" +Cohesion: 0.27 +Nodes (12): github.com/danielrpof/drop-tracker/internal/db/sqlc.NotificationSetting, time.Location, Settings, NewService(), ParseCadence(), toSettings(), WithClock(), Cadence (+4 more) -### Community 61 - "Phase 25 Tag Filter Plans" +### Community 43 - "search.go" Cohesion: 0.22 -Nodes (18): Plan 25-05: Watchlist sorts with stable ties, Plan 25-07: Watchlist multi-tag any-of filter, Plan 25-08: preference toggles and chip click-to-filter, Phase 25 Context: Find & Filter, D-05: multi-tag filter is any-of (OR), D-07: Watchlist tag options derived from payload, D-08: card tag chip toggles filter, D-09: Has muted events / Custom release types toggles (+10 more) +Nodes (10): deezerSource, musicBrainzSource, SearchArtist, searchResponse, sourceResult, ArtistSearcher, NewDeezerSource(), NewMusicBrainzSource() (+2 more) -### Community 62 - "Deezer Client Tests (62)" -Cohesion: 0.24 -Nodes (13): golang.org/x/time/rate.Limiter, net/http.Client, Client, NewClient(), Do(), TestDo_CloseCancelsTheDerivedContext(), TestDo_LimiterWaitErrorOnCancelledContext(), TestDo_Success() (+5 more) - -### Community 63 - "Notification Settings Service" -Cohesion: 0.23 -Nodes (10): stubDigestOff, fakeSettingsStore, Cadence, Settings, UpdateParams, ParseCadence(), toSettings(), Option (+2 more) - -### Community 64 - "DB Pool Config" -Cohesion: 0.23 -Nodes (14): github.com/jackc/pgx/v5/pgxpool.Config, dsnSetsMaxConns(), NewPool(), PoolConfig(), poolMaxConnsForWorkers(), redactedTarget(), blackHoleAddr(), TestPoolConfig_AppliesExplicitBounds() (+6 more) - -### Community 65 - "Phase 24 Optimistic UI & Notes" +### Community 44 - "STRUCTURE doc" Cohesion: 0.16 -Nodes (16): D-03: Optimistic chip add/remove with rollback, D-05: Note clamped to 2 lines with more expander, D-06: Note edited in place with Save/Cancel and counter, D-10: Notes on watchlist row, tags on artists.id, D-11: Counts include only watched artists (carriers), D-20: Attach/detach routes under /watchlist/{id}/tags, D-22: GET/PATCH/DELETE /tags and POST /tags/{id}/merge; 409 on collision, D-24: Functional addTag/removeTag updaters with per-row pending set (+8 more) - -### Community 66 - "Phase 25 Release-Date Enrichment" -Cohesion: 0.19 -Nodes (15): Plan 25-01: latest/next release dates on GET /watchlist, Plan 25-03: card shows latest and upcoming release, G1: latest_release_date ignores retention, G2: upcoming = strictly after UTC today at own precision, latest_release_date field, next_release_date field (G3), WLVW-03 Sort by latest release, Phase 25 Research (+7 more) - -### Community 67 - "Artist Search Stubs" -Cohesion: 0.19 -Nodes (8): perArtistOutcome, perArtistSearcher, stubArtistFetcher, stubSearcher, stubSearcherByQuery, artistSearchResponse, stubDeezerArtistSearcher, Artist +Nodes (15): Poller CAS guard release fragility, Where to add new code guide, cmd/server entry point, STRUCTURE.md (directory layout), internal/ package layout, internal/db/migrations (immutable once committed), Naming conventions, Narrow interface pattern (+7 more) -### Community 68 - "Digest Chunk Builder" -Cohesion: 0.21 -Nodes (13): continuationHeading(), continuationNote(), positionIndicator(), renderGroup(), splitOversizedGroup(), TestContinuationHeading_ExactWording(), TestContinuationNote_NoDigit(), TestPositionIndicator_EmptyAtTotalOne() (+5 more) - -### Community 69 - "Phase 24 UI Contract Concepts" -Cohesion: 0.16 -Nodes (14): D-07: Manage tags dialog from Watchlist header, D-16: Reusable AlertDialog confirm for merge/delete, G-24-4: Long chip truncation (fixture issue, not a defect), Phase 24 UI Review (6-pillar audit), 6-pillar UI audit: 17/24, Phase 24 UI Design Contract, Tag chip treatment distinct from status/event badges [R1], ConfirmDialog (reusable AlertDialog wrapper) (+6 more) +### Community 45 - "v1.0 MILESTONE AUDIT doc" +Cohesion: 0.20 +Nodes (15): Discord embed formatting constraints, internal/notifier and discord packages, Markdown escaping for real-time embeds (NTFY-07), Phase 1 debt: SIGTERM and race human verification, Phase 2 debt: review warnings WR-01..05, Phase 3 debt: Lucene injection, Deezer pagination, MusicBrainz unreachable, Phase 4 debt: unmute backlog flood, blank external id guard, Phase 5 debt: live Discord rendering and embed budget checks (+7 more) -### Community 70 - "Events Service Tests (70)" -Cohesion: 0.24 -Nodes (10): stubEventsStore, Service, eventsResponse, eventsResponseBody, stubEventsStore, Event, ListParams, Page (+2 more) +### Community 46 - "ROADMAP doc (2)" +Cohesion: 0.14 +Nodes (14): Project overview: built outward from the data layer, Phase 17 Automated VPS Deploy (deferred), Backlog Phase 999.1 Terraform + Azure ephemeral deploy, Milestone v1.0 MVP (Phases 1-7), Milestone v1.1 Hardening & Scale Readiness (Phases 8-11.1), Milestone v1.2 Cleanup & Display Fixes (Phases 12-13), Milestone v1.3 Continuous Deployment (Phases 14-17, partial), Milestone v1.4 Operator Observability (Phases 18, 18.1, 19) (+6 more) -### Community 71 - "MusicBrainz Releases" -Cohesion: 0.21 -Nodes (6): noReleaseDetailSource, Client, Release, Medium, releaseEnvelope, fakeReleaseDetailSource +### Community 47 - "musicbrainz.go" +Cohesion: 0.30 +Nodes (8): Detector, newNotifyGate(), nullableString(), deluxeDetectionEnabled(), eventTypeMuted(), releaseTypeAllowed(), Detector, releaseTypeForStorage() -### Community 72 - "Phase 25 URL State & Name Filter" -Cohesion: 0.21 -Nodes (13): Plan 25-04: name filter, count, URL state, sticky cards, D-04: accent-insensitive name substring search, D-10: three distinct empty states + Clear filters, D-12: filter state in URL query params, G4: sticky cards, G5: name fold table ($ to s, o-slash to o, ae, ss), useUrlParams hook (no code analog), foldName() helper (+5 more) +### Community 48 - "REQUIREMENTS doc" +Cohesion: 0.23 +Nodes (14): Bulk Edit requirements BULK-01..05, Client-side sort/filter decision, REQUIREMENTS.md (v1.6 Watchlist Organization), Future Requirements (deferred), History tag filter HIST-02, Bulk Add requirements IMPT-01..05, Notification requirements NTFY-05..07, Out of Scope decisions (+6 more) -### Community 73 - "Server Entrypoint" -Cohesion: 0.27 -Nodes (9): logInstanceGateStatus(), main(), run(), decodeRecord(), nonEmptyLines(), recordMentions(), TestLogInstanceGateStatus(), TestRun_BootServesHealthThenGracefulShutdownOnCancel() (+1 more) +### Community 49 - "useBulkSelection.ts (2)" +Cohesion: 0.30 +Nodes (12): bulkAddTag(), showToast(), useBulkSelection(), addTag(), applyPreferences(), clearSelection(), finishSuccess(), onRemoveDialogOpenChange() (+4 more) -### Community 74 - "v1.6 Phases & Requirements (74)" +### Community 50 - "INTEGRATIONS doc" Cohesion: 0.17 -Nodes (12): Filter vs Search, Latest Release, Upcoming Release, Option D: Upcoming Releases Calendar, BULK-01..05 Bulk Edit Requirements, IMPT-01..05 Paste-a-List Bulk Add Requirements, WLVW-01..06 + HIST-02 Find & Filter Requirements, ROADMAP.md (v1.6 Phases 24-28) (+4 more) +Nodes (13): MusicBrainz TLS handshake failure (environmental), GitHub Actions CI/CD pipeline, INTEGRATIONS.md (external integrations), Deezer API integration, Three-stage Dockerfile image, MusicBrainz API integration, No user authentication, Logging and observability (+5 more) -### Community 75 - "Discord Webhook Client" -Cohesion: 0.29 -Nodes (8): allowedMentions, EmbedImage, retry429Body, webhookPayload, Client, Embed, EmbedField, fakeSender - -### Community 76 - "Discord Client Retry Tests" +### Community 51 - "status.go" Cohesion: 0.30 -Nodes (11): NewClient(), TestSend_400_ReturnsErrorNotMatchingSentinel(), TestSend_429Exhausted_ErrorNeverLeaksBodyOrToken(), TestSend_429RetryAfterClamped(), TestSend_429ThenSuccess_HonorsRetryAfter(), TestSend_429Twice_ReturnsErrorAfterSingleRetry(), TestSend_AllowedMentionsAlwaysSuppressed(), TestSend_ErrorPaths_NeverLeakTokenOrBody() (+3 more) +Nodes (11): serverConfig, StatusDeps, statusInstance, statusResponse, statusRun, statusSource, StatusStore, WatchlistCounter (+3 more) -### Community 77 - "Activity Gate" -Cohesion: 0.27 -Nodes (7): ActivityGate, NewActivityGate(), TestActivityGate_ActiveWhileBegunNotEnded(), TestActivityGate_ConcurrentUse(), TestActivityGate_DoubleEndDoesNotCorruptState(), TestActivityGate_FreshGateIsNotActive(), TestActivityGate_TwoConcurrentBeginsBothMustEnd() - -### Community 78 - "v1.6 Phases & Requirements (78)" -Cohesion: 0.18 -Nodes (11): Carrier, Tag Merge, Note (watchlist entry annotation), Tag, Tag Link (belongs to artist), Per-artist 10-tag Cap via Locking Trigger (ADR 0004), NOTE-01 Artist Note, NTFY-05..07 Tags on Discord Notifications (+3 more) - -### Community 79 - "Phase 24 Pattern Map Concepts" -Cohesion: 0.20 -Nodes (11): D-21: Idempotent attach (200) and detach (204), D-26: POST/PATCH /watchlist return tags+note via same enrichment; tags never null, Three-layer validation (handler, service, DB CHECK), Phase 24 Pattern Map, apiFetch as single client call path, :execrows idempotent delete, Handler skeleton: parse id, bound body, decode, validate, service, switch sentinel, Non-nil slice guarantee (+3 more) - -### Community 80 - "Phase 24 Postgres Research Findings" -Cohesion: 0.22 -Nodes (11): D-29: One-statement get-or-create via ON CONFLICT (lower(name)) DO UPDATE, D-31: Non-ASCII case identity tests and NFC normalization, Constraint-name error mapping (pgErr.ConstraintName), Phase 24 Research, BEFORE INSERT trigger fires before ON CONFLICT arbitration, Postgres lower() non-ASCII folding depends on collation (assumption), Expression-index ON CONFLICT target and RAISE USING CONSTRAINT, Parallel array_agg tag enrichment, not json_agg (+3 more) - -### Community 81 - "Phase 24 Review, UAT & Verification" -Cohesion: 0.18 -Nodes (11): Requirements TAG-01..07, NOTE-01, Phase 24 Code Review (24-14 increment), IN-01/02: tailwind-merge misclassifies text-label as colour, IN-03/04: Test hygiene and missing G-24-10 branch tests, WR-01: Hand-off lands on stale rename row's Cancel, Phase 24 UAT, G-24-14: Textarea 14px reading from stale go:embed build, Phase 24 Validation Strategy (+3 more) +### Community 52 - "musicbrainz.go (2)" +Cohesion: 0.24 +Nodes (9): coverArtURLForReleaseGroup(), earlierDate(), earliestReleaseDate(), guestFeatureArt(), withinDeluxeRecheckWindow(), Client, RecordingRelease, recordingLookupResponse (+1 more) -### Community 82 - "Phase 25 History Tag Filter Plans" -Cohesion: 0.35 -Nodes (10): Plan 25-02: GET /events tag_id filter with retention, Plan 25-06: History Tag control, Plan 25-09: History filters move to URL params, Plan 25-10: rebuild embedded SPA and phase DoD gate, D-11: History single-select tag via scalar tag_id narg, G6: History URL state as its own plan, HIST-02 History tag filter, Pattern 2: tag_id narg EXISTS over artist_tags in retention-aware ListEvents/HasOlderEvents (+2 more) +### Community 53 - "STATE doc" +Cohesion: 0.21 +Nodes (12): Event history disk growth, -race testing broken on Windows dev machine, Frontend XSS via untrusted data, Phase 15 coverage-report tool and PR comment, Accumulated decision log, v1.5 digest notifications design, Grilling sessions override earlier decisions, Phase 18.1 poll-cycle instrumentation (+4 more) -### Community 83 - "Web package.json Scripts" -Cohesion: 0.18 -Nodes (10): name, private, scripts, build, dev, format, test, test:watch (+2 more) +### Community 54 - "STACK doc" +Cohesion: 0.21 +Nodes (12): Environment configuration variables, go-chi/chi v5 router, caarlos0/env v11 config, STACK.md (technology stack), React 19 + React Router 7 + Vite + Tailwind 4 SPA, Go 1.26 backend, golang-migrate v4, pgx/v5 and sqlc codegen (+4 more) -### Community 84 - "Search Cancellation Stubs" +### Community 55 - "WatchlistBulkStore" Cohesion: 0.22 -Nodes (6): cancelingSearcher, recordingTimeSearcher, ArtistSearcher, context.CancelFunc, io.ReadCloser, cancelReadCloser - -### Community 85 - "Migration-Check Git Diff" -Cohesion: 0.27 -Nodes (10): appendGithubOutput(), diffRange(), filterMigrationUpFiles(), runChangedFiles(), TestDiffRange(), TestFilterMigrationUpFiles_KeepsOnlyTheGlob(), TestValidCommitishAndValidBranchRef(), withStubCommitExists() (+2 more) +Nodes (8): logInstanceGateStatus(), main(), run(), WatchlistBulkStore, IsWeakPassphrase(), Short(), Option, WithWatchlistBulk() -### Community 86 - "Codebase Architecture Map" -Cohesion: 0.36 -Nodes (8): deezer.Client (internal/deezer/client.go), Detector (internal/detection/detector.go), discord.Client (internal/discord/client.go), events.Service.List (internal/events/service.go), handleSearch (internal/httpserver/search.go), musicbrainz.Client (internal/musicbrainz/client.go), RunDeezerCycle (internal/poller/poller.go), RunMusicBrainzCycle (internal/poller/poller.go) - -### Community 87 - "MusicBrainz Artist Lookup" +### Community 56 - "bulk.go" Cohesion: 0.33 -Nodes (6): stubArtistDetailLookup, ArtistDetail, Client, ArtistAlias, ArtistRelation, ArtistRelationURL - -### Community 88 - "MusicBrainz Artist Search" -Cohesion: 0.31 -Nodes (6): stubMusicBrainzArtistSearcher, clampLimit(), escapeLucene(), Artist, Client, artistSearchResponse - -### Community 89 - "Per-Artist Tag Cap Decisions" -Cohesion: 0.28 -Nodes (9): Phase 24 Context: Artist Tags & Notes, ADR 0004: Per-artist tag cap trigger, D-18: 10-per-artist cap as BEFORE INSERT trigger, D-19: Merge deletes duplicates then UPDATEs, never inserts, Phase 24 Discussion Log, Claude's discretion: cap mechanism, collision API shape, enrichment form, FOR NO KEY UPDATE does not block FK FOR KEY SHARE, Row visibility within multi-row INSERT (Phase 26 bulk attach) (+1 more) - -### Community 90 - "Phase 24 Security Threats" -Cohesion: 0.22 -Nodes (9): D-09: Inline rename; collision opens merge confirmation, D-30: Tag vocabulary loads on first use, Phase 24 Security Threat Register, Generation-guarded loads (vocabGen, loadGen) T-24-54/58, Migrations 000011/000012: cap trigger UPDATE path and CR-01 lock fix, Stored XSS mitigated by plain JSX text (no dangerouslySetInnerHTML), T-24-12: Silent merge on rename prevented by 409 CollisionError, T-24-63: Confirm titles overflowing hide tag names (+1 more) +Nodes (8): axesOverlap(), Service, missingIDs(), normalizeAxis(), AxisDelta, BulkRemoveResult, BulkUpdateResult, PreferencesDelta -### Community 91 - "Release Detector" -Cohesion: 0.36 -Nodes (5): Option, RecordingSource, ReleaseDetailSource, Detector, WithNotifyMaxReleaseAgeDays() - -### Community 92 - "Single-Instance ADRs (92)" +### Community 57 - "tags.go" Cohesion: 0.25 -Nodes (8): Single-instance constraint (no leader election in robfig/cron), ADR 0002: One outbox, one sender lock, CAS-skip on held lock, Digest mode (v1.5), Notification outbox (pending events), Notifier.notifying shared CAS sender lock, Postgres advisory lock (rejected option), ADR 0003: Digest ack splits event-ack from completion +Nodes (8): attachTagRequest, deleteTagResponse, mergeTagRequest, renameTagRequest, tagResponse, TagStore, Option, WithTags() -### Community 93 - "Query Refs Tests" -Cohesion: 0.46 -Nodes (7): mustHigh(), mustNotHigh(), readPrevReleaseFixture(), refsFor(), TestQueryColumnRefs(), TestQueryColumnRefs_IdentifierCaseFolding(), TestRefSet_MergeAndLookups() +### Community 58 - "recordings.go" +Cohesion: 0.33 +Nodes (6): displayArtistName(), isGuestFeature(), Client, Recording, ArtistCreditEntry, recordingEnvelope -### Community 94 - "SPA Embed Handler" +### Community 59 - "logging.go" Cohesion: 0.39 -Nodes (6): Handler(), firstJSAsset(), TestHandler_MissingAssetPathFallsBackInsteadOf404(), TestHandler_RootPathServesIndexHTML(), TestHandler_ServesRealEmbeddedAssetDirectly(), TestHandler_UnknownPathFallsBackToIndexHTML() - -### Community 95 - "End-to-End Boot Tests" -Cohesion: 0.60 -Nodes (4): RowQuerier, SchemaVersionReader, NewSchemaVersionReader(), SchemaVersion() +Nodes (6): log/slog.Level, Config, Load(), New(), NewWithWriter(), parseLevel() -### Community 96 - "Single-Instance ADRs (96)" -Cohesion: 0.33 -Nodes (6): ADR 0001: In-process ring buffer for poll-run history, poll_runs table (rejected option), CONTEXT.md glossary vocabulary, Domain Docs agent guide, Flag ADR conflicts rule, n1-boot CI job +### Community 60 - "releases.go" +Cohesion: 0.39 +Nodes (4): Client, Medium, Release, releaseEnvelope -### Community 97 - "Status Snapshot & Ring Buffer (97)" -Cohesion: 0.40 -Nodes (6): In-process poll-run ring buffer (pollruns.Store), poller.RunRecorder seam, httpserver.StatusStore seam, handleStatus (internal/httpserver/status.go), gate.Authenticate passphrase gate (X-Instance-Gated), pollruns.Snapshot() +### Community 61 - "CONTEXT doc (2)" +Cohesion: 0.29 +Nodes (7): Carrier, Merge (tags), Note, Tag, Tag link, Tag vocabulary, Watched artist -### Community 98 - "Digest Ack Split" -Cohesion: 0.40 -Nodes (6): AckDigestBatch query, AckEventsOnly query, digest_last_slot_at / digest_last_sent_at, AND notified_at IS NULL idempotence predicate, Split event-ack from digest completion, context.WithoutCancel ack bounded by dbOpTimeout +### Community 62 - "artist_lookup.go" +Cohesion: 0.43 +Nodes (5): ArtistDetail, Client, ArtistAlias, ArtistRelation, ArtistRelationURL -### Community 99 - "Tag Cap Locking & Merge" -Cohesion: 0.33 -Nodes (6): ADR 0004: Per-artist tag cap locking trigger, artist_tags_max_per_artist constraint name, Migration 000011 (cap trigger on UPDATE OF artist_id), Migration 000012 (FOR KEY SHARE vs concurrent detach), TAG-04 (10 tags per artist cap), artist_tags cap trigger (locking, skip-existing) +### Community 63 - "terraform always on env doc" +Cohesion: 0.52 +Nodes (7): Always-on B1ms Flexible Server cost, Drift detection via scheduled plan, Long-lived Terraform environment seed, Provider and version upgrades, Seed: Promote Ephemeral Terraform Env, Separate prod-like workspace, State-recovery drill -### Community 100 - "Migration Rollback Rules" +### Community 64 - "activity.go" Cohesion: 0.40 -Nodes (6): internal/sqlscan dollar-quoted body handling, migration-check:allow-destructive annotation, Rule 1: backward-incompatible changes break rollback, cmd/migration-check CI guard, Migrations rollback-safety rules, Rule 2: unsafe-forward changes break or lock the deploy +Nodes (3): sync/atomic.Int32, ActivityGate, NewActivityGate() -### Community 101 - "Status Snapshot & Ring Buffer (101)" -Cohesion: 0.33 -Nodes (6): Tag merge via UPDATE tag_id (never insert), schema_applied / schema_expected version seam, internal/db ahead-of-source no-op test, Expand / backfill / contract pattern (000006, 000007), N-1 rollback invariant, RunMigrations (boot-time embedded migrations) - -### Community 102 - "Web Template & Status Client" -Cohesion: 0.33 -Nodes (6): /status run object, SPA API client (web/app/lib/api.ts), GET /status frozen response contract, pnpm allowBuilds (esbuild yes, msw no), pnpm transitive CVE overrides (nanoid, postcss, browserslist, fast-uri, js-yaml), React Router + shadcn/ui web template +### Community 65 - "backfill.go" +Cohesion: 0.60 +Nodes (4): Stats, Store, Backfill(), waitForActivityGate() -### Community 103 - "Login Throttle Tests (103)" +### Community 66 - "alerter.go" Cohesion: 0.47 -Nodes (4): IsWeakPassphrase(), TestIsWeakPassphrase(), TestWeakPassphraseBootWarn_EmptyOrStrongLogsNothing(), TestWeakPassphraseBootWarn_OneWarnLineNeverContainsValue() +Nodes (4): noopAlerter, Alerter, NoOpAlerter(), SelectAlerter() -### Community 104 - "Build Info" +### Community 67 - "CONTEXT doc (3)" Cohesion: 0.33 -Nodes (4): Short(), TestShort_Truncates(), TestVersion_DefaultsToDev(), TestVersion_Injected() +Nodes (6): Cadence, Digest slot, Grace window, Slot record, Watermark, Calendar-based slot math over duration math -### Community 105 - "Combobox Interaction" -Cohesion: 0.47 -Nodes (5): G7: keep both comboboxes, Combobox(), commitSelection(), handleTriggerKeyDown(), openAt() +### Community 68 - "schema_version.go" +Cohesion: 0.60 +Nodes (4): RowQuerier, SchemaVersionReader, NewSchemaVersionReader(), SchemaVersion() -### Community 106 - "Digest Mode Concepts" -Cohesion: 0.40 -Nodes (5): Digest Mode, Digest Window, Flush, Outbox, SettingsReader Required Constructor Arg, Fail-closed Gate +### Community 69 - "server.go (2)" +Cohesion: 0.33 +Nodes (5): Option, readyResponse, SchemaVersioner, WithAuthGate(), WithReadiness() -### Community 107 - "Digest Slot & Watermark" +### Community 70 - "settings.go (2)" Cohesion: 0.40 -Nodes (5): Digest Slot (00:05 America/New_York), Grace Window (12h daily / 48h weekly), Slot Record (digest_last_slot_at), Watermark (last digest sent), Group-preferred Digest Chunking with Per-chunk Ack +Nodes (5): settingsResponse, SettingsStore, updateSettingsRequest, WithSettings(), toSettingsResponse() + +### Community 71 - "releasegroups.go" +Cohesion: 0.53 +Nodes (3): Client, ReleaseGroup, releaseGroupEnvelope + +### Community 72 - "HistoryFilters.tsx" +Cohesion: 0.60 +Nodes (4): Combobox(), commitSelection(), handleTriggerKeyDown(), openAt() -### Community 108 - "Deezer Client" -Cohesion: 0.50 -Nodes (3): AlbumLister, APIError, errorProbe +### Community 73 - "pnpm workspace doc" +Cohesion: 0.70 +Nodes (4): allowBuilds esbuild and msw, pnpm workspace config, Transitive CVE overrides, Trivy fs HIGH CVE findings -### Community 109 - "v1.4 Observability Milestone (109)" +### Community 74 - "CONTEXT doc (4)" Cohesion: 0.67 -Nodes (3): Option C: Operator Status Panel + /ready, Don't Roadmap Phases Gated on Uncontrolled Infra, Phase 17: Automated VPS Deploy (deferred) +Nodes (4): Latest release, Upcoming release, Option D: Upcoming Releases Calendar, latest_release_date ignores retention (G1) ## Knowledge Gaps -- **208 isolated node(s):** `vitestSummary`, `github.com/danielrpof/drop-tracker`, `loginRequest`, `notification_settings`, `Queries` (+203 more) - These have ≤1 connection - possible missing edges or undocumented components. (Counts symbols only; 417 node(s) total have ≤1 connection when file, concept and rationale nodes are included.) -- **25 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes. +- **175 isolated node(s):** `vitestSummary`, `github.com/danielrpof/drop-tracker`, `loginRequest`, `notification_settings`, `Client` (+170 more) + These have ≤1 connection - possible missing edges or undocumented components. (Counts symbols only; 336 node(s) total have ≤1 connection when file, concept and rationale nodes are included.) +- **17 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes. ## Suggested Questions _Questions this graph is uniquely positioned to answer:_ -- **Why does `Phase 25 Pattern Map` connect `Frontend API Client & Watchlist Route` to `Phase 25 Release-Date Enrichment`, `shadcn UI Primitives`, `Phase 25 URL State & Name Filter`, `History Route & Event Cards`, `Tag Chips & Combobox UI`, `Phase 25 History Tag Filter Plans`, `Artist Note & Preference Toggles`, `Watchlist Service`, `Phase 25 Tag Filter Plans`?** - _High betweenness centrality (0.219) - this node is a cross-community bridge._ -- **Why does `NewService()` connect `Watchlist & Detector DB Tests` to `Notifier Core`, `Server Entrypoint`, `Watchlist HTTP Tests`, `Watchlist Service`?** - _High betweenness centrality (0.159) - this node is a cross-community bridge._ -- **Why does `Phase 25 Context: Find & Filter` connect `Phase 25 Tag Filter Plans` to `Phase 25 Release-Date Enrichment`, `HTTP Handlers & JSON Helpers (3)`, `Frontend API Client & Watchlist Route`, `Phase 25 URL State & Name Filter`, `Combobox Interaction`, `Phase 25 History Tag Filter Plans`, `Per-Artist Tag Cap Decisions`, `Watchlist Service`?** - _High betweenness centrality (0.115) - this node is a cross-community bridge._ +- **Why does `run()` connect `WatchlistBulkStore` to `writeError`, `.HandleLogin`, `deezer/client.go`, `notifier.go`, `migrate.go`, `match.go`, `service.go`, `poller.go`, `service.go (2)`, `server.go`, `detector.go`, `settings.go`, `search.go`, `status.go`, `tags.go`, `logging.go`, `activity.go`, `backfill.go`, `alerter.go`, `schema_version.go`, `server.go (2)`, `settings.go (2)`?** + _High betweenness centrality (0.046) - this node is a cross-community bridge._ +- **Why does `NewWithWriter()` connect `logging.go` to `main.go`, `notifier.go`?** + _High betweenness centrality (0.036) - this node is a cross-community bridge._ +- **Why does `runScan()` connect `main.go` to `parse.go`?** + _High betweenness centrality (0.023) - this node is a cross-community bridge._ +- **Are the 6 inferred relationships involving `Watchlist()` (e.g. with `addTag()` and `announce()`) actually correct?** + _`Watchlist()` has 6 INFERRED edges - model-reasoned connections that need verification._ - **What connects `vitestSummary`, `github.com/danielrpof/drop-tracker`, `loginRequest` to the rest of the system?** - _208 weakly-connected nodes found - possible documentation gaps or missing edges._ -- **Should `Watchlist & Detector DB Tests` be split into smaller, more focused modules?** - _Cohesion score 0.053376623376623376 - nodes in this community are weakly interconnected._ -- **Should `Poller Tests` be split into smaller, more focused modules?** - _Cohesion score 0.06086956521739131 - nodes in this community are weakly interconnected._ -- **Should `Watchlist HTTP Tests` be split into smaller, more focused modules?** - _Cohesion score 0.05929989550679206 - nodes in this community are weakly interconnected._ \ No newline at end of file + _175 weakly-connected nodes found - possible documentation gaps or missing edges._ +- **Should `writeError` be split into smaller, more focused modules?** + _Cohesion score 0.06621226874391431 - nodes in this community are weakly interconnected._ +- **Should `26 RESEARCH doc` be split into smaller, more focused modules?** + _Cohesion score 0.05608322026232474 - nodes in this community are weakly interconnected._ \ No newline at end of file diff --git a/graphify-out/graph.html b/graphify-out/graph.html index b343139..9377004 100644 --- a/graphify-out/graph.html +++ b/graphify-out/graph.html @@ -63,12 +63,12 @@