feat: refocus on drawings — code/ADA gated off, drawing-integrity wave, Brain-directed clarification
- ENABLE_CODE_REVIEW flag (default off): skips code/ADA/jurisdiction review path in both pipelines; nothing deleted, one env flag to restore. - Per-sheet Drawing Integrity QA wave (agent + classic, default on): dangling refs, on-sheet contradictions, dimension sanity, missing sheet essentials, tag hygiene. New DrawingIntegrityAgent + classic stage. - Broadened conflict critic: intra-sheet + same-discipline contradictions, not just cross-discipline. - Wave 6.5 Brain-directed clarification (bounded hub-and-spoke): Brain names uncertain findings, verify_evidence requests route through the wave-5b verifier; refuted findings suppressed. One planning call + capped verifies, single iteration. Shared _build_verify_scopes across 5b and 6.5. - Config knobs, .env.example, frontend copy, tests (182 passing).
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
"""Tests for the classic-path drawing_integrity_review stage + gating."""
|
||||
|
||||
import backend.pipeline.drawing_integrity as di
|
||||
from backend import config
|
||||
from backend.pipeline.drawing_integrity import drawing_integrity_review
|
||||
|
||||
|
||||
def _sheet(page, sheet_number, n):
|
||||
return {
|
||||
"sheet_number": sheet_number,
|
||||
"page_number": page,
|
||||
"discipline": "Architectural",
|
||||
"assertions": [{"source_text": f"n{i}"} for i in range(n)],
|
||||
}
|
||||
|
||||
|
||||
def _pages(pages):
|
||||
return [{"page_number": p, "base64": f"IMG{p}", "text_layer": f"txt{p}"}
|
||||
for p in pages]
|
||||
|
||||
|
||||
def test_disabled_returns_empty(monkeypatch):
|
||||
monkeypatch.setattr(config, "ENABLE_DRAWING_INTEGRITY", False)
|
||||
called = []
|
||||
monkeypatch.setattr(di, "call_stage", lambda *a, **k: called.append(1) or {})
|
||||
out = drawing_integrity_review([_sheet(1, "A101", 5)], _pages([1]))
|
||||
assert out == []
|
||||
assert called == [] # no LLM calls when disabled
|
||||
|
||||
|
||||
def test_reviews_only_dense_sheets(monkeypatch):
|
||||
monkeypatch.setattr(config, "ENABLE_DRAWING_INTEGRITY", True)
|
||||
monkeypatch.setattr(config, "INTEGRITY_MIN_ASSERTIONS", 3)
|
||||
seen_sheets = []
|
||||
|
||||
def fake_call_stage(system, user, subs=None, images_b64=None, **k):
|
||||
# Record which sheet_meta reached the model.
|
||||
seen_sheets.append(subs["sheet_meta"])
|
||||
return {"issues": [
|
||||
{"severity": "medium", "confidence": "high",
|
||||
"category": "on_sheet_contradiction", "sheets": [],
|
||||
"description": "plan disagrees with same-sheet schedule"},
|
||||
]}
|
||||
|
||||
monkeypatch.setattr(di, "call_stage", fake_call_stage)
|
||||
sheets = [_sheet(1, "A101", 5), _sheet(2, "A102", 1), _sheet(3, "A103", 4)]
|
||||
out = drawing_integrity_review(sheets, _pages([1, 2, 3]))
|
||||
# Two dense sheets reviewed, one skipped; each produced one anchored finding.
|
||||
assert len(out) == 2
|
||||
assert all(f["source_stage"] == "drawing_integrity" for f in out)
|
||||
assert {tuple(f["sheets"]) for f in out} == {("A101",), ("A103",)}
|
||||
assert len(seen_sheets) == 2
|
||||
Reference in New Issue
Block a user