test: gate SKILL.md bin/ paths; name the brain skill brain.
Tests / Test (push) Skipped
Tests / Release (semver) (push) Skipped

Follow-up to the agent-cost delete: unittest fails if a skill names a missing
tool. Frontmatter name is brain, not kb-search.
This commit is contained in:
2026-08-13 17:54:18 +01:00
parent 62ce9585eb
commit 67e1eee72d
4 changed files with 38 additions and 5 deletions
+2 -2
View File
@@ -49,7 +49,7 @@ detective method: **a fact needs ≥2 independent sources or it is
2dph/
PLAN.md / AGENTS.md
docs/ published docs (this conversation → docs/ as md)
skills/ in-project skills (web-search, db-yaml, kb-search, agent-cost, diataxis-docs, …)
skills/ in-project skills (web-search, db-yaml, brain, diataxis-docs)
bin/
facts/extract auto-pair 2 sources → lexicon yaml + graph
facts/audit ["self"|"facts"|"info"|"stale"] 2-source + staleness gate
@@ -140,7 +140,7 @@ Feedback loop: every commit → PR → CI → green/gate → merge. Same discipl
1. scaffold repo (:done after this file + AGENTS.md + .gitignore + ci)
2. gh repo create eSlider/2dph --private + initial commit + CI
3. vendored skill integration (web-search, db-yaml, kb-search, agent-cost, diataxis-docs) — no remote links
3. vendored skill integration (web-search, db-yaml, brain, diataxis-docs) — no remote links
4. .venv: ladybug + model2vec + mistune
5. schema + tools with TDD (kb + md + facts + brain)
6. ~/.config/brain config
+1 -1
View File
@@ -43,7 +43,7 @@ class PublishedDocsTest(unittest.TestCase):
paths = [
ROOT / "README.md",
ROOT / "docs" / "design.md",
ROOT / "skills" / "kb-search" / "SKILL.md",
ROOT / "skills" / "brain" / "SKILL.md",
ROOT / "skills" / "diataxis-docs" / "SKILL.md",
]
# Command-style `--hop 1` / `--hop N` plus follow/walk = the old lie.
+33
View File
@@ -0,0 +1,33 @@
"""Every bin/ path named in skills/ must exist on disk."""
from __future__ import annotations
import re
import unittest
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
BIN_PATH = re.compile(r"\b(bin/[A-Za-z0-9_./-]+)")
class SkillsBinPathsTest(unittest.TestCase):
def test_agent_cost_skill_is_gone(self) -> None:
self.assertFalse(
(ROOT / "skills" / "agent-cost").exists(),
"skills/agent-cost documents bin/agents/cost which does not exist",
)
def test_brain_skill_replaces_kb_search(self) -> None:
self.assertTrue((ROOT / "skills" / "brain" / "SKILL.md").is_file())
self.assertFalse((ROOT / "skills" / "kb-search").exists())
def test_skill_bin_paths_exist(self) -> None:
missing: list[str] = []
for skill in sorted((ROOT / "skills").rglob("SKILL.md")):
text = skill.read_text()
for match in BIN_PATH.findall(text):
rel = match.rstrip("`'.,")
if rel.endswith(".go") or Path(rel).suffix == "" or Path(rel).suffix in {".go", ".py"}:
p = ROOT / rel
if not p.exists():
missing.append(f"{skill.relative_to(ROOT)}: {rel}")
self.assertEqual(missing, [], "SKILL.md names bin/ paths that do not exist")
+2 -2
View File
@@ -1,5 +1,5 @@
---
name: kb-search
name: brain
description: >-
Deduction search over the 2dph brain (Ladybug graph: ops corpus, portfolio,
ssh hosts) with bin/brain/search.go instead of reading files or grepping
@@ -8,7 +8,7 @@ description: >-
documentation.
---
# kb-search — deduction over facts and info
# brain — deduction over facts and info
One embedded Ladybug graph (`var/kb.lbug`, read-only when queried) holding two
roots: