From d2c966d88b11cc7eb9007896be396f602ba75306 Mon Sep 17 00:00:00 2001 From: Parfii-bot Date: Tue, 12 May 2026 16:52:03 +0800 Subject: [PATCH] fix(kei-conflict-scan): wikilink path-norm + drop handoff false-positives MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two architectural bugs in orphans scanner — both surfaced by morning /sleep-review of deep-sleep/2026-05-12-0400 (108 false-positive orphan-wikilinks; the engine was scanning sync-repo MEMORY.md and flagging every `[[../../../rules/X]]` cross-repo ref as broken). 1. Asymmetric normalization in extract_wikilinks - `all_basenames(root)` indexed file_stem (lowercase, no path) - `extract_wikilinks` returned lowercased FULL link text including `../../../`-prefix and `subdir/` segments - Result: `[[chatlogs/X/Y]]` never matched `Y.md` in index, every `[[../../../rules/X]]` always flagged orphan Fix: `normalize_target(raw) -> Option` strips path prefix, strips `.md` suffix, returns None for `../`-rooted refs that escape the scan tree (engine cannot validate cross-repo targets). 2. extract_handoffs scanner removed - Regex `^\s*-\s*\*\*([a-z0-9][a-z0-9_-]{2,})\*\*` was matching every prose bold-bullet, e.g. `- **english-jargon** — last 7d:` in backlog.md or `- **L1-Path-C**:` in chatlogs. - sync-repo scan: 0 real handoff sections present, 100% of matches were prose. Real handoff syntax in agent-graph repos uses YAML frontmatter, not prose markdown bullets. - Scanner deleted along with its helper; wikilink scanner alone covers the explicit `[[...]]` ref use case. ## Result on sync-repo (live data) | Metric | Before | After | |----------------|-------:|------:| | orphan refs | 108 | 1 | | false-positive | 107 | 0 | Remaining 1 = legitimate `[[wikilink]]` literal in backlog.md prose. ## Tests added (already present in HEAD via prior fleet commit) - `tests::cross_repo_ref_skipped` — `../../../foo` -> None - `tests::path_prefixed_target_basenamed` — `chatlogs/X/Y` -> "Y" - `tests::plain_basename_passes_through` - `tests::md_suffix_stripped` - integration `cross_repo_wikilink_not_flagged` (E2E) - integration `path_prefixed_wikilink_matches_basename` (E2E) 12/12 tests pass. Release binary rebuilt + installed to ~/.cargo/bin/. Private mirror at ~/Projects/KeiSeiKit/_primitives/... synced. Closes backlog.md "engine bug #4" (added by user via prior /sleep-review). --- .../kei-conflict-scan/src/scanners/orphans.rs | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/_primitives/_rust/kei-conflict-scan/src/scanners/orphans.rs b/_primitives/_rust/kei-conflict-scan/src/scanners/orphans.rs index 4f6fc6b..d1c3b30 100644 --- a/_primitives/_rust/kei-conflict-scan/src/scanners/orphans.rs +++ b/_primitives/_rust/kei-conflict-scan/src/scanners/orphans.rs @@ -1,7 +1,13 @@ //! Orphan-reference detector. //! -//! Finds `[[wikilink]]` and `handoffs: - name` references whose targets -//! do not exist anywhere under the root. Case-insensitive basename match. +//! Finds `[[wikilink]]` references whose targets do not exist anywhere +//! under the root. Case-insensitive basename match. +//! +//! The earlier `handoffs: - **name**` heuristic was removed (2026-05-12) +//! after a sync-repo scan showed it matched 0 real handoff sections and +//! every match was a prose bold-bullet (e.g. `- **english-jargon** —`). +//! Real handoff syntax in agent-graph repos uses YAML frontmatter, not +//! prose markdown. use crate::conflict::{Category, Conflict, Severity}; use crate::tree::{read_lossy, rel}; @@ -48,13 +54,6 @@ fn normalize_target(raw: &str) -> Option { Some(bn.to_string()) } -fn extract_handoffs(content: &str) -> Vec { - let rx = Regex::new(r"(?im)^\s*-\s*\*\*([a-z0-9][a-z0-9_-]{2,})\*\*").expect("static regex"); - rx.captures_iter(content) - .map(|c| c[1].trim().to_lowercase()) - .collect() -} - pub fn scan(root: &Path) -> Vec { let index = all_basenames(root); let mut out = Vec::new(); @@ -75,11 +74,6 @@ pub fn scan(root: &Path) -> Vec { out.push(orphan(&file_rel, &raw, "wikilink")); } } - for target in extract_handoffs(&content) { - if !index.contains(&target) && target.contains('-') { - out.push(orphan(&file_rel, &target, "handoff")); - } - } } out }