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."
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: "Go ahead — ask me something only you would know."
Dossier reveal"I went looking. This is what the world already knows about you.""Here's what the public web says about you. Tell me what's actually true."

Host narrator voice — FINAL (Byron 2026-08-30): two host voices, opposite temperaments, toggle at onboarding:


2c. Field-test rules (Byron's first live run, 2026-08-30 — binding)

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.**

Appearance axis — light & dark (Byron 2026-08-30: "I'd like the option of the light or dark skin")

Appearance is orthogonal to theme. Two axes, four combinations, one interface:

Dark (default for Absorption)Light (default for Cloning)
Absorption (cold)near-black + cyan — the monolithpale steel + cyan — clinical daylight
Cloning (warm)near-black + amber (today's look)porcelain cream + amber — the Kinfolk warmth (mockup 12)

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)


4b. Sent Clones — Conversation Mode + the scope envelope (Byron 2026-08-30)

The idea: sending your clone to someone is just sending a URL (text, email, QR). The recipient opens it and is face-to-face with an instance of you — full-screen talking head, mic-first, one-on-one. But every sent clone travels inside a scope envelope: a mission plus explicit switches for what this instance knows and refuses.

This is also the chosen smoke/user test: the first real-world exercise is Byron sending a scoped clone ("just Byron's AI knowledge") to one real person and watching the conversation hold its boundaries.

The two surfaces

Architecture — the envelope is enforced server-side, never in the prompt alone

A sent clone is a policy record, not a fork of the persona:

sent-clones/<sub>/<slug>.json = {
  slug, owner_sub, mission, created, expires,
  scopes: { ai_ml:true, career:true, personal:false, pii:false, employer_opinions:false },
  capabilities: {},                  // agency axis (M3) — ships empty/all-OFF; knowledge and action permissions never conflate
  refusal_line,                      // the theme-voiced "I really can't get into that…"
  cap_cents: 100, spent_cents, revoked:false,
  transcript_retention: "summary"    // owner sees a digest, not necessarily raw logs — decide in build
}

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)


7b. Screen inventory — the complete mocked set (build exactly as mocked)

Byron approved the renders 2026-08-30: "these are amazing, this is exactly what I want." Layout + copy below are canonical; the renders set the visual bar. Full gallery: https://clone-v3.arnao.ai/mockups.html

#ScreenMockupPhase
7Welcome — hold-the-light + disclosure07P1
1Absorption (scan/capture, dark-cold)01P1
12Cloning (scan/capture, light-warm)12P1
8Interview — Q 4/8 + transcript + meter08P1
9Endpoint — the clone speaks09P1
10Twin chat — fidelity dial + Mirror/Deploy/Erase rail10P1
5Parameters — core (model/prompt/cap/voice/face)05P2
6Parameters — knowledge & presence (context/socials/Dossier/memory)06P2
3The Mirror03P2
15Send a clone — scope composer (mission, switches, locked PII, share link)15P2
14Conversation Mode (recipient's 1:1 view, scope banner)14P2
16After-action digest (panel D3)16P2a
17Verify page — recipient trust card (panel F2/F5)17P2a
2Command center (dark)02P3
13Command center (light)13P3
11Deploy sheet (Meet link + brief + cost)11P3
4Deployments dashboard04P3

Known render artifacts (concept art, not spec): garbled card label on 02; duplicate vote row on 03. The PRD text wins wherever a render and this document disagree.

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 + themes + the core journeyFeature 1 (pre-rendered voice sets, DISCLOSE audio-unlock, captions) + Feature 2 (theme manifest, live toggle, re-prime on toggle) + light/dark appearance axis + the Absorption Meter (§5) + screens 7/1/12/8/9/10 built to the mockups. Build the manifest first — the voice sets are per-theme.works sound-off (captions), on mobile (unlock), in all 4 theme×appearance combos
P2a — Sent Clones (§4b) — the chosen smoke/user testScope composer (screen 15) + Conversation Mode (screen 14) + sent-clones/ envelope with 3-layer enforcement (corpus filtering, policy prompt, output gate), hard-locked PII, expiry/revoke/per-slug cap, delete-me prefix registered same PR. Exit test: Byron sends an "AI knowledge only" clone to one real person; it holds scope under adversarial prompting.corpus filtering verified: OFF-scope facts absent from context, not just refused
P2b — 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

9b. User panel — four evaluations, accepted changes (2026-08-30)

Four independent reviews of this PRD + all 15 mockups: Dana (57, senior technologist — the target demographic), Frank (61, AI skeptic), Maya (AI power-user/enthusiast), and a mobile-first UI lead. Full transcripts summarized; the following changes are ACCEPTED and binding on the build.

From Dana (the customer)

From Frank (the skeptic) — the recipient-protection package

The design's blind spot: everything protected the owner from the recipient; nothing protected the recipient from the clone. All accepted:

From Maya (the enthusiast) — structural

From the UI lead — build directives (binding on Opus 5)

  1. Keyboard avoidance first (screens 8/10): visualViewport resize handling before anything new — every text input is currently coverable on iOS.
  2. applyTheme(themeKey, appearance) runtime swap replaces one-shot resolveSkin() (index.html:365).
  3. AudioContext primed in the DISCLOSE tap handler (index.html:433) + on theme toggle; muted-speaker chip fallback; captions always; never block the flow on audio.
  4. renderAgentCard(envelope, density) — one renderer, four densities (full / row / banner / mention) — is the only markup for a deployed clone, used on screens 02/04/11/13/14/15. States: draft → live → expiring → expired | capped | revoked, server-derived.
  5. Extend every status projection deliberately (Bug 2 applies to sent-clone fields too).
  6. Meter is monotonic (Math.max(prev, server) in pollUntilDone, index.html:641) and event-driven; 40/70/90 beats fire once each.
  7. Resume-safety: persist {jobId, answers, qi, theme} to localStorage on each advance() (index.html:571); on poll failure show "Connection lost — nothing is lost, the forge keeps working" with the meter frozen, resume from server truth.
  8. Preload FaceMesh at DISCLOSE (not camera time, index.html:1044); cap particles ~600 at devicePixelRatio>2.
  9. Command center / deployments rebuild as single-column mobile stacks; destructive actions (Revoke / RECALL ALL / Erase) all reuse the press-and-hold ring — the app's signature gesture (with ~30px drift forgiveness, index.html:466).
  10. Manifest + minimal real /sw.js (shell + /voice/* only, never API); endpoint voice is never faked with SpeechSynthesis — silent + upgrade-poll instead.

10. Open decisions for Byron

  1. Billing: top up OpenRouter (consolidates), Anthropic API credits (direct-API skills), or both? (§0)
  2. ~~Host narrator voices~~ — RESOLVED (Byron 2026-08-30): Byron's cloned voice; female-register variant is the default; ~1.3× speed. Both ship, toggleable.
  3. ~~Default theme~~ — RESOLVED by panel (D1): Cloning (warm) is the default; Absorption is the toggle.
  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~~ — RESOLVED by panel (F1): will not be built. Ever.
  6. Sent-clone transcript retention: panel resolves the shape — owner gets the after-action digest (D3) and the recipient gets one-tap erase (F5). Remaining call: whether full transcripts exist at all underneath the digest. Build default: digest-only.

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
Interface mockups (6 renders)https://clone-v3.arnao.ai/mockups.html
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