16.1 装配成一份操盘手册

前 15 章各写了一份交付物,收官第一件事是把它们装订成一册操盘手册:目录、每章验收清单与配置汇总三件事缺一不可。本节给出手册的装配清单(D 层),再用一份 TypeScript 内核校验「16 章齐全、章号唯一、三要素不缺、登记的配置真实存在」,并给出一枚可跨语言对拍的清单指纹。

站内《上线变现与长线运营》 已经把渠道机制与素材设计框架、eCPM/LTV/定价/留存/AB 实验这些「赚多少」的模型写完;那 51 篇是方法论与建模口径。本卷不重做这些,只做投放后台实操、广告聚合 SDK 对接、移动归因、资质办理、渠道联运与结算这些「钱怎么花出去、怎么收回来」的落地环节。到了收官这一章,任务变成一件很朴素的事:把前面 15 章各自的交付物装订成一册能交给操盘手直接用的手册。书架索引见全部书稿 ,那只是入口;手册是把散落的配置、清单与口径按章号钉在一起的成品。

手册不是把 15 份文档拼起来

一份能用的操盘手册,光有目录不够,光有正文也不够。它至少要把三样东西对齐到同一套章号上:

组成作用缺了会怎样
目录按章号索引到交付物与配置找不到「第 9 章的渠道分级表在哪」
验收清单每章一条可核对的合格标准交付了但没人知道算不算完成
配置汇总每章登记的配置文件来源配置散落各处,改了 A 忘了 B

三样东西必须共用同一套章号与同一份清单文件,否则手册会在第一次更新时就散架:有人加了第 12 章的配置却忘了在目录里登记,有人删了清单项却没人发现。所以本节的做法不是「写一本手册」,而是写一份手册的装配清单,再用一段程序校验它自洽——清单是唯一真源,目录、检查项与配置来源都从它派生。

D 层:装配清单

下面这份是 D 层装配清单 config/o16_handbook.json。它把卷四 16 章各登记一行:章号、章标题、一份主交付物、一份配置来源、一条验收清单。第 15 章是案例复盘,交付物是文档而非配置,故 config 留空。

{
  "version": 1,
  "game": "merge-island",
  "observedAt": "2026-10",
  "title": "《合成小岛》商业运营操盘手册",
  "note": "操盘手册的装配清单(D 层):把卷四第 1–15 章的交付物按章号装订成一册,每章登记一份主交付物、一份配置来源与一条验收清单。口径是「装配结构」的建模,不是任何真实交付物的实测。config 为空字符串表示该章交付物是复盘/案例文档而非配置(第 15 章)。真实交付物内容需真实业务环境,命令行不可复现(X)。全字段为整数或字符串,无浮点。",
  "chapters": [
    { "ch": 1,  "title": "投放后台与账户结构", "deliverable": "账户层级与出价配置表", "config": "o01_hierarchy.json",   "check": "账户/计划/广告组/创意四级齐全,出价方式与预算分配已标注" },
    { "ch": 2,  "title": "出价与放量",         "deliverable": "出价选择与预算爬坡表", "config": "o02_bid_choice.json",  "check": "oCPM/CPA/ROI 三选一有依据,爬坡节奏与止损线成对出现" },
    { "ch": 3,  "title": "素材工业化",         "deliverable": "素材生产线与测试矩阵", "config": "o03_line.json",        "check": "素材编号可追溯,测试矩阵每格有判定阈值与淘汰规则" },
    { "ch": 4,  "title": "移动归因",           "deliverable": "归因窗口与三方对账表", "config": "o04_window.json",      "check": "点击/展示归因窗口写明,三方差异有容差与追因路径" },
    { "ch": 5,  "title": "广告聚合平台",       "deliverable": "聚合架构与接入差异表", "config": "o05_mediation.json",   "check": "穿山甲/优量汇/AdMob 接入差异逐项对照,瀑布流层级完整" },
    { "ch": 6,  "title": "广告位配置与调优",   "deliverable": "广告位 ID 与流量分组表", "config": "o06_adslot.json",     "check": "广告位 ID 唯一,eCPM 分层与填充/展示率诊断口径一致" },
    { "ch": 7,  "title": "内购与支付通道",     "deliverable": "订单·回调·补单流程表", "config": "o07_pay_channel.json", "check": "订单状态机闭合,回调幂等与补单重试已定义" },
    { "ch": 8,  "title": "变现合规",           "deliverable": "广告内容与隐私合规清单", "config": "o08_adcopy.json",    "check": "广告素材红线逐条可查,未成年人保护与同意管理有落点" },
    { "ch": 9,  "title": "渠道与联运",         "deliverable": "渠道分级与结算周期表", "config": "o09_channel_tier.json", "check": "渠道分档有对接清单,分成与结算周期逐渠道写明" },
    { "ch": 10, "title": "代理发行与商务",     "deliverable": "自发行/代理决策与筹码表", "config": "o10_clauses.json",   "check": "分成谈判筹码与底线量化,合同关键条款清单可核" },
    { "ch": 11, "title": "版号与资质办理",     "deliverable": "申请材料与倒排时间线", "config": "o11_material.json",   "check": "出版物号/文网文/软著材料齐全,资质倒排前置上线节点" },
    { "ch": 12, "title": "结算与财务",         "deliverable": "平台分成与结算周期表", "config": "o12_settlement.json", "check": "扣点顺序正确,账期拆结算周期+冻结期,税务口径标 X" },
    { "ch": 13, "title": "运营机制与协作",     "deliverable": "运营 SOP 与例会编排表", "config": "o13_sop.json",       "check": "关键指标挂到例会节点,客服/社区分工边界已声明" },
    { "ch": 14, "title": "从投放到变现的完整账", "deliverable": "单位账与月度经营账", "config": "o14_unit.json",       "check": "CAC/ARPDAU/LTV 口径一致,月度利润与现金流缺口可复算" },
    { "ch": 15, "title": "案例与失败模式",     "deliverable": "《合成小岛》投放变现复盘", "config": "",                "check": "失败模式有可跑对照脚本,关键决策对照表可追溯" },
    { "ch": 16, "title": "操盘收官",           "deliverable": "操盘手册与全链路对账", "config": "o16_handbook.json",  "check": "手册装配完整、全链路对账残差在容差内、交付物清单闭合" }
  ]
}

清单本身是数据,它是否自洽要靠程序判定:16 章齐不齐、章号重不重、三要素有没有空、登记的配置文件到底存不存在——这些都是可以机械检查的,不该靠人肉扫。

P 层:装配内核

下面这段是 P 层装配内核 core/src/o16/handbook.ts。它读同一份清单,逐条校验结构,并给出一枚清单指纹(对「章号|标题|交付物|配置|清单」逐行做 FNV-1a 32 位)。指纹的用处是:清单只要被人偷偷改一个字,指纹就变,交接时一比对就知道版本对不对。

// file: core/src/o16/handbook.ts
// tier: P
// verify: node --test 'core/test/o16_*.test.ts'
//
// 操盘手册装配内核:读 config/o16_handbook.json 的装配清单,校验「第 1–16 章齐全、章号唯一、
// 每章三要素(交付物/配置来源/验收清单)不缺、登记的配置确实存在」,并给出一枚清单指纹
// (FNV-1a 32 位,与 Python 侧同法可对拍)。只用可擦除语法(禁 enum / namespace / 参数属性 / 装饰器)。

export interface HandbookChapter {
  readonly ch: number; readonly title: string;
  readonly deliverable: string; readonly config: string; readonly check: string;
}
export interface Handbook {
  readonly version: number; readonly game: string; readonly title: string;
  readonly chapters: readonly HandbookChapter[];
}
export interface HandbookReport {
  readonly chapterCount: number; readonly expected: number;
  readonly missing: number[]; readonly dupChapters: number[]; readonly emptyFields: string[];
  readonly missingConfigs: string[]; readonly configCount: number;
  readonly fingerprint: string; readonly valid: boolean;
}

/** 清单指纹:对「章号|标题|交付物|配置|清单」逐行拼串做 FNV-1a 32 位(UTF-8 字节)。 */
export function fingerprint(hb: Handbook): string {
  const norm = hb.chapters
    .map((c) => `${c.ch}|${c.title}|${c.deliverable}|${c.config}|${c.check}`)
    .join("\n");
  const bytes = new TextEncoder().encode(norm);
  let h = 0x811c9dc5;
  for (const b of bytes) {
    h ^= b;
    h = Math.imul(h, 0x01000193) >>> 0;
  }
  return h.toString(16).padStart(8, "0");
}

/** 校验装配清单:章号 1..expected 齐全且唯一、三要素非空、登记的配置存在。 */
export function validateHandbook(hb: Handbook, availableConfigs: readonly string[], expected = 16): HandbookReport {
  const chs = hb.chapters.map((c) => c.ch);
  const missing: number[] = [];
  for (let i = 1; i <= expected; i += 1) if (!chs.includes(i)) missing.push(i);
  const dupChapters = chs.filter((c, i) => chs.indexOf(c) !== i);
  const emptyFields: string[] = [];
  for (const c of hb.chapters) {
    if (!c.title.trim()) emptyFields.push(`${c.ch}:title`);
    if (!c.deliverable.trim()) emptyFields.push(`${c.ch}:deliverable`);
    if (!c.check.trim()) emptyFields.push(`${c.ch}:check`);
  }
  const known = new Set(availableConfigs);
  const missingConfigs = hb.chapters
    .map((c) => c.config)
    .filter((f) => f !== "" && !known.has(f));
  const valid = hb.chapters.length === expected && missing.length === 0
    && dupChapters.length === 0 && emptyFields.length === 0 && missingConfigs.length === 0;
  return { chapterCount: hb.chapters.length, expected, missing, dupChapters, emptyFields,
    missingConfigs, configCount: hb.chapters.filter((c) => c.config !== "").length,
    fingerprint: fingerprint(hb), valid };
}

配套测试 core/test/o16_handbook.test.ts 把清单指纹写成金标准,并验「删一章」「登记不存在的配置」两种破坏都能被判无效:

// file: core/test/o16_handbook.test.ts
// tier: P
// verify: node --test 'core/test/o16_*.test.ts'
//
// 硬断言:手册装配清单校验通过,且清单指纹与 Python 侧 FNV-1a 实现逐位一致。

import { test } from "node:test";
import assert from "node:assert/strict";
import { readFileSync, readdirSync } from "node:fs";
import { fileURLToPath } from "node:url";
import { dirname, join } from "node:path";

import { validateHandbook, fingerprint } from "../src/o16/handbook.ts";

const ROOT = join(dirname(fileURLToPath(import.meta.url)), "..", "..");
const hb = JSON.parse(readFileSync(join(ROOT, "config", "o16_handbook.json"), "utf8"));
const available = readdirSync(join(ROOT, "config")).filter((f) => f.endsWith(".json"));

test("清单指纹与 Python FNV-1a 一致(跨语言对拍)", () => {
  assert.equal(fingerprint(hb), "cd875fac");
});

test("装配清单校验通过:16 章齐全、章号唯一、三要素不缺、配置存在", () => {
  const rep = validateHandbook(hb, available);
  assert.equal(rep.chapterCount, 16);
  assert.deepEqual(rep.missing, []);
  assert.deepEqual(rep.dupChapters, []);
  assert.deepEqual(rep.emptyFields, []);
  assert.deepEqual(rep.missingConfigs, []);
  assert.equal(rep.valid, true);
});

test("第 15 章为案例复盘,无独立配置,不计入配置数", () => {
  const rep = validateHandbook(hb, available);
  assert.equal(rep.configCount, 15);
  assert.equal(hb.chapters.find((c: { ch: number }) => c.ch === 15).config, "");
});

test("缺一章即判无效:删掉第 9 章后 missing 命中", () => {
  const broken = { ...hb, chapters: hb.chapters.filter((c: { ch: number }) => c.ch !== 9) };
  const rep = validateHandbook(broken, available);
  assert.deepEqual(rep.missing, [9]);
  assert.equal(rep.valid, false);
});

test("登记了不存在的配置即判无效", () => {
  const broken = { ...hb, chapters: hb.chapters.map((c: { ch: number; config: string }) =>
    c.ch === 1 ? { ...c, config: "o99_ghost.json" } : c) };
  const rep = validateHandbook(broken, available);
  assert.deepEqual(rep.missingConfigs, ["o99_ghost.json"]);
  assert.equal(rep.valid, false);
});

在本机跑 node --test 'core/test/o16_*.test.ts',11 个用例全过(含 16.2 的 6 条):

✔ 清单指纹与 Python FNV-1a 一致(跨语言对拍) (1.343333ms)
✔ 装配清单校验通过:16 章齐全、章号唯一、三要素不缺、配置存在 (0.714542ms)
✔ 第 15 章为案例复盘,无独立配置,不计入配置数 (0.202625ms)
✔ 缺一章即判无效:删掉第 9 章后 missing 命中 (0.206375ms)
✔ 登记了不存在的配置即判无效 (0.157292ms)
ℹ tests 11   ℹ pass 11   ℹ fail 0
fingerprint = cd875fac

fingerprint = cd875fac 是清单的指纹:同一份清单在 Node 的 handbook.ts 与 Python 的 FNV-1a 实现里算出同一个值(Python 侧一句 int 循环即可复算),说明「装配清单」这层也没有跨语言的口径分叉。这和第 12 章「一份 config、三种消费」是同一个信念:清单不是散文,是可以被程序读、被程序判的契约。

为什么清单是唯一真源

「写一本手册」和「写一份装配清单」的区别,在第一次更新时就会暴露。假设第 11 章的资质材料多了一项「网络文化经营许可证」,如果手册是一份 Word 文档,你得手工翻到第 11 章改正文、改目录、改检查表——三处漏一处就是一次事故。而清单是数据,正文与目录都从它渲染:

  • 目录:按 ch 排序直接生成,不会漏章;
  • 检查表:每章的 check 就是一条可勾选项,不用另抄一遍;
  • 配置汇总:config 字段一列,谁的配置改了、有没有登记,一比对就知道。

更关键的是,清单可以被程序判对错。人手写的手册没法自动验证「16 章齐不齐」,但 validateHandbook 可以在每次提交前跑一遍:缺章、重复、空字段、幽灵配置——四类错误全部机械可查。这就是把「手册」从文档降格成数据的投影换来的好处。

一个容易忽略的细节是第 15 章:它是案例复盘,交付物是一份文档而不是配置,所以 config 字段留空。校验器对此的处理是「空配置合法、不存在的配置非法」——空是「本章没有配置文件」,写了一个 o99_ghost.json 才是「登记了不存在的东西」。两者的区别很重要:前者是设计,后者是 bug。

手册的边界:内容不可复现(X 层)

必须把边界划清。本节能机械保证的是结构:章号齐、字段全、配置存在、指纹稳定。下面这些属于 X 层,需真实业务环境,命令行不可复现:

  • 每份交付物的实际内容(账户结构、素材矩阵、结算单、资质材料),要靠真实投放后台、真实平台条款与真实监管流程产出;
  • 每章 check 的实际通过与否,取决于真实运营结果,不是清单能判的;
  • 手册交付给谁、对方是否认可,是组织与商务问题,命令行不可复现。

工程上正确的切法与前几章一致:结构层可复现、内容层不可复现。结构层保证「手册没漏东西、没登记错东西」,内容层靠拿到真实材料后反填进清单(把实际交付物挂到对应章号上),结构校验立刻重跑一遍。这也是 16.3 交付物清单与本节装配清单共用同一套章号的原因。

16 章装订表

校验通过后,手册的目录就是清单的一个投影。下表是装配结果的速览(完整清单见落盘 config/o16_handbook.json):

章交付物配置来源验收清单要点
1–3账户/出价/素材配置表o01–o03四级层级齐全、爬坡配止损、素材编号可追溯
4–6归因窗口/聚合差异/广告位表o04–o06归因窗口写明、接入差异对照、广告位 ID 唯一
7–8内购流程/合规清单o07–o08订单状态机闭合、广告红线可查
9–10渠道分级/商务筹码表o09–o10分成与账期逐渠道写明、筹码与底线量化
11–12资质材料/结算周期表o11–o12材料齐全倒排上线、扣点顺序与账期拆解正确
13–14运营 SOP/单位账与月度账o13–o14指标挂例会、CAC/ARPDAU/LTV 口径一致
15–16复盘文档/手册与对账o16_handbook复盘可追溯、手册自洽、对账残差在容差内

自检表

检查项合格标准
章号覆盖1–16 齐全、无缺号、无重复
三要素每章交付物/配置来源/验收清单非空
配置存在登记的配置文件名在 config/ 下真实存在
指纹稳定清单未改则指纹不变,交接可比对
边界清晰交付物内容与验收结论标 X,不写成「实测」

手册装配解决了「东西在哪、算不算完成」,但清单自洽只说明结构没问题,不代表账算得对。下一节我们把各章的账拉到同一张台账上,用共享的经济模型复算一遍,看跨章的指标对不对得上。

阅读导航:上一节:15.3 关键决策对照表 · 下一节:16.2 全链路对账与仿真验收 。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「minigame」更多文章

  1. 附录 F:全书公式、参数与数据集索引
  2. 9.3 同意管理与数据出境
  3. 9.2 COPPA 与儿童向游戏的限制