Skip to main content

WiseAI Realtor — Reviews Manager 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 Reviews tab of reviews-automations.html. 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): the already-approved + shipped acceptance/reviews-engine-mvp.md (the owner-pressed, dry-run, CASL/FTC engine — Reviews Engine Phase 2 shipped via PR #1017), do-not-reinvent.md (reviews tables + /r/[token] + ReviewRequestsTab exist), design-direction.md, and the Reviews tab of realtor-mockups/reviews-automations.html.


0. Scope — what this spec covers, and what it does NOT

This spec covers the Reviews MANAGER screen — the command-center surface that restores Reviews to the realtor nav (the audit flagged it "shipped in prod — dropped from nav") and exposes the shipped engine: the review funnel, platform targets, the owner-pressed request list, CSV past-client import, testimonial curation → website, and response drafting.

This spec BUILDS ON and does NOT duplicate acceptance/reviews-engine-mvp.md — the approved + shipped engine spec that owns the behaviour + compliance (owner-pressed sends with dry-run default; the CASL EBR consent gate; the suppression/opt-out spine; the auto-stopping cadence; the NO-gating rule; the no-incentives/no-fake/no-cross-copy rules; the Places-API storage constraint; the per-vertical testimonial posture). This screen is the manager UI over that engine; where this spec mentions a send, a consent check, or auto-stop, the behaviour is reviews-engine-mvp.md.

Does NOT cover: the Automations / drip library (the other tab of reviews-automations.html) — covered by realtor-tasks-calendar-mvp.md §4.3; the public /s/[slug]/reviews page render (website specs); the /r/[token] private-feedback page (kept as-is, non-gating — reviews-engine-mvp.md).

Build posture: the Reviews Engine already shipped (PR #1017; owner engine, no cron, dry-run, CASL — do-not-reinvent.md, project_beckett_sutton_realestate). This spec is the manager surface + nav restoration, extending the existing ReviewRequestsTab. Do not rebuild the engine.


1. The mock screen this spec governs + what it reads

Governs the Reviews tab of realtor-mockups/reviews-automations.html: a dry-run / owner-pressed banner ("nothing is sent automatically … you press Send … no cron … consent & suppression re-checked before every touch"); a Review funnel (Requests sent → ClickedPublic review / Private feedback, with the honest note "Open rate tracked but never shown as engagement" + "same public ask to every eligible client — no happy→public/unhappy→private routing"); Platform targets (Google priority 1, RateMyAgent priority 2 — note rate-my-agent.com, reviewer-initiated Google cross-post OK / never copy text, Facebook off); a Review requests table (Client, Consent (EBR), Target, Status [Draft·approved / Sent·touch 1 / Clicked / Reviewed / Private feedback / Opted out], Last touch, Actions [Send / Reviewed / Opt-out]) with a "Send approved batch (N)" button and a CASL footer (sender name + current mailing address + one-tap unsubscribe); CSV import (past clients, 24-mo EBR, import summary imported/skipped/rejected); a Testimonials gallery (collect-only by default; republished with client consent + RECO registrant ID; feeds the website).

Reads/writes (verify exact route names; do not fabricate):

SurfaceUnderlying store
Funnel (sent/clicked/reviewed/private)local_business_review_requests statuses + local_business_message_logs
Platform targetslocal_business_review_targets (NEW) seeded from setup_profiles.google_review_url
Request list + Send/Reviewed/Opt-outlocal_business_review_requests (status, cadence, reviewed_detected_via)
Consent (EBR)ebr_basis/ebr_date (consent computed at send time)
Suppression / opt-outlocal_business_client_suppressions (NEW)
CSV importlocal_business_client_imports (NEW)
Testimonialstestimonial store → website (realtor-website-builder-mvp.md Reviews page)
Link to contactre_contacts (the review request's long-lived person)

Demo tenant: Terry & Sheri Real Estate (…0c01, terry-and-sheri, vertical real_estate) — the canonical Beckett demo (reviews-engine-mvp.md §3). NEVER a real customer (feedback_never_modify_customer_data).


2. The AI-Bridge / honesty anchor (and the engine's compliance spine)

Per reviews-engine-mvp.md §2 + ai-bridge-principle.md — surfaced, never weakened:

  • NO gating, ever. The same public ask goes to every eligible client — no happy→public / unhappy→private routing; the /r/[token] private-feedback surface never gates the public ask. The manager UI must NOT add sentiment routing.
  • No incentives; no fake / no cross-copy. No reward field; the engine never drafts/pre-fills/submits review content; never auto-copies text to RateMyAgent.
  • Honest metrics. The funnel shows clicks, not opens — opens are tracked for deliverability only and never shown as engagement (the mock states this).
  • Owner-pressed, dry-run default, no cron. A human presses Send per batch; consent + suppression re-checked before every touch; no cron auto-sends to clients (feedback_never_cron_send_campaigns).

3. Role-based visibility

BucketRolesReviews scope
Brokerage / team managementbrokerage_owner, broker_admin, team_admin (brokerage/team scope)Full manager: targets, send approved batch, import, testimonial curation, responses
Agent / ISAagent, isa (own scope)Own clients' requests + send per policy (still owner/founder-blessed sends)
Support / externalmarketing_assistant, transaction_coordinator, external_partner (bounded)marketing_assistant curates testimonials/content per policy; view/scoped otherwise; cannot press Send; external_partner read-only

The send gate never lifts regardless of role — a human at the business presses Send; agents don't get an "auto-send" capability (reviews-engine-mvp.md Decision 1).


4. Expected outputs

4.1 — Review funnel (honest: clicks, not opens) + nav restoration

Should see:

  • Reviews restored to the realtor nav (it was dropped — audit P1).
  • A funnel: Requests sent → Clicked → Public review / Private feedback, with a clear "clicks, not opens" honesty label and the no-gating statement. Open rate may be shown only as a deliverability footnote, never as engagement.

Should NOT see:

  • "Opened / Delivered" presented as engagement (honest-metrics rule).
  • Any happy→public / unhappy→private routing in the funnel framing.

Success: the owner sees real sent/clicked/reviewed/private counts; the funnel reads honestly.


4.2 — Platform targets (Google + RateMyAgent; no cross-copy)

Should see:

  • Managed targets: Google (priority 1; Place ID stored, write-review link built at send), RateMyAgent (priority 2; rate-my-agent.com — reviewer-initiated Google cross-post OK, we never copy text), Facebook (off/tertiary). Each with rating + count + enable/priority.

Should NOT see:

  • An "auto-copy this review to other platforms" control (cross-copy banned).
  • ratemyagent.com (un-hyphenated = unrelated company) — the hyphen is load-bearing (reviews-engine-mvp.md §4.2).

Success: the owner manages multi-platform targets; the engine never copies review text.


4.3 — Owner-pressed request list (Send / Reviewed / Opt-out, dry-run)

Should see:

  • A request list: client, Consent (EBR) (e.g. "Purchase · Apr 2026"), target, status (Draft·approved / Sent·touch 1 / Clicked / Reviewed / Private feedback / Opted out), last touch, and actions: Send (on approved drafts), Reviewed (operator-marked auto-stop), Opt-out.
  • A "Send approved batch (N)" control — the owner presses it; dry-run is ON by default; consent + suppression are re-checked before every touch; a terminal/opted-out row shows no further touch.
  • A CASL footer on every email: sender name (Team Beckett), a current mailing address, and a one-tap unsubscribe — opt-outs honored immediately + persist across batches; no date / lapsed EBR → no send.

Should NOT see (HARD — engine compliance):

  • Any cron / unattended send to a client; a human presses Send (feedback_never_cron_send_campaigns, feedback_db_writes_ok_sends_need_blessing).
  • A send to a suppressed/opted-out/EBR-lapsed client (re-checked before each touch).
  • A reminder after the request reached reviewed/opted_out (auto-stop fires).
  • ⚠️ Carried-forward: SMS request steps shown as a live default. The engine is email-first; SMS is OFF by default + consent-gated until the founder confirms SMS-in-scope (reviews-engine-mvp.md §1.3 / §7). The manager shows SMS as "coming soon", not an active sender.

Success: the owner approves + presses Send on a batch (dry-run by default), auto-stop fires on Reviewed/Opt-out, and no suppressed/lapsed client is ever sent.


4.4 — CSV past-client import (24-mo EBR)

Should see:

  • A CSV import (name, email, phone, transaction date), last 24 months only (CASL EBR), with an import summary: imported (staged as drafts) / skipped (duplicate / lapsed / suppressed) / rejected (no date). Imported rows are staged only — nothing sends until the owner approves the batch.

Should NOT see:

  • A row without a transaction date becoming sendable (rejected — no date, no send).
  • An out-of-window contact enqueued for sending; an import auto-sending anything.

Success: a mixed CSV imports with correct accept/skip/reject counts; valid rows stage as drafts; nothing sends until approval.


4.5 — Testimonial curation → website + response drafting

Should see:

  • A Testimonials gallerycollect-only by default; a testimonial is republished to the website only with client consent + the RECO registrant-ID + CREA material-connection disclosure (reviews-engine-mvp.md §5.7). "On website ✓" / "Add to site" affordances feed the public Reviews page (realtor-website-builder-mvp.md).
  • Response drafting: for a private feedback item ("Read & reply") or a public review, the owner can draft a response — the AI may help draft, but the owner presses send/post (no auto-reply); responses follow the no-advice / honesty guardrails.

Should NOT see:

  • A testimonial republished without consent + registrant-ID + disclosure.
  • An auto-posted review response (owner-pressed only).

Success: consented testimonials publish with the required RECO/CREA disclosure; the owner drafts + sends review responses, never auto-posted.


5. Empty / loading / error states

StateExpected output
No requests yetHonest "No review requests yet" + a "create your first request / import past clients" CTA — never fabricated funnel numbers (reviews-engine-mvp.md §4.6).
LoadingFunnel / list / gallery skeletons, not a spinner (anti-pattern #7).
Send/import errorInline retry; drafts preserved; nothing partially sent.
Suppressed/opted-out clientRow shown terminal ("Opted out · no further touch"), actions disabled.
No platform targetPrompt to add a Google target (seeded from google_review_url); no send without a target.

6. Carried-forward constraints (consistent across the batch)

  • Owner-pressed sends, dry-run default, NO cron — the gate that never lifts.
  • SMS OFF by default + consent-gated ("coming soon") until SMS-in-scope confirmed; crisis/safety never gated.
  • Aria does NOT book/schedule (N/A to reviews, but consistent).
  • Role enum (rbac.ts — implemented source of truth): agent | team_admin | transaction_coordinator | broker_admin | brokerage_owner | marketing_assistant | isa | external_partner (scopes own|team|brokerage) — but the send gate never lifts for any role.
  • No realtor pricing; honest metrics only (clicks, not opens); language never hardcoded (Punjabi-client requests use the contact's language).
  • No gating / no incentives / no fake / no cross-copy (engine compliance).

7. Accessibility (AODA → WCAG 2.1 AA)

  • Funnel has a text/table equivalent; not color-only.
  • Request table: real semantics; status conveyed by text; Send/Reviewed/ Opt-out are labelled buttons with confirmation for Send.
  • CSV import dropzone keyboard-operable with a browse fallback; the import-summary is text.
  • Testimonials gallery + response drafting keyboard-operable; consent/registrant state is text.
  • Contrast ≥4.5:1; gold accent only; teal actions meet AA; reduced-motion honored.

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.

// Funnel + nav + honesty
test.fixme('Reviews is restored to the nav; funnel shows sent/clicked/reviewed/private — clicks, not opens', () => {});
test.fixme('no happy→public / unhappy→private routing; same public ask framing; opens shown only as deliverability footnote', () => {});

// Targets
test.fixme('Google + rate-my-agent.com targets managed; NO auto-copy-to-other-platforms control; never ratemyagent.com', () => {});

// Owner-pressed sends (engine compliance)
test.fixme('"Send approved batch" requires a human press; dry-run ON by default; consent+suppression re-checked each touch', () => {});
test.fixme('NO cron/unattended send to a client; suppressed/opted-out/EBR-lapsed clients are never sent', () => {});
test.fixme('marking Reviewed/Opt-out auto-stops the cadence (no further touch); CASL footer present (name+address+unsubscribe)', () => {});
test.fixme('SMS request steps are OFF by default ("coming soon"), not an active sender, until SMS-in-scope', () => {});

// Import + testimonials + responses
test.fixme('CSV import: no date → rejected; lapsed/dup/suppressed → skipped; valid → staged drafts (not sent until approved)', () => {});
test.fixme('a testimonial republishes to the website ONLY with consent + RECO registrant-ID + CREA disclosure', () => {});
test.fixme('review responses are owner-pressed (AI may draft); never auto-posted', () => {});

// States + a11y
test.fixme('empty/loading/error/suppressed/no-target states render per §5; no fabricated funnel numbers', () => {});
test.fixme('funnel has a text equivalent; table semantics + labelled actions; Send confirms; reduced-motion honored', () => {});

9. Guardrails for agents building against this spec

  • Rule #17 not satisfied — do not build until founder approval.
  • Build ON the shipped Reviews Engine (reviews-engine-mvp.md, PR #1017) + the existing ReviewRequestsTab / /r/[token] — do NOT rebuild the engine or re-specify its compliance; this is the manager surface + nav restoration.
  • Owner-pressed, dry-run, no cron is the gate that never lifts — for any role.
  • No gating / no incentives / no fake / no cross-copy / clicks-not-opens / rate-my-agent.com (hyphen) — engine compliance, surfaced not weakened.
  • SMS off-by-default + consent-gated ("coming soon"); crisis never gated; language never hardcoded; testimonials republish only with consent+registrant-ID; verify on the real host; evidence-or-nothing.
  • Migrate-before-use — review targets/suppressions/imports columns per reviews-engine-mvp.md §6 (verify via information_schema, Rule #18; founder-gated).
  • 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) confirm SMS review requests stay out-of-scope (email-first) for the realtor MVP; (2) how much AI-assist is allowed in response drafting (draft-only, owner posts); (3) the testimonial→website consent/registrant-ID capture flow; (4) link review requests to re_contacts vs keep on the flat request table for now.