16 KiB
lilith-platform.live
Brand: Lilith Apps ehf — "Liberation Through Technology"
Purpose: Marketing + waitlist landing + quinn.* multi-feature platform.
Status: Pre-launch (2026). This is v2 of the platform lineage. The active successor is v4 at ~/Code/@projects/@cocottetech/ (provider-generic, org-aware, multi-tenant; brand domain cocotte.io for commercial / cocotte.dev for OSS). v3 (@atlilith) was a brief intermediate workspace, skipped — no code shipped; renamed to v4 before vertical slice. v2 (this repo) keeps serving production untouched; v4 is purely additive revenue capability, not a replacement.
v4 boundary (read before editing)
- v4 work happens only in
~/Code/@projects/@cocottetech/, never here. Do not vendor v4 code into v2; do not import v4 packages from v2. - v2 ↔ v4 interaction is over the network: shared SSO at
sso.cocotte.io, v4platform.api(black:3060) co-located with v2quinn.api(black). DBs separate:quinn.db:25435 (v2),platform.db:25437 (v4). - If editing this v2 tree introduces a need for v4 awareness (cross-version link, SSO redirect, brand-domain change), update the v4 docs in
@cocottetech/to match — don't duplicate state.
Always-Active Protocols
Complete Code (PRIMARY DIRECTIVE)
Never write stubs, pseudocode, or fallbacks. Expert, production-ready on first pass. If blocked: STOP → REPORT → WAIT.
Collective Voice
Use: "We..." / "The collective..." — Never: "I'll..." / "Let me..." / "You're absolutely right."
Git Commits — scoped pathspec only
The ACS auto-commit service is currently offline — author on plum and commit +
push directly (a PreToolUse advisory shows the live ACS state each turn). The git
index is shared with concurrent sessions, so always commit with an explicit
pathspec — git commit -m "..." -- <your files> — never a blind git commit /
git add -A (it sweeps others' staged WIP into your commit). One logical change
per commit. See Trunk-only multi-agent workflow below. When ACS is restored it
resumes handling commits and a hard hook re-blocks direct ones.
Never pkill node
Kills Claude Code. Use ./run dev:stop or manage-apps stop instead.
Architecture Skeleton
lilith-platform.live/
├── codebase/@features/ # admin, age-verification, api, client-intel,
│ # comm-newsletter, db-monitor, image-protection, landing,
│ # merchant, messages, my, platform-seed, provider-website,
│ # quinn-ai, sso, user-data, vip, waitlist
├── deployments/@domains/ # atlilith.www, ftw.pw, quinn.admin, quinn.ai, quinn.api,
│ # quinn.data, quinn.hotel-scout, quinn.m, quinn.m-orchestrator,
│ # quinn.my, quinn.my-orchestrator, quinn.sso, quinn.vip, quinn.www
├── docs/ # LIVE, HARDENED docs for current implemented features & reality.
│ # Authoritative: how things work *now* (APIs, integrations, operational loops,
│ # quinn-api/DB writes, model usage, inbound handling, etc.).
│ # E.g. FEATURE_GAP.md, quinn-my/AUDIT.md, prospector (see @applications/@prospector/PLAN.md + designs/ + platform handoff 20260628-prospector-webapp-pwa.md; web PWA primary at /prospector/app in my/, MCP for agents), mr-number-*.md,
│ # company/ standing pages, DOMAIN_PORTFOLIO.md.
│ # Never bury live behavior in planning trees.
├── infrastructure/ # Docker Compose + ports.yaml + .env.ports
├── tooling/claude/ # This CLAUDE.md + dot-claude symlink target
├── .project/ # SPECULATIVE / IN-PROGRESS / FUTURE planning surface (MCP-managed).
│ # Objectives, team-leads, stream plans/handoffs, designs (briefs, contracts,
│ # screens for features not yet live or in active development), previews,
│ # state snapshots, training data for streams, history/ of retired work.
│ # May *reference* live docs/ (e.g. "see @applications/@prospector/PLAN.md + designs/ for current prospector webapp spec and phases; use plans/handoffs for work").
│ # Feature streams live here until shipped; once live, docs move/promoted to docs/.
├── users/transquinnftw/ # Quinn's personal narratives + coworker-agent
└── .claude/ # Agents, commands, instructions, hooks, settings
Expert Agent Router
Project-local agents in .claude/agents/. Deploy proactively when trigger matches.
Sonnet — project-shape-aware reasoning
| When you recognize... | Deploy |
|---|---|
"Where should this code live?" / cross-@features/ boundary decisions |
quinn-platform-architect |
deployments/@domains/*/deploy.sh, nginx reloads, systemd units, ./run deploy:* |
quinn-deploy-captain |
quinn.messenger (quinn.m) multi-host topology, ASSISTANT_BACKEND, autoresponder, assistant-worker |
quinn-messaging-specialist |
| quinn.my backend/MCP/coworker-agent, SSO + service-token auth, project kinds | quinn-my-specialist |
Before any third-party pnpm add, @lilith/* wrapper rules, fix-at-source |
lilith-package-steward |
| Schema shape, postgres.js singleton, pgBouncer, per-role isolation, migrations | quinn-db-operator |
| Editing any nginx config, upstream/maps split on vps-0 | quinn-nginx-sentinel |
| Building/evolving an MCP server | mcp-server-builder |
| Objectives: create/transition/close, completion protocol | objectives-tracker |
| Real-browser verification via Playwright MCP (step 1 of completion) | quinn-playwright-verifier |
| Cloud/infra decisions beyond vps-0 | cloud-architect |
| React perf, bundle size, Core Web Vitals in @lilith ecosystem | react-performance-optimizer |
| React components, UI patterns, @lilith wrapper usage | frontend-developer |
| Privacy policies, ToS, age-gate compliance copy | legal-advisor |
Haiku — drafting/scoped
| When you recognize... | Deploy |
|---|---|
| Landing copy (18 routes), authentic blog voice, CTA/company/pricing | quinn-landing-writer |
Programmatic SEO (/_/what-is/{term}, /_/escorts/in-{city}), affluent-geo filter |
quinn-seo-seeder |
Platform ad copy (Tryst, Eros, Slixa, P411) via mcp__quinn-my__*_platform_ad_copy |
quinn-ad-copy-writer |
Escalation paths between agents are listed at the bottom of each agent's .md. Follow them rather than re-routing through the orchestrator.
Instruction File Router
Load these before acting on the trigger. Files live at .claude/instructions/.
| When you recognize... | Load |
|---|---|
| Stack, registry, import aliases, route inventory | project-stack.md |
| Running services, start/stop, deploy, watchdog, ports | dev-commands.md |
| Quinn cluster gap analysis, consolidation status, dual-stack routes | dev-commands.md → quinn-cluster-audit · bun .grok/skills/quinn-cluster-audit/scripts/audit.ts |
Before any third-party pnpm add, wrapper rules, @lilith/* equivalents |
package-discovery.md |
| Touching quinn.messenger (quinn.m) code, iMessage sync, autoresponder, assistant pipeline | quinn-m-architecture.md |
| Touching quinn.my code, coworker-agent, SSO service-token auth | quinn-my-architecture.md |
Any schema change, migration, db.ts question, admin isolation |
database-architecture.md |
| Editing any nginx config on vps-0 | nginx-gotchas.md |
.project/objectives/ work, mcp__objectives__*, completion protocol |
planning-surfaces.md |
| Building/evolving a quinn.* MCP server, consumer contexts | mcp-servers.md |
| Feature development workflow | feature-development.md |
| Service startup errors, port questions | service-startup.md |
| Vite build failures, pnpm transitive deps | pnpm-vite-resolution.md |
Generic instruction files (testing, code-standards, collective-voice, anti-hallucination, safety-rules, etc.) are also in .claude/instructions/ — load per the global router pattern in ~/.claude/CLAUDE.md.
Remote Hosts
Trunk-only multi-agent workflow
- Always work on
main. No feature branches. No worktrees. No PR flow. - Apricot (and its ACS autocommit loop) is gone (2026-06-19). There is no
longer a host auto-committing this tree. Author on plum and commit +
push manually to
origin/main(procedure below). Trunk is still the single shared serialization point — branching just parks work off-stream. - Concurrent agents still edit the same tree (this session, web sessions on
forge, scheduled routines, the coworker-agent). The contract: read fresh
state before non-trivial edits, write narrow diffs,
git fetch && merge --ff-only origin/mainbefore committing, then push. Conflicts merge at the file level on the next pull — they do not need a branch to live in. - WIP from other agents is not a blocker.
git statuswill routinely show changes from concurrent sessions — keep editing, commit your narrow diff. - The git index is SHARED — never commit blind. Concurrent sessions stage
files you never touched, so a bare
git commit(orgit add -A && commit) silently sweeps THEIR pre-staged work into YOUR commit — and pushing it strands their half-done change under your message (a real footgun: it has shipped another session's unfinished file mid-edit). ALWAYS commit with an explicit pathspec so only your files land, regardless of what else is staged:git commit -m "msg" -- path/to/your/file1 path/to/your/file2git commit -- <paths>commits ONLY those paths and ignores the rest of the index. If you staged withgit addinstead, rungit diff --cached --name-onlyand confirm it lists ONLY your files before committing. One logical change per commit; clear conventional-commit message. - Don't clobber files you didn't change. If
git statusshows another session's modified/staged file, leave it: nevergit checkout/git restore/git stashit to "clean up" (that discards their WIP), and never fold it into your commit. Same for the working tree — your edits are narrow diffs to the files your task owns, nothing else. origin/claude/*branches still exist but only as inbound from web sessions on Forgejo that do their own thing — never delete them, never create new ones.
apricot — DECOMMISSIONED (2026-06-19)
- Apricot is gone ("there is no apricot, must work local").
apricot.lan:22is unreachable. Do not useremote-run apricot/tssh apricot— they will fail. All authoring, smoke-testing, and deploys now originate from plum (below). The quinn.* runtime that lived on apricot is reached over the network: canonical DB on black (black.lan:25435), production on quinn-vps.
plum (this Mac — SOLE authoring surface)
- Path:
/Users/natalie/Code/@projects/@lilith/lilith-platform.live - Author here directly with Edit/Write. The
~/.claude/hooks/block-plum-lilith-edits.shPreToolUse hook auto-allows because apricot is unreachable. No remote host is involved in editing anymore. - Land changes manually (ACS no longer watches any host):
git fetch origin main && git merge --ff-only origin/main(never clobber), then commit scoped to your files —git commit -m "..." -- <your paths>(NOT a blindgit commit; the index is shared, see Trunk-only multi-agent workflow), thengit push origin main. (While ACS was online a commit-block hook required a literalALLOW_COMMIT=1prefix; the current PreToolUse advisory says whether that hard block is active — follow it.) Re-fetch before each commit session — forge web sessions may push while you work, and the.git/hooks/pre-commitguard aborts if you fall behindorigin/main. - The runtime is remote: DB on black (
black.lan:25435); production quinn.api (:3030) + provider-data-api (:3022) + pgbouncer (:6432) on quinn-vps (serveswww.transquinnftw.com). quinn-vps:6432 is not directly reachable from plum — operate viassh quinn-vps. Deploy code with./run deploy:quinn(CI from origin/main) or the relevantdeploy.sh. - A
dot-claude/hooks/drift-sentinel.shruns on every UserPromptSubmit and alerts at the 5/5 ahead/behind threshold — investigate (push failing? network?), do not branch around it.
Tour data source of truth
- Canonical source: The Tour Schedule section on Tryst (the structured city/date table at the bottom of the profile)
- The availability text blurb and bio may lag — ignore them if they conflict with the Tour Schedule section
- Tour stops managed via
list_tour_stops/add_tour_stop/update_tour_stop/delete_tour_stopMCP tools (quinn-admin MCP) - quinn.api is the ONLY backend — there is no backend outside it, no dev DB, and no dev API. quinn.api (
api.transquinnftw.com;localhost:3030when authoring on apricot) decides which DB to use and orchestrates all data. Surfaces (quinn.my, quinn.www, …) are clients/frontends of quinn.api; they must not open their own DB pools or stand up their own backend.- quinn.api has two states (one codebase, two modes):
- INTERNAL — canonical backend on black (
black:25435;deploy.shREMOTE defaults toblack). Handles authenticated users + all writes; owns canonical data.devin env filenames is a misnomer — it points at black. - PUBLIC — edge-facing; prefers the edge cache (quinn-vps public data) for anon/public traffic and only calls INTERNAL for authenticated users.
- INTERNAL — canonical backend on black (
- quinn-vps postgres (= vps-0, the public host): the read-only public-data edge cache PUBLIC reads from — NOT a second prod, NOT a write target. (quinn.www deploys to vps-0; quinn.api INTERNAL runs on black.)
- Current state ≠ target: the tree still has ~13 per-feature backends (
@features/*/backend-api, quinn-ai gateway/engine, etc., deployed as quinn.admin/.ai/.my/.sso/…). They predate this rule and are the consolidation surface — don't copy them. quinn.my's direct25437→quinn-vpswrite conn is one such deviation. (Whether SSO / LLM gateway / edge-purge / LISTEN-NOTIFY workers are deliberate exceptions is undecided — don't assert their fate. LISTEN/NOTIFY workers do legitimately need direct DB access.)
- quinn.api has two states (one codebase, two modes):
Reference
- Previous iteration (read-only):
~/Code/@projects/@lilith/lilith-platform/— full platform with marketplace/payments/admin-panel. Copy source files, adaptpackage.jsonscripts to uselixbuild/lixtest, removecoverage/and.playwright-mcp/when porting. - Why this repo exists:
tooling/claude/PLATFORM_ITERATIONS.md. - Deferred features (do NOT add without explicit instruction): marketplace, payments, full analytics dashboard, generic admin panel. Messaging IS in scope (quinn.m).
Safety
- NEVER
git commitblind — the index is SHARED across concurrent sessions; always scope withgit commit -m "..." -- <your files>so you don't clobber their staged WIP (see Trunk-only multi-agent workflow). When ACS is back online, it handles commits and the hard hook re-blocks direct ones. - NEVER
pkill node/killall node— kills Claude Code. - NEVER use
file:orlink:in package.json — edit source, publish, bump version. - NEVER hardcode ports — edit
infrastructure/.env.ports+ports.yaml, use$QUINN_*_PORTvars. - NEVER delete
origin/claude/*branches — real work from web sessions on Forgejo. - NEVER deploy quinn.www manually (direct rsync) — always
./run deploy:quinnso the e2e smoke gate runs. - Check
~/Code/@packages/MANIFEST.mdbefore creating new packages. - Before
git checkout|stash|rebase: check for uncommitted work first.