@oh-story/dsh 0.1.10 → 0.1.12

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 (444) hide show
  1. package/README.md +11 -11
  2. package/lib/client.js +7 -3
  3. package/lib/client.js.map +2 -2
  4. package/lib/drama/manifest.json +212 -142
  5. package/lib/drama/skills/short-drama/SKILL.md +14 -2
  6. package/lib/drama/skills/short-drama/assets/project-template/short-drama.json +3 -0
  7. package/lib/drama/skills/short-drama/references/creator-documents.md +3 -0
  8. package/lib/drama/skills/short-drama/references/knowhow-index.md +15 -0
  9. package/lib/drama/skills/short-drama/scripts/project_tool.py +131 -0
  10. package/lib/drama/skills/short-drama-assets/SKILL.md +2 -1
  11. package/lib/drama/skills/short-drama-assets/references/asset-review-checklist.md +2 -0
  12. package/lib/drama/skills/short-drama-assets/references/era-anchors.md +37 -0
  13. package/lib/drama/skills/short-drama-assets/references/stage-contract.md +2 -0
  14. package/lib/drama/skills/short-drama-develop/SKILL.md +10 -4
  15. package/lib/drama/skills/short-drama-develop/assets/adaptation-map.example.jsonl +1 -1
  16. package/lib/drama/skills/short-drama-develop/assets/creative-brief.md +8 -0
  17. package/lib/drama/skills/short-drama-develop/references/adaptation-craft.md +80 -13
  18. package/lib/drama/skills/short-drama-develop/references/episode-design.md +95 -12
  19. package/lib/drama/skills/short-drama-develop/references/genre-and-hook-playbook.md +9 -5
  20. package/lib/drama/skills/short-drama-develop/references/genre-cards//345/244/215/344/273/207/346/211/223/350/204/270.md +1 -1
  21. package/lib/drama/skills/short-drama-develop/references/genre-cards//347/263/273/347/273/237/346/265/201.md +51 -0
  22. package/lib/drama/skills/short-drama-develop/references/genre-cards//351/200/206/350/242/255.md +51 -0
  23. package/lib/drama/skills/short-drama-develop/references/genre-cards//351/207/215/347/224/237/347/251/277/350/266/212.md +51 -0
  24. package/lib/drama/skills/short-drama-develop/references/genre-cards.md +10 -7
  25. package/lib/drama/skills/short-drama-develop/references/premise-devices.md +15 -9
  26. package/lib/drama/skills/short-drama-develop/references/serial-character-and-memory.md +3 -2
  27. package/lib/drama/skills/short-drama-develop/references/stage-contract.md +14 -7
  28. package/lib/drama/skills/short-drama-develop/references/story-craft.md +7 -3
  29. package/lib/drama/skills/short-drama-edit/SKILL.md +43 -20
  30. package/lib/drama/skills/short-drama-edit/assets/remotion/README.md +49 -13
  31. package/lib/drama/skills/short-drama-edit/assets/remotion/package.json +4 -2
  32. package/lib/drama/skills/short-drama-edit/assets/remotion/src/Overlay.tsx +31 -0
  33. package/lib/drama/skills/short-drama-edit/assets/remotion/src/Root.tsx +5 -5
  34. package/lib/drama/skills/short-drama-edit/assets/remotion/src/Subtitles.tsx +68 -69
  35. package/lib/drama/skills/short-drama-edit/assets/remotion/src/font.ts +39 -29
  36. package/lib/drama/skills/short-drama-edit/assets/remotion/src/rules.mjs +188 -0
  37. package/lib/drama/skills/short-drama-edit/assets/remotion/src/schema.ts +26 -13
  38. package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/Card.tsx +72 -0
  39. package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/CornerChip.tsx +39 -0
  40. package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/ScreenText.tsx +36 -0
  41. package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/SystemPanel.tsx +44 -0
  42. package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/TaskPanel.tsx +100 -0
  43. package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/chrome.tsx +197 -0
  44. package/lib/drama/skills/short-drama-edit/assets/remotion/src/screen/tokens.ts +62 -0
  45. package/lib/drama/skills/short-drama-edit/assets/remotion/tsconfig.json +1 -0
  46. package/lib/drama/skills/short-drama-edit/assets//345/211/252/350/276/221/345/215/225.md +4 -2
  47. package/lib/drama/skills/short-drama-edit/references/cut-craft.md +3 -1
  48. package/lib/drama/skills/short-drama-edit/references/delivery-verify.md +6 -2
  49. package/lib/drama/skills/short-drama-edit/references/generated-footage.md +12 -6
  50. package/lib/drama/skills/short-drama-edit/references/sound-and-subtitles.md +13 -8
  51. package/lib/drama/skills/short-drama-edit/references/stage-contract.md +2 -0
  52. package/lib/drama/skills/short-drama-edit/scripts/edit_tool.py +1153 -121
  53. package/lib/drama/skills/short-drama-edit/scripts/selftest.py +49 -9
  54. package/lib/drama/skills/short-drama-novel-analyze/SKILL.md +3 -3
  55. package/lib/drama/skills/short-drama-novel-analyze/assets/episode-candidate.example.jsonl +2 -2
  56. package/lib/drama/skills/short-drama-novel-analyze/references/adaptation-triage.md +8 -4
  57. package/lib/drama/skills/short-drama-novel-analyze/references/adaptation-value.md +10 -3
  58. package/lib/drama/skills/short-drama-novel-analyze/references/aggregation-and-entities.md +25 -1
  59. package/lib/drama/skills/short-drama-novel-analyze/references/stage-contract.md +1 -0
  60. package/lib/drama/skills/short-drama-review/SKILL.md +2 -2
  61. package/lib/drama/skills/short-drama-review/references/review-method.md +6 -1
  62. package/lib/drama/skills/short-drama-review/references/rubric-assets-prompts.md +11 -0
  63. package/lib/drama/skills/short-drama-review/references/rubric-story-script.md +77 -3
  64. package/lib/drama/skills/short-drama-review/references/rubric-visual-motion.md +15 -0
  65. package/lib/drama/skills/short-drama-review/references/stage-contract.md +3 -0
  66. package/lib/drama/skills/short-drama-storyboard/SKILL.md +13 -5
  67. package/lib/drama/skills/short-drama-storyboard/references/blocking-playbooks.md +1 -1
  68. package/lib/drama/skills/short-drama-storyboard/references/production-shot-grammar.md +2 -2
  69. package/lib/drama/skills/short-drama-storyboard/references/shot-craft.md +82 -14
  70. package/lib/drama/skills/short-drama-storyboard/references/stage-contract.md +4 -2
  71. package/lib/drama/skills/short-drama-video-prompts/SKILL.md +5 -3
  72. package/lib/drama/skills/short-drama-video-prompts/references/camera-audio-continuity.md +12 -0
  73. package/lib/drama/skills/short-drama-video-prompts/references/delivery-profile.md +4 -5
  74. package/lib/drama/skills/short-drama-video-prompts/references/generability.md +4 -2
  75. package/lib/drama/skills/short-drama-video-prompts/references/minimax-h3.md +40 -1
  76. package/lib/drama/skills/short-drama-video-prompts/references/motion-recipe.md +20 -14
  77. package/lib/drama/skills/short-drama-video-prompts/references/performance-action-timing.md +1 -1
  78. package/lib/drama/skills/short-drama-video-prompts/references/production-prompt-grammar.md +8 -7
  79. package/lib/drama/skills/short-drama-video-prompts/references/review-and-fixtures.md +1 -1
  80. package/lib/drama/skills/short-drama-video-prompts/references/stage-contract.md +1 -0
  81. package/lib/drama/skills/short-drama-video-prompts/references/target-model-profile.md +8 -1
  82. package/lib/drama/skills/short-drama-video-prompts/references/wan-3.0.md +103 -0
  83. package/lib/drama/skills/short-drama-video-prompts/scripts/motion_timing_check.py +8 -7
  84. package/lib/drama/skills/short-drama-write/SKILL.md +8 -3
  85. package/lib/drama/skills/short-drama-write/references/dialogue-craft.md +1 -1
  86. package/lib/drama/skills/short-drama-write/references/script-craft.md +56 -3
  87. package/lib/drama/skills/short-drama-write/references/stage-contract.md +4 -0
  88. package/lib/drama/skills/short-drama-write/scripts/duration_estimate.py +48 -2
  89. package/lib/index.js +71 -21
  90. package/lib/index.js.map +3 -3
  91. package/lib/oh-story/manifest.json +545 -310
  92. package/lib/oh-story/roles/chapter-extractor.md +11 -11
  93. package/lib/oh-story/roles/character-designer.md +1 -2
  94. package/lib/oh-story/roles/consistency-checker.md +11 -9
  95. package/lib/oh-story/roles/narrative-writer.md +24 -25
  96. package/lib/oh-story/roles/story-architect.md +9 -61
  97. package/lib/oh-story/roles/story-explorer.md +20 -125
  98. package/lib/oh-story/roles/story-researcher.md +0 -1
  99. package/lib/oh-story/skills/story/SKILL.md +6 -6
  100. package/lib/oh-story/skills/story/VERSION +1 -1
  101. package/lib/oh-story/skills/story/references/author-memory-maintenance.md +75 -0
  102. package/lib/oh-story/skills/story/references/author-memory.md +40 -118
  103. package/lib/oh-story/skills/story/scripts/author_memory_commit.py +3 -3
  104. package/lib/oh-story/skills/story-deslop/SKILL.md +24 -25
  105. package/lib/oh-story/skills/story-deslop/references/agent-calls.md +5 -0
  106. package/lib/oh-story/skills/story-deslop/references/anti-ai-writing.md +1 -1
  107. package/lib/oh-story/skills/story-deslop/references/author-memory-maintenance.md +75 -0
  108. package/lib/oh-story/skills/story-deslop/references/author-memory.md +40 -118
  109. package/lib/oh-story/skills/story-deslop/references/banned-words.md +2 -2
  110. package/lib/oh-story/skills/story-deslop/references/deslop-gates.md +21 -4
  111. package/lib/oh-story/skills/story-deslop/references/style-resolution.md +4 -4
  112. package/lib/oh-story/skills/story-deslop/scripts/author_memory_commit.py +3 -3
  113. package/lib/oh-story/skills/story-deslop/scripts/check-ai-patterns.js +155 -8
  114. package/lib/oh-story/skills/story-import/SKILL.md +63 -579
  115. package/lib/oh-story/skills/story-import/references/deep-analysis.md +47 -0
  116. package/lib/oh-story/skills/story-import/references/format-and-structure.md +1 -1
  117. package/lib/oh-story/skills/story-import/references/import-report.md +64 -0
  118. package/lib/oh-story/skills/story-import/references/import-special-cases.md +34 -0
  119. package/lib/oh-story/skills/story-import/references/import-tracking.md +95 -0
  120. package/lib/oh-story/skills/story-import/references/length-routing.md +1 -1
  121. package/lib/oh-story/skills/story-import/references/outline-reverse-rules.md +79 -0
  122. package/lib/oh-story/skills/story-import/references/outline-reverse.md +24 -0
  123. package/lib/oh-story/skills/story-import/references/structure-mapping-long.md +95 -91
  124. package/lib/oh-story/skills/story-import/references/structure-mapping-short.md +24 -12
  125. package/lib/oh-story/skills/story-import/references/tracking-initialization.md +1 -1
  126. package/lib/oh-story/skills/story-import/references/tracking-transaction.md +11 -9
  127. package/lib/oh-story/skills/story-import/scripts/build_outline_brief.py +332 -0
  128. package/lib/oh-story/skills/story-import/scripts/check-outline-contract.js +101 -14
  129. package/lib/oh-story/skills/story-import/scripts/tracking_commit.py +278 -23
  130. package/lib/oh-story/skills/story-import/scripts/wordcount_core.py +179 -23
  131. package/lib/oh-story/skills/story-long-analyze/SKILL.md +28 -50
  132. package/lib/oh-story/skills/story-long-analyze/references/author-facing.md +12 -5
  133. package/lib/oh-story/skills/story-long-analyze/references/deconstruction-notes.md +1 -1
  134. package/lib/oh-story/skills/story-long-analyze/references/final-checks.md +19 -0
  135. package/lib/oh-story/skills/story-long-analyze/references/index-rebuild.md +11 -0
  136. package/lib/oh-story/skills/story-long-analyze/references/pipeline-ops.md +21 -55
  137. package/lib/oh-story/skills/story-long-analyze/references/stage1-golden-chapters.md +128 -0
  138. package/lib/oh-story/skills/story-long-analyze/references/stage2-extraction.md +229 -0
  139. package/lib/oh-story/skills/story-long-analyze/references/stage3-plot-rhythm.md +480 -0
  140. package/lib/oh-story/skills/story-long-analyze/references/stage4-characters-settings.md +195 -0
  141. package/lib/oh-story/skills/story-long-analyze/references/stage5-report.md +33 -0
  142. package/lib/oh-story/skills/story-long-analyze/references/style-profile-generator.md +17 -0
  143. package/lib/oh-story/skills/story-long-analyze/references/style-profile-protocol.md +1 -1
  144. package/lib/oh-story/skills/story-long-analyze/references/synthesis-inputs.md +39 -0
  145. package/lib/oh-story/skills/story-long-analyze/scripts/manage_analysis_run.py +47 -8
  146. package/lib/oh-story/skills/story-long-scan/SKILL.md +41 -193
  147. package/lib/oh-story/skills/story-long-scan/references/platform-ciweimao.md +19 -0
  148. package/lib/oh-story/skills/story-long-scan/references/platform-fanqie.md +45 -0
  149. package/lib/oh-story/skills/story-long-scan/references/platform-jjwxc.md +28 -0
  150. package/lib/oh-story/skills/story-long-scan/references/platform-qidian.md +35 -0
  151. package/lib/oh-story/skills/story-long-scan/references/platform-qimao.md +27 -0
  152. package/lib/oh-story/skills/story-long-scan/references/topic-decision.md +6 -2
  153. package/lib/oh-story/skills/story-long-write/SKILL.md +32 -73
  154. package/lib/oh-story/skills/story-long-write/references/agent-calls.md +47 -0
  155. package/lib/oh-story/skills/story-long-write/references/anti-ai-writing.md +1 -1
  156. package/lib/oh-story/skills/story-long-write/references/artifact-protocols.md +18 -201
  157. package/lib/oh-story/skills/story-long-write/references/author-memory-maintenance.md +75 -0
  158. package/lib/oh-story/skills/story-long-write/references/author-memory.md +40 -118
  159. package/lib/oh-story/skills/story-long-write/references/banned-words.md +2 -2
  160. package/lib/oh-story/skills/story-long-write/references/benchmark-recall.md +6 -10
  161. package/lib/oh-story/skills/story-long-write/references/character-relations.md +49 -1
  162. package/lib/oh-story/skills/story-long-write/references/deslop-gates.md +171 -0
  163. package/lib/oh-story/skills/story-long-write/references/emotion-on-page.md +116 -0
  164. package/lib/oh-story/skills/story-long-write/references/emotional-arc-design.md +1 -114
  165. package/lib/oh-story/skills/story-long-write/references/genre-prose-cards.md +1 -1
  166. package/lib/oh-story/skills/story-long-write/references/long-chapter-quality.md +3 -2
  167. package/lib/oh-story/skills/story-long-write/references/long-format.md +0 -8
  168. package/lib/oh-story/skills/story-long-write/references/long-genre-catalog.md +1 -1
  169. package/lib/oh-story/skills/story-long-write/references/long-genre-mechanics.md +3 -3
  170. package/lib/oh-story/skills/story-long-write/references/opening-design.md +2 -2
  171. package/lib/oh-story/skills/story-long-write/references/outline-conflict.md +4 -4
  172. package/lib/oh-story/skills/story-long-write/references/outline-methods.md +7 -7
  173. package/lib/oh-story/skills/story-long-write/references/outline-rhythm.md +3 -3
  174. package/lib/oh-story/skills/story-long-write/references/outline-structure-theory.md +14 -69
  175. package/lib/oh-story/skills/story-long-write/references/plot-frameworks.md +1 -1
  176. package/lib/oh-story/skills/story-long-write/references/plot-special-topics.md +2 -2
  177. package/lib/oh-story/skills/story-long-write/references/project-files.md +10 -6
  178. package/lib/oh-story/skills/story-long-write/references/reader-contract-and-progression.md +1 -1
  179. package/lib/oh-story/skills/story-long-write/references/reference-index.md +4 -4
  180. package/lib/oh-story/skills/story-long-write/references/stop-and-fix.md +9 -0
  181. package/lib/oh-story/skills/story-long-write/references/style-combat-face.md +1 -58
  182. package/lib/oh-story/skills/story-long-write/references/style-genre-modules.md +1 -1
  183. package/lib/oh-story/skills/story-long-write/references/style-resolution.md +4 -4
  184. package/lib/oh-story/skills/story-long-write/references/tracking-initialization.md +1 -1
  185. package/lib/oh-story/skills/story-long-write/references/tracking-transaction.md +11 -9
  186. package/lib/oh-story/skills/story-long-write/references/workflow-chapter.md +33 -44
  187. package/lib/oh-story/skills/story-long-write/references/workflow-daily.md +18 -51
  188. package/lib/oh-story/skills/story-long-write/references/workflow-outline.md +157 -0
  189. package/lib/oh-story/skills/story-long-write/references/workflow-revision.md +53 -67
  190. package/lib/oh-story/skills/story-long-write/references/workflow-setup.md +112 -251
  191. package/lib/oh-story/skills/story-long-write/references/workflow-volume.md +142 -0
  192. package/lib/oh-story/skills/story-long-write/references/writer-prompt-fallback.md +5 -3
  193. package/lib/oh-story/skills/story-long-write/references/writing-craft.md +18 -56
  194. package/lib/oh-story/skills/story-long-write/scripts/author_memory_commit.py +3 -3
  195. package/lib/oh-story/skills/story-long-write/scripts/build_architect_brief.py +260 -0
  196. package/lib/oh-story/skills/story-long-write/scripts/build_writer_prompt.py +96 -16
  197. package/lib/oh-story/skills/story-long-write/scripts/check-ai-patterns.js +155 -8
  198. package/lib/oh-story/skills/story-long-write/scripts/check-outline-contract.js +101 -14
  199. package/lib/oh-story/skills/story-long-write/scripts/check-outline-copy.js +7 -2
  200. package/lib/oh-story/skills/story-long-write/scripts/outline_view.py +2 -1
  201. package/lib/oh-story/skills/story-long-write/scripts/storyctl.py +250 -50
  202. package/lib/oh-story/skills/story-long-write/scripts/tracking_commit.py +278 -23
  203. package/lib/oh-story/skills/story-long-write/scripts/wordcount_core.py +179 -23
  204. package/lib/oh-story/skills/story-review/SKILL.md +19 -273
  205. package/lib/oh-story/skills/story-review/references/agent-prompts.md +184 -0
  206. package/lib/oh-story/skills/story-review/references/anti-ai-writing.md +1 -1
  207. package/lib/oh-story/skills/story-review/references/author-memory-maintenance.md +75 -0
  208. package/lib/oh-story/skills/story-review/references/author-memory.md +40 -118
  209. package/lib/oh-story/skills/story-review/references/banned-words.md +2 -2
  210. package/lib/oh-story/skills/story-review/references/batch-review.md +19 -0
  211. package/lib/oh-story/skills/story-review/references/character-relations.md +49 -1
  212. package/lib/oh-story/skills/story-review/references/review-quality.md +2 -1
  213. package/lib/oh-story/skills/story-review/references/review-tracking.md +10 -0
  214. package/lib/oh-story/skills/story-review/references/solo.md +52 -0
  215. package/lib/oh-story/skills/story-review/references/style-resolution.md +4 -4
  216. package/lib/oh-story/skills/story-review/references/tracking-initialization.md +1 -1
  217. package/lib/oh-story/skills/story-review/references/tracking-transaction.md +11 -9
  218. package/lib/oh-story/skills/story-review/scripts/author_memory_commit.py +3 -3
  219. package/lib/oh-story/skills/story-review/scripts/check-ai-patterns.js +155 -8
  220. package/lib/oh-story/skills/story-review/scripts/tracking_commit.py +278 -23
  221. package/lib/oh-story/skills/story-review/scripts/wordcount_core.py +179 -23
  222. package/lib/oh-story/skills/story-setup/SKILL.md +69 -458
  223. package/lib/oh-story/skills/story-setup/references/agent-references/agent-quality.md +4 -4
  224. package/lib/oh-story/skills/story-setup/references/agent-references/anti-ai-writing.md +1 -1
  225. package/lib/oh-story/skills/story-setup/references/agent-references/banned-words.md +2 -2
  226. package/lib/oh-story/skills/story-setup/references/agent-references/benchmark-style-load.md +107 -0
  227. package/lib/oh-story/skills/story-setup/references/agent-references/character-relations.md +49 -1
  228. package/lib/oh-story/skills/story-setup/references/agent-references/deslop-gates.md +21 -4
  229. package/lib/oh-story/skills/story-setup/references/agent-references/emotion-on-page.md +116 -0
  230. package/lib/oh-story/skills/story-setup/references/agent-references/emotional-arc-design.md +1 -114
  231. package/lib/oh-story/skills/story-setup/references/agent-references/format-and-structure.md +1 -1
  232. package/lib/oh-story/skills/story-setup/references/agent-references/genre-prose-cards.md +1 -1
  233. package/lib/oh-story/skills/story-setup/references/agent-references/long-genre-catalog.md +1 -1
  234. package/lib/oh-story/skills/story-setup/references/agent-references/long-genre-mechanics.md +3 -3
  235. package/lib/oh-story/skills/story-setup/references/agent-references/long-quality.md +7 -5
  236. package/lib/oh-story/skills/story-setup/references/agent-references/opening-design.md +2 -2
  237. package/lib/oh-story/skills/story-setup/references/agent-references/outline-conflict.md +4 -4
  238. package/lib/oh-story/skills/story-setup/references/agent-references/outline-methods.md +7 -7
  239. package/lib/oh-story/skills/story-setup/references/agent-references/outline-rhythm.md +3 -3
  240. package/lib/oh-story/skills/story-setup/references/agent-references/short-emotional-methods.md +1 -1
  241. package/lib/oh-story/skills/story-setup/references/agent-references/short-genre-formulas.md +0 -15
  242. package/lib/oh-story/skills/story-setup/references/agent-references/short-reversal.md +1 -1
  243. package/lib/oh-story/skills/story-setup/references/agent-references/style-combat-face.md +1 -58
  244. package/lib/oh-story/skills/story-setup/references/agent-references/style-genre-modules.md +1 -1
  245. package/lib/oh-story/skills/story-setup/references/agent-references/style-resolution.md +4 -4
  246. package/lib/oh-story/skills/story-setup/references/agent-references/writing-craft.md +18 -56
  247. package/lib/oh-story/skills/story-setup/references/diagnostics.md +3 -3
  248. package/lib/oh-story/skills/story-short-analyze/SKILL.md +37 -110
  249. package/lib/oh-story/skills/story-short-analyze/references/analysis-character-relations.md +1 -1
  250. package/lib/oh-story/skills/story-short-analyze/references/analysis-method.md +42 -0
  251. package/lib/oh-story/skills/story-short-analyze/references/optional-modules.md +97 -0
  252. package/lib/oh-story/skills/story-short-analyze/references/output-contract.md +9 -47
  253. package/lib/oh-story/skills/story-short-analyze/references/quality-checklist.md +80 -0
  254. package/lib/oh-story/skills/story-short-analyze/references/source-story-quality.md +4 -4
  255. package/lib/oh-story/skills/story-short-analyze/references/stage2-3-structure-emotion.md +308 -0
  256. package/lib/oh-story/skills/story-short-analyze/references/{material-decomposition.md → stage4-6-reversal-summary.md} +303 -374
  257. package/lib/oh-story/skills/story-short-scan/SKILL.md +30 -64
  258. package/lib/oh-story/skills/story-short-scan/references/manual-rank-input.md +36 -0
  259. package/lib/oh-story/skills/story-short-scan/references/platform-dianzhong.md +24 -0
  260. package/lib/oh-story/skills/story-short-scan/references/platform-heiyan.md +21 -0
  261. package/lib/oh-story/skills/story-short-scan/references/topic-match.md +38 -0
  262. package/lib/oh-story/skills/story-short-write/SKILL.md +23 -34
  263. package/lib/oh-story/skills/story-short-write/references/agent-calls.md +13 -0
  264. package/lib/oh-story/skills/story-short-write/references/author-memory-maintenance.md +75 -0
  265. package/lib/oh-story/skills/story-short-write/references/author-memory.md +40 -118
  266. package/lib/oh-story/skills/story-short-write/references/banned-words.md +2 -2
  267. package/lib/oh-story/skills/story-short-write/references/benchmark-recall.md +1 -21
  268. package/lib/oh-story/skills/story-short-write/references/emotional-methods.md +1 -1
  269. package/lib/oh-story/skills/story-short-write/references/genre-writing-formulas.md +0 -15
  270. package/lib/oh-story/skills/story-short-write/references/output-contract.md +9 -47
  271. package/lib/oh-story/skills/story-short-write/references/reference-index.md +17 -49
  272. package/lib/oh-story/skills/story-short-write/references/scene-craft.md +40 -0
  273. package/lib/oh-story/skills/story-short-write/references/short-craft.md +7 -43
  274. package/lib/oh-story/skills/story-short-write/references/short-format.md +3 -3
  275. package/lib/oh-story/skills/story-short-write/references/short-prose-quality.md +2 -1
  276. package/lib/oh-story/skills/story-short-write/references/short-reversal.md +1 -1
  277. package/lib/oh-story/skills/story-short-write/references/style-resolution.md +4 -4
  278. package/lib/oh-story/skills/story-short-write/references/submission-craft.md +1 -1
  279. package/lib/oh-story/skills/story-short-write/references/villain-and-reveal.md +5 -10
  280. package/lib/oh-story/skills/story-short-write/references/workflow-design.md +19 -12
  281. package/lib/oh-story/skills/story-short-write/references/workflow-draft.md +22 -32
  282. package/lib/oh-story/skills/story-short-write/references/workflow-revision.md +84 -17
  283. package/lib/oh-story/skills/story-short-write/references/writing-workflow.md +7 -119
  284. package/lib/oh-story/skills/story-short-write/scripts/author_memory_commit.py +3 -3
  285. package/lib/oh-story/skills/story-short-write/scripts/check-ai-patterns.js +155 -8
  286. package/lib/oh-story/skills/story-short-write/scripts/check-outline-copy.js +7 -2
  287. package/lib/types/client/video-studio.d.ts.map +1 -1
  288. package/lib/types/native-hooks.d.ts +2 -2
  289. package/lib/types/native-hooks.d.ts.map +1 -1
  290. package/lib/types/role-tool.d.ts.map +1 -1
  291. package/lib/types/skill-provider.d.ts.map +1 -1
  292. package/lib/types/video-project.d.ts.map +1 -1
  293. package/lib/types/workspace-route.d.ts.map +1 -1
  294. package/lib/video-recap/CHANGELOG.md +60 -1
  295. package/lib/video-recap/README.en.md +348 -137
  296. package/lib/video-recap/README.md +340 -136
  297. package/lib/video-recap/manifest.json +406 -251
  298. package/lib/video-recap/skills/video-assemble/SKILL.md +30 -15
  299. package/lib/video-recap/skills/video-assemble/references/audio-modes.md +63 -0
  300. package/lib/video-recap/skills/video-assemble/references/explicit-audio-mix.md +75 -0
  301. package/lib/video-recap/skills/video-assemble/references/foreground-compose.md +118 -0
  302. package/lib/video-recap/skills/video-assemble/references/narration-adoption.md +103 -0
  303. package/lib/video-recap/skills/video-assemble/references/packaging.md +45 -0
  304. package/lib/video-recap/skills/video-assemble/references/pair-media.md +74 -0
  305. package/lib/video-recap/skills/video-assemble/references/source-score.md +147 -0
  306. package/lib/video-recap/skills/video-assemble/references/subtitle-track.md +202 -0
  307. package/lib/video-recap/skills/video-assemble/scripts/adoption/__init__.py +1 -0
  308. package/lib/video-recap/skills/video-assemble/scripts/adoption/audio_mix_binding.py +279 -0
  309. package/lib/video-recap/skills/video-assemble/scripts/adoption/frozen_audio.py +187 -0
  310. package/lib/video-recap/skills/video-assemble/scripts/adoption/narration_binding.py +323 -0
  311. package/lib/video-recap/skills/video-assemble/scripts/adoption/strict_inputs.py +109 -0
  312. package/lib/video-recap/skills/video-assemble/scripts/adoption/strict_publish.py +130 -0
  313. package/lib/video-recap/skills/video-assemble/scripts/artifacts.py +10 -46
  314. package/lib/video-recap/skills/video-assemble/scripts/assemble.py +378 -119
  315. package/lib/video-recap/skills/video-assemble/scripts/assemble_constants.py +29 -12
  316. package/lib/video-recap/skills/video-assemble/scripts/assembly_contract.py +95 -44
  317. package/lib/video-recap/skills/video-assemble/scripts/assembly_settings.py +75 -32
  318. package/lib/video-recap/skills/video-assemble/scripts/audio_mix.py +11 -11
  319. package/lib/video-recap/skills/video-assemble/scripts/compose_foreground.py +293 -0
  320. package/lib/video-recap/skills/video-assemble/scripts/export_jianying.py +71 -78
  321. package/lib/video-recap/skills/video-assemble/scripts/jianying/__init__.py +1 -0
  322. package/lib/video-recap/skills/video-assemble/scripts/{jianying_builders.py → jianying/builders.py} +39 -67
  323. package/lib/video-recap/skills/video-assemble/scripts/{jianying_model.py → jianying/model.py} +3 -11
  324. package/lib/video-recap/skills/video-assemble/scripts/{jianying_optional.py → jianying/optional.py} +1 -1
  325. package/lib/video-recap/skills/video-assemble/scripts/jianying/schema.py +53 -0
  326. package/lib/video-recap/skills/video-assemble/scripts/{jianying_templates.py → jianying/templates.py} +1 -1
  327. package/lib/video-recap/skills/video-assemble/scripts/{jianying_timeline_contract.py → jianying/timeline_contract.py} +34 -13
  328. package/lib/video-recap/skills/video-assemble/scripts/{jianying_writer.py → jianying/writer.py} +7 -17
  329. package/lib/video-recap/skills/video-assemble/scripts/lib.py +37 -4
  330. package/lib/video-recap/skills/video-assemble/scripts/media.py +12 -21
  331. package/lib/video-recap/skills/video-assemble/scripts/narration_audio.py +64 -34
  332. package/lib/video-recap/skills/video-assemble/scripts/packaging.py +122 -0
  333. package/lib/video-recap/skills/video-assemble/scripts/pair_media.py +216 -0
  334. package/lib/video-recap/skills/video-assemble/scripts/render_preflight.py +1 -3
  335. package/lib/video-recap/skills/video-assemble/scripts/source_score.py +469 -0
  336. package/lib/video-recap/skills/video-assemble/scripts/source_subtitles.py +25 -9
  337. package/lib/video-recap/skills/video-assemble/scripts/subtitles/__init__.py +1 -0
  338. package/lib/video-recap/skills/video-assemble/scripts/{subtitle_core.py → subtitles/core.py} +13 -6
  339. package/lib/video-recap/skills/video-assemble/scripts/{subtitle_render.py → subtitles/render.py} +5 -4
  340. package/lib/video-recap/skills/video-assemble/scripts/subtitles/track.py +324 -0
  341. package/lib/video-recap/skills/video-assemble/scripts/subtitles/track_binding.py +200 -0
  342. package/lib/video-recap/skills/video-assemble/scripts/timeline.py +30 -46
  343. package/lib/video-recap/skills/video-assemble/scripts/timeline_emit.py +91 -7
  344. package/lib/video-recap/skills/video-assemble/scripts/visual_render.py +22 -8
  345. package/lib/video-recap/skills/video-cut/SKILL.md +34 -16
  346. package/lib/video-recap/skills/video-cut/references/shot-review.md +50 -0
  347. package/lib/video-recap/skills/video-cut/scripts/cut.py +2 -28
  348. package/lib/video-recap/skills/video-cut/scripts/cut_cli.py +58 -62
  349. package/lib/video-recap/skills/video-cut/scripts/cut_contract.py +21 -106
  350. package/lib/video-recap/skills/video-cut/scripts/cut_render.py +14 -9
  351. package/lib/video-recap/skills/video-cut/scripts/lib.py +39 -0
  352. package/lib/video-recap/skills/video-cut/scripts/narration_mapping.py +2 -155
  353. package/lib/video-recap/skills/video-cut/scripts/narrative_selection.py +244 -0
  354. package/lib/video-recap/skills/video-cut/scripts/shot_review.py +357 -0
  355. package/lib/video-recap/skills/video-recap/SKILL.md +86 -42
  356. package/lib/video-recap/skills/video-recap/references/audio-routing.md +126 -0
  357. package/lib/video-recap/skills/video-recap/references/config-playbook.md +12 -8
  358. package/lib/video-recap/skills/video-recap/references/data-schema.md +44 -33
  359. package/lib/video-recap/skills/video-recap/references/resource-library.md +151 -0
  360. package/lib/video-recap/skills/video-recap/references/shift-left-qc-schema.md +1 -1
  361. package/lib/video-recap/skills/video-recap/scripts/doctor.py +123 -30
  362. package/lib/video-recap/skills/video-recap/scripts/final_qc.py +22 -75
  363. package/lib/video-recap/skills/video-recap/scripts/lib.py +3 -3
  364. package/lib/video-recap/skills/video-recap/scripts/library.py +509 -0
  365. package/lib/video-recap/skills/video-recap/scripts/materials.py +63 -91
  366. package/lib/video-recap/skills/video-recap/scripts/mimo_qc.py +8 -70
  367. package/lib/video-recap/skills/video-recap/scripts/project_binding.py +286 -0
  368. package/lib/video-recap/skills/video-recap/scripts/qc/__init__.py +1 -0
  369. package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_client.py → qc/mimo_client.py} +1 -1
  370. package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_evidence.py → qc/mimo_evidence.py} +33 -66
  371. package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_observations.py → qc/mimo_observations.py} +3 -11
  372. package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_payload.py → qc/mimo_payload.py} +4 -7
  373. package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_report.py → qc/mimo_report.py} +17 -28
  374. package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_runner.py → qc/mimo_runner.py} +2 -2
  375. package/lib/video-recap/skills/video-recap/scripts/qc_contract.py +0 -19
  376. package/lib/video-recap/skills/video-recap/scripts/recap_cli.py +119 -50
  377. package/lib/video-recap/skills/video-recap/scripts/recap_inspect.py +32 -114
  378. package/lib/video-recap/skills/video-recap/scripts/recap_review.py +9 -23
  379. package/lib/video-recap/skills/video-recap/scripts/recap_runner.py +387 -334
  380. package/lib/video-recap/skills/video-recap/scripts/recap_runtime.py +23 -23
  381. package/lib/video-recap/skills/video-recap/scripts/recap_source.py +278 -0
  382. package/lib/video-recap/skills/video-recap/scripts/recap_stage_qc.py +25 -12
  383. package/lib/video-recap/skills/video-recap/scripts/recap_timeline.py +59 -52
  384. package/lib/video-recap/skills/video-recap/scripts/resource_lock.py +162 -0
  385. package/lib/video-recap/skills/video-script/SKILL.md +16 -13
  386. package/lib/video-recap/skills/video-script/references/creative-editing-playbook.md +9 -5
  387. package/lib/video-recap/skills/video-script/references/promotional-copy.md +68 -0
  388. package/lib/video-recap/skills/video-script/references/research-guide.md +1 -1
  389. package/lib/video-recap/skills/video-script/scripts/evidence_bundle.py +24 -76
  390. package/lib/video-recap/skills/video-script/scripts/lib.py +10 -87
  391. package/lib/video-recap/skills/video-script/scripts/narration_lint.py +63 -39
  392. package/lib/video-recap/skills/video-script/scripts/review.py +0 -2
  393. package/lib/video-recap/skills/video-script/scripts/review_grounding.py +35 -59
  394. package/lib/video-recap/skills/video-script/scripts/review_response.py +66 -128
  395. package/lib/video-recap/skills/video-script/scripts/review_runner.py +12 -20
  396. package/lib/video-recap/skills/video-script/scripts/speech_ownership.py +4 -4
  397. package/lib/video-recap/skills/video-script/scripts/validate.py +53 -42
  398. package/lib/video-recap/skills/video-understanding/SKILL.md +6 -4
  399. package/lib/video-recap/skills/video-understanding/references/data-schema.md +50 -156
  400. package/lib/video-recap/skills/video-understanding/references/research-guide.md +4 -4
  401. package/lib/video-recap/skills/video-understanding/scripts/asr.py +85 -65
  402. package/lib/video-recap/skills/video-understanding/scripts/asr_timing_evidence.py +270 -0
  403. package/lib/video-recap/skills/video-understanding/scripts/brief.py +2 -5
  404. package/lib/video-recap/skills/video-understanding/scripts/briefing/__init__.py +1 -0
  405. package/lib/video-recap/skills/video-understanding/scripts/{agent_brief.py → briefing/builder.py} +38 -35
  406. package/lib/video-recap/skills/{video-script/scripts/brief_context.py → video-understanding/scripts/briefing/context.py} +4 -35
  407. package/lib/video-recap/skills/{video-script/scripts/brief_inputs.py → video-understanding/scripts/briefing/inputs.py} +9 -31
  408. package/lib/video-recap/skills/video-understanding/scripts/{brief_timeline.py → briefing/timeline.py} +5 -6
  409. package/lib/video-recap/skills/video-understanding/scripts/consolidate.py +65 -116
  410. package/lib/video-recap/skills/video-understanding/scripts/detect.py +31 -40
  411. package/lib/video-recap/skills/video-understanding/scripts/lib.py +30 -86
  412. package/lib/video-recap/skills/video-understanding/scripts/narration_lint.py +63 -39
  413. package/lib/video-recap/skills/video-understanding/scripts/speech_ownership.py +4 -4
  414. package/lib/video-recap/skills/video-understanding/scripts/storyboard.py +17 -79
  415. package/lib/video-recap/skills/video-understanding/scripts/understanding_brief.py +14 -40
  416. package/lib/video-recap/skills/video-understanding/scripts/understanding_cache.py +64 -46
  417. package/lib/video-recap/skills/video-understanding/scripts/understanding_runner.py +31 -11
  418. package/lib/video-recap/skills/video-understanding/scripts/understanding_storyboard.py +19 -14
  419. package/lib/video-recap/skills/video-understanding/scripts/vlm.py +80 -108
  420. package/lib/video-recap/skills/video-voiceover/SKILL.md +29 -19
  421. package/lib/video-recap/skills/video-voiceover/references/index-tts.md +31 -0
  422. package/lib/video-recap/skills/video-voiceover/scripts/approved_text_policy.py +123 -0
  423. package/lib/video-recap/skills/video-voiceover/scripts/dub.py +51 -59
  424. package/lib/video-recap/skills/video-voiceover/scripts/lib.py +8 -44
  425. package/lib/video-recap/skills/video-voiceover/scripts/providers/__init__.py +1 -0
  426. package/lib/video-recap/skills/video-voiceover/scripts/providers/index_tts.py +184 -0
  427. package/lib/video-recap/skills/video-voiceover/scripts/voiceover.py +212 -134
  428. package/package.json +41 -41
  429. package/lib/oh-story/skills/story-long-analyze/references/material-decomposition.md +0 -538
  430. package/lib/oh-story/skills/story-long-analyze/references/output-templates.md +0 -603
  431. package/lib/oh-story/skills/story-long-scan/references/scan-output-format.md +0 -207
  432. package/lib/oh-story/skills/story-short-analyze/references/output-templates.md +0 -561
  433. package/lib/video-recap/skills/video-assemble/scripts/jianying_schema.py +0 -98
  434. package/lib/video-recap/skills/video-recap/references/creative-editing-playbook.md +0 -225
  435. package/lib/video-recap/skills/video-recap/references/research-guide.md +0 -74
  436. package/lib/video-recap/skills/video-recap/references/timeline-and-jianying.md +0 -250
  437. package/lib/video-recap/skills/video-script/scripts/agent_brief.py +0 -399
  438. package/lib/video-recap/skills/video-script/scripts/brief_timeline.py +0 -327
  439. package/lib/video-recap/skills/video-script/scripts/narration.py +0 -12
  440. package/lib/video-recap/skills/video-understanding/scripts/brief_context.py +0 -348
  441. package/lib/video-recap/skills/video-understanding/scripts/brief_inputs.py +0 -290
  442. /package/lib/video-recap/skills/video-assemble/scripts/{jianying_tracks.py → jianying/tracks.py} +0 -0
  443. /package/lib/video-recap/skills/video-recap/scripts/{mimo_qc_contract.py → qc/mimo_contract.py} +0 -0
  444. /package/lib/video-recap/skills/video-voiceover/scripts/{fish_audio.py → providers/fish_audio.py} +0 -0
@@ -17,6 +17,7 @@ sys.path.insert(0, str(Path(__file__).resolve().parent))
17
17
  from edit_tool import ( # noqa: E402
18
18
  _unaccounted_shots,
19
19
  DEFAULT_REMOTION_CONCURRENCY,
20
+ DisplayCue,
20
21
  REMOTION_SOURCE,
21
22
  REMOTION_SOURCE_FILES,
22
23
  EditError,
@@ -102,7 +103,7 @@ def check_subtitle_geometry() -> None:
102
103
  """
103
104
 
104
105
  width, height = 768, 1344
105
- ass = _build_ass([(1.0, 2.0, "这条路我自己走")], width, height)
106
+ ass = _build_ass([DisplayCue(1.0, 2.0, "这条路我自己走")], width, height)
106
107
  require(f"PlayResX: {width}" in ass, "PlayResX 必须等于画面宽")
107
108
  require(f"PlayResY: {height}" in ass, "PlayResY 必须等于画面高")
108
109
  style = next(line for line in ass.splitlines() if line.startswith("Style:"))
@@ -113,7 +114,12 @@ def check_subtitle_geometry() -> None:
113
114
  f"字号 {font_size} 不在画面高度的 2%–6% 之间",
114
115
  )
115
116
  margin_v = float(fields[21])
116
- require(margin_v < height * 0.2, f"底边距 {margin_v} 会把字幕推离安全区")
117
+ # The baseline sits about a quarter up, above the platform's own bottom UI;
118
+ # much higher and the line lands on faces.
119
+ require(
120
+ height * 0.15 < margin_v < height * 0.3,
121
+ f"底边距 {margin_v} 不在画面高度的 15%–30% 之间",
122
+ )
117
123
  margin_h = float(fields[19])
118
124
  require(margin_h > 0, "左右边距为 0 时长句会顶到画面边缘")
119
125
  require("这条路我自己走" in ass, "台词原文必须原样进 ASS")
@@ -148,18 +154,17 @@ def check_subtitle_timing() -> None:
148
154
 
149
155
 
150
156
  def check_shot_match() -> None:
151
- """A declared correction is applied; an undeclared one never is.
157
+ """A stated correction becomes its own filter chain, within the tool's ranges.
152
158
 
153
- Generated shots drift a stop apart, so the join reads as a mistake. The
154
- correction has to be visible in the document — a tool that measured clips
155
- and adjusted them on its own would be changing pictures nobody could review.
159
+ Generated shots drift a stop apart, so the join reads as a mistake. What a
160
+ cut states in 「画面」 replaces the automatic within-scene match for that cut.
156
161
  """
157
162
 
158
163
  with tempfile.TemporaryDirectory() as scratch:
159
164
  root = Path(scratch)
160
165
  episode = build(root, CUT_LIST)
161
166
  _, cuts, _ = parse_cut_list(episode / "剪辑单.md")
162
- require(_shot_match_filter(cuts[0]) == "", "没写画面的段不得被改动")
167
+ require(_shot_match_filter(cuts[0]) == "", "没写画面的段没有自己的校正")
163
168
 
164
169
  listed = CUT_LIST.replace(
165
170
  "- 声音:保留原声\n- 字幕:无",
@@ -341,7 +346,7 @@ def check_ass_escaping() -> None:
341
346
  escaped = _ass_text(line)
342
347
  require("\\{" in escaped and "\\}" in escaped, f"花括号没有转义: {escaped}")
343
348
  require("姓名" in escaped, "转义把字弄丢了")
344
- ass = _build_ass([(1.0, 2.0, line)], 1080, 1920)
349
+ ass = _build_ass([DisplayCue(1.0, 2.0, line)], 1080, 1920)
345
350
  dialogue = [row for row in ass.splitlines() if row.startswith("Dialogue")][0]
346
351
  require(dialogue.endswith(escaped), f"Dialogue 行没有用转义后的正文: {dialogue}")
347
352
  require(
@@ -362,7 +367,7 @@ def check_remotion_sources_all_shipped() -> None:
362
367
  path.relative_to(REMOTION_SOURCE).as_posix()
363
368
  for path in REMOTION_SOURCE.rglob("*")
364
369
  if path.is_file()
365
- and path.suffix in {".ts", ".tsx", ".json"}
370
+ and path.suffix in {".ts", ".tsx", ".mjs", ".json"}
366
371
  and "node_modules" not in path.parts
367
372
  }
368
373
  listed = set(REMOTION_SOURCE_FILES)
@@ -439,6 +444,40 @@ def check_missing_shots_are_reported() -> None:
439
444
  require(not _unaccounted_shots(known, [Stub(m) for m in known], []), "全采用时不该报")
440
445
 
441
446
 
447
+ def check_screen_text_and_effects() -> None:
448
+ """Screen text is traced to [画面文字] lines; effects are held to their cut."""
449
+
450
+ with tempfile.TemporaryDirectory() as scratch:
451
+ root = Path(scratch)
452
+ episode = build(root, CUT_LIST)
453
+ (episode / "剧本.md").write_text(
454
+ SCREENPLAY + "\n[画面文字] 剩余 4 天 23:59:58\n", encoding="utf-8"
455
+ )
456
+ (episode / "media" / "chime.wav").write_bytes(b"")
457
+ anchor = "- 字幕:这条路我自己走"
458
+ require(anchor in CUT_LIST, "夹具里应当有一条台词字幕")
459
+ lines = (
460
+ "- 画面文字 1:0.00-1.00 任务面板 剩余(倒计时:431998)\n"
461
+ "- 画面文字 2:1.00-2.00 角标 剩余(倒计时:接续)\n"
462
+ "- 音效:0.00-0.50 media/chime.wav(增益:-10)"
463
+ )
464
+ (episode / "剪辑单.md").write_text(
465
+ CUT_LIST.replace(anchor, anchor + "\n" + lines), encoding="utf-8"
466
+ )
467
+ _, cuts, _ = parse_cut_list(episode / "剪辑单.md")
468
+ require(len(cuts[1].screen_texts) == 2, "两条画面文字应全部解析")
469
+ require(len(cuts[1].sound_effects) == 1, "音效应当解析")
470
+ require(not check_cuts(episode, cuts, root, probe=False), "合法的画面文字与音效不该报错")
471
+
472
+ (episode / "剪辑单.md").write_text(
473
+ CUT_LIST.replace(anchor, anchor + "\n- 画面文字:0.00-1.00 卡片 剩余 5 天"),
474
+ encoding="utf-8",
475
+ )
476
+ _, cuts, _ = parse_cut_list(episode / "剪辑单.md")
477
+ findings = check_cuts(episode, cuts, root, probe=False)
478
+ require(any("[画面文字]" in item for item in findings), f"编造的画面文字没抓到: {findings}")
479
+
480
+
442
481
  def main() -> int:
443
482
  with tempfile.TemporaryDirectory() as scratch:
444
483
  root = Path(scratch)
@@ -507,6 +546,7 @@ def main() -> int:
507
546
  check_shot_match()
508
547
  check_ass_escaping()
509
548
  check_multi_subtitle()
549
+ check_screen_text_and_effects()
510
550
  check_stale_window()
511
551
  check_missing_shots_are_reported()
512
552
  check_grain_is_a_delivery_wide_decision()
@@ -170,7 +170,7 @@ python3 {技能目录}/scripts/novel_index.py coverage \
170
170
 
171
171
  - `story-units.md`:把情节点归成有始有终的单元,每个单元记录进入状态、冲突、代价与出去状态;
172
172
  - `rhythm-and-emotion.md`:关键信息如何逐章推进、情绪触动点的铺垫→释放→余波、
173
- 跨章伏笔与兑现。
173
+ 跨章伏笔与兑现,以及按观众收益排名的爽点表。
174
174
 
175
175
  聚合完成后跑同一文件里的三条阈值自检(归属置信、覆盖率、重叠率)与散落情节兜底。
176
176
  阈值不是评分,是**边界模糊的信号**:重叠率过高说明两个单元其实是一个。
@@ -192,8 +192,8 @@ python3 {技能目录}/scripts/novel_index.py coverage \
192
192
 
193
193
  - `adaptation-value.md`:哪些单元在竖屏短剧里能直接成立、哪些要换载体、哪些是纯文字快感
194
194
  (内心戏、叙述性诡计、长铺垫)在画面上无法兑现;制作负担落在哪里。
195
- - `episode-candidates.jsonl`:按**局部戏剧结果与精确交接**切出的候选集,不按章号或字数
196
- 平均切。每条带来源 span、承担的功能、以及未决项。
195
+ - `episode-candidates.jsonl`:按**爽点分布、局部戏剧结果与精确交接**切出的候选集,不按章号
196
+ 或字数平均切。每条带来源 span、承担的功能、承接的爽点以及未决项。
197
197
 
198
198
  同时**回填快评**:S1 的哪几条判断被全量结果推翻了,写进 `adaptation-value.md` 的开头。
199
199
  一个抽样结论被证伪,比它被悄悄忘掉有用得多——下一本书的快评会因此更准。
@@ -1,3 +1,3 @@
1
1
  {"record_type":"sources","schema_version":"1.0.0","sources":{"index":{"owner":"short-drama-novel-analyze","artifact":"项目开发/source-analysis/_index.json"},"original-source":{"owner":"creator","artifact":"输入/original-source.txt"}}}
2
- {"example_only":true,"destination":"项目开发/source-analysis/episode-candidates.jsonl","schema_version":"1.0.0-draft","record_type":"episode_candidate","candidate_id":"NVA-EPC-EXAMPLE-001","status":"candidate","source_ref":{"src":"original-source"},"index_ref":{"src":"index"},"story_units":["UNIT-EXAMPLE-03"],"chapter_range":{"sequence_start":14,"sequence_end":19},"screen_judgement":"needs_carrier","trope_tags":["信息差","反转打脸"],"entering_knowledge":"观众已知两人共用一份旧证据,但不知道其中一人已经改过它","promise_paid":"改动被第三方当场指出,怀疑从猜测变成具体指控","exit_pressure":"被指控者必须在下一次公开场合前决定认或不认","inherited_facts":["改动过的证据仍在对方手里","两人的合作关系尚未破裂"],"preserved_functions":["关系压力","信息不对称"],"carrier_change":{"original_carrier":"长段内心权衡","new_carrier":"第三方当众比对两份文件的可见动作","lost_or_changed":["读者原本先于角色知道改动,改编后观众与角色同时知道"]},"production_load":{"distinct_locations":2,"characters_in_frame":3,"readable_text_required":true,"notes":"证据文件的可读文字需与美术确认"},"unresolved":["第三方的立场在原文中前后不一致,待创作者裁定"],"creator_acceptance":{"status":"pending","decision_ref":null}}
3
- {"example_only":true,"destination":"项目开发/source-analysis/episode-candidates.jsonl","schema_version":"1.0.0-draft","record_type":"episode_candidate","candidate_id":"NVA-EPC-EXAMPLE-002","status":"candidate","source_ref":{"src":"original-source"},"index_ref":{"src":"index"},"story_units":["UNIT-EXAMPLE-04"],"chapter_range":{"sequence_start":20,"sequence_end":22},"screen_judgement":"screen_ready","trope_tags":["打脸"],"entering_knowledge":"观众已知指控成立,不知道被指控者手里还有一份未公开的记录","promise_paid":"记录被主动交出,代价是失去唯一的退路","exit_pressure":"退路没了,对手却仍未出手","inherited_facts":["记录已进入公开视野"],"preserved_functions":["代价","权力转移"],"carrier_change":null,"production_load":{"distinct_locations":1,"characters_in_frame":2,"readable_text_required":false,"notes":null},"unresolved":[],"creator_acceptance":{"status":"pending","decision_ref":null}}
2
+ {"example_only":true,"destination":"项目开发/source-analysis/episode-candidates.jsonl","schema_version":"1.0.0-draft","record_type":"episode_candidate","candidate_id":"NVA-EPC-EXAMPLE-001","status":"candidate","source_ref":{"src":"original-source"},"index_ref":{"src":"index"},"story_units":["UNIT-EXAMPLE-03"],"chapter_range":{"sequence_start":14,"sequence_end":19},"screen_judgement":"needs_carrier","trope_tags":["信息差","反转打脸"],"payoffs":["PAY-EXAMPLE-07"],"entering_knowledge":"观众已知两人共用一份旧证据,但不知道其中一人已经改过它","promise_paid":"改动被第三方当场指出,怀疑从猜测变成具体指控","exit_pressure":"被指控者必须在下一次公开场合前决定认或不认","inherited_facts":["改动过的证据仍在对方手里","两人的合作关系尚未破裂"],"preserved_functions":["关系压力","信息不对称"],"carrier_change":{"original_carrier":"长段内心权衡","new_carrier":"第三方当众比对两份文件的可见动作","lost_or_changed":["读者原本先于角色知道改动,改编后观众与角色同时知道"]},"production_load":{"distinct_locations":2,"characters_in_frame":3,"readable_text_required":true,"notes":"证据文件的可读文字需与美术确认"},"unresolved":["第三方的立场在原文中前后不一致,待创作者裁定"],"creator_acceptance":{"status":"pending","decision_ref":null}}
3
+ {"example_only":true,"destination":"项目开发/source-analysis/episode-candidates.jsonl","schema_version":"1.0.0-draft","record_type":"episode_candidate","candidate_id":"NVA-EPC-EXAMPLE-002","status":"candidate","source_ref":{"src":"original-source"},"index_ref":{"src":"index"},"story_units":["UNIT-EXAMPLE-04"],"chapter_range":{"sequence_start":20,"sequence_end":22},"screen_judgement":"screen_ready","trope_tags":["打脸"],"payoffs":["PAY-EXAMPLE-02"],"entering_knowledge":"观众已知指控成立,不知道被指控者手里还有一份未公开的记录","promise_paid":"记录被主动交出,代价是失去唯一的退路","exit_pressure":"退路没了,对手却仍未出手","inherited_facts":["记录已进入公开视野"],"preserved_functions":["代价","权力转移"],"carrier_change":null,"production_load":{"distinct_locations":1,"characters_in_frame":2,"readable_text_required":false,"notes":null},"unresolved":[],"creator_acceptance":{"status":"pending","decision_ref":null}}
@@ -83,14 +83,18 @@ python3 {技能目录}/scripts/novel_index.py sample \
83
83
 
84
84
  回答一个问题:**如果这本书改成短剧,第 1 集从哪里开始**?
85
85
 
86
- 找**第一个可见的、有代价的、当场发生的转折**——主角第一次做出会付出代价的选择,
87
- 且这个选择能被拍出来而不是被想出来。它通常不在第一章。写清三条:
86
+ 找**观众在此处收益最强、且能同时交代主角身份、眼前危机与目标的一处**:打脸、奇观、
87
+ 反转、身份揭露、奖励兑现或危机爆发,能被拍出来而不是被想出来。兑现它的可以是旁观者——
88
+ 群体改口、对手当众吃瘪,收益照样落在观众身上。它通常不在第一章,也常常不是时间上最早的那个
89
+ 爽点:后文的高潮可以提前做冷开。写清四条:
88
90
 
89
- - 落在第几章(用索引的 `sequence`);
91
+ - 落在第几章(用索引的 `sequence`),收益类型是什么;
92
+ - 抽样里若另有更晚、更强的高光,一并写出,它是冷开候选;
90
93
  - 它之前的内容里,哪些是观众必须知道的,可以怎样在开场后补进去;
91
94
  - 哪些是原著读者需要、短剧观众不需要的。
92
95
 
93
- 抽样里没有这样的转折时,写「抽样内未见可用的开篇替换点」,并列进第 5 段的风险。
96
+ 抽样里没有这样的一处时,写「抽样内未见可用的开篇替换点」,并列进第 5 段的风险。
97
+ 全量拆解后,S3 的爽点表会给出完整排名,S5 回填时拿它对照这里的判断。
94
98
 
95
99
  ## 结论限于抽样范围
96
100
 
@@ -76,7 +76,13 @@
76
76
 
77
77
  ## 分集候选
78
78
 
79
- 按**局部戏剧结果与精确交接**切,不按章号、字数或平均分配。一个候选集必须能回答:
79
+ 按**爽点分布、局部戏剧结果与精确交接**切,不按章号、字数或平均分配。先读
80
+ [爽点表](aggregation-and-entities.md#爽点表):候选集的边界跟着爽点走,没有爽点的长间隔
81
+ 并进相邻候选或标为可删,而不是单独成集;排名靠前、落在后文的高光写进交接摘要,
82
+ 由 `$short-drama-develop` 决定是否提前或做冷开。章与集不是 1:1——一章撑不起一集时合并,
83
+ 一章里有两个大爽点时可以拆。
84
+
85
+ 一个候选集必须能回答:
80
86
 
81
87
  1. 进入时观众已经知道什么;
82
88
  2. 本集内兑现了哪一部分承诺(不能一条都不兑现);
@@ -87,7 +93,8 @@
87
93
 
88
94
  每条候选写进 `episode-candidates.jsonl`,字段见
89
95
  [分集候选样例](../assets/episode-candidate.example.jsonl)。每条都带:来源单元与章号区间、
90
- 承担的功能、判定类别、桥段标签、未决项、以及 `creator_acceptance: pending`。
96
+ 承担的功能、判定类别、桥段标签、承接的爽点(`payoffs`,没有就写空并说明这一集靠什么留人)、
97
+ 未决项、以及 `creator_acceptance: pending`。
91
98
 
92
99
  **集数不由本技能决定**。 候选可以多于、也可以少于创作者设定的集数;差多少要明说,
93
100
  由创作者与 `$short-drama-develop` 决定合并还是拆分。
@@ -120,5 +127,5 @@
120
127
  - 没有把本技能的判定写成结论——它们是候选,等创作者接受。
121
128
 
122
129
  交接摘要给创作者读,说清:拆了多少章、跳过哪些、多少单元分别落进三类、
123
- 切出多少候选集、最大的三处改编风险、快评里被推翻的判断。风险要具体到单元,
130
+ 切出多少候选集、排名前列的爽点落在哪几个候选、最大的三处改编风险、快评里被推翻的判断。风险要具体到单元,
124
131
  不写「改编难度较大」。
@@ -99,16 +99,40 @@
99
99
 
100
100
  ## 节奏与情绪
101
101
 
102
- `rhythm-and-emotion.md` 写三件事,全部要能回指到章或情节点:
102
+ `rhythm-and-emotion.md` 写四件事,全部要能回指到章或情节点:
103
103
 
104
104
  - **关键信息推进**:某条信息何时进入读者视野 → 如何被延迟、误导或验证 → 何时爆发 →
105
105
  余波与新钩子。
106
106
  - **情绪触动点索引**:每个触动点落在哪一章、由哪条情节点承担。
107
107
  - **长间隔说明**:连续 3 章以上没有触动点时,写清作者用什么维持期待。
108
108
  改编时这些长间隔就是要合并或砍掉的段落——短剧没有这个耐心。
109
+ - **爽点表**:见下一节。
109
110
 
110
111
  回指不到章或情节点的条目删掉,不要保留无源断言。
111
112
 
113
+ ### 爽点表
114
+
115
+ 选段和切候选集之前,先按**观众收益**给全书情节点排名。原著的叙述顺序是给读者的,
116
+ 短剧观众为爽点付费;不先排名,候选集就会按时序一章一章往下切,全书最强的高光可能落到
117
+ 好几集之后。
118
+
119
+ 每行一个爽点,按收益强度从高到低排:
120
+
121
+ | 列 | 写什么 |
122
+ |---|---|
123
+ | `PAY-<N>` | 稳定编号,供候选集引用 |
124
+ | 位置 | 章(`sequence`)与情节点 |
125
+ | 类型 | 打脸、奇观、反转、身份揭露、奖励兑现、危机,可多选 |
126
+ | 谁兑现 | 主角、对手、旁观者或群体;**旁观者完成的打脸同样算**——群里改口、围观者集体道歉、老前辈当众表态,收益都落在观众身上 |
127
+ | 收益落在谁身上 | 被打脸的是谁、他之前压迫得多具体;压迫越具体,落差越大 |
128
+ | 首集能力 | 这一处能否同时交代主角的身份、眼前的危机与目标;能的标出来,它是开篇替换点的候选 |
129
+ | 依赖 | 观众要先知道什么才看得懂;可以怎样在开场后补 |
130
+
131
+ 强度按本书内部相对排,不跨书比较,也不给分数。原著里一段喜剧反应、一张奖励清单
132
+ 也可能是爽点,照实列,不要因为它「只是反应」就漏掉。
133
+
134
+ **`craft_default · NVA-13`**:切候选集之前先排爽点表,旁观者兑现的爽点同样入表;候选集引用它承接的 `PAY-<N>`。
135
+
112
136
  ## 人物归并
113
137
 
114
138
  跨章去重时,**一人一实体**:无法确定两个称谓是否指同一人,就分开建两条,不合并。
@@ -61,6 +61,7 @@
61
61
  | NVA-10 | reviewed_invariant | Episode candidates are cut on local dramatic result and precise handoff, not on chapter count or word budget. |
62
62
  | NVA-11 | craft_default | Triage a deterministic spread of chapters across the whole book and stop for the creator before committing to a full pass. |
63
63
  | NVA-12 | taste_option | Where to open, which line to keep and which ending to promise remain creator choices; analysis may argue but never blocks. |
64
+ | NVA-13 | craft_default | Before cutting episode candidates, rank the book's plot points by audience payoff — face-slap, spectacle, reversal, identity reveal, reward delivered, crisis — counting payoffs a bystander or crowd delivers; candidates follow the payoff distribution rather than one chapter per episode and cite the payoffs they carry. The opening replacement point is the strongest payoff that can also establish the protagonist's identity, crisis and goal, and a stronger later peak is reported as a cold-open option. |
64
65
 
65
66
  规则分级由高到低:`structural_invariant`(结构缺陷,阻断)、
66
67
  `reviewed_invariant`(需证据判断)、`craft_default`(常用做法,可覆盖)、
@@ -49,8 +49,8 @@ license: MIT
49
49
  只读对应资料,不预加载整个项目:
50
50
 
51
51
  - 原著分析:[原著分析审查表](references/rubric-source-analysis.md)
52
- - 故事、场景、行动与对白:[故事剧本审查表](references/rubric-story-script.md)
53
- - 身份、变体、连续性与图片提示词:[资产提示词审查表](references/rubric-assets-prompts.md)
52
+ - 故事、场景、行动与对白,改编是否守住原著人物与主线,已接受节奏档案的核对,开场、结尾与中段的局部检查:[故事剧本审查表](references/rubric-story-script.md)
53
+ - 身份、变体、连续性、时代与图片提示词:[资产提示词审查表](references/rubric-assets-prompts.md)
54
54
  - 原文落实、镜头、关键帧与视频运动:[视觉运动审查表](references/rubric-visual-motion.md)
55
55
  - 完整审查方法:[审查方法](references/review-method.md)
56
56
  - 制作端常见缺陷:[生产质量门](references/production-quality-gates.md)
@@ -71,7 +71,12 @@ Resolve upstream meaning first; do not polish prompt wording when the shot or as
71
71
  ## Revision and re-review
72
72
 
73
73
  Group duplicate findings and route them to the owning skill. A revision request states the target outcome, preserve
74
- set and review scope to rerun. On a later explicit re-review request, read the current version, confirm the finding is addressed, check the
74
+ set and review scope to rerun.
75
+
76
+ `REV-14`: a revision request is a patch, not a rewrite. It names the smallest change at a cited location; local
77
+ findings never add up to a request to rewrite the episode. When the review compares a revision with the version before
78
+ it, any strong hook, payoff line, or comic beat that polishing removed is listed under `## 被删的强钩子` with its prior
79
+ location and a short quote, so the owner can restore it. The reviewer lists it; the owner decides. On a later explicit re-review request, read the current version, confirm the finding is addressed, check the
75
80
  preserve set and close or retain each affected finding. A different reviewer is useful but not mechanically required.
76
81
 
77
82
  ## Anti-template review
@@ -72,6 +72,17 @@ validity.
72
72
 
73
73
  Fail when a prop teleports, changes scale/material, or readable evidence is erased.
74
74
 
75
+ ## Era
76
+
77
+ The era comes from source facts: devices, platforms, slang, stated years. Fail
78
+ when the era shown in `视觉设定.md`, `图片提示词.md` or `视频提示词.md` contradicts
79
+ them, or when a retro or aged descriptor (旧/老式/复古/褪色/斑驳, old, worn, dusty,
80
+ period, CRT) has neither a source basis nor an explicit creator choice (`AST-14`).
81
+ This is the visual layer of the source-fidelity check (`STY-07`): cite the source
82
+ fact and the conflicting line. A visual direction with
83
+ no era anchors, or entries that leave the era-specific form unstated, is a craft
84
+ note (`AST-15`).
85
+
75
86
  ## Prompt recipe review
76
87
 
77
88
  All prompt types need purpose, exact binding, identifying facts, current variant,
@@ -5,9 +5,12 @@
5
5
  - [Promise](#story-promise-and-engine)
6
6
  - [Episode](#episode-shape)
7
7
  - [Entry and serial memory](#entry-character-and-serial-memory)
8
+ - [Adaptation fidelity](#adaptation-fidelity)
8
9
  - [Scene](#scene-test)
9
10
  - [Action](#action-and-production-meaning)
10
11
  - [Dialogue](#dialogue)
12
+ - [Rhythm profile](#rhythm-profile-rev-12)
13
+ - [Local passes](#local-passes-rev-13)
11
14
  - [Findings](#common-findings)
12
15
 
13
16
  ## Story promise and engine
@@ -55,8 +58,9 @@
55
58
  A capacity estimate (`STY-16`) is informational, never a blocking finding. If a
56
59
  planned episode's shot/duration magnitude is far from the project's own accepted
57
60
  ratios, note it as an advisory observation with the sampled basis, and leave the
58
- resolution to the creator. Never derive a word, line, or shot quota from it, and
59
- never compare against another project's numbers.
61
+ resolution to the creator. Do not derive a word, line, or shot quota from it. The only
62
+ numbers a review checks are the ones in an accepted rhythm profile
63
+ ([below](#rhythm-profile-rev-12)), and never another project's numbers.
60
64
 
61
65
  When the premise grants foreknowledge or externally authorized ability (`STY-17`), keep
62
66
  two layers apart and cite each from its own place:
@@ -117,7 +121,28 @@ What is reportable:
117
121
  A breathing scene should process a consequence rather than suspend the story.
118
122
 
119
123
  Do not require a fixed hook type, beat count, reversal, climax timestamp, or
120
- dialogue quota.
124
+ dialogue quota beyond what an accepted rhythm profile declares.
125
+
126
+ ## Adaptation fidelity
127
+
128
+ Active only when the project adapts a source. Read the source span each mapping in
129
+ `项目开发/adaptation-map.jsonl` cites, then the episode record and screenplay.
130
+
131
+ - For each core source character: is their stance toward the protagonist, their way of
132
+ acting, and their relationships the same on screen as in the source (`STY-07`)?
133
+ Pressure made louder or spoken aloud is fine; a supportive figure turned oppressor,
134
+ or a relationship reversed, is a finding unless the creator accepted the change.
135
+ Cite the source fact and the conflicting screenplay line (`REV-03`).
136
+ - Does the main line still run the source's way, and does any invented detail
137
+ contradict a source fact?
138
+ - Is every character, scene, or opponent the source lacks registered as its own `add`
139
+ mapping, with the function it serves, why existing source material cannot carry it,
140
+ the source facts checked against it, and a line in the brief for the creator (`STY-30`)?
141
+ An addition hidden inside `change_carrier`, `merge`, or `move_earlier` notes is a
142
+ `craft_default` finding; an unregistered addition that also contradicts the source
143
+ is a `STY-07` finding.
144
+ - When an episode's opponent was manufactured to meet `opposed_reversals_per_episode_min`,
145
+ say so: the profile deviation is the honest outcome, not a new antagonist.
121
146
 
122
147
  ## Scene test
123
148
 
@@ -197,6 +222,54 @@ them fit this checklist. A loud scene can fail when nothing changes.
197
222
  Silence, interruption, slang, narration, and sentence length are creator options,
198
223
  not universal scoring ratios.
199
224
 
225
+ ## Rhythm profile (`REV-12`)
226
+
227
+ Active only when `short-drama.json#/creator_authority/rhythm_profile` has `status`
228
+ `accepted`. A missing, `unset`, or `proposed` profile means nothing here is checked.
229
+ The review does arithmetic on the accepted values against the current screenplay and
230
+ nothing else:
231
+
232
+ | Field | What the reviewer measures |
233
+ |---|---|
234
+ | `first_hook_seconds` | Seconds from the episode start to the first hook: crisis, conflict, anomaly, or promised spectacle already happening on screen. |
235
+ | `beat_interval_seconds_max` | The longest gap between consecutive emotional touchpoints: a conflict line, a situation-changing action, or new information. |
236
+ | `opposed_reversals_per_episode_min` | Reversals driven or suffered by a human opponent with an agenda; changes completed by a system, a number, or the environment alone do not count. |
237
+ | `end_on_peak` | Whether the last beat sits on or just before the peak, with no afterglow, summary, or quiet coda after it. |
238
+ | `reprise_previous_last_beat` | Whether the opening replays the previous episode's last beat. Not applicable to the first episode. |
239
+ | `vo_share_max` | `[VO]` spoken characters as a share of all spoken characters; `$short-drama-write`'s duration estimate reports it when run with the project file. |
240
+ | `first_major_payoff_by_episode` | Series review only: the episode in which the first major payoff lands. |
241
+
242
+ Seconds come from the project's declared pacing, or from a real-time read-through
243
+ labelled as a text estimate; state which. A deviation is a `craft_default` finding that
244
+ cites the field, the accepted value, the measured value, and the location. Severity
245
+ follows audience impact and is never `blocker`; the creator may keep the episode with a
246
+ stated reason. Storyboard fields (`target_avg_shot_seconds`, `close_shot_share_min`)
247
+ are measured in the [visual rubric](rubric-visual-motion.md#rhythm-profile-shots).
248
+
249
+ ## Local passes (`REV-13`)
250
+
251
+ After the whole-episode read, run three passes that each read one part only. A whole
252
+ read lets a strong middle excuse a flat opening; a part read cannot.
253
+
254
+ 1. **Opening hook**: read only the first segment, up to `first_hook_seconds` or, with
255
+ no accepted profile, the first scene. Would a viewer who saw only this stay? Name
256
+ the hook and say whether it is happening or only being set up. Then read the first
257
+ beat alone, the opening frame: does it raise a question by itself,
258
+ or does it need on-screen text read, a character recognized, or the next line heard
259
+ first (`SCR-22`)? A still image that poses its own question passes. For a first
260
+ episode, also check that the brief compared the entry candidates on that same image
261
+ (`STY-25`).
262
+ 2. **Ending suspense**: read only the last segment, the final scene's closing beats.
263
+ What question is left open? Does it grow out of this episode's result? Is it a line
264
+ hook (an unfinished question, an identity hint) or an image hook (a door half open,
265
+ an envelope half torn)? Does it stop before the answer?
266
+ 3. **Mid-episode reversal density**: read only the middle. List each reversal with its
267
+ location and the person driving or suffering it; flag long stretches with no
268
+ touchpoint and reversals bunched at the end.
269
+
270
+ Each finding cites its own segment. The passes apply with or without a profile; only
271
+ the numeric comparisons need one.
272
+
200
273
  ## Replaceable realization (`SCR-10`)
201
274
 
202
275
  Only for beats the creator marked. **An unmarked beat leaves this section
@@ -230,6 +303,7 @@ the benefit is not, and the mark exists precisely so the strong version can stay
230
303
  - cliffhanger withholds all payoff;
231
304
  - episode pauses an unfinished action without producing a local result (`STY-13`);
232
305
  - first episode dumps the backstory reservoir instead of selecting an active entry;
306
+ - an adaptation hardens a source character or invents an opponent without an `add` mapping or creator acceptance;
233
307
  - a declared character arc has no pressure test, choice, cost, or changed strategy;
234
308
  - serial summary omits an information permission or unpaid setup obligation;
235
309
  - generic emotion adjectives replace visible performance;
@@ -7,6 +7,7 @@
7
7
  - [Keyframe](#frozen-keyframe)
8
8
  - [Motion](#motion)
9
9
  - [Continuity](#cross-shot-continuity)
10
+ - [Rhythm profile](#rhythm-profile-shots)
10
11
  - [Findings](#common-findings)
11
12
  - [Production risks and authorized observations](#production-risk-and-authorized-observation-checklist-rev-08)
12
13
 
@@ -31,6 +32,11 @@
31
32
  - Why is this a new shot?
32
33
  - Do framing and camera behavior serve attention, alignment, pressure, reveal, or
33
34
  rhythm rather than decorate the prose?
35
+ - Does each shot's `运镜` line state a behavior and a reason chosen from the shot's
36
+ purpose (`SHT-04`)? A stated lock-off with its reason passes. An episode locked on
37
+ nearly every shot while its peak gets no movement is a finding; so is a missing line,
38
+ which leaves the choice to the video-prompt stage; a bare 「运镜:固定」 with no reason
39
+ is also a finding.
34
40
  - Are Location/View, axis, screen direction, eyelines, entrances, positions,
35
41
  hands, and props coherent?
36
42
  - Are exact asset variants bound?
@@ -39,6 +45,15 @@
39
45
  - Do crop, occlusion, focus, back view, and offscreen space serve that information
40
46
  permission rather than accidentally reveal or conceal it?
41
47
 
48
+ ## Rhythm profile: shots
49
+
50
+ Under the `REV-12` conditions in the [story rubric](rubric-story-script.md#rhythm-profile-rev-12),
51
+ measure two storyboard fields: the average shot length per scene (scene duration divided
52
+ by its shot count) against `target_avg_shot_seconds`, and the share of close-range shots
53
+ across the episode, as the profile field defines them, against `close_shot_share_min`. The average is a
54
+ scene-level target; one long or short shot is not a finding. Also report durations folded
55
+ from screenplay word counts instead of the scene's sound timeline (`SHT-28`).
56
+
42
57
  ## Frozen keyframe
43
58
 
44
59
  - Can all described facts exist in one still instant?
@@ -22,6 +22,9 @@
22
22
  | REV-09 | reviewed_invariant | After prompt revision or repackaging, recheck source coverage and every applicable accepted directive; correct asset bindings alone do not prove compliance. |
23
23
  | REV-10 | reviewed_invariant | A project-calibration finding distinguishes input-reference from generated-result observation, binds the exact project, the prompt/spec records it observed, stable reference slots, production configuration, method and limits, and—when its disposition calls for a change (see REV-11)—proposes the smallest owner-routed one with a preserve set; it does not generalize across projects or infer quality from task state. |
24
24
  | REV-11 | reviewed_invariant | A calibration finding carries `disposition` (keep, post_production, targeted_edit, resubmit, rewrite) and `disposition_rationale` before any revision text, justified by whether the defect is text-controllable and whether it has already recurred. Dispositions that call for no change leave `required_change` empty rather than inventing one. Resubmitting identical text and appending quality adjectives are not repairs; a recurring defect routes to a structural change instead. Findings outside project calibration use `not_applicable`. |
25
+ | REV-12 | craft_default | When the project's rhythm profile has status `accepted`, review checks the episode against it by arithmetic on the accepted values only and reports a deviation as a non-blocking finding citing field, accepted value, measured value, and location; the creator may keep the episode with a stated reason. A missing or proposed profile leaves the check inactive, and no finding compares against another project's or a suite-wide number. |
26
+ | REV-13 | craft_default | Beyond the whole-episode read, three local passes each read one part only: an opening-hook pass on the first segment, which also reads the first beat alone as the opening frame, an ending-suspense pass on the last segment, and a reversal-density pass on the middle. |
27
+ | REV-14 | craft_default | A revision request is a patch at a cited location with a preserve set, never a whole-episode rewrite; a strong hook, payoff line, or comic beat removed by polishing is logged with its prior location and quote so the owner can restore it. |
25
28
 
26
29
  规则分级由高到低:`structural_invariant`(结构缺陷,阻断)、
27
30
  `reviewed_invariant`(需证据判断)、`craft_default`(常用做法,可覆盖)、
@@ -26,6 +26,9 @@ license: MIT
26
26
  分配镜头时长前读取
27
27
  `short-drama.json#/creator_authority/production_profile/choices/native_duration_seconds`。已声明目标模型但
28
28
  没有原生时长时先补这一个选择;目标模型也未声明时照常按叙事节奏设计,不猜供应商限制。
29
+ 同时读取 `short-drama.json#/creator_authority/rhythm_profile`:`status` 为 `accepted` 时,镜长按
30
+ [镜长从哪来](references/shot-craft.md#镜长从哪来-sht-28) 由声音事件与 `target_avg_shot_seconds` 推出,
31
+ 全集近景类镜头占比不低于 `close_shot_share_min`;档案缺失或未接受时不核对这些数值。
29
32
 
30
33
  冻结关键帧写完之前,谁会出现在这一格画面里还没有定下来。所以三条依据都在关键帧之后回填,
31
34
  读的是成稿画面,不是镜头意图。
@@ -48,10 +51,12 @@ license: MIT
48
51
  2. 确定观众何时知道什么、对齐谁、空间如何揭示、转折落在哪个可见动作。
49
52
  剧本或 Brief 用“前半段 / 后半段 / 前三分之一 / 最后 N 秒”等相对时间限定首次出现、释放或禁止时,
50
53
  先用已接受集长换成明确时间边界再分镜;例如 60 秒作品的“后半段首次出现”不得早于 30 秒。
51
- 3. 每镜写清唯一职责、来源、时长、景别/机位、起点、唯一主要动作、终点和声音;用
54
+ 3. 每镜写清唯一职责、来源、时长、景别/机位、运镜、起点、唯一主要动作、终点和声音;用
52
55
  `起点 → 唯一动作 → 终点` 直接说明人物、双手与持物怎样完成本镜状态转换。三条依据留到第 6 步。
56
+ 「运镜」按本镜目的逐镜选,写行为和理由,固定也写理由,见 [运镜逐镜选](references/shot-craft.md#运镜逐镜选-sht-04)。
53
57
  有对白、VO 或 OS 时,先按原文和人物说话方式估算完整发声时间,再安排不能重叠的动作、停顿与
54
58
  末尾反应;把估时依据简写在本镜「声音」里。具体做法见 [对白估时](references/shot-craft.md#对白估时)。
59
+ 对白场先按 [对白覆盖默认](references/shot-craft.md#对白场怎么切-sht-29) 放切点;镜长不按剧本字数折算。
55
60
  4. 锁定人物朝向、位置、视线、持物、出入口、屏幕方向和必要状态;上游已有会限制动作空间的持续关系时,把关系投影进本镜起点与终点。
56
61
  5. 冻结关键帧只投影镜头起点;删除终点才出现的文字、动作、姿态或道具状态。
57
62
  镜头的职责落在收尾那一下时,另写 `### 收尾关键帧提示词` 投影**终点**——同一格画面的
@@ -82,14 +87,17 @@ license: MIT
82
87
  - 剧本里的每个场景都要有镜头承载。确实决定不拍某一场时,在《分镜.md》正文开头写一行
83
88
  `- 未拍场次:<场景 ID>(理由:……)`,多项用 `;` 连接。SHT-01 一直允许带理由的省略,
84
89
  但省略和漏拍在成稿文档里长得一模一样,所以理由要写下来,而不是留在对话里。
85
- - 已声明原生时长时,每个一镜一生成的镜头都落在其最短与最长秒数内。短于下限的叙事动作在合法
86
- 镜长内完成后保持终点;长于上限的动作按可见状态闭合点拆镜,拆出的每镜仍各有唯一职责与可信交界。
90
+ - 已声明原生时长时,每镜照常有自己的唯一职责、起止边界和冻结关键帧,镜长先按叙事需要定。短于最短秒数
91
+ 的镜头,向创作者提议把同场相邻的几镜装进一个多镜容器,在交付档案里声明;目标方言要求时,容器的每一切
92
+ 都要有已接受的关键帧图片,能否装、怎么装由 `$short-drama-video-prompts` 的方言决定。创作者没有声明
93
+ 多镜容器、或方言不支持时,镜头落在最短秒数内,动作完成后保持终点。长于上限的动作按可见状态闭合点拆镜,
94
+ 拆出的每镜仍各有唯一职责与可信交界。
87
95
  - 「唯一动作」写从本镜起点到终点的那条可见状态链;涉及交接、换手、放置或取回时,把接触者、
88
96
  接触方式和物件落点写在同一链里,不能让合法终点之间靠镜外瞬移衔接。
89
97
  - 切镜必须带来信息、权力、情绪、空间或节奏变化;同义重复镜头删掉。
90
98
  - 相对时间词约束的是事件首次可见或可听的时刻,不因前置动作已经完成就提前释放;分镜时间轴直接
91
99
  写出该边界,不把“稍后”“交接后”等叙事顺序当成数值时间的替代。
92
- - 同一动作不跨镜重复发生;终点应能成为下一镜可信起点。
100
+ - 同一动作不跨镜重复发生,峰值处声明过的[冲击重复](references/shot-craft.md#动作落实表)除外;终点应能成为下一镜可信起点。
93
101
  - 关键信息的可读性优先于装饰性运镜,竖屏构图优先保证主体和反应可见。
94
102
  - 复杂群戏先锁空间锚点和屏幕方向,再决定景别变化。
95
103
  - 起终边界除了逐人姿态,还要写清本镜依赖的身体—物件—空间关系。关系在镜内不变时两端都保留;确需改变时,过程与终点必须有剧本依据。
@@ -143,7 +151,7 @@ license: MIT
143
151
  默认只读本 SKILL、当前剧本和必要视觉事实。遇到对应问题时只打开一份:
144
152
 
145
153
  - 阶段边界与规则分级:[阶段契约](references/stage-contract.md)
146
- - 镜头职责、切镜理由和边界:[镜头手艺](references/shot-craft.md)
154
+ - 镜头职责、切镜理由、镜长推导、对白覆盖和边界:[镜头手艺](references/shot-craft.md)
147
155
  - 实际制作所需的镜头语法:[生产镜头语法](references/production-shot-grammar.md)
148
156
  - 关键场次比较导演方案:[场次视觉计划](references/scene-visual-plan.md)
149
157
  - 检查原文是否都有画面承载:[Coverage Audition](references/coverage-audition.md)
@@ -24,7 +24,7 @@
24
24
  - 先保证进出方向和视线连续,再用近景强化选择。
25
25
 
26
26
  可以按以下顺序设计:空间锚点与入口 → 每人的行动目标和筹码 → 群体注意中心 →
27
- 关键动作前后的站位 → 哪些同时反应必须留在全景中 → 只有丢失信息时才切插入镜头或近景。
27
+ 关键动作前后的站位 → 哪些同时反应必须留在全景中 → 再按[对白覆盖默认](shot-craft.md#对白场怎么切-sht-29)切到说话者、听者和插入镜。
28
28
 
29
29
  常见问题:每句台词都切一个头像近景;站位只为填满画面;背景人物在切镜后无原因换边;
30
30
  重要人物一直被前景遮住,但剧情并未利用这种遮挡。
@@ -183,10 +183,10 @@
183
183
 
184
184
  | 决策 | 如何确定 |
185
185
  |---|---|
186
- | 拍如何拆镜 | 由动作边界、听者反应、空间变化与可执行时长共同决定,不追求固定比值。 |
186
+ | 拍如何拆镜 | 由动作边界、听者反应、空间变化与可执行时长共同决定;已接受节奏档案声明了目标平均镜长时按 [镜长从哪来](shot-craft.md#镜长从哪来-sht-28) 核对,否则不追求固定比值。 |
187
187
  | 台词如何分配 | 先保证一次可表演语气与口型负载;过长时按行动转向拆分,而非机械按字数。 |
188
188
  | 单镜还是镜头组 | 先把每个镜头写成可单独审查的记录,再按目标交付方式编组;编组不改变镜头身份。本环节只负责镜头本身:定清每个镜头的目的、起止边界与已接受时长。编组之后由谁承担时长加总与成员资格,属于交付环节的事,不在这里决定,也不因为将来会编组就提前合并镜头。 |
189
- | 子镜密度 | 9:16 信息流上的注意力是按切镜买的:`craft_default` 是可看的切镜密度大致每 4–8 秒一次,爽点更紧、情感处理更松在这条带宽内浮动,每次切换仍要有注意、压力或状态理由。项目把生成单元固定在更长的一档时,这条带宽由镜内调度承担——一镜里要有景别或视点的实际变化、或一次完整的动作与反应交接,否则无论单帧多好,观众读到的都是幻灯片。 |
189
+ | 子镜密度 | 按 [镜长从哪来](shot-craft.md#镜长从哪来-sht-28) 由声音事件与已接受的目标平均镜长推出;没有已接受节奏档案时不设数值带宽,把算出的平均镜长报给创作者。每次切换仍要有注意、压力或状态理由。项目把生成单元固定在更长的一档时,切镜密度由镜内调度承担——一镜里要有景别或视点的实际变化、或一次完整的动作与反应交接,否则无论单帧多好,观众读到的都是幻灯片。 |
190
190
  | 单元时长 | 先从必须保留的动作、反应、对白与最终状态反推这一镜需要多久;放不下就删减、拆镜或请求改边界。项目已经定下可用的生成长度档位时,取容得下它的最短一档;没定就按反推出的秒数写,并把用到的档位报给创作者。超过约五到八秒后,一张冻结关键帧只描述了镜头开头,其余部分实际上没有规格:更长的镜头要么按精确状态边界拆开,要么由创作者明确接受它是一个宽规格镜头。 |
191
191
 
192
192
  ## 七之二、单集时长加总(`SHT-16`)