Skip to main content

Knowledge > Products > WiseAI Realtor > VOW / Sold-Data Track

WiseAI Realtor — VOW / Sold-Data Track (Phase 5)

Design-first scoping spec. No code, no migrations. This is build-roadmap.md Phase 5 and step 3 of the backend-completeness-audit "Recommended sequence." It decides how WiseAI Realtor unlocks sold data — the gate to the entire HouseSigma-class consumer feature set.

This is product requirements, not legal advice. Every item tagged [LEGAL] needs counsel sign-off and every [verify with board] needs confirmation from the board / PropTx before a client goes live. Sold-data rules, the VOW agreement terms, the sold-history window, retention, and who holds the VOW licence are the brokerage's and counsel's call, not ours.


0. The one-paragraph problem

Every Canadian consumer who has used HouseSigma, Zoocasa, or Wahi now expects to see what a home sold for, the sold comparables nearby, the price/relisting history, the true cumulative days-on-market, and an automated home-value estimate. WiseAI Realtor cannot show any of it today, because our live listings come from CREA's DDF feed, which carries zero sold/historical data (DDF is active-listings only; see do-not-reinvent.md and backend-completeness-audit.md). Sold data legally requires a board VOW (Virtual Office Website) feed displayed behind a consumer registration gate. Activating that feed is its own track with three hard dependencies: a board VOW agreement (the brokerage's licence, not ours), a consumer-account identity layer (distinct from the agent RBAC), and a registration gate that is — uniquely — the consumer expectation, the legal mechanism, and our single biggest lead-capture engine all at once.


1. What & why — VOW vs IDX vs DDF

Three different data licences, three different capabilities. Getting these straight is the whole spec.

DDF® (what we run today)IDX (board active feed)VOW (board, behind login)
SourceCREA national pool (ddfapi.realtor.ca)Local board / PropTxLocal board / PropTx
ContentActive listings onlyActive listings onlyActive + sold/off-market + sales history
Sold prices / historyNoneNoneYes (this is the point)
Public displayPublic OK (with attribution)Public OK (with attribution)Login + registration + relationship required
Mental modelFree national syndicationPublic "advertising" sitePrivate "business" site that replicates one-on-one office service online
Our statusLIVE (PR #1064)Not used (DDF covers active)Greenfield — this track
  • IDX is an advertising surface: all active listings, public, no registration. CREA's DDF is effectively our national IDX-equivalent and is already live for Beckett (office 296475, 11 listings, source='ddf').
  • VOW is a brokerage-services surface: it adds off-market and sales history (sold price + sold date), and precisely because that data is more sensitive it is not open to the public — the registrant must establish a consumer-broker relationship and agree to terms first. (Realtyna — IDX vs VOW; CREA Café — tech acronyms)

What sold data unlocks (the HouseSigma-class bar):

  1. Sold price on every recently sold home.
  2. Sold comparables — "what did similar nearby homes sell for" (the CMA-lite buyers want).
  3. Price & relisting history — list → price-drop → relist → terminate → sold, with each price.
  4. True cumulative days-on-market (defeats the relist-to-reset-DOM trick).
  5. AVM / automated home-value estimate — built on the sold comps (§7).
  6. Just-sold / price-drop alerts on a saved search (§4 of data-model.md).

Incumbents show deep history — Wahi advertises up to 21 years of sales history; HouseSigma 10+ years (finehomesandliving roundup). Note the gap vs the feed window in §6 — the live PropTx VOW feed exposes roughly 2 years of sold history; longer archives are accrued by retaining synced rows over time and/or supplementing with public land-registry data. [verify with board] whether multi-year retention/accumulation beyond the feed window is permitted under the VOW agreement before promising "10 years."


2.1 Why sold data may be shown at all — Competition Bureau v. TREB

For years the Toronto Real Estate Board forbade members from displaying sold prices online via VOWs (members could share by hand/email/fax, but not online). The Competition Bureau challenged this as an abuse of dominance. The Competition Tribunal ordered TREB to stop restricting the display and use of sold prices through VOWs; TREB's PIPEDA/privacy defence was rejected as a pretext for blocking disruptive competition; the Federal Court of Appeal upheld it; and on 2018-08-23 the Supreme Court of Canada denied leave to appeal, ending a seven-year saga and letting the order take effect. (Competition Bureau / Canada.ca — SCC won't hear appeal; McCarthy Tétrault; RECO)

The precise lesson — and it cuts both ways: the case made it permissible for members to display sold data through a VOW. It did not make sold data fully public. The VOW registration gate (login + terms + relationship) is exactly what makes the display lawful. HouseSigma, Zoocasa, and Wahi all gate it behind a free account for this reason. So the gate is not an optional UX nicety — it is the legal mechanism.

2.2 Hard invariants (do not violate)

  1. Sold data is NEVER public. It is displayed only to a registered, terms-accepted consumer in a broker-consumer relationship. There is no anonymous path to a sold price. (Architecturally: deny-by-default RLS; anon role can never read sold tables — §5.)
  2. Registration is real, per the VOW rules. A registrant must supply name + a valid email, and the brokerage must send a confirming email that the registrant agreed to the terms of use. The registrant gets a unique username/password (or modern auth equivalent), must acknowledge a lawful consumer-broker relationship, personal non-commercial use, and a bona fide interest in buying/selling/leasing. (NAR VOW policy §II.2; CREA mirrors this structure — CREA Café.)
  3. No scraping / no redistribution. Terms must prohibit copying, redistributing, or retransmitting the data except in connection with the registrant's own consideration of a specific property; commercial use is barred; throttling/anti-scraping is expected.
  4. Seller opt-out is honored. A seller who directs the listing brokerage to withhold the listing/address from the internet must not appear; opt-out forms are retained (NAR: ~1 year). (NAR VOW policy §II.5)
  5. Display obligations. Listing-brokerage "courtesy of" attribution stays on displayed records; confidential fields (e.g. cooperating-broker compensation, certain expired/withdrawn/pending data) are not shown; MLS®/REALTOR® trademark rules apply (see compliance-privacy-analytics.md §4).
  6. MLS audit rights. The terms must let the board/MLS access the VOW to verify rule compliance. Our registration + display must survive a board audit.
  7. Registrant record retention. Keep the registrant's name, email, and credentials record for at least 180 days after access expires (NAR §II.2.b) — reconcile with the consumer's PIPEDA/Law 25 deletion rights (§5 of identity-consent-model.md; the consent/suppression-proof retention carve-out applies).
  8. The VOW licence belongs to the BROKERAGE, not to us. VOW/IDX data rights are issued to the brokerage of record for specific domains; WiseAI/John is a vendor / authorized data recipient on the brokerage's agreement, exactly as with DDF. We never hold or resell the feed (§9 Q1). [LEGAL]
  9. Province/board scope, never hardcoded. Beckett is on PropTx (Ontario; supports IDX + VOW). Other provinces differ — Quebec runs on Centris/OACIQ and Saskatchewan/QC are excluded from CREA DDF; VOW availability, sold-display rules, and the sold window vary by board. Design the adapter board-agnostic (one board profile per tenant), the way DDF is per-tenant. [verify with board]

The triple identity of the gate (the spine of this whole track): the registration gate is (a) what consumers already expect from HouseSigma/Wahi, (b) the legal mechanism that makes sold display lawful (Competition Bureau v. TREB + VOW rules), and (c) our #1 lead engine — every registrant becomes a consented, tracked lead/contact. One mechanism, three payoffs. Build it as a first-class product surface, not a popup afterthought.


3. The registration gate

A consumer wants to see a sold price → they hit a soft gate (browse active/IDX freely; sold price + history + AVM blur until they register). Registration is fast and free, and it does three jobs at once (§2.2 triple identity).

3.1 What the gate collects (minimum, per VOW rules + CASL)

FieldWhySource rule
NameVOW registrant identityNAR/CREA VOW §II.2
Valid email (verified)VOW identity + the confirming emailNAR/CREA VOW §II.2
Email confirmation (double opt-in)"send an email confirming the registrant agreed to the terms"NAR/CREA VOW §II.2
Terms-of-use acceptance (versioned)non-commercial use, bona fide interest, no-scrapingNAR/CREA VOW §II.2.c
Consumer-broker relationship acknowledgementthe legal hook that permits VOW accessNAR/CREA VOW §II.1
CASL/PIPEDA consent (granular; QC → French + express)the registrant becomes a contactable leadidentity-consent-model.md §3
Phone (optional)HouseSigma uses SMS-verify; optional for us

Auth options: email+password, Google OAuth, or email OTP — same primitives as the agent side, but a separate identity space (§5). HouseSigma gates with a mobile number + SMS code (HouseSigma sign-up); email is the VOW-required minimum, phone is optional.

3.2 The gate as lead engine (do not under-build this)

  • Every registrant is upserted into the contact spine (re_contacts / local_business_contacts) via the existing identity resolver, with source_category='saved_search', source_detail='vow_signup'a value already reserved in the lead-source taxonomy (data-model.md §4).
  • Registration writes a consent event (source='web_form'/double_optin, basis per identity-consent-model.md §3.1) — so the AI front office may follow up within consent, and the universal suppression gate governs it.
  • The new registrant is routed to an agent (Beckett: language/round-robin per auth-rbac.md §3.1) and fires the hot-lead push.
  • Registrant behavioral signal is gold: saved searches, watched areas, and sold-comps they pull become lead-scoring inputs and "facts the AI may use" for the next conversation.

This is the highest-intent lead capture in the product — a registrant is actively pricing a purchase/sale. Treat the gate's analytics + routing as P0 of the track, not a follow-on.


4. Data model extension

Extends the re_* model in data-model.md (which already anticipated this in §1.11 re_saved_searches, §5.1 open-question #6, and Phase 3 "VOW/sold-data track"). This spec resolves open-question #6: a separate re_sold_listings table, not an extension of local_business_listings — because sold data has a different licence, a different feed, a different (deny-by-default) access regime, and far larger volume, and must never share a table the public site reads for active listings (leak risk).

4.1 New / extended entities

re_sold_listings — the synced sold dataset (deny-by-default; never anon-readable). Tenant-scoped because the licence is per-brokerage (mirrors per-tenant DDF storage).

ColumnTypeNotes
iduuid PK
business_iduuid NOT NULL FKthe tenant whose VOW licence covers this row
sourcetext NOT NULL DEFAULT 'vow'enum: vow | public_registry (provenance)
boardtext NULLwhich feed (proptx, …) — not hardcoded
mls_number / vow_idtext NULLboard keys (UNIQUE (business_id, mls_number))
address / unit / city / region / postal_codetext NULL+ address_norm for comp matching
latitude / longitudenumeric NULLradius/polygon comp search
property_type / beds / baths / sqft / lot_size / year_builtcomparability attributes
list_price / sold_price / sold_date / list_datenumeric / datesold_price + sold_date are the unlock
dom / cumulative_dominteger NULLtrue days-on-market
listing_brokerage_nametext NOT NULL"courtesy of" attribution (invariant §2.2.5)
seller_withheldboolean NOT NULL DEFAULT falseopt-out honored (invariant §2.2.4) — never display when true
rawjsonbRESO payload (audit/debug)
synced_at / created_at / updated_attimestamptz

Indexes: (business_id, sold_date DESC), (business_id, postal_code), geo index on (latitude, longitude), (business_id, mls_number).

re_price_history — per-property event log (list/relist/price-change/terminate/sold/back-on-market) powering the price-history chart and true cumulative DOM.

ColumnTypeNotes
iduuid PK
business_iduuid NOT NULL FK
property_keytext NOT NULLmls_number or address_norm
event_typetext NOT NULLenum: listed | price_change | relisted | terminated | expired | sold | leased | back_on_market
pricenumeric NULL
effective_datedate NOT NULL
source / rawtext / jsonb

re_avm_estimates — automated estimate + confidence range (§7). Never "the value."

ColumnTypeNotes
iduuid PK
business_iduuid NOT NULL FK
subject_listing_iduuid NULL FK → local_business_listings(id)when valuing one of our listings
subject_keytext NULLaddress_norm for "what's my home worth"
estimatenumeric NOT NULLthe midpoint
confidence_low / confidence_highnumeric NOT NULLpublished range (trust signal)
confidence_scorenumeric NULL0–1
methodtext NOT NULL DEFAULT 'comp_based'enum: comp_based | third_party
comps_usedjsonb[{sold_listing_id, weight}] — explainability + the AVM facts-used receipt
model_versiontext NULL
disclaimer_versiontext NOT NULLthe "not an appraisal" text shown (§7)
computed_attimestamptz

re_consumer_accounts — the NEW consumer identity (distinct from agent realtor_users/realtor_memberships).

ColumnTypeNotes
iduuid PK
business_iduuid NOT NULL FKthe tenant they registered with (VOW is per-brokerage)
auth_user_iduuid NULL FK → auth.users(id)Supabase Auth, consumer space (§5)
contact_iduuid NULL FK → contact spineevery registrant is a lead (§3.2)
email / email_verified_attext / timestamptzVOW-required confirmed email
display_nametext NOT NULLVOW-required name
phonetext NULLoptional
terms_version / terms_accepted_attext / timestamptzversioned ToU acceptance
relationship_established_at / relationship_basistimestamptz / textthe consumer-broker relationship hook
statustext NOT NULL DEFAULT 'pending_verification'enum: pending_verification | active | suspended | expired
created_at / last_login_attimestamptzretain ≥180 days post-expiry (§2.2.7)

re_saved_searches (extend the existing §1.11 table): add consumer_account_id uuid NULL FK → re_consumer_accounts(id) (the registrant who owns it; keep contact_id for the lead link). Alert types already include new_listing \| price_drop \| just_sold \| open_house \| back_on_market.

re_listing_alerts (new, optional — the alert/digest delivery log): id, business_id, saved_search_id, consumer_account_id, alert_type, listing_id|sold_listing_id, channel (email|sms|push), status, sent_at. One row per delivered alert → feeds the unified timeline + suppression audit.

4.2 Coexistence with active listings

  • Active listings stay on DDF (local_business_listings, source='ddf', already live). Do not dual-source active.
  • Sold lives in re_sold_listings (source='vow'). The public site reads active from local_business_listings; the gated sold UI reads re_sold_listings.
  • A comparable is a query, not a stored entity: given a subject property, select nearby recent re_sold_listings by geo radius/polygon + property-type + size band. (This is why the table is re_sold_listings, resolving the data-model's re_sold_comparables placeholder name.)
  • Decision flag (§9 Q5): PropTx VOW can also serve active (IDX) — if a tenant ever consolidates onto one PropTx feed, the active source could move VOW-side. MVP keeps DDF for active + VOW for sold to avoid disrupting the live DDF sync. [verify with board] whether running DDF (CREA) and a board VOW concurrently is permitted/required.

5. Consumer auth — a separate identity space

The consumer account is a distinct identity type from the agent. auth-rbac.md governs agents (realtor_users + realtor_memberships, capability resolver, commission gates). A consumer is none of that — they log in only to see gated sold data + manage their own saved searches.

Agent (auth-rbac.md)Consumer (this track)
Identity rowrealtor_membershipslocal_businessesre_consumer_accountslocal_businesses
AuthSupabase AuthSupabase Auth (same primitive, separate space)
Can seetenant CRM (scoped), maybe commissionsonly: gated sold data for the tenant they registered with + their own saved searches + AVM
Can NEVER seeany agent CRM table, any other consumer, any commission/financial row
Role claimrole ∈ {agent, team_admin, …}role = 'consumer'

Design (recommended):

  1. One auth.users, two membership tables, two resolvers. Agents resolve auth.uid()realtor_memberships (existing realtor_account_ids(uid) helper). Consumers resolve auth.uid()re_consumer_accounts (a new consumer_account(uid) helper). A uid is one or the other; never let a consumer claim resolve an agent capability (R1 below).
  2. RLS is the load-bearing gate for sold data — unlike the agent CRM (which ships service-role + app-layer first per auth-rbac §3.3), re_sold_listings / re_avm_estimates must be RLS-on from day one: anonno rows; authenticated consumer → only business_id = their account's business_id and only non-withheld rows; agents → their tenant's rows via the agent resolver. A single un-gated public read of a sold price is a VOW-rule + Competition-Bureau-precedent breach, not just a bug.
  3. The public site never reads sold tables directly. Gated sold UI calls a server route that checks the consumer session; the AI front office only states a sold fact when it has a registrant context + a facts-used receipt (ai-guardrails.md §RULE 3 — HO-03 today defers "I don't have sold data"; once VOW ships, the AI may surface sold data only inside an authenticated registrant session, never to an anonymous chat visitor).
  4. get_advisors security lint must be clean on every new sold/consumer table before launch (multi-tenant table with RLS off = P0).

Security risks:

  • R1 — privilege confusion across the shared auth.users. A consumer email that matches an agent email must not auto-elevate. Resolvers are table-specific; the role='consumer' claim is a hint, the membership row is truth (mirrors auth-rbac R4).
  • R2 — service-role bypass. Cron/sync/voice use service-role and skip RLS; the per-tenant + non-withheld + relationship scoping must therefore also live in app code for any path that emits sold data (mirrors auth-rbac R2).
  • R3 — registrant enumeration / credential stuffing. Rate-limit registration + login; the email confirmation (double opt-in) is mandatory; bind sessions per device.
  • R4 — sold data egress. No bulk export endpoint for consumers; throttle sold queries; honor the no-scraping terms with per-account rate limits and bot defenses (compliance-privacy-analytics.md §3).

6. Feed integration — the VOW adapter as a sibling of DDF

The VOW feed is a sibling adapter of src/lib/real-estate/ddf/, not a rebuild. PropTx exposes data over the RESO Web API (OData/JSON, bearer-token, server-to-server) — the same shape ddf/client.ts already speaks (Repliers / PropTx data access; EVNE — RESO Web API). The existing client authenticates with OAuth2 client-credentials against CREA (identity.crea.ca, scope DDFApi_Read); the VOW adapter does the same against the board/PropTx token endpoint with a VOW scope and the brokerage's VOW credentials.

Proposed structure (mirrors ddf/):

File (proposed)MirrorsResponsibility
src/lib/real-estate/vow/client.tsddf/client.tsRESO Web API client; separate VOW_* env (VOW_ENABLED, VOW_CLIENT_ID/SECRET, VOW_TOKEN_URL, VOW_API_BASE_URL, VOW_SCOPE); same BOM/CRLF cleanEnv() discipline; isVowConfigured() gate; throws VowNotAuthorizedError until enabled + credentialed (never fake feed access).
vow/map.tsddf/map.tsRESO sold Propertyre_sold_listings + re_price_history rows.
vow/sync.tsddf/sync.tsManual-safe diff — insert/update/expire only source='vow' rows; never touch manual or ddf. Honor seller_withheld.
vow/reso-types.tsddf/reso-types.tsRESO sold-status field types (close price, close date, status).
triggers/api/real-estate/ddf-sync + /api/cron/ddf-syncowner button + a slower cron (sold data changes less than active; daily is plenty) — /api/real-estate/vow-sync + /api/cron/vow-sync.

Gating (mirrors DDF exactly): every live call gated on VOW_ENABLED=true + per-tenant metadata.vow.authorized=true (set only after the board approves the brokerage's VOW agreement for the specific domain). Inert and throwing until then. The PropTx agreements are DLA + IDX + VOW, submitted per domain (1–3 URLs per agreement), each routed to the broker of record for confirmation before PropTx processes it (RealtyNinja — PropTx data agreements; PropTx VOW data feed).

Sold-window reality: the PropTx VOW feed exposes sold searches ~2 years back (RealtyNinja). To approach the HouseSigma/Wahi multi-year archive, retain synced sold rows over time (and/or supplement with public registry data) — [verify with board] retention/accumulation is permitted under the agreement (some restrict how long feed data may be stored).

Storage / coexistence: sold rows are per-tenant (business_id, synced from that tenant's VOW credentials), matching DDF's per-tenant model and keeping licence isolation clean. A shared board-keyed sold pool with per-tenant authorization joins would be more storage-efficient but risks showing one brokerage's licensed data under another's domain — defer as an optimization with a licensing review (§9 Q6). [LEGAL]


7. AVM — comp-based, with a published confidence range

Stance: build the simplest defensible estimate, and show the range incumbents hide.

  • Method (MVP): comp-based. Compute the estimate from the registrant-visible re_sold_listings comps (nearby, recent, same property-type, size band) — a transparent, explainable model whose inputs are exactly the sold comps the consumer can see. The spread of the comps naturally produces a confidence range; persist the comps + weights in re_avm_estimates.comps_used for explainability and as the AVM's facts-used receipt. Avoid a black-box proprietary model in MVP. A third-party AVM API is a later option (method='third_party') if accuracy demands it. (§9 Q4.)
  • Publish the confidence range as a trust signal. Incumbents tend to hide their accuracy; we show "estimated $X, range $low–$high, based on N recent comps" — honesty as differentiation (matches backend-completeness-audit.md "publish a confidence range — incumbents hide it").
  • Never guarantee or assert a value — this binds the AI and the UI. Per ai-guardrails.md RULE 2: an automated estimate is not an appraisal and not a professional opinion of value. Every AVM surface (the /api/real-estate/home-value endpoint, any "what's my home worth" page, and any AI relay) MUST carry the mandatory disclaimer and the range, MUST NOT present a single point value as the value, and MUST defer to the agent's real CMA. The post-LLM belt hard-fails any AI valuation turn missing the "estimate, not an appraisal" disclaimer (guardrails scenario RA-02). The AVM is a lead magnet that routes to a human CMA, not a substitute for one.

8. Phased activation plan (with dependencies)

VOW activation is gated by the board agreement (external, slowest) and the consumer identity layer (depends on the auth + identity/consent specs). Sequence:

PhaseStepDepends onOwner
5.0Board application + VOW agreement — brokerage (Sutton/Beckett) submits PropTx DLA + IDX + VOW for the WiseAI-hosted domain(s); WiseAI listed as vendor/data recipient; broker-of-record confirms. [LEGAL] [verify with board]nothing technical; this is the long poleFounder + brokerage + counsel
5.1VOW feed adaptervow/client.ts + map.ts + sync.ts + reso-types.ts; re_sold_listings + re_price_history migration (founder-gated, additive, service-role-grant-only); inert until VOW_ENABLED + metadata.vow.authorized5.0; the re_* data-model migration (Phase 6 of build-roadmap)Eng
5.2Consumer identity + registration gatere_consumer_accounts; consumer Supabase Auth space; RLS-on sold tables; terms/relationship/consent capture wired to the consent ledger; registrant → re_contacts lead + routing + hot-lead push5.1; auth-rbac.md (auth primitive) + identity-consent-model.md (consent ledger + suppression gate)Eng
5.3Gated sold UI — sold price + sold comps + price/relisting history + true DOM, behind the gate; brokerage attribution + seller-opt-out honored; soft-gate UX (blur → register)5.1 + 5.2Eng + Design (see VOW consumer mockups, task #18)
5.4Saved searches + alerts — extend re_saved_searches (consumer link); re_listing_alerts; price-drop / just-sold alerts (new on this track) + watched-area digests. Alerts are consumer-requested + consent-gated; no cron campaign sends — alert delivery is transactional, still passes the universal suppression gate (identity-consent-model.md §4.4)5.1 + 5.2 (+ 5.3 for sold alerts)Eng
5.5AVM — comp-based estimate + confidence range over re_sold_listings; re_avm_estimates; wire /api/real-estate/home-value; disclaimer + belt enforcement5.1 (sold data) + 5.3Eng
5.6Compliance + board-audit hardening — registrant record retention (≥180d) vs PIPEDA/Law-25 deletion; no-scraping throttles + anti-bot; MLS audit-access path; Canadian-region data residency; counsel/brokerage sign-offall aboveFounder + counsel

Critical path: 5.0 (board agreement) is the long pole and is not an engineering task — start it first and in parallel. Engineering 5.1→5.5 can be built inert behind the gate before 5.0 returns, exactly as DDF was built inert before authorization.


9. Open items needing founder / counsel / board

  1. [LEGAL] Who holds the VOW licence + applies? Confirm the brokerage (Sutton/Beckett) holds the IDX/VOW agreement and lists WiseAI/John as the authorized vendor/data recipient for the hosted domain(s) — we cannot hold or resell the feed. Who drives the PropTx application (broker of record must confirm)?
  2. [LEGAL] VOW agreement terms — sold-display obligations, seller opt-out handling, "courtesy of" attribution, the no-commingling / no-redistribution clauses, MLS audit-access, and how they constrain our UI + AI. Counsel + brokerage review before any registrant sees a sold price.
  3. [verify with board] Sold-history window + retention — PropTx VOW feed is ~2 years; can we retain/accumulate synced rows (or supplement with public registry) to reach the 10–21-year archive consumers expect, or is retention capped? Sets the honest promise on the sold UI.
  4. AVM method + liability — comp-based (recommended, explainable) vs a third-party AVM API; how the disclaimer + confidence range bound liability; do we ever show an AVM for a home the consumer doesn't own (privacy optics)? [LEGAL] on the "what's my home worth" flow for non-owners.
  5. Alert scope in MVP — which alert types ship first (new-listing is DDF-only and cheapest; price-drop/just-sold need VOW), default frequency caps, and confirming alert delivery is "transactional/consumer-requested," not a campaign send (no-cron-sends rule).
  6. [LEGAL] Sold-storage model — per-tenant copies (recommended, clean licence isolation) vs a shared board-keyed pool (storage-efficient, licence-risky). Confirm concurrent DDF (CREA active) + board VOW (sold) operation is permitted, or whether a tenant must consolidate onto one PropTx feed.
  7. Data residency — VOW + consumer PII in the shared Supabase instance; confirm Canadian-region hosting posture for this data class (ties to compliance-privacy-analytics.md + the audit's "Canadian-region hosting decision").
  8. Province expansion — Beckett is PropTx/Ontario; the adapter must stay board-agnostic for future provinces (QC = Centris/OACIQ, different rules; SK/QC excluded from DDF). Don't bake Ontario assumptions into the sold schema or the gate copy.

10. See also

  • data-model.md — the re_* tables this extends; resolves its §5.1 open-question #6 (separate re_sold_listings) and Phase-3 "VOW/sold-data track" line.
  • auth-rbac.md — agent identity; the consumer space here is deliberately separate.
  • identity-consent-model.md — the consent ledger + universal suppression gate every registrant + alert passes through.
  • ai-guardrails.md — the AVM "not an appraisal" disclaimer (RULE 2) and sold-fact honesty (RULE 3, HO-03) the AI must obey; sold facts only inside an authenticated registrant session.
  • backend-completeness-audit.md — the Canadian feature bar + the sold-data/VOW caveat this track closes.
  • compliance-privacy-analytics.md — per-client legal/footer, anti-bot, Canadian hosting.
  • build-roadmap.md — this is Phase 5.

Sources