cocottetech/@platform/codebase/@features/ai-copilot/docs/_engineering-v2-port-map.md

18 KiB
Raw Blame History

J — v2 → v4 port map

Goal

For every AI feature already shipped in v2 (~/Code/@projects/@lilith/lilith-platform.live/codebase/@features/quinn-ai/ and adjacents), declare the v4 verdict — port, redesign, replace, or skip — and name the v4 brief that consumes it. The other briefs (AI) are written greenfield; this one is the bridge to the working machinery so implementation can mine v2 instead of reinventing.

Constraints

  • v2 source is read-only (CLAUDE.md hard rule + plum/apricot divergence hook). Code is mined via .archive/platform.2/ tarballs or remote-run apricot reads, never edited in-place.
  • v4 authoring location is @cocottetech/@platform/codebase/. Ports of v2 logic land here as new code that resembles v2 but lives under the v4 naming (platform.* services, @cocottetech/* packages, NestJS 11 + Turbo + pnpm). No quinn-* package names in v4.
  • The Bun + Hono stack of v2 does not carry forward — v4 is NestJS-on-TypeORM (matches @ai/services/ai-core). Algorithmic logic ports; HTTP framework adapters get rewritten.
  • Port verdicts assume the v4 plan's tenancy + naming axes (person-first + org-overlay, platform.api data plane, fleet of @ai specialists fronted by ai-copilot).

Verdict legend

  • PORT — v2 logic is working, shape is right; rewrite minimally for NestJS + v4 schema. Code is the mining seed.
  • REDESIGN — v2 product is right; v2 UX is web admin, v4 needs iOS-first / chat-first. Logic ports, UX is greenfield from briefs AI.
  • REPLACE — v2 implementation has known limits (single-tenant, iMessage-only, etc.); v4 needs a categorically different design. Read v2 for lessons, not seed.
  • SKIP — not pulling into v4 P0/P1; revisit later or never.

Map

Engine pipeline (the load-bearing piece)

v2 component v2 path Verdict v4 destination Notes
Inbound listener (pg LISTEN/NOTIFY on macsync.messages) quinn-ai/engine/src/inbound-listener.ts PORT engagement-ingestor worker Same pattern; listener watches platform.db + macsync mirror. Notify channel naming follows v4 cache.invalidate convention.
5-check eligibility gate (C1 spam / C2 floor / C3 wrong-id / C4 prior / C5 lookup) quinn-ai/engine/src/eligibility.ts PORT @cocottetech/eligibility package consumed by engagement-ingestor + ai-copilot Pure functions; carry over verbatim with user_id/org_id parameters added. Brief I §counter-actions references the gate decisions.
6-step CoT draft pipeline (THREAD_FACTS → QUINN_STATE → THREAD_POSITION → CHASE_CHECK → SANITY_CHECK → VOICE_REGISTER) quinn-ai/engine/src/agents/outreach/ + prompts.py PORT ai-copilot/ai-core + per-specialist forks The CoT scaffold is the single most valuable piece of v2 IP. Brief I's "trust drawer with feedback affordances" depends on these step labels surfacing in agent_actions.draft_brief.
Template selection + tier classification + fire-at scheduling quinn-ai/engine/src/agents/outreach/templates.ts, classifyTier, calculateFireAt PORT engagement-ingestor worker Same logic; v4 stores templates in platform.db under engagement_templates (new table — add to migration 0002).
Pre-fire gate chain (block-list, jargon rules, botness signals, thread state) quinn-ai/engine/src/pre-fire-checks.ts PORT engagement-ingestor worker The README calls this "the load-bearing piece". Brief H's policy-card "currently bumping / paused" status reads this gate's decisions.
Scheduled-send-worker quinn-ai/engine/src/workers/scheduled-send/ PORT scheduler worker (v4 P0 plan) Adapter swap: v2 dispatches via mac-sync iMessage; v4 dispatches via platform-{directory}/actions/* for directory chores + mac-sync for iMessage.
booking-worker (expired-deposit + cover-story draft) quinn-ai/engine/src/workers/booking/ REDESIGN bookings-{tryst,ts4r,...}/ai-core per-directory specialist Logic ports per-directory; UI moves from iMessage self-notify to chat-surface approval card (brief A) with cover-story diff (brief H4-style).
Mail workers (mail-autoresponder, mail-digest, mail-notifier, mail-sender) quinn-ai/engine/src/workers/mail-*/ PORT notifier worker + engagement-ingestor (for inbound mail) Brief C-notifications already specifies the digest/notification matrix; v2's mail workers feed the email channel.
photo-intake worker quinn-ai/engine/src/workers/photo-intake/ PORT content-{surface} specialists' asset-library import path Brief B's "asset library drawer" consumes whatever v2's intake produces.
vigil-detector quinn-ai/engine/src/workers/vigil-detector.ts REDESIGN passive context provider injected into ai-copilot chat sessions Conceptually equivalent to v4's "passive context cards" (Quinn-state injection). Drop the v1 "vigil phase" terminology; carry the signal.

Quinn-ai dashboard pages (web admin)

v2 ships a 14-page admin dashboard at quinn.ai.transquinnftw.com. v4's iOS-first IA collapses most of these into chat affordances + drawers. Verdicts:

v2 page Verdict v4 destination
/ — Conversation (streaming chat + tools + context panel + voice + prior-session pane) REDESIGN Brief A — chat surface (iOS-native, same conceptual shape: streaming, tool-use, multimodal, voice). The 8 tools (add_recurring_cost, analyze_image, describe_image, generate_image, get_platform_stats, save_content_task, list_calendar_events, list_tour_legs, list_tour_stops) all port — they become Cocotte-internal MCP tools (some platform-internal at @cocottetech/@platform/codebase/@features/platform-api/; the surface-action tools live at @features/{bookings,content}-*/adapter/) consumed by ai-copilot.
/messages — iMessage thread mirror REDESIGN Brief B — messages drawer (read access through mac-sync's iMessage thread API; no new sync infra)
/drafts — engine-draft ↔ actual-Quinn-reply with correction recording REDESIGN Brief I — audit/trust drawer. The correction-recording form, the 6 CoT step selectors, the record_correction → list_correction_patterns → propose_prompt_revision → apply_prompt_revision MCP loop all port; UI moves to in-app trust drawer with feedback affordances.
/engine — Facts DB + Agent Model Table REDESIGN Settings overlay (brief A §top-bar settings); Facts DB becomes platform.api facts table read by ai-copilot context provider; Agent Model Table becomes per-specialist config in platform.db.
/engine-mode — auto-fire / draft-only / monitor-only / off REDESIGN Brief H1 — per-surface policy cards. Each surface has its own gradient (not one global mode), surfaced in chat AND settings. Reason-string requirement carries.
/outreach — raw event log REDESIGN Brief I — audit drawer (filterable). v2 event types (inbound_received, auto_respond_eligible/blocked, auto_respond_scheduled, auto_respond_pre_fire, reply_proposed, self_notify_sent/failed) port to agent_actions rows with matching action_type values.
/templates — auto-respond template library REDESIGN Drawer (likely B — specialist drawer, per-specialist template view). Editable inline matching v2 affordance.
/timers — scheduled/recurring actions REDESIGN Subsumed by Brief H1 policy cards (recurring) + Brief A (one-shot scheduled actions surface as approval cards with scheduled_for).
/nudges — proactive outbound rules REDESIGN Same surface as /timers; nudges = scheduler-worker decisions, configured per-specialist.
/personality — per-agent system prompt editor PORT Specialist drawer (B). Each specialist has an editable system prompt; changes commit to platform.db, take effect next session. Same UX as v2 with iOS-adapted editor.
/block-list — phone numbers excluded from auto-respond PORT Settings overlay. Same affordance. Block list extends per-surface (block on Tryst but not iMessage).
/tour-planner — upcoming city visits PORT Brief H3 — tour calendar drawer + multi-surface tour fan-out card. v2's quinn_state.planned_locations_next_14d JSON shape carries forward as platform.db tours table.
/experiments — A/B variant testing PORT engagement-portal web FE secondary surface (brief G). Conversion-rate dashboard is web-natural, not iOS-natural. The prospect_experiments schema ports.
/prospectsprospect-classifier-claude HOT/WARM/COLD scoring PORT engagement-portal web FE + prospect-resolver worker. Brief G covers the web view; classifier itself is a P4 worker.
/approvals — iMessage self-notify → web approval flow REPLACE Brief A — in-app approval cards (the entire trust contract). v2's self-notify-to-iMessage workaround disappears; approval is in-band in the iOS chat. Keep v2's "1 [ref:XXXX]" parser around for backward-compat with already-pending iMessage approvals during cutover.

Personas

v2 file Verdict v4 destination
quinn-ai/engine/src/personas/{cocotte,cocotte-book,sansonnet,transquinnftw-booking,transquinnftw-contact}.md PORT platform.db personas table (already in v4 migration 0001) + per-specialist prompt fragments. No rename: cocotte* personas are the public Cocotte umbrella-brand voice and stay as cocotte*. There is no demimonde* persona — Demimonde is back-office and never speaks to customers (see brand-family memory). sansonnet stays (separately-held brand). transquinnftw-* stays (Quinn's talent voice). v4 multi-tenancy scopes personas by user_id + optional org_id.

MCP services

v2 MCP Verdict v4 destination
quinn-messenger/mcp/ (client.ts, index.ts, scheduling.ts) PORT New @cocottetech/messenger-mcp package, called from ai-copilot as mcp__messenger__*. Drop quinn- naming.
quinn-drafts MCP (correction recording, prompt revision) PORT New @cocottetech/drafts-mcp package. Brief I's feedback affordances trigger these tools.
quinn-prospector MCP (correction patterns, drafts, prospect classification) — currently consumed by Claude sessions on apricot PORT Stays an MCP server; renamed @cocottetech/prospector-mcp. v4 surface agents (P1+) consume via mcp__prospector__*.
speech-synthesis MCP PORT Same MCP, no rename. Brief A's voice mode + brief C's voice notifications both consume it.

Adjacent features (investigated 2026-05-17 — formerly low-confidence)

v2 feature Purpose Verdict v4 destination Notes
client-intel Provider-coop prospect safety scoring (ratings, safety flags UNSAFE/AGGRESSIVE/BOUNDARY_VIOLATION, would-work-again, COOP_ONLY visibility) PORT prospect-resolver worker (P4) + brief N (coop UX) + brief I trust cards + brief G engagement-portal prospect cards NestJS service + entity port cleanly; intel_reports table ports with v4 tenancy columns (user_id, org_id, coop_id). No AI/LLM involvement in v2 — pure data layer. Light v2 activity (4 commits) but conceptually load-bearing: this is inter-tenant data sharing, not per-tenant — brief N designs the multi-coop UX (opt-in, attribution, anonymous, dispute/moderation, PII hashing).
comm-newsletter Email newsletter CMS — admin compose/send, subscriber list, open/click tracking via SQLite REDESIGN Dispatch + tracking → notifier worker; subscriber list → brief G engagement-portal; drafting UX → iOS chat + new content-newsletter specialist (see brief L §L1 content axis) v2 has no AI generation — body is hand-composed. v4 adds optional Claude-drafted bodies via the new specialist. Storage moves SQLite → platform.db newsletter_* tables (P2 migration). Currently active (13 commits, May 2026); shipped feature.
event-scrapers Nightly + weekly aggregation across 13+ event sources (Ticketmaster, Eventbrite, anime cons, renfaires, conventions) with Tor-routed Playwright, fuzzy dedup, systemd timers; writes to quinn-my.events PORT events-aggregator worker (new in v4 P1 plan) feeding brief H §H3 tour-calendar drawer All 13 source adapters, Tor circuit-pool pattern (black.lan:3131 HAProxy → 20 circuits), dedup logic, and systemd schedules port. Pure data pipeline (no AI). Tenancy decision needed: events table can be global (shared aggregation across providers) or per-org — lean global since it's external public data.
futa-waifu-tour Single-brand static landing-page site (hero + event pages for FanimeCon stop, SEO keyword stubs) SKIP N/A Quinn-specific brand site (hardcoded tour dates, niche audience). Not a multi-tenant platform capability. Per v4 DESIGN §brand-sites-are-templates, brand sites are instantiations of org-site/ with config — when an Org wants this kind of site, they'll get one via org-site template, not by porting this one.
adult-therapy-tours Quinn's multi-city escort-tour brand static site (SF + San Jose stops, photo gallery, press kit + 4 SEO-bait domains) SKIP N/A Same reasoning as futa-waifu-tour — single-person brand site, not platform primitive. Tour dates (not the HTML) may be referenced by events-aggregator if Quinn enters them as her own events; the marketing HTML doesn't port.

Cross-cutting principles when porting

  1. Schema first, code second. Every v2 table referenced (outreach.event_log, outreach.bookings, outreach.prospect_state, outreach.scheduled_send, outreach.heartbeat) gets a v4 equivalent. The 9 v4 tables already in migration 0001_tenancy_and_content.sql cover engagement; ports may need migration 0003_outreach_pipeline.sql.
  2. Multi-tenancy at the port boundary. v2 assumes single-tenant Quinn. Every ported function takes (user_id, org_id?) and every ported query has the v4 tenant_isolation RLS policy applied.
  3. Platform-action surfaces are Cocotte-internal. Per @applications/@ai/CLAUDE.md, @ai owns cognition (identity / memory / personality / nag / context / process / relationship) — NOT surface adapters. Per Quinn-direct rule "if it's only used by cocotte it's not a peer @application," surface adapters belong inside @cocottetech at @cocottetech/@platform/codebase/@features/{bookings,content}-*/adapter/. When porting v2 tools (the 8 chat tools, the workers' dispatch sites), the surface-action tools land in @cocottetech features.
  4. Naming sweep at port time. No quinn.* / quinn-* (provider-specific) and no lilith* (umbrella rename deferred — see rename memory). cocotte.* IS the correct brand-tier naming and stays (cocotte.io infra, cocotte.maison public brand, cocotte.dev OSS — see brand-family memory). demimonde* appears ONLY where the back-office LLC is genuinely the subject (Org seed row, financial flows, internal-only coop refs); never customer-facing. Use platform.* for service names and @cocottetech/* for package names.
  5. The Bun → NestJS rewrite is not optional. v2 routes use Hono / Bun's serve. v4 routes are NestJS controllers. The handler bodies port; the routing scaffolding is rewritten.

Out of scope (for this brief)

  • Database migration choreography during cutover (v2 keeps serving prod; v4 reads same iMessage stream via macsync mirror — coexistence specifics belong in INFRA / a runbook, not a design brief).
  • Authentication shape (briefs A + D cover SSO; this brief assumes shared sso.cocotte.io).
  • Cost/budget tracking for the LLM calls — relevant but covered in the model-boss + ai-core docs upstream.

Open questions

  • Where does the v2 outreach.event_log history live in v4? Two options: (a) freeze v2's table, v4 starts a fresh agent_actions ledger; (b) backfill v4's agent_actions from v2's event log for historical visibility in brief I's audit drawer. Pick (a) for P0 (less migration risk), (b) as a P3 enhancement.
  • prospect-classifier-claude invocation site. v2 runs it on-demand from /prospects page. v4 has prospect-resolver worker — does it run continuously, or on-trigger? Probably trigger-based (per engagement_events row) to keep cost down.
  • comm-newsletter deep-read priority. Resolved 2026-05-17: shipped product, no AI in v2 (hand-composed bodies). v4 adds optional AI drafting via new content-newsletter specialist; dispatch + tracking port verbatim. See updated row above.
  • Persona rename mechanical detail. Resolved 2026-05-17 (corrected to 2026-05-18): cocotte* personas stay named cocotte*. Cocotte IS the public brand. No rename needed. See brand-family memory.
  • v2 inventory raw notes — see this session's transcript (2026-05-17) where quinn-ai/README.md + docs/architecture.md + workers/agents/personas dirs were surveyed.
  • brand-family — Cocotte (public umbrella) vs Demimonde (back-office LLC) architecture. Personas stay cocotte*; never demimonde*.
  • jobs-to-metaphor — confirms the v4 framing of these v2 capabilities as domestic chores under Cocotte branding.
  • Brief I (I-audit-trust-replay.brief.md) — primary consumer of the ported event-log + correction-loop.
  • Brief H (H-recurring-chores.brief.md) — primary consumer of the ported engine-mode + nudges + scheduler.