JivikaPOC · synthetic data only
Design · CRM, memory & funnel scope

Status: DRAFT v1.1 · founder decisions recorded 2026-09-24 (§10) · owner: Abinash · companion to `product/phase1-spec-v1.md` (F8–F14, §8, §11), `product/conversation-flow-v1.md` and `CLAUDE.md` (§2–§4, §8).

Jivika — Candidate CRM, Memory Layer & Distribution Funnel: Scope v1 (draft for founder review)

Status: DRAFT v1.1 · founder decisions recorded 2026-09-24 (§10) · owner: Abinash · companion to product/phase1-spec-v1.md (F8–F14, §8, §11), product/conversation-flow-v1.md and CLAUDE.md (§2–§4, §8). Sources: realtOS Operating_System.md (six planes, §6 CRM/GTM), Realtor_Memory.md, GTM_Playbook.md §10 (DL-86 consent-first), Observation_Deck.md, Backlog.md (CS-CRM), migrations 0002 0020 0022 0062 0064, Decision Log DL-56/58/59/60/61/63/86 — and Jivika's own schema, PRD and market research. This is a scope, not a build plan. Nothing here is built. Every "proposal" is marked so; every number that needs legal or sponsor sign-off says so.


1. The ask on one screen

You asked for three things and an "etc.": a candidate CRM, a memory layer, a marketing funnel, and the machinery around them. realtOS built these as planes on one event spine. Jivika needs the same shape with different contents, because our constraints are different (§2).

flowchart TD
  SPINE["Event spine<br/>append-only: who · what · when · why"]
  SPINE --> P2["Guide desk<br/>tickets, distress, stuck applications"]
  SPINE --> P3["Candidate CRM<br/>lifecycle · 360 view · consented nudges"]
  SPINE --> P4["Lenses<br/>funnel · concierge quality · cohorts"]
  SPINE --> P5["Flags and experiments<br/>copy and flow only"]
  SPINE --> P6["Sponsor reporting<br/>aggregate only"]
  MEM["Candidate memory<br/>structured profile first"] --> P2
  MEM --> P3
  MEM --> CHAT["The concierge<br/>prefill, no re-asks, warm handoff"]
  DIST["Distribution funnel<br/>source-tagged touchpoints → registered → activated → retained"] --> SPINE
drawing diagram…
PieceVerdictWhy
Event spine (extend what exists)Build firstEverything else is a lens over it. events already exists in the schema
Guide desk → ticket lifecycleBuild earlyAlready half-built (queue, distress, help tickets); F10/F19/F20 require it
Candidate lifecycle + 360 viewBuildDerived from events; the guide's working surface
Funnel + concierge-quality lensesBuildThis is how "the agent is the product" improves
Distribution / activation funnel (domain A)Build the measurementZero-CAC government distribution; the funnel is the PRD §8 scorecard (§5.1–5.5)
Jivika-run acquisition (domain B)Build later, as a separate controller-side system behind a hard wallFounder decision 2026-09-24: outreach means service messaging and Jivika-run marketing (§2.0, §5.6)
Structured memoryBuildSmart capture (#56) and warm handoffs need it
Semantic memory (vectors)Design now, build only when gatedResidency, consent and erasure must be proven first (§6.3)
Lead scoring, purchased/scraped lists, marketing to candidates, recruiter CRMDo not buildOut of scope by constraint (§9)

2. What the scope check changes (the constraints realtOS didn't have)

2.0 Founder decision (2026-09-24): two data domains, one hard wall

"Jivika-side outreach" means both proactive service messaging and Jivika-run acquisition marketing. Those are different legal roles, so they get different data stores.

Domain A — Candidates (the product)Domain B — Growth (Jivika-run acquisition)
Whose dataThe sponsor's instance; Jivika is a Data ProcessorJivika's own prospects; Jivika is the Data Fiduciary (controller)
PurposesEligibility, applying, opt-in reminders, guide help, aggregate reportingIntroducing Jivika to people who are not users yet; measuring campaigns
Holdsprofiles, applications, conversations, memory, ticketsconsented prospects, campaigns, a suppression list, click events
ChannelsWhatsApp (service, within opt-in)Off-WhatsApp: email, community, partner and content channels — never cold WhatsApp
Consentper service purpose (consents)per marketing channel, recorded, withdrawable; unsubscribes honoured
Retention§4.6shorter — proposal: 12 months from last contact
flowchart LR
  subgraph B["Domain B · Growth (Jivika = controller)"]
    PR["consented prospects"] --> CAMP["campaigns<br/>email · community · partners"]
    CAMP --> LINK["source-tagged click-to-chat link<br/>opaque token"]
  end
  LINK -->|"person taps and messages first"| REG["registered"]
  subgraph A["Domain A · Candidates (Jivika = processor)"]
    REG --> LIFE["lifecycle · CRM · memory · guide desk"]
  end
  LIFE -.->|"aggregate counts only"| CAMP
drawing diagram…

The wall — five rules:

  1. Candidate data never flows A → B. B never learns who registered, who applied, or anything about a candidate.
  2. B → A only through an opaque attribution token in the click-to-chat link; A stamps source and the campaign code. A reports back to B aggregate, campaign-level counts only — never who.
  3. No marketing message goes to a domain-A candidate in Phase I. Re-engaging candidates is a service nudge (§4.5) on the sponsor's purposes.
  4. Separate deployable, database, credentials and audit log, so infrastructure enforces the wall, not policy.
  5. The handover is disclosed. B's notice says what happens next; the first WhatsApp message tells the person they are now using the sponsor's service under its terms.

What being a controller adds. Jivika takes on the fiduciary duties for domain B — notice, consent, purpose limitation, retention, breach notification, grievance handling. Market research notes penalties up to ₹250 cr and a plausible Significant Data Fiduciary designation at 10 M+ users. Legal confirmation needed.

On "no ads". The 2026-09-18 decisions say citizen side free; no ads; no data monetisation. This scope reads "no ads" as no advertising shown to aspirants and no audience monetisation — not a ban on Jivika promoting itself. That reading needs the founder's confirmation and a decision record (§10).

ConstraintSourceWhat it means for this system
In domain A, Jivika is a Data Processor for the sponsorDPDP Rules, Rule 6 (market research); CLAUDE.md §4Candidate data is processed only for purposes the sponsor sets — service (eligibility, applying, reminders, guide help) and aggregate reporting. Jivika's own marketing therefore lives in a separate domain B (§2.0); it may never draw on candidate data, and there is no lead scoring or profiling in either domain
No ads, no data monetisation; citizen side freeDecisions 2026-09-18No audiences, no lookalikes, no data sharing with coaching partners
Consent-first; WhatsApp opt-inrealtOS DL-86 (same logic: consent, not volume); Meta rulesNo cold outbound. Every proactive message needs a prior opt-in; STOP (band karo) is honoured everywhere
Minimal retention + erasure works end to endPRD F5/F13, §11Memory, summaries, notes, embeddings and CRM rows must all be deletable by the delete verb — including derived data
Shared-phone safetyNon-negotiable #7, F11The unit is the person (profile), never the phone; memory and CRM are profile-bound. Schema gap: profiles.simulated_number is UNIQUE, which forbids two profiles on one number (§4.1)
Never guilt; humans at the edgesNon-negotiables #5, #6Memory of missed days can only trigger a lighter task; distress content is a restricted class — guide-only, never used in nudges, metrics detail or memory
Verified or labelledNon-negotiable #2Every remembered fact carries its source and a self_reported label; low-confidence facts don't drive behaviour
India residency on the production pathCLAUDE.md §4realtOS uses Voyage/OpenAI embeddings and Claude — not allowed in production here. Sarvam-class India-hosted models only
Synthetic data only (POC)CLAUDE.md §5AEverything can be prototyped, but no real aspirant enters the system
Nothing employer-facingCLAUDE.md §2No recruiter/employer CRM, ever in Phase I; F22 stays a passive inbound capture

3. What realtOS built, and how it maps

realtOS's principle (Operating_System.md §8): build the lens when the metric becomes the thing you steer by; foundation first — spine, then flags, then lenses.

realtOS planeWhat it didJivikaChange
0 · Event spineAppend-only events + audit_log; every plane is a lensSame. Schema already has events (state transitions)Extend with domain facts (§7.1)
1 · Marketplace opsFill board, roster, money opsNo analog — one-sided, no moneyReplaced by notification-cycle ops: ingestion queue + human approval (already CLAUDE.md §4)
2 · CS / exception ops7 judgment queues; ops_cases → incidents (ticket = incident, cases = signals); lifecycle, notes, reply-into-thread, money actionsGuide desk (F10, F19, F20)Same ticket model; no money actions (Jivika handles no money) — a large simplification
3 · CRM / GTMprospects funnel, campaign drip, compliant nudges (cooldown + cap ledger, STOP honoured), attribution, two-sided balancingCandidate CRM (A) + Growth domain (B)Split by legal role. Drop lead scoring, purchased lists and cold SMS; keep the nudge ledger (A), and campaign sequencing, suppression and attribution (B only); one-sided so no liquidity balancing
4 · Observation deckFunnel, concierge quality (turns-to-post, re-ask rate, deflection, CSAT), cohorts, anomalies, transcript replayOps lenses + a separate sponsor dashboard (F12/F21)Two audiences; the sponsor sees aggregates only
5 · Flags + experimentsFlag = gate + live config; experiment = flag + events, sticky bucket, z-testSame, narrowerExperiments only on copy and flow order — never eligibility, consent, distress or fees
6 · Investor / steeringGMV, unit economics, growth accountingSponsor pack (F21)Applications assisted, error reduction, fake notices corrected
Memory (DL-63)Dual: structured profile always in context + pgvector semantic recall; memory is data, never instructions (D51)Candidate memoryStructured first; vectors gated; erasure and residency are hard gates

4. The candidate CRM

4.1 Entity model — the person is not the phone

person (profile)  ── many phones (a household shares one)
   │                   └─ a phone ── many people
   ├─ consents (versioned, per purpose)
   ├─ applications (one FSM each; the schema's status ladder)
   ├─ conversations → messages
   ├─ tickets (guide desk)
   └─ memory (structured facts, each with source + confidence)
  • Schema gap to close: profiles.simulated_number ... UNIQUE contradicts F11. Introduce a profile_phones link (and re-auth state per profile: PIN or DOB after 24 h idle). Ticket #24 already tracks shared phones — this belongs there.
  • consents is new: profile_id · purpose · version · granted_at · withdrawn_at. Purposes are the sponsor's: service, reminders, docs_via_digilocker, aggregate_reporting. There is no marketing.

4.2 The lifecycle — derived from events, never hand-edited

realtOS derived its funnel from monotonic *_at timestamps so each stage is a subset of the last. Same here: a candidate's stage is a read of their events.

stateDiagram-v2
  [*] --> registered: first message (source stamped)
  registered --> profiled: answers given
  profiled --> saw_value: eligible list shown
  saw_value --> consented: DigiLocker consent
  consented --> applying: application started
  applying --> applied: candidate submitted, confirmation kept
  applied --> engaged: daily check-ins
  engaged --> retained: active at D30
  retained --> credentialed: 20 check-ins
  credentialed --> result_day: results out
  registered --> dormant: 30 days silent
  engaged --> dormant: silent
  dormant --> engaged: user returns
  saw_value --> opted_out: band karo
  engaged --> erased: delete confirmed
drawing diagram…

Value before identity is visible in the order: saw_value comes before consented. The funnel measures exactly that.

4.3 The Candidate 360 — the guide's working surface

One page per person: stage · timeline (events, tickets, applications) · consent state · memory summary · next best action · notes.

  • Next best action is deterministic (rules on stage + stall + deadlines), never an LLM verdict — same principle as eligibility.
  • Access is a permission, not a default. Roles: guide (own tickets and the context they need), supervisor, ops admin, sponsor viewer (aggregate only), engineer (no PII). Phone numbers masked by default; revealing needs a reason, and every read of a candidate record is written to an audit log (the same who/what/why/when as document_access_log, F13).
  • Restricted class: distress history is visible only to the on-shift guide and a supervisor.

4.4 The guide desk — the CS-CRM, adapted

realtOS's design pass (migration 0064, "Option B") settled it: the ticket is the incident; signals are attached to it, because one event can spawn several signals but the human works one ticket. Jivika adopts that.

Ticket kindTriggerPriority · SLAHuman job
DistressDetector fires (built)P0 · ≤ 60 minCall; Tele-MANAS 14416 already surfaced
Form error / validation loop3 failures on one field (built as help)P1 · ≤ 2 h in an application windowFix in chat
Stuck applicationDigiLocker failed / declined, packet stalledP1 · ≤ 2 hUnstick; manual path
Fake-notice reviewForwarded notice with no matchP2Adjudicate, update the registry
Data requestErasure / "what we hold" that needs a humanP1 · mandatedCompliance process; audited
Payment-guidance failureFee step failed on the portalP2Advise — Jivika moves no money
Abuse / spamPattern detectorP2Block / warn

Lifecycle (realtOS 0062): open → claimed (named owner) → resolved / dismissed, with who/when, notes, an audit trail, and reply-into-thread (attributed to a guide) so the promise "a person will call you" is closed in the conversation. The POC already has the queue, the resume-after-resolve behaviour, and the SLA per kind; the gaps are ownership, notes, history and persistence.

4.5 Segments and nudges — purpose-limited

Only service segments exist: eligible-not-applied for notification X at T-7 / T-3 / T-1 (F8, opt-in), stalled at DigiLocker, applied, admit card pending (F17). Nudge rules, straight from realtOS's ledger (lib/crm/nudge, DL-61) with Jivika's added constraints:

  • Opted in for that purpose (a consents row), STOP honoured (band karo becomes a persisted flag, not just a reply).
  • Cooldown and hard cap via a nudge_sent ledger; thresholds are flags (live-tunable).
  • Utility templates only, capped for cost (F14); the daily check-in stays user-initiated inside the 24-hour window.
  • Never guilt: a lapse produces a lighter task, never a reminder of the lapse. Nothing distress-derived is ever a nudge input.
Data classExamplesProposed retentionWho sees itOn delete
Identity & profilename, DOB, category, stateuntil erased, or 24 months idle (proposal)the person; guides on neederased
Documentsmarksheet, photo, signatureonly while an application needs them; per-user encryptionaudited reads onlyerased, key destroyed
Conversation logmessages90 days (proposal)guides (audited)erased
Memorystructured facts, summaries, embeddingstied to the profilethe concierge; guides (audited)erased including derived data
Restricteddistress contentshortest that satisfies the protocol (proposal)on-shift guide + supervisorerased; ticket keeps a redacted stub
Aggregatesfunnel countsindefinite, k-anonymoussponsorn/a

5. The distribution funnel (measured) and Jivika-run acquisition (controller side)

5.1 Two funnels, two jobs

  • Distribution / activation (domain A) — the government puts the official number on every notification (~zero CAC; strategy/roadmap-v2.md). Here we measure and tune through the product. The funnel is the PRD §8 scorecard; cost per activated candidate (WhatsApp + LLM + guide time) is the number the sponsor and F14 care about.
  • Jivika-run acquisition (domain B) — reaching people outside government distribution (§5.6). Its CAC is real, so it is measured as spend per registered and per activated (aggregate, via the wall).
  • No cold outbound on WhatsApp, in either domain: opt-in is required, and a marketing template costs about ₹0.86 vs ₹0.115 for utility (market research, Oct 2026 rates). The first WhatsApp message is always the person's own.

5.2 Stages and the leak map

Stages track the PRD §8 metrics, so the funnel is the success scorecard:

StageDefinitionPRD target
Registeredfirst message5 L (R0) → 20 L (R1)
Saw valueeligible list shown—
Activatedeligible list + DigiLocker + 1 application + day-1 task35% → 45% of registered
Appliedcandidate submitted; confirmation kept50k → 5 L cumulative
Retainedactive at D30≥ 40% → ≥ 45%
Credentialed20 check-ins5% → 8%
Advocatecertificate shared / referral≥ 15% shared

Stalls (where it leaks, each mapped to a product fix): profiled, never saw a list · saw the list, never consented · consented, never applied · applied, never checked in · streak dropped (→ a lighter task, never guilt). Fixing exceptions is growth — realtOS's insight, unchanged.

Built in #86 (/ops/funnel): the §4.2 8-stage FSM (registered → profiled → saw_value → consented → applying → applied → engaged → retained) and all five stalls above, derived purely from the event spine. Three honest departures from this table, each labelled in the lens itself rather than silently assumed: Retained has no real wall-clock D30 in a synthetic one-shot conversation, so it reads as a proxy (a check-in streak ≥ 2 — returned on a second distinct day). Credentialed and Advocate are not shown at all — neither has a built console feature to derive them from (no admit-card/result flow, no credential card). The "profiled, never saw a list" stall is structurally always zero in this build: confirming the profile card and showing the eligible list fire in the same reply() turn (chat.ts, asserted by events.test.ts) — the lens shows this row and explains it rather than hiding it.

5.3 Touchpoints and attribution

Every entry point is a source-tagged click-to-chat link or QR: notification footer, recruiting-body page, Rozgar Mela SMS, sponsor social, partner channels. The prefilled first message carries the source code; the first inbound stamps source on the person at registered. That is user-initiated, so it opens the 24-hour service window and needs no template. (Unsure — verify with Meta: whether click-to-chat entry points carry free-conversation rules under the 2026 pricing.)

5.4 The loops we can earn (all consented, all in-product)

  • The fake-notice hook. People forward suspicious notices into groups all day. A number that answers "Verified / Old / Not found" in 30 seconds (F2) is the strongest top-of-funnel we have — and it is also useful to non-users. Decision needed (§10): bring it forward of guided apply?
  • Certificate sharing (F18) — the credential card carries the entry link.
  • Referral — a click-to-chat link a candidate can forward; the referee opts in by messaging. No bounty (we don't handle money).

5.5 What "B2B / partner" means here

Recruiting bodies, the sponsor and coaching partners are organisations, not candidates. Tracking that pipeline is Brijesh's work and lives in Notion, not in this product. Putting it in the candidate CRM would drift toward employer-facing (CLAUDE.md §2).


5.6 Jivika-run acquisition (domain B)

realtOS reached the same conclusion for its own launch (DL-86): consent-first, not a cold blast. The reasoning carries over — cold contact is a consent problem at any volume, and on WhatsApp it is also a brand-standing problem.

  • Sourcing: people who consented, or who were reached person to person. No purchased or scraped contact lists.
  • Channels (all off-WhatsApp): partner and coaching-institute introductions, community groups and orientation sessions, content (video, social, Telegram) carrying the click-to-chat link, email to opted-in prospects, CSC / Rozgar-Mela stalls, referrals.
  • Funnel: reached → clicked → registered → activated. The last two arrive only as aggregate counts across the wall (rule 2).
  • Reuse from realtOS, on the domain-B store: idempotent campaign send with a status gate; the nudge ledger (cooldown, hard cap, opt-out); referrals; experiments; attribution stamps. Segments are by channel and source only — never by candidate attributes, and no lead scoring.
  • Contextual, not personal, paid media: buying media is fine; uploading personal data to an ad platform (custom or lookalike audiences) is not in Phase I — it is a data-sharing and residency question. (Unsure — needs legal.)
Domain-B data classExamplesProposed retentionOn unsubscribe / erasure
Prospectname, email or phone given with consent, source, consent record12 months from last contact (proposal)erased; a hashed suppression entry remains so we never re-contact
Campaigncopy, schedule, cost, variantindefiniteno personal data
Click eventtoken, time, campaign90 dayserased with the prospect
Aggregate resultregistrations and activations per campaignindefinite, campaign-level onlyn/a

6. The memory layer

6.1 What we remember — and what we never do

We remember (each fact: source message · confidence · self_reported label)We never store as memory
Preferred name, register (Hinglish / Hindi / English)Aadhaar numbers, document contents (documents stay under per-user keys; memory holds only refs and status)
The four profile answers (DOB, qualification, category, state)Distress content (a restricted ticket, not memory)
Which notices they follow; deadlines they asked aboutAnything about other people on a shared phone
Application refs and status; last active; streakFree-text chatter beyond a short summary
Guide-visible notes (separate, restricted table)Inferred traits (mood, income, caste beyond what they declared)

6.2 How memory is used — and the four uses that are forbidden

Used for: pre-filling with the default shown in the card (the common-ground principle — never silent), skipping re-asks (smart capture, #56), greeting by name, "like last time", and a warm handoff (a guide opens a ticket and already has the summary). Never used for: deciding eligibility (rules engine only), guilt ("you missed…"), marketing or segmentation for ads, or influencing anything across people.

6.3 Architecture — structured first; vectors only when gated

flowchart LR
  LOG["messages<br/>(raw, short retention)"] --> X["extract facts<br/>deterministic first"]
  X --> PROF["structured profile<br/>always in context"]
  LOG --> SUM["summaries<br/>India-resident model, async"]
  SUM --> GUIDE["guide handoff"]
  LOG -.-> VEC["semantic memory<br/>pgvector · GATED"]
  PROF --> CHAT["concierge turn<br/>proposal only"]
  ERASE["'delete' verb"] --> PROF
  ERASE --> SUM
  ERASE --> VEC
drawing diagram…
SliceWhatGate
M1Structured profile, built deterministically from answers and events (realtOS did the same first: DL-63 M2.0)none — start here
M2Async summaries for guide handoff (never on the reply path)India-resident model; retention window agreed
M3Semantic recall in pgvector inside our own database — no external vector service (realtOS's call, and doubly right for DPDP)India-hosted embeddings · consent for the purpose · proven erasure of embeddings · retention agreed
M4Aggregate mining of confusion (which prompt confuses people)on de-identified, aggregate data only

6.4 Guardrails (carried over and tightened)

  • Memory is data, never instructions (realtOS D50/D51). It is injected as untrusted context; it can only write soft fields, so it cannot be poisoned to change a state or an eligibility outcome.
  • Bounded and async: extraction runs off the reply path; the profile is cheap; vector retrieval (when it exists) is top-k and only when it adds value.
  • Right to see and to forget: mere data ("what we hold") and delete (built) must cover all derived data. A test for "erasure removes memory, summaries and embeddings" is a launch gate.
  • Profile-bound: memory is keyed by profile_id. On a shared phone the assistant asks "Rohit ya Sunaina?" before it uses any memory.

7. The event spine and the lenses

7.1 The spine already exists — extend it

events(at, profile_id, flow, from_state, to_state, actor, reason, cost_inr) records state transitions. That is enough for the funnel and the lifecycle. It is not enough for facts that aren't transitions. Proposal: add name and props jsonb (as realtOS did), with a hard rule — props hold ids and codes, never free text or PII.

Built (slice 0, #85): packages/schema/src/events.ts — a typed DomainEvent (each event names its props; every string is an enum or a short code, so free text cannot type-check) and migration 20260924000001_events_domain_facts.sql (name, props, flow/to_state optional, a CHECK backstop that rejects any non-code string). The console emits from reply() and the workspace: conversation_started · answer_captured{field,via: asked|sentence|correction} · reask{field,n} · profile_card_shown · profile_confirmed · eligible_list_shown{n,k} · command_used{command} · consent_granted{purpose,version} / consent_declined · document_pulled{type,why} (the audited read) · claim_selected{claim: age|ncc|other} · form_card_shown/confirmed{card} · form_card_held{card,n} (a card withheld because validation failed; the rule ids go to the guide ticket, never into props) · application_status{status} (the schema statuses; eligible and started today — one event with a status prop instead of application_<status>) · ticket_opened/resolved{kind} · distress_detected{from} · erasure_requested/completed. Two additions to the proposal below, needed for the correction-rate lens: profile_card_shown, profile_confirmed, and command_used. A fuzz test sends PII-shaped messages and proves no prop contains anything typed. Erasure: finishing a delete keeps the spine's counts but cuts the link to the number (phone → "erased"). Not emitted yet (nothing to emit): application_status beyond started, checkin_done, nudge_sent, record_read, ticket_claimed.

Taxonomy to emit (proposal): conversation_started{source} · answer_captured{field} · reask{field,n} · eligible_list_shown{n,k} · consent_granted{purpose,version} · document_pulled{type} · application_<status> · checkin_done · ticket_opened/claimed/resolved{kind} · distress_detected · nudge_sent{kind} · erasure_requested/completed · record_read{by,reason}.

7.2 The lenses (build each when the metric becomes the thing we steer by)

LensAudienceReads
Funnel + leak mapopsstage timestamps; conversion and stalls
Concierge qualityops, conversation designerturns-to-value, re-ask rate per question, correction rate on the profile/review cards, % conversations needing a guide, cost per 10 turns. The debugger's rules are these metrics on a single thread — the lens is the same rules over all threads
Cohorts & retentionopsD1 / D7 / D30 by source, state, category, gender
Anomaliesopserror-rate spike per field map, fake-notice spike, guide backlog
Transcript viewerguidespermissioned, reason-required, audited
Sponsor dashboard (F12/F21)sponsoraggregates only, minimum cell size (proposal: 20), CSV export

7.3 Flags and experiments — narrow on purpose

Flags gate each cycle launch and each new field map (CLAUDE.md §6). Experiments run only on copy and flow order, with sticky assignment by profile_id and exposure events. Never on eligibility, consent, distress handling or anything a fee touches, and never a dark pattern. Personalization itself is an experiment (does memory lift turns-to-value?) — realtOS's M5.


8. Build order — foundation first, small visible wins

Constraint that shapes it: today the console holds everything in browser memory (persistence is #23) and /ops is publicly reachable (#13). Anything with real server routes waits for those two.

SliceWhatDepends onDone when
0 ✅Event spine in the console — emit the taxonomy from reply()/workspace; schema for name/props; in-memory store + JSON export—events visible next to each thread; debugger unchanged
1 ✅Funnel lens on synthetic events — stage derivation, conversion, stalls; a synthetic cohort (9 leads, deterministic, driven through the real engine — apps/console/lib/funnel/cohort.ts) so it isn't emptyslice 0, #63/#62/ops/funnel shows a real leak map (2026-10-01)
2Ticket lifecycle — owner, notes, history, reply-into-thread; ticket kinds from §4.4#23 persistence, #13 gatea guide can claim, note, reply and resolve
3Structured memory M1 + mere data + erasure testslice 0, #56erase removes profile and memory; test proves it
4Consents + nudge ledger — opt-in per purpose, cooldown/cap, STOP persisted#60 remindersF8 reminders obey the ledger
5Attribution — source-tagged links, stamped at registeredslice 0funnel splits by source
6Sponsor dashboard + flags/experimentsslices 1–5F12 met on synthetic data
7 (gated)Summaries (M2), semantic memory (M3)residency + consent + retention decisionsgates in §6.3 all met
B0Growth-domain foundation — a separate store, consent and suppression list, its own audit log, and the wall's tests (no A → B fields; aggregate-only join)founder decision recorded; legal review of the noticewall test suite green
B1Consented prospect ingest + first-touch channels (partner, community, email) with token-tagged linksB0, slice 5a tokenised link stamps source in domain A
B2Campaign engine (sequencing, cap, unsubscribe) + the aggregate attribution reportB1spend per registered / activated by channel on synthetic data

B-slices come after A-slices 0–5, and are not console work: domain B is a separate app and store so the wall is real.

Existing tickets this touches: #13 gate /ops · #23 persistence · #24 shared phones (also the UNIQUE fix) · #56 smart capture (first consumer of memory) · #60 reminders · #61 fake-notice · #62 cost meter · #63 more debugger rules.


9. What we deliberately do not build

  • Lead scoring or any profiling of people, in either domain — segments are by channel and source, never by attributes of a person.
  • Marketing to domain-A candidates — no marketing templates, no drip campaigns to them, in Phase I.
  • Purchased or scraped contact lists, and uploading personal data to ad platforms (custom or lookalike audiences).
  • A recruiter / employer CRM (Phase 3, and not in this system).
  • An external vector database or a US-hosted embeddings/LLM path in production.
  • Paid CRM SaaS holding candidate data (residency, custody).
  • Money actions in tickets (refunds, reversals) — Jivika moves no money.
  • Cross-person recommendations from memory.

10. Decisions

Recorded (founder, 2026-09-24)

#QuestionDecision
1Processor-only stance?No — outreach means both service messaging and Jivika-run acquisition. Resolved as two data domains with a hard wall (§2.0): A = candidates (processor), B = growth (controller)
2Semantic memory in Phase IHold until the gates are met (§6.3)
3What to build first#56 (smart capture), then slice 0 (the event spine)

Still open

#DecisionRecommendation / owner
4Confirm the reading of "no ads" (§2.0) and record the two-domain decision — CLAUDE.md §8 and §4 currently say Jivika is a Data Processor, and the Notion Decision Log needs the entryFounder approves the wording; I have not edited CLAUDE.md
5Does the sponsor accept Jivika-run marketing alongside a government-branded service? Two brands, one numberBrijesh
6Legal review of controller duties for domain B, marketing consent by channel (email / SMS / WhatsApp) under DPDP, the retention windows in §4.6 and §5.6, and guide notes as personal dataLawyer + sponsor
7Budget and channels for domain B, and who owns the channel workFounder
8Fake-notice checker as the top-of-funnel hook — before guided apply?Keep it after apply (as decided) unless the sponsor wants an early public win
9Guide roster and access model (PMIS interns; who sees what)The roles in §4.3
10Where the B2G pipeline livesNotion (Brijesh), not this product

Unsure / to verify: Meta's 2026 rules for click-to-chat entry points; whether the sponsor brands outreach; DPDP Consent Manager obligations from 13 Nov 2026 and how they interact with consents; whether uploading hashed identifiers to ad platforms is permissible under DPDP and our residency rule.

Source map: realtOS Operating_System.md §3–§8 · Realtor_Memory.md · GTM_Playbook.md §10 · Backlog.md (CS-CRM) · migrations 0002 0020 0022 0062 0064 · DL-56/58/59/60/61/63/86 · Jivika phase1-spec-v1.md F5/F8–F14/F17–F22, §8, §11 · market-research-2026-09.md (DPDP, Meta rates) · supabase/migrations/20260923000001_init.sql.