@gitruck/cli 1.2.15 → 1.3.1

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.
@@ -17,7 +17,7 @@ description: 直播切片图纸——把一场数小时的直播回放,拆成
17
17
 
18
18
  - ❌ 不去水印、❌ 不去烧录贴片、❌ 不做画面清理美化、❌ 不调色不裁切
19
19
  - 源片长什么样,切片就长什么样。要不要动那些元素,是**用户在客户端二次编辑时的决定**,不是你的。
20
- - 分段所需的时间轴裁切**必须用 `ffmpeg -c copy` 流拷贝**(不重编码)——既贯彻本条,也快得多(实测 40 分钟段 **12.5 秒**切完,重编码要几十分钟)。
20
+ - 分段所需的时间轴裁切**必须用 `ffmpeg -c copy` 流拷贝**(不重编码)。
21
21
 
22
22
  > **用户只要能直接发的成片、不打算再剪?** 那不是本图纸的活,转 `gtrk tool video_long2short_pro`(精剪,整片上传、云端渲染、计费约两倍)。判断句同 `gtrk-long2short`:**「剪完还要不要再动?」要动 → 留这儿;不动 → 转精剪。**
23
23
 
@@ -42,21 +42,21 @@ description: 直播切片图纸——把一场数小时的直播回放,拆成
42
42
  > ② 与 `/gtrk-long2short`、`/gtrk-tools` 精剪开工的「多人同框」一问同口径:是就开、不确定按否;
43
43
  > 分屏单段最长 8 秒、每条最多 3 处。
44
44
 
45
- > ⟲ **推荐面(公约 §三‴)**:问答收口时多问一句「要不要看看第三方 skill?」,不列名;题材命中场景触发词才多 1–2 句定向推(`gtrk skills recommend --scene <id> --json` 取 tier 最高者,各给一句为什么),用户追问才展开完整块;轻提加定向合计不超三句、同会话同场景只推一次、答「不要」零动作。
45
+ > **推荐面(公约 §三‴)**:问答收口时可问一句「要不要看看第三方 skill?」;题材命中场景触发词才定向推荐,读取 `gtrk skills recommend --scene <id> --json`;用户拒绝后不执行推荐动作。
46
46
 
47
47
  ## 二、分段规约(本图纸的骨干)
48
48
 
49
- ### 两道闸(都是实测,不是推算)
49
+ ### 两道闸
50
50
 
51
51
  | | 闸 | 值 | 命中时的表现 |
52
52
  |---|---|---|---|
53
53
  | **闸一** | 服务端媒体探测层全局业务限制 | **2 小时** | **建单期直接拒**:`6019 媒体时长无效或超过业务限制`。**任务不创建、不计费** |
54
54
  | **闸二** | CLI 轮询墙钟 | **60 分钟** | 轮询超时报错(任务在云端照常跑完,可取回) |
55
55
 
56
- **处理耗时 / 源时长比值必须按分屏与否分档**(同为 40 分钟源的实测):
56
+ **处理耗时 / 源时长比值按分屏与否分档**:
57
57
 
58
- - **不开分屏**:3.7 分钟 = **0.09×** ⇒ 墙钟几乎不构成约束
59
- - **开分屏**:21.0 分钟 = **0.53×** ⇒ 分屏是墙钟压力的**主要来源**
58
+ - **不开分屏**:墙钟压力较小;
59
+ - **开分屏**:处理耗时明显增加,优先按较短段切分。
60
60
 
61
61
  ⇒ **单段 MUST ≤ 2h(硬拒线),开分屏时 SHOULD ≤ 48min(墙钟线)。**
62
62
 
@@ -75,7 +75,7 @@ ffmpeg -ss 3600 -t 2400 -i "<直播回放>" -c copy "<工作区>/inputs/<名>_se
75
75
 
76
76
  ### ⚠️ 两条必须在动手前告诉用户
77
77
 
78
- 1. **切段是新文件,工程指向它、不指向原片。** 逐 clip 工程的 `materials[].path` 实指切段(已实测)⇒ **用户删掉切段文件,工程就素材脱机**。让他把 `inputs/` 留着。
78
+ 1. **切段是新文件,工程指向它、不指向原片。** 逐 clip 工程的 `materials[].path` 实指切段;用户删掉切段文件,工程就素材脱机。让他把 `inputs/` 留着。
79
79
  2. **超过 2 小时整条提交会被直接拒**,不是慢、是拒。好消息是零计费(不进队列),但会白抽白传一个大文件——所以先分段。
80
80
 
81
81
  ### 超时兜底
@@ -121,7 +121,7 @@ gtrk oralcut-result <task_id> --out <目录> # task_id 在产物根 task.json
121
121
  > **判断分屏是否真的生效,MUST 看产物证据,MUST NOT 按「没报错」推定。**
122
122
  > 证据 = `report.json` 的 `split_manifest` 条数 + 毛片旁 `split_screen/` 目录里的素材(可抽帧看)。
123
123
 
124
- **分屏在子轨、主轨原片可回退**(2026-08-27 起的服务端形态):分屏素材落在独立子轨上叠放,
124
+ **分屏在子轨、主轨原片可回退**:分屏素材落在独立子轨上叠放,
125
125
  主轨的原片全程完整在场——用户对某段分屏不满意时,在客户端隐藏/删除子轨该段即回退原片,
126
126
  零重跑。交付时把这条回退动线告诉用户。⚠️ 连带边界:本地 `gtrk render` 是快照渲染、
127
127
  **不合成子轨**——渲出来没有分屏画面;要分屏成片走客户端出片(或剪映导出)。
@@ -129,7 +129,7 @@ gtrk oralcut-result <task_id> --out <目录> # task_id 在产物根 task.json
129
129
  其余参数配方:
130
130
 
131
131
  - `--language` **必填**,缺失在上传前就报错(省一次白上传)
132
- - 竖屏直播源(实测四条靶片全是 9:16)**无需转比例**,`--output-size` 缺省即可
132
+ - 竖屏直播源通常**无需转比例**,`--output-size` 缺省即可
133
133
  - `--duration-pref` / `--max-clip-sec` 按投放平台口径给档
134
134
  - `--subtitle-out` 产逐 clip **独立 `.srt`**(不烧进画面——符合粗剪工程定位)
135
135
 
@@ -145,7 +145,7 @@ gtrk oralcut-result <task_id> --out <目录> # task_id 在产物根 task.json
145
145
  | **时效信息贴片**(价格 / 截止日期) | 切片再发布时是**过期信息** | 额外点一句,让用户自行判断是否适合再发 |
146
146
  | **无叠加** | — | 不必提 |
147
147
 
148
- > 实测参照:一条 3.4 小时讲座直播的标题贴片 **30 秒处与 9878 秒处逐字相同**(全场不变),而同段切出的 clip 主题与它完全无关;一条带货直播的分屏素材里价格贴片「安心退 / 245」原样带出。
148
+ > 贴片可能贯穿全场且与切片主题无关,也可能包含会过期的价格或日期;交付时按实际画面如实告知。
149
149
 
150
150
  **这一节不含任何去除动作。** 用户问「能不能去掉」→ 告诉他这超出本图纸射程,可在客户端二次编辑时自行处理。
151
151
 
@@ -158,14 +158,9 @@ gtrk oralcut-result <task_id> --out <目录> # task_id 在产物根 task.json
158
158
  - **格式**:B站式 `.xml` 是 `<d p="秒数,…">用户:文本</d>`,**`p` 首字段即距开播秒数 = 源片时码**;平台导出 `.txt` 通常是时钟列。归一化成「秒 + 文本 + 用户」三元组即可。
159
159
  - **两个信号**:**复述密度**(同一句话被多个用户在短窗口内重复——观众自发复述的往往就是金句)、**刷屏密度**(互动符号瞬时峰值)。
160
160
 
161
- ### ⚠️ 别高估它:实测弹幕对「选哪些段」几乎没有增量
161
+ ### ⚠️ 别高估它:弹幕对「选哪些段」通常只是辅助
162
162
 
163
- 一次判别性实测(40 分钟段、6 个复述热点、8 条选出的 clip):
164
-
165
- - **6/6 个热点全部落在选出的 clip 内**,而 clip 只占该段 **48%** 的时长
166
- - 纯随机情况下全中的概率约 1.2% ⇒ **服务端的语义选段本来就和观众投票高度同向**
167
-
168
- **结论**:弹幕**验证**了选段是对的,但**没提供选段之外的新信息**——它想告诉你的,LLM 基本已经选出来了。所以:
163
+ **结论**:弹幕主要用于验证选段、提取观众原句标题和微调边界,不是必需输入:
169
164
 
170
165
  - ❌ **不要**为了「更准地选段」去要用户补弹幕(没有就没有,主干照跑)
171
166
  - ✅ 它真正剩下的价值是 **取候选标题原句**:观众自发复述出来的那句话(如「大脑不接受否定」被 15 人复述),
@@ -205,22 +200,18 @@ gtrk oralcut-result <task_id> --out <目录> # task_id 在产物根 task.json
205
200
  ## 八、计费与预算速查(跑前转述给用户)
206
201
 
207
202
  - 计费基 = **上传物音频流时长**(≈源片时长),**2 积分/分钟**。
208
- - **分段不改总量**:切段总时长≈原片,所以分不分段花的钱差不多,分段买的是「能跑通」和「粒度更细的选题清单」。
209
- - 实算示例:40 分钟段 = 80 积分(实测 confirmed);一场 3.4 小时讲座 ≈ 410 积分。
203
+ - **分段不改总量**:切段总时长≈原片,所以分不分段花的钱差不多,分段买的是「能跑通」和「粒度更细的选题清单」。费用以实时价格和音频时长为准。
210
204
  - **建单期被拒是零计费的**(如超 2h 硬闸)——试探性提交不会烧钱,但会白传一个大文件。
211
- - **任务失败会自动退款**(实测失败单的计费记录状态为 `refunded`)⇒ 遇到 §九 那类瞬时故障
212
- **放心重跑,不会重复扣费**。跟用户解释时可以直接这么说。
205
+ - **任务失败按服务端回执处理**;只有回执明确退款时才向用户说明可重跑。
213
206
  - 运行时 CLI 自动查实时价格并打印,**把提示原样转述**;长片先向用户确认再跑。
214
207
 
215
208
  ## 九、排错
216
209
 
217
- - **`超过最大重试次数`(本线最常见的失败形态,务必先看这条)** → 这句是**通用兜底文案、不是真因**。
218
- 实测多次独立观测,真因都是**外部 ASR 供应商的查询接口失败**(不是你的参数错,通常也不是源片格式问题)。
210
+ - **`超过最大重试次数`** → 这句是**通用兜底文案**;优先检查外部 ASR 查询接口状态。
219
211
  - **判据**:失败很快(1–2 分钟内就报,而正常 40 分钟段要跑 4–20 分钟)⇒ 卡在开头的转写阶段。
220
- - **处置:先原样重跑一次**。**但要知道重试不保证成功**——实测存在**同一段连续两次都失败**的情况,
221
- 说明该故障**未必是瞬时的**,可能与具体音频内容相关。
212
+ - **处置:先原样重跑一次**。若仍失败,说明故障可能不是瞬时的。
222
213
  - **重试仍失败时,别死磕同一段**:换个切点重切该时段(边界挪几分钟)、或先跑其他段把能出的先出了,
223
- 把这一段单独挂起问客服/换时间再试。**MUST NOT 反复重跑**——虽然失败会退款,但每次都要等。
214
+ 把这一段单独挂起问客服/换时间再试。**MUST NOT 反复重跑**——每次都会重新等待,是否退款以回执为准。
224
215
  - **别改参数、别一味切更短**——那会掩盖问题;先确认是不是 ASR 侧的事。
225
216
  - 分段跑的好处在这里体现:**只需处理失败的那一段**,其余段的成果不受影响。
226
217
  - **`6019 媒体时长无效或超过业务限制`** → 单次提交超服务端 2 小时硬闸。**分段**,别重试。
@@ -22,7 +22,7 @@ description: 长剪短闭环——把一条长视频(课程/直播/播客/访
22
22
  > **⚠️ 开工再问一句:素材是不是多人同框(对谈 / 访谈 / 多人直播)?** 与 `/gtrk-tools` 精剪同一问、同一措辞,
23
23
  > 和上一问**一起问、一次答完**,MUST NOT 代猜。
24
24
  > 答「是」⇒ 带 `--split-screen`,**并在同一句里告知**:本地会改传一份压过的 720p 代理(否则只传抽出的音频、
25
- > 毛片不出本地),处理时间明显变长(实测 0.09× → 0.53× 源时长);分屏素材落毛片旁 `split_screen/`。
25
+ > 毛片不出本地),处理时间明显变长;分屏素材落毛片旁 `split_screen/`。
26
26
  > 答「否 / 不确定」⇒ 不带(「不确定」按「否」)。分屏是点缀:单段最长 8 秒、每条最多 3 处,落在子轨、
27
27
  > 不合心意在客户端隐藏该段即回退原片。
28
28
 
@@ -71,7 +71,7 @@ gtrk long2short "D:/毛片/对谈.mp4" --language zh-CN --split-screen --split-o
71
71
  切段用流拷贝、秒级完成、不重编码:`ffmpeg -ss 0 -t 2400 -i "<源片>" -c copy "<源片名>_seg01.mp4"`。
72
72
  各段产出的 clip 事后汇总成一张选题清单即可。**分段是常态动作,不是降级方案**。
73
73
  - 云端处理时长随片长涨(ASR+选段),CLI 轮询墙钟 60 分钟;超时不丢——产物根 `task.json` 里有 `task_id` 可恢复。
74
- 这也是 40 分钟/段的由来:墙钟 60min ÷ 开分屏实测耗时比上界 1.25× ≈ 48min,取 40 留余量。
74
+ 40 分钟/段是稳妥起步值;若分屏段仍接近墙钟上限,再继续缩短分段。
75
75
 
76
76
  ## 产物(跑完把这些讲给用户)
77
77
 
@@ -52,7 +52,7 @@ description: B-roll 检索铺轨编排手册——成片管线里第一个铺的
52
52
  - **变奏点**:`--top-k` 控理解成本(1 积分/张,只理解你会认真考虑的那几条);云端 plan 同样可 describe(帧从签名 url 现抽);理解产物有本地缓存,反复迭代不重复扣费。
53
53
  - **裁定要点**:`usable_flags` 是信号不是判决——结合 `desc` 复核(水印在角落的航拍也许仍可用);剔除动作=从 plan 删掉那条 result,CLI 不会替你剔。
54
54
  另读 describe 输出的**剔除风险**清单:候选数 ≤1 的 beat 一删就掏空(音频驱动 ⇒ 整段黑屏或跨 beat 借片;口播 ⇒ 露 A-roll)。先补素材再剔,MUST NOT 见 flag 就删。
55
- ——260902 真机 P3 八个 beat 里七个只有 1 条候选;该清单只是判据,剔不剔仍归你(铁律①「零件不裁定」,见 §四层架构与三条铁律)。
55
+ 该清单只是判据,剔不剔仍归你(铁律①「零件不裁定」,见 §四层架构与三条铁律)。
56
56
 
57
57
  ### 配方 C · 时间窗匹配(电影解说式)
58
58
 
@@ -139,7 +139,7 @@ description: B-roll 检索铺轨编排手册——成片管线里第一个铺的
139
139
  | 填充门槛 | `--score-floor <f>` | 浮点 0–1 · `0.2` | 低于不采纳、槽位留空露黑底;调完必看空洞告警 |
140
140
  | 切点对齐字幕句 | `--cut-align <r>` | 浮点 0–1 · `0.7`(`0`=关闭) | 三七开拍板:约七成字幕句起点恰逢镜头切点、三成有意错开;句级时码取 transcript 重投影(降级自动回旧节奏并告警);开启时结果 JSON `lay.cut_align` 报实测比例 |
141
141
  | 主轨空洞填充 | `--gap-fill <m>` | `fast` \| `solid`(默认)\| `none` | **仅音频驱动工程主轨**(口播工程不适用零回归):fast=放宽地板随便填候选→延长相邻颗粒→**跨 beat 借候选**→**次地板补真画面**→仍不够才黑片;借来的画面与本段稿子相关性弱、次地板槽是不到 1.2s 的快切,两者都会在日志里**指名报出**(`kind` 为 `borrowed` / `subfloor`)——那是如实告知,**不是缺陷,别当 bug 上报**;solid=黑片垫齐(精修一眼看出没匹配到);none=留 gap(客户端主轨磁吸会吸除 gap 致画面与配音错位,慎用);生效时结果 JSON `lay.gap_fill` 报明细 |
142
- | 编排交给云端跑 | `--arrange <m>` | **按素材来源自动定档,一般不用传** | 铺**自己电脑里的素材**→`cloud`(编排在服务端,按编排量计费);铺**素材矩阵的素材**→`local`(编排仍在本机、不计费,逐字不动)。`shadow`=本机照跑照铺轨、云端只对拍不采纳。⚠️ 本地素材路上 `--arrange local` **已不受理**(2026-08-31 拍板:编排只在服务端迭代,留旧路等于让用户在不知情时拿到另一套算法的结果);云端拿不到产物时**直接报错**,不会换算法把活干完。⚠️ **它不是省钱开关**——矩阵素材要付检索费,两条路都花钱、只是花在不同环节,MUST NOT 对用户说「用本地就不花钱」 |
142
+ | 编排交给云端跑 | `--arrange <m>` | **按素材来源自动定档,一般不用传** | 铺**自己电脑里的素材**→`cloud`(编排在服务端,按编排量计费);铺**素材矩阵的素材**→`local`(编排仍在本机、不计费,逐字不动)。`shadow`=本机照跑照铺轨、云端只对拍不采纳。⚠️ 本地素材路上 `--arrange local` **不受理**;云端拿不到产物时**直接报错**,不会换算法把活干完。⚠️ **它不是省钱开关**——矩阵素材要付检索费,两条路都花钱、只是花在不同环节,MUST NOT 对用户说「用本地就不花钱」 |
143
143
  | 落轨前先质检画音对齐 | `--arrange-qc` | 开关 · 缺省关 | 只查各 beat 的**卡点句**(span.from 领衔句):画面没给到稿句说的东西就换候选重排,最多 2 轮,到限即交付 + 如实登记残余。零渲染。⚠️ 按帧计费(每卡点句 1 帧/轮),跑前报预估求确认。**默认关,用户没说就别带**。拿不到卡点句(无 dispatch / 重投影降级)时会明说「跳过 ≠ 查过」,别把那条日志读成通过 |
144
144
  | 云端编排本次上限 | `--arrange-cost-cap <n>` | 正整数 · 不限 | 超限服务端**前置拒绝**、零执行零计费(不是跑一半掐断)。只在 `--arrange shadow\|cloud` 时有意义 |
145
145
  | 先估价再决定跑不跑 | `--arrange-estimate-only` | 开关 · 缺省关 | 走到云端编排的计价确认那一步就停:报出编排量后**成功**返回(`ok:true` + `estimateOnly:true`,不是「被拒绝」),零云端调用、工程零改动。机读值在 `lay.arrange.units` 与 `lay.arrange.scale`。⚠️ 它省的是**云端那一次调用与其计费**(及其后的下载落轨),不是整条链——工程/plan/重投影照样要走。素材矩阵路会报 `applicable:false` 而**不是 0**。与 `--yes` 同给时以它为准 |
@@ -196,12 +196,7 @@ description: B-roll 检索铺轨编排手册——成片管线里第一个铺的
196
196
  > **`false` MUST NOT 读作「无版权、可以随便用」——它恰恰相反。** 决定性反证:概念素材(他人版权物)
197
197
  > 入库时固定写 `is_copyright=0`;字段若真是「是否受版权保护」,那批必须是 1。
198
198
  >
199
- > **真机事故(2026-09-02,这条警示的由来)**:AI 执行方连续两轮**特意去挑 `is_copyright:false`**,
200
- > 以为那是「没版权、随便用」的安全选项,结果把**不可商用**素材铺进了 5 个工程;唯一安全的
201
- > `true` 反倒被主动避开。**病灶是把极性读反了,不是「用了 `false` 的素材」**——认准这一条,
202
- > 下面那条缺省口径才不会被误读成「事故的教训被推翻了」。
203
- >
204
- > **选材口径按档位分流**(⟲ 2026-09-06 主理人拍板):
199
+ > **选材口径按档位分流**:
205
200
  >
206
201
  > - **internal 矩阵成员口:缺省搜全库,MUST NOT 自设一道命令面并不存在的闸。** 命令面缺省本就是
207
202
  > `copyright_scope=all`,你 **MUST NOT 默认写上 `--commercial-only`**,也 MUST NOT 以「保险起见」
@@ -226,11 +221,11 @@ description: B-roll 检索铺轨编排手册——成片管线里第一个铺的
226
221
  |---|---|---|---|
227
222
  | 给素材夹建索引 | `gtrk matrix index --dirs <a,b,...>` | 逗号分隔**目录或素材文件** · — | 免切片只记时间戳;指纹增量零重算;断点续传 |
228
223
  | 本地检索模式 | `--local` | 开关 · 关 | 必配 `--dirs`;跳过身份探针、不触云端检索端点;与 `--column`/`--material-class` 互斥 |
229
- | 圈定检索域 | `--dirs <a,b,...>` | 逗号分隔**目录或素材文件** · — | 检索域永远显式可见;绝不与云端结果混合。**传文件即把域收窄到该素材**——一稿对一片时钉到那一部片,同夹邻片就抢不走候选(实测三片同夹时 46% 的候选来自邻片) |
224
+ | 圈定检索域 | `--dirs <a,b,...>` | 逗号分隔**目录或素材文件** · — | 检索域永远显式可见;绝不与云端结果混合。**传文件即把域收窄到该素材**——一稿对一片时钉到那一部片,避免同夹邻片抢候选 |
230
225
  | **源时间窗过滤** | `--source-window <start,end>` | 秒,`start<end` · 不过滤 | 仅 `--local`:只返回与窗口**有交集**的命中段(段边界不裁剪);与其他过滤器 AND 叠加;图片候选自动排除;**空窗 = ok 空结果非错误**,扩窗是你的裁定 |
231
226
  | 场景切分粒度 | `--scene-threshold <f>` | 浮点 (0,1) · `0.3` | 仅 index:镜头切换快调高、长镜头调低 |
232
227
  | 固定机位判稳阈值 | `--stability-threshold <f>` | 浮点 (0,1) · `0.05` | 仅 index:场景内最大帧间变化低于此值判 stable,抽帧收敛为**中点 1 帧**(60s 固定机位从 30 帧省到 1 帧);summary 分列 stable/unstable 场景数与省帧数;误判 stable 丢检索粒度、误判 unstable 只是不省钱——**宁严勿松**;默认为保守值待标定 |
233
- | 索引强制重建 | `--rebuild` | 开关 · 关 | 忽略指纹全部重算向量;**理解缓存(describes)不清**。存量索引库(2026-08-19 闪帧修复之前建的)**没有切点全集**:铺轨消不到段内切点、消不掉 2~3 帧异景残片——用户报「成片有闪帧」且素材是高帧率长视频时,先带本开关重建一次索引。⟲ 2026-09-10 起多一条重建理由:**倍帧素材的假切点治法**与**段级运动量信号**都只在重建时落库(见「本地素材检索模式要点」) |
228
+ | 索引强制重建 | `--rebuild` | 开关 · 关 | 忽略指纹全部重算向量;**理解缓存(describes)不清**。需要补齐切点、倍帧判定或段级运动量信号时使用;这些索引信号只在重建时落库 |
234
229
  | 不要图片候选 | `--no-image-broll` | 开关 · 默认参与 | 检索与铺轨完全排除图片(零图片上云);pinned 也不豁免这条 |
235
230
  | 跳过计费确认 | `--yes` | 开关 · 关 | 图片运镜 / describe >20 张两处护栏通用 |
236
231
 
@@ -247,7 +242,8 @@ description: B-roll 检索铺轨编排手册——成片管线里第一个铺的
247
242
 
248
243
  **⚠️ 一条 describe 只代表一段,不代表整条候选**(`--plan` 形态):每个候选**只抽一帧**(`segments[0]` 的 `best`),这条判决的有效射程就是**那一帧所属的那一个 segment**。`at_sec` 就是那一帧的时刻(**素材时基**秒,与 `segments[].best` 同轴——注意与 `beats[].anchors[].at_sec` 的**工程轴**秒同名不同轴,别换算)。缺这个字段的旧 plan 按 `segments[0]` 推定,**不外推到全部段**。
249
244
 
250
- - 真机 260902 量级:32 个被理解候选共带 **843 段,只有 32 段(3.8%)被看过**;95 个落轨坑位里只有 12 个(12.6%)含那一帧。命令跑完会打一行「理解覆盖率:N 帧 / M 段 = X%」(`--json` 读 `describe_coverage`),**M 是段数不是候选数**——别把「注入 N 条 result.describe」读成「这 N 条候选都看过了」。
245
+ - 命令跑完会报告「理解覆盖率:N 帧 / M 段 = X%」(`--json` 读 `describe_coverage`),**M 是段数不是候选数**——别把「注入 N 条 result.describe」读成「这 N 条候选都看过了」。
246
+ - 量级示例:843 个候选中只有 32 段被抽帧理解时,覆盖率是 3.8%;覆盖率低时必须按段说明射程,不能外推到整条素材。
251
247
  - 转述给用户时 MUST 按段说:「这条候选的 X–Y 秒那一段有字幕」,MUST NOT 说成「这条素材有字幕」。要判更多段就得多抽帧 = 多花钱(1 积分/张),是否加抽由用户拍板,CLI 不替他加。
252
248
 
253
249
  **plan 消费零件**(`gtrk matrix lay`):
@@ -318,9 +314,9 @@ description: B-roll 检索铺轨编排手册——成片管线里第一个铺的
318
314
  - **段带运动量,据此换段(`add-material-motion-signal`)**:重建过索引的素材,检索结果的每个 `segments[]` 会多带一个可选 `motion`(去重后帧间跳变分位 `p50`/`p90` + 样本数 + 有效帧率)。它答的是**「这段抖不抖」**,与 `score`(像不像)正交:`p50` 超 `0.05` 视为高运动,铺轨排序时降权 0.02 分(**只降权、不排除**——候选稀疏时宁可用高运动段也不留空,留空的观感代价更大)。用户报「这段画面晃得看不清 / 想换一段」时,`motion.p50` 就是挑替补的依据:同 beat 里挑 `p50` 更低的段。
319
315
  - ⚠️ **缺席 = 不可判,不是「平稳」**。存量索引库(本能力上线前建的)没有这份信号,段上整键无 `motion`;此时高运动降权对该素材**不生效**,不是「它很稳」。要拿到信号得 `gtrk matrix index --dirs <夹> --rebuild` 重建一次。
320
316
  - ⚠️ **样本不足也报缺席**:长静止镜头去重后可能只剩个位数帧,分位不可信,`p50`/`p90` 如实为 `null`(`samples` 仍照报)。同样 MUST NOT 读成「平稳」。
321
- - **倍帧素材(30fps 内容装进 60fps 容器)**:这类素材每隔一帧就是上一帧的复制。索引会认出来并落**有效帧率**(`motion.effective_fps`,如容器 60 而实际 30)。判据取近零帧的**连续长度**而非占比——倍帧运动段呈单帧交替(连零 ≤2),静止镜头是长串连零(实测 15–118 帧),两者近零帧都多、只有连零长度分得开。
317
+ - **倍帧素材(30fps 内容装进 60fps 容器)**:这类素材每隔一帧就是上一帧的复制。索引会认出来并落**有效帧率**(`motion.effective_fps`)。判据看近零帧的连续长度而非占比,以区分倍帧运动段和静止镜头。
322
318
  - 见到 `effective_fps` 明显低于容器帧率时,**如实告诉用户这条素材是倍帧的**(画面实际流畅度只有标称的一半,不是铺轨铺坏了)。
323
- - **假切点已在索引侧治掉**(2026-09-10):倍帧会让快摇镜头的帧间分被顶过切点阈值,从而在**单一镜头内**吐出一串假切点(实测某段 0.43s 内记了 11 个)。现在切点判定在**去重后的帧序列**上进行——持续快摇在去重序列上是一条连续高分串、整串不算刀,真实一刀仍是孤立尖峰、照留。非倍帧素材的判定一字未动。
319
+ - 倍帧素材的切点判定在**去重后的帧序列**上进行:持续快摇作为连续高分串处理,真实切换仍按孤立尖峰保留。
324
320
  - ⚠️ **存量索引里的假切点不会自己消失**:这条修法只在**重建索引**时生效。素材被判 `doubled` 且某段 `cuts` 密得离谱(零点几秒里十几刀)时,多半是本能力上线前建的库 ⇒ `gtrk matrix index --dirs <夹> --rebuild` 重建一次;重建前别把那些切点当真。
325
321
  - ⚠️ **一个已知取舍**:倍帧区里**紧挨着**的两刀(去重后相邻)会被判成持续运动而漏掉。它们在信号上与「快摇的头两帧」不可分——宁可漏这一对,也好过把十几个假切点放进去。
326
322
  - 含本地 B-roll 的工程云渲会被提交口直接拒绝(`local_broll_cloud_render_rejected`)——走客户端本地出片或 `gtrk render`。
@@ -356,8 +352,8 @@ description: B-roll 检索铺轨编排手册——成片管线里第一个铺的
356
352
 
357
353
  ## 执行(每次都带 `--json`)
358
354
 
359
- > **产物落点纪律(MUST · 全文见随包 `AGENT.md` 同名一节)**:一切产物只落**工程目录**或**用户显式指定的输出路径**;**MUST NOT** 把成片/预览/素材复制到 agent 自有工作目录——引用媒体用原路径;临时文件放系统 temp 用完即删。违者后果=用户系统盘被静默吃满(真机事故)。
360
- > 交付物(颗粒 HTML / 工程文件 / 派单稿 / 文稿等)SHALL **直接以工程目录内的最终路径为写入路径**,MUST NOT 先写 agent 自有工作目录再拷进工程——**中转本身即违规**,不以「最后拷进去了」免责,**体积不是豁免理由**(2026-09-07 事故里漂掉的是 2.7–6.2 KB 的 HTML)。与上一条的分界:抽帧图这类**不交付**的中间物走系统 temp;**要交付的东西没有暂存态**。
355
+ > **产物落点纪律(MUST · 全文见随包 `AGENT.md` 同名一节)**:交付物只写入工程目录或用户显式指定的输出路径;引用媒体用原路径,不复制到 agent 工作目录;不交付的临时文件放系统 temp,用完即删。
356
+ > 交付物 MUST NOT 先写 agent 自有目录再拷进工程;中转本身即违规,体积不是豁免理由。
361
357
 
362
358
  ```bash
363
359
  gtrk matrix --project "<split 产物目录>" [--lay N] [--score-floor F] [--top-k K] [--column <id>] --json
@@ -17,7 +17,7 @@ description: MG 动态图颗粒铺轨器——成片 SOP 第 ⑤ 步(**最后
17
17
 
18
18
  **你是第 ⑤ 步、也是最后一层。** MG 颗粒是**唯一的叠加层**——底下那整层底轨必须先定死(**三源全落齐**),否则你的排版避让是对着一个不完整的画面做的。
19
19
 
20
- > ⚠️ **AI 情景片段属于底轨 B-roll 画面家族,不是叠加层**。旧序把你排在 AI 情景动画之前、理由写「越往后叠得越上层」——**那是把「工序次序」误当成了「图层次序」**。AI 片段在你之后回铺,底轨构图就变了,你先产的颗粒必然避让错位、甚至盖住 AI 画面主体。
20
+ > ⚠️ **AI 情景片段属于底轨 B-roll 画面家族,不是叠加层**。先完成 AI 片段回铺,再依据最终底轨构图产出 MG,避免遮挡主体。
21
21
 
22
22
  所以动手前先过前置硬门。
23
23
 
@@ -158,10 +158,10 @@ description: MG 动态图颗粒铺轨器——成片 SOP 第 ⑤ 步(**最后
158
158
  ## 逐槽位工作流(产 → lint → 铺,循环到铺满)
159
159
 
160
160
  > **产物落点纪律(MUST · 全文见随包 `AGENT.md` 同名一节)**:
161
+ > 交付物 MUST NOT 先写 agent 自有目录再拷进工程;中转本身即违规,体积不是豁免理由。
161
162
  > 一切产物(颗粒 HTML / 成片 / 预览 / 素材 / 工程文件)只落**工程目录**(颗粒恒存 `<产物目录>/mg/`)或**用户显式指定的输出路径**;
162
163
  > **MUST NOT** 把成片、预览或任何大媒体文件复制到 agent 自有工作目录(如用户文档目录下 agent 产品自建的目录、agent 家目录缓存、会话工作区)——需要引用媒体时**用原路径引用**,不做副本;
163
- > 临时文件(抽帧图等)一律放系统 temp 且**用完即删**(含中断 / 失败路径)。违者后果 = 用户系统盘被静默吃满(真机事故,非假设)。
164
- > 交付物(颗粒 HTML / 工程文件 / 派单稿 / 文稿等)SHALL **直接以工程目录内的最终路径为写入路径**,MUST NOT 先写 agent 自有工作目录再拷进工程——**中转本身即违规**,不以「最后拷进去了」免责,**体积不是豁免理由**(2026-09-07 事故里漂掉的是 2.7–6.2 KB 的 HTML)。与上一条的分界:抽帧图这类**不交付**的中间物走系统 temp;**要交付的东西没有暂存态**。
164
+ > 临时文件(抽帧图等)一律放系统 temp 且**用完即删**。交付物直接写入工程目录或用户显式指定的路径;引用媒体用原路径。
165
165
 
166
166
  ### 1. 看板起手:先看 `dispatch.mg` 有哪些槽位、铺到哪了
167
167
 
@@ -176,9 +176,9 @@ gtrk mg status --project "<split产物目录>" --json
176
176
 
177
177
  对每个「缺 HTML」的槽位:把它的 `composition_id` + `handoff`(`theme` / `duration_hint` / `category`:`overlay` 透明叠加·不挡主体 / `fullscreen` 不透明满屏)+ beat 语义上下文,**交给第「业务分离」节解析出的栏目 MG 生产 skill 产一颗 html-particle**。产颗粒时 SHALL **直接以** `<产物目录>/mg/<composition_id>.html` **为写入路径**(MUST NOT 先在别处产再拷过来)(`gtrk mg` 就从这里读)。
178
178
  - **产前先抽帧看底轨(`overlay` 槽位必做,别只凭派单盲产)**:颗粒最终要叠在真实画面上,构图必须因势象形。对该槽位挂点用本地 ffmpeg 抽 1-2 帧(`ffmpeg -ss <track_st秒> -i <底轨视频> -frames:v 1 "<系统temp>/<beat>.jpg"`,成本≈0;抽帧图是临时文件——落系统 temp、用完即删,**别落 cwd / agent 自有目录**)看清三件事——①真人主体/人脸的位置(颗粒 bbox 避开,呼应栏目「不盖说话人」铁律);②该处是否已有烧入包装或 AI 画面(有 → 别铺这颗,报用户裁决——二次过毛片高发);③画面明暗基调(深底/浅底影响衬底与配色取舍)。把这些**连同抽帧图一起附进产片订单**交给栏目生产 skill;`fullscreen` 槽位可免(满屏不透明无避让问题)。
179
- - **产片订单必须附带坑位硬约束(gsap-emit v1 铁律⑦,2026-07-24 主理人硬性规定)**:颗粒 GSAP 时间线总长 ≥ **坑位时长**(该槽位 `track_ed − track_st` 包络,**不是** `duration_hint`)+ 0.3s 余量;`duration_hint` 只是动画主叙事节奏参考。主叙事播完后颗粒必须**定格保持或有限循环驻留到坑位末尾**——坑位内任意一帧核心内容都可见;**禁全局渐隐/整体退场/清空画面**(渐隐与剪辑层转场冲突,淡出由剪辑层决定);定格不动是合法终态。违反的观感 = 动画一过完颗粒突兀消失。
179
+ - **产片订单必须附带坑位硬约束(gsap-emit v1 铁律⑦)**:颗粒 GSAP 时间线总长 ≥ **坑位时长**(该槽位 `track_ed − track_st` 包络,**不是** `duration_hint`)+ 0.3s 余量;`duration_hint` 只是动画主叙事节奏参考。主叙事播完后颗粒必须定格保持或有限循环驻留到坑位末尾;禁止全局渐隐、整体退场或清空画面。
180
180
  - **`-aux<n>` 叠层颗粒同样处理**:`gtrk split` 若在某 beat 的 `aux_layers` 派了 `overlay`,会派生 `<beat>-aux<n>` 进 `dispatch.mg`(多为 B-roll 底轨之上叠透明概念图解)——照样产、照样存到对应 `composition_id.html`。
181
- - **category 决定叠法**:`overlay` 颗粒背景透明、盖在 B-roll 上不挡主体;`fullscreen` 不透明满屏。最终透明度由颗粒 HTML 的 `background` 声明反推的 `opaque` 定,生产 skill 要让二者自洽(lint 会查)。**「实心底该写在哪个元素上」的正本条款是 `contracts/gsap-emit-v1.md` 铁律 4(含真机证据锚)——本 skill 不复述元素位置,改了要以契约为准**;`fullscreen` 颗粒把实心底写错地方会吃非致命 `4-bg-on-root`(见下节)。
181
+ - **category 决定叠法**:`overlay` 颗粒背景透明、盖在 B-roll 上不挡主体;`fullscreen` 不透明满屏。最终透明度由颗粒 HTML 的 `background` 声明反推的 `opaque` 定,生产 skill 要让二者自洽(lint 会查)。**「实心底该写在哪个元素上」的正本条款是 `contracts/gsap-emit-v1.md` 铁律 4——本 skill 不复述元素位置,改了要以契约为准**;`fullscreen` 颗粒把实心底写错地方会吃非致命 `4-bg-on-root`(见下节)。
182
182
 
183
183
  ### 3. lint 门:铺之前先单测每颗(不过就退回生产 skill,别硬铺)
184
184
 
@@ -189,24 +189,24 @@ gtrk mg lint "<产物目录>/mg/<composition_id>.html" --dispatch "<产物目录
189
189
  - 纯本地静态校验颗粒 HTML 的**铁律机器可判定子集**:`<template>` 包裹、`data-composition-id` + 1920×1080、`gsap.timeline({ paused: true })`、`window.__timelines` 注册、无 `Math.random` / `Date.now`(可逐帧 seek 的确定性)、自包含无相对外链、`background` 声明与 `opaque` 自洽…;给 `--dispatch` 会额外校验 `composition_id` 命中派单。
190
190
  - **`1-cid-expect`(致命)——复制改名必查**:颗粒内部的 `data-composition-id` 必须等于期望 id(`--dispatch` 命中时 = 该条派单的 `composition_id`,否则 = 文件名)。**你从别的颗粒复制模板时最容易漏改内部 id**:那样铺出来的 clip 指向 A、文件注册的却是 `__timelines["B"]`,渲染必错,且两颗粒抢同一个 `[data-composition-id]` 样式作用域。改名的临时副本(`./tmp.html`)不比对,不会误伤。
191
191
  - **铁律④⑤「体积上限」两项**(正本条款 = `contracts/gsap-emit-v1.md` 铁律 4⑤;上限**同源自客户端颗粒运行时**,不是 CLI 的取舍):
192
- - `4-html-size`(**致命,命中即短路、其余项不跑**):颗粒 HTML 超过 **2,000,000 字符**——客户端 bootstrap 直接拒载、每次 seek 的快照同限,这颗在客户端**永远加载不出来**(此前 lint / 铺轨 / 云渲全绿放行,2026-09-18 真实案例:整张 4.4 MB PNG base64 内嵌进 CSS 背景)。文案会点名**最大的一段 data: URI**(类型 / 字符数 / 解码字节数 / 落点)。**处置**:回步骤 2,让生产 skill 把那张图**按它在颗粒里的实际显示尺寸裁剪缩放**后再内嵌(不透明图改 JPEG / WebP,只有需要 alpha 才留 PNG);仍超就把大图放图片素材轨、颗粒只留透明叠加层。**别拿云渲成功当反证**——云端没有这条上限,客户端有。
192
+ - `4-html-size`(**致命,命中即短路、其余项不跑**):颗粒 HTML 超过 **2,000,000 字符**,客户端无法加载。文案会点名最大的一段 `data:` URI。处置:按实际显示尺寸裁剪缩放,不透明图改 JPEG/WebP;仍超就把大图放图片素材轨,颗粒只留透明叠加层。云渲成功不代表客户端可加载。
193
193
  - `4-html-size-heavy`(非致命):500,000~2,000,000 字符——客户端每次 seek 都把颗粒根节点的 outerHTML 整份快照回传,体积直接决定预览帧率。能缩就缩;**不拦铺轨**。
194
- - **铁律④「实心底与透明度」两项恒非致命**(正本条款 = `contracts/gsap-emit-v1.md` 铁律 4,含 2026-07-26 真机证据锚;**本处只说看到该码怎么办,元素位置以契约为准**):
194
+ - **铁律④「实心底与透明度」两项恒非致命**(正本条款 = `contracts/gsap-emit-v1.md` 铁律 4;**本处只说看到该码怎么办,元素位置以契约为准**):
195
195
  - `4-bg-on-root`:这颗把**实心底写在了根元素的 `style` 上**。**根元素的绘制属性会在子合成挂载时被丢弃**——那层底在成片里**一个像素都不落地**:前景照常渲出、底没了、底轨透出来,观感是「浮空面板」;而**本地播放器与客户端预览都看不出**(预览会按登记的 `opaque` 位自己给根盒打底,对这个问题结构性失明)。**报了要回步骤 2 让生产 skill 把实心底下沉为子层**——改法是机械的(把那条 `background` 声明整体搬到根下第一个全幅子层,根上改写 `background:transparent`)。⚠️ 它**不影响退出码、不拦铺轨**(避免存量颗粒一夜之间铺不进去),但**不是可以放着不管的噪音**:不改就是出片丢底。
196
196
  - `4-bg-explicit`:根与根下首个全幅子层**都**没有 `background` 声明 → lint 只能按「透明叠加」处理。契约要求**透明与否显式**:满屏颗粒在全幅子层写实心底,透明叠加颗粒在根写 `background:transparent`。**别靠「不写」表达透明**——作者与机器都分不清「想透明」和「忘了想」。
197
- - 两项都**只看 `background` 声明摆在哪**,不看色值(色值属栏目审美,契约不管)。`opaque` 的推导面 = 「根 `style` ∪ 根下首个全幅子层 `style`」,与契约铁律 4 同源;**合规的子层写法不会再被误判成 `opaque=false`**(旧版 CLI 会,导致满屏颗粒被登记成透明叠加)。
197
+ - 两项都**只看 `background` 声明摆在哪**,不看色值(色值属栏目审美,契约不管)。`opaque` 的推导面 = 「根 `style` ∪ 根下首个全幅子层 `style`」,与契约铁律 4 同源;**合规的子层写法会正确识别为不透明**。
198
198
  - **铁律⑦ 估长三项恒非致命、不是放行凭据**(`--dispatch` 命中派单条目才跑,因为要拿该条的坑位包络):
199
199
  - `7-fill-slot`:静态估长 < 坑位包络 → 「疑未占满」。估长是**下界**(表达式 position、非字面量 duration 那些调用算不了、跳过不计),报出来基本就是真短,**回步骤 2 让生产 skill 把驻留补到坑位末尾**。
200
200
  - `7-no-estimate`:一条时长调用都解析不到 → **明说「铁律⑦这颗没校验」**,不是通过。这时 tl 总长只能靠真引擎 seek 或人读代码确认,别当它过了。
201
- - `7-infinite-repeat`:颗粒里写了 `repeat:-1` → 总长变 `Infinity`、铁律⑦不可验证(契约 2026-07-26 已明文禁)。让生产 skill 改成按坑位算死的有限次数:`repeat = ceil((坑位 − 循环起点) / 单圈) − 1`。
201
+ - `7-infinite-repeat`:颗粒里写了 `repeat:-1` → 总长变 `Infinity`、铁律⑦不可验证。让生产 skill 改成按坑位算死的有限次数:`repeat = ceil((坑位 − 循环起点) / 单圈) − 1`。
202
202
  - 三项都**不影响退出码、不拦铺轨**——真判据是渲染引擎逐帧,静态估长只做提醒。**但「没报 7-fill-slot」≠「时长够了」**,要看是否同时出了 `7-no-estimate`。
203
203
  - **铁律⑧「重复图元合并」为恒非致命提示,但看见必须处理**:
204
204
  - `8-primitive-merge`:这颗有一批由循环直接创建、或由循环调用具名工厂创建的可合并重复图元;它们落到同一父节点,且没有逐元素动画驱动。纯数字循环可算且同父累计 **≥ 8** 时会报数;边界算不出时会报「条数未知」。逐元素 `gsap.set` / tween、或作为 tween 首实参使用的元素数组会被排除。
205
205
  - 本项报的是「这批图元可**无损**合并,合并后画面逐像素不变」这一写法事实,**不是**「该颗粒有缺陷」或「超过某个数量会出问题」;真实触发轴未知。反过来,没报也**不代表安全**,真判据仍是真渲染出片抽帧。
206
206
  - **处置**:回步骤 2,把原始提示完整交给栏目 MG 生产 skill,让它把整组同步驱动的网格 / 排线 / 刻度 / 点阵合成单元素(SVG 用一条 `<path>` 多子路径;同色分档可分档合成),然后重产、重 lint。**别硬铺,也别当没看见**;CLI 为兼容存量把它做成**非致命、不影响退出码、不拦铺轨**,不等于 agent 可以跳过修正。确需 stagger / 逐条画入 / 逐个变色的逐元素动画批次属于契约豁免,不要为了消项删掉动画身份。
207
- - **「回调与 seek 语义」三项恒非致命**(契约同名一节,2026-07-26 增补;**报了不用改颗粒**):
208
- - `x-callback-driven`:这颗的画面靠 `onUpdate` 等时间线回调写 DOM 驱动,且没带任何 seek 兜底(GSAP `seek(t)` 的 `suppressEvents` 缺省为 `true`,会吞掉回调)。**该写法合规**——回调可达性由契约压在**引擎侧**的 MUST 条款保证(引擎定帧 MUST 用 `seek(t,false)` / `time(t)` / `progress(p)`),**且该条款已于 2026-07-26 经真渲染引擎核实**(producer `0.6.101`,纯回调驱动无垫片颗粒三帧读数各不相同)。本项**核实之后照留**做**哨兵**:结论绑死引擎版本,引擎换实现或失守时补间属性照常插值、回调不跑 → 画面**静默定格在初始态**(不是黑屏,本地播放器和预览都看不出)。**别因为它去让生产 skill 改写法,更别让它自己加垫片。**
209
- - `x-engine-api-override`:颗粒运行时覆写了 `tl.seek`(老颗粒常见的 `rr-seek-shim`)或把 `__timelines[…]` 换成了包装对象。它会推翻引擎显式传的 `seek(t, true)`,且引擎改走 `time()`/`progress()` 就完全失效。**既有垫片属过渡态**:2026-07-26 引擎侧结论已核实(引擎本就不抑制回调),垫片已无保护作用、也无害,**可择期清理**(删后须重跑 lint 并重渲复验),不清也不拦;新颗粒别再加。
207
+ - **「回调与 seek 语义」三项恒非致命**(**报了不用改颗粒**):
208
+ - `x-callback-driven`:颗粒画面由时间线回调写 DOM 驱动时,回调可达性由引擎侧契约保证。本项保留为哨兵;若引擎实现变化导致回调不跑,画面可能静默停在初始态。不要因此改写生产 skill 或自行添加垫片。
209
+ - `x-engine-api-override`:颗粒运行时覆写 `tl.seek` 或替换 `__timelines[…]` 时会绕过引擎接口。既有垫片可保留,但新颗粒不要再加。
210
210
  - `x-raf-interval`:颗粒里有 `requestAnimationFrame(` / `setInterval(`。这类自有时钟**不被 seek 驱动**,逐帧渲染时等于冻结(契约明令:所有视觉变化必须挂在 tl 上)。静态正则分不清用途,报了要**人眼确认它是不是在驱动画面**;若是 → 回步骤 2 让生产 skill 改挂 tl。
211
211
  - 另:引擎不抑制回调 = 逐帧 scrub 时 `onComplete`/`onStart`/`onRepeat` 会**反复触发**。颗粒里**别写「只跑一次」的回调**(累加计数 / `push` 数组 / 一次性 DOM 插入),要写成每次从补间状态**重算**的幂等形式。
212
212
  - **成本项 `c-filter-*` 三项恒非致命、当期全部不拦铺轨**(正本条款 = `contracts/gsap-emit-v1.md`「渲染成本:真卷积滤镜」一节):这组查的是**每帧成本**、不是正确性——命中的颗粒**画面是对的,只是渲得慢**。
@@ -214,7 +214,7 @@ gtrk mg lint "<产物目录>/mg/<composition_id>.html" --dispatch "<产物目录
214
214
  - `c-filter-static-fullbleed`:**整幅静态真卷积滤镜**(该声明自身就是 `position:absolute;inset:0` 一类铺满形态)。每帧对整幅做一次卷积。**首选改法是缩小被滤镜覆盖的几何面积**(面积一项同时压掉卷积与整幅逐帧合成两笔成本);次选把静态滤镜结果预烘成图,且**必须是 RGBA PNG**(透明叠加颗粒的 alpha 是成片合成的必需通道,烘成 JPEG 或无 alpha 格式会在成片里塌成不透明色块),但预烘只消得掉卷积、消不掉整幅逐帧合成,**收益有上限**。去不去滤镜属审美取值,**判断权在作者**,本项只给信息与改法。**不拦铺轨**。
215
215
  - `c-filter-indeterminate`:补间的 `filter` 值不是字符串字面量(变量 / 模板串 / 函数返回),lint **对该处没作判定**——既不是「判过且通过」,也不是命中。**人眼确认它到底会不会驱动 blur / drop-shadow**;会就按 `c-filter-animated` 的改法处理。**不拦铺轨**。
216
216
  - **`box-shadow` 整族不在射程内**(含 `box-shadow: 0 0 0 Npx` 这类零卷积脉冲写法,也含带模糊半径的写法)——看到 `box-shadow` 没被报**不是漏报**,是既定射程边界。
217
- - ⚠️ **没报 ≠ 这颗便宜**:这三项是**形态提示**,真判据永远是**真渲染出片计时**。收益也别外推——现网既有栏目语料(21 颗)去掉滤镜只省 **0~3.1%**(2026-07-30 真机实测,仅对该语料成立),这组规则的价值在**滤镜重的新语料进管线前先把门立好**。
217
+ - ⚠️ **没报 ≠ 这颗便宜**:这三项是形态提示,真判据永远是实际渲染计时;不要把单批素材的收益外推到所有语料。
218
218
  - **id 前缀读法**(三个命名空间,别按前缀反推错阻断行为):**数字前缀 `1-`~`8-`** = 契约铁律项,致命性**按项声明**(`4-html-size` **致命**且命中即短路;其余 `4-*` / `5-*` / `7-*` / `8-*` 非致命);**`x-`** = 哨兵项,**恒不拦**;**`c-`** = 成本项,致命性按项声明,**当前三项均不拦**。
219
219
  - **不过(非 0 退出、逐条报因)→ 把报错原样丢回栏目 MG 生产 skill 修,重产重 lint,别硬铺**。铺一颗不合规颗粒会污染工程。
220
220
  - 只想批量干校验不写回:`gtrk mg --project <dir> --lint-only`(有 beat 没过就 `ok:false` + **非 0 退出**,工程一个字节都不动)。
@@ -235,7 +235,7 @@ gtrk mg --project "<split产物目录>" --json
235
235
  - 真要**重置整轨**(连其余已铺颗粒一起剥掉重来):加 `--replace-all` 显式授权。
236
236
  - **素材表不再囤积**(剥离键按「自产身份 × 零引用」判,不认客户端可改写的 `html_material` 前缀):
237
237
  在 opencut 里编辑过工程之后重铺,旧的自产素材条目照样剥得掉,`mg-` 素材数**恒等于轨上颗粒数**;
238
- 历史遗留的重复 / 孤儿条目会在下一次重铺时一并清掉。**非自产素材零连带**——`broll-*`、`ex-solid-*`
238
+ 重复 / 孤儿条目会在下一次重铺时一并清掉。**非自产素材零连带**——`broll-*`、`ex-solid-*`
239
239
  垫轨、你自己加的素材一条不碰(哪怕它当前没被任何 clip 引用)。盘上 `assets/mg/` 的 html 副本从不删。
240
240
  - `--json` 输出:`{ ok, mode:"lay", laid, track_total, kept, kept_ids, removed, skipped, reason?, integrity?, … }`。
241
241
  - **`laid`** = **本次**铺成数;**`track_total`** = **轨上现存**已铺数;**`kept`** = 其中**上轮遗留**(本次没重铺)的颗数。三个数一起读——只看 `laid` 会让「铺 1 颗、剥 20 颗」跟「补铺 1 颗」长得一模一样。恒有 `track_total = laid + kept`。
@@ -253,7 +253,7 @@ gtrk mg --project "<split产物目录>" --json
253
253
  `danglingReferenced` / `danglingOrphan` = 被时间线引用数 / 孤儿数——**两者严重度差一个量级,回报时分开说**;
254
254
  `external` = 绝对路径素材找不到文件(另一档,不进 `dangling`)。
255
255
  **告知不拦阻**:查出悬空不改 `ok`、不改退出码、不删任何东西;非零就报给用户(哪几条、在哪一段),
256
- 多半是历史遗留(如客户端「确认原片」下载中断),修法在客户端而不在这里。**别自己去删素材或文件。**
256
+ 多半来自客户端「确认原片」下载中断,修法在客户端而不在这里。**别自己去删素材或文件。**
257
257
  - **退出码**:`ok:false` 一律连带**非 0 退出**(含「有 beat 被 skip」这种循环中途的正常态)。**别把非 0 读成「命令崩了」**——它说的是「这一轮没全铺成」,按 `reason` / `skipped` 处理后重跑即可。
258
258
  - **只铺单个 beat**:`--only <beatId>`(收的是 **beat id** 如 `B12`,不是 `composition_id`;主颗粒 + 其 `-aux<n>` 叠层一并选)。
259
259
  - **语义 = 真增量合并**:只重铺命中的那几颗,轨上**其余已铺颗粒原样保留**——连它们的透明度与用户在 opencut 的手调一起活着(保留的是既有 clip 原件,不是照登记重建的)。适合迭代改单段。
@@ -261,7 +261,7 @@ gtrk mg --project "<split产物目录>" --json
261
261
  - 代价看 `kept` / `kept_ids`:轨上会同时存在「本次这版」和「上轮那版」。要把全部颗粒刷成最新(含按当刻时间线重投影的新位置),**去掉 `--only` 全量重铺**(幂等、多铺几颗不花钱)。
262
262
  - 确实要**重置整轨**(连其余已铺颗粒一起剥掉重来)才加 `--replace-all` 显式授权。
263
263
  - **仍会拒写的唯一情形**:本次**一条都没定位到**(`--only` 打错 beat id、`dispatch.mg` 为空、或本次条目全被 skip)**而轨上已有已铺颗粒**——那是派单或选择器出问题的信号,不是清空指令,CLI 拒绝写回并报因(`.gtrk` 逐字节不变)。
264
- - **铺完必核「clip 占满坑位」**:读回 `.gtrk`,各 beat clip 的时长必须 = 槽位包络(`track_ed − track_st`)。若你的 CLI 版本按 `dispatch.mg[].duration`(旧 `duration_hint` 语义)落轨、导致 clip 短于坑位(颗粒在 beat 中途突兀消失,2026-07-24 真机实测),**把 `dispatch.mg[]` 各条 `duration` 改为包络秒数(`track_ed − track_st`)后重铺**(铺轨幂等、直接覆盖)。CLI 侧根治(落轨恒用包络)落地后此步可省。
264
+ - **铺完必核「clip 占满坑位」**:读回 `.gtrk`,各 beat clip 的时长必须 = 槽位包络(`track_ed − track_st`),不能使用 `duration_hint` 作为落轨时长。若发现 clip 短于坑位,把 `dispatch.mg[]` 各条 `duration` 改为包络秒数后重铺。
265
265
 
266
266
  ### 5. 循环到铺满
267
267
 
@@ -284,7 +284,7 @@ gtrk mg --project "<split产物目录>" --json
284
284
 
285
285
  `dispatch.mg` 全铺满、`gtrk mg status` 全绿后**别收工**——你已是最后一层,顺势收口。快速成片模式先 `gtrk subtitle lay --project <目录>` 把字幕上好(样式取用户拍板值,没选用 default)再 `gtrk render` 出片。一句话交代即推进:「MG 颗粒已叠铺完,我接着上字幕出片」。
286
286
 
287
- ### ⚠️ `render` 收口会花钱(2026-09-09 起,add-render-overlay-compositing)
287
+ ### ⚠️ `render` 收口会花钱
288
288
 
289
289
  `gtrk render` 现在**会把 MG 颗粒真的渲进成片**——做法是把每颗颗粒送去同合云烤成透明 MOV,再本地叠。于是这条命令**不再是零计费**:
290
290
 
@@ -295,10 +295,10 @@ gtrk mg --project "<split产物目录>" --json
295
295
 
296
296
  **MUST 在推进前把这件事说给用户**(一句话即可:「渲这条会对 N 颗未命中缓存的颗粒云渲、约 X 分钟计费;不想花钱可以先出无颗粒版」),**MUST NOT** 一声不吭替他确认。
297
297
 
298
- ### 剪映交付的 alpha 口径(2026-09-14 起,正本 = `contracts/gsap-emit-v1.md`「Alpha 交付口径」)
298
+ ### 剪映交付的 alpha 口径(正本 = `contracts/gsap-emit-v1.md`「Alpha 交付口径」)
299
299
 
300
300
  - 颗粒里一律写直通 alpha,半透明光晕 / 渐变 / `text-shadow` 软晕都合法;**别为迁就剪映把半透明色改暗或回避半透明**,预乘是云端 qtrle 转码的义务(infra `fix-qtrle-premultiplied-alpha-for-jianying`),CLI 与颗粒 MUST NOT 再乘一次。
301
- - lint 报 `x-soft-alpha`(非致命)= 这颗含半透明面积:照常铺、照常渲;只是**剪映真机格 MUST 用这颗验**,实心颗粒验不出预乘错配(2026-09-14 事故:软星芒在剪映成实心白多边形)。若用户反馈剪映里软边成了实心,先查渲染服务是否已含预乘配方,不是颗粒的错。
301
+ - lint 报 `x-soft-alpha`(非致命)= 这颗含半透明面积:照常铺、照常渲;剪映验收必须使用含半透明的颗粒。若软边成了实心,先查渲染服务是否已含预乘配方。
302
302
 
303
303
  另一条路仍在:**客户端出片**(opencut 打开工程 → 云渲)同样能出带颗粒的成片,且与 CLI 共用缓存。两条路选哪条由用户定。
304
304
 
@@ -341,7 +341,7 @@ SHALL NOT 自动上字幕出片**(`gtrk render` 还是计费/耗时动作,
341
341
 
342
342
  **渲完必看质检摘要**:`gtrk render` 收口后会自动扫一遍成片(闪帧 / 段内跳切 / 黑帧 / 冻结 / 爆音 / 静音 / 音画不同步),落 `<成片名>.qc.json` 并打摘要。**「严重」条目要如实转述给用户并给出路**,别把有缺陷的片子说成出好了:
343
343
 
344
- - **过短镜头 / 段内跳切** → B-roll 颗粒窗口跨过了源素材的镜头切点。**先看严重级再决定要不要动**:报「严重」的是**我们剪出来的节奏断裂**(镜头有一端落在颗粒拼接处,长镜头之间突然插进半拍短镜头,最难受),让用户在 opencut 里微调那几颗的入出点或重铺该 beat;报「备注」的是**素材自身的快剪节奏**(整段落在同一颗粒内部,比如源片本来就是蒙太奇轮播),那是素材语言、**不必动**。若素材是 2026-08-19 之前建的本地索引,先 `gtrk matrix index --dirs <素材库> --rebuild` 重建再重铺。
344
+ - **过短镜头 / 段内跳切** → B-roll 颗粒窗口跨过了源素材的镜头切点。报「严重」时让用户在 opencut 里微调那几颗的入出点或重铺该 beat;报「备注」且属于素材自身的快剪节奏时无需处理。若索引缺少切点,先 `gtrk matrix index --dirs <素材库> --rebuild` 重建再重铺。
345
345
  - **音画不同步(`av_drift`)** → 画面与配音总长不一致。本地渲染的逐段帧对齐已按累计时间线修好(不再渐进失步),所以这一项**报出来就是异常**:先确认成片是不是旧版 CLI 渲的,再看工程时间线本身有没有轨间长度冲突。云渲成片在后端跟进帧对齐前仍可能报此项(已知过渡态)。
346
346
  - **黑帧** → 对照黑底空洞告警:已登记的会自动降为「备注」,报成「提示」的是意料外的纯黑,值得回工程看一眼。
347
347
 
@@ -385,7 +385,7 @@ gtrk patch trim --project <dir> --clip <clip_id> --out -1s
385
385
 
386
386
  **MUST NOT 直接编辑 `.gtrk` 的 JSON。** 片段时码是两套并存的(`clip_st`+`clip_ed` 与
387
387
  `clip_st`+`duration`):改一份不改另一份,客户端优先读 `clip_ed`、后端又不强校验它 ⇒
388
- **没人报错,成片却用了陈旧出点**。`gtrk patch` 替你做恒等式同步 + 帧对齐 + 写前全档校验。
388
+ `gtrk patch` 负责同步两套时码、帧对齐与写前校验,避免手改 JSON 后客户端与后端读取不同出点。
389
389
 
390
390
  > 参数手册在 `AGENT.md` 的「元素级编辑:`gtrk patch`」一节与 README 命令参考。
391
391
  > 本节**只指路不搬手册** —— 搬过来就会长出会漂移的副本。
@@ -18,11 +18,11 @@ description: 音乐可视化成片——把一首歌通过同合云出成一条
18
18
 
19
19
  ## 一条命令
20
20
 
21
- > **产物落点纪律(MUST · 全文见随包 `AGENT.md` 同名一节)**:
21
+ > **产物落点纪律(MUST · 全文见随包 `AGENT.md` 同名一节)**:
22
+ > 交付物 MUST NOT 先写 agent 自有目录再拷进工程;中转本身即违规,体积不是豁免理由。
22
23
  > 成片等一切产物只落产物目录(缺省 = 音频同目录)或**用户显式指定的 `--out`**;
23
24
  > **MUST NOT** 把成片、预览或任何大媒体文件复制到 agent 自有工作目录(如用户文档目录下 agent 产品自建的目录、agent 家目录缓存、会话工作区)——需要引用媒体时**用原路径引用**,不做副本;
24
- > 临时文件一律放系统 temp 且**用完即删**(含中断 / 失败路径)。违者后果 = 用户系统盘被静默吃满(真机事故,非假设)。
25
- > 交付物(颗粒 HTML / 工程文件 / 派单稿 / 文稿等)SHALL **直接以工程目录内的最终路径为写入路径**,MUST NOT 先写 agent 自有工作目录再拷进工程——**中转本身即违规**,不以「最后拷进去了」免责,**体积不是豁免理由**(2026-09-07 事故里漂掉的是 2.7–6.2 KB 的 HTML)。与上一条的分界:抽帧图这类**不交付**的中间物走系统 temp;**要交付的东西没有暂存态**。
25
+ > 临时文件一律放系统 temp 且**用完即删**。交付物直接写入工程目录或用户显式指定的路径;引用媒体用原路径。
26
26
 
27
27
  ```
28
28
  gtrk music-visualizer <音频> --template <模板id> [可选样式/文件] [--json]