@gitruck/cli 1.1.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -22,7 +22,7 @@ description: 通用解说视频创作图纸(解说链正本)——把「一
22
22
 
23
23
  **素材来源边界**:解说的主体画面**只用本地素材**——素材就是被讲的对象本身,平台素材库在主体画面上是范畴错误;平台库最多补空镜/概念镜头作辅料,**缺省不掺、问了才加**。
24
24
 
25
- ## 二、输入契约与开工六问
25
+ ## 二、输入契约与开工七问
26
26
 
27
27
  **输入**:本地素材语料(素材夹,或单条长片——影视/游戏实况先建索引拆条)±稿件 ± 用户自己念的口播毛片。**MUST NOT 执行任何网络下载**(版权责任归用户)。
28
28
 
@@ -34,8 +34,27 @@ description: 通用解说视频创作图纸(解说链正本)——把「一
34
34
  | ④ | 声音基座 | **问用户**:TTS 配音(挑音色附试听)/ 你自己念(给口播毛片) | §五 基座路由:TTS 走配音工程;口播毛片先走 `gtrk oralcut` 粗剪(外录先 `gtrk audio align` 对轨) |
35
35
  | ⑤ | 要不要引用段 | **问用户**,按题材给建议:影视/游戏强建议开,旅拍/探店可选 | §四;答不要 = 全程零引用动作 |
36
36
  | ⑥ | 画幅 | 按投放平台问;素材几何 ffprobe 取证 | 画布;横屏素材硬做竖屏有黑边/裁切,丑话先说 |
37
+ | ⑦ | **源片语种 / 方言** | **问用户**:听一段 / 看片内有无内嵌字幕 / 看素材出处 | `gtrk transcript --lang`(`zh-CN` 普通话 / **`zh-HK` 粤语** / `en-US` / `ja-JP`…);素材通篇无对白答「无对白 / 不转写」即闭合,MUST NOT 因缺这个答案阻塞开工 |
37
38
 
38
- > ②③④⑤ MUST 问用户、MUST NOT 代猜;一张表一次问完,不碎问。
39
+ > ②③④⑤⑦ MUST 问用户、MUST NOT 代猜;一张表一次问完,不碎问。
40
+ >
41
+ > ⟲ **2026-09-02 六问补为七问(新增 ⑦ 语种)**:260902 真机一条**粤语对白**的片子按缺省 `zh-CN`
42
+ > 静默转写跑完,整条链上无一处问过语种。⑦ MUST 早于 ① 的转写发起:转写是计费动作且在检查点①**之前**,
43
+ > **非中文素材**(`en-US` / `ja-JP`…)语种传错,用户在检查点①拿到的稿子就是坏的、重来要再付一次 ASR
44
+ > (真机 `--lang en-US` 出英文稿即实证);且豆包 14 项白名单外的语种码在 `word_level=true` 下会裸
45
+ > `KeyError` 炸任务。**MUST NOT 以缺省 `zh-CN` 静默开跑**,检查点①对语种只做过目复核。
46
+ >
47
+ > ⟲ **2026-09-02 同日订正(这一问的原粤语论证段已被求证推翻,问本身照旧成立)**:原文写
48
+ > 「`zh-CN` 与 `zh-HK` 在后端是两个不同的识别语种(Whisper `zh` vs `yue`)」——**该因果论断错**。
49
+ > `gtrk transcript` 写死 `word_level: true`(`src/commands/transcript.ts:178`)⇒ 链路钉在豆包、
50
+ > 到不了 Whisper(infra `utils/process/media/audio/asr.py:44-49` 在 `AsrFunc.Whisper` 分支里
51
+ > 仍把 `word_level_handler` 钉成豆包);而豆包字典里 `zh-CN` 与 `zh-HK` **都映射空串**
52
+ > (`utils/partner/volcengine/doubao_llm_asr.py:36-37`)⇒ 两种写法发出的请求**逐字段相同**。
53
+ > 粤语能识别对,靠的是豆包空串模式自己的方言自适应,与这个参数无关;`zh-HK→yue` 那条映射真实存在
54
+ > (`utils/partner/openai/__init__.py:18`)但只在 `word_level=false` 走 Whisper 时生效,CLI 今天走不到。
55
+ > ⇒ 粤语 **SHOULD** 如实填 `zh-HK`(元数据诚实 + 备将来链路切换),但 **MUST NOT 以「粤语语种传错」
56
+ > 为由重跑转写**:`la` 进 ASR 缓存键(`asr_result_cache.py:71-75`),换码必然 cache miss,
57
+ > 白扣一次时长换回同一份结果。
39
58
 
40
59
  ## 三、时序铺排三档(本图纸的技术正本)
41
60
 
@@ -177,6 +196,7 @@ QC 反算重铺);② 段带 `cuts`,端点残片收缩生效;③ 段带 `
177
196
  - **引用点在写稿时定**:稿件里显式留引用窗口(出处 = 甲档对照表里的区间),MUST NOT 铺轨时临时起意。
178
197
  - **切取用流拷贝**(`ffmpeg -c copy`,零重编码);想让 AI 帮你海选可引用的高光,可先跑一遍 `gtrk long2short` 拿选段清单当候选(可选辅助,明示计费)。
179
198
  - **装配**:逐段 TTS + 引用段原声按稿序拼成总音频 → 合成 transcript(各段句级时码换算到拼接轴)→ `gtrk project init --audio <总音频> --transcript <合成转写>` 建工程(自备配音兜底路);引用段画面 = 该源区间直排上轨。无引用段时装配退化为单条 TTS + `--tts-task` 主路(与旅拍同款)。
199
+ **产物文件名别硬拼(fix-tool-outdir-collision)**:多段 TTS 落**同一个 `--out`** 时,第二段起的产物会带 taskId 后 6 位后缀(`tts-narrator-a1b2c3.wav`),基名只有第一份是干净的。拼接清单 MUST 按每次回执的 `files` 取路径,MUST NOT 按 `tts-<speaker>.wav` 猜——猜出来的名字会一路指向第一段,拼出来的总音频会把某一段重复多遍而不报错。
180
200
  **主轨无缝铁则(260828 主理人挑刺定案)**:合成 transcript 里引用段 utterance 的 st/ed **MUST 写物理拼接位**(拼接轴上的真实起止),MUST NOT 加 ±0.1s 字幕 pad——dispatch 的 beat 轨窗派生自转写时刻,pad 会在主轨上留 0.1s 缝(三片实测各 4 处)。已有 pad 的存量工程修法:改转写引用句时刻→重导视图→重落拆分(hash 只随文本不失效)→重铺(plan 引用窗随之外扩,Δ=0 不破)→字幕重出。
181
201
  - **克制丑话**:引用段是佐料——时长占比失衡会让片子变成搬运,平台判定风险归用户(§八 一并告知)。
182
202
 
@@ -186,10 +206,18 @@ QC 反算重铺);② 段带 `cuts`,端点残片收缩生效;③ 段带 `
186
206
  # ① 索引前置(第一步就起,不是可选项——它是质量信号的载体,见 §三 代价表)
187
207
  # 4K 长片索引慢,未提速期**与写稿/TTS/检查点①并行跑**,别串行干等
188
208
  gtrk matrix index --dirs "<这一部片的绝对路径>" & # 后台起,写稿同时跑(索引侧同口径:也钉单片)
189
- gtrk transcript "<长片>" --json # 影视/游戏类:台词与时码双锚(可选)
209
+ gtrk transcript "<长片>" --lang <开工⑦所答语种> --json # 影视/游戏类:台词与时码双锚(可选)
210
+ # ↑ 语种取开工⑦所答,MUST NOT 拿缺省顶上去 —— 但「传错就白花钱」只在**非中文**这一档成立;
211
+ # 粤语 SHOULD 如实填 zh-HK(元数据诚实 + 备链路切换),当前链路下对粤语无差别:
212
+ # CLI 写死 word_level: true ⇒ 钉在豆包,豆包字典里 zh-CN 与 zh-HK 都映射空串 ⇒ 请求逐字段相同。
213
+ # MUST NOT 以「粤语传错」为由重跑(la 进 ASR 缓存键,换码必 cache miss、白扣一次时长)。详见 §二 ⑦ 注
190
214
 
191
215
  # ②③ 写稿(甲档出处共生 / 乙路对照表对齐)→ 检查点①拍板(§六)
192
- gtrk matrix material "<情绪 题材 检索词>" --scope audio --top-k 5 --json # BGM 候选附试听
216
+ gtrk matrix material "<情绪 题材 检索词>" --scope audio --top-k 5 --commercial-only --json # BGM 候选附试听
217
+ # ⚠️ 版权判断不在零件手里,在你手里:零件缺省 copyright_scope=all(**不筛**)。
218
+ # is_copyright 的权威语义是 1/true=可商用、0/false=**不可商用**——反直觉,MUST NOT 把 false
219
+ # 读成「无版权、可随便用」。带 --commercial-only 就把不可商用的挡在候选之外;不带就 MUST
220
+ # 逐条按 copyright_label(派生位,中文标签)自己判,别默认候选都能用。
193
221
 
194
222
  # ④ 声音基座(按开工④路由)
195
223
  gtrk tool audio_tts_clone --text-file <稿段.txt> --speaker <voice_id> --json # TTS 路
@@ -271,7 +299,7 @@ gtrk subtitle lay --project "<工程>" --style <样式> --color <色> --json
271
299
 
272
300
  | 模式 | 停点 |
273
301
  |---|---|
274
- | **快速成片**(默认) | 开工六问 → 检查点①(必停一次)→ 一杆到底 |
302
+ | **快速成片**(默认) | 开工七问 → 检查点①(必停一次)→ 一杆到底 |
275
303
  | **逐步推进** | 每步停等确认(索引结论 / 稿件 / 对照表 / 铺排结果 / 字卡 / BGM / 字幕逐项) |
276
304
 
277
305
  差别只在停几次;三条腿自检见《成片型图纸公约》§四。
@@ -81,6 +81,7 @@ gtrk split --project "<oralcut产物目录>" --json
81
81
 
82
82
  关键:
83
83
  - `lane` 四选一 `A_ROLL | MG | AI_DRAMA | FILM_BROLL`;`base_track` 三选一 `真人出镜 | 口播继续 | 旁白主导`。
84
+ - `irreplaceability` 四选一 `必须真人出镜 | 优先 MG | 可被 B-roll 替代 | 可降级处理`。
84
85
  - **handoff 按 lane 分型**(校验器会硬查):
85
86
  - `MG` → `handoff:{slug_hint?, theme?, bg?, duration_hint}`,**`duration_hint`(秒)必填**;可选 `category`(overlay 透明叠加/fullscreen 不透明满屏,裁决⑩,供色带分层,详见 field-schema)。
86
87
  - `FILM_BROLL` → `handoff:{queries:[...非空], shots?, per_shot_sec?, exclude?, anchors?}`,**`queries` 非空必填**;queries 写**英文长句场景描述**(一条一个意象,避多义动词),**exclude 保持中文**;`anchors` 为关键词锚(圈定指引见下节,细则见 field-schema)。
@@ -89,7 +90,7 @@ gtrk split --project "<oralcut产物目录>" --json
89
90
 
90
91
  ### 关键词锚(FILM_BROLL 的 `handoff.anchors`,选配但强烈建议)
91
92
 
92
- **为什么**:beat 级 queries 只保证「这段有对的画面」,不保证「说到关键词的那一刻画面正好对上」——听到「野牛高速」的瞬间看到野牛,是解说视频的看点兑现契约。铺轨会把锚 query 的最高分命中**钉在关键词说出时刻**(句级时码字符比例内插 − 0.5s 提前量),其余槽位在锚点两侧照常序贯填充。
93
+ **为什么**:beat 级 queries 只保证「这段有对的画面」,不保证「说到关键词的那一刻画面正好对上」——听到「野牛高速」的瞬间看到野牛,是解说视频的看点兑现契约。铺轨会把锚 query 的**原始 sim 最高的合格命中**(原始检索相似度,**不是** mark/highlight 融合分)**钉在关键词说出时刻**(句级时码字符比例内插 − 0.5s 提前量),其余槽位在锚点两侧照常序贯填充。**锚预留优先于普通序贯槽消费**:铺轨前先为每锚锁住它的 sim 第一名,前序 beat 的泛化槽抢不走(锚落位或降级后立即释放)。真取不到第一名时**不静默**——锚 outcome 会如实报名次与去向(落的是第几名、第一名被谁取走)。
93
94
 
94
95
  ```jsonc
95
96
  "handoff": {
@@ -104,7 +105,7 @@ gtrk split --project "<oralcut产物目录>" --json
104
105
  - **圈「贵大奇多」类看点实词**——地名/地标(黄石湖、老忠实)、奇观名物(野牛高速、间歇泉)、数字头衔(全球第一、三万美元):观众听到会期待「给我看」的词。**虚词/泛词勿圈**(「非常」「其实」「这个地方」锚不出画面)。
105
106
  - **每 beat 至多 2 个**(校验硬拒超额)——锚过密会把序贯填充区间切碎,节奏反而乱。没有值得钉的词就不写 anchors,宁缺毋滥。
106
107
  - `keyword` **照原句抄写**(须为该句 text 的子串,勿改写勿增删标点);`utterance` 是关键词所在句 id(须落在该 beat 的 span 内)——两者校验器都硬查。
107
- - `query` 写**该关键词的视觉描述**(同 queries 语言规范:英文长句场景描述)——它与 queries 同链检索,锚点钉的是它的最高分命中;写抽象词等于锚一张糊画面。
108
+ - `query` 写**该关键词的视觉描述**(同 queries 语言规范:英文长句场景描述)——它与 queries 同链检索,锚点钉的是它**原始 sim 最高的合格命中**(不是融合分最高);写抽象词等于锚一张糊画面。
108
109
  - 锚 query 无合格命中时铺轨自动降级普通槽并在 summary 明示(不硬锚烂画面)——你无需为素材库兜底,只管圈对词。
109
110
 
110
111
  ### 4. 落地校验
@@ -69,7 +69,10 @@
69
69
  // - **exclude 保持中文**:负向过滤匹配的是服务端返回的中文 note,写英文会失效
70
70
  // anchors(可选,关键词锚 · add-keyword-anchored-broll):[{ keyword, utterance, query }] ≤2 个/beat——
71
71
  // - keyword 照原句抄写(须为所在句 text 子串);utterance 为该句 id(须在本 beat span 内);query 写该词的英文视觉描述
72
- // - 语义:铺轨把锚 query 最高分命中钉在关键词说出时刻(句级时码内插 −0.5s 提前量);无合格命中自动降级普通槽
72
+ // - 语义:铺轨把锚 query **原始 sim 最高的合格命中**(原始检索相似度,不是 mark/highlight 融合分)
73
+ // 钉在关键词说出时刻(句级时码内插 −0.5s 提前量);无合格命中自动降级普通槽
74
+ // - 锚预留**优先于**普通序贯槽消费(铺轨前先为每锚锁住 sim 第一名,落位或降级后立即释放);
75
+ // 取不到第一名时锚 outcome 如实报名次与去向(第几名 / 第一名被谁取走),不静默当成钉准
73
76
  // - 圈「贵大奇多」类看点实词(地名/奇观/数字头衔),虚词泛词勿圈;圈定指引见 SKILL.md「关键词锚」节
74
77
 
75
78
  // lane === "AI_DRAMA" —— 全可选(下游框架 skill /gtrk-ai-drama 有推断默认)
@@ -94,7 +94,7 @@ description: gtrk 单点工具与媒体转换能力的调用向导,覆盖 `gtr
94
94
  3. **一律带 `--json`**:`gtrk tool <name> <输入> --json`。stdout 只会有一行结果 JSON(`{ ok, outDir, files, taskId, fileId, … }`),人读日志在 stderr。按 `ok` 判成败、从 `files` 拿产物路径、把 `outDir` 回给用户。
95
95
  4. **缺 API Key 先引导配置**:cloud 型工具没配 Key 会报错让先跑 `gtrk init`。遇到就引导用户 `gtrk init`(或设 `GITRUCK_API_KEY`),别反复重试。
96
96
  5. **瞬时网络错误退避后只重试 1 次**:若 `gtrk tool list --json` 或工具命令因 `fetch failed`、`ECONNRESET`、`ETIMEDOUT`、`ENOTFOUND`、`socket hang up`、网络不可达或 HTTP `502/503/504` 失败,先等 **2 秒**,再原样执行同一命令 **1 次且仅 1 次**(总尝试次数最多 2 次)。第二次仍失败就停止,如实说明网络波动并给出最后错误,绝不循环重试。参数/文件校验错误、缺 Key、HTTP 4xx、云端业务错误码、明确的任务失败/取消均**不重试**。重试前先检查日志及输出目录:一旦已出现 `taskId` 或 `task.json`,说明任务可能已经提交,禁止重跑整条以免重复计费,转入下一条恢复语义。
97
- 6. **产物落地与恢复**:产物落在 `outDir`(缺省 = 输入同目录下 `<输入名>-<工具名>/`,可 `--out <dir>` 覆盖)。提交成功即写 `task.json`(含 `taskId`)、完成即写 `result.json`。**分析型工具**(`video_segment` / `video_ai_segment` / `video_motion_cut`)产的是**结构化数据不是下载文件**:结果落 `result-output.json`(分镜/运镜结构),`result.json` 的 `resultFile` 字段指向它、`files` 为空且 `ok=true` 属正常,别当成「没出产物」。**若 `ok=false`**(任务完成但产物下载失败,如链接过期;或既无文件也无结构):`result.json` 的 `errors` 有明细、`task.json` 保留——凭其中的 `taskId` 可稍后人工恢复取回,别急着重跑整条(重跑会重新计费)。
97
+ 6. **产物落地与恢复**:产物落在 `outDir`(缺省 = 输入同目录下 `<输入名>-<工具名>/`,可 `--out <dir>` 覆盖)。**无输入文件的工具**(`input=none`,如纯文本转语音)缺省落**当前目录**下 `<工具名>-<时间戳>/`。该名撞上已有目录时自动带 `-2`/`-3` 序号后缀;同一目录内产物文件撞名时带 taskId 后 6 位后缀。**一律以回执的 `outDir` / `files` 为准,别按名字硬拼**——猜出来的路径会指向上一次那份产物。提交成功即写 `task.json`(含 `taskId`)、完成即写 `result.json`。**分析型工具**(`video_segment` / `video_ai_segment` / `video_motion_cut`)产的是**结构化数据不是下载文件**:结果落 `result-output.json`(分镜/运镜结构),`result.json` 的 `resultFile` 字段指向它、`files` 为空且 `ok=true` 属正常,别当成「没出产物」。**若 `ok=false`**(任务完成但产物下载失败,如链接过期;或既无文件也无结构):`result.json` 的 `errors` 有明细、`task.json` 保留——凭其中的 `taskId` 可稍后人工恢复取回,别急着重跑整条(重跑会重新计费)。
98
98
  7. **透传高级参数**:命令没为某个云端参数开 flag 时,用 `--param k=v`(可重复)或 `--params-json '<对象>'` 直接透传(如 `image_move` 想指定输出几何 `--param width=1080 --param height=1920`)。
99
99
  8. **单发单收、批量靠循环**:一次一份输入;用户要批处理就你逐个循环调。例外是多文件图片工具(`image_classic_template` / `image_vertical_stitch`)——它们的一份输入天然是一组图片(一次任务一次计费),传参顺序即拼装顺序,别把它当批处理。
100
100
 
@@ -23,30 +23,68 @@ description: 旅拍解说一站式成片图纸——输入一个旅拍素材文
23
23
  | BGM 音频文件 | 可选 | 没有就走素材矩阵搜索(见检查点①) |
24
24
  | 介绍类文本(txt/md) | 可选 | 有则作写稿补充素材 |
25
25
 
26
- **MUST NOT 执行任何网络下载**:网络视频二创场景下,下载动作归用户(版权责任边界)——用户给的文件夹里是什么就用什么。
26
+ **一夹多片时检索域按场景分流(★ 2026-09-02 补)**:二创场景一个夹里常躺着好几条互不相干的片,
27
+ **B-roll 检索域 MUST 收窄到正在做的那一部片本身**——`--dirs` 既吃文件夹也吃**单个素材文件**,传文件即把域收窄到该素材(见 §五 ⑦ 的★铁则)。
28
+ 原创(自拍素材集)那一档整夹就是这一片的素材域,**传夹正确**。
29
+
30
+ **MUST NOT 下载二创源片 / 主体素材**:网络视频二创场景下,下载动作归用户(版权责任边界)——用户给的文件夹里是什么就用什么。**射程只到源片与构成成片主体画面的素材**:平台授权素材(同和素材矩阵的 BGM / 空镜)的**签名直链不在此列**(⟲ 2026-09-02 收窄:原措辞写「任何网络下载」,严于本 skill 自己的规格,且让 §四.4 那步 BGM 落地在字面上不合法;家族口径见 `gtrk-narration` / `gtrk-food-recap`——那两份长期同时挂着同款禁令与「`song` MUST 下载 `accompaniment_url` 伴奏版」,并存即证禁令从来只指源片)。收窄 MUST NOT 被读作给源片下载开口子——那条版权边界一字不动。
27
31
 
28
32
  **双场景识别**(决定理解编排走法):
29
33
  - **二创**:文件夹里是网络旅行长视频(通常含博主解说语音)→ 原片文案是写稿主料;
30
34
  - **原创**:用户自己拍的素材集(通常无解说语音)→ 素材理解(describe)是写稿主料。
31
35
  - 拿不准就 ffprobe 看时长与条数:单条 10 分钟以上大概率二创;几十条短素材大概率原创。仍拿不准,问用户一句。
36
+ - 原创场景的素材集常常**通篇没有对白**——那就不跑转写,下表的语种一问以「无对白 / 不转写」闭合,MUST NOT 因缺这个答案阻塞开工。
32
37
 
33
- **稿源与声音基座两问**(⟲ 2026-08-27 解说链家族回炉,开工时与双场景识别一并问清、MUST NOT 代猜):
38
+ **开工三问:稿源 · 声音基座 · 源片语种**(⟲ 2026-08-27 解说链家族回炉先立稿源与声音基座;⟲ 2026-09-02 补语种这一问——260902 真机一条**粤语对白**的片子按缺省 `zh-CN` 静默转写跑完,全链无一处问过语种。三问开工时与双场景识别**一并问清、一张表一次问完、MUST NOT 代猜**):
34
39
 
35
40
  | 问 | 选项与走法 |
36
41
  |---|---|
37
42
  | 稿从哪来 | **AI 代写**(缺省,§三 规约写)/ **用户自备稿**——跳过写稿,稿直接进检查点①过目(文风铁律不强加于用户手稿,只提示明显硬伤) |
38
43
  | 声音怎么来 | **TTS 配音**(缺省,检查点①挑音色)/ **用户自己念**——拿念稿毛片先走 `gtrk oralcut` 粗剪(带稿最准;外录收音先 `gtrk audio align` 对轨),产出的粗剪工程即时间基座,§五 的「配音④→建工程⑤」两步跳过,从拆分⑥接入,后续铺排/字卡/BGM/字幕照旧 |
44
+ | **源片语种 / 方言** | 取证=**听一段 / 看片内有无内嵌字幕 / 看素材出处**;答案定 §五 ① 的 `gtrk transcript --lang`(`zh-CN` 普通话 / **`zh-HK` 粤语** / `en-US` / `ja-JP`…)。**MUST 问用户、MUST NOT 代猜、MUST NOT 以缺省 `zh-CN` 静默开跑转写**——转写是计费动作**且早于检查点①**:**非中文素材**(`en-US` / `ja-JP`…)语种传错,用户在检查点①拿到的稿子就是坏的、重来要再付一次 ASR(真机实证)。**中文这一档(`zh-CN` ↔ `zh-HK`)不在此列**:粤语 **SHOULD** 如实填 `zh-HK`(元数据诚实 + 备将来链路切换),但当前实现下该参数**对粤语无影响**——两种写法发出的请求逐字段相同,详见 §五 ① 注。素材无对白:答「无对白 / 不转写」即闭合 |
45
+
46
+ ## 一′、素材适配闸(写稿前必过 · ★ 2026-09-02 真机事故立)
47
+
48
+ > **事故形态**:三条素材里有一条是**有剧情、有台词、有摆拍的学生短片**,本图纸从头到尾跑完(含 TTS 计费步骤)、**零提示**。
49
+ > 根因不是漏写一句,是**唯一的路由条款判的是「时序」而不是「题材」**——§一 的家族归位按「素材有无自带时序」出链,
50
+ > 而剧情短片**自带叙事时序**(剧情线),按解说链判据它不但不出链,**反而正落在射程内**,出链闸永远不会触发。
51
+ > ⇒ **本闸判的是题材,与「有无自带时序」正交,MUST NOT 由后者代行。**
52
+
53
+ **取证零新增计费**(读的都是编排里本来就要产的东西,MUST NOT 为这道闸新加一次 describe 或转写):
54
+
55
+ - **原创场景**:读 `gtrk matrix index` / `gtrk matrix describe` 已产的 `desc`(中文视觉描述)与 `tags`;
56
+ - **二创场景**:读 `gtrk transcript` 全文。
57
+
58
+ **判据(可判定,逐条素材过一遍)**:
59
+
60
+ - 主判据——这一条**能不能回答「这是在哪、看到了什么」**(可辨认的地点 + 所见之物)。能答的占比过低 ⇒ 不适配;
61
+ - 反向命中任一即不适配:文本呈现**剧情对白**(人物一来一往推进情节)/ **摆拍表演**(演出来的而非记录下来的)/ **单一室内场景**(全片不出一个可辨认的地点)。
62
+
63
+ **命中即硬停:MUST NOT 进入写稿**(形制照 `gtrk-vlog-docu` 的立神闸「写不出来 = 神没立住,MUST NOT 进入写稿」)。
64
+ 硬停位置是**写稿之前 = TTS 计费之前**——它与 §四 检查点①「未经确认 MUST NOT 发起计费动作」是同一条防线的**前置一层**:
65
+ 检查点①拦的是「稿子对不对」,本闸拦的是「**这活该不该接**」。停下时 MUST 如实列出**哪几条不适配 + 依据原文**
66
+ (引 `desc` / `tags` / 转写里的原句,别只下结论),并给三条出路:
67
+
68
+ | 出路 | 怎么走 |
69
+ |---|---|
70
+ | ① **剔除** | 把不适配的那几条摘出去,用剩下的素材继续跑本图纸 |
71
+ | ② **改投** | 剧情 / 影视 / 游戏这类有时序但非旅拍的题材走 `gtrk-narration`(解说链正本);素材无自带时序的题材(科普/情感/带货)走 `gtrk-voiceover` |
72
+ | ③ **照跑** | 用户坚持就照办,但 **MUST 在交付说明里如实登记**「素材与旅拍垂类不匹配、要素层(贵大奇多钩子 / 攻略 tips)多半落空」(降档路径如实登记,口径同《成片型图纸公约》) |
73
+
74
+ **两条边界写死**:agent **MUST NOT 自行判死**(决定权在用户,本闸只提名不宣判)、**MUST NOT 静默照跑**——
75
+ 后者正是 260902 那次事故的形态:全链跑完、零提示、钱已经花了。
39
76
 
40
77
  ## 二、全链总览(快速成片)
41
78
 
42
79
  ```
43
80
  ① 理解 transcript 原片(二创)/ matrix index + describe(原创)
81
+ ①′ 适配闸【必过】读 ① 的既有产物判题材(见 §一′)——不是旅拍就硬停,MUST NOT 进入写稿
44
82
  ② 写稿 三段式规约(见 §三)→ 解说稿 + 标题 + HashTag
45
- ③ 检查点① 【必停】稿件确认 · 画幅 · 音色 · BGM(gtrk matrix material --scope audio)· 字幕样式(§四)
83
+ ③ 检查点① 【必停】稿件确认 · 画幅 · 音色 · BGM(gtrk matrix material --scope audio)· 字幕样式 · B-roll 编排量预估(§四)
46
84
  ④ 配音 gtrk tool audio_tts_clone(≤5000 字,句级时码直出)
47
85
  ⑤ 建工程 gtrk project init --tts-task <id> --canvas <WxH>
48
86
  ⑥ 拆分派单 gtrk split 投影 → 你写拆分稿(含字卡 overlay aux)→ split 落地
49
- ⑦ B-roll matrix --local --dirs → describe --plan → lay --mark-weight 0.3
87
+ ⑦ B-roll matrix --local --dirs(二创钉单片)→ describe --plan → lay --mark-weight 0.3 --yes
50
88
  ⑧ 抽帧检查 对字卡挂点抽帧看底轨构图(gtrk-mg SOP)
51
89
  ⑨ MG 字卡 按 §六 轻量规约产颗粒 → mg lint → gtrk mg --project
52
90
  ⑩ BGM gtrk audio lay --volume 0.1 --beat-align(-20dB 口径)
@@ -54,7 +92,8 @@ description: 旅拍解说一站式成片图纸——输入一个旅拍素材文
54
92
  ⑫ 交付 客户端打开工程出片(gtrk render 仅主轨快照预览,见 §八)
55
93
  ```
56
94
 
57
- 检查点①之后一路跑完不再打扰用户——**垂类示例的承诺面就是快速成片一杆到底**(⟲ 2026-08-27 公约分层拍板)。交付后对个别环节不满意走 §七 增量重跑,对垂类玩法本身不满意走 §七 个性化出路。
95
+ 检查点①之后一路跑完不再打扰用户——**垂类示例的承诺面就是快速成片一杆到底**(⟲ 2026-08-27 公约分层拍板)。
96
+ ⚠️ 这条承诺**以 ①′ 适配闸通过为前提**:闸命中时的那次停顿不算「打扰用户」,它是在把钱花出去之前问一句「这活该不该接」。交付后对个别环节不满意走 §七 增量重跑,对垂类玩法本身不满意走 §七 个性化出路。
58
97
 
59
98
  ## 三、三段式写稿规约
60
99
 
@@ -84,8 +123,10 @@ description: 旅拍解说一站式成片图纸——输入一个旅拍素材文
84
123
 
85
124
  **成片时长 = min(内容所支撑, 素材所支撑)**:
86
125
  - 内容支撑:有多少真东西说多少话,素材再多也不注水;
87
- - 素材支撑:按「30% 图片×8 秒 + 70% 视频素材时长」估算上限,稿子在写稿阶段就按上限收敛(不要等铺轨时开天窗);
88
- - 折算口径:约 200-240 字/分钟(TTS 实测,语速快的音色偏 270)。3 分钟成片 ≈ 700-800 字。
126
+ - 素材支撑:按「30% 图片×8 秒 + 70% 视频素材时长」估算上限,稿子在写稿阶段就按上限收敛(不要等铺轨时开天窗);把这个秒数换算成字数用下一条的折算口径(**公式本身不动**);
127
+ - **折算口径 = 挂钟语速**(wall-clock:稿件字数 ÷ 合成音频总时长,**含**句间停顿),**按检查点①选定的那条音色取值**;取不到该音色的语速就用**缺省 ≈330 字/分钟**,并明说这是缺省估值、**不是该音色的实测值**。3 分钟成片 ≈ **1000 字**。
128
+ 缺省 330 的出处(★ 2026-09-02 立,`fix-speech-rate-calibration`):全库 49 条 zh-CN 音色挂钟中位 308.7、`narrator` 349.3(**单点实测,未覆盖全库**)、260902 真机三条片 316–342 —— 逐条档案与标定方法见 `references/speech-rate.md`,**MUST NOT 把那张表贴回本图纸**(单一真值源,垂类只许引用)。
129
+ - ⚠️ **MUST NOT 拿计费折算常量(240 字/分钟)推稿子字数**:那是**计费**用的保守下界(volc 单点实测 260 再下调留余量),与写稿侧的保守方向**正好相反**——计费侧低估语速只是「分钟数变大、不少收」,写稿侧低估语速却会让稿子写短、成片缩水(按 240 写 3 分钟 = 720 字,用 349 的挂钟语速实播只有 2.06 分钟,**缩水 31%**)。计费那一栏见 §九,两个数 MUST NOT 互相冒充。
89
130
 
90
131
  **写后自校验清单**(逐项过,不过重写):
91
132
  - [ ] 三段结构完整、时长在 min 公式内
@@ -126,26 +167,70 @@ description: 旅拍解说一站式成片图纸——输入一个旅拍素材文
126
167
 
127
168
  ## 四、检查点①(双模式共有,必停)
128
169
 
129
- 写完稿**必须停下**,把以下五项一次给用户拍板。**未经确认 MUST NOT 发起 TTS 计费动作**。
170
+ 写完稿**必须停下**,把以下六项一次给用户拍板。**未经确认 MUST NOT 发起 TTS 与 B-roll 云端编排计费动作**。
171
+
172
+ > ⟲ **2026-08-31 订正**(口径抄齐 `gtrk-narration` 正本 §六 与 `gtrk-food-recap` §五,同一条口径只许有一种说法):
173
+ > 本节原以「TTS 是唯一计费闸」立论,已不成立——**本地素材的编排自该日起默认走云端并按「编排量」计费**,
174
+ > `matrix lay` **跑前会再停一次**报预估(那次不是拍板,是花费确认)。
175
+ > **agent 纪律**:MUST 先把预估用量告诉用户、**拿到同意再带 `--yes`**;**MUST NOT 未经同意就带 `--yes`**。
176
+ > 不带 `--yes` 且无 TTY 时本步**整轮铺轨中止**、工程零改动(plan 照常可用、可重跑)——
177
+ > **MUST NOT 把它描述成「回落本机编排」**:那是 2026-08-31 二次拍板前的旧行为,家族里还有过期字面在流传。
178
+ > (260902 真机三条片全部停在第 ⑦ 步,就是「图纸没带 `--yes`、也没地方报预估」这一处漏的形态。)
179
+
180
+ > **语种不在这六项里**(⟲ 2026-09-02):它在 §一 开工三问就已定,检查点①对它最多做**过目复核**。
181
+ > MUST NOT 把语种拖到这一步才问——此时 ① 的 `gtrk transcript` 已经跑完并已计费,稿子也已按错语种写出来了。
130
182
 
131
183
  1. **解说稿 + 标题**:正文全文贴给用户(不是给路径),标题候选列出;
132
184
  2. **画幅**(★ 打样事故教训——横屏素材铺进默认竖屏画布=信箱黑边):问目标平台——横屏 B 站/西瓜=1920x1080,竖屏抖音=1080x1920。**素材几何与画幅不一致时明确提示**(横素材→竖画布会裁切或留边);
133
- 3. **TTS 音色**:拉 catalog(`GET {apiBase}/task/tts/voices`,免鉴权)按内容调性挑 2-4 个候选,**每个附试听链接**(catalog 的 audition_url 字段,api.ai-mcn.tv:9000 静态直链)——用户在对话框里直接点开听。internal 标注的音色注明「仅内部成员」。也可按用户描述语义挑(「要个温柔女声」);
185
+ 3. **TTS 音色**:拉 catalog(`GET {apiBase}/task/tts/voices`,免鉴权)按内容调性挑 2-4 个候选,**每个附试听链接**(catalog 的 audition_url 字段,api.ai-mcn.tv:9000 静态直链)——用户在对话框里直接点开听。internal 标注的音色注明「仅内部成员」。也可按用户描述语义挑(「要个温柔女声」)。
186
+ **每个候选还 SHALL 附上该音色的挂钟语速与据此推的稿件字数区间**(查 `references/speech-rate.md`;档案里没有就明说「用缺省 330 估」)——挑音色的同时也是在挑稿子长度,别让用户回头才发现稿子长了三成。这条是**加项**,MUST NOT 削弱既有的「无试听链接 = 未完成推荐」义务;
134
187
  4. **BGM 处置(双来源)**:
135
188
  - 用户有本地音乐 → 询问是否 `gtrk tool audio_separation` 伴奏分离后取伴奏(缺省建议分离——TTS 配音不与歌曲人声打架);
136
189
  - 用户未提供 → **搜同和素材矩阵**:`gtrk matrix material "<按稿件情绪+地理文化写的检索词>" --scope audio --top-k 5 --diversity --json`
137
190
  (检索词口径见公约 §三′:**内容驱动、禁通用词、至少含一个只有这一片才成立的词**;候选
138
- MUST 给用户挑不许默认 top1;跨片避让由 `audio lay` 记账 + 检索缺省 `--exclude-recent` 自动完成)(按成片时长挑可加 `--min-duration <秒>`)。身份路由(矩阵成员搜全库 / 非成员搜公开库)、版权范围、计费口径全由零件持有,你只管写好检索词并从结果里挑;出参 `results[]` 直接用,`upsell` 是独立顶层字段(非成员且没搜够时才有,原样转述给用户即可,**不要**把它当候选)。
139
- 推荐 3-5 首、**每首附试听链接**(结果的 `download_url`);`audio_type:"pure"` 纯音乐直接用,`"song"` 直接取 `accompaniment_url` 现成伴奏(零处理成本,两档都有);注意曲长 vs 成片时长(`duration` 字段,audio lay 不循环,短曲只垫前段);
191
+ MUST 给用户挑不许默认 top1;跨片避让由 `audio lay` 记账 + 检索缺省 `--exclude-recent` 自动完成)(按成片时长挑可加 `--min-duration <秒>`)。身份路由(矩阵成员搜全库 / 非成员搜公开库)与计费口径由零件持有;**版权判断不在零件手里,在你手里**——零件缺省 `copyright_scope=all`,**不筛**。挑 BGM MUST 按**可商用**口径判:出参 `is_copyright` 的权威语义是 `1/true` = **可商用**、`0/false` = **不可商用**(反直觉:`is_copyright:false` MUST NOT 读成「无版权、可随便用」,它恰恰是不可用的那一档;概念素材固定 `is_copyright=0` 即此意)。派生位 `copyright_label` 直接给了中文标签,照它转述即可。省事路是检索时就带 `--commercial-only`,把不可商用的挡在候选之外;出参 `results[]` 直接用,`upsell` 是独立顶层字段(非成员且没搜够时才有,原样转述给用户即可,**不要**把它当候选)。
192
+ 推荐 3-5 首、**每首附试听链接**(结果的 `download_url`);`audio_type:"pure"` 纯音乐直接用,`"song"` 直接取 `accompaniment_url` 现成伴奏(零处理成本,两档都有);注意曲长 vs 成片时长(`duration` 字段):`audio lay` **缺省循环叠满至工程末尾、尾段裁齐**(多 clip 首尾相接,命令会打 INFO 报段数),短曲只是**接缝多一些**、不会铺一半就静音(想少几道接缝,挑曲时加 `--min-duration <秒>`);要单次铺请显式传 `--no-loop`;
140
193
  - **试听链接义务(MUST)**:音色与 BGM 的推荐没有试听链接=未完成推荐。
194
+ - **BGM 落地一步(MUST,别留悬空 · ⟲ 2026-09-02 补)**:检索出参只给**签名 URL**,而 §五 ⑩ 的 `gtrk audio lay --file` **只收本地路径**(传 URL 必炸)——拍板之后、上轨之前,agent MUST 把选中曲**落成本地文件**。口径照解说链正本 `gtrk-narration` §五 原文对齐:`audio_type:"song"` **MUST 取 `accompaniment_url` 伴奏版上轨**、**MUST NOT 用 `download_url` 原曲**(人声与配音打架,260827 美食批踩坑);`"pure"` 取 `download_url`。文件名按 **`bgm-<曲名>[-伴奏].<扩展名>`** 约定——跨片避让记账按**标题归一化键**匹配(剥 `bgm-` 前缀与 伴奏 / instrumental / off-vocal 后缀),命名不合规会让下一轮 `--exclude-recent` 避让失准。这一步不违反 §一 的下载禁令:那条禁令的射程只到二创源片 / 主体素材,平台授权素材的签名直链不在其内。
141
195
  5. **字幕样式**:7 种样式(default/outline/cinema_yellow/immersive_box/wide_spacing/deep_shadow/boxed)× 11 色(雅黑/淡绿/森林绿/湖蓝/道奇蓝/钢蓝/浅粉红/深橙/珊瑚橙/橙红/土豪金)挑选;**用户没选就用 default+雅黑**(不追问不阻塞)。拍板值在 ⑪ `gtrk subtitle lay` 落地,客户端里仍可整轨换样式(悔棋通道)。
196
+ 6. **B-roll 编排量预估(★ 2026-09-02 补,本地素材路必报)**:本地素材产的 plan 走 `matrix lay` 时**缺省即云端编排、按「编排量」计费**(`--arrange local` 已不受理,逃生舱是关死的)。先拿数再拍板:
197
+
198
+ ```bash
199
+ gtrk matrix lay --project "<工程目录>" --arrange-estimate-only --json # 停在计价确认之前:零云端调用、工程文件零改动
200
+ ```
201
+
202
+ 把它与 TTS / describe 的预估**同屏**报给用户,一次拿到同意——§五 ⑦ 的 lay 才允许带 `--yes`。**报不出这笔就不许开跑**(图纸原来既没这一项、也没那个 flag,于是既报不出、又必断链)。
142
203
 
143
204
  ## 五、快速成片编排(打样验证过的真实命令)
144
205
 
206
+ > **产物落点纪律(MUST · 全文见随包 `AGENT.md` 同名一节)**:
207
+ > 文本产物只落 CLI 返回的路径或**用户显式指定的 `-o, --out`**;`transcript` / `oralcut` / `long2short`
208
+ > 的缺省落点都是**源文件同目录**,这是在案设计、不是 bug(`skills/gtrk-transcript/SKILL.md:21`、
209
+ > `README.md:343`·`:351`、`test/transcript-cmd.test.mjs:63` 三处独立在案)。
210
+ > 但二创的源片通常躺在**用户自己的素材库**里,落进去每跑一条污染一次
211
+ > (260902 真机在 `旅拍素材原片/` 下留了 4 个裸产物)⇒ 本图纸 §五 ① **SHOULD 带 `-o`
212
+ > 把文本产物挪进工程 / 文稿目录**;用户明说就要放源片旁,不传即可——那是缺省,不算违纪。
213
+ > **MUST NOT** 把原片或任何大媒体复制进 agent 自有工作目录(会话工作区 / agent 家目录缓存)——
214
+ > 需要引用媒体时**用原路径引用**,不做副本;临时文件一律放系统 temp 且**用完即删**(含中断 / 失败路径)。
215
+
145
216
  ```bash
146
217
  # ① 理解(二创:转写原片,--json 顺产 transcript.json 备用)
147
- gtrk transcript "<原片>" --lang <原片语言 en-US/zh-CN> --json
218
+ gtrk transcript "<原片>" --lang <zh-CN 普通话 | zh-HK 粤语 | en-US | ja-JP …> --json -o "<工程目录>/transcript/<片名>-transcript.md"
219
+ # ↑ 产物落点:不带 -o 时两个产物都落**源片同目录**(`<名>-transcript.md`;--json 另产 `<名>-transcript.json`,
220
+ # .json 跟随 .md)。缺省本身是在案设计,但二创素材多在用户素材库里 ⇒ SHOULD 用 -o 挪进工程目录(见本节顶部纪律块)
221
+ # ↑ 语种取开工三问的答案,MUST NOT 拿缺省 zh-CN 顶上去 —— **但这条对「非中文」素材才有钱可省**:
222
+ # 粤语 SHOULD 如实填 zh-HK(元数据诚实 + 备将来链路切换),当前链路下它与 zh-CN **对粤语无差别** ——
223
+ # CLI 写死 word_level: true(src/commands/transcript.ts:178)⇒ 链路钉在豆包、到不了 Whisper
224
+ # (infra utils/process/media/audio/asr.py:44-49 在 AsrFunc.Whisper 分支里仍把 word_level_handler 钉成豆包);
225
+ # 而豆包字典里 zh-CN 与 zh-HK **都映射空串**(utils/partner/volcengine/doubao_llm_asr.py:36-37)
226
+ # ⇒ 两种写法发出的请求逐字段相同。粤语能识别对,靠的是豆包空串模式自己的方言自适应,与这个参数无关。
227
+ # "zh-HK": "yue" 那条映射真实存在(utils/partner/openai/__init__.py:18),但只在 word_level=false
228
+ # 走 Whisper 时生效,CLI 今天走不到那条路。
229
+ # ↑ **MUST NOT 以「粤语语种传错」为由重跑转写**:la 进 ASR 缓存键(asr_result_cache.py:71-75),
230
+ # 换码必然 cache miss,白扣一次时长换回逐字段相同的请求与同一份结果。
148
231
  # 原创场景改跑:gtrk matrix index --dirs "<素材夹>" && gtrk matrix describe --materials ...
232
+ # ↑ 原创(自拍素材集)这一档**整夹即该片素材域,传夹正确**,不受 ⑦ 那条「钉单片」铁则约束——
233
+ # 那条治的是二创:一个夹里躺着几条互不相干的片,才会互相抢候选
149
234
 
150
235
  # ②③ 写稿(你执笔,§三规约)→ 检查点①拍板
151
236
  # BGM 候选(用户没自带音乐时,检查点①之前搜好一起拍板;试听链接=结果的 download_url)
@@ -154,6 +239,12 @@ gtrk matrix material "<情绪+地理文化检索词>" --scope audio --top-k 5 --
154
239
  # ④ 配音(音色 code 用 catalog 的 voice_id;稿子存 txt 传 --text-file)
155
240
  gtrk tool audio_tts_clone --text-file <稿.txt> --speaker <voice_id> --json
156
241
 
242
+ # ④′ 语速回校(★ 2026-09-02 新增,零成本自我标定;快速成片照跑不停顿,只汇报)
243
+ # 实测挂钟语速 = 稿件字数 ÷ 音频实际时长(时长取 ffprobe duration;字数口径同服务端:Unicode 码点、含标点与英文数字)
244
+ # 与写稿时所用的估值比对:**偏差 >15% MUST 在交付汇报里点名**(报「估 X / 实测 Y / 偏 Z%」),
245
+ # 并按 references/speech-rate.md 的五项格式追加一条标定档案 —— 每跑一条片攒一条样本,「孤证」从结构上消失。
246
+ # MUST NOT 自动改稿、MUST NOT 自动重跑 TTS:改稿得从 ④ 重跑(TTS 变=全链时码变,⑤起全部重建)、要重付 TTS 费用,返工与否是用户的决定。
247
+
157
248
  # ⑤ 建工程(画幅按检查点①拍板;产物目录含 gtrk/transcript/audio)
158
249
  gtrk project init --tts-task <TTS任务id> --canvas 1920x1080 --no-open --json
159
250
  # ↑ 产的 transcript 文稿缺省去逗号句号(成片字幕口径);要**带标点的文稿版本**
@@ -165,20 +256,42 @@ gtrk split --project "<工程目录>" --json # 投影:拿 utterance i
165
256
  # lane 全 FILM_BROLL、base_track="旁白主导"、narrative 用八枚举、
166
257
  # 字卡挂 aux_layers type:"overlay"(handoff.category:"overlay"+duration_hint,进 dispatch.mg)、
167
258
  # 看点关键词圈 handoff.anchors([{keyword,utterance,query}] ≤2 个/beat——地名/奇观/数字头衔类实词,
168
- # 铺轨把锚 query 最高分命中钉在关键词说出时刻:听到「野牛高速」的瞬间看到野牛;圈定指引见 gtrk-splitter)
259
+ # 铺轨把锚 query **原始 sim 最高的合格命中**(原始检索相似度,不是 mark/highlight 融合分)
260
+ # 钉在关键词说出时刻:听到「野牛高速」的瞬间看到野牛;锚预留优先于普通序贯槽消费,
261
+ # 取不到第一名时锚 outcome 如实报名次与去向;圈定指引见 gtrk-splitter)
262
+ # ⚠️ 上面这串是**非穷举**摘录(另含 irreplaceability / rhythm / visual_task / container_stage 四个必填项):
263
+ # beat 必填字段全表以 gtrk-splitter 的 references/field-schema.md 为准,MUST 照该表写全
169
264
  gtrk split "<拆分稿>" --project "<工程目录>" --json
265
+ # ↑ 落地后走一遍 §六 末的**字卡自检清单**:数 type:"overlay" 的 aux 条数、核对 --json 回执里
266
+ # queues.mg 的条数是否落在「每片 2-4 颗」(这个数以前全链无一处比对,真机两条片各只落 1 颗无人喊)
170
267
 
171
268
  # ⑦ B-roll 三连(describe 给字卡抽帧检查与 mark 加权供料;internal 用户 describe 免费)
172
- gtrk matrix --project "<工程目录>" --local --dirs "<素材夹>" --lay 0 --json
269
+ # ★ 铁则(口径同 gtrk-narration 与 gtrk-matrix,不许长出第二种说法):解说链**一稿对一片**——
270
+ # 二创场景 --dirs MUST 钉到**这一部片的绝对路径**,**不许传素材夹**。--dirs 既吃文件夹也吃单个素材文件,
271
+ # 传文件就是把检索域收窄到该素材。同夹邻片会抢占候选:260828 三片同夹实测 187 个候选里 86 条来自邻片(46.0%),
272
+ # 那不是「排序靠后的次优解」,是**范畴错误**——A 稿的解说配 B 片的画面永远不可能对。
273
+ gtrk matrix index --dirs "<这一部片的绝对路径>" --json
274
+ # ↑ 二创也要先建索引(原来 index 只挂在原创分支下,于是只能顺手对整夹建、正好把三条片灌进同一个 index.db);
275
+ # 若此前已对整夹建过索引则**不必重建**,检索侧传单片即可收窄(判据是路径前缀,传的就是那一条素材本身)
276
+ gtrk matrix --project "<工程目录>" --local --dirs "<这一部片的绝对路径>" --lay 0 --json
173
277
  gtrk matrix describe --plan "<工程目录>/split/broll-plan.json" --yes --json
174
278
  # ↑ describe 结果里的 usable_flags 由你裁定(text_overlay 命中=撞原片字幕区,考虑换段或保留交客户端悔棋)
175
- gtrk matrix lay --project "<工程目录>" --mark-weight 0.3 --highlight-weight 0.2 --gap-fill fast --json
279
+ # ↑ 同时读 describe 输出的**剔除风险**清单:候选数 ≤1 的 beat 一删就掏空
280
+ # (音频驱动 ⇒ 整段黑屏或跨 beat 借片;口播 ⇒ 露 A-roll)。先补素材再剔,MUST NOT 见 flag 就删。
281
+ # ——260902 真机 P3 八个 beat 里七个只有 1 条候选,按 flag 删就是把整段掏空
282
+ gtrk matrix lay --project "<工程目录>" --mark-weight 0.3 --highlight-weight 0.2 --gap-fill fast --yes --json
283
+ # ↑ --yes 的前提是**编排量预估已在检查点①(§四.6)报过并拿到同意**;MUST NOT 未经同意就带。
284
+ # 不带 --yes 且无 TTY 时本步**整轮铺轨中止**、工程零改动(plan 照常可用、可重跑)——
285
+ # 260902 真机三条片全停在这一步,就是「图纸漏了这个 flag、也没地方报预估」的形态
176
286
 
177
287
  # ⑧⑨ 字卡(§六 规约产颗粒 → lint → 铺)
178
288
  gtrk mg lint "<工程目录>/mg/<composition_id>.html" --dispatch "<工程目录>/split/dispatch.json"
179
289
  gtrk mg --project "<工程目录>" --json
180
290
 
181
- # ⑩ BGM(音量口径见下)
291
+ # ⑩ BGM(音量口径见下;<bgm> 是**本地文件**,检查点①拍板后先落地——URL 传给 --file 必炸)
292
+ # BGM 是带人声歌曲(audio_type:"song")→ MUST 下载 accompaniment_url 伴奏版上轨,
293
+ # 不得用 download_url 原曲(人声与配音打架,260827 美食批踩坑);"pure" 取 download_url。
294
+ # 文件名 bgm-<曲名>[-伴奏].<扩展名>:跨片避让按**标题归一化键**记账(剥 bgm- 前缀与伴奏/instrumental/off-vocal 后缀),乱命名=下一轮 --exclude-recent 失准
182
295
  gtrk audio lay --project "<工程目录>" --file "<bgm>" --volume 0.1 --beat-align --json
183
296
 
184
297
  # ⑪ 字幕(样式/颜色 = 检查点①拍板值;用户没选用 default/雅黑;纯本地零计费、重跑幂等替换)
@@ -194,7 +307,7 @@ gtrk subtitle lay --project "<工程目录>" --style default --color 雅黑 --js
194
307
  **MUST NOT 加到语义压不住**(那会变成「专挑好看的,不管说的是什么」)。
195
308
  ⚠️ 两个权重与 blurry 降权**都依赖 `matrix describe --plan` 跑过**(编排 ⑦ 那一步);
196
309
  没跑就是全部候选中性、排序与不开权重逐字节一致——lay 会就此打告警,看到就说明漏了;
197
- - `--gap-fill fast`(★ 主理人 2026-08-21 拍板:快速成片不留空):主轨空洞放宽地板随便填候选→延长相邻颗粒→黑片兜底——客户端主轨磁吸开启时 gap 会被吸除、画面与配音错位,快速成片以画面连续性优先;CLI 缺省是 solid(黑片垫齐,精修可见),本配方须**显式传 fast**;
310
+ - `--gap-fill fast`(★ 主理人 2026-08-21 拍板:快速成片不留空):主轨空洞按**五级**依次填——放宽地板取剩余候选 → 段界内延长相邻颗粒 → **跨 beat 借未消费候选** → **次地板补真画面** → 仍不够才落黑片。⚠️ 后两级容易被误当 bug:借来的画面**与本段稿子相关性弱**,次地板槽是**不到 1.2s 的快切**;两者都会在日志里指名报出(`kind` 为 `borrowed` / `subfloor`)——那是**如实告知,不是缺陷,别当 bug 上报**。宁可这样也不落黑,是因为客户端主轨磁吸开启时 gap 会被吸除、画面与配音错位,快速成片以画面连续性优先;CLI 缺省是 solid(黑片垫齐,精修可见),本配方须**显式传 fast**;
198
311
  - 句界吸附(`--cut-align`)默认 0.7 即三七开拍板值,不用传——约七成字幕句起点恰逢镜头切点、三成有意错开;
199
312
  - **BGM 音量口径 = -20dB(线性 0.10,★ 主理人 2026-08-19 拍板定值)**:配音主导原则——BGM 是垫底不是主角,成品音乐响度天然高于 TTS 电平。⚠️ 契约 volume 字段**只写线性增益、MUST NOT 写 dB**(composition-contract-v1 §4 明文,dB 残档曾致客户端打不开工程)——-20dB 换算=10^(-20/20)=0.10 写入。**客户端音量面板显示的就是 dB 值(标准 20·log10 换算,两侧同一标尺)**:写 0.10 打开面板即显示 -20.0,主理人实测该值听感最佳且偏保守(宁小声不大声)。用户嫌低在客户端拉高(终调权在客户端);
200
313
  - 时间窗(`--source-window`):二创场景解说序≈素材序时按 beat 对应的原片区间约束检索(可选增强,全库检索在几百场景规模下命中率已够);
@@ -213,6 +326,21 @@ gtrk subtitle lay --project "<工程目录>" --style default --color 雅黑 --js
213
326
  - **产前抽帧**(overlay 必做):对挂点用本地 ffmpeg 抽 1 帧看底轨明暗与主体位置(临时文件落系统 temp 用完即删);
214
327
  - 产物存 `<工程目录>/mg/<composition_id>.html`,逐颗 lint 过了再铺。
215
328
 
329
+ **字卡自检清单**(★ 2026-09-02 补,形制同 §三「写后自校验清单」):
330
+
331
+ - [ ] 拆分稿写完,**数一遍** `aux_layers` 里 `type:"overlay"` 的条数,是否落在**每片 2-4 颗**;
332
+ - [ ] 落地后核对 `gtrk split --json` 的 `queues.mg` 条数,与上一条对得上、且仍在 2-4;
333
+ - [ ] 不足按地标出场句补挂;超出按「稀缺才有力」裁掉。
334
+
335
+ > **为什么补在图纸而不上机器闸**(拍板留痕):「2-4 颗」以前**全链无一处拿它比对**——`split` 只如实报数、
336
+ > `mg` 的 `empty_queue` 只防误清空整轨、`mg lint` 是单颗 HTML 内的静态校验、`splitdoc` 对 `aux_layers`
337
+ > 条数零校验;于是真机两条片各只落 **1 颗**,下游每一环都 100% 报「全部铺成」,观感上完全正常,**无人喊**。
338
+ > 但它与仓内唯一那道数量硬闸(`MAX_ANCHORS_PER_BEAT`)**判据类型不同**:那条的理由是**工程后果**
339
+ > (锚过密会把序贯填充区间切碎),字卡颗数是**审美编排量**——上通用闸等于让通用契约背垂类配方
340
+ > (撞 `gtrk-mg`「不硬编任何栏目的视觉风格」)。缺口的真正位置是**图纸缺自检项**(§三 有、§六 没有),
341
+ > 补在缺口上最省,**零代码变更**。⚠️ 反方也如实记:颗数是 `dispatch.mg.length` 一行就能算的机器可判量,
342
+ > 若这类漂移反复发生,改上「通用可选入参 + 由图纸传值 + 非致命告警」是正当的。
343
+
216
344
  ## 七、增量调整与个性化出路(垂类示例定位)
217
345
 
218
346
  **本图纸是解说链的垂类示例,承诺面只有快速成片**(检查点①一次拍板后一杆到底;决策前置三条腿照公约执行,单模式不豁免)。交付后对**个别环节**不满意,用下表增量重跑悔棋——改哪步跑哪步,不整链重来:
@@ -221,7 +349,7 @@ gtrk subtitle lay --project "<工程目录>" --style default --color 雅黑 --js
221
349
  |---|---|---|---|
222
350
  | 写稿 | 解说稿 vN | 用户改意见 → 你改稿 | 改稿后从 ④ 重跑(TTS 变=全链时码变,⑤起全部重建) |
223
351
  | 拆分 | split/view.json + 拆分稿 | 改 beat 划分/queries | `gtrk split <拆分稿> --project` 重落 |
224
- | B-roll | broll-plan.json | 编辑 plan(删候选/换段/pinned 钉选) | `gtrk matrix lay`(消费 plan 零检索零计费) |
352
+ | B-roll | broll-plan.json | 编辑 plan(删候选/换段/pinned 钉选) | `gtrk matrix lay`(消费 plan **零检索**;⚠️ 本地素材路的**编排仍按编排量计费**,不是零计费——重跑前照 §四.6 再报一次预估) |
225
353
  | 字卡 | mg/*.html | 改颗粒 HTML | `gtrk mg --project --only <beatId>` 单颗重铺 |
226
354
  | BGM | audio_track | 换歌/换音量 | `gtrk audio lay` 同文件幂等替换 |
227
355
  | 字幕 | cve 字幕 lane | 换样式/颜色 | `gtrk subtitle lay --style/--color` 重跑幂等替换(手加 text 不受影响);逐条微调在客户端 |
@@ -236,6 +364,7 @@ gtrk subtitle lay --project "<工程目录>" --style default --color 雅黑 --js
236
364
  - **`gtrk render` 仅是主轨快照预览**(★ 打样误用教训):只渲一条视频轨、不合成字卡 overlay——可以当粗查混音与 B-roll 落位的预览片,**MUST NOT 当成片交付**;
237
365
  - **云渲必拒**:含本地 B-roll 的工程提交云渲会被直接拒绝(`local_broll_cloud_render_rejected`)——出片走客户端本地导出或 `gtrk render` 预览,如实告知用户;
238
366
  - 交付话术:报产物目录+客户端打开指引+各环节计费实耗;候选轨小眼睛切换、字卡可删可改、BGM 音量客户端可终调、字幕客户端可整轨换样式——把悔棋通道讲清楚。
367
+ - 报计费实耗 SHALL 转述 `--json` 的 `credits_estimated`(**实耗口径**,豁免时为 0),MUST NOT 转述 `credits_would_be`(原价);`exempt_probe:"failed"` 时须注明『身份没探到,此数按非豁免保守估』。
239
368
 
240
369
  ## 九、计费速查
241
370
 
@@ -244,12 +373,18 @@ gtrk subtitle lay --project "<工程目录>" --style default --color 雅黑 --js
244
373
  | transcript 转写 | ASR 按分钟 | 二创场景一次 |
245
374
  | matrix index(embed) | 会话计量按实际用量 | 同合云内部成员豁免 |
246
375
  | matrix describe | 1 积分/张 | 内部成员豁免;同帧缓存永不重复计费 |
247
- | TTS 配音 | 按成本档 1-12 积分/计费分钟(240 字/分钟折算) | 音色 catalog 可查档位;同参重合成走缓存不重复扣费 |
248
- | project init / split / audio lay / subtitle lay | 0 积分 | producer 同步口 0 元留痕;beat 分析(--beat-align)走 audio_music_analyze 计费 |
376
+ | **B-roll 云端编排(`matrix lay`,本地素材路)** | 按「**编排量**」计费(服务端复算为准) | 缺省即走云端(`--arrange local` 已不受理);素材矩阵路的编排在本机跑、不计费。预估用 `--arrange-estimate-only`(§四.6),跑前须已拿到同意 |
377
+ | TTS 配音 | 按成本档 1-12 积分/计费分钟(240 字/分钟折算) | **计费分钟按标准语速折算,不等于音频实际时长**;音色 catalog 可查档位;同参重合成走缓存不重复扣费 |
378
+ | project init / split / audio lay / subtitle lay | 0 积分 | **`matrix lay` 不在此列**(见上一行的云端编排);producer 同步口 0 元留痕;beat 分析(--beat-align)走 audio_music_analyze 计费 |
249
379
  | BGM 矩阵搜索(`gtrk matrix material`) | 公开口 1 积分/次;矩阵成员口 0 积分 | 档位由零件自动路由,命令输出如实报口径与计费 |
250
380
  | image_move 图片运镜 | 2 积分/张 | 素材夹含图片且被选中上轨时 |
251
381
 
382
+ > ★ **脚注(划界,2026-09-02)**:表里那个 **240 字/分钟是计费折算常量**,
383
+ > **MUST NOT 用于写稿篇幅估算** —— 写稿口径在 §三(挂钟语速,按音色取、缺省 ≈330),两者保守方向相反。
384
+ > 本脚注**只划界,不动**该行的积分档位与计量单位(单位口径归 infra `refactor-billing-measure-kchar` 的 CLI 联动件)。
385
+
252
386
  起跑前把预估总消耗报给用户(检查点①一并确认),结束报实耗。
387
+ **§一′ 适配闸命中而中止时,已经发生的计费(transcript / index / describe)SHALL 如实报出**——MUST NOT 只报一句「已中止」把账藏起来。
253
388
 
254
389
  ## 十、已知边界与排障
255
390
 
@@ -258,7 +393,7 @@ gtrk subtitle lay --project "<工程目录>" --style default --color 雅黑 --js
258
393
  - **字幕**:⑪ `gtrk subtitle lay` 已直接上好(7 样式 × 11 色,客户端可整轨换样式、逐条可编辑);改稿重跑 TTS 后须重跑 subtitle lay(时码变了);
259
394
  - describe 的 `text_overlay` 信号命中多为撞上原片烧录字幕区(片头片尾高发)——裁定换段或保留交客户端;
260
395
  - `matrix lay` 拒铺(`tracks_edited`)不是失败:用户在客户端动过候选轨,plan 照产(`planReusable:true`),提示用户后按其意愿 `--replace-all` 或保留;
261
- - BGM 曲长 < 成片:audio lay 不循环,垫不满如实告知(客户端可复制 clip 补尾)。
396
+ - BGM 曲长 < 成片:**已不再是边界**(⟲ 2026-09-02 订正——旧条目按早期行为写,落后于实现整整一版)。现行缺省是**循环叠满至工程末尾、尾段裁齐**(多 clip 首尾相接,命令打 INFO 报段数),不必再去客户端补尾;要单次铺才传 `--no-loop`。
262
397
 
263
398
  ---
264
399
 
@@ -0,0 +1,119 @@
1
+ # 语速档案(写稿折算的单一真值源 · fix-speech-rate-calibration 2026-09-02 立)
2
+
3
+ > 本文件服务于 `SKILL.md` §三 的「成片时长 = min(内容支撑, 素材支撑)」——把秒数换算成字数的那一步。
4
+ > **图纸正文只留一句指针 + 缺省值,数值表只住在这里**(垂类图纸继承通用框架层时**引用不复制**)。
5
+ >
6
+ > 表放哪:三方案取舍如下,自裁 **(B) 过渡 + (C) 终局**。
7
+ >
8
+ > | 方案 | 优点 | 缺点 | 判 |
9
+ > |---|---|---|---|
10
+ > | (A) 49 条表直接贴进 `SKILL.md` | 零新增依赖,agent 读图纸即得 | ① 淹没图纸主线(图纸是编排指南不是数据表);② 随注册表漂移,音色增删要手改;③ 图纸随 npm 发版分发,必然过期 | **弃** |
11
+ > | (B) 本文件(`references/speech-rate.md`) | 不淹图纸;仓内已有先例(`gtrk-cover` / `gtrk-splitter` / `gtrk-style-maker` 都有 `references/`);能同时装标定方法与档案 | 仍是静态快照会漂;且这条口径不止旅拍要用,挂在某一个垂类下有被复制扩散的风险 | **取(过渡态)** |
12
+ > | (C) infra 出字段 + CLI 从 catalog 直接读 | **唯一不漂**:注册表是真值源,新增音色自动带上;检查点①本来就要拉 catalog,读同一份载荷零额外往返 | 要 infra 联动件;改 `PUBLIC_FIELDS` 会让所有 ETag 失效一次;上线前 CLI 无数据 | **取(终局)** |
13
+ > | (D) 新增 `gtrk` 子命令去查语速 | 对 agent 友好 | 净新增命令面:今天 CLI 里没有任何代码拉 `/task/tts/voices`(图纸是教 agent 直接 GET 的),为一个写稿阶段只用一次的读操作立子命令,收益不抵维护面 | **弃** |
14
+ >
15
+ > (C) 落地后,本文件降级为**纯方法学文档**:只留 §二 标定方法与 §三 历史档案,删掉数值、改指 catalog 字段。
16
+
17
+ ## 一、两个数不是一回事
18
+
19
+ | | 公式 | 低估语速的后果 | 保守方向 |
20
+ |---|---|---|---|
21
+ | **计费折算**(`_SPEECH_CHARS_PER_MINUTE = 240`) | 计费分钟 = 字数 ÷ 语速 | 分钟数变大 ⇒ **多收** | 低估是**安全**的(不少收) |
22
+ | **写稿折算**(挂钟语速,本文件) | 成片时长 = 字数 ÷ 语速 | 时长被高估 ⇒ **稿子写短** | 低估是**有害**的(成片缩水) |
23
+
24
+ 240 的来历:volc 引擎**单点实测 100 汉字 ≈ 23.06 秒(约 260 字/分钟),再人为下调留余量**取 240;
25
+ 2026-08-20 起它**已退出计费链路**,保留只为时长预估。把这份「宁可低估」的偏置搬到写稿侧,
26
+ 就是本档案要治的那个缺陷 —— 按 240 写 3 分钟稿 = 720 字,用 `narrator` 349.3 的挂钟语速实播只有
27
+ **2.06 分钟,缩水 31%**。
28
+
29
+ 两条口径的换算关系:**挂钟语速 = 有效语速 × (1 − 停顿占比)**。
30
+ 注册表 `acoustic.rate` 记的是**有效语速**(扣掉停顿的净说话速度),写稿要的是**挂钟**(含停顿)。
31
+
32
+ ## 二、标定方法(一条记录 MUST 齐备五项,缺一不得作口径依据)
33
+
34
+ | # | 必填项 | 说明 |
35
+ |---|---|---|
36
+ | ① | **音色与引擎** | `voice_id` + `engine`(自训 gpt_sovits / 云引擎 volc / …) |
37
+ | ② | **影响语速的合成参数** | `speed`、`fragment_interval`、`split_method` 等。`narrator` 的 `fragment_interval=0.28` 会实打实抬高句间停顿占比,不记就没法复现 |
38
+ | ③ | **稿件** | 字数口径(Unicode 码点、含不含标点与英文数字,与服务端 `_MAX_TEXT_LEN` 同口径)+ 稿件出处或哈希 + 字数 |
39
+ | ④ | **测量方法** | 音频总时长怎么取(`ffprobe` duration)、首尾静音算不算 |
40
+ | ⑤ | **结果两个数 + 样本数 + 日期** | **挂钟语速**(写稿用)与**有效语速 / 停顿占比**(注册表口径),样本条数,标定日期 |
41
+
42
+ 两条禁令:
43
+
44
+ - **MUST NOT 再写「(TTS 实测)」这类无主体、无出处的括注**。任何写进图纸的语速数字,
45
+ 要么能指到一条满足上表的档案,要么明确标注为「派生值 / 缺省值」。
46
+ (这条的由来:`SKILL.md` 的「200-240 字/分钟(TTS 实测,语速快的音色偏 270)」是
47
+ **一次性写入、无出处**——`git log -S` 只命中 skill 首发那一个 commit,归档 change 里 grep 零命中。)
48
+ - **单点标定 MUST NOT 外推到其它引擎的音色**。240 那次是 volc 单点标定,与自训 gpt_sovits 的
49
+ `narrator` 没有任何关系。
50
+
51
+ ## 三、已标定档案
52
+
53
+ > ⚠️ **实测与派生逐条标注区分**,MUST NOT 混着读。本节今天只有一条真机实测,
54
+ > **MUST NOT 宣称「已按新口径标定过全库」**。
55
+
56
+ ### 3.1 `narrator`(**单点实测 · 未覆盖全库**)
57
+
58
+ | 项 | 值 |
59
+ |---|---|
60
+ | ① 音色 / 引擎 | `narrator`(`ext_code=narrator`)/ 自训 gpt_sovits |
61
+ | ② 合成参数 | `speed=1.0`、`fragment_interval=0.28` |
62
+ | ③ 稿件 | 见来源件 `fix-speech-rate-calibration`(注册表标定样本,字数口径未逐条留痕 —— **这一格是弱项,后续回校须补齐**) |
63
+ | ④ 测量 | 注册表 `acoustic` 口径(有效语速 + 停顿占比) |
64
+ | ⑤ 结果 | 有效语速 `rate = 379.7`、停顿占比 `pause = 0.08` ⇒ **挂钟 ≈ 349.3 字/分**;日期 2026-09-02(复算) |
65
+
66
+ ### 3.2 全库 49 条 zh-CN 音色(**派生值,非逐条实测**)
67
+
68
+ `voice_registry.json` 55 条中 49 条带 `acoustic.rate`,据 `挂钟 = rate × (1 − pause)` 派生:
69
+
70
+ | 口径 | min | 中位 | max |
71
+ |---|---|---|---|
72
+ | 有效语速(`rate`,注册表原值) | 309.77 | 361.13 | 427.47 |
73
+ | **挂钟语速**(扣停顿后,写稿用) | 222.02 | **308.66** | — |
74
+
75
+ **落进 200–240 区间的:0 条。低于旧图纸所称上限 270 的:0 条。** 旧口径不是「偏保守」,是全库无一命中。
76
+
77
+ ### 3.3 260902 真机三条旅拍片(**复盘记录,未逐条复算**)
78
+
79
+ 实测 **316–342 字/分**(挂钟口径),与 3.1 派生的 349.3 同量级、互为旁证。
80
+ 本条**不满足** §二 的五项(缺 ②③④ 的逐条留痕),故只作旁证、MUST NOT 单独当口径依据。
81
+
82
+ ### 3.4 `volc_zh_male_cixingjieshuonan_uranus_bigtts`(**五项齐备 · 双样本实测**)
83
+
84
+ | 项 | 值 |
85
+ |---|---|
86
+ | ① 音色 / 引擎 | 磁性解说男声 2.0 `volc_zh_male_cixingjieshuonan_uranus_bigtts` / 火山引擎 `volcengine`(云引擎,非自训) |
87
+ | ② 合成参数 | `speed` 未传(= 默认 1.0);`fragment_interval` **不适用**——云引擎音色不受理该参数;`split_method` 走服务端默认 |
88
+ | ③ 稿件 | 两稿,Unicode 码点口径(含标点与英文数字)。① 凯奇坎 823 码点 `sha256:fd4e4f0efaabdfa1…` ② 黄石 904 码点 `sha256:9ce70f69b9d00f20…` |
89
+ | ④ 测量 | `ffprobe -show_entries format=duration` 取 wav 总时长,**首尾静音计入**(挂钟口径的定义即如此) |
90
+ | ⑤ 结果 | 稿① 823 / 230.40s = **214.3**;稿② 904 / 248.33s = **218.4**;合并 1727 / 478.73s = **216.4 字/分**。样本 2 条,日期 2026-09-03 |
91
+
92
+ **这条记录的价值不在它自己,在它顺手验了 §3.2 那张派生表。**
93
+ 注册表给这条音色 `rate=321.77 / pause=0.31`,按 `挂钟 = rate × (1 − pause)` 派生得 **222.0**;
94
+ 两次实测 214.3 / 218.4,偏 **−3.5% / −1.6%**。
95
+ §3.2 的 49 条派生值此前**从未被任何实测检验过**(3.1 是注册表自身口径的复算,不是独立测量),
96
+ 本条是第一次拿真机音频去撞那条公式,**没撞坏**。派生表因此从「未经检验的推算」升格为「有一个实测锚点的推算」——
97
+ 仍 MUST NOT 宣称全库已标定,但对**云引擎 volc 这一档**,派生值可以当估值用,误差量级 <5%。
98
+
99
+ ⚠️ 另记一条选音色时该知道的事实:这条音色的 `pause=0.31` 是**全库最高**,挂钟 222.0 正是 §3.2 那张表的
100
+ `min` 值本人。同一份稿子交给它,比交给缺省 330 长 **48%**,比交给 `narrator`(349.3)长 **57%**。
101
+ 写稿时 MUST 按它自己的挂钟值反推字数,照缺省 330 写会让成片直接长出三成。
102
+
103
+ ## 四、缺省值 330 是怎么来的,用在哪儿
104
+
105
+ - **取值**:落在全库挂钟中位 **308.7** 与 `narrator` **349.3** 之间,覆盖真机 **316–342** 区间的中部;
106
+ - **性质**:**缺省估值,不是任何一条音色的实测值**。用它折算时 SHALL 在交付说明里明示这一点;
107
+ - **适用边界**:只适用**中文**、**正常语速档**、**未加 `--speed`** 的合成。
108
+ 换引擎、换语种、动了 `--speed` / `fragment_interval` 的,一律回 §二 重新标定,MUST NOT 沿用;
109
+ - **怎么退役**:终局 (C) 上线(catalog 投影出 `acoustic` 或派生只读字段)后,
110
+ 取值路径改为「读 catalog 字段」,330 只在字段缺失时兜底。
111
+
112
+ ## 五、回校怎么攒样本(`SKILL.md` §五 ④′)
113
+
114
+ TTS 合成完成后,稿件字数与音频实际时长都已在手(`project init --tts-task` 本就要读它):
115
+
116
+ 1. 算 **实测挂钟语速 = 稿件字数 ÷ 音频实际时长**;
117
+ 2. 与写稿所用估值比对,**偏差 >15% 在交付汇报里点名**(报「估 X / 实测 Y / 偏 Z%」);
118
+ 3. 按 §二 五项格式**追加一条**进 §三 —— 每跑一条片就攒一条样本,「孤证」这个病从结构上被治掉;
119
+ 4. **MUST NOT 自动改稿、MUST NOT 自动重跑 TTS**:改稿要从配音步重跑、重付 TTS 费用,返工与否由用户拍板。
@@ -81,7 +81,7 @@ description: Vlog 纪实类一站式成片图纸——纪实 Vlog 是散文的
81
81
  - **禁幼稚拟声与过度儿化**:换成真实事实——数字与事实比拟声词有力。
82
82
  - **风格贴着素材走**:素材什么气质,稿子就什么气质,不加分不减分。
83
83
 
84
- **成片时长 = min(内容支撑, 素材支撑)**;旁白折算约 200–240 字/分钟。
84
+ **成片时长 = min(内容支撑, 素材支撑)**;旁白折算用**挂钟语速**(按检查点①选定的音色取,取不到用缺省 ≈330 字/分钟)——口径与标定档案见 `skills/gtrk-travel-recap/references/speech-rate.md`,**MUST NOT 复制数值表**。
85
85
 
86
86
  ### 3.2 立神:找出那根线(★ 本类型的第一步,先于选材)
87
87