← all docs · north-os20 July 2026

Eval agent-quality grounding fix — design spec

Status: In progress
Author: OpenAI Codex
Date: 2026-07-20
Repo: north-os
Related: NOS-183; docs/reviews/2026-07-20-eval-agent-quality-harness-bug.md

Problem

The original eval:agent-quality gate was 0/8. Defect 1 now preserves structured search_knowledge provenance and moved main to 2/8, but capToolResultWithCoverage still drops every document-read artifact after deriving metadata.documentReadCoverage. readTranscript therefore receives no checker-consumable artifact for read_knowledge_document, and sourceBearingRead must reject otherwise genuine deep reads.

A second, independent retrieval-quality failure may remain after plumbing is fixed: a named-instrument query can rank a same-topic Environmental Indemnity Agreement above the HFA Bond Mortgage itself.

Goals and invariants

Non-goals

Root-cause decision

Chosen: preserve validated search/email touch artifacts and a minimal document-read projection in the stored ToolMessage produced by capToolResultWithCoverage, then remove every artifact only from the temporary message array passed to the chat model.

This restores the graph-state transcript contract without exposing hidden runtime metadata to the provider. Document checkpoints retain provenance fields only, not full document text or document-processing metadata.

Alternatives rejected

ApproachWhy rejected
Reconstruct artifacts in readTranscript from the coverage ledgerThe ledger is merged and no longer has a one-to-one mapping to individual tool replies. Reconstruction would be lossy and would hide future artifact-stripping bugs.
Parse excerpt IDs from tool textDuplicates the producer contract, trusts presentation text over structured provenance, and is equivalent to weakening the gate.
Pass stored artifacts straight to the modelUnnecessary provider input and contrary to the existing graph invariant that the artifact field does not reach the model.

Document-read projection

The checkpoint artifact is derived only from the validated DocumentCoverageEvent already emitted by the real tool. Its common shape is resourceType, resourceKey, title, and totalChars. For read_knowledge_document, the checker compares resourceKey to the call's document_id and the title to prior structured search provenance.

The projection survives returned state, checkpoint serialization, and readTranscript. modelViewWithoutToolArtifacts continues to clone artifact-bearing tool messages without the artifact before model invocation.

Data flow

searchKnowledgeTool / readKnowledgeDocumentTool
  → coverageToolResult(text, validated coverage event)
  → tool.invoke(call): ToolMessage { content, artifact }
  → capToolResultWithCoverage:
      search/email → capped ToolMessage { content, validated artifact }
      document     → capped ToolMessage { content, minimal artifact, metadata? }
  → AgentState/checkpoint
      ├─→ readTranscript → checker-consumable structured provenance
      └─→ model-facing projection → ToolMessage without artifact → chat model

The model projection retains content, tool identity, status, provider metadata, and document-read projection metadata. Only artifact is omitted.

Regression coverage

Defect 2 decision gate

After Defect 1, record which cases pass and inspect the ranked candidates from the first HFA search_knowledge call. Defect 2 remains present when the named HFA Bond Mortgage does not rank ahead of same-topic candidates from other instruments, whether it is absent or merely lower-ranked. Treat the existing lol-clause-body case as a live golden reference, not a deterministic test. Implement only if a trace identifies one narrow title, fused-pool, best-extent, or reranker seam and a new deterministic fixture reproduces the ordering failure before code changes. Otherwise, defer Defect 2 as a separate retrieval-quality change and preserve the failing query, wrong and intended titles, observed candidate ranks (including explicit absent markers), stage to probe, and acceptance criterion (“the named instrument's own source ranks ahead of same-topic clauses from other instruments”).

Risks

Acceptance criteria

  1. Graph-produced search results retain complete validated touch artifacts, and graph-produced document reads retain only the minimal checker-consumable projection, after capping in returned state, after checkpoint persist/reload, and in readTranscript.
  2. Direct-read ranges are cap-aware; deep-read projections retain coverageMode plus source ranges sufficient for the unchanged completeness guard. No full document text or unused document metadata enters the artifact.
  3. Every model-facing ToolMessage omits the artifact field.
  4. The focused regression test, agent-runtime typecheck, and agent-runtime lint pass.
  5. The post-fix gate is measured and compared with the 2/8 Defect 1 baseline.
  6. No line in packages/agent-runtime/scripts/eval-agent-quality.ts changes. Any independently proven checker defect requires a separate scoped change and may not weaken duplicate-title, deep-read, or provenance guards.