feat(brain): /wikilint health checker (read-only) (Phase 4)#46
Merged
Conversation
Adds a read-only audit command surfacing four classes of issue that
compound silently as the brain accumulates KUs:
1. Near-duplicate KUs (cosine >= 0.95 in same (entity, topic_key))
2. Temporal contradictions (overlapping intervals, conflicting text)
3. Orphan entities (<2 linked KUs, >30 days old)
4. Stale wiki pages (last_synthesis_at older than newest KU valid_from)
v1 does NO autonomous CRUD. Each finding includes a "merge /
mark-superseded / ignore" suggestion in the report; the user runs the
action manually. Top anti-pattern from both deep-research passes.
Wired into src/index.ts as /wikilint slash command (intercept order
matters — /wikilint check is placed BEFORE /wiki since they share the
prefix). Cron piggybacks the existing digest scheduler with a 7-day
debounce via system_state.last_wikilint, so no new setInterval.
Class 1 uses a new fetchKuVectors helper in qdrant.ts (Qdrant retrieve
with with_vector: true). Pair budget capped at 500 per run; groups
larger than 32 KUs are themselves anomalous and logged + skipped.
Group key uses a NUL separator since topic_key is space-joined by
extract.ts:normalizeTopic ("current employer") — regression-tested.
Tests: 21 new (15 in wikilint.test.ts, 6 in wikilint-command.test.ts).
Brain suite 431/431 green; full repo 2468/2468; typecheck + build clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds the read-only
/wikilinthealth checker — Phase 4 of the brain wiki layer per .omc/plans/brain-2026-04-27-phases-3-5-detailed.md §4. Builds on Phase 3a/3b (PRs #29 / #32 / #33 / #36).Surfaces four classes of issue that compound silently as KUs accumulate:
(entity, topic_key), both un-superseded.[valid_from, valid_until]with conflicting text.entitiesrow with <2 linked KUs and >30 days old.last_synthesis_atolder than newest KUvalid_from.v1 does NO autonomous CRUD. Each finding ships with a "merge / mark-superseded / ignore" suggestion; the user runs the action manually. Top anti-pattern from both deep-research passes.
Wiring
/wikilintslash command intercept insrc/index.ts, placed before/wikiso the shared prefix doesn't route/wikilintto the entity-resolver.system_state.last_wikilint— no newsetInterval.qdrant.fetchKuVectors(new) — single Qdrantretrieveround-trip withwith_vector: true. Pair budget capped at 500 per run; groups >32 KUs are themselves anomalous and logged + skipped.Notes for reviewers
\0).topic_keyis space-joined byextract.ts:normalizeTopic("current employer"), so a space separator would corrupt multi-word topics onkey.split— regression test pinned inwikilint.test.ts.(db, opts?) => Finding[], withfindDuplicateKusasync only because of the Qdrant fetch.runAllcomposes them.WikilintCommandOptions.dbandWikilintCronOptions.dballow injection for testing without going throughgetBrainDb()singleton.Test plan
npx vitest run src/brain→ 431/431 passing (+21 new tests across the two new test files)npx vitest run(full repo) → 2468/2468 passingnpx tsc --noEmitcleannpm run buildclean/wikilintagainst a realbrain.dbfrom a Telegram main-group chat — verify the report renders + thelast_wikilintrow appears insystem_state🤖 Generated with Claude Code