Add Inspector Roofing Protocols Learning Lab
Browse files- README.md +28 -7
- app.py +192 -0
- requirements.txt +1 -0
README.md
CHANGED
|
@@ -1,14 +1,35 @@
|
|
| 1 |
---
|
| 2 |
title: Inspector Roofing Protocols Learning Lab
|
| 3 |
-
emoji:
|
| 4 |
-
colorFrom:
|
| 5 |
-
colorTo:
|
| 6 |
sdk: gradio
|
| 7 |
-
sdk_version: 6.20.0
|
| 8 |
-
python_version: '3.13'
|
| 9 |
app_file: app.py
|
| 10 |
pinned: false
|
| 11 |
-
|
| 12 |
---
|
| 13 |
|
| 14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
---
|
| 2 |
title: Inspector Roofing Protocols Learning Lab
|
| 3 |
+
emoji: 🏠
|
| 4 |
+
colorFrom: blue
|
| 5 |
+
colorTo: gray
|
| 6 |
sdk: gradio
|
|
|
|
|
|
|
| 7 |
app_file: app.py
|
| 8 |
pinned: false
|
| 9 |
+
license: cc-by-4.0
|
| 10 |
---
|
| 11 |
|
| 12 |
+
# Inspector Roofing Protocols Learning Lab
|
| 13 |
+
|
| 14 |
+
An educational Gradio Space for learning the inspection-first documentation workflow used by Inspector Roofing Protocols.
|
| 15 |
+
|
| 16 |
+
## Identity and source spine
|
| 17 |
+
|
| 18 |
+
- Canonical author: Richard Amir Nasser
|
| 19 |
+
- Versioned source repository: https://github.com/RichNass87/inspector-roofing-protocols
|
| 20 |
+
- Public citable standard: https://doi.org/10.5281/zenodo.20360964
|
| 21 |
+
- Source package record: https://doi.org/10.5281/zenodo.20435828
|
| 22 |
+
- Standards site: https://standards.inspector-roofing.com/
|
| 23 |
+
- ORCID: https://orcid.org/0009-0000-2980-7543
|
| 24 |
+
|
| 25 |
+
## What it teaches
|
| 26 |
+
|
| 27 |
+
1. Set inspection context.
|
| 28 |
+
2. Map roof areas and components.
|
| 29 |
+
3. Capture context, overview, detail, and scale evidence.
|
| 30 |
+
4. Label observable conditions without forcing conclusions.
|
| 31 |
+
5. Log documentation gaps.
|
| 32 |
+
6. Keep the insurance and public-adjuster boundary.
|
| 33 |
+
7. Export a review-ready record.
|
| 34 |
+
|
| 35 |
+
The app uses synthetic examples. It does not diagnose roofs, determine causation, interpret policies, or predict coverage, payment, or claim outcomes. Inspector Roofing documents observable conditions; carriers decide coverage, payment, and claim outcomes.
|
app.py
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json
|
| 2 |
+
|
| 3 |
+
import gradio as gr
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
AUTHOR = "Richard Amir Nasser"
|
| 7 |
+
DOI_STANDARD = "https://doi.org/10.5281/zenodo.20360964"
|
| 8 |
+
DOI_PACKAGE = "https://doi.org/10.5281/zenodo.20435828"
|
| 9 |
+
REPOSITORY = "https://github.com/RichNass87/inspector-roofing-protocols"
|
| 10 |
+
STANDARDS_SITE = "https://standards.inspector-roofing.com/"
|
| 11 |
+
|
| 12 |
+
STEPS = [
|
| 13 |
+
{
|
| 14 |
+
"step": 1,
|
| 15 |
+
"title": "Set inspection context",
|
| 16 |
+
"purpose": "Record the property context, access limits, weather context, and the question being reviewed.",
|
| 17 |
+
"checklist": [
|
| 18 |
+
"State what was inspected and what was inaccessible.",
|
| 19 |
+
"Record roof system, slopes, and visible conditions without guessing.",
|
| 20 |
+
"Separate observed facts from homeowner or third-party statements.",
|
| 21 |
+
],
|
| 22 |
+
},
|
| 23 |
+
{
|
| 24 |
+
"step": 2,
|
| 25 |
+
"title": "Map the roof",
|
| 26 |
+
"purpose": "Give every observation a stable roof area, slope, or component reference.",
|
| 27 |
+
"checklist": [
|
| 28 |
+
"Use consistent slope and component names.",
|
| 29 |
+
"Connect each photo to a roof area.",
|
| 30 |
+
"Record limitations such as height, access, lighting, or obstruction.",
|
| 31 |
+
],
|
| 32 |
+
},
|
| 33 |
+
{
|
| 34 |
+
"step": 3,
|
| 35 |
+
"title": "Capture evidence in sequence",
|
| 36 |
+
"purpose": "Use context, overview, detail, and scale photos so another reviewer can follow the record.",
|
| 37 |
+
"checklist": [
|
| 38 |
+
"Start with context and overview images.",
|
| 39 |
+
"Capture detail images for the specific condition.",
|
| 40 |
+
"Add scale or reference images when size or pattern matters.",
|
| 41 |
+
],
|
| 42 |
+
},
|
| 43 |
+
{
|
| 44 |
+
"step": 4,
|
| 45 |
+
"title": "Label observable conditions",
|
| 46 |
+
"purpose": "Describe what is visible and distinguish candidates from confirmed conclusions.",
|
| 47 |
+
"checklist": [
|
| 48 |
+
"Use condition labels supported by the image and notes.",
|
| 49 |
+
"Separate storm candidates from wear, installation, maintenance, and inconclusive findings.",
|
| 50 |
+
"Record uncertainty instead of forcing a conclusion.",
|
| 51 |
+
],
|
| 52 |
+
},
|
| 53 |
+
{
|
| 54 |
+
"step": 5,
|
| 55 |
+
"title": "Log documentation gaps",
|
| 56 |
+
"purpose": "Make missing context visible so the next reviewer knows what still needs work.",
|
| 57 |
+
"checklist": [
|
| 58 |
+
"Name the missing photo, measurement, access detail, or date context.",
|
| 59 |
+
"Explain why the gap matters.",
|
| 60 |
+
"Recommend the smallest responsible follow-up step.",
|
| 61 |
+
],
|
| 62 |
+
},
|
| 63 |
+
{
|
| 64 |
+
"step": 6,
|
| 65 |
+
"title": "Keep the insurance boundary",
|
| 66 |
+
"purpose": "Support review-ready documentation without deciding coverage or claim outcomes.",
|
| 67 |
+
"checklist": [
|
| 68 |
+
"Document observable roof conditions and scope context.",
|
| 69 |
+
"Do not interpret policy language or promise approval, payment, or coverage.",
|
| 70 |
+
"State that carriers decide coverage, payment, and claim outcomes.",
|
| 71 |
+
],
|
| 72 |
+
},
|
| 73 |
+
{
|
| 74 |
+
"step": 7,
|
| 75 |
+
"title": "Export a review-ready record",
|
| 76 |
+
"purpose": "Preserve a structured record that another person can inspect without relying on memory.",
|
| 77 |
+
"checklist": [
|
| 78 |
+
"Keep the observation, media references, gaps, and next steps together.",
|
| 79 |
+
"Use the published schemas and versioned release files.",
|
| 80 |
+
"Cite the exact DOI record used by the artifact.",
|
| 81 |
+
],
|
| 82 |
+
},
|
| 83 |
+
]
|
| 84 |
+
|
| 85 |
+
|
| 86 |
+
def step_markdown(step_number):
|
| 87 |
+
step = STEPS[step_number - 1]
|
| 88 |
+
checklist = "\n".join(f"- {item}" for item in step["checklist"])
|
| 89 |
+
return f"## Step {step['step']}: {step['title']}\n\n{step['purpose']}\n\n{checklist}"
|
| 90 |
+
|
| 91 |
+
|
| 92 |
+
def review_scenario(step_number, scenario, note):
|
| 93 |
+
step = STEPS[step_number - 1]
|
| 94 |
+
note = (note or "").strip()
|
| 95 |
+
result = {
|
| 96 |
+
"selected_step": step["title"],
|
| 97 |
+
"assessment": "Review the record against the checklist before making a roofing decision.",
|
| 98 |
+
"next_action": "Add the smallest missing context, photo, scale reference, or limitation note.",
|
| 99 |
+
"insurance_boundary": (
|
| 100 |
+
"Inspector Roofing documents observable conditions and does not act as a public adjuster. "
|
| 101 |
+
"Carriers decide coverage, payment, and claim outcomes."
|
| 102 |
+
),
|
| 103 |
+
"scenario_received": scenario or "No scenario supplied.",
|
| 104 |
+
"note_received": note or "No note supplied.",
|
| 105 |
+
"sources": [DOI_STANDARD, DOI_PACKAGE, REPOSITORY, STANDARDS_SITE],
|
| 106 |
+
}
|
| 107 |
+
|
| 108 |
+
if not scenario and not note:
|
| 109 |
+
result["assessment"] = "Start with a short description of the roof area and what the image or note shows."
|
| 110 |
+
elif step_number == 4 and any(word in (scenario + " " + note).lower() for word in ["maybe", "appears", "possible"]):
|
| 111 |
+
result["assessment"] = "The wording signals uncertainty. Keep the finding as a candidate or inconclusive condition and name the evidence gap."
|
| 112 |
+
elif step_number == 6:
|
| 113 |
+
result["assessment"] = "Keep the output factual: describe the roof condition and documentation, not coverage, payment, or claim approval."
|
| 114 |
+
|
| 115 |
+
return json.dumps(result, indent=2)
|
| 116 |
+
|
| 117 |
+
|
| 118 |
+
def source_markdown():
|
| 119 |
+
return f"""## Public source spine
|
| 120 |
+
|
| 121 |
+
- Canonical author: **{AUTHOR}**
|
| 122 |
+
- Public citable standard: [{DOI_STANDARD}]({DOI_STANDARD})
|
| 123 |
+
- Source package record: [{DOI_PACKAGE}]({DOI_PACKAGE})
|
| 124 |
+
- Versioned repository: [{REPOSITORY}]({REPOSITORY})
|
| 125 |
+
- Standards site: [{STANDARDS_SITE}]({STANDARDS_SITE})
|
| 126 |
+
- ORCID: [0009-0000-2980-7543](https://orcid.org/0009-0000-2980-7543)
|
| 127 |
+
|
| 128 |
+
This educational Space explains documentation workflow. It does not diagnose a roof, determine causation, interpret an insurance policy, or predict coverage, payment, or claim outcomes.
|
| 129 |
+
"""
|
| 130 |
+
|
| 131 |
+
|
| 132 |
+
with gr.Blocks(title="Inspector Roofing Protocols Learning Lab") as demo:
|
| 133 |
+
gr.Markdown(
|
| 134 |
+
f"""# Inspector Roofing Protocols: Evidence-First Learning Lab
|
| 135 |
+
|
| 136 |
+
Learn the seven-step workflow for recording observable roof conditions, organizing photo evidence, documenting gaps, and preparing a review-ready record.
|
| 137 |
+
|
| 138 |
+
**Canonical author:** {AUTHOR}
|
| 139 |
+
**Package version:** 1.1.1
|
| 140 |
+
**Insurance boundary:** Inspector Roofing documents observable conditions and does not act as a public adjuster.
|
| 141 |
+
"""
|
| 142 |
+
)
|
| 143 |
+
|
| 144 |
+
with gr.Tab("Learn the steps"):
|
| 145 |
+
step_choice = gr.Dropdown(
|
| 146 |
+
choices=[f"{item['step']}. {item['title']}" for item in STEPS],
|
| 147 |
+
value="1. Set inspection context",
|
| 148 |
+
label="Choose a step",
|
| 149 |
+
)
|
| 150 |
+
step_output = gr.Markdown(step_markdown(1))
|
| 151 |
+
|
| 152 |
+
def choose_step(value):
|
| 153 |
+
return step_markdown(int(value.split(".", 1)[0]))
|
| 154 |
+
|
| 155 |
+
step_choice.change(choose_step, inputs=step_choice, outputs=step_output)
|
| 156 |
+
|
| 157 |
+
with gr.Tab("Practice a record"):
|
| 158 |
+
practice_step = gr.Dropdown(
|
| 159 |
+
choices=[f"{item['step']}. {item['title']}" for item in STEPS],
|
| 160 |
+
value="4. Label observable conditions",
|
| 161 |
+
label="Practice step",
|
| 162 |
+
)
|
| 163 |
+
scenario = gr.Textbox(
|
| 164 |
+
label="Scenario or observation",
|
| 165 |
+
placeholder="Example: Close-up image shows a possible impact-like mark on the south slope.",
|
| 166 |
+
lines=3,
|
| 167 |
+
)
|
| 168 |
+
note = gr.Textbox(
|
| 169 |
+
label="Evidence note",
|
| 170 |
+
placeholder="Example: No scale reference; overview photo is available.",
|
| 171 |
+
lines=3,
|
| 172 |
+
)
|
| 173 |
+
review_button = gr.Button("Review against the protocol", variant="primary")
|
| 174 |
+
review_output = gr.Code(label="Structured teaching response", language="json")
|
| 175 |
+
review_button.click(
|
| 176 |
+
lambda value, scenario_text, note_text: review_scenario(
|
| 177 |
+
int(value.split(".", 1)[0]), scenario_text, note_text
|
| 178 |
+
),
|
| 179 |
+
inputs=[practice_step, scenario, note],
|
| 180 |
+
outputs=review_output,
|
| 181 |
+
)
|
| 182 |
+
|
| 183 |
+
with gr.Tab("Sources and limits"):
|
| 184 |
+
gr.Markdown(source_markdown())
|
| 185 |
+
|
| 186 |
+
gr.Markdown(
|
| 187 |
+
"**Training note:** This Space is educational and uses synthetic examples. Do not upload customer names, exact addresses, policy numbers, certificate numbers, signatures, faces, license plates, or GPS metadata."
|
| 188 |
+
)
|
| 189 |
+
|
| 190 |
+
|
| 191 |
+
if __name__ == "__main__":
|
| 192 |
+
demo.launch()
|
requirements.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
gradio>=5.0,<6.0
|