feat: Cuddler-first Growth OS (P18–P19) + loopback design language#1
Merged
Conversation
WHY: Adex 的第一个真实客户 Cuddler 初期即投放 $5K,需要把 Adex 从 "投放 Agent 平台"扩展为服务其付费增长的"增长操作系统"。方案结合 HakkoAI 的增长基础设施能力与 Cuddler 的 GTM 与单位经济约束。 WHAT: - 00-cuddler-first-redesign.md: 三层重构(数据底座/渠道执行/Agent 决策) + Phase 18–21 路线图,承接 docs/agent 的 Phase 10–17 - 01-5k-pilot-plan.md: $5K 首投的 6 个关键决策,正反方辩论 + 逐题裁决 (web 漏斗为主测量臂、序贯 kill/scale 门、三层预算风控等) - 02-integration-contract.md: 给 Cuddler 团队的对接契约(门禁/分工/时间线) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
WHY: P18 底座第一块,也是辩论结论的代码化。所有增长指标需单一口径 (避免 HakkoAI 的 strict/wide DAU 口径事故);$5K pilot 的 kill/scale 判据(P5 裁决)需可解释、可测。 WHAT: - src/lib/growth/kpi-canon.ts: 指标单一事实来源。核心是 eCAC*(含视频 loss-leader 补贴成本),修正裸 CPI 对真实 CAC 的系统性低估。realized vs projected LTV 严格分离;k-factor 带 measured/estimated 置信标记。 - src/lib/growth/pilot-gates.ts: 序贯 kill/scale 门(Gate A/B/C + 全局 熔断),编码 payment_signal_gate 纪律——proxy 只能降/停,加码必须见 真实付费信号。返回带理由的决策。 - 两个 .test.ts(vitest):25 断言,纯逻辑经 node type-strip 全绿。 Ref: docs/growth/01-5k-pilot-plan.md §P5 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
WHY: Cuddler pilot 的度量脊柱需要一套归一化的增长数据表——把 GA4/ RevenueCat/深链的转化事件、分渠道 cohort、非 cohort 增长指标落库, 供 /growth 看板、周报与 Agent perceive 读取。 WHAT(纯增量,不改现有表): - PromotedApp: 被推广的 App(Cuddler iOS = 首行),app_install campaign 经 Campaign.promotedAppId 指向 - ConversionEvent: 归一化漏斗事件,unique 键在 ingest 去重 - CohortSnapshot: 获客日 × 渠道 cohort,growth-sync cron 每日重算 - GrowthMetric: k-factor / 周分享数 / ASO 排名等非 cohort 指标 - Organization 加 4 个反向关系;全部 FK 从 Organization CASCADE - 迁移手写(仓库无本地库约定),字段与 schema 交叉核对一致 NOTE: 本环境无 node_modules,未能在本地跑 prisma generate/validate; 生成的 client 由 Docker build(prisma generate)产出,迁移由 start.sh 的 migrate deploy 应用,CI 的 next build 会校验 schema。 Ref: docs/growth/00-cuddler-first-redesign.md §4 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
WHY: 渠道口径必须单点定义——ConversionEvent.channel、CohortSnapshot、
pilot 分臂、skan_maturity guardrail 都依赖同一套渠道分类,避免分叉。
WHAT:
- src/lib/growth/channels.ts: 规范渠道 id(web 漏斗/ASA/iOS-SKAN/KOL/
organic 等),isPaidChannel / isSkanChannel(喂 pilot-gates 的 skanImmature),
resolveChannel 按对接契约 adex_{arm} UTM 约定归因,带 deterministic/
skan/inferred 置信标记。
- channels.test.ts(vitest):13 断言,node type-strip 全绿。
Ref: docs/growth/01-5k-pilot-plan.md §P2 · docs/growth/02-integration-contract.md §3.2
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…sionEvent WHY: pilot 的 scale 判据只信真实付费信号(payment_signal_gate)。RevenueCat 是该信号来源,需一条鉴权 + 幂等的接收链路——直接规避 HakkoAI"支付回调无 鉴权无幂等"的 P0。 WHAT: - events.ts: 规范事件名/来源 taxonomy + ConversionEventInput 形状(对齐 Cuddler analytics_canon) - ingest-auth.ts: verifyBearer(常量时间,RC 静态 Authorization 头)+ verifyHmac(我方带签名事件推送,镜像 slack-signature)+ readBearer - revenuecat.ts: mapRevenueCatEvent 纯映射(INITIAL_PURCHASE/RENEWAL/ TRIAL/CHURN → 规范事件),防御性解析 unknown - POST /api/ingest/revenuecat?org=<id>: 按 org 查 secret(PlatformAuth,env 兜底)→ 常量时间校验 → createMany skipDuplicates 幂等落库 - 18 个新 vitest 断言(含 replay/篡改/长度不等边界);tsc + eslint 干净 Ref: docs/growth/00-cuddler-first-redesign.md §5 · 02-integration-contract.md §5 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
WHY: 分渠道 cohort(install→激活→D1/D7→trial→订阅→LTV)是 pilot 的度量 脊柱与 /growth 看板、周报、Agent perceive 的数据源。 WHAT: - cohorts.ts: buildCohortSnapshots 纯聚合——用户归入其首个获客事件 (install/signup)的(日×渠道)cohort;RC 无渠道的付费事件经 userKey 归因到获客渠道;留存用 engagement 事件在 day+N 的出现近似;LTV 走 kpi-canon.realizedLtv;CAC 可由传入 spend 计算否则 null - POST /api/cron/growth-sync: 滚动 60 天,删窗口内旧快照 + 重插(幂等重算), X-Cron-Secret 鉴权,纳入现有 CronSecret 体系 - 8 个新 vitest 断言(含跨渠道同日分离、RC 归因、无 userKey 忽略、CAC) Ref: docs/growth/00-cuddler-first-redesign.md §4.1 · §10 (P18) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
WHY: Cuddler 团队上线周即需在 Adex 内看到分渠道全漏斗,替代手工拼表 (对接契约 §2 的交付物)。 WHAT: - GET /api/growth/overview: 把 org 的 CohortSnapshot 折叠成 funnel 总览 + 分渠道明细,所有 rate 走 kpi-canon(看板/报告/Agent 同口径) - /growth 页:funnel StatCards(installs/激活/D1/D7/订阅/收入)+ 分渠道 cohort 表(激活/留存/订阅率/LTV/CAC)+ 未上线时的友好空状态 - sidebar 加"Growth"入口(🌱,Dashboard 之后) - tsc + eslint + next build 全通过 Ref: docs/growth/00-cuddler-first-redesign.md §8 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ncy-encoded WHY: 参考 loopback(loopback-pitch.pages.dev)重塑 Adex 设计风格。loopback 的招牌理念是"颜色即身份"——绿=人、青=机器;Adex 本身就是人+AI-agent 平台 (审批队列、guardrail、L0–L4 自治),这套理念几乎一对一契合。 WHAT: - globals.css: 注册 loopback 令牌到 @theme(bg/panel/surface/line/ink/mut/ signal/ai/ok/warn/bad/max + mono + 紧半径 5/8/11px);把既有 .dark 工具反转 重新调成 loopback 精确配色;品牌蓝→signal(lime);live● 心跳动画 - dark-first:layout 预注入脚本 + theme-provider 默认深色(loopback 是深色家) - 身份编码原则落地:sidebar 品牌/人类项=lime、agent-loop 项=cyan; status/severity badge executing=agent cyan;primary 按钮=lime 深字 - 主键 mono(StatCard 值、badge、live● 状态行 127.0.0.1 :: ready) - Card 紧半径 + 面板/hairline - docs/design/00-loopback-design-language.md:完整设计规范 - 验证:tsc + eslint + next build 全绿;登录页实机截图确认深色+lime 渲染 Ref: https://loopback-pitch.pages.dev/ Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…status WHAT: - GET /api/growth/channels: per-channel roll-up + live pilot-gate decision (pilot-gates.evaluateChannel — same logic the Agent uses); eCAC*, SKAN flag - GET /api/growth/cohorts: per-day×channel cohort rows (rates via kpi-canon) - /growth/channels: channel table + GateBadge (scale/hold/halve/kill/freeze) - /growth/cohorts: cohort table with lime→bad retention heat tint - _ui.tsx: shared GrowthTabs (Overview/Channels/Cohorts/Creators/Reviews), channelLabel, pct, GateBadge — loopback mono/agency styling - tsc + eslint + next build green Ref: docs/growth/01-5k-pilot-plan.md §P5 · docs/growth/00-cuddler-first-redesign.md §8 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
WHAT: - ga4.ts: mapGa4Event (Cuddler GA4 event names → canonical EventName, channel from UTM) + thin runGa4Report REST client (token via ADC, like storage.ts) - ingest-parse.ts: parseIncomingEvents — validate/resolve canonical events, drops unknown names/sources (never trusts input) - POST /api/ingest/events?org=: HMAC-authed batch push (backup channel when not pulling GA4), idempotent via ConversionEvent unique key - 12 new vitest assertions (80 total); tsc + eslint clean Ref: docs/growth/00-cuddler-first-redesign.md §5 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
WHAT (additive, no existing-table changes): - CreatorPartnership + CreatorPost: KOL cooperation台账 + per-post natural-uplift attribution fields (baseline/uplift installs, effectiveCpi) — hakko-kol-agent method - AppReview: store review + LLM classification (sentiment/topics/priority); id = source:review_id hash → idempotent on re-ingest - Organization back-relations; FKs cascade; migration hand-authored + field- cross-checked; prisma validate + generate pass Ref: docs/growth/00-cuddler-first-redesign.md §4.1 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
attributePost: installs above the pre-publish baseline over an attribution window → upliftInstalls + effective CPI (hakko-kol-agent method). Quasi- experiment, documented as directional. 3 vitest cases. Ref: docs/growth/00-cuddler-first-redesign.md §1.3 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…tion WHAT: - reviews.ts: parseAppStoreReviews (public RSS JSON, no auth) + rule-based fallbackClassify (sentiment/topics/priority from rating+keywords, ported Feedback_agent taxonomy) + LLM classifyReviews (completeJSON, falls back on failure) + fetchAppStoreReviews - POST /api/cron/review-sync: pull per iOS PromotedApp × [us,gb], classify, upsert AppReview (idempotent by id), count new P0s - 10 new vitest assertions (90 total); tsc + eslint clean Ref: docs/growth/00-cuddler-first-redesign.md §1.3, §10 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ict) Pure. evaluatePilotBudget (global $5K pacing: warn 80% / auto-pause 95%), evaluateChannelBreach (one-directional auto-pause only on egregious breach; learning-phase + SKAN-immature channels protected from stale-data pauses), tierCacCeiling/withinCacCeiling (eCAC* ≤ 5× first-month net). 15 vitest cases. Ref: docs/growth/01-5k-pilot-plan.md §P6 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
WHAT: - Campaign.promotedAppId field + migration (app_install/web_conversion campaigns point at a PromotedApp) - campaign-objective.ts (pure): resolvePlatformObjective (neutral → Meta/TikTok/ Google objective) + validateLaunch — app_install needs bundleId/storeId, enforces SKAN iOS campaign cap (Meta 9 / TikTok 11), web_conversion needs a destination domain. The launch route calls this before the adapter. - 12 vitest cases; prisma validate/generate + tsc + eslint clean NOTE: adapter-side API wiring (actual OUTCOME_APP_PROMOTION createCampaign) is the remaining integration step — needs platform sandbox creds. Ref: docs/growth/00-cuddler-first-redesign.md §5.2 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
WHAT: - GET /api/growth/creators: KOL partnerships + posts + blended effective CPI (cost / total uplift, via kpi-canon) - GET /api/growth/reviews: recent classified reviews + sentiment/priority filter + P0/negative counts - /growth/creators: partnership cards with per-post uplift table (mono, agency cyan links) - /growth/reviews: review stream with sentiment/priority/topic chips + filters - loopback-styled; tsc + eslint + next build clean Ref: docs/growth/00-cuddler-first-redesign.md §8 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
AgentPulse heartbeat strip (lb-live + mono `127.0.0.1 :: ready`) on the growth overview; mono/tabular-nums across the channel table. Agent surfaces (decisions/ approvals) already inherit the agency lens via the restyled status/severity badges (executing=cyan) + token cascade. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Extends Adex from an ad-execution platform into a growth operating system for its first customer, Cuddler (iOS-first AI-roleplay app running an initial $5,000 paid pilot). Also adopts the loopback design language.
What's inside
Strategy & decisions (
docs/growth/)00-cuddler-first-redesign.md— three-layer redesign + Phase 18–21 roadmap (extends the shipped Phase 10–17 agent system)01-5k-pilot-plan.md— the $5K pilot's 6 key decisions, adjudicated from a pro/con debate (web-funnel as the SKAN-free measurement spine; sequential kill/scale gates; three-layer budget control)02-integration-contract.md— Cuddler-facing integration contractP18 — measurement foundation
PromotedApp/ConversionEvent/CohortSnapshot/GrowthMetric+ migrationkpi-canon.ts(single source of truth; eCAC* includes the video loss-leader),pilot-gates.ts(sequential kill/scale gates),channels.ts(taxonomy + UTM attribution)/api/ingest/events(HMAC) +growth-synccohort cron/growthdashboard: overview / channels (live gate status) / cohortsP19 — organic attribution + paid readiness
CreatorPartnership/CreatorPost/AppReview+Campaign.promotedAppIdreview-synccronbudget-guard.ts(P6 pacing/cap/breach),campaign-objective.ts(objective resolver + SKAN-cap launch validator)/growthcreators + reviews pagesDesign — adopts loopback's dark, terminal-native language with color-encoded agency (human=lime
#a3e635/ agent=cyan#56c7f5). Spec:docs/design/00-loopback-design-language.md.Verification
prisma validate+generate· 110 vitest ·tsc --noEmit·eslint·next build— all green. Design confirmed on the live login page.Not included (needs external creds / platform sandbox)
Adapter-side app-install API wiring (
OUTCOME_APP_PROMOTIONcreateCampaign), GA4/ASC/RevenueCat live pulls, ASA adapter (P20), Growth Agent tools (P21).🤖 Generated with Claude Code