From e5a982e99aace97abbfed08989e10079c7bde85d Mon Sep 17 00:00:00 2001 From: Andrey Oblivantsev Date: Thu, 13 Aug 2026 21:36:31 +0100 Subject: [PATCH] docs: PicoClaw fact-check tool order before a factual reply (#22) search then get then audit. throttled is not absence. 2dph is the gate, not the agent loop. --- AGENTS.md | 3 +++ PLAN.md | 2 +- bin/tools/test_skills.py | 10 ++++++++++ skills/picoclaw/SKILL.md | 25 +++++++++++++++++++++++++ 4 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 skills/picoclaw/SKILL.md diff --git a/AGENTS.md b/AGENTS.md index 97ef9c9..f655523 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -15,6 +15,9 @@ Read first: [PLAN](PLAN.md) → [docs](docs/). - `info` root = descriptive/narrative leafs, searchable, never asserted as fact. - Search is deduction: `facts` → `info` → `web-search` (second independent source). An answer is `confirmed` only if it comes off the facts root. +- Fact-check every *claim* (facts → info → live → web), not every edit or + syntax tweak. PicoClaw: `search` then `get` then `audit` before a factual + reply (`skills/picoclaw/SKILL.md`). `throttled` is not a negative finding. ## Hard rules diff --git a/PLAN.md b/PLAN.md index f0c5f18..513d056 100644 --- a/PLAN.md +++ b/PLAN.md @@ -51,7 +51,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, postgres, brain, diataxis-docs) + skills/ in-project skills (web-search, postgres, brain, picoclaw, diataxis-docs) bin/ facts/extract.go audit.go crm.go # D14 shebang; Python implementation kb/index Python write path (called by bin/brain/index.go) diff --git a/bin/tools/test_skills.py b/bin/tools/test_skills.py index 330ffd2..9539816 100644 --- a/bin/tools/test_skills.py +++ b/bin/tools/test_skills.py @@ -37,3 +37,13 @@ class SkillsTest(unittest.TestCase): self.assertIn("tools.md", skill) for name in ("search", "get", "stats", "audit"): self.assertIn(f"`{name}`", tools) + + def test_picoclaw_lists_tool_order(self) -> None: + skill = (ROOT / "skills" / "picoclaw" / "SKILL.md").read_text() + agents = (ROOT / "AGENTS.md").read_text() + self.assertIn("**`search`**", skill) + self.assertIn("**`get`**", skill) + self.assertIn("**`audit`**", skill) + self.assertIn("throttled", skill.lower()) + self.assertIn("not a negative finding", agents) + self.assertIn("Fact-check every", agents) diff --git a/skills/picoclaw/SKILL.md b/skills/picoclaw/SKILL.md new file mode 100644 index 0000000..656d9e5 --- /dev/null +++ b/skills/picoclaw/SKILL.md @@ -0,0 +1,25 @@ +--- +name: picoclaw +description: >- + 2dph is the memory/fact gate, not the agent loop. Use when wiring PicoClaw + or any MCP client: call brain search/get/audit before a factual reply. + throttled is not a negative finding. +--- + +# PicoClaw — fact-check before assert + +PicoClaw (or any agent) speaks MCP at `POST /mcp` on `bin/brain/serve.go`. +2dph does not run the agent loop. Compose profile for a live agent is issue #9. + +## Tool order (before a factual reply) + +1. **`search`** — facts root first, then info. The `web` block is a second + source when there is no facts hit. Status `throttled` / `skipped` / + `refused` is **not** evidence of absence. +2. **`get`** — full leaf body only when a hit `id` is needed. +3. **`audit`** — if recall or confidence looks wrong. + +Then answer. Confirmed only from facts (≥2 independent sources). Anything +else is `(not confirmed)`. Missing graph ≠ “does not exist”. + +Generated tool list: [../brain/tools.md](../brain/tools.md).