@cloud411716/fancy-webnovel 2.2.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. package/client.js +201 -15
  2. package/cordis.patch.yml +5 -0
  3. package/docs/douyin-plugin.md +118 -0
  4. package/docs/material-library/README.md +404 -0
  5. package/docs/material-library/import.js +437 -0
  6. package/docs/material-library/prompt.md +370 -0
  7. package/docs/material-library/queries.surql +94 -0
  8. package/docs/material-library/sample.jsonl +14 -0
  9. package/docs/material-library/schema.surql +46 -0
  10. package/docs/mcp-profile.example.yml +24 -0
  11. package/docs/story-graph-design.md +602 -0
  12. package/docs/story-graph-validation.md +81 -0
  13. package/docs/workspace-mcp.md +284 -0
  14. package/index.js +11 -7
  15. package/lib/atomic-write.js +109 -0
  16. package/lib/chapter-order.js +100 -0
  17. package/lib/confirmation.js +80 -0
  18. package/lib/db-init.js +123 -0
  19. package/lib/deployed-state.js +11 -11
  20. package/lib/direction-labels.js +265 -0
  21. package/lib/error-codes.js +31 -31
  22. package/lib/infra.js +29 -4
  23. package/lib/material-db.js +149 -0
  24. package/lib/path-guard.js +150 -0
  25. package/lib/projects.js +400 -0
  26. package/lib/scraper-utils.js +140 -0
  27. package/lib/surreal-server.js +338 -0
  28. package/lib/topic-decision.js +860 -0
  29. package/lib/topic-fields.js +251 -0
  30. package/lib/topic-schema.js +225 -0
  31. package/lib/workspace.js +501 -0
  32. package/package.json +29 -4
  33. package/plugins/fancy-analyze/analyze-definitions.md +519 -0
  34. package/plugins/fancy-analyze/index.js +1128 -77
  35. package/plugins/fancy-analyze/ingest-coverage.js +107 -0
  36. package/plugins/fancy-analyze/schema-analyze.md +355 -107
  37. package/plugins/fancy-analyze/scripts/append-summary-chapter.js +612 -0
  38. package/plugins/fancy-analyze/summary-progress.js +71 -7
  39. package/plugins/fancy-analyze/templates.js +437 -139
  40. package/plugins/fancy-bootstrap/index.js +276 -131
  41. package/plugins/fancy-bootstrap/scripts/init.js +59 -25
  42. package/plugins/fancy-bootstrap/templates.js +35 -18
  43. package/plugins/fancy-db/index.js +172 -0
  44. package/plugins/fancy-douyin/deploy.js +134 -0
  45. package/plugins/fancy-douyin/index.js +551 -0
  46. package/plugins/fancy-douyin/prompts/01-analysis-prompt.md +84 -0
  47. package/plugins/fancy-douyin/scripts/crawl-note.cjs +194 -0
  48. package/plugins/fancy-douyin/scripts/lib.cjs +197 -0
  49. package/plugins/fancy-douyin/scripts/scan-account.cjs +128 -0
  50. package/plugins/fancy-douyin/scripts/start-chrome.cjs +203 -0
  51. package/plugins/fancy-douyin/state.js +197 -0
  52. package/plugins/fancy-douyin/templates.js +127 -0
  53. package/plugins/fancy-export/exporter.js +805 -0
  54. package/plugins/fancy-export/index.js +63 -0
  55. package/plugins/fancy-import/import-driver.js +29 -6
  56. package/plugins/fancy-import/index.js +13 -5
  57. package/plugins/fancy-import/prompts/01-import-prompt.md +39 -14
  58. package/plugins/fancy-import/templates.js +17 -8
  59. package/plugins/fancy-material/exporter.js +153 -0
  60. package/plugins/fancy-material/genres.js +256 -0
  61. package/plugins/fancy-material/index.js +835 -0
  62. package/plugins/fancy-material/inventory.js +143 -0
  63. package/plugins/fancy-material/kinds.js +313 -0
  64. package/plugins/fancy-material/queue.js +55 -0
  65. package/plugins/fancy-material/scripts/query.js +254 -0
  66. package/plugins/fancy-material/templates.js +258 -0
  67. package/plugins/fancy-material/tool-deploy.js +138 -0
  68. package/plugins/fancy-material/validate.js +149 -0
  69. package/plugins/fancy-project/index.js +133 -0
  70. package/plugins/fancy-scan/existing-block.js +100 -0
  71. package/plugins/fancy-scan/index.js +410 -21
  72. package/plugins/fancy-scan/prompts/01-analysis-prompt.md +302 -0
  73. package/plugins/fancy-scan/scripts/append-block.js +725 -0
  74. package/plugins/fancy-scan/scripts/report-validate.js +824 -0
  75. package/plugins/fancy-scan/scripts/run-scan.js +169 -22
  76. package/plugins/fancy-scan/scripts/scrapers/fanqie-rank-scraper.js +145 -16
  77. package/plugins/fancy-scan/scripts/scrapers/jjwxc-rank-scraper.js +179 -49
  78. package/plugins/fancy-scan/scripts/scrapers/qimao-rank-scraper.js +38 -20
  79. package/plugins/fancy-scan/templates/blocks.js +155 -0
  80. package/plugins/fancy-scan/templates/platforms.js +372 -0
  81. package/plugins/fancy-scan/templates/report-schema.js +90 -0
  82. package/plugins/fancy-scan/templates.js +545 -146
  83. package/plugins/fancy-scan/tool-deploy.js +335 -0
  84. package/plugins/fancy-scan/wait-turn.js +46 -0
  85. package/plugins/fancy-story-builder/db/README.md +106 -0
  86. package/plugins/fancy-story-builder/db/client.js +228 -0
  87. package/plugins/fancy-story-builder/db/commands.js +145 -0
  88. package/plugins/fancy-story-builder/db/ids.js +39 -0
  89. package/plugins/fancy-story-builder/db/import.js +798 -0
  90. package/plugins/fancy-story-builder/db/project.js +299 -0
  91. package/plugins/fancy-story-builder/db/query.js +361 -0
  92. package/plugins/fancy-story-builder/db/schema.js +417 -0
  93. package/plugins/fancy-story-builder/db/stage-sync.js +238 -0
  94. package/plugins/fancy-story-builder/flesh-output.js +19 -6
  95. package/plugins/fancy-story-builder/index.js +4105 -396
  96. package/plugins/fancy-story-builder/patch-driver.js +390 -0
  97. package/plugins/fancy-story-builder/prompts/01-skeleton-prompt.md +29 -19
  98. package/plugins/fancy-story-builder/prompts/02-flesh-prompt.md +72 -10
  99. package/plugins/fancy-story-builder/prompts/03-rhythm-prompt.md +40 -5
  100. package/plugins/fancy-story-builder/prompts/04-writing-prompt.md +37 -0
  101. package/plugins/fancy-story-builder/purpose-template.md +42 -66
  102. package/plugins/fancy-story-builder/references/formulas-skeleton.json +229 -56
  103. package/plugins/fancy-story-builder/references/genre-profiles.json +3514 -0
  104. package/plugins/fancy-story-builder/references/glossary.md +15 -6
  105. package/plugins/fancy-story-builder/references/index.md +97 -6
  106. package/plugins/fancy-story-builder/references//350/212/202/345/245/217/346/214/207/345/257/274/00-index.md +1 -1
  107. package/plugins/fancy-story-builder/references//350/212/202/345/245/217/346/214/207/345/257/274/07-audit.md +25 -7
  108. package/plugins/fancy-story-builder/references//350/241/200/350/202/211/346/214/207/345/257/274/01-character.md +5 -1
  109. package/plugins/fancy-story-builder/references//350/241/200/350/202/211/346/214/207/345/257/274/03-relations.md +6 -2
  110. package/plugins/fancy-story-builder/references//350/241/200/350/202/211/346/214/207/345/257/274/05-audit.md +15 -5
  111. package/plugins/fancy-story-builder/references//351/252/250/346/236/266/346/214/207/345/257/274/00-index.md +1 -1
  112. package/plugins/fancy-story-builder/references//351/252/250/346/236/266/346/214/207/345/257/274/01-positioning.md +2 -1
  113. package/plugins/fancy-story-builder/references//351/252/250/346/236/266/346/214/207/345/257/274/03-entities.md +1 -1
  114. package/plugins/fancy-story-builder/references//351/252/250/346/236/266/346/214/207/345/257/274/06-audit.md +19 -1
  115. package/plugins/fancy-story-builder/schema-setting.json +1100 -0
  116. package/plugins/fancy-story-builder/schema-setting.md +201 -293
  117. package/plugins/fancy-story-builder/scripts/brief-validate.js +164 -0
  118. package/plugins/fancy-story-builder/scripts/content-quality.js +4 -1
  119. package/plugins/fancy-story-builder/scripts/flesh-validate.js +135 -12
  120. package/plugins/fancy-story-builder/scripts/graph-utils.js +146 -47
  121. package/plugins/fancy-story-builder/scripts/reference-log.js +110 -0
  122. package/plugins/fancy-story-builder/scripts/rhythm-validate.js +100 -4
  123. package/plugins/fancy-story-builder/scripts/schema-pages.js +2668 -0
  124. package/plugins/fancy-story-builder/scripts/semantic-lint.js +5 -1
  125. package/plugins/fancy-story-builder/scripts/skeleton-validate.js +158 -17
  126. package/plugins/fancy-story-builder/scripts/stage-batches.js +36 -2
  127. package/plugins/fancy-story-builder/scripts/stage-contract.js +12 -0
  128. package/plugins/fancy-story-builder/scripts/story-artifacts.js +933 -0
  129. package/plugins/fancy-story-builder/scripts/upstream-query.js +1 -1
  130. package/plugins/fancy-story-builder/scripts/v2/baseline.js +112 -0
  131. package/plugins/fancy-story-builder/scripts/v2/cast.js +517 -0
  132. package/plugins/fancy-story-builder/scripts/v2/context.js +434 -0
  133. package/plugins/fancy-story-builder/scripts/v2/contracts.js +493 -0
  134. package/plugins/fancy-story-builder/scripts/v2/core.js +419 -0
  135. package/plugins/fancy-story-builder/scripts/v2/engine.js +1068 -0
  136. package/plugins/fancy-story-builder/scripts/v2/export-markdown.js +794 -0
  137. package/plugins/fancy-story-builder/scripts/v2/genre.js +195 -0
  138. package/plugins/fancy-story-builder/scripts/v2/knowledge.js +321 -0
  139. package/plugins/fancy-story-builder/scripts/v2/macro.js +409 -0
  140. package/plugins/fancy-story-builder/scripts/v2/manifest.js +538 -0
  141. package/plugins/fancy-story-builder/scripts/v2/migrate.js +137 -0
  142. package/plugins/fancy-story-builder/scripts/v2/prompts.js +1335 -0
  143. package/plugins/fancy-story-builder/scripts/v2/rhythm.js +618 -0
  144. package/plugins/fancy-story-builder/scripts/v2/scale.js +843 -0
  145. package/plugins/fancy-story-builder/scripts/v2/snapshot.js +121 -0
  146. package/plugins/fancy-story-builder/scripts/v2/stages.js +273 -0
  147. package/plugins/fancy-story-builder/scripts/v2/writing.js +216 -0
  148. package/plugins/fancy-story-builder/storydb/README.md +271 -0
  149. package/plugins/fancy-story-builder/storydb/cli.js +458 -0
  150. package/plugins/fancy-story-builder/storydb/client.js +351 -0
  151. package/plugins/fancy-story-builder/storydb/compile.js +452 -0
  152. package/plugins/fancy-story-builder/storydb/context.js +288 -0
  153. package/plugins/fancy-story-builder/storydb/definitions.js +699 -0
  154. package/plugins/fancy-story-builder/storydb/driver.js +106 -0
  155. package/plugins/fancy-story-builder/storydb/dsh-tools.js +313 -0
  156. package/plugins/fancy-story-builder/storydb/export.js +175 -0
  157. package/plugins/fancy-story-builder/storydb/ids.js +31 -0
  158. package/plugins/fancy-story-builder/storydb/impact.js +170 -0
  159. package/plugins/fancy-story-builder/storydb/import.js +559 -0
  160. package/plugins/fancy-story-builder/storydb/mcp.js +99 -0
  161. package/plugins/fancy-story-builder/storydb/prompts.js +952 -0
  162. package/plugins/fancy-story-builder/storydb/stage-command.js +379 -0
  163. package/plugins/fancy-story-builder/storydb/stage.js +426 -0
  164. package/plugins/fancy-story-builder/storydb/store.js +891 -0
  165. package/plugins/fancy-story-builder/storydb/tools.js +592 -0
  166. package/plugins/fancy-story-builder/storydb/validation.js +183 -0
  167. package/plugins/fancy-story-builder/templates/v2/10-scale/scale-template.json +144 -0
  168. package/plugins/fancy-story-builder/templates/v2/20-macro/emotion-template.json +15 -0
  169. package/plugins/fancy-story-builder/templates/v2/20-macro/endings-template.json +16 -0
  170. package/plugins/fancy-story-builder/templates/v2/20-macro/lines-template.json +28 -0
  171. package/plugins/fancy-story-builder/templates/v2/20-macro/roles-template.json +10 -0
  172. package/plugins/fancy-story-builder/templates/v2/20-macro/story-template.json +19 -0
  173. package/plugins/fancy-story-builder/templates/v2/20-macro/volumes-template.json +24 -0
  174. package/plugins/fancy-story-builder/templates/v2/20-macro/world-template.json +24 -0
  175. package/plugins/fancy-story-builder/templates/v2/30-cast/characters-template.json +49 -0
  176. package/plugins/fancy-story-builder/templates/v2/30-cast/climaxes-template.json +14 -0
  177. package/plugins/fancy-story-builder/templates/v2/30-cast/conflicts-template.json +30 -0
  178. package/plugins/fancy-story-builder/templates/v2/30-cast/factions-template.json +18 -0
  179. package/plugins/fancy-story-builder/templates/v2/30-cast/foreshadows-template.json +29 -0
  180. package/plugins/fancy-story-builder/templates/v2/30-cast/information-template.json +29 -0
  181. package/plugins/fancy-story-builder/templates/v2/30-cast/items-template.json +13 -0
  182. package/plugins/fancy-story-builder/templates/v2/30-cast/locations-template.json +12 -0
  183. package/plugins/fancy-story-builder/templates/v2/30-cast/payoffs-template.json +16 -0
  184. package/plugins/fancy-story-builder/templates/v2/30-cast/relations-template.json +44 -0
  185. package/plugins/fancy-story-builder/templates/v2/40-rhythm/chapter-map-template.json +81 -0
  186. package/plugins/fancy-story-builder/templates/v2/40-rhythm/outline-template.json +162 -0
  187. package/plugins/fancy-story-builder/templates/v2/50-writing/ledger-template.json +46 -0
  188. package/plugins/fancy-story-builder/templates/v2/60-deslop/report-template.json +10 -0
  189. package/plugins/fancy-story-builder/templates//350/212/202/345/245/217//346/227/266/345/272/217/346/230/240/345/260/204/346/250/241/346/235/277.json +267 -44
  190. package/plugins/fancy-story-builder/templates//350/241/200/350/202/211//344/270/226/347/225/214/350/247/202/350/247/204/345/210/231/346/250/241/346/235/277.json +121 -19
  191. package/plugins/fancy-story-builder/templates//350/241/200/350/202/211//345/205/263/351/224/256/351/201/223/345/205/267/346/250/241/346/235/277.json +129 -21
  192. package/plugins/fancy-story-builder/templates//350/241/200/350/202/211//345/205/266/344/273/226/345/256/236/344/275/223/346/250/241/346/235/277.json +62 -0
  193. package/plugins/fancy-story-builder/templates//350/241/200/350/202/211//345/206/262/347/252/201/346/250/241/346/235/277.json +76 -17
  194. package/plugins/fancy-story-builder/templates//350/241/200/350/202/211//345/211/247/346/203/205/346/250/241/346/235/277.json +56 -8
  195. package/plugins/fancy-story-builder/templates//350/241/200/350/202/211//345/212/277/345/212/233/346/250/241/346/235/277.json +63 -13
  196. package/plugins/fancy-story-builder/templates//350/241/200/350/202/211//345/234/260/347/202/271/346/250/241/346/235/277.json +34 -6
  197. package/plugins/fancy-story-builder/templates//350/241/200/350/202/211//347/273/223/345/261/200/346/250/241/346/235/277.json +81 -18
  198. package/plugins/fancy-story-builder/templates//350/241/200/350/202/211//350/247/222/350/211/262/346/250/241/346/235/277.json +202 -42
  199. package/plugins/fancy-story-builder/templates//351/252/250/346/236/266//345/205/263/347/263/273/346/250/241/346/235/277.json +160 -27
  200. package/plugins/fancy-story-builder/templates//351/252/250/346/236/266//345/256/236/344/275/223/346/250/241/346/235/277.json +217 -41
  201. package/plugins/fancy-story-builder/templates//351/252/250/346/236/266//346/241/206/346/236/266/346/250/241/346/235/277.json +215 -41
  202. package/plugins/fancy-story-builder/templates.js +272 -74
  203. package/plugins/fancy-story-builder/wiki-references.js +429 -93
  204. package/plugins/fancy-story-builder/writing-driver.js +336 -9
  205. package/plugins/fancy-topic/index.js +414 -61
  206. package/plugins/fancy-topic/prompts/01-exploration-prompt.md +115 -0
  207. package/plugins/fancy-topic/scripts/save-suggestion.js +219 -0
  208. package/plugins/fancy-topic/scripts/select-topic.js +106 -63
  209. package/plugins/fancy-topic/templates.js +225 -122
  210. package/plugins/fancy-topic/tool-deploy.js +200 -0
  211. package/lib/safe-rm.js +0 -94
@@ -42,6 +42,7 @@ ${input_snapshot_block}
42
42
 
43
43
  - 血肉阶段的**实体信息**从骨架的 4 个 JSON 读,不从任务输入读。
44
44
  - 但任务输入里的**硬门禁**和**反套路**是血肉阶段的硬约束:写实体的目标、资源、压制手段、成员关系时不得违背。
45
+ - 任务输入里的**方向设计**是选定方向的既定设计:核心设定、世界规则、金手指的代价与限制、人物设定框架都要与它一致,不得另起炉灶。
45
46
  - **核心冲突**决定血肉往哪个方向细化:每个势力的资源、内部结构、压制手段,都要能解释它怎么参与(或被排除在)核心冲突。
46
47
  - 任务输入的**书名 / 题材 / 目标章节**只用于确认"读的是同一个项目",不要拿它们当硬约束。
47
48
 
@@ -60,6 +61,7 @@ ${input_snapshot_block}
60
61
  | 6 | 结局.json | `设定/raw/sources/血肉/结局.json` | `endings` |
61
62
  | 7 | 世界观规则.json | `设定/raw/sources/血肉/世界观规则.json` | `core_rules` + `information_rules` + `social_rules` + `rule_conflict_plan` |
62
63
  | 8 | 关键道具.json | `设定/raw/sources/血肉/关键道具.json` | `core_items` + `branch_items` + `symbolic_items` + `details` |
64
+ | 9(按需) | 其他实体.json | `设定/raw/sources/血肉/其他实体.json` | `other_entities` |
63
65
 
64
66
  **你每次只写其中一个文件的**。插件会分批发指令,每条指令只涉及一个文件、一个数组。
65
67
 
@@ -80,7 +82,7 @@ ${input_snapshot_block}
80
82
 
81
83
  5. **世界观规则 id 前缀与所属数组匹配**:`core_rules` 用 `R`,`information_rules` 用 `I`,`social_rules` 用 `SR`。`FLESH_WORLD_RULE_CATEGORY` 会拦截。
82
84
 
83
- 6. **关系类型必须与骨架完全一致**。`relationships[].relationship_type` 只能取 glossary 第五节 `relation_kind` 的 12 个值(血缘/师徒/雇佣/服从/提携/合作/利益交换/利用/对立/敌对/竞争/中立),而且**必须等于骨架里同一对角色的关系类型**。骨架写"A 服从 B",这里就不能写"上下级"或"盟友"。`REL_TYPE_MISMATCH` / `ENUM` 会拦截。
85
+ 6. **关系类型必须与骨架完全一致**。`relationships[].relationship_type` 只能取 glossary 第五节 `relation_kind` 的 13 个值(血缘/师徒/雇佣/服从/提携/合作/利益交换/利用/对立/敌对/竞争/中立/其他),而且**必须等于骨架里同一对角色的关系类型**。骨架写"A 服从 B",这里就不能写"上下级"或"盟友";用 `其他` 时必须同时填 `relation_label`(如 附身/寄生/契约)。非人物实体参与的关系在骨架 `other_relations`,本项目不写进 `relationships[]`。`REL_TYPE_MISMATCH` / `REL_LABEL_REQUIRED` / `ENUM` 会拦截。
84
86
 
85
87
  7. **描述要写实,不能写空话**。`description` / `core_flaw` / `goals.*` 这类叙述字段要写出一个具体事实,而不是"很好""详细设定。"。`TEXT_TOO_SHORT` / `TEXT_PLACEHOLDER` 会拦截;不同角色不能共用同一段话(`TEXT_DUPLICATE`)。
86
88
 
@@ -124,6 +126,18 @@ node references/upstream-query.js --stage=骨架 --file=实体 --id=C001 #
124
126
  node references/upstream-query.js --stage=骨架 --file=关系 --list # 看该文件有哪些记录分组
125
127
  ```
126
128
 
129
+ **这个脚本怎么判**(返回是 JSON,看 `status`,**没有 `ok` 字段**):
130
+
131
+ | status | 含义 | 怎么办 |
132
+ |---|---|---|
133
+ | `0` | 查到了 | 用返回的 `items` |
134
+ | `1` | **没查到**(不是失败) | `items` 是空数组。换个 `--id`,或用 `--list` 看有哪些记录 |
135
+ | `2` | 参数错 / 上游文件读不到 | 看 stdout 的 `error` 字段(**stderr 是空的**)。**改命令,不要编内容** |
136
+
137
+ `status:2` 时 stdout 里没有 `items`,只有 `error`。
138
+ 拿不到档案就**用指令里已经给的 id+name 写**,不要凭印象补一份档案 ——
139
+ 编出来的字段会带着假信息进成品,比缺字段更糟。
140
+
127
141
  - 不得声称"已读取"参考文件。
128
142
 
129
143
  ---
@@ -162,6 +176,8 @@ node references/upstream-query.js --stage=骨架 --file=关系 --list #
162
176
  | `language_profile.personality_tone` | 性格基调(冷硬/温和/尖刻/木讷) |
163
177
  | `language_profile.relationship_stage_tone` | 对不同关系的人说话语气怎么变 |
164
178
  | `behavior_repeat_points` | 反复出现的小动作或口头习惯,字符串数组 |
179
+ | `traits` | **必填 3-5 条**独有特征/习惯/感官锚点。每条都要能在场景里演出来,不要写"善良""勇敢"这类评价词 |
180
+ | `extensions` | 题材特有的扩展设定;键用中文,值用字符串/数组。不要塞章节号 |
165
181
  | `mirror_type` | 反派专用:与主角互为镜像的类型,取 glossary `mirror_type` 词表。非反派不填 |
166
182
  | `relationships[]` | 关系条目,见下 |
167
183
  | `arc_changes[]` | 弧光变化条目:`stage`(阶段序号)+ `description`(这一阶段他变了什么) |
@@ -176,10 +192,10 @@ node references/upstream-query.js --stage=骨架 --file=关系 --list #
176
192
 
177
193
  ### `relationships[]` 的写法
178
194
 
179
- 每条三个必填字段:`target_name` / `relationship_type` / `description`,可选 `changes[]`(`from` / `to` / `description`,写关系随剧情怎么变)。
195
+ 每条三个必填字段:`target_name` / `relationship_type` / `description`。`relationship_type=其他` 时加 `relation_label`。可选 `changes[]`:每条至少写 `stage`(阶段名)/ `from`(变化前状态)/ `to`(变化后状态)/ `trigger`(触发事件)/ `description`(怎么变),可加 `timing`(前期/中期/后期/某卷,不写章节号)。
180
196
 
181
197
  - `target_name` 写**对方的角色名**(不是 id)。
182
- - `relationship_type` 只能取 glossary 第五节 `relation_kind` 的 12 个值。
198
+ - `relationship_type` 只能取 glossary 第五节 `relation_kind` 的 13 个值;`其他` 必须配 `relation_label`。
183
199
  - **必须和骨架给的关系完全一致**:插件会在指令里把本批角色涉及的关系列出来,照抄 `relation_kind` 即可。
184
200
  - **方向不能反**:骨架 `C001 → C002 = 师徒`,意思"C001 是 C002 的师父",所以关系写在 **C001** 的文件里,`target_name` 写 C002 的名字。写在 C002 文件里就是 `REL_DIRECTION_FLIP`。
185
201
  - 骨架里没写过的关系**不要自己加**(`REL_NOT_IN_SKELETON`)。骨架写的是双向关系时,两个方向都要写。
@@ -212,6 +228,8 @@ node references/upstream-query.js --stage=骨架 --file=关系 --list #
212
228
  | `resolution_plan.method` | 怎么收场 |
213
229
  | `resolution_plan.residual_impact` | 收完还剩什么后遗症(余韵) |
214
230
  | `information_gaps[]` | 信息差条目:`info_name` / `who_knows[]` / `who_does_not_know[]` / `resolution_method` |
231
+ | `traits` | 可选:2-5 条独属于这个冲突的特征/气味/反复出现的场面 |
232
+ | `extensions` | 可选:题材特有扩展(如 诡计类型/献祭规则),键用中文,不写章节号 |
215
233
 
216
234
  ### 不填的字段
217
235
 
@@ -237,6 +255,8 @@ node references/upstream-query.js --stage=骨架 --file=关系 --list #
237
255
  | `main_line_connection` | 它和主线的关系:参与还是被排除,排除的理由是什么 |
238
256
  | `members[]` | 成员条目:`name`(**角色名,不是 id**)/ `position_description`(这个人在势力里的位置)/ `relation_description`(他为什么在这里) |
239
257
  | `relations[]` | 势力关系条目:`target_name`(**对方势力名**)/ `description`(关系是什么样的) |
258
+ | `traits` | 可选:2-5 条独属于这个势力的规矩/气味/仪式 |
259
+ | `extensions` | 可选:题材特有扩展(如 灵脉/香火/阴兵),键用中文,不写章节号 |
240
260
 
241
261
  ### 不填的字段
242
262
 
@@ -268,6 +288,8 @@ node references/upstream-query.js --stage=骨架 --file=关系 --list #
268
288
  | `goal` | 这条支线要达成什么 |
269
289
  | `main_relation` | 它和主线的关系(怎么挂上去、挂在哪一段) |
270
290
  | `expected_outcome` | 预期结果:这条线走完给出什么 |
291
+ | `traits` | 可选:2-5 条独属于这条线的特征/意象/反复桥段 |
292
+ | `extensions` | 可选:题材特有扩展,键用中文,不写章节号 |
271
293
 
272
294
  ### 不填的字段
273
295
 
@@ -288,6 +310,8 @@ node references/upstream-query.js --stage=骨架 --file=关系 --list #
288
310
  | `features.key_elements[]` | 关键陈设/要素,字符串数组 |
289
311
  | `key_event_descriptions[]` | 这里发生过什么关键事件,字符串数组 |
290
312
  | `narrative_role_description` | 叙事作用:这个地点在故事里承担什么(人物主场/线索源头/压迫空间……) |
313
+ | `traits` | 可选:2-5 条独属于这个地点的声音/气味/光线/禁忌 |
314
+ | `extensions` | 可选:题材特有扩展(如 阴气/灵脉/结界规则),键用中文,不写章节号 |
291
315
 
292
316
  ### 不填的字段
293
317
 
@@ -321,6 +345,8 @@ node references/upstream-query.js --stage=骨架 --file=关系 --list #
321
345
  | `memorable_scenes[]` | 值得记住的场面,字符串数组 |
322
346
  | `epilogue_hints[]` | 尾声暗示,字符串数组 |
323
347
  | `foreshadow_recovery_plan[]` | 伏笔回收条目:`foreshadow_id`(**必须是骨架 `实体.json` 里真实存在的伏笔 id**)+ `method`(怎么回收) |
348
+ | `traits` | 可选:2-5 条独属于这个结局的情绪/意象/收束方式 |
349
+ | `extensions` | 可选:题材特有扩展,键用中文,不写章节号 |
324
350
 
325
351
  ### 不填的字段
326
352
 
@@ -355,6 +381,8 @@ node references/upstream-query.js --stage=骨架 --file=关系 --list #
355
381
  | `content` | 规则本身 |
356
382
  | `violation_consequence` | 违反这条会付出什么代价 |
357
383
  | `impact_on_plot` | 这条规则怎么推着剧情走 |
384
+ | `traits` | 可选:2-5 条独属于这条规则的表现/禁忌/代价 |
385
+ | `extensions` | 可选:题材特有扩展,键用中文,不写章节号 |
358
386
 
359
387
  ### `rule_conflict_plan[]`(规则冲突预案)
360
388
 
@@ -406,6 +434,8 @@ node references/upstream-query.js --stage=骨架 --file=关系 --list #
406
434
  | `limit` | 限制:它做不到什么(可空) |
407
435
  | `related_characters[]` | 相关角色**名字**,字符串数组 |
408
436
  | `related_conflicts[]` | 相关冲突**名字**,字符串数组 |
437
+ | `traits` | 可选:2-5 条独属于这件道具的磨损/声音/使用痕迹 |
438
+ | `extensions` | 可选:题材特有扩展(如 器灵/诅咒/认主规则),键用中文,不写章节号 |
409
439
 
410
440
  ### 不填的字段
411
441
 
@@ -414,12 +444,38 @@ node references/upstream-query.js --stage=骨架 --file=关系 --list #
414
444
 
415
445
  ---
416
446
 
447
+ <!-- contract:file:其他实体 -->
448
+ ## 十三、其他实体.json 的字段契约(按需)
449
+
450
+ **顶层数组**:`other_entities` **模板**:`模板/血肉/其他实体模板.json`
451
+
452
+ 只有骨架 `实体.json` 的 `other_entities` 非空时才需要写这个文件。它给灵魂/神魂/器灵/妖灵/鬼魂/概念体等**不适合当人物**的存在补档案;id 和 name 必须从骨架原样抄。
453
+
454
+ | 字段 | 写什么 |
455
+ |---|---|
456
+ | `id` | 骨架 `other_entities` 的 id(`O001` 起),原样抄 |
457
+ | `name` | 骨架名,逐字一致 |
458
+ | `kind` | 具体类别:灵魂 / 神魂 / 器灵 / 妖灵 / 鬼魂 / 概念体 …,不要只写"其他" |
459
+ | `description` | 它是什么、现在附着/盘踞在哪里、对谁构成影响 |
460
+ | `traits` | 2-6 条独有特征/征兆/感官锚点(如"出现时铜铃只响不落灰") |
461
+ | `abilities[]` | 能做什么;每条写清代价或限制,不要写万能能力 |
462
+ | `limits[]` | 不能做什么、怕什么、受什么约束 |
463
+ | `extensions` | 题材特有扩展,键用中文,不写章节号 |
464
+
465
+ ### 不填的字段
466
+
467
+ - **不填章节号**:它何时出现、何时附身、何时离开,属于节奏阶段的 `时序映射.json`。
468
+ - **不填关系**:它与人物的附身/寄宿/共生/镇压关系在骨架 `关系.json` 的 `other_relations`,此处只写档案。
469
+ - **不要把它写成人物**:不要加 `goals` / `arc_type` / `language_profile` 这类角色字段。
470
+
471
+ ---
472
+
417
473
  <!-- contract:quality -->
418
- ## 十三、关系类型与内容质量(照着正例写)
474
+ ## 十四、关系类型与内容质量(照着正例写)
419
475
 
420
476
  脚本不只查结构,也查"写的东西是不是真的"、"两个阶段说的是不是同一件事"。
421
477
 
422
- **关系类型**——`relationships[].relationship_type` 只从这 12 个值里选,且必须与骨架一致:
478
+ **关系类型**——`relationships[].relationship_type` 只从这 13 个值里选,且必须与骨架一致:
423
479
 
424
480
  | 词表值 | 正例(骨架 `关系.json` → 血肉 `角色.json`) |
425
481
  |---|---|
@@ -432,8 +488,9 @@ node references/upstream-query.js --stage=骨架 --file=关系 --list #
432
488
  | 利益交换 | 骨架 `C001 → C002` = `利益交换` → 写 `利益交换` |
433
489
  | 利用 | 骨架 `C001 → C002` = `利用` → 利用者写 `利用` |
434
490
  | 对立 / 敌对 / 竞争 / 中立 | 同理,逐一照抄骨架的值 |
491
+ | 其他 | 词表外的角色关系(附身/寄生/契约…),必须同时填 `relation_label`,并与骨架完全一致 |
435
492
 
436
- **不要写的**(不在词表,`ENUM` 拦截):`盟友`→`合作`;`对手`→`对立` 或 `敌对`;`上下级`→先想清楚是`师徒`/`雇佣`/`服从`哪一个;`血亲`→`血缘`。
493
+ **不要写的**(不在词表,`ENUM` 拦截):`盟友`→`合作`;`对手`→`对立` 或 `敌对`;`上下级`→先想清楚是`师徒`/`雇佣`/`服从`哪一个;`血亲`→`血缘`;`附身`→人物之间写 `其他` + `relation_label`,非人物存在写骨架 `other_relations`。
437
494
 
438
495
  **关系方向**:`relationships[]` 表达的是"**本角色**对 `target_name` 的关系",方向与骨架的 `from`→`to` 一致。
439
496
 
@@ -457,7 +514,7 @@ node references/upstream-query.js --stage=骨架 --file=关系 --list #
457
514
  ---
458
515
 
459
516
  <!-- contract:errors -->
460
- ## 十四、常见错误代码速查
517
+ ## 十五、常见错误代码速查
461
518
 
462
519
  插件回喂给你的错误清单里的 `code` 对应下表。**只改被点名的字段**,其余不要动。
463
520
 
@@ -483,6 +540,9 @@ node references/upstream-query.js --stage=骨架 --file=关系 --list #
483
540
  | `REL_NOT_IN_SKELETON` | 血肉声明了骨架没有的关系对 | 骨架补上,或删掉血肉这条 |
484
541
  | `REL_DIRECTION_FLIP` | 有向关系被写到了反方向 | 写回关系起点那个角色的文件里 |
485
542
  | `REL_UNDECLARED`(warning) | 骨架的关系还没在血肉里展开 | 补该角色的 relationships 条目 |
543
+ | `FLESH_TRAITS_MISSING` / `FLESH_TRAITS_COUNT` / `FLESH_TRAITS_DUPLICATE` | 角色的独有特征缺失/条数不对/重复 | 补 3-5 条具体特征,删重复 |
544
+ | `REL_CHANGE_INCOMPLETE` | 关系变化缺 stage/from/to/trigger/description | 按五段写全,章节号留给节奏 |
545
+ | `REL_LABEL_REQUIRED` / `REL_LABEL_MISMATCH` | `其他` 关系缺标签,或标签与骨架不一致 | 补 `relation_label` 或照抄骨架 |
486
546
  | `FLESH_SELF_RELATION` | 角色把自己列为关系对象 | 删掉;自我矛盾写进 description / core_flaw |
487
547
  | `FLESH_GROUP_CATEGORY_MISMATCH` | 分组与所属数组不匹配 | 调整分组 |
488
548
  | `FLESH_EXPECTED_VOLUME_MISSING`(warning) | exclusive_needs.expected_volume 不在骨架卷里 | 改为骨架层级里已存在的卷 id |
@@ -498,7 +558,7 @@ node references/upstream-query.js --stage=骨架 --file=关系 --list #
498
558
  ---
499
559
 
500
560
  <!-- contract:forbidden -->
501
- ## 十五、本阶段禁令(11 条)
561
+ ## 十六、本阶段禁令(12 条)
502
562
 
503
563
  1. **不得出现任何章节号**——单章号字段(`chapter` / `ch` / `start` / `end` / `turning` / `midpoint` / `resolution` / `resolution_chapter` / `appear_start` / `appear_end` / `exit_chapter` / `buried_chapter` / `recovered_chapter` / `hook_chapter` / `climax_chapter` / `pleasure_chapter`)、区间字段(`appearance_chapters` / `chapter_range`)、嵌套形式(`escalation_nodes[].chapter` / `info_gaps[].created` / `key_nodes[].chapter` / `arc_stages[].chapter` / `interweaves[].chapter` / `foreshadow_recovery[].chapter`)**全部禁止**;完整清单见 glossary 第六节(脚本按它判定,别自己猜字段名)。
504
564
 
@@ -520,12 +580,14 @@ node references/upstream-query.js --stage=骨架 --file=关系 --list #
520
580
 
521
581
  10. **不得输出"通过/完成/PASS"等结论词**,不得宣布阶段结束。阶段成败由插件判定。
522
582
 
523
- 11. **不得修改 `模板/` 和 `references/` 下的任何文件**,也不得修改 `设定/raw/sources/骨架/` 下的任何文件。这三者都是**只读输入**。严禁为了"通过校验"而修改校验脚本或规则文件——所有脚本与参考文件的修改由项目维护者通过 plugin 升级路径完成。**本阶段的输出目录 `设定/raw/sources/血肉/` 是你要写的产物**。
583
+ 11. **角色必须写 `traits`(3-5 条独有特征)**;关系变化必须写全 `stage` / `from` / `to` / `trigger` / `description`;`relationship_type=其他` 必须写 `relation_label`。特征和关系阶段是人物立得住的核心,不是可选项。
584
+
585
+ 12. **不得修改 `模板/` 和 `references/` 下的任何文件**,也不得修改 `设定/raw/sources/骨架/` 下的任何文件。这三者都是**只读输入**。严禁为了"通过校验"而修改校验脚本或规则文件——所有脚本与参考文件的修改由项目维护者通过 plugin 升级路径完成。**本阶段的输出目录 `设定/raw/sources/血肉/` 是你要写的产物**。
524
586
 
525
587
  ---
526
588
 
527
589
  <!-- contract:semantic -->
528
- ## 十六、语义检查(可选,由用户显式开启)
590
+ ## 十七、语义检查(可选,由用户显式开启)
529
591
 
530
592
  上面的校验全是**确定性脚本**:id 在不在、名字对不对、枚举合不合法、配额对不对得上、关系有没有声明。凡是脚本能判死的问题,都已经被判死了。
531
593
 
@@ -44,6 +44,7 @@ ${input_snapshot_block}
44
44
  - 节奏阶段的**实体信息**从骨架 + 血肉的上游产物读(校验脚本实际读 6 个:骨架 `框架.json`/`实体.json`/`层级.json` + 血肉 `角色.json`/`地点.json`/`关键道具.json`),不从任务输入读。
45
45
  - **目标章节 T** 和 **目标字数**是节奏阶段的硬约束:章节数、高潮/爽点/伏笔的数量配额都必须对得上。
46
46
  - **硬门禁**和**反套路**同样适用于节奏阶段:例如"每 8 至 12 章必须完成一个案件单元闭环"这类硬门禁,直接决定章节切分粒度。
47
+ - 任务输入里的**方向设计**给出了既定的爽点模式、情绪价值曲线、开篇切入点与节奏规划:排卷、分章、配高潮时要与它对齐,不要另排一套。
47
48
  - 书名 / 题材 / 一句话故事 / 核心冲突只用于确认"读的是同一个项目"以及把握全剧走向。
48
49
 
49
50
  ---
@@ -55,7 +56,7 @@ ${input_snapshot_block}
55
56
  |---|---|---|---|
56
57
  | 1 | 章节规划.json | `设定/raw/sources/节奏/章节规划.json` | `chapters` |
57
58
  | 2 | 节奏参数.json | `设定/raw/sources/节奏/节奏参数.json` | 纯对象(无顶层数组) |
58
- | 3 | 时序映射.json | `设定/raw/sources/节奏/时序映射.json` | 11 个 `*_timeline` 数组 |
59
+ | 3 | 时序映射.json | `设定/raw/sources/节奏/时序映射.json` | 13 个 `*_timeline` 数组(含 `relationship_timeline`、`faction_relationship_timeline`) |
59
60
  | 4 | 章节细纲.json | `设定/raw/sources/节奏/章节细纲.json` | `outlines` |
60
61
 
61
62
  **生成顺序(严格按依赖,不可跳)**:章节规划 → 节奏参数 → 时序映射 → 章节细纲。
@@ -118,6 +119,18 @@ node references/upstream-query.js --stage=骨架 --file=实体 --id=FS042
118
119
  node references/upstream-query.js --stage=血肉 --file=角色 --id=C001
119
120
  ```
120
121
 
122
+ **这个脚本怎么判**(返回是 JSON,看 `status`,**没有 `ok` 字段**):
123
+
124
+ | status | 含义 | 怎么办 |
125
+ |---|---|---|
126
+ | `0` | 查到了 | 用返回的 `items` |
127
+ | `1` | **没查到**(不是失败) | `items` 是空数组。换个 `--id`,或用 `--list` 看有哪些记录 |
128
+ | `2` | 参数错 / 上游文件读不到 | 看 stdout 的 `error` 字段(**stderr 是空的**)。**改命令,不要编内容** |
129
+
130
+ `status:2` 时 stdout 里没有 `items`,只有 `error`。
131
+ 拿不到档案就**用指令里已经给的 id+name 写**,不要凭印象补一份档案 ——
132
+ 编出来的字段会带着假信息进成品,比缺字段更糟。
133
+
121
134
  - 不得声称"已读取"参考文件。
122
135
 
123
136
  ---
@@ -269,9 +282,9 @@ main_progress_chapter_count = T - branch_chapter_total + overlap_chapter_count
269
282
  <!-- contract:file:时序映射 -->
270
283
  ## 七、时序映射.json 的字段契约
271
284
 
272
- **顶层**:11 个 `*_timeline` 数组 **模板**:`模板/节奏/时序映射模板.json`
285
+ **顶层**:13 个 `*_timeline` 数组 **模板**:`模板/节奏/时序映射模板.json`
273
286
 
274
- **核心要求**:11 类时序映射必须**引用骨架/血肉中真实存在的 id**,且**布局严格匹配节奏参数**。
287
+ **核心要求**:13 类时序映射必须**引用骨架/血肉中真实存在的 id**,且**布局严格匹配节奏参数**。
275
288
 
276
289
  **步骤 1:character_timeline**
277
290
 
@@ -282,6 +295,25 @@ main_progress_chapter_count = T - branch_chapter_total + overlap_chapter_count
282
295
  - `exit_chapter`:有退场的填(血肉 `角色.json` 的 `exit.type !== "未退场"` 时填),必须在 `[appear_start, appear_end]` 内
283
296
  - `arc_stages`:从血肉 `角色.json` 的 `arc_change_descriptions` 取 stage 名,为每个 stage 分配章节号。**章节号必须递增**(`start < turning < midpoint < end`),且必须在 `[appear_start, min(exit_chapter, appear_end)]` 内
284
297
 
298
+ **步骤 1.5:relationship_timeline**
299
+
300
+ 血肉 `角色.json` 的 `relationships[].changes[]` 只写了"关系怎么变、因为什么变";**具体从第几章开始变,只能在节奏阶段决定**。
301
+
302
+ - 只写**有变化**的角色关系;没有变化的关系不必写。
303
+ - 每行一对角色、一个阶段:`from` / `to`(人物 id)/ `stage`(阶段名,尽量与血肉 changes 的 stage 对齐)/ `state`(这一阶段的关系状态,如 对立、被迫合作、合作、决裂)/ `start_chapter`(该阶段开始生效的章)/ `end_chapter`(可选,不填则持续到下一阶段或全书结束)/ `trigger_event`(可选,触发事件)/ `description`(可选)。
304
+ - 同一对角色按 `start_chapter` **严格递增**;后一阶段必须晚于前一阶段。
305
+ - 只要血肉某条关系写了 `changes[]`,这里就必须有对应行(`RHYTHM_RELATION_TIMELINE_MISSING` 会查)。
306
+ - 关系变化章尽量落在双方都出场的区间内;不要把"合作"写成从第 1 章持续到全书结束却没有任何触发。
307
+
308
+ **步骤 1.6:faction_relationship_timeline**
309
+
310
+ 势力关系同样会随时间变化(结盟、敌对、休战、吞并……),**不能只写一个静态关系类型**。
311
+
312
+ - 只写**有变化**的势力关系;没有变化的可以不写。
313
+ - 每行一对势力、一个阶段:`from` / `to`(势力 id)/ `stage`(阶段名)/ `state`(这一阶段的关系状态)/ `start_chapter`(该阶段开始生效的章)/ `end_chapter`(可选)/ `trigger_event`(可选)/ `description`(可选)。
314
+ - 同一对势力按 `start_chapter` **严格递增**;后一阶段必须晚于前一阶段。
315
+ - 这一列的意义是让写作阶段明确知道:**这一章势力之间应该是什么态度,哪些合作/敌对还不能提前写。**
316
+
285
317
  **步骤 2:conflict_timeline**
286
318
 
287
319
  为每个冲突填:
@@ -377,8 +409,7 @@ main_progress_chapter_count = T - branch_chapter_total + overlap_chapter_count
377
409
  - 钩子章(`hook_timeline` 里出现的章 —— 细纲的 hook 字段必须与它对齐)
378
410
 
379
411
  **只写指令里列出的章**,不要自己加章,也不要漏。
380
- (主线 `key_nodes` 的"转折"节点不单独算重点章:它们是自由文本,插件无法可靠识别;
381
- 转折章如果同时是卷首/卷尾/高潮/结局/钩子章,本来就会出现在上面的清单里。)
412
+ (主线 `key_nodes` 的"转折"节点不单独算重点章:它们是自由文本,插件无法可靠识别;转折章如果同时是卷首/卷尾/高潮/结局/钩子章,本来就会出现在上面的清单里。)
382
413
 
383
414
  **每行细纲填**:
384
415
 
@@ -415,6 +446,8 @@ main_progress_chapter_count = T - branch_chapter_total + overlap_chapter_count
415
446
  | 冲突升级递增 | `RHYTHM_TIMING` | error |
416
447
  | 弧光顺序递增 | `RHYTHM_TIMING` | error |
417
448
  | 弧光章在出场区间内 | `RHYTHM_ARC_OUT_OF_SPAN` | error |
449
+ | 关系阶段开始章递增 | `RHYTHM_RELATION_ORDER` | error |
450
+ | 血肉有变化的关系必须有时序落点 | `RHYTHM_RELATION_TIMELINE_MISSING` | error |
418
451
  | 退场章在出场区间内 | `RHYTHM_EXIT_IN_SPAN` | error |
419
452
  | 章节号在 [1, T] 内 | `RHYTHM_CHAP_RANGE` | error |
420
453
  | 区间 start <= end | `RHYTHM_CHAP_ORDER` | error |
@@ -447,6 +480,8 @@ main_progress_chapter_count = T - branch_chapter_total + overlap_chapter_count
447
480
  | `RHYTHM_CHAP_RANGE` | 章节号越界 | 改到 `[1, T]` |
448
481
  | `RHYTHM_CHAP_ORDER` | 区间 start > end | 交换或调整 |
449
482
  | `RHYTHM_TIMING` | 时序错误 | 调整章节号 |
483
+ | `RHYTHM_RELATION_ORDER` | 同一对关系阶段开始章没有递增 | 把后一阶段改到更晚的章 |
484
+ | `RHYTHM_RELATION_TIMELINE_MISSING` | 血肉写了关系变化,时序映射没有落点 | 补 `relationship_timeline` 行 |
450
485
  | `RHYTHM_ARC_OUT_OF_SPAN` | 弧光章不在出场区间 | 调整 `arc_stages[].chapter` |
451
486
  | `RHYTHM_EXIT_IN_SPAN` | 退场章不在出场区间 | 调整 `exit_chapter` |
452
487
  | `RHYTHM_REF_MISSING` | 引用的 id 不存在 | 改 id 或补上游实体 |
@@ -37,6 +37,43 @@
37
37
 
38
38
  ---
39
39
 
40
+ ## 二·五、每章细纲(硬约束)
41
+
42
+ 节奏阶段会为 **每一章** 生成一份独立细纲:`设定/raw/sources/节奏/细纲/第NNN章.json`。
43
+ 写作驱动会在每章派活时把该文件折算成 `本章细纲:第 N 章(硬约束,必须执行)` 注入提示词。
44
+
45
+ - `must_write`:本章必须出现的功能、人物、地点、道具、冲突、伏笔、高潮/爽点、信息差动作、字数目标。
46
+ - `must_not_write`:本章绝对不能提的内容,尤其是 **角色尚不知道的信息**。
47
+ 例如“C002 尚不知道 X,本章不得让其提及、知情或据此行动”。
48
+ - `information_boundaries`:每个本章角色的 `unknown_secrets` / `false_beliefs`。
49
+ 这些是“角色此刻不知道或误以为”的事,不能让人物说破,也不能用旁白提前纠正。
50
+ - `how_to_write`:本章的视角、开场/推进/转折/收束技法、场景节拍。
51
+ - `elements`:人物、地点、道具、冲突、伏笔、高潮、爽点、结局、时间线、信息差的组织结果。
52
+
53
+ **违反 `must_not_write` 视为本章失败**:不要让角色说出他此时不该知道的事,不要用旁白提前揭示未到回收章的伏笔,不要写未列入本章 cast 的关键行动。
54
+
55
+ ---
56
+
57
+ ## 二·六、参考决策记录(必须)
58
+
59
+ 每章开始前必须实际读取本章相关的 `references` 目录写作指导文档和 `对标/wiki` 目录总结;插件注入的摘要只用于定位,不能替代原文件。
60
+
61
+ 每章至少向 `设定/.reference-decisions.md` 追加一行:
62
+
63
+ | 阶段 | 批次 | 决策对象 | 决策内容 | 参考文件 | 参考条目 | 备注 |
64
+ |---|---|---|---|---|---|---|
65
+ | 写作 | 第001章 | 第001章 | 例如 用“未完成动作”做章首 | 例如 写作指导目录中的开篇文档 | 例如 未完成动作引子 | 例如 让动作停在推门前 |
66
+
67
+ 规则:
68
+
69
+ - 每章至少一行;同一章内不同决策依据不同参考时拆成多行。
70
+ - `参考文件` 写实际读过的路径;`参考条目` 写原文里的标题/原则名,不能只写文件名。
71
+ - `备注` 写清为什么用、怎么用、哪些地方没有采用。
72
+ - 只追加数据行,不要重复写表头,不要覆盖已有行;备注里的 `|` 写成 `\|`。
73
+ - 除正文与台账外,`.reference-decisions.md` 是本阶段唯一允许写的额外文件。
74
+
75
+ ---
76
+
40
77
  ## 三、怎么写
41
78
 
42
79
  写作方法在 `references/写作指导/`,按需读:
@@ -2,29 +2,33 @@
2
2
 
3
3
  ## Goal
4
4
 
5
- 分析 `raw/sources/骨架/`、`raw/sources/血肉/`、`raw/sources/节奏/` 三个目录下的设定文件,根据 heading 层级结构提炼内容到 `wiki/` 对应的子目录。
5
+ 2.0 项目基于 `00-baseline/`、`10-scale/`、`20-macro/`、`30-cast/`、`40-rhythm/`、`50-writing/` 下的阶段文件;旧 1.x 项目基于 `raw/sources/骨架|血肉|节奏|写作/`。生成来源摘要、冲突检测和缺失检测结果。
6
+
7
+ 故事对象页(书/卷/幕/章/人物/势力/关系等)由插件的 `schemaingest` 从阶段 JSON 确定性生成;LLM ingest 不负责重复抽取这些对象。
6
8
 
7
9
  ## Key Questions
8
10
 
9
11
  1. `raw/sources/骨架/` 目录下的框架要素、角色、冲突是否完整?
10
12
  2. `raw/sources/血肉/` 目录下的势力、物品、地点是否与骨架目录一致?
11
13
  3. `raw/sources/节奏/` 目录下的细纲、分卷、伏笔是否与骨架、血肉匹配?
12
- 4. 三个目录下的设定之间是否存在冲突、矛盾或遗漏?
13
- 5. 伏笔的埋设、推进、回收是否形成完整闭环?
14
+ 4. `raw/sources/写作/` 目录下的正文是否覆盖了对应章节的细纲要求?
15
+ 5. 三个设定目录之间是否存在冲突、矛盾或遗漏?
16
+ 6. 伏笔的埋设、推进、回收是否形成完整闭环?
14
17
 
15
18
  ## Scope
16
19
 
17
20
  **In scope:**
18
- - `raw/sources/骨架/` 目录:框架要素、核心冲突、核心角色、主线支线、结局方向
19
- - `raw/sources/血肉/` 目录:世界观、势力、物品、地点、关系网
20
- - `raw/sources/节奏/` 目录:主线大纲、分卷表、情绪节奏、伏笔表、章节细纲
21
+ - `raw/sources/骨架/`:框架要素、核心冲突、核心角色、主线支线、结局方向
22
+ - `raw/sources/血肉/`:世界观、势力、物品、地点、关系网
23
+ - `raw/sources/节奏/`:主线大纲、分卷表、情绪节奏、伏笔表、章节细纲
24
+ - `raw/sources/写作/`:章节正文与细纲要求的覆盖情况
21
25
  - 冲突检测:量化冲突、角色冲突、伏笔冲突、关系冲突
22
- - 缺失检测:骨架缺失、血肉缺失、节奏缺失
26
+ - 缺失检测:数量缺失、宏观缺失、实体缺失、节奏/细纲缺失、正文覆盖缺失
23
27
 
24
28
  **Out of scope:**
25
29
  - `*闭环检查报告.md` 文件
26
30
  - `故事框架.md` 文件
27
- - 具体的章节正文内容
31
+ - 手工创建或改写故事对象页
28
32
  - 文笔、语句优化
29
33
 
30
34
  ## Thesis
@@ -33,73 +37,45 @@
33
37
 
34
38
  ## Analysis Workflow
35
39
 
36
- 1. **第一步:骨架分析**
37
- - 分析 `raw/sources/骨架/` 目录下的文件
38
- - 每个 `## heading` 生成一个独立的 wiki 页面
39
- - 根据 heading 名称推断 type
40
-
41
- 2. **第二步:血肉分析**
42
- - 分析 `raw/sources/血肉/` 目录下的文件
43
- - 势力/物品/地点文件根据 `## 基本信息` 等 heading 提取
44
- - 生成关系网页面
40
+ 1. **第一步:读取阶段文件**
41
+ - 读取四个 `raw/sources/` 子目录下的 JSON / Markdown 文件
42
+ - 记录每个文件的对象数量、ID 范围和明显缺项
45
43
 
46
- 3. **第三步:节奏分析**
47
- - 分析 `raw/sources/节奏/` 目录下的文件
48
- - 细纲_*.md 直接对应章节细纲
49
- - 伏笔表生成伏笔回收页面
44
+ 2. **第二步:写来源摘要**
45
+ - 每个被 ingest 的源文件写一个 `wiki/来源/*.md` 页面
46
+ - 使用 `type: 来源`,标题为 `SRC-xxx_标题`,正文第一块为 `## 来源`
47
+ - 摘要只描述源文件内容,不复制对象页
50
48
 
51
- 4. **第四步:冲突检测**
52
- - 对比骨架、血肉、节奏三个目录的分析结果
49
+ 3. **第三步:冲突检测**
50
+ - 对比 00-baseline / 10-scale / 20-macro / 30-cast / 40-rhythm / 50-writing(旧项目对比骨架/血肉/节奏/写作)
53
51
  - 检测量化冲突、角色冲突、伏笔冲突、关系冲突
54
52
  - 生成 review 条目到 `.llm-wiki/review.json`
55
53
 
56
- 5. **第五步:缺失检测**
57
- - 检查骨架、血肉、节奏三个目录是否有缺失内容
54
+ 4. **第四步:缺失检测**
55
+ - 检查各阶段是否有缺失内容
56
+ - 检查正文是否覆盖对应章节的全部 `requirement`
58
57
  - 生成 review 条目
59
58
 
60
59
  ## Expected Outputs
61
60
 
62
- - `wiki/框架-容量/`:容量.md
63
- - `wiki/框架-结构/`:结构.md
64
- - `wiki/框架-角色/`:角色.md
65
- - `wiki/框架-冲突/`:冲突.md
66
- - `wiki/框架-弧光/`:弧光.md
67
- - `wiki/核心冲突/`:核心冲突详情
68
- - `wiki/人物/`:角色详情
69
- - `wiki/结构-三幕/`:三幕结构.md
70
- - `wiki/结构-主线/`:主线.md
71
- - `wiki/结构-支线/`:支线-{N}.md
72
- - `wiki/结局/`:结局.md
73
- - `wiki/世界观/`:世界观.md
74
- - `wiki/势力/`:势力详情
75
- - `wiki/物品/`:物品详情
76
- - `wiki/地点/`:地点详情
77
- - `wiki/关系/`:关系网.md
78
- - `wiki/技能/`:技能详情
79
- - `wiki/节奏-大纲/`:主线大纲.md
80
- - `wiki/节奏-分卷/`:分卷表.md
81
- - `wiki/节奏-情绪/`:情绪节奏.md
82
- - `wiki/节奏-伏笔/`:伏笔表.md
83
- - `wiki/细纲/`:细纲_{NNN}.md
84
- - `wiki/审查-冲突/`:冲突检测结果
85
- - `wiki/审查-缺失/`:缺失检测结果
86
- - `.llm-wiki/review.json`:结构化的冲突/缺失列表
87
-
88
- ## Heading to Type Mapping
89
-
90
- | Heading Name | Inferred Type |
91
- |--------------|-----------|
92
- | 容量要素 | 框架-容量 |
93
- | 结构要素 | 框架-结构 |
94
- | 角色要素 | 框架-角色 |
95
- | 冲突要素 | 框架-冲突 |
96
- | 弧光要素 | 框架-弧光 |
97
- | 基本信息 | base type(根据文件路径) |
98
- | 核心成员 / 角色名 | 角色 |
99
- | 势力设定 / 世界观设定 | 继承父级 |
100
- | 势力资源 / 物品 | 物品/地点 |
101
- | 与其他势力的关系 | 关系 |
102
- | 卷数与章节分配 | 分卷表 |
61
+ 故事对象页由插件的 `schemaingest` 确定性生成;LLM ingest 只负责来源摘要和无法结构化归类的补充说明。
62
+
63
+ - `wiki/来源/`:每个源文件一个摘要页(`type: 来源`),并在 `related` 中用 `[[ID|ID_标题]]` 链接 `[[SRC-INDEX|来源索引]]` 和相关对象
64
+ - `.llm-wiki/review.json`:结构化的冲突/缺失列表(审查结果只写这里,不建 wiki 页面)
65
+
66
+ 以下对象页由 `schemaingest` 生成,LLM 不要手工创建:
67
+
68
+ - `wiki/书/`、`wiki/卷/`、`wiki/幕/`、`wiki/章/`
69
+ - `wiki/细纲要求/`、`wiki/场景/`、`wiki/正文/`
70
+ - `wiki/人物/`、`wiki/势力/`、`wiki/地点/`、`wiki/道具/`
71
+ - `wiki/冲突/`、`wiki/伏笔/`、`wiki/高潮/`、`wiki/爽点/`、`wiki/结局/`
72
+ - `wiki/世界观/`、`wiki/主线/`、`wiki/支线/`
73
+ - `wiki/关系/`、`wiki/势力关系/`、`wiki/势力成员/`
74
+ - `wiki/主题/`、`wiki/角色弧光/`、`wiki/角色状态/`、`wiki/时间线/`
75
+
76
+ ## Type Mapping
77
+
78
+ 不再根据 heading 推断故事对象 type。故事对象 type 以 `schema.json` 为准,由插件的阶段转换器决定;LLM ingest 只允许写 `type: 来源` 的摘要页。
103
79
 
104
80
  ## Files to Skip
105
81