OpenParser

Extraction and transforms

Read verbatim source text, then record any rewrite as a separate checked step.

Extraction is always verbatim

activity:extract always produces the verbatim text read out of the document. Its output entity's value is that text. You cannot extract something that is not there: if the schema asks for format: date, the page says 20 day of May 2025, and the result is 2025-05-20, the extraction is still 20 day of May 2025. The formatting is a second step.

The extraction can always be checked. OpenParser verifies that the verbatim text really appears in the parsed document, and drops a span it cannot find — models do invent quotes, and an unverifiable one dresses a hallucination up as evidence. Some rewrites can also be checked without another model call when they are unambiguous representation changes. The rest remain model-reported or unscored.

So the graph states the two claims separately. A field at /signed_on that the model rewrote is emitted as:

  • an entity source-text:/signed_on with kind: value, holding the verified verbatim text. It has no path: it is a real intermediate value, but it is not one of your output's fields. Its confidence is kind: derived, method: source_text_alignment, with attributes: { "openparser:alignmentStatus": "match_exact" } — the text was found verbatim, so the read scores like any other exact match.
  • a derivation producing source-text:/signed_on through activity:extract, taking the parsed document, the extraction schema, and the cited resolved_source_evidence inputs. This is the edge that cites the document, so it carries the per-field recognition score described in evidence and confidence.
  • a derivation producing field:/signed_on through activity:transform, whose only input is { "entity": "source-text:/signed_on", "role": "source_text", "effect": "direct" }. It cites nothing, because it read nothing.

A justification is an attribute of the entity its step produced (openparser:justification), so each account sits beside the claim it defends. Reading text off the page and converting it are two claims:

  • reason — why the quoted passage is the source for this value: what in the document identifies it. It does not explain formatting. On a rewritten field this lives on source-text:/signed_on, the verbatim quote the extract step produced.
  • transform_claim.reason — the model's untrusted account of how that quote became the returned value. On a rewritten field this lives on field:/signed_on, which the transform step produced.

A value returned as written has one extract step, so reason is on the field entity itself and transform_claim is omitted. Justifications are never read from activity attributes: one extract activity covers every field, so nothing there could be about a single field.

Each field record in grounding.fields[] may include reason and a bounded transform_claim (operation, parameters, reason, and ordinal confidence). OpenParser copies the model's wording onto openparser:justification on the entity each step produced, and does not synthesize a rationale. Absence of the key means none was recorded.

{
  "source-text:/signed_on": {
    "kind": "value",
    "value": "20 day of May 2025",
    "attributes": {
      "openparser:justification": "The commencement clause states the lease begins on the 20 day of May 2025."
    }
  },
  "field:/signed_on": {
    "kind": "decision",
    "path": "/signed_on",
    "value": "2025-05-20",
    "attributes": {
      "openparser:justification": "The schema asks for an ISO 8601 date, so the written date was reformatted to 2025-05-20."
    }
  }
}

The field entity's confidence records what checked the transform:

  • 1, kind: derived, and a versioned openparser.transform.*.v1 method only when trusted intent selected a validator and it proved its narrow claim
  • 0.25, 0.5, or 0.75, kind: reported, and method: model_ordinal when the model reports low, medium, or high and a permitted deterministic validator did not return contradicted
  • no assertion when a deterministic check contradicted the output, or when neither source measured it

not_applicable (no parse, no trusted source format, or no matching policy) may still keep a reported ordinal. contradicted never does: the transform is unscored, composite output confidence is unknown, and Studio states that the deterministic check contradicted the output.

The ordinal score is deliberately coarse and uncalibrated. It does not pretend that a model's self-assessment is a probability.

activity:transform has type: transform and attributes: { "openparser:implicit": true }, and shares agent:extraction-model with activity:extract. One model call did both the reading and the rewriting; the graph says so outright rather than implying a second request.

A value that does appear verbatim in the source has no transform step: one extract edge from the evidence to the field, no intermediate entity.

Transform verification

Verification is controlled by explicit request/schema intent, never by prose or the model's claim. The complete trust model, extension schema, proof metadata, strict date rules, validator catalog, and legacy method migration are on Transform verification.

Recognition scores, region selectors, and why extraction and transform confidence stay on separate edges are on evidence and confidence.

On this page