Clone — Absorption v3 PRD

"It becomes you." Two skins, a living voice, a status bar you can feel, and a clone that already knows you.

Build target: Claude Opus 5 · Creative/plan: Claude Fable 5 (this document) · Architecture critique: folded in (system-architect pass) · Date: 2026-08-29

App: https://clone.arnao.ai · source /Users/byronarnao/clone-mvp · worker /Users/byronarnao/clone-absorb

Predecessor: Absorption v2 proposal (the UX overhaul this builds on)


0. Read this first — the billing reality (you don't need new money, you need the right wallet)

You have three separate wallets, and topping up one never funds the others:

WalletPowersState today
Anthropic subscription planClaude Code / me (this session)Fine — this is what you pay monthly
Anthropic API key (ANTHROPIC_API_KEY)clone's server chat, the fable-critique skill, Gia Signal-on-FableEmpty — "credit balance too low"
OpenRouter (OPENROUTER_API_KEY)clone chat (I wired it in), can route Fable/Opus too~$12.50 left of $250 ($237 used)

Recommendation: top up OpenRouter — it consolidates everything (clone chat + I can re-point the critique skill and worker LLM calls through one balance, at OpenRouter's no-markup token rates), and separately drop ~$20 on the Anthropic API credits only if you want the direct-API skills back verbatim. Neither is your subscription. One-tap: Anthropic API billing · OpenRouter credits.

Why it matters for this PRD: the Mac worker (watch.py) runs Gemini Flash end-to-end — persona, first-line, and any new research summarization. It has no premium path. So "use the default Opus 5 model" (v2 §5) describes the chat path only; the worker needs its own funded LLM route (OpenRouter is the clean answer). This is load-bearing for the research agent below.


1. What we're building (on top of v2)

Three things Byron asked for, layered onto Absorption v2:

  1. A living voice — the app speaks its beats ("Absorption initiated…") instead of just printing them.
  2. Two toggleable skins on one interface — a cold, futuristic Absorption theme and a warm, human Cloning theme. Toggle for giggles; same flow, same code.
  3. A background research agent — after your photo, a parallel job quietly assembles what the public web already knows about you, then asks you to confirm each fact before it joins your clone. (Highest-risk feature; owner-only, flagged, P2 — see §5 and the guardrails.)

Plus the v2 backlog and three real bugs the architecture pass surfaced (§6).


2. Feature 1 — The living voice

Verdict: sound. One hard constraint: the lines are static, so never run TTS at runtime.

How it works

The scripts (Fable creative — this is the "say something cool" ask)

Proven already: both hero lines rendered locally today —

Absorption hero (cold) · Cloning hero (warm).

BeatABSORPTION (cold · 2001 · the machine takes you in)CLONING (warm · human · a reflection)
Land"Step closer. I want to see what you're made of.""Let's make your reflection."
Disclose (unlock gesture)"This takes more than your picture — your voice, your patterns, the way you decide. Hold the light when you're ready.""This isn't just a photo. I'll learn your voice, and the small ways you're you. Touch the light when you're ready."
Arm"Steady.""There. Hold still."
Face lock (HERO)"Absorption initiated. I have your face.""There you are. I see you."
Capture"Held. That version of you is mine now.""That's the you the world meets. Got it."
Interview"A face is only the surface. Now I take how you think.""A picture isn't a person. Tell me who you are underneath."
40%"I'm beginning to sound like you.""You're starting to feel familiar."
70%"I know what you'll say before you say it.""You feel like someone I already know."
90%"Almost all of you.""Nearly you."
Synthesize"Assembling.""Bringing you together."
Endpoint (clone speaks, your voice)"Absorption complete." → twin: "So — ask me something only I would know.""Come meet yourself." → twin: "Hi. It's strange, isn't it, hearing me be you."
Dossier reveal"I went looking. This is what the world already knows about you.""I looked you up, the way anyone might. Tell me what's really true."

Host narrator voice is a design choice per theme (cold synthetic vs warm human) — distinct from the user's cloned voice, which only speaks the endpoint. Production picks two host reference voices; the demo above reuses Byron's sample at two exaggeration settings to prove the mood range.


3. Feature 2 — Two skins, one interface

**Verdict: needs rework. The existing HOST_SKINS cannot carry this — it swaps one CSS var (--accent) and six copy strings. You're renaming a product, not recoloring an accent.**

The theme manifest (replaces the 1-var skin for this axis)

THEMES = {
  absorption: {
    term:  { verb:"absorb", gerund:"absorbing", noun:"absorption", done:"Absorbed." },
    palette: { bg:"#05070a", accent:"#4fd6e0", type:"grotesk, wide-tracking" },  // cold monolith
    voiceSet: "absorption",       // → /voice/absorption/*.mp3
    soundscape: "low-sine-drone + single tone on lock",
    copy: { ...full per-beat strings... }
  },
  cloning: {
    term:  { verb:"clone", gerund:"cloning", noun:"clone", done:"Here you are." },
    palette: { bg:"#0f0b08", accent:"#e0a24f", type:"humanist, soft" },          // warm (≈ current default)
    voiceSet: "cloning",
    soundscape: "warm pad + gentle chime",
    copy: { ... }
  }
}

4. Feature 3 — The Dossier (background research agent)

Verdict: risky. Build P2, behind an owner/admin flag, identity-asserted, reverse-image OFF. Three of the ask's load-bearing claims are false or unenforceable against the current code — corrected below.

The experience (when it's earned)

While your face and voice absorb, a second track — the Dossier — quietly searches the public web for you and returns confirm cards:

> "I found this. Is it you?"

> AI/ML engineer at AWS, Responsible AI — source: linkedin.com/in/… — [Yes, that's me] · [No] · [Skip]

Only cards you tap Yes on join your clone's persona. Each card cites a source URL. The Dossier sub-track fills the status bar alongside Face/Voice/Mind.

Corrections to the ask (architect pass)

  1. "Runs in parallel" was false. The worker (watch.py) is strictly sequential — one job at a time inside process_job. A research stage would add 10–60s to the critical path and, if a search hangs, strand the user behind the 20-minute stale timeout. → Build it as a separate research-jobs/ record claimed by a second worker loop, genuinely concurrent with absorption.
  2. "Researching themselves" is an unenforced assumption. Nothing verifies the photographed face is the logged-in user — so as-proposed it's a stalking tool (absorb a stranger's photo → research + reverse-image them). → **Key research to asserted identity only: claims.email + claims.name from the signed session + what the user explicitly types** ("I'm an AI engineer at AWS"). This eliminates reverse-image search as an input entirely. Reverse-image, if ever, is isAdmin-only and disabled, not merely defaulted off.
  3. "Cheap under the cap" was unbudgeted. Search + summarization per absorption is a real cost, and the worker has no premium LLM. → New metered op COST.research, its own BURST_PER_MIN entry, charged at create-time, summarization routed through the funded OpenRouter path.

Guardrails (all mandatory)


5. The status bar — the Absorption Meter

One hero number, decomposed into what's being taken. This is the "I want to see how much has happened and how much is left" ask.

  ABSORBING  ▓▓▓▓▓▓▓░░░  68%
  Face ✓   Voice ▓▓▓░   Mind ▓▓░░   Dossier ▓░░░

6. Bugs the architecture pass found (fix in P0, before anything new)

  1. Metering is dead-code-wired. absorb-create.js:32 charges a hardcoded ABSORB_CENTS = 8; _meter.js COST.absorb is never read on this path. My v2 "raise COST.absorb to 15" edit would do nothing. → Fix the literal in absorb-create.js (or make it read COST.absorb). Real absorption cost ≈ 13¢; chat turn under the new tokenizer ≈ 1.7¢ not 1¢. Re-price both so the $1 cap means what it says before adding the metered research op.
  2. jobView() is an allowlist — new fields are invisible. absorb-status.js:25-43 projects a fixed field set; every new field (v2 heartbeat, voice-early stage, research summary, theme) is silently dropped until jobView is extended. → Make "extend jobView" an explicit line item for every new job field, v2 and v3 alike. This is the #1 "we built it and the UI shows nothing" trap.
  3. Deletion retains data it didn't ship with. delete-me.js:46-50 deletes a hardcoded prefix list. Any new prefix (research-jobs/, research derived/) survives "delete my clone" — and research data is the one category that names non-consenting third parties. → Register new prefixes in delete-me.js in the same PR; make it a checklist gate. Sharpest legal exposure in the plan.

7. Data schema additions (Blob)


8. Phasing (what Opus 5 builds, in order)

PhaseScopeGate
P0 — de-risk what's already claimedBug fixes 1–3 (metering literal, jobView extension discipline, delete-me prefixes). Ship Absorption v2 (v2 §2) with jobView/delete-me as explicit line items. Worker gets a funded LLM route (OpenRouter).metering re-priced & verified before any new metered op
P1 — voice + themesFeature 1 (pre-rendered voice sets, DISCLOSE audio-unlock, captions) + Feature 2 (theme manifest, live toggle, re-prime on toggle) + the Absorption Meter (§5). Low risk, high payoff, no new backend surface. Build the manifest first — the voice sets are per-theme.works sound-off (captions) and on mobile (unlock)
P2 — Dossier, flagged & owner-onlyFeature 3 behind isAdmin, identity-asserted, reverse-image disabled, separate research-jobs + second worker loop, Brave Search, per-claim provenance, exclusion-default, delete-me prefix registered same PR.self-only owner path proven before it's even a question whether non-owners get it — answer stays "no" until the face-belongs-to-user problem has a real gate (liveness/selfie-match, its own project)

Do not let Feature 3 ride P0's coattails. It's the one feature that can turn a consented self-portrait into an abuse tool.


9. Build notes for Opus 5

10. Open decisions for Byron

  1. Billing: top up OpenRouter (consolidates), Anthropic API credits (direct-API skills), or both? (§0)
  2. Host narrator voices: pick two reference voices — one cold/synthetic (Absorption), one warm/human (Cloning) — or reuse a single voice at two exaggeration settings?
  3. Default theme on first visit: Absorption or Cloning?
  4. Dossier reach: even owner-only, cap it at Brave web search — or also allow you to paste specific profile URLs to summarize?
  5. Reverse-image search: keep it fully disabled (recommended), or owner-only behind a second explicit flag later?

11. Research & evidence

Talking head: FasterLivePortrait-MLX (proven 47.9s local). Voice: Chatterbox (local, $0). Interview science: Stanford genagents (finite interview ≈ 85% fidelity). Search backbone: Brave Search API (in-fleet, generate-rai-content.py). Meet stand-in (v2): joinly. Models: refreshed benchmarks.

Links

WhatLink
This PRD (published)https://clone-v3.arnao.ai
Absorption v2 proposal (predecessor)https://clone-v2.arnao.ai
Live apphttps://clone.arnao.ai
Hero voice — Absorption (cold)https://clone-v2.arnao.ai/assets/theme-absorption-hal.wav
Hero voice — Cloning (warm)https://clone-v2.arnao.ai/assets/theme-cloning-warm.wav
Talking-head smoke testhttps://clone-v2.arnao.ai/assets/byron-talkinghead-quality.mp4
Anthropic API billinghttps://console.anthropic.com/settings/billing
OpenRouter creditshttps://openrouter.ai/settings/credits