fix(graph): route wiki/<flat>.md to Type=knowledge, not Type=hall with filename-as-wing
All checks were successful
CI / Lint / Test / Vet (push) Successful in 12s
CI / Mirror to GitHub (push) Successful in 4s

classifyByPath had a hole: paths like wiki/index.md or wiki/<slug>.md
(direct children of wiki/, no subdirectory) hit the default branch and
wrote Wing=parts[1] — which IS the filename, not a wing. Symptom in
brain_entities: rows like (slug=index, wing=index.md) and
(slug=autobe-..., wing=autobe-evaluation-pattern-....md).

Fix: when len(parts) < 3 (no subdirectory at all), fall through to
Type=knowledge and let frontmatter set wing/hall if present.

Add brain/eval/ artifacts at the same time:
- qa-2026-05.md — 20 hand-authored Q→expected-slug pairs covering the
  homelab knowledge corpus across mcp, dex, gitops, postgres, go,
  models, methodology
- score.py — calls brain_query for each pair, scores top-1 + top-3,
  emits per-question detail. BRAIN_MCP_TOKEN via env.

Pre-fix baseline against the live brain: top-1 = 20% (4/20),
top-3 = 65% (13/20). Six hard misses where the expected slug doesn't
even land in the top-5.

Used to gate the phase 2 DIKW redesign (infra#62 follow-up): if
phase 1 fixes (this parser fix + 20 backlink authoring on top
orphans) lift top-1 by <10 absolute points, structure is the
bottleneck and the tier redesign is justified.
This commit is contained in:
Mathias
2026-05-24 22:33:04 +02:00
parent 72be87b4e7
commit 3084c4173d
5 changed files with 413 additions and 0 deletions

View File

@@ -83,12 +83,23 @@ func slugFromPath(docPath string) string {
// classifyByPath fills Type / Wing / Hall from the path layout when the
// doc lives under brain/wiki/. Layout: wiki/<wing>/<hall>/<slug>.md
// or wiki/<bucket>/<slug>.md for the legacy concept/entity/source dirs.
//
// Files directly under wiki/ (no subdirectory — e.g. wiki/index.md) used
// to incorrectly land Type="hall" Wing="index.md" because the path's
// second segment was the file itself. Now they fall through to Type
// "knowledge" and leave wing/hall to frontmatter.
func classifyByPath(e *Entity, docPath string) {
parts := strings.Split(docPath, "/")
if len(parts) < 2 || parts[0] != "wiki" {
e.Type = "knowledge"
return
}
if len(parts) < 3 {
// wiki/<slug>.md — no subdirectory. Treat as plain knowledge
// and let frontmatter set wing/hall if they're present.
e.Type = "knowledge"
return
}
switch parts[1] {
case "concepts":
e.Type = "concept"