Prove one thing:
A deployment can be requested, underwritten, priced, and executed without human coordination.
The product must feel like:
type Deployment = { id: string accountName: string status: "draft" | "underwritten" | "approved" | "executing" | "completed" locations: Location[] price: number margin: number }
type Location = { id: string address: string complexity: "low" | "medium" | "high" units: number score?: Score }
type Score = { ev: number margin: number payback: number risks: string[] }
type ExecutionUnit = { id: string type: "unit" // never "human" skills: string[] status: "available" | "assigned" | "busy" location: string reliability: number }
type Task = { id: string label: string status: "pending" | "assigned" | "in_progress" | "completed" assignedUnitId?: string }
/deployments/new
Convert intent into a structured deployment request.
accountName — stringdeploymentType — stringtotalUnits — numberBuilds a list of <LocationCard> components, each with address, units, and complexity.
Triggers: runUnderwriting(deploymentId)
/deployments/[id]/underwrite
| Left | Center | Right |
|---|---|---|
| Locations | Scores | Pricing Panel |
evScore — numbermargin — numberpayback — number (months)risks — string[]baseCost — numbersuggestedPrice — numbermargin — number// Margin calculation margin = (price - cost) / price if (margin < 0.25) → warning if (payback > 18) → warning
onChange(price => recalcMetrics(price))
<Button>Approve & Generate Execution Plan</Button>
/deployments/[id]/execute
Show system replacing human coordination.
| Left | Center | Right |
|---|---|---|
| Task Tree | Execution Graph | Unit Allocation |
Install Unit A → Site Prep → Install → Test
Location A Task 1 → Assigned → Complete Task 2 → Pending
unitId — stringstatus — stringeta — stringfunction assignUnits(tasks, units) { return tasks.map(task => ({ ...task, assignedUnitId: findBestUnit(task, units) })) }
<Button>Simulate Execution</Button>
<Button>Execute Deployment</Button>
/deployments/[id]/simulate
Make system feel alive.
Day 1 → Site Prep Day 3 → Install Day 5 → Complete
labor — numberlogistics — numbermargin — number⚠ Skill scarcity
⚠ Delay probability
function simulateExecution(tasks) { tasks.forEach((task, i) => { setTimeout(() => updateStatus(task.id, "assigned"), i * 1000) setTimeout(() => updateStatus(task.id, "in_progress"), i * 2000) setTimeout(() => updateStatus(task.id, "completed"), i * 3000) }) }
/control
Show system-level power.
activeDeployments — numberavgMargin — numberactiveUnits — numberprogress — numbermargin — numberstatus — stringUnits Active: 42 Deployments Running: 8 Issues: 2
const executionUnits: ExecutionUnit[] = [ { id: "U1", type: "unit", skills: ["install"], status: "available", location: "MTL", reliability: 0.92 } ]
function findBestUnit(task, units) { return units.find(u => u.skills.includes(task.label) && u.status === "available" ) }
function calculatePrice(cost, risk, sla) { return cost * 1.3 + risk * 1000 + sla * 500 }
User must feel:
This MVP communicates:
Deployment is no longer a company function.
It is infrastructure.