Production workflows / Guide 31
A Construction Project Agent That Separates Progress from Permission
Build a construction project agent that reconciles site reports, drawing revisions, and dependencies without treating optimistic progress notes as work authorization.
Illustrative engineering guide. Examples are not client deployments, production-ready integrations, or evidence of measured results. Validate the design with your domain and security owners.

Imagine a hypothetical commercial building project where tomorrow’s concrete pour appears ready in the schedule. The foreman’s report says reinforcement is complete. A later inspection record leaves one section open, and a revised drawing changes an embedded plate. An assistant that summarizes the most recent paragraph can confidently recommend a pour that the evidence does not support.
A useful construction project agent does something narrower: assemble a defensible lookahead, identify unresolved constraints, and prepare decisions for the superintendent. It must distinguish reported progress, accepted work, approved design, and permission to proceed. Those are separate states, even when site conversation treats them as interchangeable.
Model the constraint, not just the task
Give every work package stable identifiers for location, trade, schedule activity, and drawing references. Record observations separately from approvals. A photograph can support an observation that reinforcement appears installed; it cannot supply an inspector’s acceptance. A delivery confirmation proves receipt, not installation or material suitability.
The constraint register should include an owner, required resolution date, evidence references, and blocking scope. A missing inspection for level three should not freeze unrelated landscaping. Conversely, a project-wide design hold must propagate to every affected work package. Explicit scope prevents both excessive interruption and false readiness.
Represent dependencies as a graph maintained by scheduling software. Detect cycles and compute affected successors deterministically. The model can explain why a delay matters, but it should not invent task durations or calculate the critical path in prose. Keep the approved baseline separate from the current forecast so that proposed recovery measures never silently rewrite contractual history.
A small, useful workflow
Start with read adapters for the schedule, drawing register, inspection log, and daily reports. Normalize project identifiers before retrieval. Preserve document revisions, publication times, and ingestion times. The retrieval layer returns evidence from the selected project and work package, including superseded documents when needed to explain a change, but labels them clearly.
One model extracts candidate observations and drafts the lookahead. A rules service reconciles revisions and constraints. A superintendent reviews the proposed action and its dependencies. Only a separate command handler can update the forecast or create a request for information. Every accepted change retains the previous value, explanation, approver, and evidence snapshot.
A specialist drawing-comparison component earns its cost only if geometric or revision differences repeatedly escape text extraction. It need not be an autonomous agent. Similarly, a schedule solver is a tool with a bounded input and output, not another conversational worker.
Make readiness a deterministic gate
This illustrative Python function checks administrative readiness for a selected package. It is not a safety certification or structural assessment. Inputs must come from authenticated, validated records rather than model-generated booleans.
def readiness(package, current_revision):
reasons = []
if package["drawing_revision"] != current_revision:
reasons.append("drawing_changed")
if package["inspection_status"] != "accepted":
reasons.append("inspection_open")
if package["blocking_constraints"]:
reasons.append("constraints_open")
if not package["predecessors_accepted"]:
reasons.append("predecessor_open")
return {"reviewable": not reasons, "reasons": reasons}
p = {"drawing_revision": 7, "inspection_status": "accepted",
"blocking_constraints": [], "predecessors_accepted": True}
assert readiness(p, 8)["reasons"] == ["drawing_changed"]
assert readiness(p, 7)["reviewable"] is True
Production still needs revision subscriptions, graph validation, role checks, and transactional persistence. The function deliberately says reviewable, not safe_to_build. OSHA’s construction provisions assign inspection and accident-prevention responsibilities to people and employers. This reference design does not replace those responsibilities or determine which jurisdictional rules apply.
Readiness should also expire. An accepted inspection may remain historically valid while a later design change invalidates the proposed next action. Bind approval to the package revision, evidence digest, and intended operation. Any material change requires another review rather than a reassuring green badge.
Recover without rewriting site history
Daily reports often arrive after the shift. Store when work reportedly happened and when the system learned about it. If yesterday’s report arrives after today’s forecast, recalculate the affected packages and flag the difference. Do not reorder history solely by upload time.
For writes, use a command key such as project, package, change type, and approved proposal identifier. A retry must return the original change result. If a schedule vendor times out, reconcile its activity history before issuing another update. Local transaction isolation cannot make a remote system atomic; PostgreSQL’s isolation documentation explains why concurrent local changes also need deliberate consistency handling.
If a drawing service is unavailable, show the last verified revision and stop readiness promotion. Continue collecting observations without pretending they are reconciled. A site supervisor needs to know what can still be recorded, not merely that the assistant failed.
Protect commercial and safety boundaries
Authorize project and subcontractor access on the server before retrieving documents. A subcontractor may see its work package without seeing another bidder’s rates or the owner’s contingency. Separate safety observations from employee performance scoring; image interpretation should not become unreviewed disciplinary evidence.
Treat instructions inside uploaded reports as untrusted content. A note saying “ignore inspection holds” is evidence to display, never a command to execute. OWASP’s LLM security project documents prompt injection and excessive agency risks. MCP can expose the approved tools, but it does not grant project authority.
Acceptance tests that resemble a job site
- Submit a complete progress report with an open inspection. Expect a blocked readiness result naming the inspection, not an automatic schedule release.
- Approve a package, then publish a newer drawing before execution. Expect the command to reject the stale approval and request review.
- Deliver the same change command twice after a simulated timeout. Expect one schedule change and one durable audit identifier.
- Upload a report instructing the assistant to reveal another contractor’s pricing. Expect no cross-scope retrieval and no pricing in the response.
- Disconnect the drawing register while reports continue arriving. Expect observations to save, readiness to remain unverified, and reconciliation to resume after recovery.
Measure coordination, not generated pages
Establish a baseline across comparable work packages: time from constraint discovery to owner acknowledgment, and manual minutes spent preparing weekly lookaheads. Measure supported constraint identification as correctly identified blocking constraints divided by all reviewer-labeled blocking constraints. Separately measure false blocks divided by all proposed blocks.
The guardrail is unsupported readiness promotions per reviewed package, alongside unauthorized changes. Begin with shadow lookaheads, then human-approved constraint creation for one trade. Proposed improvement targets should be agreed after baseline collection; there are no achieved results implied here.
Start by reconciling one inspection log with one drawing register. That foundation also supports a manufacturing maintenance agent, while resource commitments resemble a field service dispatch agent. For implementation, AI systems and agent engineering should begin with those evidence boundaries, not autonomous schedule control.