@cloud411716/fancy-webnovel 1.0.46 → 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 (271) hide show
  1. package/client.js +369 -0
  2. package/cordis.patch.yml +4 -13
  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 +26 -38
  15. package/lib/atomic-write.js +109 -0
  16. package/lib/chapter-order.js +100 -0
  17. package/lib/chinese-num.js +111 -0
  18. package/lib/confirmation.js +80 -0
  19. package/lib/db-init.js +123 -0
  20. package/lib/deployed-state.js +141 -0
  21. package/lib/direction-labels.js +265 -0
  22. package/lib/error-codes.js +104 -0
  23. package/lib/infra.js +594 -0
  24. package/lib/llm-wiki.js +109 -0
  25. package/lib/material-db.js +149 -0
  26. package/lib/path-guard.js +150 -0
  27. package/lib/projects.js +400 -0
  28. package/lib/scraper-utils.js +305 -0
  29. package/lib/surreal-server.js +338 -0
  30. package/lib/topic-decision.js +860 -0
  31. package/lib/topic-fields.js +251 -0
  32. package/lib/topic-schema.js +225 -0
  33. package/lib/workspace.js +501 -0
  34. package/package.json +62 -5
  35. package/plugins/fancy-analyze/analyze-definitions.md +519 -0
  36. package/plugins/fancy-analyze/command-input.js +65 -0
  37. package/plugins/fancy-analyze/index.js +2024 -0
  38. package/plugins/fancy-analyze/ingest-coverage.js +107 -0
  39. package/plugins/fancy-analyze/schema-analyze.md +627 -0
  40. package/plugins/fancy-analyze/schema-write.md +178 -0
  41. package/plugins/fancy-analyze/scripts/append-summary-chapter.js +612 -0
  42. package/plugins/fancy-analyze/scripts/split_source.js +292 -0
  43. package/plugins/fancy-analyze/summary-progress.js +495 -0
  44. package/plugins/fancy-analyze/templates.js +1179 -0
  45. package/plugins/fancy-bootstrap/index.js +313 -0
  46. package/plugins/fancy-bootstrap/scripts/init.js +177 -0
  47. package/plugins/fancy-bootstrap/scripts/path-utils.js +21 -0
  48. package/plugins/fancy-bootstrap/templates.js +71 -0
  49. package/plugins/fancy-db/index.js +172 -0
  50. package/plugins/fancy-douyin/deploy.js +134 -0
  51. package/plugins/fancy-douyin/index.js +551 -0
  52. package/plugins/fancy-douyin/prompts/01-analysis-prompt.md +84 -0
  53. package/plugins/fancy-douyin/scripts/crawl-note.cjs +194 -0
  54. package/plugins/fancy-douyin/scripts/lib.cjs +197 -0
  55. package/plugins/fancy-douyin/scripts/scan-account.cjs +128 -0
  56. package/plugins/fancy-douyin/scripts/start-chrome.cjs +203 -0
  57. package/plugins/fancy-douyin/state.js +197 -0
  58. package/plugins/fancy-douyin/templates.js +127 -0
  59. package/plugins/fancy-export/exporter.js +805 -0
  60. package/plugins/fancy-export/index.js +63 -0
  61. package/plugins/fancy-import/import-core.js +1118 -0
  62. package/plugins/fancy-import/import-driver.js +604 -0
  63. package/plugins/fancy-import/index.js +738 -0
  64. package/plugins/fancy-import/prompts/01-import-prompt.md +131 -0
  65. package/plugins/fancy-import/templates.js +58 -0
  66. package/plugins/fancy-material/exporter.js +153 -0
  67. package/plugins/fancy-material/genres.js +256 -0
  68. package/plugins/fancy-material/index.js +835 -0
  69. package/plugins/fancy-material/inventory.js +143 -0
  70. package/plugins/fancy-material/kinds.js +313 -0
  71. package/plugins/fancy-material/queue.js +55 -0
  72. package/plugins/fancy-material/scripts/query.js +254 -0
  73. package/plugins/fancy-material/templates.js +258 -0
  74. package/plugins/fancy-material/tool-deploy.js +138 -0
  75. package/plugins/fancy-material/validate.js +149 -0
  76. package/plugins/fancy-project/index.js +133 -0
  77. package/plugins/fancy-scan/existing-block.js +100 -0
  78. package/plugins/fancy-scan/index.js +708 -0
  79. package/plugins/fancy-scan/prompts/01-analysis-prompt.md +302 -0
  80. package/plugins/fancy-scan/scripts/append-block.js +725 -0
  81. package/plugins/fancy-scan/scripts/report-validate.js +824 -0
  82. package/plugins/fancy-scan/scripts/run-scan.js +667 -0
  83. package/plugins/fancy-scan/scripts/scrapers/fanqie-rank-scraper.js +923 -0
  84. package/plugins/fancy-scan/scripts/scrapers/jjwxc-rank-scraper.js +469 -0
  85. package/plugins/fancy-scan/scripts/scrapers/qimao-rank-scraper.js +629 -0
  86. package/plugins/fancy-scan/templates/blocks.js +155 -0
  87. package/plugins/fancy-scan/templates/platforms.js +372 -0
  88. package/plugins/fancy-scan/templates/report-schema.js +90 -0
  89. package/plugins/fancy-scan/templates.js +694 -0
  90. package/plugins/fancy-scan/tool-deploy.js +335 -0
  91. package/plugins/fancy-scan/wait-turn.js +46 -0
  92. package/plugins/fancy-story-builder/db/README.md +106 -0
  93. package/plugins/fancy-story-builder/db/client.js +228 -0
  94. package/plugins/fancy-story-builder/db/commands.js +145 -0
  95. package/plugins/fancy-story-builder/db/ids.js +39 -0
  96. package/plugins/fancy-story-builder/db/import.js +798 -0
  97. package/plugins/fancy-story-builder/db/project.js +299 -0
  98. package/plugins/fancy-story-builder/db/query.js +361 -0
  99. package/plugins/fancy-story-builder/db/schema.js +417 -0
  100. package/plugins/fancy-story-builder/db/stage-sync.js +238 -0
  101. package/plugins/fancy-story-builder/deploy-manifest.js +239 -0
  102. package/plugins/fancy-story-builder/deslop-driver.js +821 -0
  103. package/plugins/fancy-story-builder/flesh-output.js +168 -0
  104. package/plugins/fancy-story-builder/index.js +6861 -0
  105. package/plugins/fancy-story-builder/patch-driver.js +390 -0
  106. package/plugins/fancy-story-builder/prompts/01-skeleton-prompt.md +563 -0
  107. package/plugins/fancy-story-builder/prompts/02-flesh-prompt.md +602 -0
  108. package/plugins/fancy-story-builder/prompts/03-rhythm-prompt.md +539 -0
  109. package/plugins/fancy-story-builder/prompts/04-writing-prompt.md +225 -0
  110. package/plugins/fancy-story-builder/prompts/05-deslop-prompt.md +96 -0
  111. package/plugins/fancy-story-builder/purpose-template.md +83 -0
  112. package/plugins/fancy-story-builder/references/formulas-rhythm.json +302 -0
  113. package/plugins/fancy-story-builder/references/formulas-skeleton.json +402 -0
  114. package/plugins/fancy-story-builder/references/genre-profiles.json +3514 -0
  115. package/plugins/fancy-story-builder/references/glossary.md +594 -0
  116. package/plugins/fancy-story-builder/references/index.md +581 -0
  117. package/plugins/fancy-story-builder/references//345/206/231/344/275/234/346/214/207/345/257/274/00-index.md +174 -0
  118. package/plugins/fancy-story-builder/references//345/206/231/344/275/234/346/214/207/345/257/274/01-scene.md +150 -0
  119. package/plugins/fancy-story-builder/references//345/206/231/344/275/234/346/214/207/345/257/274/02-chapter-workflow.md +99 -0
  120. package/plugins/fancy-story-builder/references//345/206/231/344/275/234/346/214/207/345/257/274/03-opening-chapter.md +104 -0
  121. package/plugins/fancy-story-builder/references//345/206/231/344/275/234/346/214/207/345/257/274/04-dialogue-mastery.md +274 -0
  122. package/plugins/fancy-story-builder/references//345/206/231/344/275/234/346/214/207/345/257/274/05-genre-formulas.md +432 -0
  123. package/plugins/fancy-story-builder/references//345/206/231/344/275/234/346/214/207/345/257/274/06-tone-ensemble.md +259 -0
  124. package/plugins/fancy-story-builder/references//345/206/231/344/275/234/346/214/207/345/257/274/07-ledger-audit.md +222 -0
  125. package/plugins/fancy-story-builder/references//345/206/231/344/275/234/346/214/207/345/257/274/08-diagnosis-revision.md +205 -0
  126. package/plugins/fancy-story-builder/references//345/206/231/344/275/234/346/214/207/345/257/274/09-reading-power.md +135 -0
  127. package/plugins/fancy-story-builder/references//345/206/231/344/275/234/346/214/207/345/257/274/10-deslop.md +129 -0
  128. package/plugins/fancy-story-builder/references//350/212/202/345/245/217/346/214/207/345/257/274/00-index.md +98 -0
  129. package/plugins/fancy-story-builder/references//350/212/202/345/245/217/346/214/207/345/257/274/01-upgrade-rhythm.md +300 -0
  130. package/plugins/fancy-story-builder/references//350/212/202/345/245/217/346/214/207/345/257/274/02-arc-rhythm.md +168 -0
  131. package/plugins/fancy-story-builder/references//350/212/202/345/245/217/346/214/207/345/257/274/03-highpoint-hooks.md +189 -0
  132. package/plugins/fancy-story-builder/references//350/212/202/345/245/217/346/214/207/345/257/274/04-satisfaction.md +226 -0
  133. package/plugins/fancy-story-builder/references//350/212/202/345/245/217/346/214/207/345/257/274/05-foreshadow-density.md +195 -0
  134. package/plugins/fancy-story-builder/references//350/212/202/345/245/217/346/214/207/345/257/274/06-chapter-outline.md +226 -0
  135. package/plugins/fancy-story-builder/references//350/212/202/345/245/217/346/214/207/345/257/274/07-audit.md +181 -0
  136. package/plugins/fancy-story-builder/references//350/241/200/350/202/211/346/214/207/345/257/274/00-index.md +100 -0
  137. package/plugins/fancy-story-builder/references//350/241/200/350/202/211/346/214/207/345/257/274/01-character.md +243 -0
  138. package/plugins/fancy-story-builder/references//350/241/200/350/202/211/346/214/207/345/257/274/02-worldbuilding.md +245 -0
  139. package/plugins/fancy-story-builder/references//350/241/200/350/202/211/346/214/207/345/257/274/03-relations.md +185 -0
  140. package/plugins/fancy-story-builder/references//350/241/200/350/202/211/346/214/207/345/257/274/04-emotion-methods.md +286 -0
  141. package/plugins/fancy-story-builder/references//350/241/200/350/202/211/346/214/207/345/257/274/05-audit.md +187 -0
  142. package/plugins/fancy-story-builder/references//351/252/250/346/236/266/346/214/207/345/257/274/00-index.md +91 -0
  143. package/plugins/fancy-story-builder/references//351/252/250/346/236/266/346/214/207/345/257/274/01-positioning.md +209 -0
  144. package/plugins/fancy-story-builder/references//351/252/250/346/236/266/346/214/207/345/257/274/02-packaging.md +135 -0
  145. package/plugins/fancy-story-builder/references//351/252/250/346/236/266/346/214/207/345/257/274/03-entities.md +305 -0
  146. package/plugins/fancy-story-builder/references//351/252/250/346/236/266/346/214/207/345/257/274/04-conflict.md +328 -0
  147. package/plugins/fancy-story-builder/references//351/252/250/346/236/266/346/214/207/345/257/274/05-quota.md +187 -0
  148. package/plugins/fancy-story-builder/references//351/252/250/346/236/266/346/214/207/345/257/274/06-audit.md +160 -0
  149. package/plugins/fancy-story-builder/rhythm-output.js +140 -0
  150. package/plugins/fancy-story-builder/schema-setting.json +1100 -0
  151. package/plugins/fancy-story-builder/schema-setting.md +232 -0
  152. package/plugins/fancy-story-builder/scripts/ai-patterns.js +619 -0
  153. package/plugins/fancy-story-builder/scripts/brief-validate.js +164 -0
  154. package/plugins/fancy-story-builder/scripts/check-guide-compliance.js +289 -0
  155. package/plugins/fancy-story-builder/scripts/content-quality.js +416 -0
  156. package/plugins/fancy-story-builder/scripts/deslop-validate.js +143 -0
  157. package/plugins/fancy-story-builder/scripts/error-classes.js +112 -0
  158. package/plugins/fancy-story-builder/scripts/flesh-validate.js +1312 -0
  159. package/plugins/fancy-story-builder/scripts/formula-engine.js +112 -0
  160. package/plugins/fancy-story-builder/scripts/graph-utils.js +1484 -0
  161. package/plugins/fancy-story-builder/scripts/label-coverage.js +171 -0
  162. package/plugins/fancy-story-builder/scripts/prompt-drift-check.js +441 -0
  163. package/plugins/fancy-story-builder/scripts/reading-power.js +298 -0
  164. package/plugins/fancy-story-builder/scripts/reference-log.js +110 -0
  165. package/plugins/fancy-story-builder/scripts/rhythm-validate.js +1312 -0
  166. package/plugins/fancy-story-builder/scripts/schema-pages.js +2668 -0
  167. package/plugins/fancy-story-builder/scripts/semantic-lint.js +381 -0
  168. package/plugins/fancy-story-builder/scripts/skeleton-quota.js +145 -0
  169. package/plugins/fancy-story-builder/scripts/skeleton-validate.js +1973 -0
  170. package/plugins/fancy-story-builder/scripts/stage-batches.js +1405 -0
  171. package/plugins/fancy-story-builder/scripts/stage-contract.js +429 -0
  172. package/plugins/fancy-story-builder/scripts/story-artifacts.js +933 -0
  173. package/plugins/fancy-story-builder/scripts/upstream-query.js +198 -0
  174. package/plugins/fancy-story-builder/scripts/v2/baseline.js +112 -0
  175. package/plugins/fancy-story-builder/scripts/v2/cast.js +517 -0
  176. package/plugins/fancy-story-builder/scripts/v2/context.js +434 -0
  177. package/plugins/fancy-story-builder/scripts/v2/contracts.js +493 -0
  178. package/plugins/fancy-story-builder/scripts/v2/core.js +419 -0
  179. package/plugins/fancy-story-builder/scripts/v2/engine.js +1068 -0
  180. package/plugins/fancy-story-builder/scripts/v2/export-markdown.js +794 -0
  181. package/plugins/fancy-story-builder/scripts/v2/genre.js +195 -0
  182. package/plugins/fancy-story-builder/scripts/v2/knowledge.js +321 -0
  183. package/plugins/fancy-story-builder/scripts/v2/macro.js +409 -0
  184. package/plugins/fancy-story-builder/scripts/v2/manifest.js +538 -0
  185. package/plugins/fancy-story-builder/scripts/v2/migrate.js +137 -0
  186. package/plugins/fancy-story-builder/scripts/v2/prompts.js +1335 -0
  187. package/plugins/fancy-story-builder/scripts/v2/rhythm.js +618 -0
  188. package/plugins/fancy-story-builder/scripts/v2/scale.js +843 -0
  189. package/plugins/fancy-story-builder/scripts/v2/snapshot.js +121 -0
  190. package/plugins/fancy-story-builder/scripts/v2/stages.js +273 -0
  191. package/plugins/fancy-story-builder/scripts/v2/writing.js +216 -0
  192. package/plugins/fancy-story-builder/scripts/writing-rules.js +167 -0
  193. package/plugins/fancy-story-builder/scripts/writing-validate.js +682 -0
  194. package/plugins/fancy-story-builder/skeleton-output.js +199 -0
  195. package/plugins/fancy-story-builder/stage-driver.js +1049 -0
  196. package/plugins/fancy-story-builder/storydb/README.md +271 -0
  197. package/plugins/fancy-story-builder/storydb/cli.js +458 -0
  198. package/plugins/fancy-story-builder/storydb/client.js +351 -0
  199. package/plugins/fancy-story-builder/storydb/compile.js +452 -0
  200. package/plugins/fancy-story-builder/storydb/context.js +288 -0
  201. package/plugins/fancy-story-builder/storydb/definitions.js +699 -0
  202. package/plugins/fancy-story-builder/storydb/driver.js +106 -0
  203. package/plugins/fancy-story-builder/storydb/dsh-tools.js +313 -0
  204. package/plugins/fancy-story-builder/storydb/export.js +175 -0
  205. package/plugins/fancy-story-builder/storydb/ids.js +31 -0
  206. package/plugins/fancy-story-builder/storydb/impact.js +170 -0
  207. package/plugins/fancy-story-builder/storydb/import.js +559 -0
  208. package/plugins/fancy-story-builder/storydb/mcp.js +99 -0
  209. package/plugins/fancy-story-builder/storydb/prompts.js +952 -0
  210. package/plugins/fancy-story-builder/storydb/stage-command.js +379 -0
  211. package/plugins/fancy-story-builder/storydb/stage.js +426 -0
  212. package/plugins/fancy-story-builder/storydb/store.js +891 -0
  213. package/plugins/fancy-story-builder/storydb/tools.js +592 -0
  214. package/plugins/fancy-story-builder/storydb/validation.js +183 -0
  215. package/plugins/fancy-story-builder/templates/v2/10-scale/scale-template.json +144 -0
  216. package/plugins/fancy-story-builder/templates/v2/20-macro/emotion-template.json +15 -0
  217. package/plugins/fancy-story-builder/templates/v2/20-macro/endings-template.json +16 -0
  218. package/plugins/fancy-story-builder/templates/v2/20-macro/lines-template.json +28 -0
  219. package/plugins/fancy-story-builder/templates/v2/20-macro/roles-template.json +10 -0
  220. package/plugins/fancy-story-builder/templates/v2/20-macro/story-template.json +19 -0
  221. package/plugins/fancy-story-builder/templates/v2/20-macro/volumes-template.json +24 -0
  222. package/plugins/fancy-story-builder/templates/v2/20-macro/world-template.json +24 -0
  223. package/plugins/fancy-story-builder/templates/v2/30-cast/characters-template.json +49 -0
  224. package/plugins/fancy-story-builder/templates/v2/30-cast/climaxes-template.json +14 -0
  225. package/plugins/fancy-story-builder/templates/v2/30-cast/conflicts-template.json +30 -0
  226. package/plugins/fancy-story-builder/templates/v2/30-cast/factions-template.json +18 -0
  227. package/plugins/fancy-story-builder/templates/v2/30-cast/foreshadows-template.json +29 -0
  228. package/plugins/fancy-story-builder/templates/v2/30-cast/information-template.json +29 -0
  229. package/plugins/fancy-story-builder/templates/v2/30-cast/items-template.json +13 -0
  230. package/plugins/fancy-story-builder/templates/v2/30-cast/locations-template.json +12 -0
  231. package/plugins/fancy-story-builder/templates/v2/30-cast/payoffs-template.json +16 -0
  232. package/plugins/fancy-story-builder/templates/v2/30-cast/relations-template.json +44 -0
  233. package/plugins/fancy-story-builder/templates/v2/40-rhythm/chapter-map-template.json +81 -0
  234. package/plugins/fancy-story-builder/templates/v2/40-rhythm/outline-template.json +162 -0
  235. package/plugins/fancy-story-builder/templates/v2/50-writing/ledger-template.json +46 -0
  236. package/plugins/fancy-story-builder/templates/v2/60-deslop/report-template.json +10 -0
  237. 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 +427 -0
  238. package/plugins/fancy-story-builder/templates//350/212/202/345/245/217//347/253/240/350/212/202/347/273/206/347/272/262/346/250/241/346/235/277.json +34 -0
  239. package/plugins/fancy-story-builder/templates//350/212/202/345/245/217//347/253/240/350/212/202/350/247/204/345/210/222/346/250/241/346/235/277.json +24 -0
  240. package/plugins/fancy-story-builder/templates//350/212/202/345/245/217//350/212/202/345/245/217/345/217/202/346/225/260/346/250/241/346/235/277.json +27 -0
  241. 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 +168 -0
  242. 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 +184 -0
  243. 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
  244. 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 +131 -0
  245. 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 +85 -0
  246. 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 +103 -0
  247. 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 +68 -0
  248. 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 +142 -0
  249. 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 +292 -0
  250. 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 +266 -0
  251. 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 +336 -0
  252. package/plugins/fancy-story-builder/templates//351/252/250/346/236/266//345/261/202/347/272/247/346/250/241/346/235/277.json +65 -0
  253. 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 +308 -0
  254. package/plugins/fancy-story-builder/templates.js +1446 -0
  255. package/plugins/fancy-story-builder/wiki-references.js +540 -0
  256. package/plugins/fancy-story-builder/writing-driver.js +1388 -0
  257. package/plugins/fancy-topic/index.js +1057 -0
  258. package/plugins/fancy-topic/prompts/01-exploration-prompt.md +115 -0
  259. package/plugins/fancy-topic/scripts/save-suggestion.js +219 -0
  260. package/plugins/fancy-topic/scripts/select-topic.js +317 -0
  261. package/plugins/fancy-topic/templates.js +476 -0
  262. package/plugins/fancy-topic/tool-deploy.js +200 -0
  263. package/commands/bootstrap/index.js +0 -164
  264. package/commands/bootstrap/init-project.js +0 -121
  265. package/commands/scan/index.js +0 -283
  266. package/commands/scan/platforms/fanqie.js +0 -146
  267. package/commands/scan/platforms/jinjiang.js +0 -143
  268. package/commands/scan/platforms/qidian.js +0 -102
  269. package/commands/scan/platforms/qimao.js +0 -127
  270. package/commands/scan/scraper.js +0 -195
  271. package/infra.js +0 -160
@@ -0,0 +1,563 @@
1
+ # 01 骨架阶段产物契约
2
+
3
+ > 本文件是骨架阶段的**产物契约**:每个文件长什么样、哪些规则不能破。
4
+ >
5
+ > 怎么派活、怎么校验、错了怎么改、下一批做什么,全部由插件负责:
6
+ > 插件按批次把活派给你,校验脚本判定通过与否,
7
+ > 错误清单由插件整理后回喂给你。**你只负责按指令生成文件。**
8
+ >
9
+ > 本阶段是第一层,无上游依赖。
10
+
11
+ @meta-only
12
+
13
+ ---
14
+
15
+ <!-- contract:overview -->
16
+ ## 一、本阶段目标
17
+
18
+ 产出 4 个 JSON 文件到 `设定/raw/sources/骨架/`:
19
+
20
+ 1. `框架.json` —— 定数量(quota)、定卷比例(volume_ratio)、记录公式推导(derivations)
21
+ 2. `实体.json` —— 12 类常规实体清单(id + name + 枚举)+ 可选的 `other_entities` 题材扩展实体
22
+ 3. `关系.json` —— 9 类常规关系清单(ID 引用)+ 可选的 `other_relations`
23
+ 4. `层级.json` —— 卷/幕/主线/支线的卷级归属
24
+
25
+ **本阶段回答**:有哪些实体、实体如何连接、有多少、分几卷几幕。
26
+ **本阶段不回答**:实体长什么样(血肉阶段)、什么时间发生(节奏阶段)、具体怎么写(写作阶段)。
27
+
28
+ ### 生成顺序(有硬依赖,插件按这个顺序派活)
29
+
30
+ | 序 | 文件 | 依赖 | 为什么 |
31
+ |---|---|---|---|
32
+ | 1 | 框架.json | 无 | quota 是实体与层级数量的唯一来源 |
33
+ | 2 | 实体.json | 框架.json | 每类实体写几条,按框架的 quota 写 |
34
+ | 3 | 关系.json | 实体.json | 关系里填的 id 只能来自实体清单 |
35
+ | 4 | 层级.json | 框架 + 实体 | 卷数按 quota.volume_count;span 引用主线/支线 id |
36
+
37
+ **不得并行,不得预生成下游文件。**
38
+
39
+ ---
40
+
41
+ <!-- contract:input -->
42
+ ## 二、任务输入
43
+
44
+ > 本节由插件注入,只读,不得修改。
45
+ > 骨架阶段没有上游,这输入就是选题时的原始输入。
46
+
47
+ ${input_snapshot_block}
48
+
49
+ **注**:
50
+
51
+ - **目标章节**是全部数量公式的输入(T)。先算 T,后面所有数量都从 T 推。
52
+ - **选题方向 + 11 项方向设计**是扫榜报告里选定方向的设计(一句话定位、读者与情绪价值、金手指、核心设定、爽点模式、情绪价值曲线、开篇切入点、节奏规划、人物设定、差异化策略、风险与验证)。**逐项原样抄进 `input_snapshot`**:血肉、节奏阶段都从这份快照读它,不必也不得自行重设计。
53
+ - **一句话故事**决定主角是谁、核心冲突是什么;**核心冲突**决定要配几个核心冲突、几个核心反派。
54
+ - **硬门禁**与**反套路**是硬约束:配实体类型、势力性质、结局走向时不得违背。
55
+
56
+ ---
57
+
58
+ <!-- contract:output-list -->
59
+ ## 三、本阶段产出清单
60
+
61
+ | # | 文件 | 路径 | 前置依赖 |
62
+ |---|---|---|---|
63
+ | 1 | 框架.json | `设定/raw/sources/骨架/框架.json` | 无 |
64
+ | 2 | 实体.json | `设定/raw/sources/骨架/实体.json` | 框架.json 已产出 |
65
+ | 3 | 关系.json | `设定/raw/sources/骨架/关系.json` | 实体.json 已产出 |
66
+ | 4 | 层级.json | `设定/raw/sources/骨架/层级.json` | 框架.json + 实体.json 已产出 |
67
+
68
+ ---
69
+
70
+ <!-- contract:rules -->
71
+ ## 四、核心铁律(违反任意一条都会校验失败)
72
+
73
+ > 1. **不得出现任何章节号**(`chapter` / `ch` / `start` / `end` / `appearance_chapters` / `chapter_range` / `buried_chapter` / `recovered_chapter` / `key_nodes` 等,完整清单见 glossary 第六节)。骨架脚本会拦截 `SKELETON_CHAPTER_FORBIDDEN`。
74
+ >
75
+ > 2. **常规实体的枚举必须遵守 glossary**。例如 `character_type` 只允许"主角/贯穿级核心配角/卷级重要配角/贯穿级核心反派/卷级反派",不能自创。题材特有存在不要硬塞进 `characters`,改写进可选的 `other_entities`(`kind` 是自由文本,如 灵魂/神魂/器灵/妖灵/概念体)。ENUM 校验会拦截常规枚举。
76
+ >
77
+ > 3. **引用关系只允许 id,不允许编名字**。关系.json 的 `from`/`to`/`character`/`faction`/`item`/`location`/`ending`/`main_line`/`branch` 必须是 `C001`/`X001`/`F001` 这种 id,不是名字。`SKELETON_REF_MISSING` 会拦截。
78
+ >
79
+ > 4. **不得自创字段**。每个文件的字段必须严格在 `模板/骨架/<文件名>模板.json` 的 `structure.properties` 中定义。`EXTRA_FIELD` 会拦截。
80
+ >
81
+ > 5. **公式推导(`derivations`)必须 30 条齐全**,每条 `{formula, range_low, range_high, note}`,且 `formula` 逐字与 `formulas-skeleton.json` 一致。`DERIVATION_MISSING` / `DERIVATION_RANGE_MISMATCH` 会拦截。
82
+ >
83
+ > 6. **关系类型只能取第 8.2 节各自那套词表**。`character_relations[].relation_kind` 取 13 值(血缘/师徒/雇佣/服从/提携/合作/利益交换/利用/对立/敌对/竞争/中立/其他);用 `其他` 时必须填 `relation_label` 写清具体关系(如 附身/寄生/契约/共生)。非人物实体的关系写 `other_relations`;`faction_membership[].member_relation` 取 8 值(利益交换/合作/对立/利用/师徒/雇佣/血亲/无);`faction_relations[].relation_type` 取 4 值(合作/对立/利用/中立);`main_line_branch_relation[].relation_kind` 取 6 值(促成/阻碍/并行/揭示/收束/依存)。不要写"盟友""对手""上下级""血亲"——它们不在对应词表里,ENUM 会拦截。
84
+ >
85
+ > 7. **实体名要是真名字,内容要是真内容**。名字写"陆子仲"而不是"主角1";`input_snapshot` 的 `positioning` / `core_conflict` 要写清一个具体处境,而不是"核心概述。"。`NAME_PLACEHOLDER` / `TEXT_TOO_SHORT` / `TEXT_PLACEHOLDER` 会拦截。
86
+ >
87
+ > 8. **实体条数必须与框架的 quota 完全一致**。框架里声明 `character_counts.protagonist = 2`,实体清单里就恰好要有 2 个 `type=主角` 的角色;多一个少一个都会报 `QUOTA_MISMATCH`。
88
+
89
+ ---
90
+
91
+ <!-- contract:refs -->
92
+ ## 五、参考文件
93
+
94
+ ### 必读(每次任务开始时读一次,之后不再重读)
95
+
96
+ - `references/glossary.md` —— 术语、ID 前缀、枚举、章节号字段清单
97
+ - `references/formulas-skeleton.json` —— 30 条数量公式(框架.json 生成时用)
98
+
99
+ ### 按本轮文件选读
100
+
101
+ | 本轮生成文件 | 读 |
102
+ |---|---|
103
+ | 框架.json | `references/骨架指导/01-positioning.md`(读者定位)、`references/骨架指导/05-quota.md`(数量) |
104
+ | 实体.json | `references/骨架指导/01-positioning.md`、`references/骨架指导/03-entities.md`(实体卡) |
105
+ | 关系.json | `references/骨架指导/02-packaging.md`(势力包装)、`references/骨架指导/03-entities.md`、`references/骨架指导/04-conflict.md` |
106
+ | 层级.json | `references/骨架指导/02-packaging.md`、`references/骨架指导/04-conflict.md` |
107
+ | 全部 | `references/骨架指导/00-index.md`(阶段入口,强烈推荐) |
108
+
109
+ ${benchmark_refs_block}
110
+
111
+ ### 规则
112
+
113
+ - 必读文件不可读时,停下来上报(原因:参考文件缺失)。
114
+ - 选读文件不可读时,记 warning,继续。
115
+ - 读后不重读。
116
+ - 不得声称"已读取"参考文件。
117
+
118
+ ---
119
+
120
+ <!-- contract:file:框架 -->
121
+ ## 六、框架.json 的字段契约
122
+
123
+ **顶层**:纯对象(没有顶层数组) **模板**:`模板/骨架/框架模板.json`
124
+
125
+ | 顶层键 | 写什么 |
126
+ |---|---|
127
+ | `capacity` | `{target_chapters, target_words, avg_words_per_chapter}` |
128
+ | `input_snapshot` | 任务输入 17 项(书名/题材/一句话定位/核心冲突/选题方向/11 项方向设计/硬门禁/反套路),原样照抄 |
129
+ | `quota` | 每类实体要多少个(见下) |
130
+ | `volume_ratio` | 每卷占多少章,数组 |
131
+ | `derivations` | 30 条公式推导,对象 |
132
+
133
+ ### 6.1 capacity
134
+
135
+ - `target_chapters`:任务输入的 T
136
+ - `target_words`:任务输入
137
+ - `avg_words_per_chapter`:`round(target_words / target_chapters)`
138
+
139
+ `CAPACITY_MISMATCH` 会核对三者。
140
+
141
+ ### 6.2 quota(数量配额)
142
+
143
+ 28 个字段,每个字段的值就是**实体清单里该类型的条数**:
144
+
145
+ | quota 路径 | 对应实体数组 | 统计口径 |
146
+ |---|---|---|
147
+ | `character_counts.protagonist` | characters | type=主角 |
148
+ | `character_counts.core_supporting` | characters | type=贯穿级核心配角 |
149
+ | `character_counts.volume_supporting` | characters | type=卷级重要配角 |
150
+ | `character_counts.core_antagonist` | characters | type=贯穿级核心反派 |
151
+ | `character_counts.volume_antagonist` | characters | type=卷级反派 |
152
+ | `conflict_counts.core` | conflicts | type=核心 |
153
+ | `conflict_counts.phase` | conflicts | type=阶段 |
154
+ | `conflict_counts.branch` | conflicts | type=交织 |
155
+ | `faction_count` | factions | 全部 |
156
+ | `location_count` | locations | 全部 |
157
+ | `ending_count` | endings | 全部 |
158
+ | `main_line_count` | main_lines | 全部 |
159
+ | `branch_count` | branches | 全部 |
160
+ | `foreshadow_counts.small` | foreshadows | type=小伏笔 |
161
+ | `foreshadow_counts.medium` | foreshadows | type=中伏笔 |
162
+ | `foreshadow_counts.large` | foreshadows | type=大伏笔 |
163
+ | `climax_counts.small` | climaxes | type=小高潮 |
164
+ | `climax_counts.medium` | climaxes | type=中高潮 |
165
+ | `climax_counts.large` | climaxes | type=大高潮 |
166
+ | `pleasure_counts.small` | pleasures | scale=小爽点 |
167
+ | `pleasure_counts.medium` | pleasures | scale=中爽点 |
168
+ | `pleasure_counts.large` | pleasures | scale=大爽点 |
169
+ | `item_counts.core` | items | category=核心道具 |
170
+ | `item_counts.branch` | items | category=支线道具 |
171
+ | `item_counts.symbolic` | items | category=象征道具 |
172
+ | `world_rule_counts.core` | world_rules | category=核心规则 |
173
+ | `world_rule_counts.information` | world_rules | category=信息规则 |
174
+ | `world_rule_counts.social` | world_rules | category=社会规则 |
175
+ | `volume_count` | 层级.json 的 volumes | 全部(另见 `faction_relation_count`) |
176
+ | `faction_relation_count` | 关系.json 的 faction_relations | 无向关系对数(行数 = 它,或对立关系写双向时 = 它的 2 倍) |
177
+
178
+ **quota 的值决定后面每一批要写多少条**。写错了,后面每一批都会跟着错。
179
+
180
+ ### 6.3 数量公式(30 条,按拓扑顺序算)
181
+
182
+ 读 `references/formulas-skeleton.json` 拿到 30 条公式(含 `fixed.*` 固定值),按下面的拓扑顺序逐层计算区间:
183
+
184
+ ```
185
+ Level 0(基础量):
186
+ T = target_chapters
187
+
188
+ Level 1(只依赖 T 或固定值):
189
+ structure.volume_count
190
+ fixed.character_elements.protagonist_count
191
+ fixed.character_elements.core_supporting_count
192
+ fixed.character_elements.core_antagonist_count
193
+ fixed.conflict_elements.core_conflict_count
194
+ fixed.structure.main_line_count
195
+
196
+ Level 2(依赖 V;也可以用 T):
197
+ V = quota.volume_count
198
+ structure.branch_count
199
+ character_elements.volume_supporting_count
200
+ character_elements.volume_antagonist_count
201
+ conflict_elements.phase_conflict_count
202
+ faction_elements.faction_count
203
+ location_elements.key_location_count
204
+ foreshadow_elements.small_foreshadow_count
205
+ foreshadow_elements.medium_foreshadow_count
206
+ foreshadow_elements.large_foreshadow_count
207
+ climax_elements.small_climax_count
208
+ climax_elements.medium_climax_count
209
+ climax_elements.large_climax_count
210
+ pleasure_elements.small_pleasure_count
211
+ pleasure_elements.medium_pleasure_count
212
+ pleasure_elements.large_pleasure_count
213
+ ending_elements.ending_count
214
+ world_rule_counts.core
215
+ world_rule_counts.information
216
+ world_rule_counts.social
217
+
218
+ Level 3(依赖实体数):
219
+ conflict_elements.branch_conflict_count(依赖 BC = branch_count)
220
+ faction_elements.faction_relation_count(依赖 faction_count 作为输入)
221
+ item_elements.core_item_count(依赖 CC = core_conflict_count)
222
+ item_elements.branch_item_count(依赖 BC = branch_count)
223
+ item_elements.symbolic_item_count(依赖 P + CS + CA)
224
+ ```
225
+
226
+ `faction_elements.faction_relation_count` 必须在 `faction_count` 之后算(依赖它作为输入)。
227
+
228
+ ### 6.4 derivations(30 条,一条不多一条不少)
229
+
230
+ - key:公式名(如 `structure.volume_count`),必须与 `formulas-skeleton.json` 完全一致
231
+ - value:`{formula, range_low, range_high, note}`
232
+ - `formula`:逐字复制 `formulas-skeleton.json` 对应条目的 `formula` 字段
233
+ - `range_low` / `range_high`:6.3 算出的数字
234
+ - `note`:可选字符串;**终值超出区间时必须写明理由**(超出会产生 `QUANTITY_MISMATCH` warning,不阻塞)
235
+
236
+ **30 条公式名**(与 `formulas-skeleton.json` 一一对应):
237
+
238
+ | # | 公式名 |
239
+ |---|---|
240
+ | 1 | `structure.volume_count` |
241
+ | 2 | `structure.branch_count` |
242
+ | 3 | `character_elements.volume_supporting_count` |
243
+ | 4 | `character_elements.volume_antagonist_count` |
244
+ | 5 | `conflict_elements.phase_conflict_count` |
245
+ | 6 | `conflict_elements.branch_conflict_count` |
246
+ | 7 | `faction_elements.faction_count` |
247
+ | 8 | `faction_elements.faction_relation_count` |
248
+ | 9 | `location_elements.key_location_count` |
249
+ | 10 | `foreshadow_elements.small_foreshadow_count` |
250
+ | 11 | `foreshadow_elements.medium_foreshadow_count` |
251
+ | 12 | `foreshadow_elements.large_foreshadow_count` |
252
+ | 13 | `climax_elements.small_climax_count` |
253
+ | 14 | `climax_elements.medium_climax_count` |
254
+ | 15 | `climax_elements.large_climax_count` |
255
+ | 16 | `pleasure_elements.small_pleasure_count` |
256
+ | 17 | `pleasure_elements.medium_pleasure_count` |
257
+ | 18 | `pleasure_elements.large_pleasure_count` |
258
+ | 19 | `item_elements.core_item_count` |
259
+ | 20 | `item_elements.branch_item_count` |
260
+ | 21 | `item_elements.symbolic_item_count` |
261
+ | 22 | `world_rule_counts.core` |
262
+ | 23 | `world_rule_counts.information` |
263
+ | 24 | `world_rule_counts.social` |
264
+ | 25 | `ending_elements.ending_count` |
265
+ | 26 | `fixed.structure.main_line_count` |
266
+ | 27 | `fixed.character_elements.protagonist_count` |
267
+ | 28 | `fixed.character_elements.core_supporting_count` |
268
+ | 29 | `fixed.character_elements.core_antagonist_count` |
269
+ | 30 | `fixed.conflict_elements.core_conflict_count` |
270
+
271
+ ### 6.5 volume_ratio
272
+
273
+ - 长度等于 `quota.volume_count`
274
+ - 每个 `volume_id` 格式 `V001`、`V002`……连续不跳号
275
+ - `chapter_ratio` 之和等于 1.0(容差 0.01)
276
+
277
+ ---
278
+
279
+ <!-- contract:file:实体 -->
280
+ ## 七、实体.json 的字段契约
281
+
282
+ **顶层**:12 个常规数组 + 可选的 `other_entities` **模板**:`模板/骨架/实体模板.json`
283
+
284
+ ### 7.1 每类实体的字段
285
+
286
+ | 数组 | id 前缀 | 字段 |
287
+ |---|---|---|
288
+ | `characters` | C | `id` `name` `type` `gender` `age_group` |
289
+ | `conflicts` | X | `id` `name` `type` `scale` |
290
+ | `factions` | F | `id` `name` `type` |
291
+ | `locations` | L | `id` `name` `type` `narrative_function` |
292
+ | `items` | P | `id` `name` `category` |
293
+ | `endings` | E | `id` `name` `level` `type` |
294
+ | `foreshadows` | FS | `id` `name` `type` |
295
+ | `climaxes` | CL | `id` `name` `type` |
296
+ | `pleasures` | PL | `id` `name` `scale` `kind` |
297
+ | `world_rules` | R / I / SR | `id` `name` `category` |
298
+ | `main_lines` | M | `id` `name` |
299
+ | `branches` | B | `id` `name` `type` |
300
+ | `other_entities`(可选) | O | `id` `name` `kind`(`note` 可选) |
301
+
302
+ **id 规则**:`C001`/`X001`/`F001`/`L001`/`P001`/`E001`/`FS001`/`CL001`/`PL001`/`M001`/`B001`,三位数从 001 连续递增,不跳号。可选扩展实体用 `O001` 起单独编号。
303
+ **同一个数组里的 id 必须两两不同 —— 不管 `type` / `scale` / `kind` 是不是同一类。**
304
+ 一个数组只有一个 id 前缀时,**不同类别也共用同一个编号空间**,必须合在一起连续编号:`climaxes` 的小高潮 / 中高潮 / 大高潮共用 `CL`,要写成 `CL001`…`CL079` 这样一路排下来,**不能按类型各编一套**(各编一套必然撞号,`ID_DUP` 会拦截 —— 2026-10-24 实测就是这么失败的)。
305
+ 世界观的规则按分类用不同前缀:**R** = 核心规则、**I** = 信息规则、**SR** = 社会规则
306
+ (`WORLD_RULE_CATEGORY_MISMATCH` 会核对前缀与所属数组);这三个前缀各自独立编号,互不冲突。
307
+
308
+ ### 7.2 枚举取值(只能从词表里选,ENUM 会拦截)
309
+
310
+ | 字段 | 取值 |
311
+ |---|---|
312
+ | `characters[].type` | 主角 / 贯穿级核心配角 / 卷级重要配角 / 贯穿级核心反派 / 卷级反派 |
313
+ | `characters[].age_group` | 少年 / 青年 / 中年 / 老年 |
314
+ | `conflicts[].type` | 核心 / 阶段 / 交织 |
315
+ | `conflicts[].scale` | 全局性 / 区域性 / 个人 |
316
+ | `factions[].type` | 官方组织 / 民间组织 / 商业组织 / 其他 |
317
+ | `locations[].type` | 主要场景 / 次要场景 / 过渡场景 / 其他 |
318
+ | `locations[].narrative_function` | 对话 / 冲突 / 情感 / 转折 / 伏笔 / 其他 |
319
+ | `items[].category` | 核心道具 / 支线道具 / 象征道具 |
320
+ | `endings[].level` | 全书级 / 卷级 |
321
+ | `endings[].type` | 开放式结局 / 闭合式结局 / 悲剧结局 / 喜剧结局 |
322
+ | `foreshadows[].type` | 小伏笔 / 中伏笔 / 大伏笔 |
323
+ | `climaxes[].type` | 小高潮 / 中高潮 / 大高潮 |
324
+ | `pleasures[].scale` | 小爽点 / 中爽点 / 大爽点 |
325
+ | `pleasures[].kind` | 打脸 / 收获 / 身份 / 情感 / 智力 / 探索 / 团战 |
326
+ | `world_rules[].category` | 核心规则 / 信息规则 / 社会规则 |
327
+ | `branches[].type` | 角色成长型 / 身份揭示型 / 背景揭示型 |
328
+ | `other_entities[].kind` | **自由文本**:灵魂 / 神魂 / 器灵 / 妖灵 / 鬼魂 / 概念体 / 其他题材特有类别 |
329
+
330
+ ### 7.3 关键约束
331
+
332
+ - **全书级结局恰好 1 个**(`level=全书级`),其余是卷级(`BOOK_ENDING_COUNT` 会查)
333
+ - **每类实体的条数严格等于框架 quota 里对应字段的值**(`QUOTA_MISMATCH` 会查)
334
+ - **id 与 name 都不能重复**(`ID_DUP` / `NAME_DUP`);**角色 / 势力 / 冲突 / 地点**四类之间也不能同名(`CROSS_TYPE_NAME_DUP` warning)
335
+ - **同一实体只建一条**:本名/正式名优先。称呼(哥哥/父亲/老师/老板)、绰号、简称、集团/公司/大学等后缀不要另建实体;归一化后重名会报 `NAME_ALIAS_SUSPECT` warning
336
+ - **名字是真名**:写"陆子仲"不写"主角1"(`NAME_PLACEHOLDER` 会查)
337
+ - **常规实体只写 id + name + 枚举**;`other_entities` 只写 `id` / `name` / `kind`(可带一句 `note`)。描述属于血肉阶段(`EXTRA_FIELD` 会查)
338
+ - **不许出现章节号**(`SKELETON_CHAPTER_FORBIDDEN` 会查)
339
+ - **不许同质化**:不同实体的同一字段不能几乎一字不差(`TEXT_DUPLICATE` 会查)
340
+
341
+ ---
342
+
343
+ <!-- contract:file:关系 -->
344
+ ## 八、关系.json 的字段契约
345
+
346
+ **顶层**:9 个常规数组 + 可选的 `other_relations` **模板**:`模板/骨架/关系模板.json`
347
+
348
+ ### 8.1 每类关系的字段
349
+
350
+ | 数组 | 一行代表什么 | 字段 |
351
+ |---|---|---|
352
+ | `character_relations` | 两个角色之间的关系 | `from` `to` `relation_kind`;`relation_kind=其他` 时加 `relation_label` |
353
+ | `other_relations`(可选) | 非人物实体参与的关系 | `from`(O 开头)`to`(C/O 开头)`relation_label`(必填)`description`(可选) |
354
+ | `faction_membership` | 一个角色属于一个势力 | `character` `faction` `member_relation` `position_level` |
355
+ | `faction_relations` | 两个势力之间的关系 | `from` `to` `relation_type` |
356
+ | `conflict_participants` | 一个冲突的参战方 | `conflict` `protagonist_side` `main_antagonist` `secondary_antagonist` `third_party` |
357
+ | `branch_protagonist` | 一条支线的主角 | `branch` `character` |
358
+ | `item_owner` | 一件道具的归属者 | `item` `owner_id` `owner_kind` |
359
+ | `location_conflict` | 一个地点牵涉哪些冲突 | `location` `conflicts` |
360
+ | `ending_character` | 一个结局牵涉哪些角色 | `ending` `character` |
361
+ | `main_line_branch_relation` | 一条支线怎么挂到主线上 | `main_line` `branch` `relation_kind` |
362
+
363
+ ### 8.2 关系类型词表
364
+
365
+ **`character_relations[].relation_kind`** —— 只从这 13 个值里选:
366
+
367
+ | 词表值 | 什么时候用 |
368
+ |---|---|
369
+ | 血缘 | 有亲属关系 |
370
+ | 师徒 | 有师承(师父在前,徒弟在后) |
371
+ | 雇佣 | 有雇佣(雇主在前) |
372
+ | 服从 | 一方服从另一方 |
373
+ | 提携 | 一方提携另一方 |
374
+ | 合作 | 平等合作 |
375
+ | 利益交换 | 以利益为纽带 |
376
+ | 利用 | 一方利用另一方 |
377
+ | 对立 | 立场对立 |
378
+ | 敌对 | 敌视仇视 |
379
+ | 竞争 | 争夺同一目标 |
380
+ | 中立 | 无特殊立场 |
381
+ | 其他 | 词表外的题材特有角色关系(附身/寄生/契约/共生…);**必须同时填 `relation_label`**,能归入前 12 类的不要滥用 |
382
+
383
+ **不要写的**(不在词表,ENUM 拦截):`盟友`→写 `合作`;`对手`→写 `对立` 或 `敌对`;`上下级`→写 `师徒` / `雇佣` / `服从`;`血亲`→写 `血缘`;`附身` 不是词表值,人物之间写 `其他` + `relation_label: 附身`,灵魂/神魂等非人物存在写进 `other_relations`。
384
+
385
+ **`other_relations[].relation_label`** —— 自由文本,但必须具体:`附身` / `寄宿` / `共生` / `契约` / `镇压` / `吞噬` / `前世` 等。`from` 必须是 `other_entities` 的 id,`to` 可指人物或其他实体。
386
+
387
+ **`main_line_branch_relation[].relation_kind`** —— 只从这 6 个值里选:`促成` / `阻碍` / `并行` / `揭示` / `收束` / `依存`。
388
+
389
+ **`faction_membership[].member_relation`** —— 只从这 8 个值里选:`利益交换` / `合作` / `对立` / `利用` / `师徒` / `雇佣` / `血亲` / `无`。
390
+
391
+ **`faction_relations[].relation_type`** —— 只从这 4 个值里选:`合作` / `对立` / `利用` / `中立`。
392
+
393
+ > ⚠️ **这是四套互不相同的词表,别串用**:
394
+ > `relation_kind`(角色关系,13 值,含扩展出口 `其他`)/ `member_relation`(成员关系,8 值)/ `relation_type`(势力关系,4 值)/ `main_line_branch_relation[].relation_kind`(支线挂主线,6 值)。
395
+ > 拿 `relation_kind` 的值去填 `member_relation` 或 `relation_type` 一律报 ENUM
396
+ > (tt5 实测 2026-10-27:9 条 ENUM 错误,2 个批次重写,理由全是"从角色关系词表里取值")。
397
+
398
+ ### 8.3 关键约束
399
+
400
+ - **所有 id 字段填 id,不填名字**;id 必须来自实体清单(`SKELETON_REF_MISSING` 会查)
401
+ - **同一对角色,正反两个方向的关系要相容**:不能一边 `合作` 一边 `敌对`,也不能互相 `服从`(`REL_ASYMMETRIC_INCOMPATIBLE` 会查)
402
+ - **同一有序对不能写两种关系类型**(`REL_KIND_CONFLICT` 会查)
403
+ - **不能自环**:`from` 与 `to` 不能是同一个 id(`NO_SELF_RELATION` 会查)
404
+ - **对立势力关系必须写双向两行**:`A→B` 与 `B→A` 都要写,且关系类型一致(`G_REL_ONE_WAY` / `G_REL_ASYMMETRIC` 会查)。合作/利用/中立写一行即可(校验器只对"对立"强制双向)
405
+ - **每个实体都要连上**:`G_ISOLATED` 会查孤立节点 —— 角色、冲突、势力都得有关系
406
+ - **`faction_relations` 的行数 = `quota.faction_relation_count`(每对关系一行)或它的 2 倍**(对立关系写双向两行时)。`quota.faction_relation_count` 记的是**无向关系对数**,不是行数
407
+ - **每条支线都要挂到主线上**:`main_line_branch_relation` 一行代表"一条支线挂到主线上",每个支线 id 都要出现(`BRANCH_MAINLINE_UNLINKED` 会查);反过来每条主线也要挂到支线(`MAINLINE_BRANCH_UNLINKED` 会查)
408
+ - **只写 ID 引用 + 关系类型/标签**,不写大段描述(描述属于血肉阶段,`EXTRA_FIELD` 会查)
409
+ - **`other_relations` 不能自环**:`from` 与 `to` 不能是同一个 id;每个 `other_entities` 至少要有一条关系,不能是孤立设定(`G_ISOLATED` 会查)
410
+
411
+ ---
412
+
413
+ <!-- contract:file:层级 -->
414
+ ## 九、层级.json 的字段契约
415
+
416
+ **顶层**:4 个数组 **模板**:`模板/骨架/层级模板.json`
417
+
418
+ | 数组 | 一行代表什么 | 字段 |
419
+ |---|---|---|
420
+ | `volumes` | 一卷 | `id` `name` `theme_short` |
421
+ | `acts` | 一卷里的一幕 | `volume` `act_index` `theme_short` |
422
+ | `main_line_span` | 一条主线跨哪几卷 | `main_line` `volume_ratio` |
423
+ | `branch_span` | 一条支线跨哪几卷 | `branch` `volume_ratio` |
424
+
425
+ ### 关键约束
426
+
427
+ - **`volumes` 的条数 = `quota.volume_count`**(`VOLUME_COUNT_MISMATCH` 会查)
428
+ - **`volumes[].id` 格式 `V001`、`V002`……连续不跳号**,与框架的 `volume_ratio[].volume_id` 一一对应
429
+ - **`acts[].volume` 必须是 volumes 里已有的卷 id**(`SKELETON_REF_MISSING` 会查)
430
+ - **同一卷内 `act_index` 不能重复**(`ACT_INDEX_DUP` 会查)
431
+ - **`main_line_span[].main_line` / `branch_span[].branch` 必须是实体清单里的 id**(`SKELETON_REF_MISSING` 会查)
432
+ - **`main_line_span` 的条数 = 主线数,`branch_span` 的条数 = 支线数**(与实体清单一致)
433
+ - **`volume_ratio` 是数组,元素在 [0,1] 内**(`SPAN_RATIO_RANGE` 会查)
434
+ - **不许出现章节号**(`SKELETON_CHAPTER_FORBIDDEN` 会查)
435
+
436
+ ---
437
+
438
+ <!-- contract:consistency -->
439
+ ## 十、本阶段全量校验清单
440
+
441
+ 全量模式(插件在四个文件都产出后跑一次)检查以下项目:
442
+
443
+ | 检查 | 错误代码 | 类型 |
444
+ |---|---|---|
445
+ | 章节号越界 | `SKELETON_CHAPTER_FORBIDDEN` | error |
446
+ | 模板结构 | `EXTRA_FIELD` / `REQUIRED` / `TYPE` / `PATTERN` / `ENUM` / `ENUM_MISSING` | error |
447
+ | 字符集 | `CHARSET_KO` / `CHARSET_JP` | error |
448
+ | 占位符 | `PLACEHOLDER` | error |
449
+ | ID 唯一 | `ID_DUP` | error |
450
+ | 名称唯一 | `NAME_DUP` | error |
451
+ | 名称软重复 | `NAME_ALIAS_SUSPECT` | warning |
452
+ | derivations 完整性 | `DERIVATION_MISSING` / `DERIVATION_EXTRA` | error |
453
+ | derivations 区间 | `DERIVATION_RANGE_MISMATCH` | error |
454
+ | derivations 公式文本 | `DERIVATION_FORMULA_TEXT` | warning |
455
+ | 数量偏离 | `QUANTITY_MISMATCH` | warning |
456
+ | capacity 一致性 | `CAPACITY_MISMATCH` | error |
457
+ | volume_ratio 长度/总和/取值 | `VOLUME_RATIO_LENGTH` / `VOLUME_RATIO_SUM` / `VOLUME_RATIO_RANGE` | error |
458
+ | span 长度 | `SPAN_LENGTH_MISMATCH` | error |
459
+ | span 比例范围 | `SPAN_RATIO_RANGE` | error |
460
+ | 关系引用 | `SKELETON_REF_MISSING` | error |
461
+ | 图孤立 | `G_ISOLATED` | error |
462
+ | 核心子图连通 | `G_DISCONNECTED` | warning |
463
+ | 势力关系对称 | `G_REL_ONE_WAY` / `G_REL_ASYMMETRIC` | error |
464
+ | **quota 一致性** | **`QUOTA_MISMATCH`** | **error** |
465
+ | **全书级结局数量** | **`BOOK_ENDING_COUNT`** | **error** |
466
+ | **卷数量一致** | **`VOLUME_COUNT_MISMATCH`** | **error** |
467
+ | **act_index 唯一** | **`ACT_INDEX_DUP`** | **error** |
468
+ | **关系组合重复** | **`ID_DUP`** | **error** |
469
+ | 关系类型语义 | `REL_KIND_CONFLICT` / `REL_ASYMMETRIC_INCOMPATIBLE` | error |
470
+ | 关系自环 | `NO_SELF_RELATION` | error |
471
+ | 内容质量 | `NAME_PLACEHOLDER` / `TEXT_PLACEHOLDER` / `TEXT_TOO_SHORT` / `TEXT_DUPLICATE` | error |
472
+ | 规则分类与前缀 | `WORLD_RULE_CATEGORY_MISMATCH` | error |
473
+ | 下游节奏可行性 | `RHYTHM_INFEASIBLE_PRECHECK` | error |
474
+
475
+ **注**:加粗的 5 项是核心检查项,生成时必须保证通过。
476
+
477
+ ---
478
+
479
+ <!-- contract:errors -->
480
+ ## 十一、常见错误代码速查(详见 glossary 与脚本)
481
+
482
+ | code | 含义 | 修复方向 |
483
+ |---|---|---|
484
+ | `EXTRA_FIELD` | 模板外字段 | 删除该字段 |
485
+ | `REQUIRED` | 必填为空 | 补值 |
486
+ | `TYPE` | 类型错误 | 按模板改 |
487
+ | `PATTERN` | 正则不匹配 | 按 ID 规范改 |
488
+ | `ENUM` | 枚举值非法 | 查第七、八节的枚举表 |
489
+ | `ENUM_MISSING` | 枚举未定义 | 查 glossary |
490
+ | `SKELETON_CHAPTER_FORBIDDEN` | 骨架出现章节号 | 删除,移到节奏阶段 |
491
+ | `SKELETON_REF_MISSING` | 关系引用的 id 不存在 | 改成实体清单里已有的 id |
492
+ | `BRANCH_MAINLINE_UNLINKED` | 有支线没挂到任何主线 | 给每条支线补一行 `main_line_branch_relation` |
493
+ | `MAINLINE_BRANCH_UNLINKED` | 有主线没挂任何支线 | 给这条主线补支线关系 |
494
+ | `ID_DUP` | 同文件 ID 重复 / 关系组合重复 | 重新编号 / 删重复 |
495
+ | `NAME_DUP` | 名称重复 | 改名 |
496
+ | `NAME_ALIAS_SUSPECT`(warning) | 归一化后同名,疑似同一实体的全称/简称/别名 | 确认后只保留正式名,合并另一条 |
497
+ | `CHARSET_KO` / `CHARSET_JP` | 含韩文/日文 | 删除 |
498
+ | `PLACEHOLDER` | 含占位符 | 改为具体值 |
499
+ | `DERIVATION_MISSING` | 缺推导记录 | 补 derivations |
500
+ | `DERIVATION_EXTRA` | 多写推导记录 | 删除多余 key |
501
+ | `DERIVATION_RANGE_MISMATCH` | 区间与公式不符 | 按公式重算 |
502
+ | `DERIVATION_FORMULA_TEXT`(warning) | formula 文本不符 | 逐字复制 formulas-skeleton.json |
503
+ | `DERIVATION_EVAL` | 公式表达式本身求值失败 | 这是公式定义的问题,不是你写的数字;照抄公式即可(若仍报错说明插件内置公式有误) |
504
+ | `CAPACITY_MISMATCH` | 平均字数与总字数/章数不符 | 改 avg_words_per_chapter |
505
+ | `VOLUME_RATIO_LENGTH` | volume_ratio 长度与 volume_count 不符 | 补齐或删除 |
506
+ | `VOLUME_RATIO_SUM` | volume_ratio 之和不为 1.0 | 调整比例 |
507
+ | `VOLUME_RATIO_RANGE` | volume_ratio 里某项的 chapter_ratio 不在 [0,1] 内(负数会让节奏阶段算出负的期望章数) | 按各卷实际章数重新分配比例 |
508
+ | `VOLUME_COUNT_MISMATCH` | 层级 volumes 长度与 quota.volume_count 不符 | 补齐或删除 |
509
+ | `SPAN_LENGTH_MISMATCH` | span 长度与主线/支线数不符 | 补齐 |
510
+ | `SPAN_RATIO_RANGE` | span 的 volume_ratio 元素不在 [0,1] 内 | 调整 |
511
+ | `ACT_INDEX_DUP` | 同卷内 act_index 重复 | 改为唯一值 |
512
+ | `QUOTA_MISMATCH` | quota 声明值与实体数组实际数量不符 | 调整 quota 或实体 |
513
+ | `BOOK_ENDING_COUNT` | 全书级结局数量不是恰好 1 个 | 调整结局的 level |
514
+ | `G_ISOLATED` | 孤立节点 | 补引用 |
515
+ | `G_DISCONNECTED`(warning) | 核心子图不连通 | 补角色/冲突/势力关系 |
516
+ | `G_REL_ONE_WAY` | 势力对立单向 | 补另一方向 |
517
+ | `G_REL_ASYMMETRIC` | 势力关系不对称 | 统一双向 |
518
+ | `QUANTITY_MISMATCH`(warning) | 数量偏离公式区间 | 在 note 写理由,或调回区间 |
519
+ | `WORLD_RULE_CATEGORY_MISMATCH` | 规则 id 前缀与 `category` 字段不匹配 | R→核心规则,I→信息规则,SR→社会规则(骨架只有 `world_rules` 一个数组) |
520
+ | `CROSS_TYPE_NAME_DUP`(warning) | 跨类型同名(含归一化后的全称/简称) | 改名,避免跨类型歧义 |
521
+ | `EMPTY_HARD_CONSTRAINTS` | 硬门禁为空 | 至少写一条硬约束,或确认任务输入本就没有 |
522
+ | `NO_SELF_RELATION` | 关系两端相同 | 删掉自环 |
523
+ | `REL_KIND_CONFLICT` | 同一有序对写了两种关系类型 | 保留一种 |
524
+ | `REL_LABEL_REQUIRED` | `relation_kind=其他` 或 `other_relations` 缺 `relation_label` | 补具体关系名(附身/寄生/契约/共生) |
525
+ | `REL_ASYMMETRIC_INCOMPATIBLE` | 同一对角色正反两个方向的关系语义冲突 | 统一成一个意思 |
526
+ | `REL_KIND_META_DRIFT` | 关系词表与元数据不同步 | 脚本/词表不同步,停下来上报 |
527
+ | `NAME_PLACEHOLDER` | 实体名是"主角1"这类占位名 | 换成有辨识度的专名 |
528
+ | `TEXT_PLACEHOLDER` | 字段内容是"待补充/TBD/xxx"这类占位 | 写实内容 |
529
+ | `TEXT_TOO_SHORT` | 字段内容过短 | 补成一句具体的事实 |
530
+ | `TEXT_DUPLICATE` | 两个实体的同一字段几乎一字不差 | 各写各的具体内容 |
531
+ | `RHYTHM_INFEASIBLE_PRECHECK` | 卷数/分支数组合下游节奏阶段无解 | **看错误里的方向**:支线数太少就调大 `branch_count`,太多就调小;不要凭感觉改 |
532
+ | `NEED_ALL_CHECK`(warning) | 单检通过,但还缺全量校验 | 四个文件单检都通过后跑一次 `--all` |
533
+
534
+ ---
535
+
536
+ <!-- contract:forbidden -->
537
+ ## 十二、本阶段禁令(13 条)
538
+
539
+ 1. **不得出现任何章节号**(`chapter` / `ch` / `start` / `end` / `appearance_chapters` / `chapter_range` / `buried_chapter` / `recovered_chapter` / `key_nodes` 等,完整清单见 glossary 第六节)。骨架脚本会报 `SKELETON_CHAPTER_FORBIDDEN`。
540
+
541
+ 2. **不得出现模板外字段**(`EXTRA_FIELD` 会拦截)。数据文件顶层只允许模板 `structure.properties` 中定义的字段。
542
+
543
+ 3. **实体清单只写 `id` + `name` + 枚举字段**(描述属于血肉阶段)。`EXTRA_FIELD` 会拦截。
544
+
545
+ 4. **关系清单只写 ID 引用 + 关系类型枚举**(描述属于血肉阶段)。`EXTRA_FIELD` 会拦截。
546
+
547
+ 5. **本阶段只输出 4 个 JSON**,不预先编写血肉/节奏/写作的任何字段。
548
+
549
+ 6. **`derivations` 必须包含 formulas-skeleton.json 的全部 30 条记录**,不多不少。每条 value 为 `{formula, range_low, range_high, note}`,`formula` 逐字一致。
550
+
551
+ 7. **数量偏离公式区间时在 note 写明理由**(会产生 warning,不阻塞)。不得默默偏离。
552
+
553
+ 8. **不声称"已读取"参考文件**;引用了哪份文件就说明它的路径与作用。
554
+
555
+ 9. **JSON 语法符号用英文**(`{` `}` `[` `]` `:` `,` `"`),字符串内容用中文标点。
556
+
557
+ 10. **不输出"通过/完成/PASS/✅"等结论词**。只有插件校验通过后才会有结论,那是插件说的,不是你说的。
558
+
559
+ 11. **不得修改 `模板/` 和 `references/` 下的任何文件**。`模板/` 是骨架阶段的结构来源,`references/` 是规则/公式/枚举/glossary 来源,两者都是**只读输入**。脚本若存在缺陷,停下来上报(原因:脚本缺陷);**严禁为了"通过校验"而修改 scripts 下的 validator 或 references 下的规则文件**。所有脚本与参考文件的修改由项目维护者通过 plugin 升级路径完成。**本阶段的输出目录 `设定/raw/sources/骨架/` 是你要写的产物**,不是只读输入。
560
+
561
+ 12. **关系类型只取第八节的两套词表**;实体名用真名,叙述字段写实内容。
562
+
563
+ 13. **只写本轮指令指定的那一个分片文件**。不要写别的文件,不要改已经产出的文件 —— 插件会负责把分片合并成最终产物。