a4cc4cdb0f
Add UC-04 (conversational SSP first hour) and UC-05 (ongoing relationship) structured as use cases per Ty's direction. Update ssp-refined.md with decision record, revised intent/scope, conversational flow diagram, and revision history. Co-authored-by: Ty <tybala@outlook.com> Signed-off-by: Ty <tybala@outlook.com>
530 lines
20 KiB
Markdown
530 lines
20 KiB
Markdown
# Self-Service Portal (SSP) — Refined Spec
|
||
|
||
**Status:** Draft (ssp-refinement branch)
|
||
**Author:** Bumble (research), Buzz SouthPaw (engineering review)
|
||
**Date:** 2026-07-29
|
||
**Supersedes:** `docs/product/ssp.md` (thin intent doc)
|
||
|
||
**Source documents:**
|
||
- [Canonical Strategy](../strategy/CANONICAL_STRATEGY.md) — product definition, priorities, scope
|
||
- [UC-01: Endpoint Activation](./use-cases/uc-01-endpoint-auto-repair.md) — operating use case
|
||
- [UC-04: Conversational SSP — First Hour](./use-cases/uc-04-conversational-ssp-first-hour.md) — conversational onboarding
|
||
- [UC-05: Conversational SSP — Ongoing](./use-cases/uc-05-conversational-ssp-ongoing.md) — ongoing relationship
|
||
- [Owner MCP](../owner-mcp.md) — MCP tool definitions
|
||
- MVP scope (Idea research channel, 2026-07-29) — in/out decisions
|
||
- Product decisions (SSP Refinement channel, 2026-07-29) — five decision record (below)
|
||
|
||
---
|
||
|
||
## 1. Intent
|
||
|
||
The SSP is the activation experience for Model 1 (individual local businesses). It turns a business owner's raw info into a live, AI-discoverable MCP endpoint through a **conversational interface** — no forms, no wizards.
|
||
|
||
The owner describes their business in natural language, verifies ownership, receives a presence audit, and gets actionable recommendations — all through a ChatGPT-like experience at GeoLocal.io.
|
||
|
||
**Two phases, one relationship:**
|
||
- **The First Hour** (UC-04): Verification, presence audit, initial recommendations, guided setup
|
||
- **The First Month+** (UC-05): Ongoing monitoring, data updates, periodic reports, seasonal guidance
|
||
|
||
**One line we will not blur:** the conversational SSP is the **only activation path** — no form-based fallback. Chat replaces forms entirely.
|
||
|
||
---
|
||
|
||
## 2. Scope (MVP)
|
||
|
||
One conversational flow, zero forms. The goal is the smallest shippable thing that lets one real business owner go from "tell me about my business" to "discoverable by AI" — all through chat.
|
||
|
||
### In (MVP)
|
||
|
||
- Conversational welcome and discovery (natural language input)
|
||
- Ownership verification (OTP via email)
|
||
- Presence audit (automated, multi-platform)
|
||
- Actionable recommendations (ranked, platform-specific)
|
||
- Guided setup (conversational data capture, pointer install, preflight)
|
||
- Session persistence (resume later)
|
||
- Landing page with animated demo + "Get Started" CTA
|
||
|
||
### Out (deferred)
|
||
|
||
- OAuth / SSO
|
||
- Ingestion pipeline (continuous sync)
|
||
- Genre packs beyond basic category
|
||
- Telemetry dashboard
|
||
- Partner handoff flow
|
||
- Voice input
|
||
- Multi-language support
|
||
- Multi-business accounts
|
||
- Form-based fallback (chat is the only path — see decision record)
|
||
|
||
---
|
||
|
||
## 2.5 Product Decision Record
|
||
|
||
**Date:** 2026-07-29
|
||
**Source:** SSP Refinement channel — five decisions from Ty
|
||
|
||
| # | Decision | Rationale |
|
||
|---|----------|-----------|
|
||
| 1 | **Landing page with entry point** — GeoLocal.io showcases the experience (animated demo of what the chat feels like) with a clear "Get Started" CTA that launches the conversational flow. Not buried behind a separate URL. | Lower friction; demonstrate value before asking for commitment. |
|
||
| 2 | **LLM: TBD, hosted 8–12B model** — Workflow scripts drive the conversation structure; model selection defers to implementation. The model handles natural language within the workflow-driven flow. | Requirements phase, not design phase. Defer provider choice; lock the structure now. |
|
||
| 3 | **Requirements phase for OTP/email** — OTP-by-email is a verification requirement without implementation detail. No email provider selected yet. | Focus on use cases first; implementation details come later. |
|
||
| 4 | **Chat replaces forms entirely** — No form-based fallback. The conversational SSP is the only activation path. | Clean break; forms are the problem we're solving away. |
|
||
| 5 | **Onboarding becomes ongoing** — Two phases: "The First Hour" (verification + audit + first recommendations) and "The First Month+" (presence updates, new audits, monitoring, ongoing guidance). | One-time activation degrades over time. Ongoing relationship maintains data quality and platform value. |
|
||
|
||
---
|
||
|
||
## 3. Screen-by-Screen Spec (Superseded)
|
||
|
||
> ⚠️ **This section is superseded by UC-04 and UC-05.** The screen-by-screen form wizard is replaced by the conversational flow. Retained for reference during transition; remove when conversational implementation is complete.
|
||
|
||
### Screen 1: Signup
|
||
|
||
**Purpose:** Create an account tied to one business. No OAuth — email + password only for MVP.
|
||
|
||
**Fields:**
|
||
- Email (required, validated format)
|
||
- Password (required, min 8 chars)
|
||
- Password confirm (required, must match)
|
||
|
||
**Behavior:**
|
||
- Creates a `tenants` row (email, password hash, status = 'active')
|
||
- Creates a `businesses` row with status = 'draft'
|
||
- Associates tenant with business via FK
|
||
- Redirects to Screen 2 (Business Info)
|
||
- No email verification for MVP (defer)
|
||
|
||
**Errors:**
|
||
- Email already registered → "Account exists. Try signing in." (add signin link)
|
||
- Password mismatch → "Passwords don't match"
|
||
- Empty required field → inline validation
|
||
|
||
**Notes:**
|
||
- One tenant = one business for MVP (multi-business deferred)
|
||
- Password hashing: bcrypt or argon2 (whatever the framework provides)
|
||
|
||
---
|
||
|
||
### Screen 2: Business Info Capture
|
||
|
||
**Purpose:** Collect the structured data that becomes the MCP payload. This is the core data entry screen.
|
||
|
||
**Fields (organized in sections):**
|
||
|
||
**Identity:**
|
||
- Business name (required)
|
||
- Business slug (auto-generated from name, editable, unique)
|
||
- Category (required, select from predefined list)
|
||
- Description / story (optional, textarea)
|
||
|
||
**Location:**
|
||
- Street address (optional but encouraged)
|
||
- City (optional)
|
||
- State (optional)
|
||
- ZIP (optional)
|
||
- Phone (optional)
|
||
- Website URL (optional — used for scrape reflection)
|
||
|
||
**Operations:**
|
||
- Hours (JSON structure: Mon-Sun open/close, plus holiday override flag)
|
||
- MVP: simple time picker per day + "closed" toggle
|
||
- Holiday overrides deferred to post-MVP
|
||
- Services (array of name/description pairs)
|
||
- MVP: add/remove rows, no sub-categories
|
||
- Booking link (optional, URL — Cal.com or equivalent)
|
||
|
||
**Behavior:**
|
||
- Slug validation: lowercase, hyphenated, unique (check against existing businesses)
|
||
- Save drafts as user types (auto-save to `businesses` row, status = 'draft')
|
||
- "Next: See what we found" button → Screen 3 (Scrape Reflection)
|
||
- Back to signup not needed (one-way flow; edit later from dashboard — deferred)
|
||
|
||
**Schema mapping:**
|
||
|
||
| Field | businesses column |
|
||
|-------|-------------------|
|
||
| Business name | `name` |
|
||
| Slug | `slug` |
|
||
| Category | `category` |
|
||
| Description | `story` |
|
||
| Address fields | `address`, `city`, `state`, `zip` |
|
||
| Phone | `phone` |
|
||
| Website | `website` |
|
||
| Hours | `hours` (JSONB) |
|
||
| Services | `services` (JSONB) |
|
||
| Booking link | `calcom_link` |
|
||
|
||
---
|
||
|
||
### Screen 3: Scrape Reflection
|
||
|
||
**Purpose:** Show the owner what the platform already sees on their website — and where there are gaps. This is the "aha" moment.
|
||
|
||
**Input:** Website URL from Screen 2.
|
||
|
||
**Behavior:**
|
||
- One-time scrape triggered when user clicks "Analyze my site" (or auto-triggers if URL provided)
|
||
- Parse public HTML for: business name, hours, services, phone, address, booking links
|
||
- Display side-by-side comparison:
|
||
|
||
```
|
||
+---------------------+---------------------+
|
||
| What you entered | What we found |
|
||
+---------------------+---------------------+
|
||
| Name: Bob's Garage | Name: Bob's Garage | (match)
|
||
| Hours: M-F 8-5 | Hours: not found | (gap)
|
||
| Services: [3 items] | Services: [5 items] | (partial match)
|
||
| Booking: Cal.com | Booking: not found | (gap)
|
||
+---------------------+---------------------+
|
||
```
|
||
|
||
**Output:**
|
||
- Green check: field found on site and matches entry
|
||
- Yellow warning: field found but differs from entry (show both values)
|
||
- Red X: field not found on site at all
|
||
- "Use what we found" button to auto-populate gaps from scrape
|
||
- "Skip" button to proceed without scrape (site may not exist yet)
|
||
|
||
**Technical notes:**
|
||
- Scrape runs server-side (not client-side — CORS)
|
||
- Timeout: 10 seconds per page
|
||
- No JS rendering for MVP (static HTML only — defer puppeteer/playwright)
|
||
- Store scrape result in a temporary field or session (not persisted to `businesses` until user confirms)
|
||
- Rate limit: one scrape per signup session
|
||
|
||
**Deferred:**
|
||
- Continuous sync (ingestion pipeline)
|
||
- JS-rendered page support
|
||
- Image/logo extraction
|
||
|
||
---
|
||
|
||
### Screen 4: Pointer Install
|
||
|
||
**Purpose:** Give the owner concrete instructions to attach a discovery pointer on their website so AI agents can find the hosted MCP.
|
||
|
||
**Content:**
|
||
|
||
**What this does (plain language):**
|
||
> "This installs a tiny marker on your website that tells AI assistants where to find your business data. It takes 2 minutes."
|
||
|
||
**Option A: `.well-known/mcp-server` (preferred)**
|
||
|
||
Instructions:
|
||
1. Create a file: `yourdomain.com/.well-known/mcp-server`
|
||
2. Contents: `{"mcp": "https://geolocal.io/mcp/{slug}"}`
|
||
3. Upload to your website root (or ask your web host)
|
||
4. Click "Verify" below
|
||
|
||
**Option B: DNS CNAME (for static sites / hosted platforms)**
|
||
|
||
Instructions:
|
||
1. Add a CNAME record: `mcp.yourdomain.com` → `geolocal.io`
|
||
2. Path: `/mcp/{slug}` will be routed by hostname
|
||
3. DNS propagation: up to 24 hours
|
||
4. Click "Verify" below
|
||
|
||
**Option C: Link tag (quick test)**
|
||
|
||
Instructions:
|
||
1. Add to your site's `<head>`:
|
||
```html
|
||
<link rel="mcp" href="https://geolocal.io/mcp/{slug}" />
|
||
```
|
||
2. Click "Verify" below
|
||
|
||
**Verification:**
|
||
- "Verify" button triggers a server-side fetch of the pointer location
|
||
- Success: green check + "Pointer verified" message
|
||
- Failure: plain-language error ("We couldn't find the file at that URL — check the path and try again")
|
||
- DNS CNAME verification: check CNAME record + follow to MCP endpoint
|
||
|
||
**Behavior:**
|
||
- Owner can proceed to Screen 5 without verified pointer (endpoint goes live as "unverified")
|
||
- Unverified endpoints show a warning badge in Screen 5
|
||
- No blocking — we want them live even if pointer install takes time
|
||
|
||
**Notes:**
|
||
- Multi-path discovery is the strategy (not a single fragile convention)
|
||
- The pointer URL uses the HTTP transport endpoint (see decision record)
|
||
- For MVP, Option A is the primary path; B and C are fallbacks
|
||
|
||
---
|
||
|
||
### Screen 5: Live Status
|
||
|
||
**Purpose:** Confirm the endpoint is live and show what an AI agent sees.
|
||
|
||
**Content:**
|
||
|
||
**Status banner:**
|
||
- Green: "You are discoverable" — MCP endpoint is live and responding
|
||
- Yellow: "Almost live" — MCP is live but pointer not verified
|
||
- Red: "Not ready" — preflight failed (missing required fields)
|
||
|
||
**MCP Preview:**
|
||
- Show the actual JSON response an agent would get for `get_business_info` with their slug
|
||
- Collapsible sections for each tool: `get_hours`, `get_services`, `get_booking_link`, `get_related_businesses`
|
||
|
||
**Preflight Checklist:**
|
||
- [ ] Business name set
|
||
- [ ] Category set
|
||
- [ ] At least one service entered
|
||
- [ ] Hours entered (at least one day)
|
||
- [ ] Phone or booking link set
|
||
- [ ] Pointer verified (optional but recommended)
|
||
|
||
**Actions:**
|
||
- "Edit business info" → back to Screen 2 (post-MVP: needs a dashboard)
|
||
- "Re-verify pointer" → back to Screen 4
|
||
- "Share endpoint URL" → copy `https://geolocal.io/mcp/{slug}`
|
||
|
||
**Done-when criteria met:**
|
||
1. ✅ One business owner completed signup through SSP
|
||
2. ✅ Their data is queryable via HTTP MCP endpoint
|
||
3. ✅ An AI agent can discover and call the MCP (pointer verified)
|
||
4. ✅ The agent returns a useful answer (preflight passes)
|
||
|
||
---
|
||
|
||
## 4. Data Model
|
||
|
||
### Businesses table (expanded)
|
||
|
||
```sql
|
||
CREATE TABLE businesses (
|
||
id SERIAL PRIMARY KEY,
|
||
slug VARCHAR(255) UNIQUE NOT NULL,
|
||
name VARCHAR(500) NOT NULL,
|
||
category VARCHAR(100),
|
||
address TEXT,
|
||
city VARCHAR(200),
|
||
state VARCHAR(50),
|
||
zip VARCHAR(20),
|
||
phone VARCHAR(50),
|
||
website VARCHAR(500),
|
||
hours JSONB DEFAULT '{}',
|
||
services JSONB DEFAULT '[]',
|
||
story TEXT,
|
||
owner_bio TEXT,
|
||
photos JSONB DEFAULT '[]',
|
||
calcom_link VARCHAR(500),
|
||
mcp_endpoint VARCHAR(500),
|
||
related_business_ids INTEGER[] DEFAULT '{}',
|
||
status VARCHAR(50) DEFAULT 'draft', -- NEW: draft | active | inactive | quarantine
|
||
pointer_verified BOOLEAN DEFAULT FALSE, -- NEW
|
||
created_at TIMESTAMP DEFAULT NOW(),
|
||
updated_at TIMESTAMP DEFAULT NOW()
|
||
);
|
||
```
|
||
|
||
**Status values:**
|
||
- `draft` — owner in progress, not queryable
|
||
- `active` — live, queryable by agents
|
||
- `inactive` — owner requested pause or business closed
|
||
- `quarantine` — quality loop flagged, manually reviewed
|
||
|
||
**Decision:** Use a `status` column on `businesses` instead of a separate `quality_flags` table. Rationale: MVP has four states that are mutually exclusive per business. A separate table adds join complexity for a single-row-per-business relationship. Revisit if quality flags become multi-dimensional (e.g., separate flags for data freshness, booking health, pointer validity).
|
||
|
||
### Tenants table (new)
|
||
|
||
```sql
|
||
CREATE TABLE tenants (
|
||
id SERIAL PRIMARY KEY,
|
||
email VARCHAR(500) UNIQUE NOT NULL,
|
||
password_hash VARCHAR(500) NOT NULL,
|
||
business_id INTEGER REFERENCES businesses(id) ON DELETE CASCADE,
|
||
status VARCHAR(50) DEFAULT 'active', -- active | suspended
|
||
created_at TIMESTAMP DEFAULT NOW(),
|
||
updated_at TIMESTAMP DEFAULT NOW()
|
||
);
|
||
|
||
CREATE INDEX idx_tenants_business ON tenants(business_id);
|
||
```
|
||
|
||
**MVP constraints:**
|
||
- One tenant per business (enforced by application logic, not schema)
|
||
- No role system (owner is the only role)
|
||
- No multi-business support
|
||
|
||
---
|
||
|
||
## 5. HTTP Transport Decision Record
|
||
|
||
**Date:** 2026-07-29
|
||
**Status:** Accepted
|
||
|
||
**Decision:** Use streamable-HTTP transport for the public MCP gateway, not stdio.
|
||
|
||
**Context:**
|
||
- Stdio transport works for local development and single-process agents but cannot serve internet-discoverable endpoints.
|
||
- The MCP spec defines streamable-HTTP as the transport for remote server access (SSE-based, with POST for tool calls).
|
||
- Our gateway must be discoverable via a URL that any AI assistant can reach — stdio cannot satisfy this.
|
||
|
||
**Consequences:**
|
||
- Replace `StdioServerTransport` with `StreamableHTTPTransport` (or equivalent) in `mcp-server.ts`.
|
||
- The Fastify/Express server will expose `/mcp/{slug}` as the streamable-HTTP endpoint.
|
||
- Each slug routes to the correct business's tool set (multi-tenant via slug lookup).
|
||
- No JWT auth on MVP endpoints (defer OAuth; open access is acceptable for read-only business data).
|
||
- Rate limiting will be added post-MVP.
|
||
|
||
**Alternatives considered:**
|
||
- WebSocket: heavier client requirement, no MCP spec support yet.
|
||
- gRPC: overkill for JSON tool calls, poor browser compatibility.
|
||
- REST API without MCP framing: loses MCP compatibility, reinvents the protocol.
|
||
|
||
---
|
||
|
||
## 6. Flow Diagram
|
||
|
||
### Conversational Flow (Primary — UC-04)
|
||
|
||
```
|
||
Owner arrives at geolocal.io
|
||
| sees animated demo + "Get Started" CTA
|
||
|
|
||
v
|
||
[Chat Opens] "Welcome to GeoLocal! Tell me about your business."
|
||
| owner describes business in natural language
|
||
| AI extracts: business type, location, goal
|
||
v
|
||
[Verification] "Let me verify you're the owner. Emailing OTP to your website's contact."
|
||
| owner enters OTP code
|
||
| ownership confirmed
|
||
v
|
||
[Audit] "I'll review your online presence — one moment."
|
||
| scans: Google, Apple, Bing, Yelp, website
|
||
| gap analysis: what's missing, inconsistent, outdated
|
||
v
|
||
[Results] "This looks like a terrific salon! Here's what I found..."
|
||
| specific findings per platform
|
||
| ranked recommendations
|
||
v
|
||
[Guided Setup] "Want me to help you set things up?"
|
||
| conversational data capture (no forms)
|
||
| pointer install guidance
|
||
| preflight verification
|
||
v
|
||
[First Session Complete]
|
||
| endpoint live (or in progress)
|
||
| action list for ongoing optimization
|
||
| session saved for resume
|
||
|
|
||
v
|
||
[Ongoing — UC-05] Owner returns for updates, monitoring, reports
|
||
| presence monitoring
|
||
| data updates (hours, services, specials)
|
||
| periodic health reports
|
||
| seasonal guidance
|
||
```
|
||
|
||
### Legacy Form Flow (Superseded — retained for reference)
|
||
|
||
```
|
||
Owner arrives at geolocal.io
|
||
|
|
||
v
|
||
[Screen 1] Signup (email + password)
|
||
| creates tenant + business(draft)
|
||
v
|
||
[Screen 2] Business Info Capture (manual entry)
|
||
| populates businesses row
|
||
v
|
||
[Screen 3] Scrape Reflection (one-time, optional)
|
||
| compares site content vs entered data
|
||
| owner confirms or edits
|
||
v
|
||
[Screen 4] Pointer Install (instructions + verify)
|
||
| owner installs .well-known/mcp-server or CNAME
|
||
| platform verifies pointer
|
||
v
|
||
[Screen 5] Live Status
|
||
| status = 'active'
|
||
| preflight passes
|
||
| MCP endpoint live at /mcp/{slug}
|
||
|
|
||
v
|
||
AI agent discovers pointer -> calls /mcp/{slug} -> gets structured data
|
||
```
|
||
|
||
---
|
||
|
||
## 7. Acceptance Criteria
|
||
|
||
### Screen 1: Signup
|
||
- [ ] User can create an account with email + password
|
||
- [ ] Duplicate email is rejected
|
||
- [ ] Tenant row created with correct business_id FK
|
||
- [ ] Business row created with status = 'draft'
|
||
|
||
### Screen 2: Business Info
|
||
- [ ] All fields save to businesses row
|
||
- [ ] Slug is auto-generated, editable, unique
|
||
- [ ] Category is required (from predefined list)
|
||
- [ ] Services can be added/removed (min 1)
|
||
- [ ] Hours captured as JSONB
|
||
|
||
### Screen 3: Scrape Reflection
|
||
- [ ] Server-side scrape of provided URL (10s timeout)
|
||
- [ ] Side-by-side comparison displayed
|
||
- [ ] "Use what we found" populates gaps
|
||
- [ ] Skippable (proceed without scrape)
|
||
|
||
### Screen 4: Pointer Install
|
||
- [ ] Three pointer options presented (well-known, CNAME, link tag)
|
||
- [ ] Verification fetches and validates pointer
|
||
- [ ] Proceed without verification allowed (unverified badge)
|
||
|
||
### Screen 5: Live Status
|
||
- [ ] Status banner reflects endpoint state
|
||
- [ ] MCP preview shows actual JSON response
|
||
- [ ] Preflight checklist is accurate
|
||
- [ ] Setting status = 'active' makes endpoint queryable
|
||
|
||
### Cross-cutting
|
||
- [ ] HTTP transport replaces stdio for `/mcp/{slug}`
|
||
- [ ] Slug-based routing returns correct business data
|
||
- [ ] Done-when criteria 1-4 are all satisfied
|
||
|
||
---
|
||
|
||
## 8. Open Questions
|
||
|
||
1. **Minimum content bar:** What fields are required before status = 'active'? Proposal: name, category, at least one service, at least one day of hours.
|
||
2. **Category list:** What categories ship in MVP? Proposal: auto repair, beauty/salon, home services, restaurant, retail/general store, tourism/activity.
|
||
3. **Scrape depth:** Single page only, or follow links? Proposal: single page (homepage) for MVP.
|
||
4. **Edit after live:** Do we need a dashboard screen for post-live edits? Proposal: yes, but defer to post-MVP; allow re-running the flow for now.
|
||
5. **Booking link validation:** Do we verify the Cal.com link actually works? Proposal: URL format check only for MVP.
|
||
|
||
---
|
||
|
||
## 9. What Changed from Original SSP Spec
|
||
|
||
| Area | Before | After |
|
||
|------|--------|-------|
|
||
| Length | 14 lines | Implementation-ready |
|
||
| Screens | Named but not described | 5 screens with fields, behavior, errors (superseded by conversational flow) |
|
||
| Data model | Not specified | Schema with status column, tenants table |
|
||
| Scrape | Mentioned | One-time on signup, side-by-side comparison |
|
||
| Pointer | Mentioned | 3 options with verification flow |
|
||
| Transport | Not decided | Streamable-HTTP with decision record |
|
||
| Quality flags | Separate table | Status column on businesses |
|
||
| Acceptance criteria | None | Per-screen + cross-cutting |
|
||
|
||
## 10. Conversational SSP Revision (2026-07-29)
|
||
|
||
This revision incorporates five product decisions from the SSP Refinement channel:
|
||
|
||
| Area | Before (Form SSP) | After (Conversational SSP) |
|
||
|------|-------------------|----------------------------|
|
||
| Activation path | 5-screen form wizard | Conversational chat (ChatGPT-like) |
|
||
| Fallback | N/A | No form fallback — chat only |
|
||
| Landing page | Not specified | Animated demo + "Get Started" CTA |
|
||
| Verification | Email + password signup | OTP to website contact email |
|
||
| Data capture | Manual form entry | Conversational (AI asks, owner answers) |
|
||
| Audit timing | Not in original | After verification, before setup |
|
||
| Scope | One-time activation | Ongoing relationship (First Hour + First Month+) |
|
||
| LLM | Not in original | Hosted 8–12B model, workflow-driven (TBD provider) |
|
||
| Use cases | UC-01, UC-02, UC-03 | UC-04 (First Hour), UC-05 (Ongoing) added |
|
||
|
||
**Status of form-based screens (§3):** Superseded by UC-04 and UC-05. Retained for reference during transition. Remove when conversational implementation is complete.
|