@gitruck/cli 1.2.15 → 1.3.0

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.
package/AGENT.md CHANGED
@@ -39,46 +39,36 @@
39
39
  (如用户文档目录下 agent 产品自建的目录、agent 家目录缓存、会话工作区)。
40
40
  需要引用媒体时**用原路径引用**,不做副本。
41
41
  - 临时文件(抽帧图 / 中间物等)一律放系统 temp 且**用完即删**(含中断 / 失败路径也要清干净)。
42
- - **交付物 SHALL 直写工程目录,MUST NOT 中转暂存**(2026-09-07 事故后立)。
42
+ - **交付物 SHALL 直写工程目录,MUST NOT 中转暂存**。
43
43
  产颗粒 / 产工程 / 产派单稿时,**写入路径本身**就必须是工程目录里的最终路径;
44
44
  MUST NOT 先写 agent 自有工作目录(会话工作区 / `work/` / 暂存区)再拷进工程。
45
- · **中转本身即违规**,不以「最后确实拷进去了」免责——事故当晚工程目录里的 10 个颗粒
46
- 全都正确落地了,漏出来的是那份留在 agent 工作目录里的副本。
47
- · **体积不是豁免理由**:上一条禁的是「大媒体文件」,而事故里漂掉的是 2.7–6.2 KB 的 HTML。
48
- · 与上一条的分界:抽帧图这类**不交付**的中间物走系统 temp;**要交付的东西没有暂存态**。
49
- · 直观后果:一份无主副本只要留着,迟早与工程正本漂成两版,而**两份读起来各自都自洽**,
50
- 没有任何信号提示谁是正本。
51
- - 违反本条的直观后果:用户系统盘被静默吃满——这是真机发生过的事故,不是假设。
45
+ · 中转本身即违规,体积不构成例外(体积不是豁免理由);抽帧图等不交付的中间物走系统 temp,用完即删。
46
+ · 交付物没有暂存态,避免工程正本与副本漂移。
52
47
 
53
- **在 gtrk-cli 仓库自身里跑真机走查时,追加一条(2026-08-23 立):**
48
+ **在 gtrk-cli 仓库自身里跑真机走查时:**
54
49
 
55
50
  - **仓根不落任何产物**。工作区一律 `--out .runs/<名字>`;命令回执与日志一律重定向进
56
51
  `.runs/_receipts-<日期>/`,例如
57
52
  `gtrk audio lay ... > .runs/_receipts-260823/audio-lay-out.json 2> .runs/_receipts-260823/audio-lay-stderr.log`。
58
53
  - **MUST NOT** 使用 `> foo-out.json 2> foo-stderr.log` 这类**落在仓根**的重定向,
59
54
  也 **MUST NOT** 让 `--out` 缺省落到仓根。
60
- - 直观后果:这是**公开 GitHub 仓**。仓根散落的 `*-out.json` 正文里带素材绝对路径与本机目录结构,
61
- 一次 `git add -A` 就提上去了。2026-08-06 泄漏后历史已被 filter-repo 重写过一次,代价极高。
62
- `.gitignore` 里的 `/.runs/` 与 `/*-out.json` 只是兜底;第一道闸是落点纪律本身。
63
- - 历史积压已于 2026-08-23 清空:14 个走查工作区(2.0G)+ 13 个回执统一归入 `.runs/`,
64
- 搬迁时同步改写了工程文件里 110 处绝对路径(含跨目录借用音频的交叉引用)。
55
+ - 仓根文件可能包含素材绝对路径和本机目录结构;`.gitignore` 只能兜底,第一道闸仍是落点纪律。
65
56
 
66
57
  ---
67
58
 
68
- ## 工程文件改动纪律(全局 MUST · 2026-08-25 立)
59
+ ## 工程文件改动纪律(全局 MUST)
69
60
 
70
61
  - **agent MUST NOT 裸手改 `.gtrk` JSON。** 元素级编辑(挪位置 / 改时长 / 切开 / 改参数)
71
62
  一律走 **`gtrk patch`**。
72
- - **为什么不是「小心点就行」**:`.gtrk` 一个片段的时码是**两套并存**的
63
+ - `.gtrk` 一个片段的时码是**两套并存**的
73
64
  (`clip_st`+`clip_ed` 与 `clip_st`+`duration`)。改 `duration` 不同步 `clip_ed`,
74
- **客户端 importer 优先读 `clip_ed`** ⇒ 用的是陈旧出点;而**后端 Profile A 反而不强校验它**
75
- ⇒ 没人报错。这是**静默失败**:命令说成功、你以为改了、实际没改。
65
+ **客户端 importer 优先读 `clip_ed`**,后端可能不强校验它,导致命令成功但实际出点未变。
76
66
  - 另外轨道时基端点要落在 `video_rate` 的帧边界上,浮点秒累加会漂。这两件 `gtrk patch`
77
67
  都替你做(恒等式同步 + 帧对齐 + 写前全档校验 + 原子写回 + 机器可读回执)。
78
68
  - **例外只有一个**:铺自产物的那几条既有链路(`gtrk matrix` 铺轨、`gtrk mg` 铺颗粒、
79
69
  `gtrk audio` / `gtrk subtitle` 建新轨)—— 它们只动自己新建的东西,不改既有 clip 的时码。
80
70
 
81
- ## 标定数据落点纪律(全局 MUST · 2026-08-29 立 · tighten-distribution-surface)
71
+ ## 标定数据落点纪律(全局 MUST)
82
72
 
83
73
  **新增**的实测标定数据 MUST 写进对应 change 的 `design.md` 附录,MUST NOT 写进代码注释或
84
74
  随包分发的 `skills/*/SKILL.md`。
@@ -93,8 +83,7 @@
93
83
  丑话属于「怎么用」,是使用者的决策依据;
94
84
  ③ **算法本体**——公式与判定式本身就是代码在做的事,注释是它的可读投影。
95
85
  - **代码注释的目标口径**:只讲**是什么 + 怎么用**,不讲**为什么是这个值**。
96
- - **存量不清洗**(主理人 260829 拍板):既有注释里的标定数据已随公开镜像与 npm 发布出去,
97
- 删它们保护为零、却净损失维护者上下文,且那两个文件是承重墙密集区、误伤代价高。
86
+ - **存量不清洗**:既有注释里的标定数据已经随公开镜像与 npm 发布;删除它们收益有限,且容易损失维护上下文。
98
87
  本纪律**只管新增**。已知的存量标定已在 `tighten-distribution-surface/design.md 附录 A`
99
88
  留档(含「改值前必须知道什么」速查表)——**改那些常量前先读它**。
100
89
 
@@ -235,7 +224,7 @@ gtrk transcript <本地视频.mp4> --json # 转成一个含总结/时
235
224
  | 参数 | 作用 | 缺省 |
236
225
  |---|---|---|
237
226
  | `<taskId>`(位置参数) | 任务 id | 必填 |
238
- | `-o, --out <dir>` | 产物目录 | **必填**(2026-09-08 起无缺省;`--out .` = 当前目录本身) |
227
+ | `-o, --out <dir>` | 产物目录 | **必填**(无缺省;`--out .` = 当前目录本身) |
239
228
  | `--render` | 额外本地渲染成片(需原毛片仍在 gtrk 内嵌路径 + ffmpeg) | 关 |
240
229
  | `--jianying-draft-dir` / `--ffmpeg-path` / `--crf` / `--codec` / `--no-open` / `--json` | 同 `oralcut` | — |
241
230
 
@@ -274,7 +263,7 @@ gtrk split <拆分稿.json> --project <目录> --md --json # ⑤ 校验落地
274
263
  | `--words` | 视图模式附字级明细(缺省只出句级) |
275
264
 
276
265
  **关键行为(agent 需知):**
277
- - **时码恒挂源时基、每次发起现场投影**:用户手调切点后重导视图即跟随;此前被剪、现落回 clip 的句子自动复活,无需重跑转写。「拖入已剪好成片」= 恒等投影,同一套逻辑。
266
+ - **时码恒挂源时基、每次发起现场投影**:用户手调切点后重导视图即跟随;已被剪掉、现落回 clip 的句子自动复活,无需重跑转写。「拖入已剪好成片」= 恒等投影,同一套逻辑。
278
267
  - **dispatch 的时码是快照,但消费侧会现场重投影**:`dispatch.json` 里的 `track_st/track_ed` 只在投影那一刻成立;`gtrk mg` / `gtrk matrix` **每次消费都用 `transcript × 当刻 .gtrk` 重算窗口**(与 split 落地同一段代码,构造性同源),所以**用户在 split 之后继续微调口播轨无需重跑 split**——只有**拆分稿本身**变了才要重跑。派单条目另带 `span:{from,to}` 自述「派什么」(aux 条目写 aux 自己的 span)。重投影不可行时(transcript 缺失 / 工程定位不到 / 主轨查不到口播素材)**降级用快照 + 显式告警 + `--json` 标 `reprojection.degraded`**,绝不硬崩。
279
268
  - **拆分稿零时码、id 区间引用**:beat 的文稿范围 = `span:{from:"u0007",to:"u0011"}`(utterance id 区间),**绝不抄原句文字、绝不自造时码**(防 LLM 幻觉)。幻觉 id / 区间倒序 / 跨 beat 重叠 / `transcript_hash` 错版 → **硬拒、非 0 退出、零副作用**。
280
269
  - **dropped 处理**:beat 的 span 内 utterance 全被剪 → 跳过该 beat 并入报告;部分被剪 → 按存活句包络收缩、标 `shrunk`。均不使命令失败。
package/CHANGELOG.md CHANGED
@@ -11,13 +11,17 @@
11
11
 
12
12
  ## 未发布
13
13
 
14
+ ## 1.3.0(2026-09-28)
15
+
14
16
  - 视频去水印不再默认 FFmpeg:Agent 必须在处理前说明快速模糊与慢速内容修复的效果代价,等待用户选模式;`purify run/apply`、人工框和 `tool video_purify` 缺少显式模式时在上传前停止。仅检测、编辑和空清单不受影响;旧记录未建处理单时需补选模式,已建单继续原任务。失败后不得擅自改用快速或本地 FFmpeg。
15
17
 
16
- - `tool --batch` 补齐整批费用预估:标准价/超额价积分与额度包单位数分别汇总,按分钟收费先本地探时长,逐任务取整后求和;跳过项不计费、不探测。价格或计量不可用时明确说明无法预估。
17
-
18
- - `ai-drama lay` 成功回轨后提示先显式指定口播音频运行 `patch snap --dry-run` 检查,再执行吸附并用 `patch seal` 补缝;只提示,不自动编辑。
19
-
20
- ## 1.2.13(2026-09-22,AI 漫剧工具批次补记)
18
+ - `tool --batch` 补齐整批费用预估:标准价/超额价积分与额度包单位数分别汇总,按分钟收费先本地探时长,逐任务取整后求和;跳过项不计费、不探测。价格或计量不可用时明确说明无法预估。
19
+
20
+ - `ai-drama lay` 成功回轨后提示先显式指定口播音频运行 `patch snap --dry-run` 检查,再执行吸附并用 `patch seal` 补缝;只提示,不自动编辑。
21
+
22
+ - 清理随包 skills、共享 Agent 规则、GSAP handoff 契约和双语参考文档中的历史叙事;当前执行规则不变,GSAP 证据保留在维护者附录。
23
+
24
+ ## 1.2.13(2026-09-22,AI 漫剧工具批次补记)
21
25
 
22
26
  > npm 发布时点为 2026-09-22 08:26:53 UTC。本节补记这批已实现能力;不表示其全部 OpenSpec 已归档。后续音轨识别、素材内容寻址和镜头锚定仍在独立待办中。
23
27
 
@@ -12,3 +12,5 @@
12
12
  | 契约 | 版本 | 适用 handoff | 文档 |
13
13
  |---|---|---|---|
14
14
  | gsap-emit(HTML 动画颗粒逐帧 seek 合规) | v1 | MG(去品牌化前 RRV_MG,消费方查表前归一) | [gsap-emit-v1.md](gsap-emit-v1.md) |
15
+
16
+ 维护者证据附录:[`gsap-emit-v1-evidence.md`](gsap-emit-v1-evidence.md)。该文件不属于 agent 执行时的必读契约。
@@ -0,0 +1,196 @@
1
+ # gsap-emit v1 · 证据附录
2
+
3
+ 本文件供契约维护者追溯实验、版本和阈值来源,不是 agent 执行时的必读文档。当前有效规则以 [`gsap-emit-v1.md`](gsap-emit-v1.md) 为准;本附录中的日期、样本和版本不能覆盖正文契约。
4
+
5
+ ---
6
+
7
+ ## 回调与 seek 语义(2026-07-26 增补 · 补此前留白)
8
+
9
+ > **一句话**:颗粒**可以**用时间线回调(`onUpdate` 等)驱动画面;**保证这些回调在定帧时被触发是渲染引擎侧的义务**,不是颗粒作者的义务。
10
+ > 本节是该主题的**唯一口径来源**——契约引用(`skills/gtrk-style-maker/references/contracts-ref.md`)与消费侧检查(`gtrk mg lint`)的文案都指向这里,不得各自表述。
11
+
12
+ ### 一、GSAP 3.13.0 实测事实(写死在此,免后来者重测)
13
+
14
+ 复现方式:拉铁律⑤指定 CDN 的 `gsap.min.js` 到本地,Node `vm` 里造 `paused` timeline + proxy 对象 + 计数回调,**每种定位方式各新建一条 timeline 单独跑**(回调计数互不串)。
15
+
16
+ **样本一**——10s、`ease:"none"` 的单条 tween(`{v:0}` → `{v:100}`),分别 seek 到 t=5(中途)与 t=10(末端):
17
+
18
+ | 定位方式 | `onUpdate` / `onStart` | `onComplete` | 补间目标属性 |
19
+ |---|---|---|---|
20
+ | `tl.seek(t)`(默认,`suppressEvents` 缺省为 `true`) | **不触发** | **不触发**——连 `seek(10)`(到末端)也不触发 | 已更新(t=5 → `v=50.00`;t=10 → `v=100.00`) |
21
+ | `tl.seek(t, true)` | 不触发 | 不触发 | 已更新 |
22
+ | `tl.seek(t, false)` | 触发 | `seek(10,false)` 触发;`seek(5,false)` 不触发 | 已更新 |
23
+ | `tl.time(t)` / `tl.progress(p)` / `tl.totalTime(t)` | 触发 | 同上(按是否到末端) | 已更新 |
24
+
25
+ ⚠️ **`onComplete` 那两行必须分清**:默认 seek 下它**到末端也不触发**,这才是「被抑制」的证据;而 `false` 模式下 `seek(5,false)` 的 `onComplete` 不触发,只是「补间尚未走完」的正常语义。混为一谈,后来者会拿后者误判成「垫片无效」。
26
+
27
+ **样本二(含真实 DOM 写入 · 引擎侧条款的直接依据)**——同一 t=1.0 定帧点,补间在 t=1.0 处的目标属性期望值 75.0,`onUpdate` 体内做一次真实 DOM 写入:
28
+
29
+ | 定位方式(同一 t=1.0 定帧点) | `onUpdate` 触发次数 | 补间目标属性 | 回调内的 DOM 写入 |
30
+ |---|---|---|---|
31
+ | `tl.seek(1.0)`(默认) | **0 次** | 已更新为 **75.0** | **未执行** |
32
+ | `tl.seek(1.0, false)` | 1 次 | 75.0 | 正常 |
33
+ | `tl.time(1.0)` | 1 次 | 75.0 | 正常 |
34
+ | `tl.progress(0.5)` | 1 次 | 75.0 | 正常 |
35
+
36
+ 要害是**「值更新了、回调没跑」**:补间目标对象的属性照常插值,但写在 `onUpdate` 里的 DOM 写入一次都不执行。所以这种翻车**不是黑屏,是画面定在初始态**——本地播放器与客户端预览都完全正常,比黑屏更难发现。
37
+
38
+ 样本二同时给出条款一的**可行性依据**:三种「不抑制」写法(`seek(t,false)` / `time(t)` / `progress(p)`)行为**完全一致**,故对引擎侧的要求**可实现且不挑实现**——引擎爱用哪种用哪种,只要不是裸 `seek(t)`。
39
+
40
+ ### 二、条款
41
+
42
+ 1. **引擎侧(MUST)**:渲染引擎定帧时 **MUST 保证 GSAP 时间线回调可达**——MUST 用 `seek(t, false)` 或 `time(t)` / `progress(p)` / `totalTime(t)`,**MUST NOT 用默认的 `seek(t)`**。违反后果:补间目标属性照常更新、回调内的 DOM 写入不执行 → 画面**定在初始态而非黑屏**,本地播放器与客户端预览均看不出异常。
43
+ 2. **颗粒侧(合规声明)**:颗粒**可以**用时间线回调(`onUpdate` / `onStart` / `onComplete` / `onRepeat`)写 DOM / 属性来驱动画面——这是**合规**写法(相机推进、数值读数这类效果用纯属性补间难以表达)。其可达性由条款 1 承担;契约 **MUST NOT** 反过来要求颗粒作者自行保证。
44
+ 3. **颗粒侧(不应)**:颗粒**不应**在运行时覆写引擎所调用的 API——重新赋值 `tl.seek`、或把 `window.__timelines[…]` 换成包装对象。两条实测理由:① 覆写会推翻引擎**显式**传入的 `seek(t, true)`(实测:打上垫片后 `seek(5)` 与 `seek(6, true)` 两次调用回调都触发),颗粒无权静默否决引擎的意图;② 垫片只作用于 `seek`,引擎改走 `time()` / `progress()` 时**完全失效**,而作者不会知道。
45
+ 已存在的垫片属**过渡态**:**新颗粒不应再加**。**2026-07-26 更新**——条款 1 的前提已经真引擎核实(见下「三」),垫片赖以存在的「真空期」已结束,故已存在的垫片**可择期清理**(清理是**可做**、不是 MUST 做;删后须重跑 lint 并**重渲复验**)。垫片留着也无害:实测引擎既然本就不抑制回调,垫片对画面结果无影响,只会被 lint 记一条非致命的 `x-engine-api-override`。
46
+ 4. **作者侧应知(这不是甩锅)**:作者 MUST 知晓——回调可达性的保证方是**引擎侧**,且该保证当前的核实状态见下「三」(2026-07-26 起为**已核实(行为层)· 绑定引擎 0.6.101**)。`gtrk mg lint` 会对「回调驱动画面且无任何兜底」的颗粒给一条**非致命**提醒,那是**哨兵**(引擎换实现或失守时有人喊一声),**不是**「请作者自行保证 seek 下回调可达」——**核实之后哨兵照留**,因为结论绑死引擎版本,换版即须重测。
47
+
48
+ ### 三、核实状态:**已核实(行为层)· 2026-07-26 · 绑定渲染引擎 producer `0.6.101`**
49
+
50
+ **把某条引擎行为写成 MUST,MUST NOT 被当作它已被核实**——二者在本节分别成文。本小节记的是**核实到了什么、以及没核实到什么**。
51
+
52
+ **结论:真渲染引擎在定帧时 `onUpdate` 回调可达,条款 1 的前提成立。** 结论**绑定上述引擎版本**,换版即失效、须重测。
53
+
54
+ - **核实方式(真引擎,非本地无头模拟)**:造一颗最小颗粒 `seekcb-probe`,**不打任何 seek 垫片**,画面正中的大号数字**只**由一条 tween 的 `onUpdate` 写入(proxy `{v:0}` → `480`,`ease:"none"`,16s),初值静态写死 `CB 000`;同屏并排一组**纯属性补间**对照物(方块横移 + 进度条拉长,均无回调),刻度尺与回调数字**同单位 0..480**,故单帧之内即可比对「应该是多少」与「实际是多少」。该颗粒先过 `gtrk mg lint`(`lint.ok=true`,`opaque=true`,只出 `x-callback-driven` 哨兵、无 `x-engine-api-override`),排除「因不合规才没渲」。走生产同款装配(`CompositionRender` 整轨路径 / 同底轨 `bed.mp4` / 1920×1080 / fps=60 / 15.97s / 958 帧分片 13 chunk)。
55
+ - **实测结果(三帧,肉眼判读整帧 PNG)**:
56
+
57
+ | 抽帧时刻 | 回调驱动的数字(onUpdate 唯一驱动) | 纯属性补间对照物 | 期望值 |
58
+ |---|---|---|---|
59
+ | t=2s | **CB 060** | 进度条/方块 @ 60 | 060 |
60
+ | t=8s | **CB 240** | 进度条/方块 @ 240 | 240 |
61
+ | t=14s | **CB 420** | 进度条/方块 @ 420 | 420 |
62
+
63
+ 三帧数字**各不相同**、**无一帧停在初值 `CB 000`**,且**逐帧与同单位对照物精确重合**——即回调不仅被触发,还是在**当前帧对应的时间点**上触发的(不是滞后一帧的陈值)。对照物同时移动,排除「整颗没渲/时间线没被定位」这一混淆解释。
64
+ - **证据留档**:三帧整帧 PNG、成片、颗粒与渲染脚本一并留档,落点见本仓 change `define-seek-suppress-events-contract` 的工件(复现件的本地路径与文件名不进入分发契约)。引擎版本取自渲染日志自报的 producer `0.6.101`。
65
+ - **⚠️ 本次核实的边界(MUST NOT 越界引用)**:核实的是**可观测行为**(回调可达),**不是调用形态**。引擎仍是无源码第三方包,本轮**没有**读到定帧调用点,故**无法区分**它走的是 `seek(t,false)` / `time(t)` / `progress(p)`,还是压根不经 GSAP 定位 API 的自有推进方式。条款 1 里那串 API 白名单仍是**应然的实现约束**,只有「回调 MUST 可达」这个**结果**被真机背书。调用形态的核实仍由 gitruck-infra 侧联动 change `link-guarantee-seek-callback-reachability` 承接(读调用点 + 把「纯回调驱动无垫片颗粒渲两帧、像素 MUST 不同」挂进引擎版本变更门禁)。
66
+ - **旁证(本轮之前的间接证据,保留备查)**:gitruck-infra 自家 9 个 music_visualizer 模板 **9/9** 把整块画面挂在单条 tween 的 `onUpdate` 上、且 **0/9** 带任何垫片,走的正是同一渲染内核,而 `gtrk music-visualizer` 是**已上线**能力——若引擎默认抑制回调,这 9 个模板早该渲成静止首帧。本仓 exemplar b06/b07/b08 同理。本轮直接核实**与旁证同向**。
67
+ - **假设失效的后果(哨兵为何 MUST 留)**:结论绑定 `0.6.101`;引擎升版换调用方式 → 全部回调驱动型颗粒(MG 与 music_visualizer 模板)**一起静默冻结**,lint 全绿、退出码 0、无任何告警。故 `gtrk mg lint` 的 `x-callback-driven` 哨兵(条款 4)**MUST NOT 因本次核实而撤**——它防的正是「换版后无人喊一声」。
68
+
69
+ ### 四、连带风险:回调可达 = 逐帧反复触发
70
+
71
+ 条款 1 的另一面:逐帧 scrub 时 `onComplete` / `onStart` / `onRepeat` 会**反复触发**(每帧一次)。故颗粒 **MUST NOT** 把「只跑一次」的逻辑写进回调——累加计数、`push` 进数组、一次性 DOM 插入、抽样。那会把「静默冻结」换成「静默错乱」。
72
+
73
+ **2026-07-26 起这条从「假设的另一面」变成「已确证的现实风险」**:上「三」已实测该引擎**确实**在逐帧定位时触发回调,故本条不是防患于未然,而是**当下就在生效**的约束。
74
+
75
+ **推荐写法**:回调做成**幂等**的——每次都从补间状态**重算**整个画面,不依赖上一次的结果(真机与 exemplar 的 `render()` / `apply()` / `paint()` 均如此)。
76
+
77
+ ### 五、优先级
78
+
79
+ **本节口径优先于任何栏目指南的招式建议。** 栏目指南若与本节冲突,以本节为准。(当前二者同向:栏目指南推荐的 `onUpdate` 驱动写法在本节下**合规**,作坊侧**无需修订**——本节不向作坊侧派发任何待办。此条照写不误,它防的是将来的分歧。)
80
+
81
+ ---
82
+
83
+ ### 铁律 4「实心底下沉子层」的真机证据锚(2026-07-26)
84
+
85
+ 本条断言的是**渲染引擎行为**(「根元素的绘制属性在挂载时被丢弃」),故按契约库要求附可追溯证据锚:
86
+
87
+ - **结论**:根 `style` 的 `background` **不落成像素**;同一颗粒把同一底色改写到根下首个全幅子层则**满屏落地并盖住底轨**。
88
+ - **实验日期 / 机器**:2026-07-26 · 真机(生产同款渲染主机;真渲,非本地无头模拟)。
89
+ - **引擎版本口径**:渲染引擎 CLI 与 producer 同版 `0.6.101` · 无头浏览器内核 `131.x`。
90
+ - **设计**:同颗粒母本造两个变体,**唯一变量 = 实心底摆在根 `style` 还是根下首个全幅子层**,其余逐字节相同;
91
+ 底色临时取高饱和标志色以便与「根合成兜底黑」区分;底轨用一段有明显画面、非黑的真人镜头;抽同一时间点 `t=8.0s` 的帧,
92
+ 取四角 `crop=40:40` 于 `(20,20) (1860,20) (20,1020) (1860,1020)` 后 `scale=1:1` 读像素。
93
+ - **观测**(整轨拆分渲染路径,两格同素材同引擎同批)。
94
+ ⚠️ 下表的六位数字是**抽帧读出的 RGB 像素读数**(实验观测),**不是本契约规定的任何底色**——
95
+ 轴一边界照旧:契约不点名任何色值,底色取值永远由调用方栏目决定:
96
+
97
+ | 变体 | 四角像素 | 判读 |
98
+ |---|---|---|
99
+ | 实心底写**根 `style`** | `dfdad4 / fafcfb / 4e4f52 / f9fbfb` | ≈ 底轨基线 → **底丢失、底轨透出** |
100
+ | 实心底写**根下首个全幅子层** | `01ff81 / 00fe80 / 01fd80 / 01fd80` | ≈ 标志色 → **底存活、满屏盖住底轨** |
101
+ | 底轨本身(阴性对照) | `e0dbd4 / fbfdfc / 4f5052 / fbfdfd` | 四角始终高亮非黑,对照有效 |
102
+
103
+ - **阳性对照(关键,排除平凡解)**:「写根」那格的整帧里颗粒**前景元素完整渲出**(标题文字、网格、连线、色块都在)——
104
+ 所以它**不是「颗粒没渲上」,而是「颗粒渲上了、根 `background` 被丢掉」**。缺这一步,两种情况在像素上同解。
105
+ - **复现方式**:造上述两变体 → 同一批走整轨拆分渲染 → 按上「设计」段的抽帧与四角取样口径(`t=8.0s` 单帧 / `crop=40:40` / `scale=1:1`)取样,
106
+ 再以 RGB24 原始字节读出四角的十六进制像素值。取样工具与复现件的本地路径不进入分发契约(同铁律 8 证据锚口径)。
107
+ - **历史**:本条现象最早由创作侧于 **2026-07-15** 记载(一颗满屏颗粒的根 `background` 丢帧、成片只剩浮空面板),
108
+ 当时未进框架契约,框架正本反而长期要求「写在根上」——2026-07-26 的实验复现并坐实了该记载,本条据此改写。
109
+ - **相关跨仓 change**:`gitruck-cli` / `align-particle-solid-backdrop-contract`(本条的来源);
110
+ `gitruck-infra` / `add-html-animate-opaque-fullscreen-cover`(**另一个独立问题**:渲染侧要不要按 `opaque` 位替颗粒兜一层黑底)。
111
+ ⚠️ 两者**互不依赖**:上表的观测正是在后者**未 apply** 时取得的——即**本条的修法(下沉子层)当场生效,不需要渲染侧任何配合**。
112
+
113
+ ### 铁律 8「重复图元合并」的真机证据锚(2026-07-26)
114
+
115
+ 本条断言的是一条**作者侧规避写法**及其在真渲染中的效果,不断言已知触发轴。证据锚如下:
116
+
117
+ - **结论**:同一故障样本把 37 条满幅 `<line>` 合为一条 `<path>` 多子路径后,目标画面逐像素不变,横带重复率由 **65%~68% 降至 2%**;规避当场有效,但合并同时改变了图元数、DOM 结构与栅格化路径,故本实验**不能证明是哪一个变量生效**。
118
+ - **实验日期 / 机器**:2026-07-26 · 真机(生产同款渲染主机;真渲,非本地无头模拟)。
119
+ - **引擎版本口径**:渲染引擎 CLI 与 producer 同版 `0.6.101` · 无头浏览器内核 `131.x`。
120
+ - **二分设计**:以同一颗粒为母本逐项只改一个构建块,每个变体各做一次真渲;每格抽取 168 帧,按等高横带间的重复像素统计复现率。装配路径、分辨率、帧率、底轨与其余颗粒代码保持一致。
121
+ - **范围限定(硬约束)**:下表全部是**同一颗粒内部**的二分结果,**MUST NOT 跨颗粒外推**;它只能说明这些改动在该颗粒内与复现率同向变化,不能推出「元素数少就安全」或任何数字门槛。
122
+
123
+ | 同一颗粒内的变体 | 重复率 | 限定读法 |
124
+ |---|---:|---|
125
+ | 原件:背景网格为 37 条满幅 `<line>` | **65%~68%**(复跑一致) | 故障基线 |
126
+ | 37 条 `<line>` 合为一条 `<path>` 多子路径 | **2%** | 本条规避正例;目标画面逐像素不变 |
127
+ | 整块删除背景网格 | **2%** | 与合并同档;只说明该块在本颗粒内参与复现 |
128
+ | 删除两个静态术语文本块 | **0%~1%** | 删除任一块负载都退烧;作用域仅限本颗粒,机制未知 |
129
+ | 删除三行静态标签文本块 | **0%~1%** | 同上 |
130
+ | 换字体族 / 去斜体 / 关闭 3D 加速 / 改入场位移 / 把文字改为 SVG `<text>` / 给根加变换提示 / 把网格改静态 | **仍为 65%+** | 均无效 |
131
+ | 增加满屏失效脉冲层 | **14%** | 作者侧强制全幅失效仍不能根治 |
132
+ | 极简结构(20 个静态 `<div>` + 1 个网格) | **0%** | 空载变体不复现;不得外推为通用预算 |
133
+
134
+ - **阳性对照(排除平凡解)**:合并版仍完整绘制与原件相同的整张网格,逐像素对拍一致;它不是「把内容删没了所以不重复」。同一颗粒内另有 24 条局部短线在合并版中继续保留,故 24 与 37 也 **MUST NOT** 被写成安全 / 故障分界。
135
+ - **跨颗粒反证(同批全量体检)**:同装配、同引擎、同机完成 **21 颗粒 + 六 beat 同页聚合,共 24 次渲染 / 约 22,000 帧**。这些结果专门限制上表的外推范围:
136
+
137
+ | 样本 | 真渲结果 | 可否证的候选轴 |
138
+ |---|---:|---|
139
+ | 另一密阵样本:884 条短划、全颗共 921 个绘制图元 | **0.0% 脏帧** | 图元总数、同父同类聚簇 |
140
+ | 六 beat 同页聚合:约 1,400 个绘制图元 | **0.0% 脏帧** | 同页累积负载 |
141
+ | 当前修复版样本(回归 / 阴性对照) | **0.0% 脏帧** | 规避在整轨分片路径下仍稳 |
142
+ | 未修版样本(阳性对照) | **70.3% 脏帧** | 缺陷仍活且可稳定复现 |
143
+
144
+ **真实触发轴至今未知**;当前已否证的候选轴 = **图元总数 / 同页累积负载 / 同父同类聚簇**。上表中「921 个图元干净」与「较少图元的阳性对照中招」同时成立,因此数字方向不存在可据此写入契约的安全门槛。
145
+ - **复现方式**:从同一母本生成上述单变量变体 → 走生产同款整轨分片渲染 → 对每格 168 帧计算等高横带间的重复率并抽取高分帧肉眼复核;再以同一口径跑 21 颗全量语料、六 beat 同页聚合、修复版阴性对照与未修版阳性对照。复现件的本地路径与文件名不进入分发契约。
146
+ - **相关 change / 根治状态**:本仓 `add-particle-primitive-merge-law` 收录作者侧规避;渲染管线侧根治**未立项(2026-07-26,本 change 实施会话按非目标不代提;待主理人另行决定)**。根治上线并经真机确认后,按铁律 8 的预案把 MUST 降为 SHOULD。
147
+
148
+ ---
149
+
150
+ ### 证据锚(只收有出处的数;每条带测量日期 + 语料标注)
151
+
152
+ - **测量日期**:2026-07-30。**版本口径**:渲染引擎 CLI 与 producer 同版 `0.7.82` · 无头浏览器内核 `152.x`。
153
+ 测量在真机(生产同款渲染主机)取得,非本地无头模拟。
154
+ - **现网既有栏目语料(21 颗生产颗粒)**:去掉真卷积滤镜的可省墙钟 **0~3.1%**——即**本节对现有语料近似零收益**,
155
+ 它立在这里是**前置门**(防止大批带滤镜的新语料进渲染管线后整批返工),**不是**提速手段。
156
+ - ⚠️ **「去滤镜省墙钟」依颗粒形态而定,MUST NOT 一概而论**(2026-08-06 真机同颗粒对照,**测出方向相反的两侧**):
157
+ | 形态 | 去滤镜后墙钟 | 产物字节 | 方向 |
158
+ |---|---|---|---|
159
+ | **局部**滤镜、底下**平坦**(现网真颗粒:790×290 衬底 + 词光) | 51.66s → **46.10s(省 10.76%)** | −62% | **省** |
160
+ | **整幅**滤镜、底下**带抖动渐变** | 38.07s → **69.70s(慢 83%)** | +29%(356 MB → 459 MB) | **亏** |
161
+ **机制是同一条**:本管线的墙钟由 **capture + encode** 主导(capture 约占单次 CLI 全程 **89%**),
162
+ 而 `blur` **抹掉高频** ⇒ 每帧截图与 ProRes 4444 编码都更便宜。
163
+ ⇒ **决定墙钟的是「去掉滤镜后画面频谱的变化方向」,不是「有没有滤镜」**——
164
+ 去滤镜让画面变平就省,让高频回来就亏。
165
+ 📌 **这条不动摇本节的立项与条文**:本节真正要抓的是**每帧重卷积导致缓存失效**那一类
166
+ (补间驱动 `filter` / 静态 filter 而 `transform` 被补间驱动),它们是**同一颗粒内的对照**、方向确定为正
167
+ (实测 **+36.2%** / **+42.7%**),与「去不去某个滤镜」是两个不同的问题。
168
+ - **单次误用的止损量级(同一颗粒内对照)**:**1.3~3.3×**。
169
+ - **同一颗粒内的形态对照(2026-08-06 真机,1920×1080 / 180 帧 / 30fps,每档 3 次取中位数)**——
170
+ 这组才是本节条文的直接依据(**控制内容不变、只换 filter 的用法**):
171
+ | 形态 | 中位墙钟 | 相对整幅静态 blur |
172
+ |---|---|---|
173
+ | 整幅**静态** `blur(24px)`(基准) | 38.07s | — |
174
+ | `gsap.set` **只设一次** filter | 38.29s | **+0.6%(噪声内,产物逐字节相同)** ⇒ 等价于静态 |
175
+ | 整幅 blur **被补间驱动**(8→40px) | 51.86s | **+36.2%** |
176
+ | **静态** filter、其 `transform` **被补间驱动** | 54.32s | **+42.7%(最贵的一档)** |
177
+ - **滤镜重语料(技法颗粒,单颗 646 帧)**:**7.0×**(339.6s → 48.3s)。
178
+ ⚠️ 该数**只对该语料成立**,MUST NOT 外推成通用提速承诺。
179
+ - **消费侧沉默不等于便宜**:`gtrk mg lint` 的四个成本项(`c-filter-animated` / `c-filter-static-fullbleed` /
180
+ **`c-filter-static-transformed`**(2026-08-06 增补,覆盖上面那条 +42.7% 的漏报面)/ `c-filter-indeterminate`)
181
+ 是**形态提示**,**当期一律非致命、不拦铺轨**;没报**不代表**这颗渲得快——
182
+ 真判据永远是**真渲染出片计时**。
183
+ - **致命性的升级触发器(登记在此,免得日后凭印象改)**:把 `c-filter-animated` 提为**致命**
184
+ SHALL 另走一个独立 change,且 SHALL 同时满足两项前提——① 「滤镜重语料批量进渲染管线」那条路线**已立项**;
185
+ ② 提级前对现网生产语料**全量复扫且零命中**(复扫在生产颗粒上命中 > 0 即 MUST NOT 提级)。
186
+ 触发一次评估的时机 = 上述路线立项 **或** 本节首次改版,以先到者为准。
187
+ **MUST NOT** 以「规范就该严」为由径直提级,也 **MUST NOT** 把致命性做成可现场翻转的运行期开关。
188
+
189
+ ### 根治登记
190
+
191
+ - **① 这是降本规范、不是缺陷规避**:命中项的画面本身是对的,逐帧也正确,只是每帧贵。
192
+ - **② 成本的根在渲染管线侧**:逐帧路径走**软件光栅**(无图形硬件加速),卷积按面积×半径吃 CPU。
193
+ - **③ 根治状态 = 明确不立项(2026-07-30)**:改走图形硬件加速路径会破坏「逐帧确定性」与「产出端版本对齐」这两项前提
194
+ (异构机器还会破坏分片与单次的产物等价),渲染侧调研已把它列为**已排除项**。故本节以作者侧写法收敛,不等渲染侧。
195
+ - **④ 根治后的处置预案**:若渲染侧将来换掉光栅路径并经真机复测确认成本塌陷,本节由 MUST NOT/SHOULD **降为提示**,
196
+ 并保留「本节曾于 2026-07-30、本证据锚所载版本口径下作为降本规范所必需」的历史记录。