PPT Master 执行锁 spec_lock.md 编写权威指南:从 Design Spec 到跨页锚点与路由的结构投影
【免费下载链接】ppt-masterAI turns documents or topics into real, native PowerPoint decks—with native shapes, transitions and animations,>项目地址: https://gitcode.com/GitHub_Trending/ppt/ppt-master
spec_lock.md(Execution Lock)是 PPT Master 生成流水线中位于设计决策与逐页执行之间的结构性契约文件:它把审计过的design_spec.md与上下文投影为跨页稳定的锚点与路由,同时刻意排除局部绘制(paint)与排版(type)细节。本篇指南以仓库内 spec_lock_reference.md 为骨架,结合 spec_lock.schema.json、project_specs.py 与 test_spec_lock_forbidden.py 的源码实现,完整讲解执行锁的编写时机、基础章节、条件字段、字段语法索引与机器验证方式。读完本文,你将掌握如何手写一份可通过project_manager.py validate的规范执行锁,并理解其背后的语法契约与所有权边界。
1. 职责边界:spec_lock.md 与 design_spec.md 的分工
在 PPT Master 的规划工件体系中,两个 Markdown 工件各司其职:
- design_spec.md 参考文档 规定项目级
design_spec.md的编写结构。它是面向人类的、以英文标题组织的完整设计规格,记录画布、视觉主题、排版、布局、图标、可视化、图片资源、完整页册与演讲者备注。 spec_lock.md则只投影跨页锚点(cross-page anchors)和路由(routes),排除局部绘制与排版。文件本身拥有结构(structure),spec_lock.schema.json 拥有语法(grammar)。
三权分立的关系贯穿整个体系:
| 层 | 拥有者 | 说明 |
|---|---|---|
| 结构(Structure) | spec_lock.md | 章节、字段、跨页锚点的组织方式 |
| 语法(Grammar) | spec_lock.schema.json | 字段名、枚举值、正则、条件与引用关系的机器可读定义 |
| 语义(Semantics) | Strategist 模块 / Executor | 字段含义由策略模块裁决,消费方式由执行器分支接管 |
从生命周期看,二者存在严格的先后依赖:Strategist 只读取一次最终确认(final confirmation),基于保留状态与源分析写出design_spec.md并审计每一个已确认字段;随后基于完成的 Design Spec 加上上下文编写spec_lock.md,而不再重开result.json。这与 executor-base.md 中"Executor 读取持久化的design_spec.md和spec_lock.md"的约定(Default only项绑定二者)完全一致。
2. 一次性编写完整工件:时机、Marker 与硬规则
2.1 编写时机
在Generate Step 4 Gate 1之后:此时已读取完整的 Design Spec 与当前页面/资源/模板上下文,应在活动上下文中一次性组合整个执行锁,并在<project_path>/spec_lock.md一次性写入。禁止分次追加、留空章节或写入脚手架的占位符(project_manager.py scaffold-lock只是可选的排障工具,不属于 Generate 正常编写流程的一部分)。
2.2 强制 Marker(新项目必写)
新项目写入时,第一个非空行必须逐字符是:
<!-- ppt-master-schema: spec-lock/v1 -->随后第二行才是# Execution Lock。该 Marker 是版本契约的入口:project_specs.py 中的_SCHEMA_MARKER_RE会以正则^<!--[ \t]+ppt-master-schema:[ \t]*([a-z0-9-]+/v[1-9][0-9]*)[ \t]+-->$全匹配校验它;缺少 Marker 或格式错误都会触发校验错误。测试 test_spec_lock_forbidden.py 中,无 Marker 的旧版工件会被标记为legacy artifact has no ppt-master-schema marker警告,但不再按新版规则报 forbidden 错误——这是显式的向后兼容策略。
2.3 硬规则:只有两种行
执行锁的正文只允许出现两类内容:
##章节标题(H2);- key: value数据行。
唯一例外是## forbidden章节,其条目是字面规则文本。绝不允许把任何指导性段落(guidance paragraphs)抄进执行锁。
2.4 修复与重建规则
- 可修复:面对可信的、已完成的成对工件(Design Spec + Lock)时,只能先审计 Design Spec,再只重新投影受影响的行。
- 必须重建:遇到孤儿执行锁(orphan lock,即无对应 Design Spec)时,以恢复出的 Design Spec 为权威,完全重新编写执行锁。
- 无论何种情况,都不得重开
result.json来编写执行锁,也不得让执行锁覆盖 Design Spec 的合法决策。
3. 基础章节全解析
执行锁包含以下必选基础章节:
| 章节 | 必填键 | 说明 |
|---|---|---|
canvas | viewBox、format | format是规范展示名(如PPT 16:9);viewBox是精确几何 |
communication | primary_language、audience、objective、core_message | 语言使用规范 BCP-47 标签(拒绝und,拒绝无脚本/地区限定的中文;旧锁可省略);objective合并意图/结果;consumption_mode在非 PPT 场景下可选 |
mode | mode | 预设值或custom |
visual_style | visual_style | 预设值或custom |
colors | 稳定的语义色角色 | 只写核心身份色与反复出现的角色,含secondary_text与divider;一次性上下文用色不占行;image_rendering仅用于 AI 图片 |
typography | font_family、body、title | 核心字体族/字号锚点;新锁额外写title_family与body_family;字号为无单位 px |
icons | library、inventory | library是主捆绑样式或none;simple-icons/*可单独或伴随准备;inventory索引精选同步池而非页面用量;stroke_width条件性出现 |
page_rhythm | 每页一个P<NN>行 | 取值为anchor、dense、breathing |
pptx_structure | mode | flat或structured |
forbidden | 字面规则条目列表 | 技术基线行保持无标记;其余每行都是用户用自己的话表达的禁令,逐字引用并以(user)结尾 |
可选数据章节:images、page_visualizations(仅 Chart/Table)。新锁绝不再写遗留的page_charts(已有锁可只读保留);同一页不得同时在两个章节声明。
3.1 colors 的角色纪律
colors章节只收纳稳定的语义色角色——核心身份色与反复出现的角色(含secondary_text与divider)。上下文性的绘制(一次性的色调、渐变停止点、阴影/发光用色、透明度合成)无需成行;image_rendering字段只在与 AI 图片相关时出现。
3.2 typography 的投影纪律
排版投影遵循明确规则(详见第 4 节):Title 字体栈投影为title_family,Body 字体栈投影为body_family并兼容性保留font_family;每个额外反复出现的角色<role>投影为<role>_family;字体大小层级中的每个角色以小写 snake_case写为带数字锚点的字段。新锁即使 Title/Body 相同也必须同时写title_family与body_family;只有继承且无覆盖的角色族才可省略;旧锁回退到font_family。Schema 中typography章节的必填字段正是font_family、body、title,同时允许title_family、body_family以及subtitle_family、annotation_family、footer_family、footnote_family、data_family、emphasis_family、quote_family、code_family等角色族字段(见 spec_lock.schema.json 的typography定义)。
3.3 forbidden:基线规则与 (user) 溯源标记
## forbidden是执行锁中最特殊的章节。它的内容由两部分组成:
- 技术基线行:保持无标记(untagged),来自版本化脚手架 scaffolds/spec_lock.md;
- 用户禁令行:用户用自己的话(请求、对话、
image_notes)表达的每一个禁令,逐字引用并以(user)结尾——不是转述,绝不扩大化。
典型基线行示例:
## forbidden - `mask`, `<style>`, `class`, external CSS, `<foreignObject>`, `textPath`, `@font-face`, `<animate*>`, `<set>`, `<script>` / event attributes, `<iframe>` - HTML named entities in text; write typography as raw Unicode and escape XML reserved characters - 不要用任何阴影和发光 (user)project_manager.py validate会拒绝未标记的非基线行(rejects an untagged non-baseline row)。实现位于 project_specs.py 的_validate_spec_lock_forbidden:它把脚手架默认行与遗留锚点(<style>、<foreignObject>、HTML named entities、Mixing icon libraries、rgba()、<g opacity等)作为放行集合,其余行必须满足"属于基线"或"以(user)结尾"二者之一。测试 test_spec_lock_forbidden.py 验证了三种典型情形:仅基线行通过;带(user)标记的用户行通过;未标记的用户行不要用任何阴影和发光报错is not a baseline rule and lacks the (user) tag。
值得强调的边界:Strategist 起草的方向性描述——即使已被确认——也是visual_style_behavior中的身份性散文(identity prose),不是禁令,因此不会从其中投影任何内容进入forbidden章节。通用标准停留在其所属的参考文档中,模板规则停留在其安装的 spec 中。
4. 条件章节与字段:按触发条件补齐结构
执行锁的结构不是固定的:以下条件一旦成立,就必须追加相应章节/字段:
| 触发条件 | 必须补充的内容 |
|---|---|
mode.mode: custom | mode_behavior;仅当使用了目录 modes 时可选mode_references |
visual_style.visual_style: custom | visual_style_behavior;可选visual_style_references |
colors.image_rendering: custom | image_rendering_behavior;可选image_rendering_references |
icons.library: tabler-outline | stroke_width: 1.5、2或3 |
pptx_structure.mode: structured | template_reuse_scope: layout\|mirror、template_adherence,外加pptx_masters、pptx_layouts、page_pptx_layouts、page_layouts四个章节 |
template_reuse_scope: mirror | mode: structured且template_adherence: strict |
template_reuse_scope: style | mode: flat;省略所有 structured 章节 |
pptx_structure.mode: flat | 省略全部四个 structured 章节 |
这些条件在 schema 的x-markdown.conditions中被机械编码为custom-mode、custom-visual-style、custom-image-rendering、stroke-icon-weight、structured-pptx、style-is-flat、layout-is-structured、mirror-is-strict、flat-has-no-structured-mappings九条规则,并在 project_specs.py 的_condition_applies/_validate_condition中执行(含required_sections、forbidden_sections、required_fields、field_values四类约束)。
4.1 结构化模板映射示例
当启用structured模式时,四个章节协同工作:
## pptx_masters - master-default: Default Master ## pptx_layouts - content-two-column: master-default | Two Column | template:03_content ## page_pptx_layouts - P01: content-two-column ## page_layouts - P01: 03_content ## page_visualizations - P03: chart/line_chart - P09: table/record_table注意 schema 中的引用约束:pptx_layouts的第一个|分段(master key)必须已在pptx_masters中声明(layout-master引用规则);page_pptx_layouts的值必须指向已声明的 Layout key(page-pptx-layout);page_layouts的值必须解析到项目内templates/{value}.svg资产(page-input-prototype引用规则,对应 cli.py 的validate_project调用链)。
4.2 page_visualizations 投影规则
Design Spec §VII 的每一行最多投影为每页一个page_visualizations的<chart|table>/<key>行,且必须解析到一个活 SVG。Usage(用途)、子视觉、无匹配回退与定性关系都留在 Design Spec §IX 中。遗留兼容:既有page_charts裸键在两个活注册表(charts / tables)中唯一解析;退役的 Structure 键仅具语义、无 SVG;同一页的双重声明即使解析结果相同也构成冲突。Schema 对page_visualizations的值约束为^(?:chart|table)/[a-z0-9]+(?:_[a-z0-9]+)*$,对遗留page_charts为^[a-z0-9]+(?:_[a-z0-9]+)*$,且page_charts绝不写入新锁。
4.3 排版投影规则
排除 Character/upgrade References 后,排版投影按如下规则进行:
- Title 字体栈 →
title_family; - Body 字体栈 →
body_family加上兼容性的font_family; - 每个额外反复出现的角色
<role>→<role>_family; - 每个字体大小层级角色 → 小写 snake_case 的
<role>及其数字锚点。
新锁总是同时写title_family与body_family(即使相等);只有继承且无覆盖的角色族才省略;旧锁回退到font_family。
4.4 自定义方向的引用字段
## mode - mode: custom - mode_references: pyramid, narrative, instructional - mode_behavior: Open conclusion-first with pyramid, develop the risk through a narrative tension-and-resolution act, then close with an instructional action sequence.自定义引用字段(mode_references、visual_style_references、image_rendering_references)必须是逗号分隔的精确目录 id、无重复,且仅对custom有效;真正的全新方向(无目录材料可用)则省略该字段。Schema 用正则^[a-z0-9][a-z0-9-]*(?:\s*,\s*[a-z0-9][a-z0-9-]*)*$约束,且 project_specs.py 通过_CUSTOM_REFERENCE_CATALOGS把三个引用字段分别绑定到references/modes、references/visual-styles、references/image-renderings三个目录的目录页做成员校验。
5. 字段语法索引(Field Grammar Index)
本节逐条给出执行锁全部字段的精确语法契约:
font_family、title_family、body_family及每个<role>_family:一个非空的、可在 PPT 中导出的字体族栈(family stack)。font_family是 body/default 的兼容栈,不是抹平角色差异的许可。- 每个非 family 的
typography值:一个正的有限无单位 px 锚点。Executor 的工作带与展示例外见 executor-base.md §2.1,扩展规则见其 §6。Schema 的field_value_rules强制该值为positive finite unitless px number(正则^(?=.*[1-9])(?:[0-9]+(?:\.[0-9]+)?|\.[0-9]+)$,且math.isfinite且> 0)。 icons.library:chunk-filled、tabler-filled、tabler-outline、phosphor-duotone或none。simple-icons/*标记可以单独或随inventory出现,但不构成 library 或确认选择;<project_path>/icons/下的每个 SVG 仍是有效素材。插画式图标切片不产生 icon 字段——其路径归属images,未放置的图页(sheet)不入锁。objective:一句简洁句子,保留目标与受众成功条件。image_rendering:一个目录 id,或custom搭配image_rendering_behavior。images:格式为- <key>: <path> | source=<via> | crop=<adaptive|no-crop>,例如- p04: images/a.png | source=user | crop=no-crop。路径必须是规范的images/<filename>;source与crop精确投影 Design Spec §VIII;Image pattern不投影(Executor 从 §VIII 作为建议读取);兼容旧版pattern=<layout>分段;未放置的图页省略。stroke_width:1.5、2或3,仅对tabler-outline有效(schemafield_enums允许的枚举正是这三个字符串值)。page_rhythm:P+ 至少两位数字(P01、P100),后接anchor|dense|breathing之一。Schema 用entry_key_pattern: ^P[0-9]{2,}$与value_enum约束。Execuitor 的兜底策略是:缺失章节/标签时统一警告并回退为dense(见 executor-base.md),绝不自行发明标签。page_visualizations:P+ 至少两位数字,后接chart|table、/与一个通过匹配的活索引解析到单个 SVG 的规范键。遗留page_charts:P+ 至少两位数字与一个裸键;绝不加入新锁。pptx_masters:<master_key>: <PowerPoint picker name>。pptx_layouts:<layout_key>: <master_key> | <PowerPoint layout name> | <prototype source>。Schema 值正则要求原型来源为template:[A-Za-z0-9._-]+或P[0-9]{2,}。page_pptx_layouts:P+ 至少两位数字,后接一个已声明的 Layout key。page_layouts:P+ 至少两位数字,后接一个完整的 Slide 模板 SVG 基名。仅定义用途的layout_<layout_key>文件已废弃,不得作为来源。
6. 机器验证:project_manager.py validate 与语法契约
执行锁的机器验证入口是:
python3 skills/ppt-master/scripts/project_manager.py validate <project_path>它直接读取 Markdown,报告:未解析的[fill...]占位符、大小写错误、未知章节或字段、非法枚举值、格式错误的页面键、缺失的目录资产、损坏的 structured-layout 引用、未满足的条件。关键边界是:它既不重写执行锁,也不检查语义投影(语义投影由 Gate 2 承担)。字段含义留在 Strategist 模块,Executor 分支拥有消费方式,schema 只拥有语法与结构条件。
从源码看验证链路:
- project_manager.py 是稳定 CLI 入口,其
validate子命令委托给 cli.py 的ProjectManager.validate_project; validate_project调用validate_project_artifacts(定义于 project_specs.py),后者加载SCHEMA_DIR/spec_lock.schema.json并执行validate_markdown_schema;- 解析器
_parse_markdown_sections用正则把##章节与- key: value数据行切成结构化对象(parse_spec_lock_artifact还会把旧版"路径即 key"的 images 行归一化为- <key>: <path> | ...形态); - 逐章节应用
_validate_section(必填字段、允许字段、枚举、正则、数值规则、最小条目数、条目键正则、值枚举、值正则、目录成员校验),再应用九条跨章节条件与引用规则。
因此,任何一个手写执行锁都可以用这条命令获得与仓库语义完全一致的语法裁决,而无需自己实现解析器。
7. 锚点与扩展语义
7.1 什么是稳定锚点
已确认的核心调色板角色与每个已声明的排版字体族/字号角色都是跨页稳定锚点(cross-page anchors):它们跨页面保持不变,是所有页面共享的身份基准。相反,页面局部的色调、渐变停止点、阴影/发光绘制、透明度合成、一次性导出安全的展示字体族,都可以直接从上下文编写而不占行——Executor 工作在其上的尺寸带与展示例外见 executor-base.md §2.1。
7.2 何时升级为正式角色
两个触发条件会推动上下文值升格为正式语义角色:
- 某个上下文值变成反复出现的语义角色;
- 某个未声明的展示字号达到第三次出现。
此时应:添加描述性角色 → 读回并重新验证受影响的规划片段 → 之后反复使用。而超出工作带的机构性排版(structural typography)必须立即上抛(returns upstream),不能就地降级处理。
7.3 两个反向约束
- 绝不为了清空某个信息性检查器的对比项而扩展执行锁——一次锁编辑表达的是复用或身份(reuse or identity),不是偶发字面量(incidental literals)。
- Executor 侧的硬规则同样是纪律的来源:模板与
spec_lock.md只指导构造,绝不在导出时提供内容(executor-base.md 的 Shape-first 页面权威规则);tabler-outline的stroke-width只能是1.5、2、3之一,且锁中声明的icons.stroke_width全册生效(旧锁缺失时以2回退并告警)。
8. 最佳实践小结
- 一次写全:在 Gate 1 后于活动上下文完成整份锁,Marker 逐字符正确,无占位符、无空锁、无未激活的可选章节。
- 结构纯净:只有
##章节与- key: value行;指导性散文、模板规则、通用标准一律留在其所属参考/模板文档。 - 溯源清晰:
forbidden中的用户禁令逐字引用并以(user)结尾;Strategist 方向性散文只进visual_style_behavior。 - 条件自洽:
custom必配*_behavior;tabler-outline必配stroke_width;structured必配四个映射章节且各 key 交叉可解析;flat绝不携带 structured 映射。 - 以小见大:稳定语义才占行,偶发上下文不入锁;第三种重复出现才升级角色;不为了取悦检查器而扩锁。
- 验证闭环:每次手写或修复后用
python3 skills/ppt-master/scripts/project_manager.py validate <project_path>做语法裁决,把语义正确性交给 Gate 2,把含义交给 Strategist 模块与 Executor 分支。
【免费下载链接】ppt-masterAI turns documents or topics into real, native PowerPoint decks—with native shapes, transitions and animations,>项目地址: https://gitcode.com/GitHub_Trending/ppt/ppt-master
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考