slim the submit schemas: evidence and messages die; stringified-payload heal at the pre-validation seam

OpenRouter log diagnosis (owner, 2026-09-28): extraction time was
dominated by tool-validation retries. The failing call had the whole
propositions array emitted as ONE JSON-STRING ('propositions.0: must
be object'), a truncated placeholder artifact inside it, and
word-salad statements late in the array — payload-size collapse.
Field audit: 'evidence' was never persisted anywhere and its
faithfulness-checking consumer died with the fully-trusted ruling;
'messages' fed messageId granularity that NOTHING downstream reads,
and the model sent [] anyway (chat-level provenance in practice).
'aliases' stays (optional now): the auditor's find tool globs them.

Schema: propositions = {id, name, statement, aliases?}; edges =
{from, to, type}. Prompts lose the evidence/messages doctrine and
[id]-anchor guidance, gain a compact faithfulness line;
transcriptView renders anchorless. The auditor echo instruction
drops the evidence/messages mention, so its payload halves too.

Heal: healStringifiedArrays on the submit tool's prepareArguments
(pi-agent-core's sanctioned pre-TypeBox shim) parses a stringified
propositions/edges back into arrays — the LaTeX-restore doctrine:
heal weak-model wire behavior at the seam. Test drives the real
agent-loop seam with a stringified submit.
This commit is contained in:
amosblomqvist
2026-09-28 19:04:39 +03:00
parent 14a7f0de1d
commit bd9694b0e4
7 changed files with 131 additions and 125 deletions
+10 -12
View File
@@ -85,16 +85,11 @@ export interface MergeSource {
coverage?: CoverageEntry[];
}
/** (chatId, messageIds) → provenance points; order-preserving, deduped. */
function pointsOf(chatId: string, messages: string[]): ProvenancePoint[] {
const seen = new Set<string>();
const out: ProvenancePoint[] = [];
for (const messageId of messages) {
if (messageId.length === 0 || seen.has(messageId)) continue;
seen.add(messageId);
out.push({ chatId, messageId });
}
return out;
/** The run's chat-level provenance point (submit-schema slim, 2026-09-28:
* propositions no longer carry message ids — the model never reported
* them reliably anyway — so every birth from a run shares one point). */
function pointOf(chatId: string): ProvenancePoint[] {
return [{ chatId, messageId: "" }];
}
const samePoint = (a: ProvenancePoint, b: ProvenancePoint): boolean =>
@@ -140,7 +135,7 @@ export function mergeFindings(chatId: string, audit: AuditResult, deps: GraphDep
for (const p of audit.propositions) {
if (mapping.has(p.id)) continue; // already resolved for this chat — idempotent
const points = pointsOf(chatId, p.messages);
const points = pointOf(chatId);
let graphNodeId: string;
if (p.linkTo !== undefined && existingIds.has(p.linkTo)) {
// Identity verdict: this proposition IS that node. Append a link
@@ -206,7 +201,10 @@ export function mergeFindings(chatId: string, audit: AuditResult, deps: GraphDep
from,
to,
type: edge.type,
provenance: bridged ? [{ chatId, messageId: "" }] : pointsOf(chatId, edge.messages),
// bridged vs transcript edges both carry the run's chat-level
// point now; the distinction lives in the endpoint resolution
// above (mapping vs existing node id), not in the provenance.
provenance: pointOf(chatId),
});
assertedByChat.add(key);
stats.edges++;