fix: excluded categories still capture nested threads - #216
hannesrudolph merged 1 commit into
Conversation
|
🦞👀 Pull request received. I will update this pull request when review starts. ClawSweeper review completeClawSweeper finished reviewing this revision. The review result is being finalized. |
|
Codex review: needs maintainer review before merge. Reviewed September 11, 2026, 2:20 PM ET / 18:20 UTC. ClawSweeper reviewWhat this changesMakes Discord collection exclusions follow category and channel ancestry during sync, repair, and live capture, with regression tests and configuration guidance. Merge readiness✅ Ready for maintainer review This remains a useful, focused fix: current main and v0.14.1 retain the nested-thread exclusion gap. No introduced correctness defect was found, and the member-authored PR is protected from automatic closure. Priority: P2 Review scores
Verification
How this fits togetherDiscrawl collects Discord messages into a local archive. Its syncer combines configured collection rules with channel relationships to decide which historical messages and live events reach storage. flowchart TD
A[Collection configuration] --> D[Ancestry exclusion checks]
B[Discord channel metadata] --> C[Channel relationship catalog]
C --> D
E[Historical sync and live events] --> D
D -->|Allowed| F[Local message archive]
D -->|Excluded| G[Skip collection]
Before mergeNone. Agent review detailsSecurityNone. Review metrics
Technical reviewBest possible solution: Use the shared ancestry checks across collection paths while preserving existing inclusion precedence, configuration values, and archive format. Do we have a high-confidence way to reproduce the issue? Yes, from source: a stored thread beneath a forum in an excluded category passes current main's immediate-parent checks when no category allowlist is set. This review did not execute that path. Is this the best way to solve the issue? Yes. Extending the existing shared evaluator and resolving live ancestry at event time addresses the defect without introducing a competing configuration mechanism. AGENTS.md: not found in the target repository. Codex review notes: model internal, reasoning medium; reviewed against 88a05763f1f0. LabelsLabel changes:
Label justifications:
EvidenceWhat I checked:
Likely related people:
Rating scale
Overall follows the weaker of proof and patch quality. Workflow
|
Additional instructions
MUST: Keep Allow edits from maintainers enabled for this PR so maintainers
can help update the branch when needed.
What Problem This Solves
Fixes an issue where users excluding a Discord category would still collect messages from its nested threads during sync, repair, or live capture after startup. For example, excluding a category containing a forum could leave that forum's threads in collection.
Moving a parent channel between included and excluded categories could also leave existing threads using outdated collection rules.
Why This Change Was Made
Exclusion checks now follow the complete channel ancestry, including when filtering stored channels and targeted threads. Live capture retains channel relationships and evaluates them when checking events, so parent updates also apply to existing descendants. Ancestry traversal handles missing category metadata and cycles.
User Impact
Excluding a category or channel through
sync.exclude_channel_idsnow excludes its descendant channels and threads consistently. Existing category allowlists remain supported, and explicit exclusions still take precedence.Users can choose opt-out collection by leaving
sync.include_category_idsempty and excluding unwanted categories. This PR documents that option; configuration defaults and database schemas are unchanged.Evidence
go test ./internal/syncer -count=1,go test -race ./internal/syncer -count=1, andgo vet ./internal/syncer; changed Go files pass gofumpt.go test ./... -count=1. All packages passed except the pre-existingTestPublishProducerValidationBeforeMutationfailure (tracked remote branch origin/main is missing), also reproduced against the unchanged application source.