WiseAI Realtor — Active Business Hub (Deals) Expected Output Spec
⛔ STATUS: DRAFT — NOT APPROVED. CLAUDE.md Rule #17 (HARD GATE) is NOT satisfied.
Stage-1 agent research, pre-populated from the realtor design docs + the
deals.htmlmock. Do not build the customer-facing screen until the founder approves and confirms the open items in a Stage-2 interview.
Sourced from (read-only, 2026-06-29):
data-model.md§1.4 (re_deals/re_deal_parties— transactions, key dates, conditions; commission columns exist in the data model but are deferred per the A2 locked decision),design-direction.md(Listings/board archetype + pipeline component + anti-patterns),backend-completeness-audit.md(Active Business Hub NEED; FINTRAC/e-sign OUT of scope — "integrate/hand off, never rebuild"), andrealtor-mockups/deals.html. Format matched toacceptance/ai-front-desk.md.
0. Scope — what this spec covers, and what it does NOT
This spec covers the Active Business Hub (Deals) — the transactions workspace:
a Kanban pipeline by deal status, a Board/Table view switch, and a deal
drawer (money strip, Aria summary, parties, key-date reminder timeline,
conditions checklist, commission [deferred], linked records, FINTRAC flag,
activity). Sibling of realtor-leads-mvp.md (the contact/lead pipeline — a
different object: a deal is a transaction, a contact is a person; a
contact can have multiple deals over years, data-model.md §1.1/§1.4).
Does NOT cover, and the build must NOT rebuild (audit "OUT of scope — integrate/hand off, never rebuild"): trust accounting, deposits, commission disbursement, the FINTRAC ID system-of-record, the binding agreement of purchase & sale, e-signatures, regulated disclosure documents. WiseAI tracks milestones + reminders only; the money, the legal record, and the FINTRAC ID live in the brokerage software (the mock's footer states this verbatim). The hub surfaces a reminder/flag at most and links out.
Build posture: the deals hub is NEW. It reads the proposed re_deals/
re_deal_parties spine (migrate-before-use); nothing reads them yet. A deal is
spawned/attached when a contact reaches won (data-model.md §2.2).
1. The mock screen this spec governs + what it reads
Governs: realtor-mockups/deals.html — a horizontal Kanban board
(New → Active → Offer → Conditional → Firm/Sold → Closed) with per-column **count
- summed value + color bar**; cards show address, side chip (Buy/Sell), client, price, the next key milestone, language chip, days-in-stage; a Board ⇄ Table switch; AI: Co-pilot toggle; and a right deal drawer (Conditional deal for 14 Riddell St) with: money strip (sale price / Est. GCI [deferred, §3] / closing), Aria's summary, Parties, Key dates & reminders timeline, Conditions checklist, Commission split [deferred, §3], Linked records, a Compliance block (FINTRAC flag-only + the out-of-scope/"open in brokerage system" note), Activity, and footer actions (Log update / Add reminder / Advance stage).
Reads (target-state CRM-spine APIs — WS2; verify exact route names; do not fabricate):
| Surface | Underlying read |
|---|---|
| Board columns | re_deals.status (prospect/active/offer_out/conditional/firm/closed/fell_through), counts + summed expected_close_value (role-scoped) |
| Card side chip | re_deals.side (buy/sell/lease_tenant/lease_landlord/referral) |
| Key milestone / dates | re_deals date columns (offer_date, acceptance_date, condition_dates[], conditions_waived_date, closing_date, possession_date) |
| Drawer parties | re_deal_parties (role/contact_id/snapshot) |
| Conditions checklist | re_deals.condition_dates jsonb [{label,due_date,status}] |
| Key-date reminders | re_tasks (type=deadline/document, due_at) tied to the deal |
| Aria summary | re_deals rollup / re_contacts.ai_summary |
| Activity | re_interactions WHERE deal_id = … |
| Linked listing/contact | local_business_listings, re_contacts |
| Commission/GCI | DEFERRED (A2) — see §3; not part of MVP |
Demo tenant: Terry & Sheri Real Estate (…0c01, terry-and-sheri). Mock
deals are demo content; NEVER a real customer (feedback_never_modify_customer_data).
2. The AI-Bridge / honesty anchor
- Aria summarizes a deal; she does not practice law or finance. The deal
Aria-summary recaps status/conditions/dates and proposes an agent next
action (e.g. "Confirm TD financing approval before Jun 28"). It must NOT give
legal advice on conditions/waivers, quote a payout, or assert a value
(
ai-guardrails.mdRULE 2). Any reminder Aria sends a client is honest and attributed to AI. - Honest milestones only. Dates/conditions reflect what the agent logged; nothing fabricated. "Deposit · held in brokerage trust" is a status flag, not a money movement WiseAI performs.
3. Commission / GCI — DEFERRED (A2), and role-gated if it ever lands
⚠️ NEW INCONSISTENCY — flagged, not silently resolved. The
deals.htmlmock shows GCI on every card and a full Commission split block (Est. GCI $15,998, agent 85% / brokerage 15%, agent net $13,598). But the A2 locked decision is "commissions deferred" (memoryproject_wiseai_realtor_system), and this batch's directive is "no commission columns in re_deals" for the MVP.data-model.md§1.4 proposes commission columns onre_dealsgated toFINANCIAL_ROLES— that proposal is deferred, not MVP. Reconcile:
- MVP: the deals hub ships without persisted commission/GCI. The
re_dealsMVP migration includes no commission columns; the board cards and drawer omit GCI/commission (or show "—"). Pipeline value usesexpected_close_value/ sale price, not commission. - If/when commissions land (post-MVP, founder-gated): commission/GCI is gated
by capability (
rbac.ts): onlybrokerage_owneredits (commissions:amount:edit);broker_admin/team_admin/brokerage_ownerread at their scope (brokerage/team); the owningagentreads their OWN deal's commission (commissions:amount:read:own);isa/transaction_coordinator/marketing_assistant/external_partnerhave no commission capability. A peer's commission never shows to an agent. Enforced at the API + query layer; every commission read logged (data-model.md§5.2); a contract test liketier-config.contract.test.tsguards it. - The Stage-2 interview must confirm: defer GCI entirely for MVP (recommended), or ship GCI capability-gated from day one.
Other role scoping (applies regardless of commission):
| Bucket | Roles (rbac.ts) | Deals scope |
|---|---|---|
| Brokerage management | brokerage_owner, broker_admin (brokerage scope) | All deals across the brokerage; brokerage pipeline value |
| Team management | team_admin (team scope) | The team's deals; team pipeline value |
| Agent / ISA | agent, isa (own scope) | Own deals (owner_agent_id/co_agent_id); not a peer's |
| Support / external | transaction_coordinator (deals + team-read), marketing_assistant, external_partner (bounded) | Scoped/read-only; never commission capability |
4. Expected outputs
4.1 — Kanban board by deal status (+ Board/Table switch)
Should see:
- Columns New → Active → Offer → Conditional → Firm/Sold → Closed, each header
with stage name, count, and summed value + a color bar (colorblind-safe,
label-paired). Cards are draggable between stages; a drag durably updates
re_deals.status(optimistic, skeleton — not a spinner) and writes astatus_changere_interaction. A Board ⇄ Table switch shows the same set as a sortable table. - Each card: address, side chip (Buy/Sell), client name, price (with label: target/est. value/budget/list/offer), the next key milestone (e.g. "Waiver due Jun 30 · 3d", "Closing Aug 14 · 48d"), language chip, days-in-stage. The Closed column gets the gold celebration treatment (won = gold accent, per design-direction "gold = celebration only").
Should NOT see:
- GCI/commission on cards in the MVP (§3).
- A drag that doesn't persist; a value sum that leaks a peer's commission or
another agent's deals to an
agent(who reads only their OWN commission,read:own). - A "showing booked" claim implying the AI scheduled it (§6 carry-forward).
Success: the agent sees every live transaction by stage with its next deadline, and can advance a deal by drag — durably (verify at ≥2 timepoints).
4.2 — Deal drawer: parties + key-date reminders + conditions
Should see (on card click):
- A money strip (sale price / closing; GCI omitted in MVP §3).
- Aria's summary of the deal (status + remaining conditions + next action).
- Parties (
re_deal_parties): the client (you represent), co-op agent + brokerage, your agent — each with role + a "you repr."/"listing side" tag. - Key dates & reminders timeline: offer accepted, deposit received (status
flag), financing condition due (with a reminder toggle), inspection waiver
due, closing — each with status color and a 🔔 reminder indicator. Reminders
are
re_tasksand surface in Calendar & Tasks (realtor-tasks-calendar-mvp.md) and Notifications (realtor-notifications-mvp.md). - Conditions checklist ("1 of 3 cleared": deposit cleared, financing due, inspection scheduled) with cleared/due/scheduled states.
- Linked records (listing, contact) deep-linking to those screens.
- Footer actions: Log update, Add reminder, Advance stage.
Should NOT see:
- WiseAI performing a money movement, generating the APS, or storing an e-signed record (those are out of scope — §4.3).
- Commission split block in MVP (§3).
Success: the agent opens a deal and sees, in one drawer, who's involved, what must happen by when (with reminders set), and which conditions remain — without leaving for the brokerage system except where required.
4.3 — Compliance: FINTRAC flag-only + out-of-scope hand-off
Should see:
- A FINTRAC ID verification row that is a status flag only ("Requested" / "Verified") with an explicit "no ID stored here" note — WiseAI never stores the FINTRAC identity record.
- An out-of-scope card: "Documents & e-sign handled in your brokerage system" with an Open in brokerage system link — the APS, e-signatures, trust deposits, commission disbursement, and the FINTRAC ID record live in the brokerage software (audit; mock footer).
Should NOT see:
- Any UI that captures/stores a FINTRAC ID document, generates a binding APS, or collects an e-signature as a legal record (rebuilding brokerage back-office is explicitly forbidden — audit).
Success: compliance items are surfaced as flags + hand-offs, never rebuilt.
5. Empty / loading / error states
| State | Expected output |
|---|---|
| No deals | Demo-seeded board + onboarding nudge ("Won leads become deals here — mark a lead Won to start a transaction") — never a blank board (anti-pattern #6). |
| Empty column | Column header shows 0 + summed $0; column renders, not collapsed. |
| Loading | Board card / drawer skeletons, not a spinner (anti-pattern #7); optimistic on drag. |
| Read/advance error | Inline "Couldn't update stage — retry"; the card reverts to its prior column (no silent loss). |
| Brokerage-system link unconfigured | "Open in brokerage system" shows a "connect your brokerage system" hint rather than a dead link. |
6. Carried-forward constraints (consistent across the batch)
- Aria does NOT book/schedule. Anywhere the board/drawer shows a "showing"
(e.g. a card's "3 showings booked Sat"), it is a showing REQUEST captured
pending agent confirmation — never "booked" by the AI — until a scheduler
ships and the founder decides (
ai-front-desk.mddecision 4; audit "scheduler named, not designed"). Reframe/relabel; do not claim the AI confirmed a booking. - SMS is consent-gated and OFF by default (no unattended sender) pending the
founder's "SMS in scope" confirmation; crisis/safety is NEVER gated
(
ai-guardrails.mdRULE 5). - No realtor pricing exists — the hub gates by role/module, never by price.
- Honest metrics only; "Not measured" when unknown.
7. Accessibility (AODA → WCAG 2.1 AA)
- Kanban: columns/cards are keyboard-navigable; drag has a keyboard
alternative (a "move to stage" menu); stage colors are paired with labels
(colorblind-safe); summed values use
tabular-nums. - Drawer: traps + restores focus; Esc closes; the conditions checklist uses real checkbox semantics with state; the key-date timeline is a semantic list.
- Contrast: ≥4.5:1 text; gold (won/celebration) is accent with AA text over tint; teal actions/links meet AA.
- Reminders/flags convey state by text + icon, not color alone.
- Motion: drag/skeleton respects
prefers-reduced-motion.
8. Acceptance checklist (QA runs on the deployed URL)
Behavioural verification on wiseaiagency.com (real host) against the demo
tenant (…0c01); never "build passes". Sample at ≥2 timepoints; assert change.
// Board + table
test.fixme('board shows New→…→Closed with count + summed value + color bar; Board⇄Table shows the same set', () => {});
test.fixme('dragging a card durably updates re_deals.status and writes a status_change interaction', () => {});
test.fixme('Closed column uses the gold celebration treatment; stage colors are label-paired (colorblind-safe)', () => {});
// Commission deferred + RBAC
test.fixme('MVP board/drawer show NO commission/GCI (deferred A2); pipeline value uses sale/expected value', () => {});
test.fixme('if GCI ships, it is capability-gated: brokerage_owner edits; broker_admin/team_admin/owning-agent read at scope; isa/support/external none; a peer commission never shows; API-enforced + read-logged', () => {});
test.fixme('an agent sees only own deals; cannot see a peer’s deal or value', () => {});
// Drawer
test.fixme('deal drawer shows parties, key-date reminder timeline, conditions checklist, linked listing+contact', () => {});
test.fixme('a key-date reminder is a re_task that also surfaces in Calendar & Tasks and Notifications', () => {});
// Out-of-scope compliance
test.fixme('FINTRAC is a status flag only ("no ID stored here"); e-sign/APS/commission-disbursement hand off to brokerage system', () => {});
// Carried-forward
test.fixme('any "showing" on a deal reads as a captured REQUEST pending agent confirmation, never AI-"booked"', () => {});
// States + a11y
test.fixme('empty/loading/error states render per §5; never blank board, never a spinner', () => {});
test.fixme('board is keyboard-navigable with a move-to-stage alternative; drawer traps+restores focus; reduced-motion honored', () => {});
9. Guardrails for agents building against this spec
- Rule #17 not satisfied — do not build until founder approval.
- Milestones + reminders ONLY — never rebuild trust accounting, FINTRAC ID system-of-record, APS/e-sign, or commission disbursement (audit). Surface a flag, link out.
- Commission is deferred (A2) — no commission columns in the MVP
re_dealsmigration; if it lands later it is capability-gated (rbac.ts:brokerage_owneredits;broker_admin/team_admin/owning-agentread at scope;isa/support/external none) + read-logged (data-model.md§5.2). Reconcile thedata-model.md§1.4 commission proposal with A2 before building (flag for founder). - Migrate-before-use —
re_deals/re_deal_partiesare proposals; verify columns viainformation_schema(Rule #18); founder-gated DDL. - Aria books nothing; SMS off-by-default + consent-gated; crisis never gated; honest metrics; verify on the real host; behaviour not DOM presence; evidence-or-nothing.
- If code diverges, update the spec first (founder approval), then the code.
End of spec. STATUS: DRAFT — NOT APPROVED. Open items for Stage-2: (1) defer GCI
entirely for MVP vs ship it capability-gated (reconcile data-model.md §1.4 vs A2);
(2) the exact deal-stage set + which maps to re_deals.status; (3) how deep the
brokerage-system hand-off links go (deep-link vs generic).