31 KiB
@cocottetech — Designing the V4 Platform
Status: Design phase
Date: 2026-05-16
Lineage: v0 egirl-platform (viky-era, ambitious 27-app monorepo) → v1 lilith-platform (54-feature SaaS, shipped only partial) → v2 lilith-platform.live (Quinn-personal, currently in production) → v3 @atlilith (brief intermediate workspace, skipped — no code shipped; superseded by rename to v4) → v4 @cocottetech (org-aware, provider-generic, multi-tenant)
1. Why a V4?
V2 works, but is outgrowing the single-person frame:
- Quinn now operates 2 parent orgs (Lilith Apps, Demimonde — back-office LLC) and multiple customer-facing brands under the Cocotte umbrella (ADULT Therapy Tour, Futa Waifu Tour, ftw.pw, future merche biche); Sansonnet is a separately-held independent venture
transquinnftwis both a standalone provider AND org-admin of Demimonde — V2 has no concept of "org"- V2's
user-datafeature should really beorg-analytics(analytics aggregating at both user AND org level) - V2's services are named
quinn.*— fine for Quinn's instance, but ossifies the "platform = Quinn" assumption that prevents onboarding new providers - V1 has features V2 dropped (marketplace, profile/attributes, bookings, payments, reviews, trust, streaming) that will be needed eventually — V4 architecture must accommodate mining them
V4 keeps everything V2 has working, generalizes the naming, and adds the tenancy model V2 lacks.
2. Core Concepts
Three concentric layers
┌──────────────────────────────────────────────────────────┐
│ PLATFORM (Lilith Apps ehf — the tech company) │
│ Infrastructure, shared services, admin │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ PROVIDER (user / org tenants) │ │
│ │ - Person: transquinnftw, future-provider-x │ │
│ │ - Org: demimonde, sansonnet, future-merche-biche │ │
│ │ ┌──────────────────────────────────────────────┐ │ │
│ │ │ CLIENT (the provider's customers) │ │ │
│ │ │ Bookings, messaging-from-client-side │ │ │
│ │ └──────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────┘
Tenancy model: Person-first, Org-as-overlay
Person (primary tenant)
├── standalone mode (most providers start here)
└── may admin or join one or more Orgs (optional)
Org (optional overlay)
├── owner: 1 Person
├── admins: N Persons
├── members: N Persons
└── brands / domains / sub-entities attached
Worked example — transquinnftw + Demimonde:
transquinnftwis a Person tenant with their own profile (transquinnftw.com), inbox, bookings, analyticsdemimondeis the back-office Org tenant (the LLC that holds the talent contracts + financial flows); Cocotte is the public-facing umbrella brand it operates under, with brand site atcocotte.maison. Customers never see the name "Demimonde."transquinnftwis the owner ofdemimonde— when logged in, they see a context switcher:[ Personal | Demimonde ]- Future providers can:
- Operate as Person-only (no org needed)
- Be a Person + admin of an Org
- Be a Person who is just a member of someone else's Org (e.g., joining Demimonde as a managed talent)
What this is NOT
- ❌ Not "org-as-workspace" where Person logs into a single tenant context (Slack/Notion model)
- ❌ Not "single Person per Org" — Orgs can have multiple members
- ❌ Not mandatory — most providers will operate without ever touching an Org
3. Architecture Principles
- Person-first, Org-optional. Onboarding never asks "what's your org" — that's a later upgrade.
- Provider-generic in code. Internal package names contain no person/org name. Quinn's instance lives at
quinn.*domains, but the code isprovider-portal,ai-assistant,messenger, etc. - Sibling services stay sibling. mail-sync, mac-sync, knowledge-platform, agents — peer services consumed over HTTP/MCP. Not inside the platform monorepo.
- ML/AI work belongs in peer apps, never in the platform. Crystal-AI, image diffusion, translation, content moderation, classification, RAG — all live under
~/Code/@applications/@{ai,ml,imajin}/and are called over HTTP/MCP. The platform contains orchestration (request routing, prompt assembly, draft tracking), never weights or training data. If a v1 feature mixed orchestration + ML, port only the orchestration part. Noml-service/directories in@platform/. - Brand sites are templates. Cocotte (umbrella), Sansonnet (separately-held), ADULT Therapy Tour, Futa Waifu Tour, future merche biche — each is an instantiation of
org-site/with config, not a forked codebase. - Monolith repo holds the full lineage. All three prior versions live inside this repo as zstd-compressed tarballs under
.archive/, tracked through Git LFS. The whole point of@cocottetechis to be the canonical workspace — having v0/v1/v2 co-located here is by design, not a bloat problem. (Practical caveat: the LFS push hit Forgejo's reverse-proxyclient_max_body_sizelimit on the first attempt — that's a server config fix tracked in Phase 5.7, not an architectural pivot.) - No leakage between tenants. Org A's data invisible to Org B. Person A's data invisible to Org A unless explicitly shared.
- Schema is the contract. Add
orgs,org_members,org_idforeign keys. Migrations are forward-only; no downgrades after Phase 2.
4. Directory Layout
~/Code/@projects/@cocottetech/
│
├── @platform/ ← V4 monorepo (NestJS + React + Swift, Turbo + pnpm)
│ ├── codebase/
│ │ ├── @features/ ← feature-rooted; each feature owns its surfaces
│ │ │ ├── ai-copilot/ ← Quinn-facing front-door specialist
│ │ │ │ ├── ai-core/ (NestJS @ai instance, port 3791)
│ │ │ │ ├── ios-fe/ (Swift/SwiftUI — primary AI UI;
│ │ │ │ │ ported from lilith-messenger-ios)
│ │ │ │ └── web-fe/ (React — secondary; ai.cocotte.maison)
│ │ │ ├── content-onlyfans/ ← P1 per-surface specialist
│ │ │ │ └── ai-core/ (NestJS @ai, port 3792)
│ │ │ ├── content-x/ ← P2 per-surface specialist
│ │ │ │ └── ai-core/ (NestJS @ai, port 3793)
│ │ │ ├── content-{instagram,tiktok,threads,...}/ ← P3 social surfaces
│ │ │ │ └── ai-core/ (NestJS @ai, ports 3794+)
│ │ │ ├── bookings-{tryst,ts4rent,slixa,eros,...}/ ← P3 directory axis
│ │ │ │ └── ai-core/ (NestJS @ai)
│ │ │ ├── cocottetech-api/ (NestJS data plane, port 3060, on black)
│ │ │ ├── scheduler-worker/ (polls content_posts; dispatches platform skills)
│ │ │ ├── engagement-ingestor/ (pulls inbound across surfaces)
│ │ │ ├── prospect-resolver/ (P4 — cross-surface prospect dedup)
│ │ │ ├── notifier/ (iOS push / iMessage / email digest)
│ │ │ ├── cache-rebuilder/ (vps-0 — consumes cache.invalidate)
│ │ │ ├── content-portal/ (secondary web — calendar, asset library)
│ │ │ │ └── web-fe/
│ │ │ └── engagement-portal/ (secondary web — prospect CRM)
│ │ │ └── web-fe/
│ │ └── @packages/ ← shared libs (NestJS modules + Swift packages)
│ │ ├── cocottetech-context-providers/ (impl @ai's ContextProvider interfaces
│ │ │ against platform.api)
│ │ ├── auth-provider/ (SSO client for V4 services)
│ │ ├── i18n/
│ │ └── ui-shared/ (React + Swift shared design tokens)
│ ├── deployments/
│ │ └── @domains/ ← per-domain deploy configs
│ │ ├── cocotte.io/
│ │ ├── ai.cocotte.maison/ (V4 web-fe entry point)
│ │ └── ...
│ ├── infrastructure/ (sql migrations, ports.yaml, Caddy/nginx)
│ ├── docs/
│ ├── scripts/
│ ├── CLAUDE.md
│ ├── package.json
│ ├── turbo.json
│ ├── pnpm-workspace.yaml
│ ├── pnpm-lock.yaml
│ └── tsconfig.json
│
├── .archive/ ← read-only history
│ ├── platform.0/ (egirl-platform, v0)
│ ├── platform.1/ (lilith-platform, v1)
│ ├── platform.2/ (lilith-platform.live, v2)
│ └── ARCHIVED.md (lineage notes + mining map)
│
├── tooling/ ← shared scripts (carried from @lilith)
├── .content-lifecycle/ ← content workflow config
├── CLAUDE.md ← project-root rules
├── DESIGN.md ← this file
└── README.md
Peer services (NOT inside @cocottetech/)
These stay at their current locations and are consumed over HTTP/MCP:
~/Code/@projects/@lilith/mail-sync/— Proton Bridge wrapper (port 4444)~/Code/@applications/@mac-sync/— macOS iMessage bidirectional sync~/Code/@applications/@messenger/— separate messenger codebase (needs reconciliation with v2'smessagesfeature)~/Code/@applications/@agents/— Claude SDK agent monorepo (assistant, companion, egirl, nag, nudge, social, travel, quinn-voice, quinn-prospector)~/Code/@applications/@ml/knowledge-platform/— Crystal's successor (knowledge verification, content auditing)~/Code/@applications/@ml/*— other ML pipelines (rag-retrieval, content-moderation, message-classifier, prospect-classifier-claude, cot-reasoning, draft-pipeline-claude, etc.)~/Code/@applications/@quinn-ios/— Swift iOS app
5. Schema additions for tenancy
-- New tables in platform.db (V4 — black:25437; v2's quinn.db at :25435 is untouched)
CREATE TABLE orgs (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
slug TEXT UNIQUE NOT NULL,
name TEXT NOT NULL,
owner_id UUID NOT NULL REFERENCES users(id),
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE TABLE org_members (
org_id UUID NOT NULL REFERENCES orgs(id) ON DELETE CASCADE,
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
role TEXT NOT NULL CHECK (role IN ('owner', 'admin', 'member')),
joined_at TIMESTAMPTZ NOT NULL DEFAULT now(),
PRIMARY KEY (org_id, user_id)
);
CREATE INDEX idx_org_members_user ON org_members(user_id);
-- Existing tables gain optional org_id where data can belong to either Person or Org:
ALTER TABLE bookings ADD COLUMN org_id UUID NULL REFERENCES orgs(id);
ALTER TABLE brands ADD COLUMN org_id UUID NULL REFERENCES orgs(id);
ALTER TABLE analytics_events ADD COLUMN org_id UUID NULL REFERENCES orgs(id);
-- (When org_id IS NULL, the row belongs to the Person via user_id)
Seed for V4 launch
-- Bootstrap Quinn + Demimonde
INSERT INTO users (id, slug, ...) VALUES ('<quinn-uuid>', 'transquinnftw', ...);
INSERT INTO orgs (slug, name, owner_id) VALUES ('demimonde', 'Demimonde', '<quinn-uuid>');
INSERT INTO org_members (org_id, user_id, role)
VALUES ((SELECT id FROM orgs WHERE slug='demimonde'), '<quinn-uuid>', 'owner');
SSO JWT extension
interface SessionToken {
user_id: string;
device_id: string;
// NEW: optional org context (set when user switches into org view)
org_id?: string;
org_role?: 'owner' | 'admin' | 'member';
}
UI: context switcher in provider-portal nav toggles between Personal and each Org the user is a member of. Switching emits a new JWT scoped to that context.
6. Feature Composition for V4
Carry from v2 directly (working code, just rename + org-context)
21 features: sso, api, landing, my→provider-portal, provider-website→provider-site, cocotte-web+sansonnet-web→org-site, adult-therapy-tours→tour-site, messages, quinn-ai→ai-assistant, quinn-messenger→messenger, comm-newsletter→newsletter, user-data→org-analytics, admin→platform-admin, age-verification, client-intel, image-protection, vip, merchant, hotel-scout→tour-scout, price-watcher, edge-purge, db-monitor, platform-seed, waitlist, ui-dev-content, ai-engine, mail-autoresponder
Mine from v1 (production-quality code worth porting)
Phase A (foundations for multi-provider): marketplace, profile, attributes, bookings, trust, queue-worker, feature-flags, bot-defense, media
Phase B (depth & monetization): payments, reviews, threat-intelligence, safety, cms, blog, streaming, health-verification, content-moderation, image-generator, webmap
Mine from v0 (older but unique)
onboarding flow, mobile-messenger patterns (if pursuing a native mobile build), drive / mobile-drive (if pursuing first-class file management), content-moderation ML lineage (Python-based)
Superseded — don't port, but don't dismiss either
The following were genuinely novel and useful work in v0/v1 that has since been superseded by dedicated peer apps under ~/Code/@applications/@{ai,ml,imajin}/. The platform calls those peers over HTTP/MCP; the platform itself contains zero ML inference code.
| v0/v1 thing | Superseded by (peer app) |
|---|---|
knowledge-verification (v1, 262 tests, Crystal-AI's predecessor) |
~/Code/@applications/@ml/knowledge-platform/ |
conversation-assistant/ml-service (v1, 4.5G) |
~/Code/@applications/@ml/{assistant-trainer,chat,draft-pipeline-claude,message-classifier} |
i18n/ml-service (v1, 4.4G translation model) |
~/Code/@applications/@ml/ translation pipeline |
image-generator/ml-service (v1, 4.2G diffusion weights) |
~/Code/@applications/@imajin/ |
content-moderation/ml-service (v0+v1) |
~/Code/@applications/@ml/content-moderation/ |
talent-scout/packages/captcha-solver (v1, 3.8G) |
rebuild via @applications/@ml/ if needed |
| LLM gateway / agents (v0+v1) | ~/Code/@applications/@ai/{@agents,services,packages} |
Drop entirely
v0/v1 work that didn't pan out or was just placeholder: dating-autopilot, bio-scraper, linky/link-tree, pitch-deck, investor-dashboard, user-guide (move pitch-deck/investor/user-guide content into business/ non-code), and v1 empty shells consumable, content-editing, video-studio, share, favicon-generator, platform-content-tools, platform-assistant.
7. Naming Convention
| Concept | Old (Quinn-specific) | New (provider-generic) | Deployed domain |
|---|---|---|---|
| Provider dashboard | quinn.my |
provider-portal |
quinn.my (Quinn's instance), {provider}.my (others) |
| AI assistant | quinn-ai |
ai-assistant |
quinn.ai (Quinn's), {provider}.ai |
| Messenger | quinn-messenger |
messenger |
quinn.m (Quinn's), {provider}.m |
| Admin | quinn.admin |
platform-admin |
platform.admin (single, shared) |
| SSO | quinn.sso |
auth / sso |
sso.cocotte.io (single, shared root) |
| Analytics | quinn.data / user-data |
org-analytics |
{provider}.data |
| Tour booking | hotel-scout |
tour-scout |
(internal) |
Rule: Quinn's deployed quinn.* domains remain — they are Quinn's instance of the generic system. New providers get parallel {name}.* domains at onboarding time. The shared root (SSO, admin, commercial product) lives at cocotte.io; OSS work (open-source repos, public dev tooling) is published under cocotte.dev.
7.5 Brand family architecture
The platform serves multiple legally-distinct entities and customer-facing brands. Two LLCs operate it; customers see only one.
Cocotte LLC — the public umbrella + tech entity
- The face. Operates the platform code, infrastructure, and the public umbrella brand.
- Owns domains:
cocotte.io(commercial infrastructure —sso.cocotte.io,beacon.cocotte.io),cocotte.dev(OSS),cocotte.maison(consumer-facing brand surface),analytics.cocotte.maison(brand-tier dashboards). - Operates customer-facing tour sub-brands under the umbrella:
- ADULT Therapy Tour (
adulttherapytour.com) — clinical register; APA / AASLD / MedTech CEO audiences. - Futa Waifu Tour (
futawaifutour.com) — bimbo-geek register; FanimeCon / WonderCon / SDCC / PAX audiences.
- ADULT Therapy Tour (
- Represents talent:
- Quinn (Victoria Lackey) — primary talent. Personal site:
transquinnftw.com. - Reserved slots for future talent once v4 is operational (multi-tenant model).
- Quinn (Victoria Lackey) — primary talent. Personal site:
Demimonde LLC — the back-office (invisible)
- The wallet. A separately-held entity that handles bookings, revenue, invoicing, and talent contracts.
- Customers never see the name "Demimonde." All client-facing UX says "Cocotte" (or the specific tour brand).
- In v4's
orgstable: Demimonde is the inaugural Org row (slug=demimonde, owner=Quinn). The brand it operates under is metadata on the Org row, distinct from the Org's own name.
Sansonnet — separately-held independent venture
- Owned independently from Cocotte LLC (different cap table).
- Discretion-maximizing register; future venue / property ventures.
- Domain:
sansonnet.maison. - In v4's
orgstable: its own Org row with its own owner (not Quinn).
Sansonnet goals (cocottetech-tracked, because the AI concierge infrastructure lives here)
- IATA TIDS registration — free, self-issued via iata.org. Gives Sansonnet a recognized identifier that hotels/airlines route to their trade desk for upgrades, FAM rates, group inquiries. No booking-authority, but the credential lifts B2B email response quality immediately. Target: register within Q3 once MaisonCocotte LLC is filed (TIDS application requires a registered business entity). Add TIDS number to
concierge@sansonnet.maisonemail signature once issued. - IATA / ARC full accreditation — ~$1k+ setup, gives real booking authority + commission on hotel/air bookings. Justifiable once Sansonnet's annual hotel-spend × estimated comm rate exceeds the membership cost (rough threshold: one luxury tour leg per quarter).
- CA Seller of Travel registration — only required if Sansonnet ever charges clients a markup or booking fee. Pure-concierge (cost-pass-through to Quinn or other talent) skips this. Re-evaluate if Sansonnet starts taking commission.
- CLIA / NACTA membership — credibility boost + opens FAM rates. Cheap, defer until TIDS is in hand.
Why two LLCs (Cocotte + Demimonde)?
Liability + tax separation. The public-facing entity (Cocotte) and the entity that holds talent contracts + financial flows (Demimonde) are different containers. The platform schema must distinguish the Org (back-office, e.g. Demimonde) from the Brand (presentation, e.g. Cocotte) — they're not the same field. A future onboarding flow asks new agencies: "What's your back-office LLC name? What brand do customers see?" — both are stored.
Domain summary
| Surface | Owner | Domain | Customer-visible? |
|---|---|---|---|
| Platform infra (SSO, beacon ingest) | Cocotte LLC | *.cocotte.io |
Operators + auth flows |
| OSS work | Cocotte LLC | cocotte.dev |
Public |
| Public umbrella brand | Cocotte LLC | cocotte.maison |
Yes |
| Cocotte umbrella v4 surfaces | Cocotte LLC | ai.cocotte.maison, content.cocotte.maison, engagement.cocotte.maison, analytics.cocotte.maison |
Operators (auth-gated) |
| Tour sub-brand: clinical | Cocotte LLC | adulttherapytour.com |
Yes |
| Tour sub-brand: geek | Cocotte LLC | futawaifutour.com |
Yes |
| Quinn talent site | Cocotte LLC (rep) | transquinnftw.com |
Yes |
| Back-office LLC | Demimonde LLC | (no public domain) | No |
| Sansonnet venture | Sansonnet (separate) | sansonnet.maison |
Yes |
8. Migration Strategy
Sequencing principle: infrastructure first, features second. Paving the road (ports, DBs, proxy, tunnel, ACS, backups, CI/CD) is the highest-effort / lowest-rework work — and every feature lands on top of it. Lock it down before touching feature code. The infrastructure phase replaces both the old "Phase 4 skeleton" and "Phase 5 schema" steps because the two are coupled (compose files + ports + migrations + Caddy must all agree).
Phase 1 — Scaffold (DONE)
Create @cocottetech/{@platform,.archive,tooling,.content-lifecycle}. Write DESIGN.md, INFRA.md, CLAUDE.md, README.md. Initial git + remote setup.
Phase 2 — Archives located, NOT vendored (DONE)
Prior versions are referenced where they already live; v0 is locally cached on apricot at ~/.cache/cocottetech-archives/platform.0.tar.zst because its NFS source is slow. No archives in git. See .archive/ARCHIVED.md and scripts/{cache-v0.sh,extract-archive.sh}.
Phase 3 — Carry-overs (DONE, no-op)
tooling/ and .content-lifecycle/ from @lilith/ are empty stubs — already mirrored as empty directories. mail-sync and other peer services stay where they are.
Phase 4 — Monorepo skeleton (DONE)
@platform/{package.json, bunfig.toml, tsconfig.json}, codebase/tsconfig.base.json, empty codebase/@{apps,features,packages}/, deployments/@domains/, infrastructure/, docs/, scripts/.
Phase 5 — Infrastructure foundation (NEXT, must complete before any feature work)
Goal: a deployable, observable, recoverable system with all the glue in place. No feature code yet. When this phase ends, manage-apps start cocottetech apricot brings up an empty-but-functional platform, deploys can be triggered via ./run deploy:<service>, and backups + tunnels run unattended.
5.1 Port registry & env
infrastructure/ports.yaml— provider-generic service names (noquinn.*); V4 port ranges that don't conflict with v2 running in parallel:3060-3079V4 APIs (platform.api:3060 + per-specialist health endpoints)3791-3799V4@aiinstances (forks of@ai/ai-core; @ai itself sits at 3790)3820-3839V4 workers (scheduler, ingestor, resolver, notifier)5300-5399V4 web frontends25437V4 Postgres (platform.db)
infrastructure/.env.ports— committed env file in sync with ports.yaml.
5.2 Databases
platform.dblives on black at port 25437 — a new, isolated DB. v2'squinn.db:25435stays untouched. V4 ↔ v2 cross-data flows over HTTP/MCP only, never cross-DB SQL.infrastructure/sql/migrations/:0001_tenancy_and_content.sql—users,orgs,org_members,personas,content_plans,content_assets,content_posts,agent_actions,engagement_events,prospects(all org-aware from day one).0002_seed_demimonde.sql— inaugural Demimonde org, transquinnftw as owner.- (more as features land — every feature ships its own migrations).
- No persistent dev DB on apricot. Engineering points at prod
platform.api. Tests use ephemeral docker-compose containers spun up + torn down per test run.
5.3 Reverse proxy (Caddy)
infrastructure/Caddyfile.local— dev TLS for*.cocotte.apricot.laninfrastructure/certs/— self-signed certs (gitignored)infrastructure/gen-local-certs.sh— regenerates certs as services are added- Production: per-host Caddyfile templates under
deployments/@domains/<domain>/
5.4 Single API plane (no SSH reverse tunnels for V4)
- V4 deliberately drops the v2-era
ssh -Rtunnel from black → vps-0. vps-0 web FEs reachplatform.apiandquinn.apion black over HTTPS as a single API plane (engineering dev FEs on apricot use the same path). No dev API stack. - Public APIs on black are exposed through Caddy with mTLS or service-token auth between vps-0 ↔ black.
- VPN endpoint on black covers engineering remote shell access;
@model-boss(apricot) is reachable from black-resident @ai instances over LAN HTTP. - See INFRA.md §5 for the canonical inter-host map.
5.5 ACS integration
users/transquinnftw/app.manifest.yaml—manage-appsservice registry for @cocottetech (apricot + black + vps-0 platforms each with their services)- Verify ACS picks up @cocottetech repo (it already commits; just confirm hooks/CI integration)
- Pre-commit hook for
pnpm typecheck/bun linton changed files
5.6 Backups & DR
infrastructure/scripts/backup-pg.sh— nightlypg_dumpallfrom black → restic repo on apricot tankinfrastructure/scripts/restore-pg.sh— counterpart with --dry-run guard- MinIO replication: vps-0 (hot) → black (cold) via
mc mirrorcron - Forgejo daily mirror push to GitHub (existing org policy)
- Verification: end-to-end restore drill into a scratch DB on apricot
5.7 Build / deploy pipeline
runshell entrypoint at repo root (./run dev,./run dev:stop,./run dev:status,./run dev:logs,./run build,./run deploy:<service>).forgejo/workflows/:typecheck.yml— runs on every push (bun install && bun run typecheck)lint.yml— runs on every pushdeploy-template.yml— reusable workflow each feature can call withwith: service: provider-portal
- Per-service
deployments/@domains/<svc>/deploy.shtemplate — rsync to vps-0/black, systemd reload, smoke test
5.8 Verification gates (must all pass before Phase 6)
manage-apps start cocottetech blackbringsplatform.api:3060 up cleanly on black; healthy/health.psql -h black -p 25437 -U platform -d cocottetech -c "SELECT * FROM orgs WHERE slug='demimonde'"returns 1 row (run from VPN-connected workstation, not via SSH tunnel).- A web FE on vps-0 calling
https://platform.api/...over HTTPS succeeds. @model-bossreachable from a black-resident @ai instance over LAN HTTP; a vision-tag request returns within SLA.- Backup script runs end-to-end (
backup-pg.sh && restore-pg.sh --to=/tmp/restore-test). - A trivial commit triggers
.forgejo/workflows/typecheck.ymland it passes.
Files to read/carry from v2:
~/Code/@projects/@lilith/lilith-platform.live/infrastructure/{ports.yaml,.env.ports,Caddyfile.local,compose.*.yml,pg-services.yml,quinn-db-init.sql,gen-local-certs.sh,setup-*.sh}~/Code/@projects/@lilith/lilith-platform.live/users/transquinnftw/app.manifest.yaml~/Code/@projects/@lilith/lilith-platform.live/run
Phase 6 — V4 AI-first content engine (features start here)
V4's first feature wave is net-new revenue capability, not v2 carry-over. v2 stays running untouched. See ~/.claude/plans/this-is-a-new-wiggly-wren.md for the priority-ordered build plan:
- P0 —
platform.api+platform.db+ai-copilot@ai instance +@features/ai-copilot/ios-fe. Vertical slice working end-to-end. - P1 —
content-onlyfansper-surface specialist +@ai/@skills/platform-onlyfans/actions/*(upstream contribution). - P2 —
content-xper-surface specialist +platform-xskills. Cross-surface prospect dedup begins. - P3 — Additional content surfaces (
instagram,tiktok,threads, ...) + escort-directory axis (bookings-tryst,bookings-ts4rent, ...). Demand-driven; one platform at a time. - P4 — Engagement consolidation, funnel telemetry, conversion experiments.
- P5 — Compounders (persona-tuning, lookalike modeling, OF→booking handoff, specialist iOS threads, org context-switcher UI, selective v1 mining).
Phases 7+ — V2 carry-over and v1 mining (deferred, demand-driven)
v2 feature carry-over and v1 mining (marketplace, profile/attributes, bookings, trust, payments, etc.) are NOT V4 priorities. They land only when (a) V4's AI-first content engine is humming and (b) carrying them over delivers clear revenue lift. There is no scheduled v2 deprecation; v2 keeps running until V4 strictly dominates.
9. Open Questions
- Operating host: should
@cocottetechlive on apricot only, plum only, or both (synced)? Default assumption: develop on plum, push to apricot for deploy. - v0 variants: archive only
egirl-platform/asplatform.0, or also include-worktrees/,-releases/,-partial-backups/,egirl.vault/as.archive/platform.0-variants/? @messengervsmessagesfeature:~/Code/@applications/@messenger/exists separately from v2'smessagesfeature. Are they the same code? Different concerns? Needs reconciliation before V4 messaging starts.- knowledge-platform lineage: v1 had
features/knowledge-verification(262 tests, Python).crystal-cli(Feb 2026) was a CLI wrapper.@applications/@ml/knowledge-platformv2.0.0 is the current successor. Confirm: is this dead code or active? Should it stay peer, or fold into V4? - Mining sequence: which V1 feature lands first in V4 — marketplace (multi-provider discovery), profile/attributes (provider profile depth), or trust/safety (verification before opening up)?
- Client surface: when V4 launches, do clients have accounts (logged in to view bookings, message providers), or stays anonymous-on-request?
10. Success Criteria
V4 is delivering value when within ~8 weeks of P0 start (per the approved plan):
- ✅ Quinn opens
@features/ai-copilot/ios-fedaily; ai-copilot is her primary surface. - ✅ Quinn's OF account has ≥30 days of agent-planned + Quinn-approved content live (via
content-onlyfans). - ✅ ≥3 social surfaces post on schedule with zero manual scheduling steps from Quinn.
- ✅ ≥80% of inbound engagement across surfaces gets a same-day response (draft or auto).
- ✅ ≥1 booking or PPV sale is attributable to the engagement funnel.
- ✅
agent_actionsis the source-of-truth audit spine; every specialist decision is replayable. - ✅ Each specialist's
@aiinstance runs independently on black; each calls@model-bosson apricot for GPU work. - ✅ Org-aware schema is in
platform.dbfrom day one (Demimonde seeded as owner-Org for Quinn).
V2 retirement is not a success criterion. V4 is purely additive revenue capability. V2 keeps running until/unless V4 strictly dominates and Quinn decides to cut over.
Appendix: Sources
- v0 source: apricot:
/mnt/bigdisk/_/last-linux-backup/applications/src/@egirl/egirl-platform/(27 apps, 23 services, 14 packages, viky-era) - v1 source:
~/Code/@projects/@lilith/lilith-platform/(54 features, 38 packages, 72GB, never deployed end-to-end) - v2 source:
~/Code/@projects/@lilith/lilith-platform.live/(24 features, 7 packages, 27 live domains) - Peer apps source:
~/Code/@applications/{@ai,@chobit,@mac-sync,@messenger,@ml,lilith-messenger-ios}/and@ai/@skills/platform-*for platform-action skills.