@gitruck/cli 1.0.2 → 1.0.5

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.
@@ -1,134 +1,138 @@
1
- # 拆分稿字段契约 v1(JSON)
2
-
3
- `gtrk-splitter` 的产物是**机器 JSON 拆分稿**(不是 Markdown)——`gtrk split <拆分稿.json>` 校验落地。
4
- 目标:LLM 可稳定产出、校验器可硬拒、下游(matrix / mg / ai-drama)可直接消费。
5
-
6
- > 时码零触碰:拆分稿里**不含任何秒级时码字段**。轨道时码由 `gtrk split` 落地时现场投影写入 `struct_meta.split` / `dispatch.json`。
7
-
8
- ## 顶层结构
9
-
10
- ```jsonc
11
- {
12
- "contract_version": "v1", // 固定 "v1"
13
- "transcript_hash": "<64 位 hex>", // 必填:原样透传投影视图的 transcript_hash(hash 链,错版硬拒)
14
- "beats": [ /* Beat[],见下 */ ], // 必填非空
15
- "queues": { /* 人读派单汇总,可选;机器侧不消费,dispatch.json 由 beats 现场生成 */ }
16
- }
17
- ```
18
-
19
- - `transcript_hash` 不匹配当前 `transcript.json` 的 `text_hash` → **硬拒**(提示转写已变更、需重新导出视图重拆)。
20
- - `queues` 是给人看的四车道汇总(`a_roll/mg/ai_drama/film_broll` 各 `[{beat, note}]`),**可选**;真正的机器派单 `dispatch.json` 由落地时按 beats 现场生成,不读 `queues`。
21
-
22
- ## Beat 字段
23
-
24
- ### 必填
25
-
26
- | 字段 | 类型 | 取值 |
27
- |---|---|---|
28
- | `id` | string | `B` + 两位起序号(`B01`…);同稿内唯一 |
29
- | `span` | object | `{from, to}` 两端均为投影视图中存在的 utterance id;`from ≤ to`(id 序);beats 间**不重叠**(允许留空隙) |
30
- | `base_track` | enum | 口播底轨三态:`真人出镜` \| `口播继续` \| `旁白主导` |
31
- | `lane` | enum | 主层四选一:`A_ROLL` \| `MG` \| `AI_DRAMA` \| `FILM_BROLL`(遗留 `RRV_MG` 读旧归一为 `MG`) |
32
- | `narrative` | enum | 八枚举:`mirror-hook` \| `demolition` \| `container-translation` \| `abyssal-fall` \| `holding` \| `reversal-elevation` \| `callback-closure` \| `typography-emphasis` |
33
- | `container_stage` | enum | 七枚举:`none` \| `seed` \| `expand` \| `translate` \| `rupture` \| `flip` \| `callback` |
34
- | `rhythm` | string | 人读节奏标签(`快剪` / `平稳` / `渐升` / `停顿` / `悬停` / `回扣` 等);**机器不消费**、只透传 |
35
- | `visual_task` | string | 一句话:该 beat 让观众「看到什么变化」 |
36
- | `irreplaceability` | enum | `必须真人出镜` \| `优先 MG` \| `可被 B-roll 替代` \| `可降级处理` |
37
-
38
- ### 可选
39
-
40
- | 字段 | 类型 | 说明 |
41
- |---|---|---|
42
- | `handoff` | object | 按 `lane` 分型(见下)。`A_ROLL` 不应带,带了被警告忽略 |
43
- | `aux_layers` | array | 辅助层(见下) |
44
- | `fallback` | string | 预算/素材/AI 稳定性不足时的降级方案 |
45
- | `callback_of` | string | 回扣对象 beat id(如 `B07`);前文意象后文重调时**不合并 beat**,在后文 beat 写此字段 |
46
- | `note` | string | 其他对制作有帮助的信息 |
47
-
48
- ## handoff 按 lane 分型(校验器硬查)
49
-
50
- ```jsonc
51
- // lane === "MG"(遗留 "RRV_MG" 读旧兼容)
52
- "handoff": { "category": "overlay", "slug_hint": "neural-overfit", "theme": "overfitting", "bg": "paper", "duration_hint": 12 }
53
- // duration_hint(秒)必填;slug_hint / theme / bg / category 可选(bg 底色可由底轨态推导)
54
- // ⚠️ duration_hint 语义(2026-07-24 主理人硬性规定):只是「动画主叙事时长」参考,供生产 skill 排布节奏;
55
- // 落轨 clip 恒占满槽位包络(track_ed − track_st),颗粒 tl 总长须 ≥ 包络、终态定格或有限循环驻留、
56
- // 禁全局渐隐退场(gsap-emit v1 铁律⑦)。别把 duration_hint 当颗粒寿命写短。
57
- // category(颗粒品类子类型,裁决⑩):overlay(透明叠加,叠在 A-roll/B-roll 上,不挡主体)
58
- // | fullscreen(不透明满屏,旁白主导整帧);缺省=下游按颗粒 HTML 根 background 反推透明度。
59
- // 二期扩 subtitle/title。供剪辑器色带按品类分层(叠加/满屏 各一行)。
60
- // 读旧兼容:遗留品牌值 rrv-overlay/mg-fullscreen/explain-subtitle/op-ed-title 仍认。
61
-
62
- // lane === "FILM_BROLL"
63
- "handoff": { "queries": ["lonely person in a city apartment at night", "exhausted commuter on a crowded subway train"], "shots": 6, "per_shot_sec": 2, "exclude": ["卡通", "水印"] }
64
- // queries(非空字符串数组)必填;shots / per_shot_sec / exclude 可选
65
- // queries 语言规范(经真机中英 A/B 校准):
66
- // - 用**英文长句场景描述**(5-12 词,谁+在哪+做什么),不是关键词堆叠——检索后端向量模型英文场景级命中明显更准
67
- // - 每条 query 只装一个场景意象,多意象拆成多条
68
- // - **避多义/字面义强的动词**("pointing" 会召回手指特写、"hunting" 召回猎人——改用 "giving suggestions in a meeting" 这类场景语义)
69
- // - **exclude 保持中文**:负向过滤匹配的是服务端返回的中文 note,写英文会失效
70
-
71
- // lane === "AI_DRAMA" —— 全可选(下游框架 skill /gtrk-ai-drama 有推断默认)
72
- "handoff": { "narrative": "trauma-repetition", "theme": "freud-fort-da", "emotion_stage": "abyssal", "platform": "video-gen", "shot_count": 5 }
73
-
74
- // lane === "A_ROLL" —— 无 handoff
75
- ```
76
-
77
- ## 辅助层字段(aux_layers[])
78
-
79
- ```jsonc
80
- {
81
- "type": "quote-card", // 八类:quote-card | term-callout | network-diagram
82
- // | archive-caption | pause-card | data-annotation | timeline-tag | overlay
83
- "mount": { "from": "u0001", "to": "u0002" }, // 挂载范围三型:"same_beat" | {from,to} | {trigger:"uNNNN"}
84
- "role": "金句提炼", // 职责:金句提炼/术语解释/关系表达/证据标注/停顿加压/情绪聚焦/回扣提示
85
- "necessity": "强建议", // 可选:必须 | 强建议 | 建议 | 可省略
86
- "note": "为什么加它", // 可选
87
- "promote_condition": "若连续承担主要理解职责,则升级为下一个 beat 主层", // 可选
88
- "fallback": "该辅助层不可做时的替代方式" // 可选
89
- }
90
- ```
91
-
92
- - `mount` 里的所有 id(`from`/`to`/`trigger`)MUST 为视图中存在的 utterance id,否则硬拒。
93
- - 辅助层是补充理解职责,不是装饰。满足升级规则时**切出新 beat 升级为主层**,别硬塞辅助层。
94
- - 前七类是**纯建议性**(人读稿一行摘要,不承接派单);第八类 `overlay` 是**承接颗粒派单**的叠层类型(见下)。
95
-
96
- ### `overlay` 叠层颗粒 aux(第八类,承接派单)
97
-
98
- `overlay` = 与底轨主视觉(如 `FILM_BROLL` 电影感 B-roll)**同段共存的透明概念颗粒**——想「底轨放实拍情绪镜头、其上叠一层 MG 透明图解/金句」时用它。与前七类不同,`overlay` aux 必带 `handoff`,由 `gtrk split` 落地投影成派生颗粒(进 `dispatch.mg` + 合成 `struct_meta.split.beats`),后续 `gtrk mg` 铺出透明颗粒盖在底轨上。
99
-
100
- ```jsonc
101
- {
102
- "type": "overlay",
103
- "mount": "same_beat", // same_beat(复用当前 beat 落轨区间)| {from,to}(子区间);{trigger} 一期不支持
104
- "role": "概念叠层图解",
105
- "handoff": { // overlay 必带(镜像 MG lane 的 handoff)
106
- "duration_hint": 6, // 必填正数秒(该 aux 要生成颗粒,无时长不成立;缺/非正数硬拒)
107
- "category": "overlay", // 可选品类(软校验,非法只告警不拒;派生颗粒实际 category "overlay")
108
- "slug_hint": "overfit-mirror", // 可选:颗粒 slug 提示
109
- "theme": "overfitting", // 可选:主题
110
- "bg": "transparent" // 可选:底色(叠层通常透明)
111
- }
112
- }
113
- ```
114
-
115
- - **mount 投影**:`same_beat` → 复用当前 beat 的 `track_st/track_ed`;`{from,to}` → 取该子区间存活实例的包络(全被剪则计入 `skipped` 不落)。**`{trigger}` 点挂载一期不支持**(无干净源区间,`duration_hint` 是时间线秒非源秒 → 跟随会不准):遇到计入 `skipped` + 告警,二期再补。
116
- - **composition_id 命名**:派生颗粒 = `<工程slug>-<beatId>-aux<n>`(`n` 从 1,位置计数);同 beat 主颗粒仍是 `<工程slug>-<beatId>`。「一 beat 一 composition_id」松绑为「`composition_id` 全局唯一,一 beat 可派生主 + N 个 `-aux<n>` 颗粒」。
117
- - **一期约束**:`FILM_BROLL` 主(底轨不产 MG 颗粒)+ 一颗 `overlay` aux 同段安全;`MG` 主 beat 再挂 `overlay` aux 会同段两颗撞一轨(后续拆轨),先避开。
118
-
119
- ## 落地产物(CLI 写,供参照)
120
-
121
- - **`.gtrk` `struct_meta.split`**:`{contract_version, transcript_hash, projected_at, material_id, beats:[{id, lane, span, track_st, track_ed, source_ranges, narrative, container_stage, visual_task, shrunk?, handoff}]}`——投影时刻快照。
122
- **谁负责重投影**:CLI 的消费方命令(`gtrk mg` / `gtrk matrix`)**每次消费都自己现场重投影**(`transcript × 当刻 .gtrk`,与 `gtrk split` 落地同一段代码),所以**用户在 split 之后继续微调口播轨是常态、无需重跑 split**;只有**拆分稿本身**变了才要重跑 `gtrk split`。快照只在重投影不可行时(transcript 缺失 / 工程定位不到 / 主轨查不到口播素材)作回退值,届时命令会显式告警并在 `--json` 里标注降级。
123
- - `material_id`:口播素材 id(= transcript.material_id),消费方脱离 transcript 文件即可定位素材。
124
- - `beats[].source_ranges`:`[{st, ed}]` 源时基秒(v1 恒单元素 = span 源包络,含句间静默与被剪词)——**源时基不随时间线编辑漂移**,消费方以「源区间 ∩ 当刻颗粒源窗口」投影可得实时覆盖(客户端色带跟随模式即此)。
125
- - **`split/dispatch.json`**:`{mg:[{beat, composition_id, duration, category?, theme, bg, slug_hint, track_st, track_ed, span}], film_broll:[{beat, queries, shots, per_shot_sec, exclude, track_st, track_ed, span}], ai_drama:[{beat, ...handoff, track_st, track_ed, span}]}`(去品牌化前 `mg` 键为 `rrv_mg`,消费方 `mg ?? rrv_mg` 双读)。
126
- - **`span:{from,to}`**:该条目对应的 utterance 区间——派单**自述「派什么」**,消费方据它现场重投影,时码不再是派单唯一的权威内容。**aux 派生条目写的是 aux 自己的 span**(`mount` 为子区间时 beat span);注意 aux 条目的 `beat` 字段记的仍是**主 beat id**,所以按 `beat` 回查 `struct_meta.split` 会把 aux 错算成主 beat 的整段窗口——要回查一律用 `composition_id`。
127
- - **`track_st/track_ed` 是快照**:投影那一刻的值。老档(无 `span`)消费方会回落到 `struct_meta.split.beats[].span` 定位,照样重投影。`composition_id` = `<工程slug>-<beatId>`(MG 颗粒 `data-composition-id` 直接用它,打通 beat↔颗粒命名);`overlay` aux 派生颗粒 = `<工程slug>-<beatId>-aux<n>`(`n` 从 1)——`composition_id` 全局唯一,一 beat 可派生主 + N 个 `-aux<n>` 颗粒。
128
- - **`split/visual-split.md`**(`--md`):由机器 JSON 单向渲染的人读稿,不回读。
129
-
130
- ## 落地时的 dropped 处理(你要知道)
131
-
132
- - beat span 内 utterance **全部** dropped(在当前时间线被剪光)→ 该 beat 被**跳过**(不写标注、不进派单),进 result 报告。
133
- - **部分** dropped → beat 轨道区间按存活 utterances 的包络**收缩**、标 `shrunk:true`,进报告提示人工复核。
134
- - 所以:别把 `dropped:true` 的句子划进 span;想让某段进画面,先让用户在客户端恢复它(拉长 clip)再重导视图。
1
+ # 拆分稿字段契约 v1(JSON)
2
+
3
+ `gtrk-splitter` 的产物是**机器 JSON 拆分稿**(不是 Markdown)——`gtrk split <拆分稿.json>` 校验落地。
4
+ 目标:LLM 可稳定产出、校验器可硬拒、下游(matrix / mg / ai-drama)可直接消费。
5
+
6
+ > 时码零触碰:拆分稿里**不含任何秒级时码字段**。轨道时码由 `gtrk split` 落地时现场投影写入 `struct_meta.split` / `dispatch.json`。
7
+
8
+ ## 顶层结构
9
+
10
+ ```jsonc
11
+ {
12
+ "contract_version": "v1", // 固定 "v1"
13
+ "transcript_hash": "<64 位 hex>", // 必填:原样透传投影视图的 transcript_hash(hash 链,错版硬拒)
14
+ "beats": [ /* Beat[],见下 */ ], // 必填非空
15
+ "queues": { /* 人读派单汇总,可选;机器侧不消费,dispatch.json 由 beats 现场生成 */ }
16
+ }
17
+ ```
18
+
19
+ - `transcript_hash` 不匹配当前 `transcript.json` 的 `text_hash` → **硬拒**(提示转写已变更、需重新导出视图重拆)。
20
+ - `queues` 是给人看的四车道汇总(`a_roll/mg/ai_drama/film_broll` 各 `[{beat, note}]`),**可选**;真正的机器派单 `dispatch.json` 由落地时按 beats 现场生成,不读 `queues`。
21
+
22
+ ## Beat 字段
23
+
24
+ ### 必填
25
+
26
+ | 字段 | 类型 | 取值 |
27
+ |---|---|---|
28
+ | `id` | string | `B` + 两位起序号(`B01`…);同稿内唯一 |
29
+ | `span` | object | `{from, to}` 两端均为投影视图中存在的 utterance id;`from ≤ to`(id 序);beats 间**不重叠**(允许留空隙) |
30
+ | `base_track` | enum | 口播底轨三态:`真人出镜` \| `口播继续` \| `旁白主导` |
31
+ | `lane` | enum | 主层四选一:`A_ROLL` \| `MG` \| `AI_DRAMA` \| `FILM_BROLL`(遗留 `RRV_MG` 读旧归一为 `MG`) |
32
+ | `narrative` | enum | 八枚举:`mirror-hook` \| `demolition` \| `container-translation` \| `abyssal-fall` \| `holding` \| `reversal-elevation` \| `callback-closure` \| `typography-emphasis` |
33
+ | `container_stage` | enum | 七枚举:`none` \| `seed` \| `expand` \| `translate` \| `rupture` \| `flip` \| `callback` |
34
+ | `rhythm` | string | 人读节奏标签(`快剪` / `平稳` / `渐升` / `停顿` / `悬停` / `回扣` 等);**机器不消费**、只透传 |
35
+ | `visual_task` | string | 一句话:该 beat 让观众「看到什么变化」 |
36
+ | `irreplaceability` | enum | `必须真人出镜` \| `优先 MG` \| `可被 B-roll 替代` \| `可降级处理` |
37
+
38
+ ### 可选
39
+
40
+ | 字段 | 类型 | 说明 |
41
+ |---|---|---|
42
+ | `handoff` | object | 按 `lane` 分型(见下)。`A_ROLL` 不应带,带了被警告忽略 |
43
+ | `aux_layers` | array | 辅助层(见下) |
44
+ | `fallback` | string | 预算/素材/AI 稳定性不足时的降级方案 |
45
+ | `callback_of` | string | 回扣对象 beat id(如 `B07`);前文意象后文重调时**不合并 beat**,在后文 beat 写此字段 |
46
+ | `note` | string | 其他对制作有帮助的信息 |
47
+
48
+ ## handoff 按 lane 分型(校验器硬查)
49
+
50
+ ```jsonc
51
+ // lane === "MG"(遗留 "RRV_MG" 读旧兼容)
52
+ "handoff": { "category": "overlay", "slug_hint": "neural-overfit", "theme": "overfitting", "bg": "paper", "duration_hint": 12 }
53
+ // duration_hint(秒)必填;slug_hint / theme / bg / category 可选(bg 底色可由底轨态推导)
54
+ // ⚠️ duration_hint 语义(2026-07-24 主理人硬性规定):只是「动画主叙事时长」参考,供生产 skill 排布节奏;
55
+ // 落轨 clip 恒占满槽位包络(track_ed − track_st),颗粒 tl 总长须 ≥ 包络、终态定格或有限循环驻留、
56
+ // 禁全局渐隐退场(gsap-emit v1 铁律⑦)。别把 duration_hint 当颗粒寿命写短。
57
+ // category(颗粒品类子类型,裁决⑩):overlay(透明叠加,叠在 A-roll/B-roll 上,不挡主体)
58
+ // | fullscreen(不透明满屏,旁白主导整帧);缺省=下游按颗粒 HTML 根 background 反推透明度。
59
+ // 二期扩 subtitle/title。供剪辑器色带按品类分层(叠加/满屏 各一行)。
60
+ // 读旧兼容:遗留品牌值 rrv-overlay/mg-fullscreen/explain-subtitle/op-ed-title 仍认。
61
+
62
+ // lane === "FILM_BROLL"
63
+ "handoff": { "queries": ["lonely person in a city apartment at night", "exhausted commuter on a crowded subway train"], "shots": 6, "per_shot_sec": 2, "exclude": ["卡通", "水印"] }
64
+ // queries(非空字符串数组)必填;shots / per_shot_sec / exclude 可选
65
+ // queries 语言规范(经真机中英 A/B 校准):
66
+ // - 用**英文长句场景描述**(5-12 词,谁+在哪+做什么),不是关键词堆叠——检索后端向量模型英文场景级命中明显更准
67
+ // - 每条 query 只装一个场景意象,多意象拆成多条
68
+ // - **避多义/字面义强的动词**("pointing" 会召回手指特写、"hunting" 召回猎人——改用 "giving suggestions in a meeting" 这类场景语义)
69
+ // - **exclude 保持中文**:负向过滤匹配的是服务端返回的中文 note,写英文会失效
70
+ // anchors(可选,关键词锚 · add-keyword-anchored-broll):[{ keyword, utterance, query }] ≤2 个/beat——
71
+ // - keyword 照原句抄写(须为所在句 text 子串);utterance 为该句 id(须在本 beat span 内);query 写该词的英文视觉描述
72
+ // - 语义:铺轨把锚 query 最高分命中钉在关键词说出时刻(句级时码内插 −0.5s 提前量);无合格命中自动降级普通槽
73
+ // - 圈「贵大奇多」类看点实词(地名/奇观/数字头衔),虚词泛词勿圈;圈定指引见 SKILL.md「关键词锚」节
74
+
75
+ // lane === "AI_DRAMA" —— 全可选(下游框架 skill /gtrk-ai-drama 有推断默认)
76
+ "handoff": { "narrative": "trauma-repetition", "theme": "freud-fort-da", "emotion_stage": "abyssal", "platform": "video-gen", "shot_count": 5 }
77
+
78
+ // lane === "A_ROLL" —— 无 handoff
79
+ ```
80
+
81
+ ## 辅助层字段(aux_layers[])
82
+
83
+ ```jsonc
84
+ {
85
+ "type": "quote-card", // 八类:quote-card | term-callout | network-diagram
86
+ // | archive-caption | pause-card | data-annotation | timeline-tag | overlay
87
+ "mount": { "from": "u0001", "to": "u0002" }, // 挂载范围三型:"same_beat" | {from,to} | {trigger:"uNNNN"}
88
+ "role": "金句提炼", // 职责:金句提炼/术语解释/关系表达/证据标注/停顿加压/情绪聚焦/回扣提示
89
+ "necessity": "强建议", // 可选:必须 | 强建议 | 建议 | 可省略
90
+ "note": "为什么加它", // 可选
91
+ "promote_condition": "若连续承担主要理解职责,则升级为下一个 beat 主层", // 可选
92
+ "fallback": "该辅助层不可做时的替代方式" // 可选
93
+ }
94
+ ```
95
+
96
+ - `mount` 里的所有 id(`from`/`to`/`trigger`)MUST 为视图中存在的 utterance id,否则硬拒。
97
+ - 辅助层是补充理解职责,不是装饰。满足升级规则时**切出新 beat 升级为主层**,别硬塞辅助层。
98
+ - 前七类是**纯建议性**(人读稿一行摘要,不承接派单);第八类 `overlay` 是**承接颗粒派单**的叠层类型(见下)。
99
+
100
+ ### `overlay` 叠层颗粒 aux(第八类,承接派单)
101
+
102
+ `overlay` = 与底轨主视觉(如 `FILM_BROLL` 电影感 B-roll)**同段共存的透明概念颗粒**——想「底轨放实拍情绪镜头、其上叠一层 MG 透明图解/金句」时用它。与前七类不同,`overlay` aux 必带 `handoff`,由 `gtrk split` 落地投影成派生颗粒(进 `dispatch.mg` + 合成 `struct_meta.split.beats`),后续 `gtrk mg` 铺出透明颗粒盖在底轨上。
103
+
104
+ ```jsonc
105
+ {
106
+ "type": "overlay",
107
+ "mount": "same_beat", // same_beat(复用当前 beat 落轨区间)| {from,to}(子区间);{trigger} 一期不支持
108
+ "role": "概念叠层图解",
109
+ "handoff": { // overlay 必带(镜像 MG lane 的 handoff)
110
+ "duration_hint": 6, // 必填正数秒(该 aux 要生成颗粒,无时长不成立;缺/非正数硬拒)
111
+ "category": "overlay", // 可选品类(软校验,非法只告警不拒;派生颗粒实际 category 恒 "overlay")
112
+ "slug_hint": "overfit-mirror", // 可选:颗粒 slug 提示
113
+ "theme": "overfitting", // 可选:主题
114
+ "bg": "transparent" // 可选:底色(叠层通常透明)
115
+ }
116
+ }
117
+ ```
118
+
119
+ - **mount 投影**:`same_beat` → 复用当前 beat 的 `track_st/track_ed`;`{from,to}` → 取该子区间存活实例的包络(全被剪则计入 `skipped` 不落)。**`{trigger}` 点挂载一期不支持**(无干净源区间,`duration_hint` 是时间线秒非源秒 → 跟随会不准):遇到计入 `skipped` + 告警,二期再补。
120
+ - **composition_id 命名**:派生颗粒 = `<工程slug>-<beatId>-aux<n>`(`n` 从 1,位置计数);同 beat 主颗粒仍是 `<工程slug>-<beatId>`。「一 beat 一 composition_id」松绑为「`composition_id` 全局唯一,一 beat 可派生主 + N 个 `-aux<n>` 颗粒」。
121
+ - **一期约束**:`FILM_BROLL` 主(底轨不产 MG 颗粒)+ 一颗 `overlay` aux 同段安全;`MG` beat 再挂 `overlay` aux 会同段两颗撞一轨(后续拆轨),先避开。
122
+
123
+ ## 落地产物(CLI 写,供参照)
124
+
125
+ - **`.gtrk` 的 `struct_meta.split`**:`{contract_version, transcript_hash, projected_at, material_id, beats:[{id, lane, span, track_st, track_ed, source_ranges, narrative, container_stage, visual_task, shrunk?, handoff}]}`——投影时刻快照。
126
+ **谁负责重投影**:CLI 的消费方命令(`gtrk mg` / `gtrk matrix`)**每次消费都自己现场重投影**(`transcript × 当刻 .gtrk`,与 `gtrk split` 落地同一段代码),所以**用户在 split 之后继续微调口播轨是常态、无需重跑 split**;只有**拆分稿本身**变了才要重跑 `gtrk split`。快照只在重投影不可行时(transcript 缺失 / 工程定位不到 / 主轨查不到口播素材)作回退值,届时命令会显式告警并在 `--json` 里标注降级。
127
+ - `material_id`:口播素材 id(= transcript.material_id),消费方脱离 transcript 文件即可定位素材。
128
+ - `beats[].source_ranges`:`[{st, ed}]` 源时基秒(v1 恒单元素 = span 源包络,含句间静默与被剪词)——**源时基不随时间线编辑漂移**,消费方以「源区间 ∩ 当刻颗粒源窗口」投影可得实时覆盖(客户端色带跟随模式即此)。
129
+ - **`split/dispatch.json`**:`{mg:[{beat, composition_id, duration, category?, theme, bg, slug_hint, track_st, track_ed, span}], film_broll:[{beat, queries, shots, per_shot_sec, exclude, track_st, track_ed, span}], ai_drama:[{beat, ...handoff, track_st, track_ed, span}]}`(去品牌化前 `mg` 键为 `rrv_mg`,消费方 `mg ?? rrv_mg` 双读)。
130
+ - **`span:{from,to}`**:该条目对应的 utterance 区间——派单**自述「派什么」**,消费方据它现场重投影,时码不再是派单唯一的权威内容。**aux 派生条目写的是 aux 自己的 span**(`mount` 为子区间时 ≠ 主 beat span);注意 aux 条目的 `beat` 字段记的仍是**主 beat id**,所以按 `beat` 回查 `struct_meta.split` 会把 aux 错算成主 beat 的整段窗口——要回查一律用 `composition_id`。
131
+ - **`track_st/track_ed` 是快照**:投影那一刻的值。老档(无 `span`)消费方会回落到 `struct_meta.split.beats[].span` 定位,照样重投影。`composition_id` = `<工程slug>-<beatId>`(MG 颗粒 `data-composition-id` 直接用它,打通 beat↔颗粒命名);`overlay` aux 派生颗粒 = `<工程slug>-<beatId>-aux<n>`(`n` 从 1)——`composition_id` 全局唯一,一 beat 可派生主 + N 个 `-aux<n>` 颗粒。
132
+ - **`split/visual-split.md`**(`--md`):由机器 JSON 单向渲染的人读稿,不回读。
133
+
134
+ ## 落地时的 dropped 处理(你要知道)
135
+
136
+ - beat 的 span 内 utterance **全部** dropped(在当前时间线被剪光)→ 该 beat 被**跳过**(不写标注、不进派单),进 result 报告。
137
+ - **部分** dropped → beat 轨道区间按存活 utterances 的包络**收缩**、标 `shrunk:true`,进报告提示人工复核。
138
+ - 所以:别把 `dropped:true` 的句子划进 span;想让某段进画面,先让用户在客户端恢复它(拉长 clip)再重导视图。