Ver código fonte

fix: darwin审查修复——双judge盲评+回归QA挑出的9处问题

- hook Bug1/2:echo类命令误伤+sed BRE致cd目标提取失效(四场景复测通过);补拦render-narration.sh和npm run render
- SKILL.md:direction-approved落档动作接入Fallback Phase 5(发现A)、异常表「直接做」纳入豁免落档(C)、deck三版各出2页代表页(D)、术语统一+二选一笔误(B)、20-30s导演稿边界(Judge B#6)、弱runtime不豁免gate(#3)
- hyperframes-backend:pitfalls数字打架修正、解说长视频选型裁决行、可移植性表述(#1/#2/#5)
- pitfalls自查清单补#21

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
alchain 1 mês atrás
pai
commit
6623ff01cf

+ 7 - 7
SKILL.md

@@ -191,7 +191,7 @@ description: 花叔Design——用HTML做高保真原型、幻灯片、动画、
 - 用户已经说清楚要什么("做个 Apple Silicon 风格的发布会动画")→ 直接进 Junior Designer 流程
 - 小修小补、明确的工具调用("帮我把这段 HTML 变成 PDF")→ skip
 
-不确定就用最轻量版:**列出 3 个差异化方向让用户二选一,不展开不生成**——尊重用户节奏。
+不确定就用最轻量版:**列出 3 个差异化方向让用户,不展开不生成**——尊重用户节奏。
 
 ### 完整流程(7 个 Phase,顺序执行;Phase 3.5 是图片前置半步)
 
@@ -266,7 +266,7 @@ description: 花叔Design——用HTML做高保真原型、幻灯片、动画、
 - **三版的布局骨架必须互异**:导航/构图/内容区结构至少一项结构性不同,不许两版共用同一骨架只换色换字体(盲测实锤:共用骨架会被评审一眼识破「换皮」)
 - 🔴 **可读性硬底线(任何风格温度都不豁免,包括「奢侈留白」的安静派)**:正文 ≥14px、标签/注释 ≥12px、正文对比度 ≥4.5:1;留白必须是**构图**(首屏有明确视觉锚点,视线有落点),不是内容缺席。盲测实锤:安静派做过头 = 「大片死白+微缩字号,第一眼像页面渲染坏了」,直接输给普通 baseline
 - 纯 HTML/CSS 单文件;**内容必需的图用 Phase 3.5 取的真图**(三版共用),仅装饰/抽象图才用 CSS 几何/SVG/纯色块,绝不留空占位
-- 🎞️ **PPT / deck 场景必走 deck 模板(绝不写竖向平铺长页!)**:每页独立 `<section>`(1920×1080)套 `assets/deck_index.html` 外壳,三版只换视觉风格、deck 骨架统一(架构规则与概览墙细节见「技术红线」+ `references/slide-decks.md`)。截图按**单页** 1920×1080 截;**单页内容绝不自带页码/进度标记**——页码由 deck 外壳统一承载(实测出过「02/03」+「6/16」双页码打架)
+- 🎞️ **PPT / deck 场景必走 deck 模板(绝不写竖向平铺长页!)**:每页独立 `<section>`(1920×1080)套 `assets/deck_index.html` 外壳,三版只换视觉风格、deck 骨架统一(架构规则与概览墙细节见「技术红线」+ `references/slide-decks.md`)。截图按**单页** 1920×1080 截;**单页内容绝不自带页码/进度标记**——页码由 deck 外壳统一承载(实测出过「02/03」+「6/16」双页码打架)。**多页deck走Fallback时,三版各出2页代表页**(兼作deck链的showcase),选定方向后再批量其余页
 - 存当前**项目目录**(`项目名/design-demos/[逻辑名].html`)——❌ 禁 `_temp/`(花叔铁律)
 - 截图:`npx playwright screenshot file:///path.html out.png --viewport-size=1440,900`(PPT 用 1920,1080)
 - ✅ **产出自检(防偷懒,进 Phase 5 前必查)**:确认 `design-demos/` 下真有 **3 个 .html**——少于 3 个 = 没走完三套逻辑,补齐再往下,不许只做一版交差
@@ -275,7 +275,7 @@ description: 花叔Design——用HTML做高保真原型、幻灯片、动画、
 > 仅当用户**已确认有生图能力**时,AI 生成型风格才走 `huashu-gpt-image`(见 `design-styles.md` 尾部「AI 生图专用风格」);否则一律 HTML。
 > 完整 40 种风格库(网页 20+PPT 20,含还原度/温度/HTML 实现/开源字体)→ `references/design-styles.md`。
 
-**Phase 5 · 用户基于「看到的真实视觉」选择**(第一次有效选择):看完三版真实截图,选一版深化 / 混合("轮盘版的配色 + 设计师版的布局")/ 微调 / 全部重来 → 重跑三套逻辑。
+**Phase 5 · 用户基于「看到的真实视觉」选择**(第一次有效选择):看完三版真实截图,选一版深化 / 混合("轮盘版的配色 + 设计师版的布局")/ 微调 / 全部重来 → 重跑三套逻辑。**用户选定后,立刻把「展示了哪几版、截图路径、用户选择原话」写入项目目录 `direction-approved.md`**(Gate文件协议)。
 
 **Phase 6 · 进入主干执行**
 用户选定(或混合)后 → 回到「核心哲学」+「工作流程」的 Junior Designer pass,把那一版做扎实。这时已有明确 design context,不再凭空。
@@ -362,10 +362,10 @@ description: 花叔Design——用HTML做高保真原型、幻灯片、动画、
 | Gate文件 | 对应环节 | 什么时候必须有 |
 |---|---|---|
 | `brand-spec.md` | §1.a资产协议产物 | 涉及具体品牌/产品的任何设计 |
-| `direction-approved.md` | 三方向真实视觉展示+用户选择记录(含截图路径和用户原话);已有明确design context时**记录豁免理由**,豁免也要落档 | 实现开工前;**≥45s长片渲染前有hook硬检查**(scripts/design-gate-hook.sh,缺文件block渲染,用户明说跳过用SKIP_DESIGN_GATE=1显式放行) |
-| `导演稿.md`/director's notes | 长片/launch film的分镜与**视觉密度条款**(标准+参照标杆+氛围层清单,见animation-best-practices §6.5) | ≥20s动画开工前 |
+| `direction-approved.md` | 三方向真实视觉展示+用户选择记录(含截图路径和用户原话;「三方向」即Fallback三套逻辑产出的三版);已有明确design context时**记录豁免理由**,豁免也要落档 | 实现开工前;**≥45s长片渲染前有hook硬检查**(scripts/design-gate-hook.sh,缺文件block渲染,用户明说跳过用SKIP_DESIGN_GATE=1显式放行) |
+| `导演稿.md`/director's notes | 长片/launch film的分镜与**视觉密度条款**(标准+参照标杆+氛围层清单,见animation-best-practices §6.5) | ≥20s动画开工前;launch film级(品牌宣传片/「Apple级」预期)在此基线上按launch-film-director-notes.md升级为万字notes——导演稿是底线,万字notes是launch film的加强版,不是两套并行要求 |
 
-**「用户说继续」授权的是进入下一步,不是跳过该步内部的gate**。跳过必须用户明说,且把「用户明示跳过」写进对应gate文件。
+**「用户说继续」授权的是进入下一步,不是跳过该步内部的gate**。跳过必须用户明说,且把「用户明示跳过」写进对应gate文件。**弱runtime降级模式不豁免gate文件**——降级第5条允许把检查点问答换成assumption清单,但三个gate文件本身照写(写文件不耗上下文),assumption清单就写进对应gate文件里。
 **两套检查点的衔接**:主干用 🛑 检查点1-5,Fallback 用 🔴 CHECKPOINT(Phase 3.5 图片前置 + logo 子门)。从 Fallback Phase 1-5 走完回到主干 Step 2 时,检查点1(问题清单)已被 Phase 1 的澄清覆盖,**跳过不重复问**;检查点2 起照常执行。
 
 ### 问问题的要点
@@ -383,7 +383,7 @@ description: 花叔Design——用HTML做高保真原型、幻灯片、动画、
 | 场景 | 触发条件 | 处理动作 |
 |------|---------|---------|
 | 需求模糊到无法着手 | 用户只给一句模糊描述(如"做个好看的页面") | 主动列3个可能方向让用户选(如"落地页 / Dashboard / 产品详情页"),而不是直接问10个问题 |
-| 用户拒绝回答问题清单 | 用户说"不要问了,直接做" | 尊重节奏,用best judgment做1个主方案+1个差异明显的变体,交付时**明确标注assumption**,方便用户定位要改哪里 |
+| 用户拒绝回答问题清单 | 用户说"不要问了,直接做" | 尊重节奏,用best judgment做1个主方案+1个差异明显的变体,交付时**明确标注assumption**,方便用户定位要改哪里;此情形视为用户明示跳过三方向,在`direction-approved.md`记一句「用户跳过问答,best judgment交付1+1版」 |
 | Design context矛盾 | 用户给的参考图和品牌规范打架 | 停下,指出具体矛盾("截图里字体是衬线,规范说用sans"),让用户选一个 |
 | Starter component加载失败 | 控制台404/integrity mismatch | 先查`references/react-setup.md`常见报错表;还不行降级纯HTML+CSS不用React,保证产出可用 |
 | 时间紧迫要快交付 | 用户说"30分钟内要" | 跳过Junior pass直接Full pass,只做1个方案,交付时**明确标注"未经early validation"**,提醒用户质量可能打折 |

+ 1 - 0
references/animation-pitfalls.md

@@ -427,3 +427,4 @@ GSAP 的 `fromTo()` 默认 `immediateRender: true`:build timeline 时就把 fr
 - [ ] 【HyperFrames】渲染路径上没有 CSS `transition`?状态变化全是 tween 或 t 的纯函数?(坑 #18)
 - [ ] 【HyperFrames】代理 tween 场景注册后补了 `render(0)`?(坑 #19)
 - [ ] 【HyperFrames】check 过了?暗色电影风用 `--no-contrast`,其余四门 0 error?(坑 #20)
+- [ ] 【HyperFrames/GSAP】from 态可见的 `fromTo()` 全部加了 `immediateRender:false`?(坑 #21,B00 实测 4 处幻影)

+ 3 - 2
references/hyperframes-backend.md

@@ -12,6 +12,7 @@
 | 老 Stage demo 要复用/改版 | 顺手迁移(适配器配方见下,20-30 分钟/个);只重渲不改就仍用 render-video-seek.js |
 | 弱 runtime(无 npm / 无法装依赖 / 单文件交付给用户双击打开) | 自研 Stage(assets/animations.jsx),老流程不变 |
 | 交互演示(用户要在浏览器里玩,不导出视频) | 自研 Stage 或普通 HTML,HyperFrames 是渲染管线不是交互框架 |
+| 带解说长视频(Step 9.5,narration_stage 驱动) | **自研 narration 管线**(voiceover-pipeline.md + render-narration.sh),暂不走 HyperFrames——双时间源/字幕/TTS timeline 深度耦合自研 Stage;与「动画默认 HyperFrames」两行同时命中时按本行裁决 |
 | 批量参数化视频(千人千面/模板换字) | Remotion(见规划方向5,独立于本 skill 主流程) |
 
 **设计语言永远是甲方**:叙事结构、easing 体系、SFX/BGM 双轨制照旧全部生效(animation-best-practices.md / audio-design-rules.md),HyperFrames 只是实现和渲染工具。GSAP 实现配方见 `references/gsap-recipes.md`。
@@ -23,7 +24,7 @@ npx -y hyperframes init 项目名 --example blank   # 非交互必须带 --examp
 cd 项目名 && npm install
 ```
 
-生成 index.html / hyperframes.json / meta.json / package.json(pin 了 CLI 版本)+ 项目级 CLAUDE.md。init 会把 19 个 hyperframes skill 装到 `~/.claude/skills/`(本机已装)。合成写法契约读 `~/.claude/skills/hyperframes-core/SKILL.md`,本地文档 `npx hyperframes docs <topic>`(data-attributes / gsap / rendering / troubleshooting)。
+生成 index.html / hyperframes.json / meta.json / package.json(pin 了 CLI 版本)+ 项目级 CLAUDE.md。init 会把 19 个 hyperframes skill 装到 `~/.claude/skills/`(本机已装)。合成写法契约读 hyperframes-core skill 的 SKILL.md(init 装到各 runtime 的 skill 目录,Claude Code 默认 `~/.claude/skills/`;无 skill 机制的 runtime 直接读 `npx hyperframes docs` 本地文档替代),本地文档 `npx hyperframes docs <topic>`(data-attributes / gsap / rendering / troubleshooting)。
 
 **版本策略**:项目 package.json 会 pin 精确版本(当前实测过的是 0.7.61)。它迭代极快(300+ releases),升级先 `npx hyperframes@latest upgrade --project . --check` 看 delta,跑一遍回归 demo 再动。
 
@@ -78,4 +79,4 @@ HyperFrames 合成里 `<audio>` 元素可直接进时间轴(BGM/解说随片
 
 ## pitfalls 增量(相对自研管线)
 
-自研管线 pitfalls(animation-pitfalls.md §7/10/12/13 录制协议类、§6 字体时序、§15/17 网络类)在 HyperFrames 后端上**不适用**:录制协议由框架内部处理,字体编译期抓取,CDN 实测代理下可通。新增的坑只有三条,已录入 animation-pitfalls.md §18-20:CSS transition 非确定性、代理 tween 首帧、contrast 门冲突。
+自研管线 pitfalls(animation-pitfalls.md §7/10/12/13 录制协议类、§6 字体时序、§15/17 网络类)在 HyperFrames 后端上**不适用**:录制协议由框架内部处理,字体编译期抓取,CDN 实测代理下可通。新增的坑共四条,已录入 animation-pitfalls.md §18-21:CSS transition 非确定性、代理 tween 首帧、contrast 门冲突、fromTo immediateRender 幻影

+ 6 - 3
scripts/design-gate-hook.sh

@@ -17,14 +17,17 @@ INPUT=$(cat)
 CMD=$(printf '%s' "$INPUT" | python3 -c "import json,sys;print(json.load(sys.stdin).get('tool_input',{}).get('command',''))" 2>/dev/null)
 CWD=$(printf '%s' "$INPUT" | python3 -c "import json,sys;print(json.load(sys.stdin).get('cwd',''))" 2>/dev/null)
 
-# 只管渲染命令
-echo "$CMD" | grep -qE "hyperframes(@[0-9.]+)? +render|render-video(-seek)?\.js" || exit 0
+# 谈论命令的命令(echo/grep等)直接放行,防纯文本误伤(QA Bug1)
+FIRST=$(echo "$CMD" | sed -E 's/^[[:space:]]*//' | cut -d' ' -f1)
+case "$FIRST" in echo|printf|grep|cat|ls|head|tail|wc|sed|awk) exit 0;; esac
+# 只管渲染命令(含npm run render与解说长片渲染)
+echo "$CMD" | grep -qE "hyperframes(@[0-9.]+)? +render|render-video(-seek)?\.js|render-narration\.sh|npm +run +render\b" || exit 0
 # 显式跳过(可审计的逃生门)
 echo "$CMD" | grep -q "SKIP_DESIGN_GATE=1" && exit 0
 
 # 定位项目目录:命令中cd的目标 > hook cwd
 DIR="$CWD"
-CDDIR=$(echo "$CMD" | grep -oE 'cd +"[^"]+"|cd +[^ &;]+' | head -1 | sed 's/^cd +//; s/"//g')
+CDDIR=$(echo "$CMD" | grep -oE 'cd +"[^"]+"|cd +[^ &;]+' | head -1 | sed -E 's/^cd +//; s/"//g')
 [ -n "$CDDIR" ] && [ -d "$CDDIR" ] && DIR="$CDDIR"
 
 # 取合成时长:hyperframes项目读index.html的data-duration;render-video-seek读--duration参数