50 — Blueprint Extraction Architecture

Snapshot: 2026-05-18 Owner: 47-gtm-plan Track D Ship gate: v11.1, NLT 2026-07-09 (CV-324 due date) Related risks: R26 / R27 / R28 — see 00-vision-and-success-criteria §Top Risks Patent coupling: 01-CV-Patent-Construction-Drawings — CV-337 (Sprint 26) is the patent-evidence checkpoint.

Why this document exists

Track D (Blueprint Extraction R&D) was pulled into the v11.1 ship gate on 2026-05-18. Thirteen child stories (CV-326 – CV-338) now compress into Sprints 21–27, with the schema landing first in Sprint 21 (CV-336) as the R28 mitigation. This doc fixes the architecture so every downstream consumer — Tier 2 VLM bridges, the cv-blueprint-mcp tools, the cv-cad import path (CV-337), and the LandingAI ADE benchmark (CV-338) — writes to and reads from a stable contract. Without that contract pinned, parallel sprint execution is impossible.

High-level pipeline

        ┌──────────────────────────┐
input → │ Born-digital PDF (vector)│ ─┐
        └──────────────────────────┘  │
                                      ▼
                              ┌────────────────────────────┐    ┌────────────────────┐
                              │  cv-blueprint-mcp          │ →  │ .cvextract.json    │
                              │  (Tier 3, sprint 21+)       │    │ (schema v0.1)      │
                              ├────────────────────────────┤    └─────────┬──────────┘
        ┌──────────────────────────┐ ▲     │ vector path                  │
input → │ Scanned PDF (raster)     │ │     │ raster path                  │
        └──────────────────────────┘ │     │ scale calibration            ▼
                                     │     │                    ┌─────────────────┐
                                     │     ▼                    │ cv-cad import   │
                              ┌────────────────────────────┐    │ (CV-337, S26)   │
                              │  Tier 1 MCP infrastructure │    └─────────────────┘
                              │  • pdf-mcp (vector)        │
                              │  • ocr-mcp (raster)        │
                              │  • Tier 2 VLM (raster)     │
                              └────────────────────────────┘

Input split. A PDF is either born-digital (vector text + geometry) or scanned (raster pixels only). The pipeline routes:

  • Vector PDFspdf-mcp extracts text positions and geometry → vector dimension parser (CV-333) → schema.

  • Scanned PDFspdf-mcp page-renders to PNG → ocr-mcp + Tier 2 VLM (Qwen2.5-VL or Qwen3-VL 8B) extract dim strings, leaders, symbols with bboxes (CV-326–331, CV-334) → scale calibration (CV-335) → schema.

Both paths write to the same .cvextract.json schema. Downstream consumers (cv-cad import, benchmark harness, patent-evidence figures) are schema-blind to which path produced the output, except via the provenance.path field.

MCP server boundaries

Server

Status (2026-05-18)

Responsibility

Owner repo

pdf-mcp

Wired Sprint 19

PDF chunked read, BM25 + semantic hybrid search, Tesseract OCR fallback, page-render-as-PNG, SQLite cache

jztan/pdf-mcp (upstream)

ocr-mcp

Wired Sprint 19

SOTA OCR backends (PP-OCRv5, DeepSeek-OCR, Florence-2, DOTS.OCR, Qwen-Image-Layered)

sandraschi/ocr-mcp (upstream)

Tier 2 VLM (Qwen)

Stand up Sprint 21 (CV-326)

Bbox + symbol recognition zero-shot; A/B’d in CV-327; hardware decision closes EOS Sprint 21 (R27)

Local (Ollama) or cloud-GPU fallback

cv-blueprint-mcp

Scaffold Sprint 22 (CV-332)

Domain wrapper: extract_panels, extract_dimensions, extract_openings; vector + raster + scale paths; emits .cvextract.json

mcp-servers/cv-blueprint-mcp/ (this repo)

cv-cad importer

Sprint 26 (CV-337)

Reads .cvextract.json; produces cv-cad TB11 input on reference project. Patent-evidence checkpoint.

src/x64/TB11-01x64/ (this repo)

LandingAI ADE

Sprint 27 (CV-338) baseline

Commercial-baseline comparison; result attached to ADN submission package

External SaaS

Tool surface (cv-blueprint-mcp, v0.1):

extract_panels(pdf_path, page=None) → {panels: [...], provenance: {...}}
extract_dimensions(pdf_path, page=None) → {dimensions: [...], provenance: {...}}
extract_openings(pdf_path, page=None) → {openings: [...], provenance: {...}}
extract_all(pdf_path, page=None) → full .cvextract.json document
calibrate_scale(pdf_path, page=None) → {scale: {value, unit, source}}

Each tool returns the schema fragment it owns plus a provenance block. extract_all composes them.

.cvextract.json schema v0.1

Pinned in Sprint 21 by CV-336. Every Tier 2 / Tier 3 consumer writes to this contract. Schema rev only at sprint boundaries (R28 mitigation).

{
  "$schema": "https://constructivision.com/schemas/cvextract/v0.1.json",
  "version": "0.1.0",
  "source": {
    "pdf_path": "string",
    "page": 0,
    "sheet_id": "string|null",
    "scale": {
      "value": 0.25,
      "unit": "in/ft",
      "source": "title-block|user-override|calibration",
      "confidence": 0.0
    }
  },
  "provenance": {
    "path": "vector|raster",
    "tools": ["pdf-mcp", "ocr-mcp", "qwen2.5-vl-7b", "qwen3-vl-8b", "cv-blueprint-mcp"],
    "model_version": "string|null",
    "extracted_at": "ISO8601",
    "git_sha": "string"
  },
  "panels": [
    {
      "id": "P-001",
      "type": "ledger|top-plate|pilaster|lintel|other",
      "bbox_pdf": [x1, y1, x2, y2],
      "bbox_world": [x1, y1, x2, y2],
      "dimensions": ["D-001", "D-002"],
      "openings": ["O-001"],
      "evidence": {
        "page": 0,
        "bbox": [x1, y1, x2, y2],
        "crop_uri": "string|null",
        "confidence": 0.0
      }
    }
  ],
  "openings": [
    {
      "id": "O-001",
      "type": "door|window|wc|pp|bp|unknown",
      "panel_id": "P-001",
      "bbox_pdf": [x1, y1, x2, y2],
      "bbox_world": [x1, y1, x2, y2],
      "width": null,
      "height": null,
      "evidence": {
        "page": 0,
        "bbox": [x1, y1, x2, y2],
        "crop_uri": "string|null",
        "confidence": 0.0
      }
    }
  ],
  "dimensions": [
    {
      "id": "D-001",
      "kind": "linear|radial|leader|note",
      "text": "12'-6\"",
      "value": 150.0,
      "unit": "in",
      "endpoints_pdf": [[x1, y1], [x2, y2]],
      "endpoints_world": [[x1, y1], [x2, y2]],
      "leader_bbox": [x1, y1, x2, y2],
      "arrow_bboxes": [[x1, y1, x2, y2]],
      "associated_to": "P-001|O-001|null",
      "evidence": {
        "page": 0,
        "bbox": [x1, y1, x2, y2],
        "crop_uri": "string|null",
        "confidence": 0.0
      }
    }
  ]
}

Notes on the schema:

  • evidence.bbox is required on every panel / opening / dimension. This is the R26 (hallucination) mitigation — downstream tools can re-OCR or visually verify the crop region for any claim the VLM makes.

  • bbox_pdf is in PDF user-space coordinates; bbox_world is in real-world units (inches) once scale calibration runs. Both are preserved so calibration errors are debuggable.

  • value is normalized to inches (cv-cad’s internal unit). text preserves the source string for audit.

  • confidence is on [0, 1]. Schema does not prescribe how each tool computes it; consumers may filter on threshold.

  • crop_uri is optional. When present (Sprint 24+ via CV-330), it points to a PNG crop the VLM saw — patent-evidence figures and benchmark reports use these directly.

  • associated_to links a dim to the panel or opening it measures. When ambiguous, the field is null and downstream tools handle disambiguation.

Downstream consumer surface. The cv-cad import path (CV-337) writes schema values into cv-cad’s panel/project/site dialog globals. The full key/global/schema-field join is documented in 51-cv-cad-data-entry-map, including a “Schema v0.2 candidates” appendix aggregating dialog fields not yet modeled in v0.1 (project metadata, site geometry, per-panel feature arrays like pilasters/dock-levelers/ledgers/weld-connections). Schema v0.1 stays pinned for Sprints 21–27; v0.2 is a Sprint 22+ design pass driven by that gap analysis.

Sequencing — why schema lands first

Sprint

Story

What lands

Why this order

21

CV-336

.cvextract.json schema v0.1 pinned

Every downstream consumer writes to this — schema is the contract. R28 mitigation.

21

CV-326

Qwen2.5-VL stood up locally

Hardware decision (R27) closes EOS Sprint 21.

22

CV-332

cv-blueprint-mcp scaffold + 3 tools

Schema exists; scaffold writes empty-but-valid docs.

22

CV-327, CV-328

A/B Qwen2.5 vs Qwen3; bbox-quality measure

Hardware proven; schema gives the bboxes a home.

23

CV-333, CV-329

Vector path lands; symbol recognition baseline

Vector path is high-precision baseline; symbols feed openings.

24

CV-330, CV-331

End-to-end pipeline; Tier 2→Tier 3 decision

First full vertical slice; informs Sprint 25 raster work.

25

CV-334, CV-335

Raster fallback; scale calibration

Schema’s scale block populated.

26

CV-337

cv-cad round-trip on reference project (patent evidence)

Schema, pipelines, scale all exist; round-trip proves the claim.

27

CV-338

Benchmark vs LandingAI ADE

All paths working; benchmark goes in ADN submission package.

Critical sequencing rule: schema v0.1 (Sprint 21) MUST land before scaffold (Sprint 22). If schema slips a sprint, scaffold slips a sprint, A/B slips a sprint, and the patent-evidence checkpoint moves past the submission deadline. This is the load-bearing dependency.

Risks (cross-reference)

See 00-vision-and-success-criteria §Top Risks for ship-gate framing. Track-D-specific:

  • R26 — VLM hallucination on dimensions. Mitigated by mandatory evidence.bbox; CV-328 measures bbox quality in Sprint 22.

  • R27 — Hardware for local VLM. Hardware decision must close EOS Sprint 21; cloud-GPU + commercial-API escape hatch documented.

  • R28 — .cvextract.json schema churn. Mitigated by shipping schema first (CV-336 Sprint 21), pinning version, rev only at sprint boundaries.

Beyond these, the patent-evidence dependency (CV-337) carries calendar risk: it lands Sprint 26 (ends 2026-07-01), giving exactly one week of slack before the NLT 2026-07-09 ADN deadline. If CV-337 slips, the submission package ships without the round-trip evidence and the patent claim files without a worked example.

Cross-references