Estimating and bid leveling built on 23 real jobs, with AI kept out of the totals
Estimates start from the client's own closed jobs instead of a blank template, and every number in a bid total has a person's sign-off behind it.
- 426cost codes
- 23real jobs loaded
- 40API checks
- 5closed jobs minimum
The client's real codes, extracted so precon and operations share one structure.
493 cost lines and 13 estimate revisions, with zero lines left unclassified.
End-to-end verification of the lead-to-change-order flow before driving it through the screens.
Before the accuracy view will recommend a correction factor for any category.
The problem
The client's construction team had years of estimates, bid tabs, and job costs spread across shared drive folders and spreadsheets. Every new estimate started from a template and someone's memory of what similar jobs cost. Leadership had just sat through a demo of a preconstruction software platform and asked whether we could build it instead.
Our recommendation was simpler than the demo: get the historicals into one place first, then layer AI on top.
The head of preconstruction had one objection to AI, and it shaped the whole build. Every sub submits differently. Some quote a lump sum "per the drawings" and list nothing else. A tool that reads that as "everything included" puts a wrong number in the bid.
What we built
A web app with two views over one database: precon and construction.
The precon side covers a project pipeline in the team's own stage names, conceptual estimates built from comparable past jobs, cash flow spread across each bid package's timing, bid packages and bid lists, bid leveling, and award. The construction side covers subcontracts opened automatically from awards, job cost by cost code, change orders, and insurance and bond compliance.
Under the screens sit tested engines for cost code normalization, time and location adjustment, conceptual estimating with back-checks that fail loudly, cash flow, and leveling. Three rules carry the weight:
- Silence is not consent. When a proposal says nothing about a scope item, leveling marks it "unclear," never included and never excluded. A machine suggestion never enters a total. Only a verdict a person has accepted counts, and the screen shows the machine's call beside the person's so the audit trail survives.
- A plug and an adjustment are different money. A number a sub gave you and a number you filled in because they did not call back add the same way but carry very different risk, so they are tracked and reported separately.
- Consent for automated calls is a recorded fact. Leadership wanted AI agents making sub follow-up calls. Under a 2024 FCC ruling, an AI-generated voice counts as an artificial voice, which requires prior express consent. Each bidder carries a consent flag, date, and source, and both the API and the database refuse an automated call without it.
How it works
The real data rewrote the assumptions. The client does not estimate on the current industry cost code structure. It uses the older 16-division structure, the same codes its accounting system carries. The team wanted a clean handoff from precon to operations on one set of codes, so we extracted all 426 of the client's real codes, rebuilt the code engine around them, and keyed bid packages by trade instead of by division, so plumbing, HVAC, and fire sprinkler go out as separate packages.
Then the job book arrived: 23 real job folders, 493 cost lines, and 13 estimate revisions. The importer flags what it does not understand instead of guessing, and that paid off. Codes written with a trailing decimal had sent 87 percent of real cost lines into an unknown division until the parser was fixed. A date cell held the day the template was saved, not the day the job was estimated, which would have back-dated current work. The markup on each estimate compounds rather than adding flat, so a naive total lands low. Gaps in the client's own data, like a job number used twice, were flagged for a person and never silently fixed.
The head of preconstruction asked for one screen in particular: what we estimated against what it actually cost, with a correction factor per category. It is guarded. It uses the median so one bad job cannot set policy, it refuses to recommend anything with fewer than five closed jobs, and it says so in plain words when the sample spreads too wide. Its figures fill in as final costs from closed jobs are loaded.
The result
A new job can now go from lead to change orders inside the app. The buyout checklist builds one package per trade line from the estimate, with budgets attached. Each package gets a bid desk for invitations, bids, and revisions, and award opens a subcontract on the right cost code at the leveled amount. We verified the flow with 40 API checks, then drove the same job through the screens. That walkthrough found seven bugs, the worst being an import rule that filed the painting division as markup on every job. All seven were fixed.
The 23 real jobs loaded with zero cost lines left unclassified. We deliberately did not build takeoff or accounting, because the team already has tools for both, or a bid marketplace, because the team did not want another one.
Read the full build notes: Preconstruction software built on the firm's own job history.
Your turn
Same problem? Different industry?
We work with one client per vertical at a time. If your shape matches one of our dossiers, we’ll tell you straight.