Status: FINALIZED & IMPLEMENTED (2026-07-27). Decisions recorded in §9. The orchestrator (
SKILL.md) and five subagents underagents/are built; Phases 4.5 and 8–11 are now delegation stubs.
A single general agent would carry unrelated evidence, calculations, and regulatory boundaries through every turn. The modular design instead provides focused context, domain-specific schemas and guardrails, selective activation, independent evaluation, reusable direct invocation, and a smaller blast radius when a prompt or model changes. The six agents are logical workflow modules; they do not require six simultaneous or unconstrained model calls.
Non-goals: cross-property data mixing, personal/background dossiers, legal/financial advice, or changing the reusable templates we just built (loan/insurance/inspection dashboards stay as-is).
The subagents map onto the natural stages of a purchase. Not every buyer does every stage, and stages overlap, so the orchestrator treats these as a checklist with dependencies, not a rigid wizard.
flowchart TD
A[0. Readiness\nbudget, pre-approval] --> B[1. Discovery\nfind a house, listing sheet]
B --> C[2. Investigation\ndisclosures, survey, title, photos]
C --> D[3. Neighborhood & value\ncomps / appraisal district]
C --> E[4. Financing\nloan shopping]
D --> F[5. Offer & contract\nnegotiate, execute]
E --> F
F --> G[6. Option period\ninspection + repair negotiation]
F --> H[7. Insurance\nquotes, bind before closing]
G --> I[8. Closing prep\nfinal walkthrough, cash-to-close]
H --> I
I --> J[9. Post-closing\nmove-in, repairs]
| Stage | What the buyer is doing | Which agent leads | Existing phase |
|---|---|---|---|
| 0 Readiness | Sets budget, gets pre-approved | Loan (light) | Phase 9 (early) |
| 1 Discovery | Picks a property, gathers docs | Orchestrator | Phase 0–1 |
| 2 Investigation | Reads disclosures/survey/title | Orchestrator | Phase 2–6 |
| 3 Neighborhood & value | Comps, is the price fair | Orchestrator (Neighborhood) | Phase 4.5 |
| 4 Financing | Compares Loan Estimates | Loan subagent | Phase 9 |
| 5 Offer & contract | Negotiates, executes contract | Orchestrator | (contract capture) |
| 6 Option period | Inspection → repair asks | Inspection subagent | Phase 11 |
| 7 Insurance | Gets quotes, binds | Insurance subagent | Phase 10 |
| 8 Closing prep | Reconciles cash-to-close | Orchestrator | (checklist) |
| 9 Post-closing | Move-in / repairs | Orchestrator | (move-in plan) |
One orchestrator (the current Property Investigator) plus three domain subagents. Each subagent is a self-contained module with its own trigger phrases, its own templates, and its own outputs — but all of them read and write a single shared journey state for the property.
flowchart LR
U([User]) --> R{Router\ntrigger phrases}
R -->|full journey / property docs| ORCH[Property Investigator\nORCHESTRATOR]
R -->|"compare loans"| LOAN[Loan Advisor]
R -->|"review inspection"| INSP[Inspection Advisor]
R -->|"compare insurance"| INS[Insurance Advisor]
ORCH -.invokes at stage 4.-> LOAN
ORCH -.invokes at stage 6.-> INSP
ORCH -.invokes at stage 7.-> INS
LOAN <--> STATE[(.property/journey.json\nshared state)]
INSP <--> STATE
INS <--> STATE
ORCH <--> STATE
loan/<Lender>/; from state: purchase price, planned loan, contract max
rate, closing date, escrow premium (if insurance has run).Loan-Comparison-Report.html + loan-comparison-dashboard.html (from the loan template),
data/loan-quotes.json, loan/history/.insurance/<Carrier>/; from state: dwelling replacement cost, roof
age/condition, foundation notes, closing date.Insurance-Call-Prep.html + (≥2 carriers) Insurance-Comparison-Report.html (from the
insurance templates).inspection/documents/, specialist quotes in estimates/; from
state: executed-contract option deadline, purchase price, value cushion.Inspection-Analysis-Report.html, Inspection-Repair-Budget.html (interactive), the two
data files + page images, Inspection-Repair-Request.html, data/inspection-findings.json..property/journey.jsonA single per-property file is the “spine”. Each subagent reads it for context and writes back its results. It never contains another property’s data (isolation preserved).
{
"property": { "address": "…", "slug": "…", "purchasePrice": 0, "county": "…" },
"stage": "option-period", // current journey stage
"contract": {
"effectiveDate": null, "optionDeadline": null, "financingApprovalDate": null,
"closingDate": null, "asIs": true, "status": "verified|unverified"
},
"value": { "estimatedValue": null, "cushion": null }, // from Neighborhood/Investigation
"loan": { "ran": false, "bestLender": null, "rate": null, "monthlyPITI": null,
"escrowMonthly": null, "cashToClose": null, "maxRateFlag": null },
"insurance": { "ran": false, "carrier": null, "annualPremium": null,
"roofSettlement": null, "deductibles": null },
"inspection": { "ran": false, "exposureBase": null, "sellerScope": null,
"buyerCredit": null, "dealBreaker": "no|conditional|yes|pending" },
"openRisks": [],
"updated": "ISO-8601"
}
Rules: every write is timestamped; a subagent only overwrites its own section + openRisks; the
orchestrator is the only writer of stage and contract; missing values stay null (never invented).
The three domains are financially coupled. The orchestrator reconciles these after any subagent runs:
annualPremium, prompt Loan to recompute escrow and re-flag the
best pick; tell the user to give the lender the final premium.buyerCredit, Loan and
the closing checklist must reflect it.flowchart LR
INS[Insurance\nannual premium] -->|escrow| LOAN[Loan\nPITI + cash-to-close]
INSP[Inspection\ncredit / price cut] -->|cash-to-close / loan amt| LOAN
CON[(Contract deadlines)] --> INSP
CON --> LOAN
CON --> CLOSE[Closing prep]
LOAN --> CLOSE
INS --> CLOSE
A. Independent (direct). User triggers a subagent by phrase. The subagent:
journey.json for context if present; otherwise runs standalone with what it can extract.B. Orchestrated (journey). The main agent:
journey.json + available docs.openRisks.Routing is by trigger phrase first; if a property journey is active and the request is ambiguous, the orchestrator picks the stage-appropriate subagent.
sequenceDiagram
actor Buyer
participant O as Orchestrator
participant R as Property-scoped retrieval
participant A as Domain advisor
participant S as Journey state
Buyer->>O: question + new evidence
O->>S: load stage, deadlines, and open risks
O->>R: retrieve with tenant/engagement/property filters
R-->>O: evidence chunks + source locators
O->>A: bounded evidence + owned schema
A-->>O: structured result + citations + confidence
O->>O: validate schema, calculations, and evidence coverage
O->>S: update advisor-owned section
O->>O: reconcile dependent values
O-->>Buyer: decision, evidence, uncertainty, and next action
The orchestrator must reject invalid schemas, unsupported material claims, cross-property evidence, and stale results. A failed specialist remains failed/blocked; it must not be converted into a success-shaped fallback.
The prototype keeps a provider adapter and deterministic local fallback. Azure OpenAI is the production target because it can share the Azure identity, private-network, regional, governance, safety, and monitoring boundary; the architecture remains model-portable so deployments are selected by evaluation rather than hard-coded preference.
Production grounding uses engagement-scoped Blob Storage plus Azure AI Search hybrid retrieval. Indexed chunks carry property, document, page/record, authority, effective-date, jurisdiction, and retrieval metadata. Mandatory security filters are applied before retrieval, and every material output cites the retrieved evidence.
For thousands of users:
Option chosen for discussion — modular skill folder (keeps everything in this repo, no external agent registry needed):
Property-Report-Skill/
SKILL.md # becomes the ORCHESTRATOR (journey + routing + reconciliation)
agents/
loan-advisor/SKILL.md # Phase 9 content, self-contained, independently triggerable
insurance-advisor/SKILL.md # Phase 10 content
inspection-advisor/SKILL.md # Phase 11 content
templates/ # unchanged (loan/insurance/inspection dashboards already reusable)
properties/<slug>/
.property/journey.json # NEW shared state spine
… # existing per-domain folders unchanged
agents/*/SKILL.md carries its own trigger phrases, workflow, templates reference, and guardrails,
lifted from the current phase text (no behavior change).SKILL.md keeps a slim version of each phase that delegates to the subagent doc, plus the new
journey/state/reconciliation logic..agent.md files. Rejected for now because the workspace has none and the
modular-skill approach is self-contained and portable. (Flag if you prefer native agents.)journey.json schema + a short “read/update state” contract in SKILL.md.agents/loan-advisor, agents/insurance-advisor,
agents/inspection-advisor (verbatim behavior + their template references), each independently triggerable.SKILL.md with delegation stubs + the journey
checklist, routing table, and the §5 reconciliation rules.agents/<name>-advisor/SKILL.md (recommended option)..property/journey.json (kept separate from manifest.json, which tracks doc
hashes — separation of concerns).loan/history/ (never silently discard the prior one).agents/{neighborhood,comparison,loan,inspection,insurance}-advisor/SKILL.md — created (independently
triggerable; own workflow, templates, guardrails, and journey-state contract).SKILL.md — added the Agent Architecture & Buyer Journey section, the journey.json schema, the
cross-agent reconciliation rules, the first-time-buyer entry point, and delegation stubs for Phases 4.5, 8–11.Decision-support tooling only — not legal, financial, lending, insurance, or professional-inspection advice. Each property remains an isolated, confidential engagement.