Product Requirements Document
Conversational memory + cross-product grounding for Mio agents
| Field | Value |
|---|---|
| Version | v1.0 |
| Date | 2026-09-03 |
| Owner | Protyaydeep S. (protyaydeep.s@meritto.com) |
| Status | Draft — In Review |
| Module | Mio AI Platform |
| Vertical | Higher Ed · Ed-Tech · Study Abroad · Coaching · Skilling |
| Related | StudentMemoryLayer_PRD_v2.1 (Alok Sharma) — consumed, not replaced. See §2.3. |
Mio agents today start every conversation blank. They cannot recall what a student said last week, on another channel, or to another agent persona — and they cannot see the student's live application, payment, or enrolment state unless it is hard-coded into a prompt.
This PRD specifies two complementary systems that fix that:
| System | What it holds | Written by | Source of truth |
|---|---|---|---|
| Conversational Memory | What the student said — preferences, constraints, objections, commitments made to them, journey state | LLM extraction from conversations | The conversation |
| Grounding Data | What is true — application stage, fee status, documents, payment, enrolment | Never written by AI. Read live from Meritto / Collexo / Nexeo | The source systems |
The separation is the core design rule: the LLM never writes a fact that a system of record owns, and the system of record never tries to store what was said in a conversation. Conflating them is what makes agent memory unsafe.
Analysis of 6,006 unique real student queries across 50 institutes (Mio QC exports, 20–26 Jul 2026; 2,765 message-level records with turn metadata, 1,100 identified applicants):
| Finding | Value | What it proves |
|---|---|---|
| Queries arriving at turn 2+ | 61.2% | Most queries are not openers — they assume prior context |
| Applicants sending >1 message | 60.8% (avg 2.51) | Multi-turn is the norm, not the exception |
| Queries depending on personal application/account state | 9.8% (5.6% QC-tagged PERSONAL_DATA) |
RAG over documents structurally cannot answer these |
Applicants using both web and sap channels in one week |
1.3% — with zero carry-over observed | Cross-channel continuity is broken today (e.g. applicant 84954 re-asked identical BBA fee/seat questions after switching channel) |
| Applicants returning on a different day inside the 7-day window | 4.6% | A floor, not a ceiling — real admission cycles run months |
Conversations hitting REPHRASE_BUG_DROPPED |
1.2% (34/2,875) | Even single-session continuity is not reliably held today — see §9 |
| "Other/long-tail" queries ≤5 words | 56% of a 29.6% bucket | Elliptical fragments that are uninterpretable without context |
That PRD specifies a shared, platform-level brief — code-computed facts and signals from CRM, plus a single LLM-written narrative — with demand-driven regeneration and a Golden ID join key. Mio is named there as a consumer.
This PRD does not replace it. It consumes it, and adds the two things it deliberately scopes out:
| Student Memory Layer boundary (its own wording) | What Mio needs | Covered by |
|---|---|---|
| "LLM writing facts (auto-enrichment) — Never (by design). Facts = CRM only" | Capture what a student states in conversation that no CRM field holds | §5 Conversational Memory |
| Fixed schema, uniform across verticals | Per-institute configurable fields with LLM-readable descriptions | §6 Grounding Data |
| Journey brief keyed to CRM modules | Session/channel/agent-scoped conversational state | §4 Scoping |
Consumption rule: where a grounding field already exists in the Student Memory Layer brief, Mio reads it from that API rather than querying Meritto directly. New connector work is scoped only to the residual — institute-specific custom fields, and Collexo/Nexeo fields the brief does not model. This avoids duplicating the cache, event-subscription and freshness infrastructure that layer already owns.
| Item | Rationale | Candidate |
|---|---|---|
| Non-Meritto third-party CRM connectors | Connector interface is designed to accept them without redesign (§6.2); no v1 customer demand at priority | v2 |
| Counsellor-facing worker agents | Scoping model (§4) already accommodates role-based read policy; no agent exists yet to consume it | v2, with Workflows |
| Memory-triggered proactive campaigns | Depends on WhatsApp campaign engine (ships end Sep 2026) | v2 |
| Cross-institute memory linkage | Prohibited by design — see §10.1 | Never |
| LLM writing to CRM fields | Anti-hallucination rule inherited from Student Memory Layer | Never |
| ML-computed scores (conversion probability) | Owned by Student Memory Layer intelligence block |
N/A — consumed |
| Key | Meaning | Role |
|---|---|---|
institute_id |
Tenant | Hard isolation boundary. No query may span two institutes. |
golden_lead_id |
One person across Meritto (lead), Collexo (payer), Nexeo (student) | Primary partition for long-term memory |
agent_id |
Agent persona (admissions, fee & scholarship, alumni, placement) | Provenance + read policy |
agent_channel_id |
web · whatsapp · voice | Provenance + retrieval ranking |
session_id |
One conversation thread | Working-state scope |
/institutes/{institute_id}/leads/{golden_lead_id}/ → long-term memory
/institutes/{institute_id}/leads/{golden_lead_id}/sessions/{session_id}/ → working state
agent_id and agent_channel_id are metadata, not path segments. Rationale: the primary use case is cross-agent and cross-channel recall. Putting either in the path would make the common read a fan-out across N paths and the rare read cheap — exactly backwards. They are recorded as provenance on every record and used for ranking and policy filtering at read time.
Cross-agent recall is the default and the point. But not every disclosure should surface everywhere: financial hardship disclosed to the fee agent should not surface in an alumni conversation.
Every memory carries a sensitivity_class. Every agent persona carries a memory_read_policy listing the classes it may retrieve.
sensitivity_class |
Example | Default persona access |
|---|---|---|
general |
Prefers evening calls; comparing three colleges | All personas |
academic |
Scored 78% in 12th; targeting CS | All personas |
financial |
Needs EMI; scholarship dependency; family income context | Admissions + Fee only |
personal_circumstance |
Health, family situation, relocation constraint | Fee + Admissions, flagged for counsellor, never used for segmentation |
commitment |
"Counsellor promised a 10% waiver" | All personas, always surfaced, never decayed (§5.5) |
Institute admins may tighten but not widen the defaults.
| Case | Behaviour |
|---|---|
| Anonymous visitor (no identity yet) | Memory written to provisional_id derived from session; promoted and merged on identity resolution. Never retained beyond provisional_ttl if identity never resolves. |
| WhatsApp-first contact (phone known, lead not yet created) | provisional_id = salted hash of phone + institute; merged when Meritto lead is created |
| Golden ID merge (CRM lead dedupe) | Memory merge job: union of records, recon pass over the union to collapse contradictions, provenance preserved from both sides, audit entry written |
| Golden ID split (bad merge reversed) | Manual ops procedure; memories follow their originating source_session_id. Records that cannot be attributed are quarantined, not guessed. |
| Same human at two institutes | Two completely separate memory sets. No linkage, ever — including identical phone/email. Enforced at the storage partition, not in application logic. |
| Lead deleted in CRM | Cascade purge within 24h (§10.4) |
| Lead converts to enrolled student (Nexeo) | golden_lead_id persists; memory continues under the same partition, with lifecycle_stage updated. No re-keying. |
Extraction targets six types. Anything not matching a type is not stored.
| Type | Definition | Why it cannot live in CRM |
|---|---|---|
preference |
Stated choice or constraint — "only if EMI is available", "prefer evening calls" | No field exists; varies infinitely |
objection |
Concern raised, plus whether and how it was resolved | Resolution state is conversational, not transactional |
commitment |
Something Mio or a counsellor promised the student | Must be honoured before it becomes a CRM record |
sentiment |
Frustration, urgency, disengagement signals | Derived from tone, not events |
journey_state |
Compare-shopping / ready-to-apply / stuck-on-documents | An interpretation, not a stage value |
fact_stated |
A durable personal fact stated by the student that no CRM field holds | By definition absent from schema |
memory_id uuid
institute_id string -- partition key
golden_lead_id string -- partition key
memory_type enum -- §5.1
content text -- one self-contained statement
sensitivity_class enum -- §4.3
confidence enum -- stated | inferred
confidence_score float
language string -- BCP-47; native script preserved
embedding vector
entities string[] -- co-occurrence links (no graph DB)
provenance {
source_agent_id, source_channel_id, source_session_id,
source_turn_refs[], extracted_at,
extractor_model, extractor_prompt_version
}
lifecycle {
created_at, last_reinforced_at, last_retrieved_at,
decay_score, ttl_class, expires_at, superseded_by
}
status enum -- active | superseded | soft_deleted | purged
extractor_prompt_version enables lazy regeneration when the extraction prompt changes, without a migration job.
Extraction runs asynchronously, off the live response path. It fires on whichever comes first:
idle_timeout (default 15 min), or an explicit session-close signal.throttle_interval (default 15 min) elapsed since the last extraction on this session, even if the session is still active.Why both. Pure idle-timeout resets on every message, so a long active conversation never extracts until it finally goes quiet — and a student who moves to WhatsApp mid-conversation finds an agent with none of the web thread's context. The throttle caps that staleness window regardless of ongoing activity. Both defaults are per-institute configurable.
Sweep job: any session with events older than sweep_threshold and no completed extraction is swept and extracted. Covers crashes, dropped connections and abandoned threads where neither trigger fired.
recon)Every extracted candidate is reconciled against existing memory for that golden_lead_id before write. Four outcomes:
| Outcome | Condition |
|---|---|
ADD |
Genuinely new |
UPDATE |
Extends or supersedes an existing record. A newer statement overwrites an older one only at equal or higher confidence — a stated fact supersedes an inferred one; the reverse does not hold |
SKIP |
Duplicate, immaterial, or matches a hard exclusion (§5.6) |
SUPERSEDE |
Direct contradiction resolved in favour of the higher-confidence record; the loser is marked superseded, never hard-deleted (audit) |
Hardening requirements (memory poisoning defence — a false memory becomes a recurring error, not an isolated one):
inferred confidence, not stated.Soft-forget, not deletion: unretrieved memories dampen in retrieval score over time; reinforced ones boost. A memory that looks unimportant mid-conversation can become decisive when a lead re-engages near a deadline.
ttl_class |
Applies to | Behaviour |
|---|---|---|
volatile |
Sentiment, transient journey state | Decays fastest; expires at volatile_ttl |
standard |
Preferences, objections, stated facts | Soft decay; expires at standard_ttl |
durable |
Commitments made to the student | Never decays, never auto-expires. Cleared only on fulfilment or explicit human deletion |
Hard deletion occurs only via erasure (§10.4) or CRM cascade.
Enforced in the recon prompt and by a deterministic post-extraction filter (defence in depth — a prompt instruction alone is not a control):
personal_circumstance.Session start (hydration). One retrieval per session, before turn 1: durable + high-salience memories for that golden_lead_id, filtered by the persona's memory_read_policy, trimmed to hydration_token_budget.
Mid-session (conditional). A search_memory tool call, invoked only when the conversation raises something hydration did not cover. Not called on every turn — the initiation prompt already produces a rephrased query for the KB decision; the same signal gates the memory decision at no additional LLM cost.
Ranking: semantic_similarity + recency_weight + type_priority + reinforcement_boost, with a similarity floor below which nothing is returned. Commitments always rank above the floor.
Degradation: if retrieval fails or exceeds retrieval_timeout, the turn proceeds without memory. Memory never blocks a response. The agent must not fabricate personalisation on an empty result.
| Control | Actor | Behaviour |
|---|---|---|
| Explicit remember | Student or counsellor | Written at stated confidence, bypasses the materiality gate, still subject to §5.6 |
| Explicit forget | Student or counsellor | Soft-delete; excluded from retrieval immediately; purged per retention policy |
| Memory review | Counsellor | Read-only view of what Mio holds about a lead, with provenance — which conversation, which turn, when |
| Correction | Counsellor | Edit content; original preserved in audit trail |
One-time extraction over historical conversations at institute onboarding.
Live state read from source systems, never written by the LLM.
| Source | Modules |
|---|---|
| Meritto | Lead Manager, Opportunity Manager, Application Manager, Communication activity |
| Collexo | Payment status, transaction history |
| Nexeo | Enrolled-student state |
The scaling question is not "fixed schema or per-institute schema" — it is what stays fixed.
| Fixed for every institute | Variable per institute |
|---|---|
| The default bundle per persona | Additional fields an admin exposes |
| The field-definition schema (the shape of a field entry) | Which fields exist |
The connector engine, fetch_fields interface, cache layer, audit path |
— |
| The mandatory-description rule | The description text |
The engine is uniform; the configuration varies. This is the same Platform-vs-Product split the Student Memory Layer already establishes ("Mio Platform (built once)… Product (per product): a ~10-line config pack"), applied at field granularity.
Field definition:
institute_id, field_key
source_system enum -- meritto | collexo | nexeo
source_module string
source_field_path string
data_type enum
label string
description text -- MANDATORY, ≤200 chars, enforced at write
tier enum -- default_push | on_demand
cache_class enum -- static | session | realtime
sensitivity_class enum
enabled bool
created_by, created_at
The description is not documentation. It is injected into the tool schema and is the only thing that tells the model what custom_field_47 means. A field cannot be saved without one.
Tier 1 — default push. The persona's default bundle, injected once at session start. Zero configuration required for a new institute.
Tier 2 — on-demand. Everything else the admin has marked on_demand, exposed to the agent as a single fetch_fields tool whose schema enumerates the eligible fields with their descriptions. The model selects a subset by name; it cannot request a field outside the list, which removes hallucinated field lookups as a failure mode.
The two tiers are a strict partition — a field is in one or the other, never both.
Cap: max_on_demand_fields per persona (default 20). Tool schemas are sent on every turn whether invoked or not; an unbounded list is a permanent per-turn token cost.
golden_lead_id + field_key, kept fresh by source-system events, with per-field cache_class:cache_class |
Refresh | Example |
|---|---|---|
static |
Session lifetime | Program applied, city |
session |
Cached for session, invalidated on event | Application stage, sub-stage |
realtime |
Always fetched fresh | Payment status, seat availability |
Without this, on-demand fetch reintroduces the exact 800–1500ms per-turn rebuild latency the Student Memory Layer exists to remove.
value · null_confirmed (genuinely empty) · unavailable (source failed). The agent must distinguish "no counsellor is assigned" from "the counsellor API timed out" — without this the model states a fabricated value on a silent failure.| Case | Behaviour |
|---|---|
| Source system unreachable | Return unavailable per field; turn proceeds; never block |
| Partial fan-out failure | Return successful fields with values, failed fields as unavailable |
| Field deleted at source, still configured in Mio | Config validation flags it; runtime returns unavailable; admin notified |
| Admin revokes a field mid-session | Enforced at fetch time, not only at config time |
| Field contains excluded PII (§5.6) | Hard denylist at connector level — not exposable regardless of admin configuration |
| Memory contradicts grounding data | Grounding wins, always. Memory is annotated as "as stated by the student", never presented as system truth |
| Institute has no Collexo/Nexeo | Connector degrades to available systems; no error surface to the student |
Session start
└─ resolve identity → golden_lead_id (or provisional_id)
└─ hydrate: memory retrieval (policy-filtered) + default-push grounding bundle
└─ inject into system context
Per turn
└─ initiation prompt → rephrased query + KB decision + memory-needed decision (one call)
└─ [conditional] search_memory → ranked memories
└─ [conditional] fetch_fields → cache-backed grounding values
└─ RAG prompt → KB chunks + memories + grounding values → response
Async, off the response path
└─ turn events appended to session log
└─ debounce (idle) OR throttle (interval) → extract → recon → write
└─ sweep job catches sessions where neither fired
The memory-needed decision rides on the initiation-prompt call Mio already makes for its KB decision. No additional LLM call is introduced for retrieval gating.
| Tier | Contents |
|---|---|
| Vector store + metadata | Memory records, embeddings, provenance. Metadata-filtered ANN query — institute_id and golden_lead_id are filter predicates in the same query as similarity, not a second pass |
| Hot cache | Session working state, grounding cache |
| Relational | Field definitions, read policies, audit log, erasure ledger |
No graph database. Entity links are co-occurrence metadata that boost ranking. Both mem0 and Hindsight converged on vector-primary storage with relationship metadata; mem0 abandoned a graph DB after a production failure at scale. This is a settled pattern, not an open question.
Storage engine selection is an engineering decision, not a product one. The contract that must not change: metadata-filtered semantic search, namespace-scoped access, per-record provenance and lifecycle.
| Function | Requirement |
|---|---|
| Conversation | Luna 5.6 (current) |
| Extraction + recon | Cheap, schema-forced, async — not the conversational model |
| Embedding | Multilingual, native-script preserving (§8) |
Internal, service-to-service, institute-scoped tokens.
| Endpoint | Method | Purpose |
|---|---|---|
/memory/{institute_id}/sessions |
POST | Open session; returns hydration payload |
/memory/{institute_id}/sessions/{session_id}/events |
POST | Append turn to extraction queue |
/memory/{institute_id}/leads/{golden_lead_id}/search |
GET | Ranked retrieval (q, top_k, policy applied server-side) |
/memory/{institute_id}/leads/{golden_lead_id}/memories |
POST | Explicit remember |
/memory/{institute_id}/leads/{golden_lead_id}/memories/{memory_id} |
PATCH / DELETE | Correct / forget |
/memory/{institute_id}/leads/{golden_lead_id} |
DELETE | Full erasure (§10.4) |
/memory/{institute_id}/leads/merge |
POST | Identity merge |
/grounding/{institute_id}/fetch_fields |
POST | Tool endpoint |
/grounding/{institute_id}/fields |
GET / POST / PATCH | Connector configuration |
/memory/{institute_id}/leads/{golden_lead_id}/audit |
GET | Provenance + access log |
Institutes serve non-English-medium students; voice and WhatsApp traffic includes Hindi and regional languages.
inferred confidence unless the student confirms the value in-conversation. Low-ASR-confidence spans are excluded from extraction rather than guessed.| Dependency | Status | Impact if unmet |
|---|---|---|
REPHRASE_BUG_DROPPED fix |
Blocking. 1.2% of conversations already cold-reset mid-thread because the initiation-prompt rephrase step returns null with no fallback — observed as late as turn 26 of 29 | Cross-session memory is meaningless while single-session continuity is unreliable. Must ship before or alongside v1 |
| Golden ID availability across Meritto / Collexo / Nexeo | Required | Without it, one person appears as three, and memory fragments |
| Clean lead dedupe in Meritto | Required | Duplicate leads fragment memory; merge job (§4.4) mitigates but does not fix the source |
| Student Memory Layer brief API | Required for grounding reuse | Fallback: Mio queries Meritto modules directly — duplicated infrastructure, higher cost |
| Collexo / Nexeo read APIs | Required for those sources | Connector degrades gracefully (§6.5) |
institute_id is a storage partition boundary, not an application-layer filter. Cross-institute reads return 403 at the data layer. The same human at two institutes has two unlinked memory sets — including identical phone and email. Penetration testing for cross-tenant leakage is a GA gate.
Memory is derived personal data and inherits the obligations of its source.
| Requirement | Implementation |
|---|---|
| Purpose limitation | Memory is processed only to support the student's own admission journey. It is not used for profiling unrelated to that purpose, for advertising, or for cross-institute analytics |
| Data minimisation | The six-type taxonomy (§5.1) and hard exclusions (§5.6) are the minimisation control — everything outside them is discarded at extraction, not stored-then-filtered |
| Consent and notice | Institutes are Data Fiduciaries; Meritto processes on their instruction. Institute-facing notice text must disclose that conversations are used to build durable memory. Backfill (§5.9) requires the existing basis to cover secondary processing |
| Children's data | Material for this product. A large share of applicants are 17–18. DPDP requires verifiable parental consent for under-18 processing and prohibits behavioural monitoring and targeted advertising directed at children. Where date of birth indicates a minor: memory is restricted to general and academic classes, sentiment extraction is disabled, and memory is never used to drive campaign targeting. This flag is read from CRM, not inferred |
| Correction and erasure | §5.8 and §10.4 |
| Grievance redressal | Memory audit view (§10.5) is the evidence path for a student query about what is held |
Memory is derived PII and inherits its source's residency. Each institute's memory is stored in the same region as its source data. Study Abroad institutes may process EU-resident data subjects — GDPR obligations attach, and cross-border transfer requires the institute's own lawful transfer basis. v1 ships single-region per deployment; per-institute region routing is required before onboarding an institute whose contract mandates it.
| Trigger | Behaviour | SLA |
|---|---|---|
| CRM lead/journey delete | Cascade purge of all memory under that golden_lead_id |
24h |
| Student erasure request | Full purge via DELETE endpoint | Per institute's DPDP commitment |
| Institute offboarding | Full partition purge | Per contract |
Purge is complete: records, embeddings, cache entries, extraction queue items, and derived aggregates. Embeddings derived from personal data remain personal data — deleting the row and leaving the vector is not erasure. The erasure ledger retains proof-of-deletion (IDs and timestamps, never content).
| Control | Implementation |
|---|---|
| Memory poisoning | §5.4 hardening. A false memory becomes a recurring error, not an isolated one — this is the highest-severity failure mode in the system |
| Prompt injection via memory | Retrieved memory is data, never instruction. It cannot invoke tools, override system prompts, or alter authorisation |
| Never overrides system of record | §6.5. Grounding always wins over memory |
| Explainability | Every memory carries provenance to the originating session and turn. A counsellor can answer "why did the agent say that" |
| Human oversight | Review, correct, forget (§5.8) |
| Reproducibility | extractor_model and extractor_prompt_version stamped per record |
| Non-discrimination | Protected attributes are hard-excluded (§5.6) and must not be inferable from stored content or influence retrieval, routing, or prioritisation |
| Scope of automation | Mio provides information and support. It does not make or recommend admission, eligibility or financial-aid decisions. This boundary must hold in product behaviour, not only in documentation — education-sector AI used for admissions decisioning is classified high-risk under the EU AI Act, and Study Abroad exposure makes this a live constraint |
| Audit | Every memory read and write logged: actor, agent, channel, session, scope, timestamp. Content masked in logs |
| Event | Status |
|---|---|
| PII handling | Tier-1. Memory is dense personal data |
| Encryption at rest and in transit | Required |
| Tenant isolation | Partition-level; pen-tested before GA |
| Prompt-injection sanitisation | Required on conversation content and counsellor free-text |
| Right to erasure | §10.4 |
| Data residency | §10.3 |
| Audit logging | §10.5 |
| LLM vendor data-processing review | Required for extraction and embedding models |
US-01 — Cross-session continuity
As a returning applicant, I want Mio to recall what I already explained, so I don't repeat myself.
AC: Session start hydrates memory for the golden_lead_id within the hydration budget · policy-filtered by persona · no memory → normal greeting with no fabricated personalisation.
US-02 — Cross-channel continuity
As an applicant who moves from web to WhatsApp, I want the agent to already know my context.
AC: Memory keyed on golden_lead_id, not channel · a session opened on any channel hydrates from the same partition · extraction from the prior session has fired via debounce or throttle before or during the new session, and the sweep job guarantees eventual capture.
US-03 — Cross-agent continuity
As an applicant handed from admissions to fee & scholarship, I want the second agent to know what was covered.
AC: Memory readable across personas subject to memory_read_policy · financial and personal_circumstance classes respect policy · provenance identifies the originating agent.
US-04 — Personal grounding
As an applicant asking "what's my application status", I want a live, correct answer.
AC: Default bundle covers stage, sub-stage, fee status, documents pending, assigned counsellor · beyond-bundle fields fetched on demand · unavailable never presented as a value.
US-05 — Institute-specific fields As an institute admin, I want to expose fields specific to my process. AC: Admin selects from all connector-visible fields · description mandatory, ≤200 chars, save blocked without it · tier and cache class set per field · cap enforced · excluded PII not selectable.
US-06 — Commitment integrity
As a counsellor, I want to know what Mio promised a student.
AC: commitment memories never decay or auto-expire · always retrievable regardless of persona · surfaced in the counsellor memory view · cleared only on fulfilment or explicit deletion.
US-07 — Human control As a counsellor, I want to see, correct and delete what Mio remembers. AC: Review view with provenance · correction preserves the original in audit · forget removes from retrieval immediately.
US-08 — Erasure As an institute, I need memory to disappear when a lead is deleted. AC: Cascade within 24h · records, embeddings, cache and queue items all purged · erasure ledger written · verifiable by audit query.
US-09 — Graceful degradation
As an applicant, I want an answer even when memory or grounding fails.
AC: Retrieval timeout → turn proceeds without memory · grounding failure → per-field unavailable · no user-facing error · degradation logged.
US-10 — Minor protection
As a compliance owner, I need under-18 applicants handled correctly.
AC: Minor flag read from CRM, never inferred · sentiment extraction disabled · memory restricted to general and academic · excluded from campaign targeting.
| Limit | Default | Configurable |
|---|---|---|
max_on_demand_fields per persona |
20 | Per institute |
| Default-push bundle size | Per-persona bundle | Per institute |
| Field description length | 200 chars | No |
hydration_token_budget |
Fixed budget per session | Per institute |
idle_timeout |
15 min | Per institute |
throttle_interval |
15 min | Per institute |
retrieval_timeout |
Sub-second | No |
top_k per retrieval |
Bounded | Per persona |
volatile_ttl / standard_ttl |
Set at build | Per institute |
durable (commitments) |
No expiry | No |
provisional_ttl |
Short | Per institute |
Memories per golden_lead_id |
Soft cap with decay-based eviction | Per institute |
Baselines are the §2.1 dataset. Targets are set at build kickoff.
Primary
| Metric | Baseline | Direction |
|---|---|---|
| Cross-channel context loss rate | 1.3% of applicants, zero carry-over observed | ↓ |
| Repeat-question rate (same question re-asked across sessions by the same lead) | To be measured on the same corpus | ↓ |
| Personal-state query resolution rate | 9.8% of queries currently unanswerable from RAG | ↑ |
| Turn-2+ answer quality (blind-rated) | 61.2% of queries arrive at turn 2+ | ↑ |
Secondary
| Metric | Purpose |
|---|---|
| Memory hydration hit rate | Coverage of active leads |
| Extraction precision / recall vs. golden set | Quality gate before GA |
| Grounding fetch p95 latency; on-demand invocation rate | Verifies the two-tier design |
| Added p95 latency per turn | Guards the response path |
| Extraction cost per session | Verifies the debounce+throttle design |
Counter-metrics (regression triggers, not vanity metrics)
| Metric | Why it matters |
|---|---|
| Incorrect-memory rate (blind-audited) | Memory poisoning |
| Memory–grounding contradiction rate | Source-of-truth violations |
| PII-in-memory incidents | Must be zero |
| Cross-tenant access attempts | Must be zero |
| Erasure SLA breaches | Must be zero |
| Protected-attribute presence in stored memory | Must be zero |
| Sessions degraded by memory failure | Availability |
Evaluation. A golden set is drawn from the 6,006-query corpus, covering: multi-turn threads, cross-channel pairs, personal-state queries, elliptical fragments, non-English and transliterated input, and adversarial injection attempts. Extraction and retrieval are scored against it before v1 GA and re-scored on every extraction-prompt version bump.
| Phase | Scope | Exit criteria |
|---|---|---|
| v0 — Proof of quality | Extraction + recon + retrieval for one persona, one institute, web channel. No live traffic | Golden-set precision/recall met · zero protected-attribute or PII leakage in audit · recon survives adversarial injection set |
| v1 — Single-channel live | Web channel, hydration + on-demand grounding via default bundle, human controls, erasure, audit. REPHRASE_BUG_DROPPED fixed |
Continuity demonstrated across sessions · added latency within budget · erasure verified end-to-end |
| v2 — Multi-channel | WhatsApp + voice, cross-channel identity merge, provisional-ID promotion, multilingual extraction | Cross-channel carry-over demonstrated on real traffic · ASR-confidence handling verified |
| v3 — Configurable grounding | Admin field configuration UI, custom fields with descriptions, Collexo + Nexeo connectors, backfill | Institute self-configures without engineering · backfill lawful-basis gate operational |
| Question | Owner |
|---|---|
| Ownership — does the AI Platform team build and operate the memory layer, or does it ship inside Mio and get extracted later? | Product + Eng leadership |
| Golden ID readiness across Collexo and Nexeo — confirmed available, or a prerequisite build? | Platform Eng |
Retention defaults (volatile_ttl, standard_ttl) per institute contract class |
Product + Legal |
Whether personal_circumstance should be visible to any agent persona, or counsellor-only |
Product + Compliance |
| Region-routing requirement in current institute contracts — which, if any, mandate in-region storage today | Legal + Sales |
| Success-metric targets | Product + leadership, at build kickoff |
| Reviewer | Team | Status |
|---|---|---|
| Alok Sharma | Product | Pending |
| — | Mio / AI Engineering | Pending |
| — | Platform Engineering | Pending |
| — | Security & Compliance | Pending |
| — | CRM (Golden ID, lead dedupe) | Pending |
| — | QA | Pending |