feat: deterministic sheet-list reconciliation (cover index vs identified sheets)
Docker Release / build-and-push (push) Successful in 1m19s
Docker Release / release (push) Skipped

This commit is contained in:
2026-08-18 13:49:34 -05:00
parent fe09e4a66b
commit bae608a505
4 changed files with 211 additions and 0 deletions
+17
View File
@@ -31,6 +31,7 @@ from backend.pipeline.report import build_report, to_markdown
from backend.pipeline.sheet_index import derive_project_meta_from_cover
from backend.review.gate import build_review_queue
from backend.review.store import ReviewStore
from backend.sheet_reconcile import declared_sheet_list, reconcile_sheets
from backend.text_layer import (
attach_text_layers, coverage_gaps, find_evidence_bbox, render_crop,
)
@@ -84,6 +85,20 @@ def run_agent_pipeline(
sheets.sort(key=lambda sheet: sheet.get("page_number") or 0)
memory.replace("sheets", sheets)
memory.dump("01-extract.json")
# Deterministic reconciliation: the cover sheet's own sheet index
# declares what the set should contain; compare against what wave 1
# identified (catches missed sheets AND phantom/misread sheet numbers).
sheet_recon = reconcile_sheets(sheets, declared_sheet_list(page_to_text))
if sheet_recon["declared_total"]:
print(f"[SheetIndex] cover declares {sheet_recon['declared_total']} "
f"sheets; {sheet_recon['found_total']} identified in set")
if sheet_recon["declared_not_in_set"]:
print(f"[SheetIndex] declared but not in set: "
f"{', '.join(sheet_recon['declared_not_in_set'][:20])}")
if sheet_recon["in_set_not_declared"]:
print(f"[SheetIndex] in set but not declared: "
f"{', '.join(sheet_recon['in_set_not_declared'][:20])}")
# Coverage signal: text layer present but extraction failed/empty reuses
# the failed-scopes gap-finding path (finding built below wave 6).
for gap_page in coverage_gaps(pages, sheets):
@@ -289,6 +304,7 @@ def run_agent_pipeline(
"project_input": merged_input,
"jurisdiction": jurisdiction,
"sheet_index": sheet_index,
"sheet_reconciliation": sheet_recon,
"project_intelligence": object_graph,
"validated_issues": prioritized,
"rfis": [],
@@ -365,6 +381,7 @@ def run_agent_pipeline(
"project_input": merged_input,
"jurisdiction": jurisdiction,
"sheet_index": sheet_index,
"sheet_reconciliation": sheet_recon,
"project_intelligence": object_graph,
"validated_issues": prioritized,
"rfis": rfis,