An errata agent reviews each document's typed facts, structure first, through the gate by WaylandYang · Pull Request #885 · deeplethe/utopia · GitHub
Skip to content

An errata agent reviews each document's typed facts, structure first, through the gate - #885

Merged
WaylandYang merged 3 commits into
devfrom
feat/errata-agent
Sep 23, 2026
Merged

WaylandYang merged 3 commits into
devfrom
feat/errata-agent

Conversation

@WaylandYang

Copy link
Copy Markdown
Contributor

The sixth cut of 0044 — decision 7: an errata agent reviews the typed graph after extraction, through the 0027 gate. The prototype measured what such an agent buys (judged precision 76.1% → 89.5% on 99 documents) and what it costs (278 retractions, about a quarter of them correct); this builds it so the cost can be governed rather than accepted.

What it does

  • Structure first. For each document with typed facts nobody has looked at, the store flags facts the structure can already doubt: domain / range (an end outside the property's declared kinds, through the class hierarchy), name_absent (a name that does not occur in the document), no_date (a date property without a date). Flagged facts go to the model first; the rest is sampled. The classification is one SQL query with the ancestor closure computed in it, no model call.
  • A JSON action protocol with a per-document budget. The errata_review job sends the document, the ontology's properties and the numbered facts (with their flags and the quote each was read from) in batches of 20, at most two requests per document. The model answers keep / retract / revise for every fact and may add only once every given fact is answered (the parser refuses additions otherwise). Every retract, revise and add must quote the document's own words; the store verifies the quote against the document text and records a quote that is not there — or a name not in the base, or a property that does not exist — as refused, never applied. The agent creates nothing.
  • Actions through the gate. execution_gate gains impact_of_fact (derived facts resting on it, answers that named its subject) and impact_of_write (a one-value property that would get two values, 0027 §5's yardstick). A held action goes to a new errata queue on the Review page — document, proposed change, quote, the reason it was held in 0027's wording — where a person applies or rejects it (POST /kbs/{id}/review/errata/{action_id}). An applied retraction uses reject_fact (invalidated, evidence kept); a revision retracts the old row and writes a typed row that inherits its validity; an addition writes one anchored on the document's date; new rows get the quote as evidence on the chunk that contains it.
  • A retraction sticks. Materialisation and implication skip a (statement, property) pair an applied errata action retracted or revised, so the next run does not resurrect the row; another document's statement of the same thing still materialises, because errata reviews one document.
  • The account. errata_runs records per document what was flagged and sampled, how many requests were made and the endpoint's token usage (utopia_llm::Reply now carries usage from the stream's last frame; absent means none reported, not zero). errata_actions records every verdict, keep included, so a fact is reviewed once.
  • Measurement. scripts/bench/typed.mjs --errata runs the agent after alignment and reports the account, scores again, and with --judge sends the retracted rows to the judge: facts it calls stated are the ones removed wrongly. That is 0044's measure for this cut, precision gained against correct facts removed, at what cost. Not yet run with a model (the bench in A typed-graph bench on Re-DocRED measures what alignment recovers against the record's thresholds #880 has not been either).

Schema (migration 0074): errata_runs, errata_actions. CURRENT_SCHEMA_VERSION → 73.

Verified against pgvector/pgvector:pg16 on a fresh database:

cargo fmt --all --check                                     ok
cargo clippy --workspace --all-targets -- -D warnings       clean
cargo test -p utopia-store   (UTOPIA_TEST_REQUIRE_DB=1)      340 passed, 0 failed
cargo test -p utopia-server  (UTOPIA_TEST_REQUIRE_DB=1)      400 passed, 0 failed
cargo test --workspace (other crates)                        334 passed, 0 failed
cd web && pnpm build && pnpm test                            tsc clean, 132 passed

New coverage: the four structural flags land on the right facts and flagged ones come first, a reviewed fact is not offered again and a document leaves the due list only when all its facts are reviewed; a retraction survives a second materialisation while the statement and binding stay, and a retraction whose quote is not in the document is refused and touches nothing; a retraction with a derived fact resting on it is held, listed on the queue with its reason, and a person's rejection keeps the row while an approval retracts it (answered once); a revision retracts the old row and writes a new one with the quote as evidence, an addition writes a value, an unknown name and an unknown property are refused, and an addition under a one-value property that already has a value is held as a contradiction; the parser gives every fact one verdict, counts malformed rows without believing them, requires a quote for retract/revise/add and refuses additions until every fact is answered; the server job (scripted model) puts the flagged fact first in the prompt, applies the retraction, records keep, applies an addition with a real quote and refuses one without, books one request with the endpoint's tokens, and asks nothing on a second run; an unreadable reply leaves every fact unreviewed and the job reports failure so it retries; the route answers 403 to a viewer, 404 in another base, lists the held action with its counts, applies it on approve and 404s once answered.

Not in this PR, said in the record: reverting an applied errata action (the ledger has the row; the undo is the same path as a manual retraction); a revision table for keep verdicts; evidence beyond the quote's chunk for quotes that span chunks (they fall back to the document's first chunk).

🤖 Generated with Claude Code

WaylandYang and others added 3 commits September 23, 2026 17:54
… through the gate

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: WaylandYang <145302500+WaylandYang@users.noreply.github.com>
…oved and what it cost

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: WaylandYang <145302500+WaylandYang@users.noreply.github.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: WaylandYang <145302500+WaylandYang@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant