跳到主要内容

layout 与工件

内核不认识文件名,只认语义 id

Channek 内核里没有任何具体的工件文件名。凡「找某类产物在哪」,系统只写工件 kind(如 channek.entryacme.script),实际路径按这条链解析:

kind 的默认 pattern(注册该 kind 的插件声明)
→ 被卡 layout.artifacts 逐 kind 覆盖
→ 相对条目目录解析出真实路径

这意味着:换一套目录结构 = 换一段声明,不用改任何代码。你的频道想把母版放 master/final.mp4 而不是默认位置,写一行覆盖就行。

内核只自带两个与创作域无关的 kind:

kind默认 pattern承载
channek.entryentry.md条目清单:一条内容的状态机(状态/所在步/阻塞原因)
channek.projectproject/{slug}.channek剪辑工程文件

其余工件 kind(口播稿、分镜、旁白轨、母版、封面……)由贡献对应步骤的插件注册——它们是具体创作域的知识,不同频道用的完全不同。

layout 段

"layout": {
"preset": "channek.default", // 布局骨架(内核默认:contentDir 'content')
"contentDir": "content", // 条目容器目录(相对工作区根)
"entryDirName": "{date}-{slug}", // 新条目目录命名模板
"sections": [ // 辅助区(情报/选题库/复盘…)
{ "id": "intel", "path": "intel", "index": "index.md" }
],
"artifacts": { // 逐 kind 覆盖默认 pattern(唯一写位置)
"acme.master": "master/final.mp4"
},
"artifactAlsoRead": { // 读时也认的备用位置(不影响写)
"acme.script": ["脚本*.md"]
},
"detect": { "anyOf": ["content"] } // 「这个目录像不像本卡的频道」的探测线索
}

关键规则:

  • 写位置永远只有一个(artifacts 的 pattern);artifactAlsoRead 只扩大的范围——多个写位置意味着产物落哪不确定,那比少认一个位置严重得多;
  • artifacts / artifactAlsoRead 的语义都是替换不是追加:卡说了就完全按卡说的算;
  • 新建频道时按 layout 搭目录骨架(contentDir + sections + 卡根资源目录),打开无标记目录时按 detect 探测。

cardAssets:卡根里摆什么

工作区目录之外,卡目录自己的资源约定也归 layout 声明:

"layout": {
"cardAssets": {
"libraries": {
"sound": "素材库/声音", // 声音库目录(卡内相对路径)
"asset": "素材库/图形",
"scenes": "素材库/场景",
"skills": "skills", // 频道专属 skill 目录(给用户的 AI Agent 读)
"fonts": "fonts" // 卡自带字型目录
},
"docs": { "docs.charter": "创作宪章.md" }, // 文档挂载:卡字段 → 卡内路径
"brandAssets": {
"root": "品牌套件",
"avatar": ["头像/main.png", "头像/fallback.png"] // 有序候选,按序回落
}
}
}

内核对 cardAssets 没有默认值——素材库、品牌套件叫什么是创作域知识,卡没声明就是没有,系统一个目录都不会去猜。

注意

cardAssets 里的库路径必须是遏制在卡根内的相对路径——绝对路径、盘符、含 .. 的逃根路径都会被 schema 直接拒绝。这些路径会被拼在卡根后面直接上盘,放行逃根等于让导入的卡把软链指到卡外,那是路径逃逸漏洞,不是配置自由。

诚实进度:灯轨从工件推导

进度灯轨的灯色从工件的存在性与新鲜度链推导,不信内存标志——产物在就是在,不在就是不在,上游更新了下游就显示过期。layout.progressAnalyzer 可以为这套布局指定一个进度分析器(语义 id,只在已注册的分析器里选);不写或认不出,落到通用的「如实报产物在不在」。