auditor grounding — a prescribed, bounded exploration procedure + born-in find pointers

Observed live: the auditor looped find for a very long time, never touching
list_sessions/list_propositions. Root cause was the prompt: its only
procedure text was 'For each proposition, search the graph (its key words,
its synonyms, its phrasings)' — a per-proposition find loop with no
starting point, no sense of the space's extent, and no termination rule.
And find returned id+name+statement with no session pointer, so results
never composed with the listing tools (owner diagnosis, 2026-09-29).

- AUDITOR_INSTRUCTIONS now prescribes the process: (1) list_sessions ONCE —
  the graph is small and finite, this shows its entire extent; (2) read
  plausibly-related sessions with list_propositions (full text) — every
  realistic candidate seen in a few calls; (3) find as the targeted sweep;
  (4) SUBMIT once related sessions are read — never re-search seen ground
- find hits now carry 'born in: <session id>' — results point at sessions
  the auditor can read whole (legacy no-provenance nodes name none)
- identity doctrine untouched: equivalence bias, linkTo mechanics,
  verdicts-only deliverable
This commit is contained in:
amosblomqvist
2026-09-29 04:10:38 +03:00
parent 86ba2804d1
commit 5707672a09
3 changed files with 30 additions and 7 deletions
+13 -2
View File
@@ -123,7 +123,8 @@ export function auditorGraphTools(ctx: GraphToolContext): Record<string, AgentTo
label: "find",
description:
"Search the knowledge graph for existing propositions — glob over names, statements, and aliases. " +
"Returns each match's id, name, and full statement. This is how you decide whether a new proposition IS an existing one: search its key words, its synonyms, its phrasings.",
"Returns each match's id, name, full statement, and the session(s) it was born in (a list_propositions id). " +
"This is how you decide whether a new proposition IS an existing one: search its key words, its synonyms, its phrasings.",
parameters: findInput,
execute: serverExecute("find", findInput, async ({ query }): Promise<string> => {
const nodes = getGraph(deps.graphStore).nodes;
@@ -131,7 +132,17 @@ export function auditorGraphTools(ctx: GraphToolContext): Record<string, AgentTo
(n) => globMatch(query, n.name) || globMatch(query, n.statement) || n.aliases.some((a) => globMatch(query, a)),
);
if (hits.length === 0) return `No existing proposition matches "${query}".`;
const lines = hits.map((n) => `- ${n.id} :: ${n.name}\n statement: ${n.statement}`);
// BORN-IN POINTER (owner, 2026-09-29): a hit names its birth
// session(s) — find results now compose with list_propositions
// (read the whole session the hit came from) instead of being
// dead ends. Legacy no-provenance nodes name none.
const lines = hits.map((n) => {
const born = [...new Set(n.provenance.map((pt) => pt.chatId))];
return (
`- ${n.id} :: ${n.name}\n statement: ${n.statement}` +
(born.length > 0 ? `\n born in: ${born.join(", ")}` : "")
);
});
return `${hits.length} match(es):\n${lines.join("\n")}`;
}),
},