Inspiration
We started this hackathon the way most teams probably did: staring at the four tracks, promising ourselves we wouldn't build another chatbot. The brief itself dared everyone to go deeper than an API call, so we went looking for a problem where a chat window is actually the wrong shape.
We found it while reading up on how general contractors award work. Three subcontractors bid the same electrical scope. One bid says $455,000, lowest number on the table, and buried in its exclusions are three words: "lighting fixtures by others." Those three words mean the GC buys roughly $70,000 of fixtures separately. So the "cheapest" bid is actually the most expensive one, and nobody finds out until after the contract is signed.
The same failure repeats on the submittal side. An architect checks a product cut sheet against the spec under deadline pressure. Three of four attributes match, so it gets approved and the one that didn't match (a Grade 2 lockset where the spec demands Grade 1) shows up on site as a failed inspection and rework.
Both are the same disease: expensive mistakes hiding in documents that humans review manually, inconsistently, and late. And neither is a conversation problem. Nobody wants to chat with their bids. They want them checked.
What it does
Verdict is a verification engine for construction procurement, with two modules on one pipeline.
BidLevel maps every subcontractor bid onto a canonical scope checklist, detects what each bid quietly excludes, prices those gaps from what the other bidders charged, and re-ranks on true cost. In our worked example the naive ranking $B < A < C$ flips to $A < C < B$ once B's excluded fixtures are priced back in. That flip is the demo.
SpecGuard extracts required attributes from the spec and actual attributes from the submitted cut sheet, then checks conformance attribute by attribute. Three PASSes don't rescue one FAIL: Grade 2 against a Grade 1 requirement returns "Revise & resubmit," with the failing requirement quoted.
Every flag traces back to a rule plus a quoted source passage, and every decision carries a confidence score, the ambiguous ones get routed to a human instead of guessed.
How we're building it
We're stats-and-software people, not ML people, so we designed this around an old engineering rule: if you can write the rule, write the rule. The AI appears in exactly one place, reading messy PDFs, and everything after that is deterministic logic we can test.
The pipeline has six stages. A vision-language model reads each document and returns structured JSON (we force the format: "return ONLY valid JSON, use null if a field is absent, do not guess"). Sentence embeddings then match differently-worded line items, "electrical rough-in" and "power rough-in" land close together in vector space, and closeness is just
$$\cos(\theta) = \frac{a \cdot b}{\lVert a \rVert \, \lVert b \rVert}$$
which made us feel at home, because it's the same arithmetic as the Pearson correlation coefficient we already knew from statistics.
From there it's rules and robust statistics, which is where we've spent most of our design effort because it's the part a wrapper can't fake. A scope item with no match above threshold (plus exclusion cues like "by others" or "NIC") becomes a candidate gap, priced from the peer median $\hat{p}_s = \mathrm{median}{p_s^{(j)}}$. Conformance checks are typed comparators: $=$, $\geq$, $\leq$, set membership, with a synonym map so "BHMA 626" and "satin chrome" count as the same finish. Unit-price outliers get flagged with quartiles rather than z-scores, flag if $x > Q_3 + 1.5\,\mathrm{IQR}$ , because with $n = 3$–$5$ bids, the mean and standard deviation are too fragile to trust.
For evaluation we're generating synthetic bid sets (which gives us ground truth by construction, and we'll disclose it) plus real public manufacturer cut sheets to prove the extraction survives ugly layouts. We'll report precision and recall per stage, and we're optimizing recall first for SpecGuard,
$$R = \frac{TP}{TP + FN},$$
because a false alarm costs a reviewer a minute while a miss costs rework and schedule.
Challenges we ran into
The honest one first: when we started, "embedding" was jargon to us. The wall of ML vocabulary was real, and what got us through was noticing how much of it is statistics wearing a costume, training is fitting, cosine similarity is correlation's geometric twin, precision/recall are Type I and II errors rearranged. Once we saw that, the field stopped being intimidating.
Second: resisting our own feature creep. Every AI tutorial pushed us toward RAG, vector databases, and agent frameworks. We kept asking "what does this add for a targeted check on a known spec section?" and the answer kept being "moving parts." Cutting them felt scary and then immediately right.
Third: data. Real bids are confidential, so we couldn't just scrape a dataset. Flipping that constraint into synthetic data, where we control every inclusion and exclusion, so the ground truth is exact, turned our biggest blocker into our evaluation plan.
And underneath everything: learning to distrust the model productively. Language models hallucinate, they'd rather sound right than admit ignorance, so we designed the whole system around never letting one make the final call.
What we learned
That a model is just a very large fitted function, and we'd all technically done machine learning the first time we fit a regression line. That the best AI system design is mostly knowing where not to use AI. That choosing recall over precision isn't a math decision, it's a product decision about which mistake is expensive. And more about door hardware grades and CSI spec numbering than we ever expected to know.
What's next
Stage 2 is one slice built deep rather than a platform built shallow: SpecGuard for door-hardware submittals, end to end, in Streamlit, reproducing the price flip and the failing-attribute catch on real cut sheets, with measured precision and recall on a hand-labeled set. After that: flow-down clause verification, and conformal prediction to turn our confidence scores into calibrated guarantees.
Construction procurement doesn't need another chatbot. It needs a checker.