The Work Protocol is how 4 Seasons describes, orders, proves and settles a job in a form both people and software can read. Its core is the Work Spec, a versioned JSON document with a published schema. The same document is what a crew's app works from on site and what a developer's software sends and receives.
This Work Spec was compiled by the production spec compiler from a sample request, a photo of a leaking gas water heater in a garage and a short description that also asks for a leak sensor. Choose a field to see what it says and where it sits in the document.
ws_example0000000001 · 4s.work/v2 · revision 1 · spec-compiler/2026-10-08.1
What it says
Where it is in the document
JSON
[
{
"ref": "s1",
"kind": "task",
"task": "water-heater-replace",
"title": "Replace a tank water heater",
"category": "plumbing",
"trade": "plumbing"
},
{
"ref": "s2",
"kind": "task",
"task": "leak-sensor",
"title": "Place a leak sensor",
"category": "plumbing",
"trade": "plumbing"
}
]{
"spec": "4s.work/v2",
"id": "ws_example0000000001",
"revision": 1,
"title": "Replace a tank water heater and 1 more",
"intent": "The water heater in the garage is leaking at the base. Put a leak sensor in the new pan too.",
"site": {
"homeId": null,
"address": {
"line1": "100 Example St NE",
"city": "Atlanta",
"region": "GA",
"postal": "30307",
"country": "US"
},
"access": null
},
"evidence": [
{
"kind": "photo",
"id": "photo-1",
"capturedAt": null
},
{
"kind": "transcript",
"id": "words-1",
"capturedAt": null
}
],
"scope": [
{
"ref": "s1",
"task": "water-heater-replace",
"title": "Replace a tank water heater",
"qty": 1,
"unit": "each",
"location": null,
"params": {},
"trade": "plumbing",
"category": "plumbing",
"license": "plumbing_license",
"requires": {
"capabilities": [
"plumbing.water-heater-replace"
],
"credentials": [
"license:plumbing_license"
]
},
"acceptance": [
{
"id": "old-heater",
"check": "The old heater in place and its rating label",
"proof": "photo",
"required": true,
"shot": "old-heater",
"measurement": null
},
{
"id": "new-heater",
"check": "The new heater, its pan, relief pipe and connections",
"proof": "photo",
"required": true,
"shot": "new-heater",
"measurement": null
},
{
"id": "new-label",
"check": "The new rating label, serial readable",
"proof": "photo",
"required": true,
"shot": "new-label",
"measurement": null
},
{
"id": "relief-piped",
"check": "Relief valve piped to a safe place",
"proof": "photo",
"required": true,
"shot": "new-label",
"measurement": null
},
{
"id": "no-leaks",
"check": "No leaks at the connections after 10 minutes",
"proof": "photo",
"required": true,
"shot": "new-label",
"measurement": null
},
{
"id": "hot-far",
"check": "Hot water at the farthest faucet",
"proof": "photo",
"required": true,
"shot": "new-label",
"measurement": null
},
{
"id": "venting",
"check": "Gas venting, clearances and the seismic or expansion items per local code",
"proof": "photo",
"required": true,
"shot": "new-label",
"measurement": null
}
],
"steps": [
{
"n": 1,
"text": "Photograph before starting: The old heater in place and its rating label",
"proof": "old-heater",
"node": "s1"
},
{
"n": 2,
"text": "Replace a tank water heater",
"proof": null,
"node": "s1"
},
{
"n": 3,
"text": "Check: Relief valve piped to a safe place",
"proof": "relief-piped",
"node": "s1"
},
{
"n": 4,
"text": "Check: No leaks at the connections after 10 minutes",
"proof": "no-leaks",
"node": "s1"
},
{
"n": 5,
"text": "Check: Hot water at the farthest faucet",
"proof": "hot-far",
"node": "s1"
},
{
"n": 6,
"text": "Check: Gas venting, clearances and the seismic or expansion items per local code",
"proof": "venting",
"node": "s1"
},
{
"n": 7,
"text": "Photograph: The new heater, its pan, relief pipe and connections",
"proof": "new-heater",
"node": "s1"
},
{
"n": 8,
"text": "Photograph: The new rating label, serial readable",
"proof": "new-label",
"node": "s1"
}
],
"kind": "task",
"qtyRange": {
"low": 1,
"expected": 1,
"high": 1
},
"room": null,
"assumptions": [],
"confidence": 0.855
},
{
"ref": "s2",
"task": "leak-sensor",
"title": "Place a leak sensor",
"qty": 1,
"unit": "each",
"location": null,
"params": {},
"trade": "plumbing",
"category": "plumbing",
"license": null,
"requires": {
"capabilities": [
"plumbing.leak-sensor"
],
"credentials": [
"license:none"
]
},
"acceptance": [
{
"id": "sensor-placed",
"check": "The sensor flat on the floor and the fixture it watches",
"proof": "photo",
"required": true,
"shot": "sensor-placed",
"measurement": null
},
{
"id": "sensor-app",
"check": "The app showing the sensor online with its room",
"proof": "photo",
"required": true,
"shot": "sensor-app",
"measurement": null
},
{
"id": "alarms-wet",
"check": "Sensor alarms when its contacts are wet",
"proof": "photo",
"required": true,
"shot": "sensor-app",
"measurement": null
},
{
"id": "online-named",
"check": "Shows online with its room name",
"proof": "photo",
"required": true,
"shot": "sensor-app",
"measurement": null
}
],
"steps": [
{
"n": 1,
"text": "Place a leak sensor",
"proof": null,
"node": "s2"
},
{
"n": 2,
"text": "Check: Sensor alarms when its contacts are wet",
"proof": "alarms-wet",
"node": "s2"
},
{
"n": 3,
"text": "Check: Shows online with its room name",
"proof": "online-named",
"node": "s2"
},
{
"n": 4,
"text": "Photograph: The sensor flat on the floor and the fixture it watches",
"proof": "sensor-placed",
"node": "s2"
},
{
"n": 5,
"text": "Photograph: The app showing the sensor online with its room",
"proof": "sensor-app",
"node": "s2"
}
],
"kind": "task",
"qtyRange": {
"low": 1,
"expected": 1,
"high": 1
},
"room": null,
"assumptions": [],
"confidence": 1
}
],
"constraints": {
"needBy": null,
"windows": [],
"occupied": null,
"pets": true
},
"price": {
"currency": "USD",
"kind": "fixed",
"amountCents": 227400,
"lines": [
{
"ref": "s1",
"label": "Replace a tank water heater",
"amountCents": 219500
},
{
"ref": "s2",
"label": "Place a leak sensor",
"amountCents": 7900
}
],
"validUntil": "2026-10-14T15:00:00.000Z",
"confidence": 0.855,
"visitFirst": false,
"rateRelease": null
},
"credential": {
"level": "licensed",
"label": "Licensed technician (plumbing license)",
"licenses": [
"plumbing_license"
]
},
"arrival": null,
"materials": [
{
"sku": "SVC-WATER-HEATER-REPLACE-TANK-WATER-HEATER-40-OR-50-GALLO",
"name": "Tank water heater, 40 or 50 gallon",
"qty": 1,
"unit": "ea",
"ref": "s1",
"node": "s1",
"qtyRange": {
"low": 1,
"expected": 1,
"high": 1
}
},
{
"sku": "SVC-WATER-HEATER-REPLACE-WATER-HEATER-DRAIN-PAN",
"name": "Water heater drain pan",
"qty": 1,
"unit": "ea",
"ref": "s1",
"node": "s1",
"qtyRange": {
"low": 1,
"expected": 1,
"high": 1
}
},
{
"sku": "SVC-WATER-HEATER-REPLACE-FLEXIBLE-WATER-HEATER-CONNECTORS",
"name": "Flexible water heater connectors",
"qty": 2,
"unit": "ea",
"ref": "s1",
"node": "s1",
"qtyRange": {
"low": 2,
"expected": 2,
"high": 2
}
},
{
"sku": "SVC-LEAK-SENSOR-WI-FI-LEAK-SENSOR",
"name": "Wi-Fi leak sensor",
"qty": 1,
"unit": "ea",
"ref": "s2",
"node": "s2",
"qtyRange": {
"low": 1,
"expected": 1,
"high": 1
}
}
],
"guarantee": {
"kind": "workmanship",
"days": 365,
"months": 12,
"remedy": "redo_or_refund",
"startsOn": "accepted"
},
"settlement": {
"mode": "release_on_proof",
"holdCents": 227400,
"milestones": [
{
"ref": "s1",
"amountCents": 219500,
"releasesOn": "accepted"
},
{
"ref": "s2",
"amountCents": 7900,
"releasesOn": "accepted"
}
],
"acceptWindowHours": 48
},
"provenance": {
"clientId": null,
"mandateId": null,
"createdAt": "2026-10-13T15:00:00.000Z",
"source": "compiled",
"quote": null,
"parentRevision": null,
"compiledSpecId": "cs_example",
"compiler": "spec-compiler/2026-10-08.1"
},
"labor": [
{
"ref": "s1",
"capability": "plumbing.water-heater-replace",
"level": 1,
"trade": "plumbing",
"credentials": [
"license:plumbing_license",
"license:gl_insurance",
"license:workers_comp"
],
"hours": {
"low": 4,
"expected": 4,
"high": 4
},
"crewSize": 2,
"nodes": [
"s1"
],
"basis": "240 min each (catalog minutes); high adds every hidden condition's rate-card hours"
},
{
"ref": "s2",
"capability": "plumbing.leak-sensor",
"level": 1,
"trade": "plumbing",
"credentials": [
"license:none",
"license:gl_insurance",
"license:workers_comp"
],
"hours": {
"low": 0.2,
"expected": 0.2,
"high": 0.2
},
"crewSize": 1,
"nodes": [
"s2"
],
"basis": "10 min each (catalog minutes); high adds every hidden condition's rate-card hours"
}
],
"dependencies": {
"nodes": [
{
"id": "s1",
"ref": "s1",
"label": "Replace a tank water heater",
"kind": "work",
"hours": 2,
"gate": true,
"weatherSensitive": false
},
{
"id": "s1:signoff",
"ref": "s1",
"label": "Licensed sign-off: Replace a tank water heater",
"kind": "signoff",
"hours": 0.25,
"gate": true,
"weatherSensitive": false
},
{
"id": "s2",
"ref": "s2",
"label": "Place a leak sensor",
"kind": "work",
"hours": 0.2,
"gate": false,
"weatherSensitive": false
},
{
"id": "insp:final-plumbing",
"ref": null,
"label": "Inspection: final plumbing",
"kind": "inspection",
"hours": 1,
"gate": true,
"weatherSensitive": false
}
],
"edges": [
{
"from": "s1",
"to": "s1:signoff",
"kind": "signoff",
"lagHours": 0,
"reason": "water pressure and gas and electrical work is signed off by the licensed pro"
},
{
"from": "s1:signoff",
"to": "s2",
"kind": "trade",
"lagHours": 0,
"reason": "The sensor goes in the new heater's pan"
},
{
"from": "s1:signoff",
"to": "insp:final-plumbing",
"kind": "inspection",
"lagHours": 8,
"reason": "Final plumbing is requested 1 working day ahead"
}
],
"order": [
"s1",
"s1:signoff",
"s2",
"insp:final-plumbing"
],
"criticalPath": [
"s1",
"s1:signoff",
"insp:final-plumbing"
],
"lengthHours": 11.25,
"days": 2
},
"priceRange": {
"currency": "USD",
"lowCents": 227400,
"expectedCents": 227400,
"highCents": 227400,
"baseCents": 227400,
"ceilingCents": 227500,
"basis": "5th percentile, mean and 95th percentile of the cost once everything unseen is seen",
"drivers": [
{
"ref": "s1",
"kind": "scope",
"label": "Whether this is needed: Replace a tank water heater (86% sure)",
"spreadCents": 219500
}
]
},
"questions": [
{
"id": "exists:water-heater-replace",
"kind": "exists",
"text": "Is this the work: Replace a tank water heater?",
"why": "We're 86% sure from what we have",
"options": [
{
"id": "yes",
"label": "Yes"
},
{
"id": "no",
"label": "No"
}
],
"shot": null,
"voiCents": 0
},
{
"id": "timeline",
"kind": "timeline",
"text": "When does it need to be done?",
"why": "It sets the window we hold crews for",
"options": [
{
"id": "asap",
"label": "As soon as possible"
},
{
"id": "weeks",
"label": "In the next few weeks"
},
{
"id": "months",
"label": "In the next few months"
},
{
"id": "flexible",
"label": "No rush"
}
],
"shot": null,
"voiCents": 0
}
],
"confidence": {
"overall": 0.855,
"scope": 0.855,
"price": 1
},
"risks": [
{
"kind": "safety",
"ref": "s1",
"label": "Replace a tank water heater: water pressure, gas, electrical work, signed off by the licensed pro and never approved automatically",
"probability": null,
"amountCents": null
},
{
"kind": "access",
"ref": null,
"label": "dog",
"probability": null,
"amountCents": null
}
],
"permits": {
"status": "permit_needed",
"items": [
{
"work": "water-heater-replace",
"label": "Replace a water heater"
}
],
"note": "These are draft rules for City of Atlanta that our permit desk hasn't checked with the jurisdiction yet. An expediter confirms what's needed before anything is filed."
}
}Work Spec v1
The bookable spec for listed repairs.
Work Spec v2
The compiler's output, including remodel packages.
Specs are designed so the executor can be a person, a crew or, eventually, a machine that registers the skills a line requires. Today every executor is a person. No machine is registered.
A short film of an assistant ordering a repair through the protocol, from photo to payment on proof. It is a demonstration with a made-up home and pro.