| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325 |
- {
- "$schema": "https://json-schema.org/draft/2020-12/schema",
- "$id": "https://procedure-dsl/spec/format/case-data.schema.json",
- "title": "Procedure DSL · case_data",
- "description": "Canonical structure consumed by spec/tools/renderer.build_html(case_data) -> str. 一篇 case 可含 1 ~ N 个独立工序 (procedures), 共享同一份 source 原帖. 单工序 case 也用 procedures 数组长度 1 的形式 — schema 不区分.",
- "type": "object",
- "required": [
- "page_title",
- "source",
- "procedures"
- ],
- "additionalProperties": false,
- "properties": {
- "page_title": {
- "type": "string",
- "description": "HTML <title> + <h1>. e.g. 'Case 5 · 产品宣传图 AI 工作流可视化'"
- },
- "case_id": {
- "type": ["integer", "string", "null"],
- "description": "Optional case identifier shown in UI badge."
- },
- "source": {
- "$ref": "#/$defs/Source",
- "description": "case-level 原帖信息, 跨所有 procedures 共享 (一篇文章对应一份 source)."
- },
- "procedures": {
- "type": "array",
- "minItems": 1,
- "description": "一篇 case 包含的工序数组. 多工序场景 (e.g. case-5 '简单工作流 + 进阶工作流 + 附加案例'). 单工序 case 也用长度 1 数组. 每个 procedure 独立含 declarations / steps / type_registry / return_row.",
- "items": { "$ref": "#/$defs/Procedure" }
- }
- },
- "$defs": {
- "Procedure": {
- "type": "object",
- "description": "一个独立工序: 工序头部 (name/purpose/...) + declare 块 + 步骤 + 返回行. 一个 procedure 内的 type_registry 是该工序的 case-specific 类型扩展.",
- "required": ["id", "name", "purpose", "category", "platform", "author", "declarations", "steps"],
- "additionalProperties": false,
- "properties": {
- "id": { "type": "string", "description": "procedure 局部 id (单 case 内唯一). e.g. 'p1' / 'p1-simple' / 'p2-advanced'." },
- "name": { "type": "string", "description": "工序名称, e.g. '简单工作流: 一步生成'." },
- "purpose": { "type": "string", "description": "One-sentence intent (该工序在做什么)." },
- "category": { "type": "string", "description": "Top-level taxonomy, e.g. '产物创造'." },
- "platform": { "type": "string", "description": "原帖来源 platform; 通常跟 case-level source.platform 一致." },
- "author": { "type": "string", "description": "原作者; 通常跟 case-level source.author 一致." },
- "declarations": { "$ref": "#/$defs/Declarations" },
- "type_registry": {
- "type": "object",
- "description": "Per-procedure case-specific type entries; 渲染期跟 spec/taxonomy/type.json 的 stdlib 叶子合并 — case 项覆盖 stdlib 项. 跨工序共享的 case-specific type 可在多个 procedure 各自声明 (允许冗余).",
- "additionalProperties": { "$ref": "#/$defs/TypeRegistryEntry" }
- },
- "steps": {
- "type": "array",
- "description": "工序的步骤数组, 按执行顺序排. block/step 在顶层; nested 子项 kind:nested + group 指向父 block id.",
- "items": { "$ref": "#/$defs/Step" }
- },
- "return_row": { "$ref": "#/$defs/ReturnRow" }
- }
- },
- "Declarations": {
- "type": "object",
- "description": "工序的声明: declared inputs / resources / return type. 渲染成 declare 折叠块.",
- "required": ["inputs", "resources", "returns"],
- "additionalProperties": false,
- "properties": {
- "inputs": {
- "type": "array",
- "items": { "$ref": "#/$defs/DeclareItem" },
- "description": "Caller-provided inputs to the procedure."
- },
- "resources": {
- "type": "array",
- "items": { "$ref": "#/$defs/DeclareItem" },
- "description": "Long-lived resources (libraries, knowledge bases) read or written across runs."
- },
- "returns": { "$ref": "#/$defs/DeclareReturn" }
- }
- },
- "DeclareItem": {
- "type": "object",
- "required": ["type", "name"],
- "additionalProperties": false,
- "properties": {
- "type": { "type": "string", "description": "Type leaf (§A.3) or case-extended type." },
- "name": { "type": "string" },
- "default": { "type": "string", "description": "Optional default value/template." },
- "desc": { "type": "string", "description": "Optional human description." }
- }
- },
- "DeclareReturn": {
- "type": "object",
- "required": ["type"],
- "additionalProperties": false,
- "properties": {
- "type": { "type": "string" },
- "note": { "type": "string", "description": "e.g. 'extends 视频成品 (序列关系)'." }
- }
- },
- "Source": {
- "type": "object",
- "description": "case-level 原帖信息. 渲染成 foldable 折叠块 (default closed). 跨所有 procedures 共享.",
- "required": ["platform", "author", "date", "title", "excerpt"],
- "additionalProperties": false,
- "properties": {
- "platform": { "type": "string" },
- "author": { "type": "string" },
- "date": { "type": "string", "description": "Free-text date, e.g. '2026 上半年'." },
- "url": { "type": ["string", "null"], "description": "原帖 URL; 没有干净 URL 时填 null 或省略 (不强制 uri 格式)." },
- "title": { "type": "string" },
- "excerpt": { "type": "string", "description": "1-2 sentence pipeline summary." },
- "body_text": { "type": "string", "description": "Optional full body of the source article." },
- "cover_image": { "type": "string", "description": "Optional cover image URL." }
- }
- },
- "TypeRegistryEntry": {
- "type": "object",
- "description": "Case-specific 类型定义 (procedures[*].type_registry). 桥接到一个 stdlib 叶子 + 人类可读描述.",
- "required": ["extends", "desc"],
- "additionalProperties": false,
- "properties": {
- "extends": { "type": "string", "description": "桥接到的 stdlib 叶子名 (spec/taxonomy/type.json $leaves 之一)." },
- "desc": { "type": "string", "description": "case-specific 类型的人类可读说明 (renderer drawer + type_suggestions 用)." }
- }
- },
- "Step": {
- "type": "object",
- "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).",
- "required": ["id", "kind", "via", "feature", "inputs", "outputs", "intent"],
- "additionalProperties": false,
- "properties": {
- "id": {
- "type": "string",
- "pattern": "^(s\\d+(\\.\\d+)*|a\\d+)$",
- "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."
- },
- "kind": {
- "enum": ["step", "block", "nested", "atom"],
- "description": "step=plain; block=control-flow parent; nested=child of a block; atom=experimental dimensional projection (only used in case1)."
- },
- "group": {
- "type": "string",
- "description": "When kind=nested, the parent block's id (e.g. 's3')."
- },
- "parent_step": {
- "type": "string",
- "description": "When kind=atom, the host step's id."
- },
- "name": {
- "type": "string",
- "description": "Only meaningful for kind=atom (displayed above the intent text)."
- },
- "key_dim": {
- "type": "string",
- "description": "atom-only: the dimension this atom projects (e.g. '实质' / '形式')."
- },
- "key_value": {
- "type": "string",
- "description": "atom-only: the specific path within the key_dim (e.g. '/表象/视觉/.../形象呈现')."
- },
- "effect": {
- "enum": [
- "预处理", "主体生成", "装配", "后期",
- "工艺规约", "预准备", "配套伴生", "检验", "交付"
- ],
- "description": "§A.1 L3 leaf. Required to hit a leaf — non-leaf = extraction error."
- },
- "via": {
- "type": "string",
- "description": "Canonical L1 tool name (manus / nano_banana_pro / human / <llm-agent>) or generic placeholder for unspecified tools ('(AI 生图工具)'). Use '-' for control-flow blocks."
- },
- "action": {
- "type": "string",
- "pattern": "^[^/]+(/[^/]+)*$",
- "description": "§A.2 path, e.g. '生成/元素生成', '提取/化学提取/反推'. Control-flow already routed to `control` field."
- },
- "feature": {
- "type": "string",
- "enum": ["随机", "幂等", "人工", "本地", "写外部", "读外部", "-"],
- "description": "Execution attribute (internal). Block-level steps use '-'. NEVER referenced in intent column."
- },
- "control": {
- "type": "string",
- "enum": ["并行", "遍历", "分支", "请求", "等待", "", "-"],
- "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)."
- },
- "instruction": {
- "type": "array",
- "description": "Heterogeneous list of (kind, text) tuples. Order is preserved; any subset of kinds is allowed; control-flow blocks usually only carry memo entries.",
- "items": {
- "type": "array",
- "prefixItems": [
- {
- "enum": ["directive", "config", "decorator", "memo"],
- "description": "directive=literal prompt text; config=tool runtime params; decorator=caller-side @decorator; memo=engineering wisdom not captured elsewhere."
- },
- { "type": "string" }
- ],
- "items": false,
- "minItems": 2,
- "maxItems": 2
- }
- },
- "inputs": {
- "type": "array",
- "items": { "$ref": "#/$defs/IOItem" }
- },
- "outputs": {
- "type": "array",
- "items": { "$ref": "#/$defs/IOItem" }
- },
- "intent": {
- "type": "string",
- "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."
- },
- "focus": {
- "type": "array",
- "items": { "type": "string" },
- "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.)."
- },
- "inferred_marks": {
- "type": "object",
- "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.",
- "additionalProperties": { "type": "string" }
- },
- "atoms": {
- "type": "array",
- "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.",
- "items": { "$ref": "#/$defs/Step" }
- }
- },
- "allOf": [
- {
- "if": { "properties": { "kind": { "enum": ["step", "nested", "atom"] } } },
- "then": { "required": ["effect", "action", "focus"] }
- },
- {
- "if": { "properties": { "kind": { "const": "nested" } } },
- "then": { "required": ["group"] }
- },
- {
- "if": { "properties": { "kind": { "const": "atom" } } },
- "then": { "required": ["parent_step", "name", "key_dim", "key_value"] }
- }
- ]
- },
- "IOItem": {
- "type": "object",
- "description": "One row in inputs[] or outputs[]. Input and output items share the same shape (anchor points up for inputs, down for outputs).",
- "required": ["type", "name", "value", "anchor"],
- "additionalProperties": false,
- "properties": {
- "substance": {
- "type": ["string", "null"],
- "description": "What the content IS (理念 vs 表象 layer). Path from `分类库导出_实质_*.json`. null for abstract containers / pure tool params."
- },
- "form": {
- "type": ["string", "null"],
- "description": "How the content is PRESENTED (呈现 vs 架构 layer). Path from `分类库导出_形式_*.json`. null when not applicable."
- },
- "type": {
- "type": "string",
- "description": "§A.3 leaf or case-extended type name."
- },
- "name": {
- "type": "string",
- "description": "Variable identifier within this step. Same concept across steps MUST use the same name (lint enforces this)."
- },
- "value": {
- "type": "string",
- "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)."
- },
- "anchor": {
- "type": "string",
- "description": "Inputs: upstream ref ('← 工序输入', '← sN.varname', '← 容器[i]'). Outputs: downstream destination ('→ sN', '→ 视频片段列表.追加', '→ 返回 X')."
- },
- "inferred": {
- "type": "boolean",
- "description": "True when this whole IO item was filled by 工艺补全 (not in source material). Renderer dyes the entire row's 6 data-flow cells."
- },
- "inferred_reason": {
- "type": "string",
- "description": "REQUIRED when inferred=true. Shown on hover."
- }
- },
- "if": {
- "required": ["inferred"],
- "properties": { "inferred": { "const": true } }
- },
- "then": { "required": ["inferred_reason"] }
- },
- "ReturnRow": {
- "type": "object",
- "description": "Bottom row of the table announcing what the procedure returns.",
- "required": ["arrow", "text"],
- "additionalProperties": false,
- "properties": {
- "arrow": {
- "type": "string",
- "description": "Usually '↩'."
- },
- "text": {
- "type": "string",
- "description": "May contain inline HTML fragments (chip / name / em spans) — emitted verbatim into a colspan=24 cell."
- }
- }
- }
- }
- }
|