以下情境为教学假设,人物与数字不代表经核实的真实案例。
卷二写了 12 章,从合同结构一路写到保险、IP、渠道与业务连续性。这一节做收口:用附录 C 的 46 项清单给三个案例打分,看分数落在哪一档,再把最弱的组映射到卷三的具体章节。最后不写总结陈词,而是留三个交接问题——它们决定卷三从哪一章开始读。
六组清单:从条款到分数
附录 C 把卷二收成六组、46 项、满分 92 分。每组按 0、1、2 三档评分:2 分是有书面证据且金额可复算,1 分是有证据但不完整,0 分是拿不出证据。组内条目与证据要求见附录 C,正文只保留组级分数和权重。
| 组 | 对应章节 | 满分 | 这一组在问什么 |
|---|---|---|---|
| 合同结构 | 第 1–2 章 | 20 | 八个部分是否齐全,每个部分有没有数字 |
| 关键条款 | 第 2 章 | 16 | 责任上限、续约窗口、SLA 抵扣能不能算出金额 |
| 应收与坏账 | 第 3–4 章 | 14 | 应收能不能收回,准备、催收与前置保护是否匹配 |
| 争议与保险 | 第 5–6 章 | 14 | 出事之后能主张多少,保险实际赔多少 |
| IP 与渠道 | 第 7–9 章 | 14 | 资产能否转移,渠道净得与退出成本是否算过 |
| 依赖与连续性 | 第 10–12 章 | 14 | 关键依赖、迁移成本、预案与责任人是否齐全 |
权重不是平均分的。合同结构 20 分,因为它决定合同能不能执行、能不能算钱;关键条款 16 分,因为它决定最坏损失;其余四组各 14 分,分别覆盖现金、尾部、资产转移与业务连续性。权重是附录 C 的固定口径,读者可以按自己的生意调整,但调整后要固定下来,否则跨期分数不可比。
评分规则只有一条:拿不出证据的项按 0 分。没有合同原件、没有账龄表、没有保单、没有退出条款,都算 0 分;「大概有」「应该在邮箱里」不算证据。这条规则会让分数偏低,但偏低比虚高有用——它指向的是可以补的材料,而不是一个让人安心的数字。
三案例的评分
把三案例代入附录 C,得到下表。分数是教学示例,用于演示评分方法,不是对案例的正式评价。
| 组 | 满分 | LedgerLite | Tidecast | Nord Studio |
|---|---|---|---|---|
| 合同结构 | 20 | 18 | 15 | 12 |
| 关键条款 | 16 | 14 | 12 | 9 |
| 应收与坏账 | 14 | 12 | 13 | 7 |
| 争议与保险 | 14 | 12 | 10 | 9 |
| IP 与渠道 | 14 | 11 | 7 | 6 |
| 依赖与连续性 | 14 | 11 | 5 | 7 |
| 合计 | 92 | 78 | 62 | 50 |
| 得分率 | 84.8% | 67.4% | 54.3% | |
| 评级 | 健康 | 需关注 | 高风险 |
LedgerLite 78/92,84.8%,落在健康档。合同结构 18/20 是三家里最高的:企业订阅协议、DPA、Net 15、12 个月费用上限、99.5% 与 10% 抵扣都有书面落点。失分集中在终止过渡、上限之外的赔偿、开源与 DPA 维护成本,以及云 60%、支付 25% 的依赖。它的最弱组不是合同,而是依赖与连续性(11/14):合同能算钱,但云和支付账号不在自己手里。
Tidecast 62/92,67.4%,落在需关注档。应收与坏账 13/14 是三家里最高的,因为平台月结把应收压到接近零;合同结构 15/20 已经接近平台标准协议的上限。真正拖低总分的是依赖与连续性(5/14):Steam 占销量 80%,没有保险,平台条款不可谈,90 天收入暴露 $19,079。它的高分项和低分项指向同一件事——平台替它收了钱,也替它承担了风险。
Nord 50/92,54.3%,落在高风险档。应收与坏账 7/14 最低:Net 30、8% 逾期、2% 坏账准备;IP 与渠道 6/14 也最低:前 3 家客户 48%、转介绍 55%,把回款和收入来源绑在同一批人身上。合同结构 12/20、关键条款 9/16,说明它的弱项不是「不会写合同」,而是「生意形态让条款难以转移」。这也解释了 3.0 倍 SDE 与 4.5 倍 SDE 的差距。
分数之间的差距不是经营水平的排序。Tidecast 的 62 分高于 Nord 的 50 分,但 Tidecast 的 SDE 是 $121,171,Nord 只有 $34,320;Nord 的生意更小、更依赖人,所以同样的缺口占 SDE 的比例更高。清单衡量的是「合同与风险能不能被第三方复核」,不是「谁赚得多」。
最弱的组指向卷三哪一章
卷三解决的是「生意怎么定价、怎么交割、怎么退出」。把每组最弱的项映射到卷三,就得到一张入场任务表。注意映射的是「缺口会在哪里被定价」,不是「缺口应该在哪里修」;修缺口是卷二的事,定价是卷三的事。
| 案例 | 最弱的组 | 得分 | 卷三对应章节 | 缺口会在哪里变成价格 |
|---|---|---|---|---|
| LedgerLite | 依赖与连续性 | 11/14(78.6%) | 第 8 章 8.2 客户、合同与账号迁移 | 云 60%、支付 25% 的账号迁移进入交割条件 |
| Tidecast | 依赖与连续性 | 5/14(35.7%) | 第 8 章 8.2 客户、合同与账号迁移 | Steam 账号、商店页与结算关系决定收入能否延续 |
| Nord Studio | IP 与渠道 | 6/14(42.9%) | 第 6 章 6.3 技术与知识产权尽调 | 交付物归属、转介绍关系与客户集中进入尽调 |
| Nord Studio | 应收与坏账 | 7/14(50.0%) | 第 6 章 6.1 财务尽调 | Net 30、8% 逾期与 2% 准备进入营运资金调整 |
LedgerLite 的 IP 与渠道也是 11/14,和依赖与连续性并列最低。这里选连续性,是因为附录 C 把第六组设为交叉校验组:合同矩阵和敞口表都说「条款可控」,但云与支付账号不在公司手里,交割后收入可能断。买方不会因为一份 DPA 就忽略账号迁移;它会在交割清单里逐项确认云账号、支付账号、域名和回调地址能不能转。
Tidecast 的最弱组没有争议:依赖与连续性 5/14。它的应收与坏账 13/14,看起来很好,但这是因为平台替它收款;平台一旦下架或改变结算,应收科目仍然是零,收入却归零。买方在 8.2 里要确认的不是「有没有应收」,而是「Steam 账号、商店页、评价与结算关系能不能一起转」。如果转不了,191.8% 的缺口就只能折价。
Nord 有两组并列最弱。IP 与渠道 6/14 更低,所以先映射到 6.3 技术与知识产权尽调:咨询交付物归客户、产品归工作室,但转介绍 55% 没有合同,前 3 家客户 48%,买方会追问「客户关系是公司的还是合伙人的」。应收与坏账 7/14 映射到 6.1 财务尽调:Net 30、8% 逾期、2% 准备会进入营运资金调整。两组一起看,才能解释为什么 Nord 只能按 3.0 倍 SDE 成交,而不是 4.5 倍。
三张映射表合起来说明一件事:卷二末的最弱组,决定卷三的阅读起点。LedgerLite 和 Tidecast 从第 8 章读起,Nord 从第 6 章读起。不是所有人都要从第 1 章融资选项开始。
写成代码:volume-review.ts
代码把六组评分、评级和最弱组的路由写成函数。reviewRiskVolume 要求恰好六组,并且每组必须使用附录 C 的固定权重 20/16/14/14/14/14:少一组或改权重都报错,而不是按零分算——缺组意味着评审不完整,不是这一组没有风险。评级沿用 70% 和 55% 两条线,和卷一保持同一把尺子,跨卷比较不用重新换算。
最弱组按得分率排序,不按绝对失分排序。合同结构满分 20,丢 5 分是 75%;依赖与连续性满分 14,丢 3 分是 78.6%;绝对失分不同,得分率才说明相对缺口。分数相同时取后一组:LedgerLite 的 IP 与渠道、依赖与连续性都是 11/14,附录 C 把第六组设为交叉校验组,所以平局归连续性。
volumeThreeFocus 把六组映射到卷三的章节,返回章节号、节名和一句理由。依赖与连续性映射到第 8 章 8.2,而不是第 2 章的合伙人退出:这两家的依赖是云、支付和平台账号,不是合伙人;只有 Nord 的合伙人问题走第 2 章,而它当前的最弱组是 IP 与渠道,先走第 6 章。
// file: src/contract/volume-review.ts
// tier: L1
// verify: node --test test/contract/volume-review.test.ts
import { type Bps, divide } from "../core/rate.ts";
import { type Result, fail, ok } from "../core/result.ts";
export type RiskGroupKey =
| "contract"
| "keyTerms"
| "receivable"
| "disputeInsurance"
| "ipChannel"
| "continuity";
export type RiskReviewGroup = {
key: RiskGroupKey;
maxScore: number;
score: number;
};
export type VolumeThreeFocus = {
chapter: number;
section: string;
reason: string;
};
export type RiskReviewResult = {
totalScore: number;
maxScore: number;
scoreBps: Bps;
grade: "healthy" | "watch" | "high-risk";
weakestKey: RiskGroupKey;
weakestBps: Bps;
focus: VolumeThreeFocus;
};
export const GROUP_ORDER: RiskGroupKey[] = [
"contract",
"keyTerms",
"receivable",
"disputeInsurance",
"ipChannel",
"continuity",
];
export const GROUP_LABELS: Record<RiskGroupKey, string> = {
contract: "合同结构",
keyTerms: "关键条款",
receivable: "应收与坏账",
disputeInsurance: "争议与保险",
ipChannel: "IP 与渠道",
continuity: "依赖与连续性",
};
/** Weights come from appendix C: 20 + 16 + 14 + 14 + 14 + 14 = 92. */
export const GROUP_MAX: Record<RiskGroupKey, number> = {
contract: 20,
keyTerms: 16,
receivable: 14,
disputeInsurance: 14,
ipChannel: 14,
continuity: 14,
};
/**
* Each group points at the volume-three section where its gap gets priced.
* The continuity group routes to closing and transition, because account and
* contract migration is where dependency gaps become closing conditions.
*/
const FOCUS: Record<RiskGroupKey, VolumeThreeFocus> = {
contract: {
chapter: 6,
section: "6.2 客户与合同尽调",
reason: "合同能否转让、控制权变更是否触发终止,决定买方买到的收入是否延续",
},
keyTerms: {
chapter: 7,
section: "7.3 陈述保证、赔偿与托管",
reason: "责任上限、SLA 与终止结算的缺口,要进入陈述保证与赔偿条款",
},
receivable: {
chapter: 6,
section: "6.1 财务尽调",
reason: "应收账龄、坏账准备与营运资金调整,决定成交价的下调项",
},
disputeInsurance: {
chapter: 7,
section: "7.3 陈述保证、赔偿与托管",
reason: "未决争议与未覆盖缺口,要在交割前转成托管或赔偿上限",
},
ipChannel: {
chapter: 6,
section: "6.3 技术与知识产权尽调",
reason: "IP 归属、授权链与渠道集中度,决定资产能否干净地交割",
},
continuity: {
chapter: 8,
section: "8.2 客户、合同与账号迁移",
reason: "云、支付与平台账号的迁移能力,决定交割后收入能不能连续",
},
};
function isGroupKey(value: string): value is RiskGroupKey {
return (GROUP_ORDER as string[]).includes(value);
}
/**
* Scores the six fixed groups. All six must be present and each must use its
* appendix C weight; a missing group or a reweighted group is a broken
* review, not a zero score. Grades use the same 70% and 55% lines as volume
* one so the two volumes can be compared without rescaling.
*/
export function reviewRiskVolume(
groups: RiskReviewGroup[],
): Result<RiskReviewResult> {
if (groups.length !== GROUP_ORDER.length) {
return fail(`expected ${GROUP_ORDER.length} groups, got ${groups.length}`);
}
const seen = new Set<RiskGroupKey>();
let totalScore = 0;
let maxScore = 0;
let weakestKey: RiskGroupKey = GROUP_ORDER[0];
let weakestBps: Bps = 10001;
for (const group of groups) {
if (!isGroupKey(group.key)) {
return fail(`unknown group ${group.key}`);
}
if (seen.has(group.key)) {
return fail(`duplicate group ${group.key}`);
}
seen.add(group.key);
if (group.maxScore !== GROUP_MAX[group.key]) {
return fail(`group ${group.key} must use weight ${GROUP_MAX[group.key]}`);
}
if (
!Number.isInteger(group.score) ||
group.score < 0 ||
group.score > group.maxScore
) {
return fail(`group ${group.key} score must be between 0 and its max`);
}
totalScore += group.score;
maxScore += group.maxScore;
const groupBps = divide(group.score, group.maxScore);
// Ties go to the later group: continuity is appendix C's cross-check
// group, so a tie with IP and channel should still surface as continuity.
if (groupBps <= weakestBps) {
weakestKey = group.key;
weakestBps = groupBps;
}
}
for (const key of GROUP_ORDER) {
if (!seen.has(key)) {
return fail(`missing group ${key}`);
}
}
const scoreBps = divide(totalScore, maxScore);
const grade: RiskReviewResult["grade"] =
scoreBps >= 7000 ? "healthy" : scoreBps >= 5500 ? "watch" : "high-risk";
return ok({
totalScore,
maxScore,
scoreBps,
grade,
weakestKey,
weakestBps,
focus: FOCUS[weakestKey],
});
}
/** Returns the volume-three routing target for a single group. */
export function volumeThreeFocus(key: RiskGroupKey): VolumeThreeFocus | null {
return FOCUS[key] ?? null;
}
把三案例代进去,结果是 LedgerLite 78 分、健康、最弱依赖与连续性、路由到卷三第 8 章;Tidecast 62 分、需关注、最弱依赖与连续性、路由到第 8 章;Nord 50 分、高风险、最弱 IP 与渠道、路由到第 6 章。代码给出的 weakestBps 分别是 7,857、3,571、4,286,和正文的百分比一致。
代码不判断分数是否「够好」,也不判断卷三的章节是否真的适合你的生意。它只保证三件事:六组必须齐全、权重必须固定、最弱组必须有路由。剩下的判断留给读者,因为评分是工具,不是结论。
进入卷三前的三个动作
第一个动作:把 13.1 的矩阵升级成「可转让版本」。原矩阵的八列回答「条款值多少钱」,升级版要再加四列:控制权变更是否触发终止、合同转让是否需要对方同意、终止后卖方是否提供过渡支持、依赖账号能否迁移。四列都是「是/否/不清楚」,不清楚按否处理。LedgerLite 的 260 份订阅合同里,如果有一份写了控制权变更条款,买方就会要求逐份确认;Tidecast 的 Steam 账号与商店页能不能转,直接决定 8.2 的交割清单;Nord 的咨询合同大多按项目签,转让相对容易,但客户关系跟人走。这个动作的成本是几个小时,收益是尽调时少一轮追问。
第二个动作:把 13.2 的敞口表做成季度基线。一张表只需要五列:应收余额、逾期比例、坏账准备、风险期望损失、未覆盖缺口;再加两个比率:缺口 ÷ SDE、保额 ÷ 单次最大损失。每季度用同一个口径填一次,连续四个季度后,趋势比单点数字更有信息。LedgerLite 的缺口从 $13,337 涨到 $20,000,可能是保额没跟上收入,也可能是免赔额变了;Tidecast 的缺口从 $232,430 降到 $150,000,可能是 Steam 占比降了,也可能是授权保底重谈了。没有基线,这两种变化都看不出来。
第三个动作:用附录 C 打一次分,把最弱的一组写成一页「卷三入场任务」。一页纸四行:最弱的组、对应卷三章节、需要补的证据、负责人和截止日。不要一次修六组;先修最弱的一组,再修与它联动的那一组。Nord 的最弱组是 IP 与渠道 6/14,联动的是应收与坏账 7/14;两组一起修,才能把「客户关系是公司的还是合伙人的」这个问题回答清楚。LedgerLite 和 Tidecast 的最弱组都是依赖与连续性,联动的是合同结构里的转让条款;账号迁移和合同转让要一起谈。
三个动作做完,卷三的第一节不会从估值倍数开始,而会从「你的生意能不能被交割」开始。估值是结果,交割能力是前提。
三个交接问题
从卷二进入卷三,有三个问题必须先回答。它们不属于合同正文,但决定了卷三哪些章节对你最重要。
第一,融资结构:你需要外部资本吗? 如果需要,稀释多少、治理权让多少、投资人信息权到哪一步?LedgerLite 的 3.2× ARR = $768,768 是收购锚,不是融资锚;它现在的现金流不需要外部资本,融资只会增加退出时的清算优先权。Tidecast 和 Nord 的现金流更薄,但融资的代价也更高:一个依赖平台,一个依赖合伙人,投资人会要求更强的保护条款。卷三第 1 章会把自力更生、借款、股权融资三条路的代价算清楚。
第二,退出路径:这门生意卖给谁? LedgerLite 走战略买方,价格 3.2× ARR = $768,768,结构是现金 70%($538,138)+ earn-out 30%($230,630,12 个月,ARR ≥95% 全额),另有 10% 托管 $76,877。Tidecast 有两条路:IP 授权 3 年,保底 $60,000/年 + 8% 净收入,最低保证 $180,000;或者整体出售 1.8× 收入 = $248,708。Nord 也有两条:一位合伙人退出,买断 50% × 4.5 × SDE = $77,220,分 24 个月;或者整体被并购,3.0× SDE = $102,960。路径不同,卷二哪些条款最重要也不同:A 看账号迁移与托管,B 看平台账号与不得转授权,C 看 IP 归属与客户关系。
第三,交割条件:买方会在交割前要求什么? 哪些合同需要对方同意才能转让?控制权变更会不会触发终止?托管和 earn-out 怎么设?LedgerLite 的营运资金调整已经出现:目标 $15,000、实际 $12,000,下调 $3,000;Tidecast 的音乐授权不得转授权,Steam 账号与商店页要逐项确认;Nord 的合伙人买断分 24 个月,交割前必须先把这份协议写成书面文件,并把交付物归属列成清单。三个问题的答案,会直接变成卷三第 6 章尽调、第 7 章结构、第 8 章交割的检查项。
三个问题没有标准答案,但每个答案都能回到卷二的一张表:融资结构回到现金流与缺口,退出路径回到估值锚与合同终止条款,交割条件回到矩阵的可转让列与依赖账号清单。把这三张表放在手边,卷三就不是一本新书,而是卷二的自然延续。
小结
- 卷二用附录 C 的六组清单收口:合同结构 20 分、关键条款 16 分、应收与坏账 14 分、争议与保险 14 分、IP 与渠道 14 分、依赖与连续性 14 分,合计 92 分。
- 三案例得分:LedgerLite 78(84.8%,健康)、Tidecast 62(67.4%,需关注)、Nord Studio 50(54.3%,高风险)。
- LedgerLite 的最弱组是依赖与连续性(11/14),云与支付账号迁移会进入卷三第 8 章 8.2 的交割条件。
- Tidecast 的最弱组也是依赖与连续性(5/14),Steam 账号、商店页与结算关系决定收入能否延续。
- Nord 的最弱组是 IP 与渠道(6/14),其次是应收与坏账(7/14);分别进入卷三 6.3 与 6.1。
- 进入卷三前的三个动作:矩阵加可转让四列、敞口做成季度基线、用附录 C 打分并写一页入场任务。
- 三个交接问题:融资结构、退出路径、交割条件;每个答案都能回到卷二的一张表。
- 分数不是估值;它只衡量合同与风险能不能被第三方复核,估值还看增长、市场与买方战略。
阅读导航:上一节:13.2 应收与风险敞口 · 下一节:目录与学习路径 。
常见错误与边界
- 把分数当估值。 78 分不代表能按 3.2× ARR 成交;评分衡量可复核性,估值还看增长、市场与买方战略。
- 只修高分项。 高分项再修也加不了几分,最弱组才是折价来源;LedgerLite 的依赖与连续性只丢 3 分,但账号迁移会卡交割。
- 缺一组按零分算。 缺组是评审不完整,不是这一组没有风险;代码直接报错,正文也不给补零。
- 按绝对失分选最弱组。 满分不同,失分不可直接比;合同结构满分 20,依赖与连续性满分 14,要用得分率。
- 把「不适用」当满分。 Tidecast 没有保险,不代表争议与保险组满分;没有替代证据就给 0 或 1。
- 三个动作同时做。 矩阵、敞口、评分一起动,流程会乱;先做敞口基线,再做矩阵升级,最后评分。
- 把最弱组当成「要修的组」。 最弱组是「会被定价的组」;修它在卷二,定价它在卷三,两个动作不能混。
- 忽略交接问题的顺序。 先答融资结构,再答退出路径,最后答交割条件;顺序反了,会把融资当成退出的替代。
- 把卷三当成独立的一本书。 卷三的估值、尽调、结构、交割都建立在卷二的三张表上;表不在,章节就只是概念。
- 分数不动就以为没问题。 分数不动但结构在恶化——缺口占 SDE 上升、最弱组换人——同样要处理。
本节的边界是「卷二评审与卷三交接」:只覆盖附录 C 的六组评分、最弱组路由、三个动作和三个交接问题,不展开卷三的估值方法、交易结构与交割清单。所有分数和阈值都是教学示例;正式交易中的评审与尽调应由专业人员完成。合同条款的财务后果见 13.1 合同条款矩阵 ,应收与缺口的横向对照见 13.2 应收与风险敞口 ,保险与缺口的联动见 12.3 保险、备份与应急预案的联动 。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。