case-data.schema.json 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. {
  2. "$schema": "https://json-schema.org/draft/2020-12/schema",
  3. "$id": "https://procedure-dsl/spec/format/case-data.schema.json",
  4. "title": "Procedure DSL · case_data",
  5. "description": "Canonical structure consumed by spec/tools/renderer.build_html(case_data) -> str. 一篇 case 可含 1 ~ N 个独立工序 (procedures), 共享同一份 source 原帖. 单工序 case 也用 procedures 数组长度 1 的形式 — schema 不区分.",
  6. "type": "object",
  7. "required": [
  8. "page_title",
  9. "source",
  10. "procedures"
  11. ],
  12. "additionalProperties": false,
  13. "properties": {
  14. "page_title": {
  15. "type": "string",
  16. "description": "HTML <title> + <h1>. e.g. 'Case 5 · 产品宣传图 AI 工作流可视化'"
  17. },
  18. "case_id": {
  19. "type": ["integer", "string", "null"],
  20. "description": "Optional case identifier shown in UI badge."
  21. },
  22. "source": {
  23. "$ref": "#/$defs/Source",
  24. "description": "case-level 原帖信息, 跨所有 procedures 共享 (一篇文章对应一份 source)."
  25. },
  26. "procedures": {
  27. "type": "array",
  28. "minItems": 1,
  29. "description": "一篇 case 包含的工序数组. 多工序场景 (e.g. case-5 '简单工作流 + 进阶工作流 + 附加案例'). 单工序 case 也用长度 1 数组. 每个 procedure 独立含 declarations / steps / type_registry / return_row.",
  30. "items": { "$ref": "#/$defs/Procedure" }
  31. }
  32. },
  33. "$defs": {
  34. "Procedure": {
  35. "type": "object",
  36. "description": "一个独立工序: 工序头部 (name/purpose/...) + declare 块 + 步骤 + 返回行. 一个 procedure 内的 type_registry 是该工序的 case-specific 类型扩展.",
  37. "required": ["id", "name", "purpose", "category", "platform", "author", "declarations", "steps"],
  38. "additionalProperties": false,
  39. "properties": {
  40. "id": { "type": "string", "description": "procedure 局部 id (单 case 内唯一). e.g. 'p1' / 'p1-simple' / 'p2-advanced'." },
  41. "name": { "type": "string", "description": "工序名称, e.g. '简单工作流: 一步生成'." },
  42. "purpose": { "type": "string", "description": "One-sentence intent (该工序在做什么)." },
  43. "category": { "type": "string", "description": "Top-level taxonomy, e.g. '产物创造'." },
  44. "platform": { "type": "string", "description": "原帖来源 platform; 通常跟 case-level source.platform 一致." },
  45. "author": { "type": "string", "description": "原作者; 通常跟 case-level source.author 一致." },
  46. "declarations": { "$ref": "#/$defs/Declarations" },
  47. "type_registry": {
  48. "type": "object",
  49. "description": "Per-procedure case-specific type entries; 渲染期跟 spec/taxonomy/type.json 的 stdlib 叶子合并 — case 项覆盖 stdlib 项. 跨工序共享的 case-specific type 可在多个 procedure 各自声明 (允许冗余).",
  50. "additionalProperties": { "$ref": "#/$defs/TypeRegistryEntry" }
  51. },
  52. "steps": {
  53. "type": "array",
  54. "description": "工序的步骤数组, 按执行顺序排. block/step 在顶层; nested 子项 kind:nested + group 指向父 block id.",
  55. "items": { "$ref": "#/$defs/Step" }
  56. },
  57. "return_row": { "$ref": "#/$defs/ReturnRow" }
  58. }
  59. },
  60. "Declarations": {
  61. "type": "object",
  62. "description": "工序的声明: declared inputs / resources / return type. 渲染成 declare 折叠块.",
  63. "required": ["inputs", "resources", "returns"],
  64. "additionalProperties": false,
  65. "properties": {
  66. "inputs": {
  67. "type": "array",
  68. "items": { "$ref": "#/$defs/DeclareItem" },
  69. "description": "Caller-provided inputs to the procedure."
  70. },
  71. "resources": {
  72. "type": "array",
  73. "items": { "$ref": "#/$defs/DeclareItem" },
  74. "description": "Long-lived resources (libraries, knowledge bases) read or written across runs."
  75. },
  76. "returns": { "$ref": "#/$defs/DeclareReturn" }
  77. }
  78. },
  79. "DeclareItem": {
  80. "type": "object",
  81. "required": ["type", "name"],
  82. "additionalProperties": false,
  83. "properties": {
  84. "type": { "type": "string", "description": "Type leaf (§A.3) or case-extended type." },
  85. "name": { "type": "string" },
  86. "default": { "type": "string", "description": "Optional default value/template." },
  87. "desc": { "type": "string", "description": "Optional human description." }
  88. }
  89. },
  90. "DeclareReturn": {
  91. "type": "object",
  92. "required": ["type"],
  93. "additionalProperties": false,
  94. "properties": {
  95. "type": { "type": "string" },
  96. "note": { "type": "string", "description": "e.g. 'extends 视频成品 (序列关系)'." }
  97. }
  98. },
  99. "Source": {
  100. "type": "object",
  101. "description": "case-level 原帖信息. 渲染成 foldable 折叠块 (default closed). 跨所有 procedures 共享.",
  102. "required": ["platform", "author", "date", "title", "excerpt"],
  103. "additionalProperties": false,
  104. "properties": {
  105. "platform": { "type": "string" },
  106. "author": { "type": "string" },
  107. "date": { "type": "string", "description": "Free-text date, e.g. '2026 上半年'." },
  108. "url": { "type": ["string", "null"], "description": "原帖 URL; 没有干净 URL 时填 null 或省略 (不强制 uri 格式)." },
  109. "title": { "type": "string" },
  110. "excerpt": { "type": "string", "description": "1-2 sentence pipeline summary." },
  111. "body_text": { "type": "string", "description": "Optional full body of the source article." },
  112. "cover_image": { "type": "string", "description": "Optional cover image URL." }
  113. }
  114. },
  115. "TypeRegistryEntry": {
  116. "type": "object",
  117. "description": "Case-specific 类型定义 (procedures[*].type_registry). 桥接到一个 stdlib 叶子 + 人类可读描述.",
  118. "required": ["extends", "desc"],
  119. "additionalProperties": false,
  120. "properties": {
  121. "extends": { "type": "string", "description": "桥接到的 stdlib 叶子名 (spec/taxonomy/type.json $leaves 之一)." },
  122. "desc": { "type": "string", "description": "case-specific 类型的人类可读说明 (renderer drawer + type_suggestions 用)." }
  123. }
  124. },
  125. "Step": {
  126. "type": "object",
  127. "description": "One row group in the 25-column procedure table. Renders to N <tr> where N = max(len(inputs), len(outputs), 1). The dictionary-tree fields (effect/via/action/feature/control) MUST hit canonical leaves per spec §A. NOTE: kind=block 是控制容器, 只带 control + intent + via='-' + feature='-' + io; effect/action/focus 由其下 kind=nested 执行步承担 (见下方 allOf 条件: 仅 step/nested/atom 要求 effect/action/focus).",
  128. "required": ["id", "kind", "via", "feature", "inputs", "outputs", "intent"],
  129. "additionalProperties": false,
  130. "properties": {
  131. "id": {
  132. "type": "string",
  133. "pattern": "^(s\\d+(\\.\\d+)*|a\\d+)$",
  134. "description": "Step id. Plain step / block / nested use 's' prefix (block children dotted, e.g. 's3.1'); atoms use 'a' prefix (e.g. 'a1') scoped under their parent step."
  135. },
  136. "kind": {
  137. "enum": ["step", "block", "nested", "atom"],
  138. "description": "step=plain; block=control-flow parent; nested=child of a block; atom=experimental dimensional projection (only used in case1)."
  139. },
  140. "group": {
  141. "type": "string",
  142. "description": "When kind=nested, the parent block's id (e.g. 's3')."
  143. },
  144. "parent_step": {
  145. "type": "string",
  146. "description": "When kind=atom, the host step's id."
  147. },
  148. "name": {
  149. "type": "string",
  150. "description": "Only meaningful for kind=atom (displayed above the intent text)."
  151. },
  152. "key_dim": {
  153. "type": "string",
  154. "description": "atom-only: the dimension this atom projects (e.g. '实质' / '形式')."
  155. },
  156. "key_value": {
  157. "type": "string",
  158. "description": "atom-only: the specific path within the key_dim (e.g. '/表象/视觉/.../形象呈现')."
  159. },
  160. "effect": {
  161. "enum": [
  162. "预处理", "主体生成", "装配", "后期",
  163. "工艺规约", "预准备", "配套伴生", "检验", "交付"
  164. ],
  165. "description": "§A.1 L3 leaf. Required to hit a leaf — non-leaf = extraction error."
  166. },
  167. "via": {
  168. "type": "string",
  169. "description": "Canonical L1 tool name (manus / nano_banana_pro / human / <llm-agent>) or generic placeholder for unspecified tools ('(AI 生图工具)'). Use '-' for control-flow blocks."
  170. },
  171. "action": {
  172. "type": "string",
  173. "pattern": "^[^/]+(/[^/]+)*$",
  174. "description": "§A.2 path, e.g. '生成/元素生成', '提取/化学提取/反推'. Control-flow already routed to `control` field."
  175. },
  176. "feature": {
  177. "type": "string",
  178. "enum": ["随机", "幂等", "人工", "本地", "写外部", "读外部", "-"],
  179. "description": "Execution attribute (internal). Block-level steps use '-'. NEVER referenced in intent column."
  180. },
  181. "control": {
  182. "type": "string",
  183. "enum": ["并行", "遍历", "分支", "请求", "等待", "", "-"],
  184. "description": "Control-flow kind. Typically on kind=block; may appear on a regular step that itself is a control. Empty string or '-' = no control flow (kept for atom rows and plain steps that explicitly set the field)."
  185. },
  186. "instruction": {
  187. "type": "array",
  188. "description": "Heterogeneous list of (kind, text) tuples. Order is preserved; any subset of kinds is allowed; control-flow blocks usually only carry memo entries.",
  189. "items": {
  190. "type": "array",
  191. "prefixItems": [
  192. {
  193. "enum": ["directive", "config", "decorator", "memo"],
  194. "description": "directive=literal prompt text; config=tool runtime params; decorator=caller-side @decorator; memo=engineering wisdom not captured elsewhere."
  195. },
  196. { "type": "string" }
  197. ],
  198. "items": false,
  199. "minItems": 2,
  200. "maxItems": 2
  201. }
  202. },
  203. "inputs": {
  204. "type": "array",
  205. "items": { "$ref": "#/$defs/IOItem" }
  206. },
  207. "outputs": {
  208. "type": "array",
  209. "items": { "$ref": "#/$defs/IOItem" }
  210. },
  211. "intent": {
  212. "type": "string",
  213. "description": "≤ ~20 chars natural-language sentence. Tokens `{kind:value}` with kind ∈ {effect, via, act, control, in-type, out-type, in-sub, out-sub, in-form, out-form}. NEVER reference {feature:X}, NEVER use variable-name tokens, NEVER use 'X: Y → Z' pseudo-code."
  214. },
  215. "focus": {
  216. "type": "array",
  217. "items": { "type": "string" },
  218. "description": "Column-cell keys to highlight on this row. Format: bare key for step-level cells ('via', 'action', 'effect', 'idx', 'intent'), or '<col>-<io_index>' for IO cells ('in-type-0', 'out-substance-1', etc.)."
  219. },
  220. "inferred_marks": {
  221. "type": "object",
  222. "description": "Step-level field-by-field inference annotations (single cells, not whole rows). Maps column key → reason string. Used when only a specific field was filled by 工艺补全, not the whole row.",
  223. "additionalProperties": { "type": "string" }
  224. },
  225. "atoms": {
  226. "type": "array",
  227. "description": "EXPERIMENTAL extension (case1-only). Dimensional projections of this step; each atom mirrors a Step shape with kind='atom' + parent_step + name + key_dim + key_value.",
  228. "items": { "$ref": "#/$defs/Step" }
  229. }
  230. },
  231. "allOf": [
  232. {
  233. "if": { "properties": { "kind": { "enum": ["step", "nested", "atom"] } } },
  234. "then": { "required": ["effect", "action", "focus"] }
  235. },
  236. {
  237. "if": { "properties": { "kind": { "const": "nested" } } },
  238. "then": { "required": ["group"] }
  239. },
  240. {
  241. "if": { "properties": { "kind": { "const": "atom" } } },
  242. "then": { "required": ["parent_step", "name", "key_dim", "key_value"] }
  243. }
  244. ]
  245. },
  246. "IOItem": {
  247. "type": "object",
  248. "description": "One row in inputs[] or outputs[]. Input and output items share the same shape (anchor points up for inputs, down for outputs).",
  249. "required": ["type", "name", "value", "anchor"],
  250. "additionalProperties": false,
  251. "properties": {
  252. "substance": {
  253. "type": ["string", "null"],
  254. "description": "What the content IS (理念 vs 表象 layer). Path from `分类库导出_实质_*.json`. null for abstract containers / pure tool params."
  255. },
  256. "form": {
  257. "type": ["string", "null"],
  258. "description": "How the content is PRESENTED (呈现 vs 架构 layer). Path from `分类库导出_形式_*.json`. null when not applicable."
  259. },
  260. "type": {
  261. "type": "string",
  262. "description": "§A.3 leaf or case-extended type name."
  263. },
  264. "name": {
  265. "type": "string",
  266. "description": "Variable identifier within this step. Same concept across steps MUST use the same name (lint enforces this)."
  267. },
  268. "value": {
  269. "type": "string",
  270. "description": "Content itself. Text data: full prose, no wrappers. Non-text data: '<整段描述>' (the whole description angle-bracketed). NEVER metadata ('[图 N 显示]', '原文: ...') or upstream refs ('← sN.x' — those go in anchor)."
  271. },
  272. "anchor": {
  273. "type": "string",
  274. "description": "Inputs: upstream ref ('← 工序输入', '← sN.varname', '← 容器[i]'). Outputs: downstream destination ('→ sN', '→ 视频片段列表.追加', '→ 返回 X')."
  275. },
  276. "inferred": {
  277. "type": "boolean",
  278. "description": "True when this whole IO item was filled by 工艺补全 (not in source material). Renderer dyes the entire row's 6 data-flow cells."
  279. },
  280. "inferred_reason": {
  281. "type": "string",
  282. "description": "REQUIRED when inferred=true. Shown on hover."
  283. }
  284. },
  285. "if": {
  286. "required": ["inferred"],
  287. "properties": { "inferred": { "const": true } }
  288. },
  289. "then": { "required": ["inferred_reason"] }
  290. },
  291. "ReturnRow": {
  292. "type": "object",
  293. "description": "Bottom row of the table announcing what the procedure returns.",
  294. "required": ["arrow", "text"],
  295. "additionalProperties": false,
  296. "properties": {
  297. "arrow": {
  298. "type": "string",
  299. "description": "Usually '↩'."
  300. },
  301. "text": {
  302. "type": "string",
  303. "description": "May contain inline HTML fragments (chip / name / em spans) — emitted verbatim into a colspan=24 cell."
  304. }
  305. }
  306. }
  307. }
  308. }