Skip to content

A chunk reads the opening of its document, and a date keeps the contract format - #680

Merged
WaylandYang merged 5 commits into
devfrom
fix/a-chunk-reads-its-document-opening
Sep 13, 2026
Merged

WaylandYang merged 5 commits into
devfrom
fix/a-chunk-reads-its-document-opening

Conversation

@WaylandYang

@WaylandYang WaylandYang commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

Two extraction contract fixes found on a real lease amendment chain. Each chunk now sees the opening of its document, and a date keeps the contract format even though other literals keep their units.

A chunk reads the opening of its document

A chunk was extracted on its own. The Blackbaud HQ lease's fifth amendment puts the new deadlines in a table in its third chunk, which says only "the Existing Dates in Article 13 are extended". Which lease, and from which date, are both in the first chunk.

Without them, the model made the deadline name itself the subject, and the server dropped it as subject_not_declared. Or it wrote a deadline with no start, which the temporal engine cannot use to close the old value.

build_messages_with_opening adds the first chunk, capped at 1,500 characters, to every later chunk as read-only context before the known entities. build_messages is unchanged and delegates with no opening, so its output is identical. Rule 10 now says a value changed by a document takes effect when the change does, by default the document's own effective date. Rule 1a adds that a name ends where a description of the thing's history begins.

After review.

  • The opening is the document's lowest-seq live chunk, fetched on its own (documents::opening_chunk) and compared by id. It used to be the first chunk not yet extracted, so re-extracting chunks 3 and 7 of a changed document gave chunk 7 chunk 3 as its opening, and a retry after a failed chunk did the same.
  • Memory documents get no opening, because each episode is its own chunk.
  • A fact whose quote is in the opening but not in the chunk is dropped as quote_from_opening, along with any declaration only that fact referenced. It would otherwise cite chunk 0's words as evidence from chunk k.
  • Rule 5 now says the quote comes from the Text block, not the opening.
  • Rule 10 no longer lists "restates". A restated prior-year figure does not take effect on the filing date (rule 3c).
  • The change-takes-effect guidance still reaches attribute facts only.

A date keeps the contract format

Rule 8a told the model to keep a literal as written, with its units, and listed a date among the literals. Rule 3 and the attribute rule require YYYY-MM-DD. The model followed 8a, wrote "June 23, 2020", and the attribute datatype check dropped the fact. Across the bench runs that happened more than 20 times, and it was the largest single loss of deadline values. 8a now makes dates the exception and says a deadline stated relative to an event is not a date. Rule 8c qualifiers take the same exception.

Checks

  • cargo test -p utopia-extract --lib: 48 passed, including a_later_chunk_reads_the_opening_of_its_document, a_long_opening_is_cut_on_a_character_boundary, a_literal_keeps_its_units_but_a_date_takes_the_contract_format and a_fact_quoting_the_opening_is_dropped_with_its_orphan.
  • a_document_opening_is_its_first_live_chunk (database): the opening skips a superseded chunk and ignores extracted_at.
  • cargo test -p utopia-server --bins: 267 passed.
  • Clippy with -D warnings and fmt are clean.

Measured

Contract bench (set up as in #679), right answers of 18:

build runs
dev 5
dev + opening context 5, 8
dev + #670 + opening context 8, 8
+ date format + an amendment class in the bench ontology 10, 5

With the opening, deadline facts carry the amendment's effective date as valid_from; on dev they had none. With the date carve-out, all five extended deadlines were extracted in a run for the first time. The total moves less than recall does, because the engine still misordered late values. #679 fixes that. Runs vary by about 3 questions, and this chain has not been run through the NVIDIA recall bench.

🤖 Generated with Claude Code

WaylandYang and others added 3 commits September 13, 2026 23:11
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: WaylandYang <wayland0916@gmail.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: WaylandYang <wayland0916@gmail.com>
…s not evidence

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: WaylandYang <wayland0916@gmail.com>
@WaylandYang
WaylandYang force-pushed the fix/a-chunk-reads-its-document-opening branch from c55dc3c to 316a7ea Compare September 13, 2026 15:17
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: WaylandYang <wayland0916@gmail.com>
@WaylandYang

Copy link
Copy Markdown
Contributor Author

Recall bench (NVIDIA corpus, DeepSeek-V3 through SiliconFlow) before merging. Both rounds ran tonight under the same heavy throttling, 45–47 rate-limit warnings and 4 chunks skipped per round:

build score
dev at f680576 40/52
this PR at 09996ce 39/52

Flat within one standard deviation (about 2.7). An earlier round on c55dc3c scored 38/52, but that one was disturbed by a concurrent run (70 warnings, 7 chunks skipped) and doesn't count. Both scores sit well below this morning's 49/52; that drop is being attributed separately, because it appears on dev as well.

Also reviewed:

  • The opening is now the document's first live chunk, compared by id, and memory documents are skipped.
  • "restates" is gone from rule 10.
  • A quote from the opening is dropped as quote_from_opening.
  • Rule 8c has the same date exception as 8a.
  • Rule 8e: an obligation belongs to the agreement that imposes it (A lease amendment chain still has four gaps after #679 and #680 #681 §3).

🤖 Generated with Claude Code

@WaylandYang
WaylandYang merged commit 785ce6a into dev Sep 13, 2026
4 checks passed
@WaylandYang
WaylandYang deleted the fix/a-chunk-reads-its-document-opening branch September 13, 2026 16:43
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