AGPL-3.0 reference implementation of
mortgage-decision-record-audit-stream. Runs the Pacific Coast Mortgage Holdings × VendorR LoanDecision v5.2 trajectory end-to-end. 2 invariants: human-underwriter-required UNIVERSAL on every adverse-action-capable kind (PropTech is the ONLY Suite vertical with universal-not-scoped rule) + ECOA Reg B 30-day adverse-action notice clock per 12 CFR §1002.9.
Part of the Kinetic Gain Protocol Suite.
Sibling to fhir-resource-access-audit-reference, matter-decision-record-audit-stream-reference, grid-decision-record-audit-stream-reference, defense-decision-record-audit-stream-reference, government-decision-record-audit-stream-reference, financial-decision-record-audit-stream-reference, employment-decision-record-audit-stream-reference, and student-data-access-audit-stream-reference.
PropTech is structurally distinct from every other Suite vertical:
-
Invariant #1 — human_underwriter_required UNIVERSAL on adverse-action-capable kinds, regardless of recommendation. Every other Suite vertical (FinTech, HR Tech, InsurTech, GovTech, HealthTech, DefenseTech, EnergyTech, LegalTech, EdTech) scopes the human-required rule to adverse outcomes only. PropTech doesn't — a clean approval still requires a named underwriter on file because the audit trail itself is what protects against post-hoc reverse-engineering claims under Fair Housing + Reg B.
-
Invariant #2 — ECOA Reg B 30-day adverse-action notice forward clock per 12 CFR §1002.9. When an outcome recommendation is adverse (decline, approve-with-conditions, counter-offer, withdraw-incomplete) AND the application has a
completed_attimestamp, the lender has 30 days from completed-application to send written adverse-action notice. A different wall-clock pattern from the others: anchored on application completeness, not event timestamp.
orchestrator.mjs (3 steps, escalating to recommendation)
│
├─ requests access via mortgage-vault.mjs (universal underwriter + ECOA clock)
│
├─ builds hash-chained event via event-builder.mjs (canonical-JSON SHA-256)
│
└─ emits to examples/pcm-loandecision-reference-stream.ndjson
verifier.mjs (independent, post-hoc)
│
├─ chain integrity (each prev_hash = prior hash)
├─ invariant #1: universal human-underwriter on adverse-action-capable kinds
└─ invariant #2: ECOA 30-day adverse-action notice clock
npm install && npm start
# → Built 3 events → examples/pcm-loandecision-reference-stream.ndjson
# → OK · 3 events · chain ✓ · 2 invariants ✓
npm test # 9 unit tests| Step | Event | Adverse-action-capable? | Underwriter required? |
|---|---|---|---|
| 1 | Application received (URLA 1003 stamp) | No (informational) | No |
| 2 | AI underwriting analysis produced (advisory) | No | No |
| 3 | Application decision recommended — approve-with-conditions |
Yes | Yes — UNIVERSAL rule fires + ECOA 30-day notice sent within 2 days |
approve-with-conditions counts as an adverse-action recommendation under Reg B because it changes terms from the original application — so both invariants fire on the same event.
| Kind | Why universal-not-scoped |
|---|---|
application-decision-recommended |
Could be decline/approve/counter — all need audit trail |
refinance-decision-recommended |
Same risk profile as origination |
modification-decision-recommended |
Loss-mit decisions trigger Reg X obligations |
pricing-decision-recommended |
Disparate-impact risk on rate-sheet outputs |
appraisal-review-recommended |
HVCC / appraiser-independence rules |
decline · approve-with-conditions · counter-offer · withdraw-incomplete
A clean approve does not trigger Reg B's 30-day notice requirement (no adverse-action notice owed) but still triggers Invariant #1's universal underwriter requirement.
| Failure mode | Reason |
|---|---|
Adverse-action-capable kind WITHOUT underwriter (even on approve) |
"PropTech is the only Suite vertical with universal-not-scoped underwriter rule — Reg B + Fair Housing + RESPA risk profile" |
Adverse recommendation without adverse_action_notice_sent_at |
"ECOA Reg B 12 CFR §1002.9 — 30-day notice required" |
| ECOA notice sent >30 days after completed application | "ECOA 30-day adverse-action notice clock missed — sent N days after completed application" |
mortgage-decision-record-audit-stream— the spec this implementsrespa-readiness-evidence-bundle— evidence bundle that ingests eventstitle-chain-evidence-incident-card-profile— invariant failures become Incident Cardsstate-real-estate-ai-disclosure-tracker— 50-state lifecyclemls-data-access-vault-contract-profile— Decision Card vault contract- Kinetic Gain Protocol Suite — umbrella
Reference implementation readiness scaffolding for ECOA (Reg B) + RESPA (Reg X) + Fair Housing Act + TILA (Reg Z) + HMDA + state mortgage lending regimes. Does NOT constitute CFPB attestation, FHA insurance qualification, or substitute for a lender's own QC + fair-lending statistical analysis. The mock vault is in-memory — production deployments must integrate with the LOS (Encompass / Empower) + DU/LP underwriting engines + adverse-action notice generator. Per the standing Suite public-language guardrail: readiness · evidence · posture · controls · scaffolding — never "compliant" / "certified" without external attestation.
AGPL-3.0-only. Spec repos this depends on remain MIT.