dsh-openwrite 0.2.8

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 (275) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +107 -0
  3. package/THIRD_PARTY_NOTICES.md +33 -0
  4. package/assets/logo-dark.svg +31 -0
  5. package/assets/logo-light.svg +31 -0
  6. package/cordis.patch.yml +11 -0
  7. package/docs/BENCHMARK_TASKS.md +54 -0
  8. package/docs/COST_MEASUREMENT.md +39 -0
  9. package/docs/DEVELOPMENT.md +65 -0
  10. package/docs/DSH_STORE.md +58 -0
  11. package/docs/FRAMEWORK_ADVANTAGES.md +288 -0
  12. package/docs/IMPROVEMENT_PLAN.md +252 -0
  13. package/docs/INSTALL.md +99 -0
  14. package/docs/LEARNING.md +68 -0
  15. package/docs/OPEN_SOURCE_NOVEL_AUDIT.md +191 -0
  16. package/docs/PLUGIN_MAINTENANCE.md +54 -0
  17. package/docs/PLUGIN_MAINTENANCE_RC7.md +157 -0
  18. package/docs/QA_20260908.md +103 -0
  19. package/docs/QA_20260909_BENCHMARK.md +24 -0
  20. package/docs/RELEASE_ACCEPTANCE.md +116 -0
  21. package/docs/REVIEW_DAG_FRAMEWORK.md +82 -0
  22. package/docs/TARGETED_NOVEL_PROJECT_REVIEW.md +167 -0
  23. package/docs/WORKFLOWS.md +74 -0
  24. package/docs/WORKSPACE_CONTEXT_CONTRACT.md +125 -0
  25. package/docs/WORKSPACE_INTEGRATION_GOAL.md +278 -0
  26. package/docs/research/autosave-race-repro.mjs +133 -0
  27. package/docs/research/framework-stats-2026-09-05.json +116 -0
  28. package/dog-tools.mjs +11 -0
  29. package/package.json +132 -0
  30. package/packages/openwrite-bridge/LICENSE +201 -0
  31. package/packages/openwrite-bridge/cordis.patch.yml +10 -0
  32. package/packages/openwrite-bridge/lib/client.d.ts +95 -0
  33. package/packages/openwrite-bridge/lib/client.js +193 -0
  34. package/packages/openwrite-bridge/lib/contracts-generated.d.ts +367 -0
  35. package/packages/openwrite-bridge/lib/contracts-generated.js +1764 -0
  36. package/packages/openwrite-bridge/lib/dog-delivery.d.ts +12 -0
  37. package/packages/openwrite-bridge/lib/dog-delivery.js +362 -0
  38. package/packages/openwrite-bridge/lib/dog-review.d.ts +50 -0
  39. package/packages/openwrite-bridge/lib/dog-review.js +470 -0
  40. package/packages/openwrite-bridge/lib/domain.d.ts +70 -0
  41. package/packages/openwrite-bridge/lib/domain.js +496 -0
  42. package/packages/openwrite-bridge/lib/index.d.ts +17 -0
  43. package/packages/openwrite-bridge/lib/index.js +89 -0
  44. package/packages/openwrite-bridge/lib/managed-runtime.d.ts +95 -0
  45. package/packages/openwrite-bridge/lib/managed-runtime.js +510 -0
  46. package/packages/openwrite-bridge/lib/preset-tools.d.ts +13 -0
  47. package/packages/openwrite-bridge/lib/preset-tools.js +18 -0
  48. package/packages/openwrite-bridge/lib/tool-policy.d.ts +6 -0
  49. package/packages/openwrite-bridge/lib/tool-policy.js +56 -0
  50. package/packages/openwrite-bridge/lib/tools.d.ts +24 -0
  51. package/packages/openwrite-bridge/lib/tools.js +2404 -0
  52. package/packages/openwrite-bridge/package.json +67 -0
  53. package/packages/studio-panel/LICENSE +21 -0
  54. package/packages/studio-panel/README.md +51 -0
  55. package/packages/studio-panel/cordis.patch.yml +5 -0
  56. package/packages/studio-panel/lib/client.js +158087 -0
  57. package/packages/studio-panel/lib/client.js.map +1 -0
  58. package/packages/studio-panel/lib/index.js +50 -0
  59. package/packages/studio-panel/lib/types/client/AssetEditor.d.ts +122 -0
  60. package/packages/studio-panel/lib/types/client/AssetsView.d.ts +43 -0
  61. package/packages/studio-panel/lib/types/client/BenchmarkView.d.ts +9 -0
  62. package/packages/studio-panel/lib/types/client/ContinuousReader.d.ts +13 -0
  63. package/packages/studio-panel/lib/types/client/CreationView.d.ts +6 -0
  64. package/packages/studio-panel/lib/types/client/DagCanvas.d.ts +11 -0
  65. package/packages/studio-panel/lib/types/client/DiscardDraftDialog.d.ts +8 -0
  66. package/packages/studio-panel/lib/types/client/DomainToolCard.d.ts +9 -0
  67. package/packages/studio-panel/lib/types/client/GraphView.d.ts +46 -0
  68. package/packages/studio-panel/lib/types/client/HeaderChrome.d.ts +18 -0
  69. package/packages/studio-panel/lib/types/client/LaunchOpenWrite.d.ts +13 -0
  70. package/packages/studio-panel/lib/types/client/LibraryView.d.ts +6 -0
  71. package/packages/studio-panel/lib/types/client/MarkdownText.d.ts +3 -0
  72. package/packages/studio-panel/lib/types/client/ModelView.d.ts +9 -0
  73. package/packages/studio-panel/lib/types/client/OperationsView.d.ts +6 -0
  74. package/packages/studio-panel/lib/types/client/OutlinePlans.d.ts +37 -0
  75. package/packages/studio-panel/lib/types/client/OutlineView.d.ts +29 -0
  76. package/packages/studio-panel/lib/types/client/ResearchView.d.ts +7 -0
  77. package/packages/studio-panel/lib/types/client/ReviewCard.d.ts +28 -0
  78. package/packages/studio-panel/lib/types/client/SceneWorkbench.d.ts +55 -0
  79. package/packages/studio-panel/lib/types/client/SearchView.d.ts +33 -0
  80. package/packages/studio-panel/lib/types/client/TasksView.d.ts +11 -0
  81. package/packages/studio-panel/lib/types/client/TransferWorkspaces.d.ts +19 -0
  82. package/packages/studio-panel/lib/types/client/TurnMutationSummary.d.ts +62 -0
  83. package/packages/studio-panel/lib/types/client/VditorBody.d.ts +55 -0
  84. package/packages/studio-panel/lib/types/client/WorkbenchStore.d.ts +121 -0
  85. package/packages/studio-panel/lib/types/client/api.d.ts +72 -0
  86. package/packages/studio-panel/lib/types/client/asset-drafts.d.ts +20 -0
  87. package/packages/studio-panel/lib/types/client/benchmark-options.d.ts +43 -0
  88. package/packages/studio-panel/lib/types/client/draft-store.d.ts +26 -0
  89. package/packages/studio-panel/lib/types/client/dto.d.ts +517 -0
  90. package/packages/studio-panel/lib/types/client/index.d.ts +4 -0
  91. package/packages/studio-panel/lib/types/client/locales.d.ts +15 -0
  92. package/packages/studio-panel/lib/types/client/manuscript-annotations.d.ts +59 -0
  93. package/packages/studio-panel/lib/types/client/manuscript-markers.d.ts +61 -0
  94. package/packages/studio-panel/lib/types/client/manuscript-mentions.d.ts +30 -0
  95. package/packages/studio-panel/lib/types/client/manuscript-overlay-dom.d.ts +7 -0
  96. package/packages/studio-panel/lib/types/client/manuscript-overlay.d.ts +42 -0
  97. package/packages/studio-panel/lib/types/client/manuscript-selection.d.ts +59 -0
  98. package/packages/studio-panel/lib/types/client/model-view-memory.d.ts +17 -0
  99. package/packages/studio-panel/lib/types/client/storage.d.ts +8 -0
  100. package/packages/studio-panel/lib/types/client/workbench-epochs.d.ts +16 -0
  101. package/packages/studio-panel/lib/types/client/workspace-context.d.ts +52 -0
  102. package/packages/studio-panel/lib/types/client/writing-scope.d.ts +7 -0
  103. package/packages/studio-panel/lib/types/index.d.ts +5 -0
  104. package/packages/studio-panel/package.json +105 -0
  105. package/packages/studio-panel/vendor/vditor/LICENSE +21 -0
  106. package/packages/studio-panel/vendor/vditor/dist/css/content-theme/dark.css +123 -0
  107. package/packages/studio-panel/vendor/vditor/dist/css/content-theme/light.css +101 -0
  108. package/packages/studio-panel/vendor/vditor/dist/index.css +1823 -0
  109. package/packages/studio-panel/vendor/vditor/dist/index.min.js +1 -0
  110. package/packages/studio-panel/vendor/vditor/dist/js/i18n/zh_CN.js +86 -0
  111. package/packages/studio-panel/vendor/vditor/dist/js/icons/ant.js +174 -0
  112. package/packages/studio-panel/vendor/vditor/dist/js/lute/lute.min.js +72 -0
  113. package/plugin.d.ts +3 -0
  114. package/plugin.mjs +80 -0
  115. package/presets/README.md +32 -0
  116. package/presets/openwrite/agent.cordis.yml +317 -0
  117. package/presets/openwrite/preset.yml +3 -0
  118. package/presets/openwrite/skills/canon/SKILL.md +15 -0
  119. package/presets/openwrite/skills/dialoguequality/SKILL.md +166 -0
  120. package/presets/openwrite/skills/dog-delivery-query/SKILL.md +40 -0
  121. package/presets/openwrite/skills/dog-import-query/SKILL.md +27 -0
  122. package/presets/openwrite/skills/dog-review-query/SKILL.md +40 -0
  123. package/presets/openwrite/skills/export-book/SKILL.md +14 -0
  124. package/presets/openwrite/skills/foreshadow/SKILL.md +14 -0
  125. package/presets/openwrite/skills/foreshadowing-system/SKILL.md +125 -0
  126. package/presets/openwrite/skills/learn/SKILL.md +24 -0
  127. package/presets/openwrite/skills/novel-creator/SKILL.md +88 -0
  128. package/presets/openwrite/skills/novel-creator/templates/beat_templates.yaml +179 -0
  129. package/presets/openwrite/skills/novel-creator/templates/example_usage.yaml +74 -0
  130. package/presets/openwrite/skills/novel-reviewer/SKILL.md +85 -0
  131. package/presets/openwrite/skills/oh-story-deslop/LICENSE +21 -0
  132. package/presets/openwrite/skills/oh-story-deslop/SKILL.md +36 -0
  133. package/presets/openwrite/skills/oh-story-deslop/agents/openai.yaml +4 -0
  134. package/presets/openwrite/skills/oh-story-deslop/references/method.md +22 -0
  135. package/presets/openwrite/skills/oh-story-long-analyze/LICENSE +21 -0
  136. package/presets/openwrite/skills/oh-story-long-analyze/SKILL.md +37 -0
  137. package/presets/openwrite/skills/oh-story-long-analyze/agents/openai.yaml +4 -0
  138. package/presets/openwrite/skills/oh-story-long-analyze/references/method.md +22 -0
  139. package/presets/openwrite/skills/oh-story-long-scan/LICENSE +21 -0
  140. package/presets/openwrite/skills/oh-story-long-scan/SKILL.md +36 -0
  141. package/presets/openwrite/skills/oh-story-long-scan/agents/openai.yaml +4 -0
  142. package/presets/openwrite/skills/oh-story-long-scan/references/method.md +21 -0
  143. package/presets/openwrite/skills/oh-story-long-write/LICENSE +21 -0
  144. package/presets/openwrite/skills/oh-story-long-write/SKILL.md +37 -0
  145. package/presets/openwrite/skills/oh-story-long-write/agents/openai.yaml +4 -0
  146. package/presets/openwrite/skills/oh-story-long-write/references/method.md +33 -0
  147. package/presets/openwrite/skills/oh-story-review/LICENSE +21 -0
  148. package/presets/openwrite/skills/oh-story-review/SKILL.md +36 -0
  149. package/presets/openwrite/skills/oh-story-review/agents/openai.yaml +4 -0
  150. package/presets/openwrite/skills/oh-story-review/references/method.md +25 -0
  151. package/presets/openwrite/skills/progress/SKILL.md +16 -0
  152. package/presets/openwrite/skills/review-chapter/SKILL.md +17 -0
  153. package/presets/openwrite/skills/revise-span/SKILL.md +16 -0
  154. package/presets/openwrite/skills/style-system/SKILL.md +135 -0
  155. package/presets/openwrite/skills/style-system/prompts/analyze_style.md +214 -0
  156. package/presets/openwrite/skills/style-system/prompts/batch_extract_style.md +66 -0
  157. package/presets/openwrite/skills/style-system/prompts/compose_style.md +83 -0
  158. package/presets/openwrite/skills/style-system/prompts/extract_style.md +84 -0
  159. package/presets/openwrite/skills/style-system/prompts/initialize_style.md +52 -0
  160. package/presets/openwrite/skills/style-system/templates/analysis_report.yaml +78 -0
  161. package/presets/openwrite/skills/style-system/templates/composed_style.md +96 -0
  162. package/presets/openwrite/skills/style-system/templates/extraction_report.yaml +80 -0
  163. package/presets/openwrite/skills/style-system/templates/fingerprint.yaml +61 -0
  164. package/presets/openwrite/skills/style-system/tools/README.md +33 -0
  165. package/presets/openwrite/skills/truth-validation/SKILL.md +119 -0
  166. package/presets/openwrite/skills/workflow-manager/SKILL.md +81 -0
  167. package/presets/openwrite/skills/world-query/SKILL.md +45 -0
  168. package/presets/openwrite/skills/write-next/SKILL.md +17 -0
  169. package/release/core-requirements.in +12 -0
  170. package/release/licenses/@deepseek-ai__cosmokit@1.8.3/LICENSE +21 -0
  171. package/release/licenses/@deepseek-ai__schemastery@3.18.2/LICENSE +21 -0
  172. package/release/licenses/@isaacs__fs-minipass@4.0.1/LICENSE +15 -0
  173. package/release/licenses/@standard-schema__spec@1.1.0/LICENSE +21 -0
  174. package/release/licenses/@types__d3-color@3.1.3/LICENSE +21 -0
  175. package/release/licenses/@types__d3-drag@3.0.7/LICENSE +21 -0
  176. package/release/licenses/@types__d3-interpolate@3.0.4/LICENSE +21 -0
  177. package/release/licenses/@types__d3-selection@3.0.11/LICENSE +21 -0
  178. package/release/licenses/@types__d3-transition@3.0.9/LICENSE +21 -0
  179. package/release/licenses/@types__d3-zoom@3.0.8/LICENSE +21 -0
  180. package/release/licenses/@xyflow__react@12.11.6/LICENSE +21 -0
  181. package/release/licenses/@xyflow__system@0.0.82/LICENSE +21 -0
  182. package/release/licenses/ajv-formats@3.0.1/LICENSE +21 -0
  183. package/release/licenses/ajv@8.20.0/LICENSE +22 -0
  184. package/release/licenses/chownr@3.0.0/LICENSE.md +63 -0
  185. package/release/licenses/classcat@5.0.5/LICENSE.md +7 -0
  186. package/release/licenses/commander@7.2.0/LICENSE +22 -0
  187. package/release/licenses/d3-array@3.2.4/LICENSE +13 -0
  188. package/release/licenses/d3-axis@3.0.0/LICENSE +13 -0
  189. package/release/licenses/d3-brush@3.0.0/LICENSE +13 -0
  190. package/release/licenses/d3-chord@3.0.1/LICENSE +13 -0
  191. package/release/licenses/d3-color@3.1.0/LICENSE +13 -0
  192. package/release/licenses/d3-contour@4.0.2/LICENSE +13 -0
  193. package/release/licenses/d3-delaunay@6.0.4/LICENSE +14 -0
  194. package/release/licenses/d3-dispatch@3.0.1/LICENSE +13 -0
  195. package/release/licenses/d3-drag@3.0.0/LICENSE +13 -0
  196. package/release/licenses/d3-dsv@3.0.1/LICENSE +13 -0
  197. package/release/licenses/d3-ease@3.0.1/LICENSE +28 -0
  198. package/release/licenses/d3-fetch@3.0.1/LICENSE +13 -0
  199. package/release/licenses/d3-force@3.0.0/LICENSE +13 -0
  200. package/release/licenses/d3-format@3.1.2/LICENSE +13 -0
  201. package/release/licenses/d3-geo@3.1.1/LICENSE +34 -0
  202. package/release/licenses/d3-hierarchy@3.1.2/LICENSE +13 -0
  203. package/release/licenses/d3-interpolate@3.0.1/LICENSE +13 -0
  204. package/release/licenses/d3-path@3.1.0/LICENSE +13 -0
  205. package/release/licenses/d3-polygon@3.0.1/LICENSE +13 -0
  206. package/release/licenses/d3-quadtree@3.0.1/LICENSE +13 -0
  207. package/release/licenses/d3-random@3.0.1/LICENSE +13 -0
  208. package/release/licenses/d3-scale-chromatic@3.1.0/LICENSE +28 -0
  209. package/release/licenses/d3-scale@4.0.2/LICENSE +13 -0
  210. package/release/licenses/d3-selection@3.0.0/LICENSE +13 -0
  211. package/release/licenses/d3-shape@3.2.0/LICENSE +13 -0
  212. package/release/licenses/d3-time-format@4.1.0/LICENSE +13 -0
  213. package/release/licenses/d3-time@3.1.0/LICENSE +13 -0
  214. package/release/licenses/d3-timer@3.0.1/LICENSE +13 -0
  215. package/release/licenses/d3-transition@3.0.1/LICENSE +13 -0
  216. package/release/licenses/d3-zoom@3.0.0/LICENSE +13 -0
  217. package/release/licenses/d3@7.9.0/LICENSE +13 -0
  218. package/release/licenses/delaunator@5.1.0/LICENSE +15 -0
  219. package/release/licenses/elkjs@0.12.0/LICENSE.md +263 -0
  220. package/release/licenses/fast-deep-equal@3.1.3/LICENSE +21 -0
  221. package/release/licenses/fast-uri@3.1.7/LICENSE +30 -0
  222. package/release/licenses/fflate@0.8.2/LICENSE +21 -0
  223. package/release/licenses/graceful-fs@4.2.11/LICENSE +15 -0
  224. package/release/licenses/iconv-lite@0.6.3/LICENSE +21 -0
  225. package/release/licenses/internmap@2.0.3/LICENSE +13 -0
  226. package/release/licenses/json-schema-traverse@1.0.0/LICENSE +21 -0
  227. package/release/licenses/lucide-react@0.468.0/LICENSE +15 -0
  228. package/release/licenses/minipass@7.1.3/LICENSE.md +55 -0
  229. package/release/licenses/minizlib@3.1.0/LICENSE +26 -0
  230. package/release/licenses/proper-lockfile@4.1.2/LICENSE +21 -0
  231. package/release/licenses/require-from-string@2.0.2/license +21 -0
  232. package/release/licenses/retry@0.12.0/License +21 -0
  233. package/release/licenses/robust-predicates@3.0.3/LICENSE +24 -0
  234. package/release/licenses/rw@1.3.3/LICENSE +26 -0
  235. package/release/licenses/safer-buffer@2.1.2/LICENSE +21 -0
  236. package/release/licenses/signal-exit@3.0.7/LICENSE.txt +16 -0
  237. package/release/licenses/tar@7.5.7/LICENSE.md +55 -0
  238. package/release/licenses/use-sync-external-store@1.6.0/LICENSE +21 -0
  239. package/release/licenses/yallist@5.0.0/LICENSE.md +63 -0
  240. package/release/licenses/zustand@4.5.7/LICENSE +21 -0
  241. package/release/openwrite-5.8.1-py3-none-any.whl +0 -0
  242. package/release/platform-overrides.in +5 -0
  243. package/release/python-constraints.in +96 -0
  244. package/release/requirements.lock +2927 -0
  245. package/release/runtime-manifest.json +98 -0
  246. package/release/sdk-compatibility.json +240 -0
  247. package/release/source.json +859 -0
  248. package/release/wheels/cryptography-50.0.1-cp312-abi3-macosx_13_0_x86_64.whl +0 -0
  249. package/release/wheels/licenses/LICENSE.txt +177 -0
  250. package/release/wheels/provenance.json +15 -0
  251. package/scripts/dog/delivery-stage.js +32 -0
  252. package/scripts/dog/import-chapter.js +20 -0
  253. package/scripts/dog/import-record.js +35 -0
  254. package/scripts/dog/review-dimension.js +41 -0
  255. package/scripts/dog/review-record.js +42 -0
  256. package/scripts/maintenance.mjs +179 -0
  257. package/scripts/prepare.mjs +21 -0
  258. package/vendor/dsh-dog/LICENSE +29 -0
  259. package/vendor/dsh-dog/README.md +114 -0
  260. package/vendor/dsh-dog/UPSTREAM.md +22 -0
  261. package/vendor/dsh-dog/cordis.patch.yml +14 -0
  262. package/vendor/dsh-dog/lib/client.js +2898 -0
  263. package/vendor/dsh-dog/lib/client.js.map +1 -0
  264. package/vendor/dsh-dog/lib/core-BiEBMLz3.d.ts +495 -0
  265. package/vendor/dsh-dog/lib/core-DdfMcrB4.js +2074 -0
  266. package/vendor/dsh-dog/lib/core.d.ts +2 -0
  267. package/vendor/dsh-dog/lib/core.js +2 -0
  268. package/vendor/dsh-dog/lib/index.d.ts +133 -0
  269. package/vendor/dsh-dog/lib/index.js +967 -0
  270. package/vendor/dsh-dog/package.json +97 -0
  271. package/vendor/dsh-dog/schemas/schema-0.2/graph.schema.json +139 -0
  272. package/vendor/dsh-dog/schemas/schema-0.2/report.schema.json +87 -0
  273. package/vendor/dsh-dog/schemas/schema-0.2/run.schema.json +259 -0
  274. package/vendor/dsh-dog/schemas/schema-0.2/runtime-event.schema.json +105 -0
  275. package/vendor/dsh-dog/schemas/schema-0.2/verification.schema.json +40 -0
@@ -0,0 +1,1764 @@
1
+ function typeOk(value, name) {
2
+ switch (name) {
3
+ case 'object': return value !== null && typeof value === 'object' && !Array.isArray(value);
4
+ case 'array': return Array.isArray(value);
5
+ case 'null': return value === null;
6
+ case 'integer': return Number.isInteger(value);
7
+ case 'number': return typeof value === 'number' && !Number.isNaN(value);
8
+ default: return typeof value === name;
9
+ }
10
+ }
11
+ /** Minimal JSON Schema subset validator mirroring OpenWrite
12
+ * `tools/schema_lint.py` and `scripts/schema-lint.mjs`. */
13
+ export function validateSchema(value, schema, path = '$', root = schema) {
14
+ const errors = [];
15
+ const fail = (message) => errors.push(`${path}: ${message}`);
16
+ const ref = schema['$ref'];
17
+ if (typeof ref === 'string' && ref.startsWith('#/')) {
18
+ let resolved = root;
19
+ for (const part of ref.slice(2).split('/'))
20
+ resolved = resolved?.[part];
21
+ if (resolved && typeof resolved === 'object')
22
+ return validateSchema(value, resolved, path, root);
23
+ }
24
+ const rawType = schema['type'];
25
+ if (rawType !== undefined) {
26
+ const names = Array.isArray(rawType) ? rawType.map(String) : [String(rawType)];
27
+ if (!names.some(name => typeOk(value, name))) {
28
+ const got = value === null ? 'null' : Array.isArray(value) ? 'array' : typeof value;
29
+ fail(`expected type ${names.join('/')}, got ${got}`);
30
+ return errors;
31
+ }
32
+ }
33
+ if (schema['const'] !== undefined && value !== schema['const']) {
34
+ fail(`expected const ${JSON.stringify(schema['const'])}, got ${JSON.stringify(value)}`);
35
+ }
36
+ const enumValues = schema['enum'];
37
+ if (Array.isArray(enumValues) && !enumValues.includes(value)) {
38
+ fail(`${JSON.stringify(value)} not in enum ${JSON.stringify(enumValues)}`);
39
+ }
40
+ if (value !== null && typeof value === 'object' && !Array.isArray(value)) {
41
+ const record = value;
42
+ for (const key of schema['required'] ?? []) {
43
+ if (!(key in record))
44
+ fail(`missing required property '${key}'`);
45
+ }
46
+ for (const key of schema['disallowed'] ?? []) {
47
+ if (key in record)
48
+ fail(`forbidden credential-like property '${key}' must not appear`);
49
+ }
50
+ const properties = schema['properties'] ?? {};
51
+ const additional = schema['additionalProperties'];
52
+ for (const [key, sub] of Object.entries(record)) {
53
+ if (key in properties) {
54
+ errors.push(...validateSchema(sub, properties[key], `${path}.${key}`, root));
55
+ }
56
+ else if (additional === false) {
57
+ fail(`unexpected property '${key}'`);
58
+ }
59
+ else if (additional !== undefined && typeof additional === 'object') {
60
+ errors.push(...validateSchema(sub, additional, `${path}.${key}`, root));
61
+ }
62
+ }
63
+ const minProperties = schema['minProperties'];
64
+ if (typeof minProperties === 'number' && Object.keys(record).length < minProperties) {
65
+ fail(`expected at least ${minProperties} properties, got ${Object.keys(record).length}`);
66
+ }
67
+ }
68
+ const items = schema['items'];
69
+ if (Array.isArray(value) && items !== undefined && typeof items === 'object') {
70
+ value.forEach((item, index) => {
71
+ errors.push(...validateSchema(item, items, `${path}[${index}]`, root));
72
+ });
73
+ }
74
+ if (typeof value === 'number' && !Number.isNaN(value)) {
75
+ const minimum = schema['minimum'];
76
+ if (typeof minimum === 'number' && value < minimum) {
77
+ fail(`${value} is less than minimum ${minimum}`);
78
+ }
79
+ const maximum = schema['maximum'];
80
+ if (typeof maximum === 'number' && value > maximum) {
81
+ fail(`${value} is greater than maximum ${maximum}`);
82
+ }
83
+ }
84
+ if (typeof value === 'string') {
85
+ const minLength = schema['minLength'];
86
+ if (typeof minLength === 'number' && value.length < minLength) {
87
+ fail(`string shorter than minLength ${minLength}`);
88
+ }
89
+ const pattern = schema['pattern'];
90
+ if (typeof pattern === 'string' && new RegExp(pattern).test(value) === false) {
91
+ fail(`'${value}' does not match pattern '${pattern}'`);
92
+ }
93
+ }
94
+ return errors;
95
+ }
96
+ const SCHEMAS = {
97
+ "delivery_manifest_v2": {
98
+ "$id": "https://openwrite.dev/schemas/delivery-manifest-v2.schema.json",
99
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
100
+ "additionalProperties": true,
101
+ "properties": {
102
+ "chapterId": {
103
+ "pattern": "^ch_\\d+$",
104
+ "type": "string"
105
+ },
106
+ "decisionSource": {
107
+ "enum": [
108
+ "v2",
109
+ "v1-adapter"
110
+ ]
111
+ },
112
+ "novelId": {
113
+ "minLength": 1,
114
+ "type": "string"
115
+ },
116
+ "readyForDelivery": {
117
+ "type": "boolean"
118
+ },
119
+ "recordType": {
120
+ "const": "chapter-delivery"
121
+ },
122
+ "schemaVersion": {
123
+ "const": "dsh-novel.delivery.manifest.v2"
124
+ },
125
+ "stages": {
126
+ "additionalProperties": {
127
+ "additionalProperties": true,
128
+ "properties": {
129
+ "chapterId": {
130
+ "pattern": "^ch_\\d+$",
131
+ "type": "string"
132
+ },
133
+ "evidence": {
134
+ "type": "object"
135
+ },
136
+ "recordType": {
137
+ "const": "delivery-stage"
138
+ },
139
+ "schemaVersion": {
140
+ "const": "dsh-novel.delivery.stage.v2"
141
+ },
142
+ "stage": {
143
+ "minLength": 1,
144
+ "type": "string"
145
+ },
146
+ "status": {
147
+ "minLength": 1,
148
+ "type": "string"
149
+ },
150
+ "verdict": {
151
+ "enum": [
152
+ "pass",
153
+ "fail",
154
+ "inconclusive"
155
+ ]
156
+ }
157
+ },
158
+ "required": [
159
+ "schemaVersion",
160
+ "recordType",
161
+ "chapterId",
162
+ "stage",
163
+ "verdict",
164
+ "status",
165
+ "evidence"
166
+ ],
167
+ "type": "object"
168
+ },
169
+ "minProperties": 1,
170
+ "type": "object"
171
+ },
172
+ "threshold": {
173
+ "maximum": 100,
174
+ "minimum": 0,
175
+ "type": "integer"
176
+ }
177
+ },
178
+ "required": [
179
+ "schemaVersion",
180
+ "recordType",
181
+ "chapterId",
182
+ "stages"
183
+ ],
184
+ "title": "dsh-novel delivery manifest v2",
185
+ "type": "object"
186
+ },
187
+ "delivery_stage_v2": {
188
+ "$id": "https://openwrite.dev/schemas/delivery-stage-v2.schema.json",
189
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
190
+ "additionalProperties": true,
191
+ "properties": {
192
+ "chapterId": {
193
+ "pattern": "^ch_\\d+$",
194
+ "type": "string"
195
+ },
196
+ "evidence": {
197
+ "type": "object"
198
+ },
199
+ "recordType": {
200
+ "const": "delivery-stage"
201
+ },
202
+ "schemaVersion": {
203
+ "const": "dsh-novel.delivery.stage.v2"
204
+ },
205
+ "stage": {
206
+ "minLength": 1,
207
+ "type": "string"
208
+ },
209
+ "status": {
210
+ "minLength": 1,
211
+ "type": "string"
212
+ },
213
+ "verdict": {
214
+ "enum": [
215
+ "pass",
216
+ "fail",
217
+ "inconclusive"
218
+ ]
219
+ }
220
+ },
221
+ "required": [
222
+ "schemaVersion",
223
+ "recordType",
224
+ "chapterId",
225
+ "stage",
226
+ "verdict",
227
+ "status",
228
+ "evidence"
229
+ ],
230
+ "title": "dsh-novel delivery stage v2",
231
+ "type": "object"
232
+ },
233
+ "model_benchmark_v1": {
234
+ "$id": "https://openwrite.dev/schemas/model-benchmark-v1.schema.json",
235
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
236
+ "additionalProperties": true,
237
+ "properties": {
238
+ "candidates": {
239
+ "items": {
240
+ "additionalProperties": true,
241
+ "disallowed": [
242
+ "api_key",
243
+ "embedding_api_key",
244
+ "secret"
245
+ ],
246
+ "properties": {
247
+ "candidate_id": {
248
+ "minLength": 1,
249
+ "type": "string"
250
+ },
251
+ "cost_reported": {
252
+ "type": "boolean"
253
+ },
254
+ "cost_usd": {
255
+ "type": [
256
+ "number",
257
+ "null"
258
+ ]
259
+ },
260
+ "error": {
261
+ "additionalProperties": true,
262
+ "properties": {
263
+ "code": {
264
+ "minLength": 1,
265
+ "type": "string"
266
+ },
267
+ "message": {
268
+ "type": "string"
269
+ }
270
+ },
271
+ "required": [
272
+ "code",
273
+ "message"
274
+ ],
275
+ "type": [
276
+ "object",
277
+ "null"
278
+ ]
279
+ },
280
+ "latency_ms": {
281
+ "type": [
282
+ "integer",
283
+ "null"
284
+ ]
285
+ },
286
+ "outline_chapter_count": {
287
+ "maximum": 20,
288
+ "minimum": 1,
289
+ "type": "integer"
290
+ },
291
+ "outline_chapters": {
292
+ "items": {
293
+ "type": "object"
294
+ },
295
+ "type": "array"
296
+ },
297
+ "outline_end_chapter": {
298
+ "maximum": 100000,
299
+ "minimum": 1,
300
+ "type": "integer"
301
+ },
302
+ "outline_start_chapter": {
303
+ "maximum": 100000,
304
+ "minimum": 1,
305
+ "type": "integer"
306
+ },
307
+ "reliability_status": {
308
+ "enum": [
309
+ "completed",
310
+ "failed"
311
+ ]
312
+ },
313
+ "task_type": {
314
+ "enum": [
315
+ "chapter",
316
+ "outline"
317
+ ]
318
+ },
319
+ "usage": {
320
+ "additionalProperties": true,
321
+ "properties": {
322
+ "completion_tokens": {
323
+ "type": [
324
+ "integer",
325
+ "null"
326
+ ]
327
+ },
328
+ "prompt_tokens": {
329
+ "type": [
330
+ "integer",
331
+ "null"
332
+ ]
333
+ },
334
+ "reasoning_tokens": {
335
+ "type": [
336
+ "integer",
337
+ "null"
338
+ ]
339
+ },
340
+ "total_tokens": {
341
+ "type": [
342
+ "integer",
343
+ "null"
344
+ ]
345
+ }
346
+ },
347
+ "type": [
348
+ "object",
349
+ "null"
350
+ ]
351
+ },
352
+ "writer_profile": {
353
+ "type": "object"
354
+ }
355
+ },
356
+ "required": [
357
+ "candidate_id",
358
+ "writer_profile",
359
+ "reliability_status"
360
+ ],
361
+ "type": "object"
362
+ },
363
+ "type": "array"
364
+ },
365
+ "config": {
366
+ "additionalProperties": true,
367
+ "properties": {
368
+ "blind_review": {
369
+ "type": "boolean"
370
+ },
371
+ "concurrency": {
372
+ "maximum": 4,
373
+ "minimum": 1,
374
+ "type": "integer"
375
+ },
376
+ "execution_mode": {
377
+ "enum": [
378
+ "framework",
379
+ "creative"
380
+ ]
381
+ },
382
+ "outline_chapter_count": {
383
+ "maximum": 20,
384
+ "minimum": 1,
385
+ "type": "integer"
386
+ },
387
+ "outline_end_chapter": {
388
+ "maximum": 100000,
389
+ "minimum": 1,
390
+ "type": "integer"
391
+ },
392
+ "outline_start_chapter": {
393
+ "maximum": 100000,
394
+ "minimum": 1,
395
+ "type": "integer"
396
+ },
397
+ "pipeline": {
398
+ "properties": {
399
+ "execution_mode": {
400
+ "enum": [
401
+ "framework",
402
+ "creative"
403
+ ]
404
+ },
405
+ "id": {
406
+ "type": "string"
407
+ },
408
+ "nodes": {
409
+ "items": {
410
+ "properties": {
411
+ "depends_on": {
412
+ "items": {
413
+ "type": "string"
414
+ },
415
+ "type": "array"
416
+ },
417
+ "id": {
418
+ "type": "string"
419
+ },
420
+ "label": {
421
+ "type": "string"
422
+ }
423
+ },
424
+ "required": [
425
+ "id",
426
+ "label",
427
+ "depends_on"
428
+ ],
429
+ "type": "object"
430
+ },
431
+ "type": "array"
432
+ },
433
+ "review_domains": {
434
+ "items": {
435
+ "properties": {
436
+ "id": {
437
+ "type": "string"
438
+ },
439
+ "label": {
440
+ "type": "string"
441
+ }
442
+ },
443
+ "type": "object"
444
+ },
445
+ "type": "array"
446
+ }
447
+ },
448
+ "type": "object"
449
+ },
450
+ "repeats": {
451
+ "maximum": 5,
452
+ "minimum": 1,
453
+ "type": "integer"
454
+ },
455
+ "reviewer_profile_ids": {
456
+ "items": {
457
+ "type": "string"
458
+ },
459
+ "type": "array"
460
+ },
461
+ "run_scoped_profiles": {
462
+ "type": "boolean"
463
+ },
464
+ "target_words": {
465
+ "maximum": 12000,
466
+ "minimum": 200,
467
+ "type": "integer"
468
+ },
469
+ "task_type": {
470
+ "enum": [
471
+ "chapter",
472
+ "outline"
473
+ ]
474
+ },
475
+ "writer_profile_ids": {
476
+ "items": {
477
+ "type": "string"
478
+ },
479
+ "type": "array"
480
+ }
481
+ },
482
+ "required": [
483
+ "writer_profile_ids",
484
+ "reviewer_profile_ids"
485
+ ],
486
+ "type": "object"
487
+ },
488
+ "context_hash": {
489
+ "minLength": 1,
490
+ "type": "string"
491
+ },
492
+ "evaluations": {
493
+ "items": {
494
+ "additionalProperties": true,
495
+ "disallowed": [
496
+ "api_key",
497
+ "embedding_api_key",
498
+ "secret"
499
+ ],
500
+ "properties": {
501
+ "candidate_id": {
502
+ "minLength": 1,
503
+ "type": "string"
504
+ },
505
+ "cost_reported": {
506
+ "type": "boolean"
507
+ },
508
+ "cost_usd": {
509
+ "type": [
510
+ "number",
511
+ "null"
512
+ ]
513
+ },
514
+ "error": {
515
+ "additionalProperties": true,
516
+ "properties": {
517
+ "code": {
518
+ "minLength": 1,
519
+ "type": "string"
520
+ },
521
+ "message": {
522
+ "type": "string"
523
+ }
524
+ },
525
+ "required": [
526
+ "code",
527
+ "message"
528
+ ],
529
+ "type": [
530
+ "object",
531
+ "null"
532
+ ]
533
+ },
534
+ "execution_status": {
535
+ "enum": [
536
+ "completed",
537
+ "partial",
538
+ "failed"
539
+ ]
540
+ },
541
+ "latency_ms": {
542
+ "type": [
543
+ "integer",
544
+ "null"
545
+ ]
546
+ },
547
+ "reviewer_profile": {
548
+ "type": "object"
549
+ },
550
+ "usage": {
551
+ "additionalProperties": true,
552
+ "properties": {
553
+ "completion_tokens": {
554
+ "type": [
555
+ "integer",
556
+ "null"
557
+ ]
558
+ },
559
+ "prompt_tokens": {
560
+ "type": [
561
+ "integer",
562
+ "null"
563
+ ]
564
+ },
565
+ "reasoning_tokens": {
566
+ "type": [
567
+ "integer",
568
+ "null"
569
+ ]
570
+ },
571
+ "total_tokens": {
572
+ "type": [
573
+ "integer",
574
+ "null"
575
+ ]
576
+ }
577
+ },
578
+ "type": [
579
+ "object",
580
+ "null"
581
+ ]
582
+ }
583
+ },
584
+ "required": [
585
+ "candidate_id",
586
+ "reviewer_profile",
587
+ "execution_status"
588
+ ],
589
+ "type": "object"
590
+ },
591
+ "type": "array"
592
+ },
593
+ "run_id": {
594
+ "pattern": "^bench_[A-Za-z0-9_-]+$",
595
+ "type": "string"
596
+ },
597
+ "schema_version": {
598
+ "const": "openwrite.model-benchmark.v1"
599
+ },
600
+ "started_at": {
601
+ "minLength": 1,
602
+ "type": "string"
603
+ },
604
+ "status": {
605
+ "enum": [
606
+ "completed",
607
+ "partial",
608
+ "failed"
609
+ ]
610
+ },
611
+ "summary": {
612
+ "additionalProperties": true,
613
+ "properties": {
614
+ "failed_candidates": {
615
+ "minimum": 0,
616
+ "type": "integer"
617
+ },
618
+ "latency_ms_total": {
619
+ "type": [
620
+ "integer",
621
+ "null"
622
+ ]
623
+ }
624
+ },
625
+ "type": "object"
626
+ },
627
+ "task_id": {
628
+ "minLength": 1,
629
+ "type": "string"
630
+ },
631
+ "task_type": {
632
+ "enum": [
633
+ "chapter",
634
+ "outline"
635
+ ]
636
+ }
637
+ },
638
+ "required": [
639
+ "schema_version",
640
+ "run_id",
641
+ "status",
642
+ "context_hash",
643
+ "config",
644
+ "candidates",
645
+ "evaluations"
646
+ ],
647
+ "title": "OpenWrite model benchmark v1 artifact",
648
+ "type": "object"
649
+ },
650
+ "model_connection_test_v1": {
651
+ "$id": "https://openwrite.dev/schemas/model-connection-test-v1.schema.json",
652
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
653
+ "additionalProperties": true,
654
+ "disallowed": [
655
+ "api_key",
656
+ "embedding_api_key",
657
+ "secret",
658
+ "credential"
659
+ ],
660
+ "properties": {
661
+ "base_url": {
662
+ "type": "string"
663
+ },
664
+ "dimension": {
665
+ "minimum": 1,
666
+ "type": "integer"
667
+ },
668
+ "latency_ms": {
669
+ "minimum": 0,
670
+ "type": "integer"
671
+ },
672
+ "max_tokens": {
673
+ "minimum": 1,
674
+ "type": "integer"
675
+ },
676
+ "model": {
677
+ "minLength": 1,
678
+ "type": "string"
679
+ },
680
+ "ok": {
681
+ "const": true
682
+ },
683
+ "provider": {
684
+ "minLength": 1,
685
+ "type": "string"
686
+ },
687
+ "provider_label": {
688
+ "type": "string"
689
+ },
690
+ "reply": {
691
+ "type": "string"
692
+ },
693
+ "status": {
694
+ "const": "ok"
695
+ },
696
+ "tested_at": {
697
+ "minLength": 1,
698
+ "type": "string"
699
+ },
700
+ "vectors": {
701
+ "minimum": 1,
702
+ "type": "integer"
703
+ }
704
+ },
705
+ "required": [
706
+ "ok",
707
+ "status",
708
+ "provider",
709
+ "model",
710
+ "latency_ms",
711
+ "tested_at"
712
+ ],
713
+ "title": "OpenWrite model connection test v1 success payload (chat and embedding variants)",
714
+ "type": "object"
715
+ },
716
+ "model_profile_surface_v1": {
717
+ "$defs": {
718
+ "chat_profile": {
719
+ "additionalProperties": true,
720
+ "disallowed": [
721
+ "api_key",
722
+ "embedding_api_key",
723
+ "secret"
724
+ ],
725
+ "properties": {
726
+ "capabilities": {
727
+ "properties": {
728
+ "chat": {
729
+ "const": true
730
+ }
731
+ },
732
+ "required": [
733
+ "chat"
734
+ ],
735
+ "type": "object"
736
+ },
737
+ "configured": {
738
+ "type": "boolean"
739
+ },
740
+ "id": {
741
+ "type": "string"
742
+ },
743
+ "label": {
744
+ "type": "string"
745
+ },
746
+ "last_test": {
747
+ "$ref": "#/$defs/test"
748
+ },
749
+ "model": {
750
+ "type": "string"
751
+ },
752
+ "provider": {
753
+ "type": "string"
754
+ },
755
+ "schema_version": {
756
+ "const": "openwrite.model-profile.v1"
757
+ },
758
+ "used_by_routes": {
759
+ "items": {
760
+ "enum": [
761
+ "goethe",
762
+ "dante",
763
+ "chapter_write",
764
+ "review",
765
+ "source_extract",
766
+ "revision",
767
+ "search",
768
+ "research"
769
+ ]
770
+ },
771
+ "type": "array"
772
+ }
773
+ },
774
+ "required": [
775
+ "id",
776
+ "label",
777
+ "provider",
778
+ "model",
779
+ "configured",
780
+ "schema_version",
781
+ "capabilities",
782
+ "used_by_routes",
783
+ "last_test"
784
+ ],
785
+ "type": "object"
786
+ },
787
+ "embedding_profile": {
788
+ "additionalProperties": true,
789
+ "disallowed": [
790
+ "api_key",
791
+ "embedding_api_key",
792
+ "secret"
793
+ ],
794
+ "properties": {
795
+ "active": {
796
+ "type": "boolean"
797
+ },
798
+ "base_url": {
799
+ "type": "string"
800
+ },
801
+ "configured": {
802
+ "type": "boolean"
803
+ },
804
+ "dimension": {
805
+ "minimum": 1,
806
+ "type": "integer"
807
+ },
808
+ "id": {
809
+ "type": "string"
810
+ },
811
+ "label": {
812
+ "type": "string"
813
+ },
814
+ "last_test": {
815
+ "$ref": "#/$defs/test"
816
+ },
817
+ "max_tokens": {
818
+ "minimum": 1,
819
+ "type": "integer"
820
+ },
821
+ "model": {
822
+ "type": "string"
823
+ },
824
+ "provider": {
825
+ "type": "string"
826
+ },
827
+ "schema_version": {
828
+ "const": "openwrite.embedding-profile.v1"
829
+ }
830
+ },
831
+ "required": [
832
+ "id",
833
+ "label",
834
+ "provider",
835
+ "model",
836
+ "dimension",
837
+ "max_tokens",
838
+ "configured",
839
+ "active",
840
+ "schema_version",
841
+ "last_test"
842
+ ],
843
+ "type": "object"
844
+ },
845
+ "test": {
846
+ "additionalProperties": true,
847
+ "disallowed": [
848
+ "api_key",
849
+ "secret",
850
+ "credential"
851
+ ],
852
+ "properties": {
853
+ "error_code": {
854
+ "type": [
855
+ "string",
856
+ "null"
857
+ ]
858
+ },
859
+ "failed_stage": {
860
+ "type": "null"
861
+ },
862
+ "latency_ms": {
863
+ "minimum": 0,
864
+ "type": "integer"
865
+ },
866
+ "provider": {
867
+ "type": "string"
868
+ },
869
+ "resolved_model": {
870
+ "type": "string"
871
+ },
872
+ "status": {
873
+ "enum": [
874
+ "ok",
875
+ "failed"
876
+ ]
877
+ },
878
+ "tested_at": {
879
+ "type": "string"
880
+ }
881
+ },
882
+ "required": [
883
+ "status",
884
+ "tested_at",
885
+ "latency_ms",
886
+ "provider",
887
+ "resolved_model",
888
+ "error_code",
889
+ "failed_stage"
890
+ ],
891
+ "type": [
892
+ "object",
893
+ "null"
894
+ ]
895
+ }
896
+ },
897
+ "$id": "https://openwrite.dev/schemas/model-profile-surface-v1.schema.json",
898
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
899
+ "additionalProperties": true,
900
+ "properties": {
901
+ "active_embedding_profile_id": {
902
+ "type": "string"
903
+ },
904
+ "default_profile_id": {
905
+ "minLength": 1,
906
+ "type": "string"
907
+ },
908
+ "embedding_profiles": {
909
+ "items": {
910
+ "$ref": "#/$defs/embedding_profile"
911
+ },
912
+ "type": "array"
913
+ },
914
+ "profiles": {
915
+ "items": {
916
+ "$ref": "#/$defs/chat_profile"
917
+ },
918
+ "type": "array"
919
+ },
920
+ "routes": {
921
+ "additionalProperties": {
922
+ "type": "string"
923
+ },
924
+ "type": "object"
925
+ },
926
+ "schema_version": {
927
+ "const": "openwrite.model-profile.v1"
928
+ }
929
+ },
930
+ "required": [
931
+ "schema_version",
932
+ "profiles",
933
+ "routes",
934
+ "default_profile_id",
935
+ "embedding_profiles",
936
+ "active_embedding_profile_id"
937
+ ],
938
+ "title": "OpenWrite independent chat and embedding model surface v1",
939
+ "type": "object"
940
+ },
941
+ "research_surface_v1": {
942
+ "$id": "https://openwrite.dev/schemas/research-surface-v1.schema.json",
943
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
944
+ "additionalProperties": true,
945
+ "disallowed": [
946
+ "api_key",
947
+ "credential",
948
+ "secret"
949
+ ],
950
+ "properties": {
951
+ "available": {
952
+ "type": "boolean"
953
+ },
954
+ "dependencies_ready": {
955
+ "type": "boolean"
956
+ },
957
+ "model_route": {
958
+ "additionalProperties": true,
959
+ "disallowed": [
960
+ "api_key",
961
+ "credential",
962
+ "secret"
963
+ ],
964
+ "properties": {
965
+ "compatible": {
966
+ "type": "boolean"
967
+ },
968
+ "configured": {
969
+ "type": "boolean"
970
+ },
971
+ "label": {
972
+ "type": "string"
973
+ },
974
+ "model": {
975
+ "type": "string"
976
+ },
977
+ "profile_id": {
978
+ "type": "string"
979
+ },
980
+ "provider": {
981
+ "type": "string"
982
+ }
983
+ },
984
+ "required": [
985
+ "profile_id",
986
+ "label",
987
+ "model",
988
+ "provider",
989
+ "configured",
990
+ "compatible"
991
+ ],
992
+ "type": "object"
993
+ },
994
+ "node_ready": {
995
+ "type": "boolean"
996
+ },
997
+ "package_ready": {
998
+ "type": "boolean"
999
+ },
1000
+ "pnpm_ready": {
1001
+ "type": "boolean"
1002
+ },
1003
+ "reports": {
1004
+ "items": {
1005
+ "additionalProperties": true,
1006
+ "disallowed": [
1007
+ "api_key",
1008
+ "credential",
1009
+ "secret"
1010
+ ],
1011
+ "properties": {
1012
+ "bytes": {
1013
+ "minimum": 0,
1014
+ "type": "integer"
1015
+ },
1016
+ "completed_at": {
1017
+ "type": [
1018
+ "string",
1019
+ "null"
1020
+ ]
1021
+ },
1022
+ "cost_usd": {
1023
+ "additionalProperties": true,
1024
+ "properties": {
1025
+ "reported": {
1026
+ "type": "boolean"
1027
+ },
1028
+ "value": {
1029
+ "minimum": 0,
1030
+ "type": [
1031
+ "number",
1032
+ "null"
1033
+ ]
1034
+ }
1035
+ },
1036
+ "required": [
1037
+ "value",
1038
+ "reported"
1039
+ ],
1040
+ "type": "object"
1041
+ },
1042
+ "created_at": {
1043
+ "type": [
1044
+ "string",
1045
+ "null"
1046
+ ]
1047
+ },
1048
+ "episode_id": {
1049
+ "type": [
1050
+ "string",
1051
+ "null"
1052
+ ]
1053
+ },
1054
+ "failure": {
1055
+ "additionalProperties": true,
1056
+ "disallowed": [
1057
+ "api_key",
1058
+ "credential",
1059
+ "secret"
1060
+ ],
1061
+ "properties": {
1062
+ "code": {
1063
+ "minLength": 1,
1064
+ "type": "string"
1065
+ },
1066
+ "message": {
1067
+ "type": "string"
1068
+ }
1069
+ },
1070
+ "required": [
1071
+ "code",
1072
+ "message"
1073
+ ],
1074
+ "type": [
1075
+ "object",
1076
+ "null"
1077
+ ]
1078
+ },
1079
+ "id": {
1080
+ "minLength": 1,
1081
+ "type": "string"
1082
+ },
1083
+ "latency_ms": {
1084
+ "minimum": 0,
1085
+ "type": [
1086
+ "integer",
1087
+ "null"
1088
+ ]
1089
+ },
1090
+ "metrics": {
1091
+ "type": "object"
1092
+ },
1093
+ "model_profile": {
1094
+ "additionalProperties": true,
1095
+ "disallowed": [
1096
+ "api_key",
1097
+ "credential",
1098
+ "secret"
1099
+ ],
1100
+ "properties": {
1101
+ "id": {
1102
+ "type": [
1103
+ "string",
1104
+ "null"
1105
+ ]
1106
+ },
1107
+ "label": {
1108
+ "type": [
1109
+ "string",
1110
+ "null"
1111
+ ]
1112
+ },
1113
+ "model": {
1114
+ "type": [
1115
+ "string",
1116
+ "null"
1117
+ ]
1118
+ },
1119
+ "provider": {
1120
+ "type": [
1121
+ "string",
1122
+ "null"
1123
+ ]
1124
+ }
1125
+ },
1126
+ "required": [
1127
+ "id",
1128
+ "label",
1129
+ "model",
1130
+ "provider"
1131
+ ],
1132
+ "type": [
1133
+ "object",
1134
+ "null"
1135
+ ]
1136
+ },
1137
+ "path": {
1138
+ "minLength": 1,
1139
+ "type": "string"
1140
+ },
1141
+ "search_provider": {
1142
+ "type": [
1143
+ "string",
1144
+ "null"
1145
+ ]
1146
+ },
1147
+ "source_count": {
1148
+ "minimum": 0,
1149
+ "type": [
1150
+ "integer",
1151
+ "null"
1152
+ ]
1153
+ },
1154
+ "sources": {
1155
+ "items": {
1156
+ "additionalProperties": true,
1157
+ "properties": {
1158
+ "cited": {
1159
+ "type": "boolean"
1160
+ },
1161
+ "source_type": {
1162
+ "type": "string"
1163
+ },
1164
+ "title": {
1165
+ "type": "string"
1166
+ },
1167
+ "url": {
1168
+ "type": "string"
1169
+ }
1170
+ },
1171
+ "required": [
1172
+ "title",
1173
+ "url",
1174
+ "source_type",
1175
+ "cited"
1176
+ ],
1177
+ "type": "object"
1178
+ },
1179
+ "type": [
1180
+ "array",
1181
+ "null"
1182
+ ]
1183
+ },
1184
+ "sources_status": {
1185
+ "enum": [
1186
+ "ok",
1187
+ "unavailable"
1188
+ ]
1189
+ },
1190
+ "status": {
1191
+ "enum": [
1192
+ "succeeded",
1193
+ "failed",
1194
+ "needs_human_review",
1195
+ "unknown"
1196
+ ]
1197
+ },
1198
+ "task_id": {
1199
+ "type": [
1200
+ "string",
1201
+ "null"
1202
+ ]
1203
+ },
1204
+ "title": {
1205
+ "type": "string"
1206
+ },
1207
+ "usage": {
1208
+ "additionalProperties": true,
1209
+ "properties": {
1210
+ "reported": {
1211
+ "type": "boolean"
1212
+ },
1213
+ "total_tokens": {
1214
+ "minimum": 0,
1215
+ "type": [
1216
+ "integer",
1217
+ "null"
1218
+ ]
1219
+ }
1220
+ },
1221
+ "required": [
1222
+ "total_tokens",
1223
+ "reported"
1224
+ ],
1225
+ "type": "object"
1226
+ },
1227
+ "word_count": {
1228
+ "minimum": 0,
1229
+ "type": [
1230
+ "integer",
1231
+ "null"
1232
+ ]
1233
+ }
1234
+ },
1235
+ "required": [
1236
+ "id",
1237
+ "title",
1238
+ "status",
1239
+ "episode_id",
1240
+ "task_id",
1241
+ "created_at",
1242
+ "completed_at",
1243
+ "model_profile",
1244
+ "search_provider",
1245
+ "sources",
1246
+ "sources_status",
1247
+ "source_count",
1248
+ "word_count",
1249
+ "latency_ms",
1250
+ "usage",
1251
+ "cost_usd",
1252
+ "failure",
1253
+ "metrics",
1254
+ "path",
1255
+ "bytes"
1256
+ ],
1257
+ "type": "object"
1258
+ },
1259
+ "type": "array"
1260
+ },
1261
+ "schema_version": {
1262
+ "const": "openwrite.research-surface.v1"
1263
+ },
1264
+ "settings": {
1265
+ "additionalProperties": true,
1266
+ "disallowed": [
1267
+ "api_key",
1268
+ "credential",
1269
+ "secret"
1270
+ ],
1271
+ "properties": {
1272
+ "search_provider": {
1273
+ "enum": [
1274
+ "bocha",
1275
+ "bing",
1276
+ "jina",
1277
+ "none"
1278
+ ]
1279
+ },
1280
+ "search_providers": {
1281
+ "items": {
1282
+ "additionalProperties": true,
1283
+ "disallowed": [
1284
+ "api_key",
1285
+ "credential",
1286
+ "secret"
1287
+ ],
1288
+ "properties": {
1289
+ "configured": {
1290
+ "type": "boolean"
1291
+ },
1292
+ "credential_configured": {
1293
+ "type": "boolean"
1294
+ },
1295
+ "id": {
1296
+ "enum": [
1297
+ "bocha",
1298
+ "bing",
1299
+ "jina",
1300
+ "none"
1301
+ ]
1302
+ },
1303
+ "label": {
1304
+ "minLength": 1,
1305
+ "type": "string"
1306
+ },
1307
+ "requires_api_key": {
1308
+ "type": "boolean"
1309
+ }
1310
+ },
1311
+ "required": [
1312
+ "id",
1313
+ "label",
1314
+ "requires_api_key",
1315
+ "configured",
1316
+ "credential_configured"
1317
+ ],
1318
+ "type": "object"
1319
+ },
1320
+ "type": "array"
1321
+ }
1322
+ },
1323
+ "required": [
1324
+ "search_provider",
1325
+ "search_providers"
1326
+ ],
1327
+ "type": "object"
1328
+ },
1329
+ "setup_hint": {
1330
+ "type": "string"
1331
+ }
1332
+ },
1333
+ "required": [
1334
+ "schema_version",
1335
+ "available",
1336
+ "node_ready",
1337
+ "pnpm_ready",
1338
+ "package_ready",
1339
+ "dependencies_ready",
1340
+ "setup_hint",
1341
+ "settings",
1342
+ "reports",
1343
+ "model_route"
1344
+ ],
1345
+ "title": "OpenWrite research surface v1 (credential-free)",
1346
+ "type": "object"
1347
+ },
1348
+ "review_manifest_v2": {
1349
+ "$id": "https://openwrite.dev/schemas/review-manifest-v2.schema.json",
1350
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
1351
+ "additionalProperties": true,
1352
+ "properties": {
1353
+ "chapterId": {
1354
+ "pattern": "^ch_\\d+$",
1355
+ "type": "string"
1356
+ },
1357
+ "coverage": {
1358
+ "maximum": 1,
1359
+ "minimum": 0,
1360
+ "type": "number"
1361
+ },
1362
+ "decisionSource": {
1363
+ "enum": [
1364
+ "v2",
1365
+ "v1-adapter"
1366
+ ]
1367
+ },
1368
+ "qualityScore": {
1369
+ "maximum": 100,
1370
+ "minimum": 0,
1371
+ "type": [
1372
+ "number",
1373
+ "null"
1374
+ ]
1375
+ },
1376
+ "recordType": {
1377
+ "const": "review"
1378
+ },
1379
+ "schemaVersion": {
1380
+ "const": "dsh-novel.review.manifest.v2"
1381
+ },
1382
+ "threshold": {
1383
+ "maximum": 100,
1384
+ "minimum": 0,
1385
+ "type": "integer"
1386
+ },
1387
+ "verdict": {
1388
+ "enum": [
1389
+ "pass",
1390
+ "fail",
1391
+ "inconclusive"
1392
+ ]
1393
+ }
1394
+ },
1395
+ "required": [
1396
+ "schemaVersion",
1397
+ "recordType",
1398
+ "chapterId",
1399
+ "verdict"
1400
+ ],
1401
+ "title": "dsh-novel review manifest v2",
1402
+ "type": "object"
1403
+ },
1404
+ "review_v2_decision": {
1405
+ "$id": "https://openwrite.dev/schemas/review-v2-decision.schema.json",
1406
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
1407
+ "additionalProperties": true,
1408
+ "properties": {
1409
+ "coverage": {
1410
+ "maximum": 1,
1411
+ "minimum": 0,
1412
+ "type": "number"
1413
+ },
1414
+ "delivery_status": {
1415
+ "enum": [
1416
+ "pass",
1417
+ "revise",
1418
+ "blocked",
1419
+ "inconclusive",
1420
+ "stale"
1421
+ ]
1422
+ },
1423
+ "execution_status": {
1424
+ "enum": [
1425
+ "completed",
1426
+ "partial",
1427
+ "failed"
1428
+ ]
1429
+ },
1430
+ "gate_status": {
1431
+ "enum": [
1432
+ "pass",
1433
+ "blocked",
1434
+ "inconclusive"
1435
+ ]
1436
+ },
1437
+ "production_gate_status": {
1438
+ "enum": [
1439
+ "pass",
1440
+ "revise",
1441
+ "blocked",
1442
+ "inconclusive",
1443
+ "stale",
1444
+ "disabled",
1445
+ "disabled_uncalibrated"
1446
+ ]
1447
+ },
1448
+ "quality_score": {
1449
+ "maximum": 100,
1450
+ "minimum": 0,
1451
+ "type": [
1452
+ "number",
1453
+ "null"
1454
+ ]
1455
+ },
1456
+ "schema_version": {
1457
+ "const": "openwrite.review.v2"
1458
+ }
1459
+ },
1460
+ "required": [
1461
+ "schema_version",
1462
+ "execution_status",
1463
+ "quality_score",
1464
+ "coverage",
1465
+ "gate_status",
1466
+ "delivery_status",
1467
+ "production_gate_status"
1468
+ ],
1469
+ "title": "OpenWrite review v2 decision",
1470
+ "type": "object"
1471
+ },
1472
+ "task_surface_v1": {
1473
+ "$id": "https://openwrite.dev/schemas/task-surface-v1.schema.json",
1474
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
1475
+ "additionalProperties": true,
1476
+ "properties": {
1477
+ "counts": {
1478
+ "type": "object"
1479
+ },
1480
+ "phase_order": {
1481
+ "items": {
1482
+ "enum": [
1483
+ "queued",
1484
+ "reading",
1485
+ "preparing",
1486
+ "model",
1487
+ "validating",
1488
+ "committing",
1489
+ "complete"
1490
+ ]
1491
+ },
1492
+ "type": "array"
1493
+ },
1494
+ "schema_version": {
1495
+ "const": "openwrite.task-surface.v1"
1496
+ },
1497
+ "tasks": {
1498
+ "items": {
1499
+ "additionalProperties": true,
1500
+ "disallowed": [
1501
+ "api_key",
1502
+ "credential",
1503
+ "secret"
1504
+ ],
1505
+ "properties": {
1506
+ "attempt": {
1507
+ "minimum": 1,
1508
+ "type": "integer"
1509
+ },
1510
+ "chapter_id": {
1511
+ "type": [
1512
+ "string",
1513
+ "null"
1514
+ ]
1515
+ },
1516
+ "completed_at": {
1517
+ "type": [
1518
+ "string",
1519
+ "null"
1520
+ ]
1521
+ },
1522
+ "created_at": {
1523
+ "type": [
1524
+ "string",
1525
+ "null"
1526
+ ]
1527
+ },
1528
+ "error": {
1529
+ "additionalProperties": true,
1530
+ "properties": {
1531
+ "code": {
1532
+ "minLength": 1,
1533
+ "type": "string"
1534
+ },
1535
+ "failed_stage": {
1536
+ "type": [
1537
+ "string",
1538
+ "null"
1539
+ ]
1540
+ },
1541
+ "message": {
1542
+ "type": "string"
1543
+ },
1544
+ "recoverable": {
1545
+ "type": "boolean"
1546
+ }
1547
+ },
1548
+ "required": [
1549
+ "code",
1550
+ "message",
1551
+ "recoverable"
1552
+ ],
1553
+ "type": [
1554
+ "object",
1555
+ "null"
1556
+ ]
1557
+ },
1558
+ "input_summary": {
1559
+ "type": [
1560
+ "string",
1561
+ "null"
1562
+ ]
1563
+ },
1564
+ "phase": {
1565
+ "enum": [
1566
+ "queued",
1567
+ "reading",
1568
+ "preparing",
1569
+ "model",
1570
+ "validating",
1571
+ "committing",
1572
+ "complete",
1573
+ null
1574
+ ]
1575
+ },
1576
+ "phase_index": {
1577
+ "type": [
1578
+ "integer",
1579
+ "null"
1580
+ ]
1581
+ },
1582
+ "progress": {
1583
+ "additionalProperties": true,
1584
+ "properties": {
1585
+ "completed_units": {
1586
+ "minimum": 0,
1587
+ "type": "integer"
1588
+ },
1589
+ "ratio": {
1590
+ "maximum": 1,
1591
+ "minimum": 0,
1592
+ "type": [
1593
+ "number",
1594
+ "null"
1595
+ ]
1596
+ },
1597
+ "total_units": {
1598
+ "minimum": 0,
1599
+ "type": "integer"
1600
+ },
1601
+ "unit_kind": {
1602
+ "enum": [
1603
+ "candidates",
1604
+ "evaluations",
1605
+ "chapters",
1606
+ "files"
1607
+ ]
1608
+ }
1609
+ },
1610
+ "required": [
1611
+ "completed_units",
1612
+ "total_units",
1613
+ "ratio",
1614
+ "unit_kind"
1615
+ ],
1616
+ "type": [
1617
+ "object",
1618
+ "null"
1619
+ ]
1620
+ },
1621
+ "result_ref": {
1622
+ "additionalProperties": true,
1623
+ "properties": {
1624
+ "id": {
1625
+ "minLength": 1,
1626
+ "type": "string"
1627
+ },
1628
+ "type": {
1629
+ "enum": [
1630
+ "chapter",
1631
+ "review",
1632
+ "revision",
1633
+ "research_report",
1634
+ "benchmark_run",
1635
+ "import",
1636
+ "archive"
1637
+ ]
1638
+ }
1639
+ },
1640
+ "required": [
1641
+ "type",
1642
+ "id"
1643
+ ],
1644
+ "type": [
1645
+ "object",
1646
+ "null"
1647
+ ]
1648
+ },
1649
+ "retryable": {
1650
+ "type": "boolean"
1651
+ },
1652
+ "schema_version": {
1653
+ "minLength": 1,
1654
+ "type": "string"
1655
+ },
1656
+ "started_at": {
1657
+ "type": [
1658
+ "string",
1659
+ "null"
1660
+ ]
1661
+ },
1662
+ "status": {
1663
+ "enum": [
1664
+ "pending",
1665
+ "running",
1666
+ "awaiting_confirmation",
1667
+ "completed",
1668
+ "failed",
1669
+ "cancelled",
1670
+ "interrupted"
1671
+ ]
1672
+ },
1673
+ "task_id": {
1674
+ "minLength": 1,
1675
+ "type": "string"
1676
+ },
1677
+ "type": {
1678
+ "minLength": 1,
1679
+ "type": "string"
1680
+ },
1681
+ "updated_at": {
1682
+ "type": [
1683
+ "string",
1684
+ "null"
1685
+ ]
1686
+ }
1687
+ },
1688
+ "required": [
1689
+ "task_id",
1690
+ "type",
1691
+ "status",
1692
+ "phase",
1693
+ "phase_index",
1694
+ "progress",
1695
+ "attempt",
1696
+ "retryable",
1697
+ "created_at",
1698
+ "updated_at",
1699
+ "started_at",
1700
+ "completed_at",
1701
+ "error",
1702
+ "result_ref",
1703
+ "input_summary",
1704
+ "chapter_id",
1705
+ "schema_version"
1706
+ ],
1707
+ "type": "object"
1708
+ },
1709
+ "type": "array"
1710
+ }
1711
+ },
1712
+ "required": [
1713
+ "schema_version",
1714
+ "phase_order",
1715
+ "tasks",
1716
+ "counts"
1717
+ ],
1718
+ "title": "OpenWrite task surface v1 (credential-free)",
1719
+ "type": "object"
1720
+ }
1721
+ };
1722
+ function validateContract(value, key, label) {
1723
+ const errors = validateSchema(value, SCHEMAS[key]);
1724
+ if (errors.length > 0) {
1725
+ throw new Error(`CONTRACT_INVALID: ${label} violates ${key}: ${errors.join('; ')}`);
1726
+ }
1727
+ return value;
1728
+ }
1729
+ /** Validate `value` against the review_v2_decision schema; throw on failure. */
1730
+ export function validateReviewV2Decision(value) {
1731
+ return validateContract(value, 'review_v2_decision', 'review_v2');
1732
+ }
1733
+ /** Validate `value` against the review_manifest_v2 schema; throw on failure. */
1734
+ export function validateReviewManifestV2(value) {
1735
+ return validateContract(value, 'review_manifest_v2', 'review manifest');
1736
+ }
1737
+ /** Validate `value` against the delivery_manifest_v2 schema; throw on failure. */
1738
+ export function validateDeliveryManifestV2(value) {
1739
+ return validateContract(value, 'delivery_manifest_v2', 'delivery manifest');
1740
+ }
1741
+ /** Validate `value` against the delivery_stage_v2 schema; throw on failure. */
1742
+ export function validateDeliveryStageV2(value) {
1743
+ return validateContract(value, 'delivery_stage_v2', 'delivery stage');
1744
+ }
1745
+ /** Validate `value` against the model_benchmark_v1 schema; throw on failure. */
1746
+ export function validateModelBenchmarkV1(value) {
1747
+ return validateContract(value, 'model_benchmark_v1', 'benchmark');
1748
+ }
1749
+ /** Validate `value` against the model_profile_surface_v1 schema; throw on failure. */
1750
+ export function validateModelProfileSurfaceV1(value) {
1751
+ return validateContract(value, 'model_profile_surface_v1', 'model profile surface');
1752
+ }
1753
+ /** Validate `value` against the task_surface_v1 schema; throw on failure. */
1754
+ export function validateTaskSurfaceV1(value) {
1755
+ return validateContract(value, 'task_surface_v1', 'task surface');
1756
+ }
1757
+ /** Validate `value` against the research_surface_v1 schema; throw on failure. */
1758
+ export function validateResearchSurfaceV1(value) {
1759
+ return validateContract(value, 'research_surface_v1', 'research surface');
1760
+ }
1761
+ /** Validate `value` against the model_connection_test_v1 schema; throw on failure. */
1762
+ export function validateModelConnectionTestV1(value) {
1763
+ return validateContract(value, 'model_connection_test_v1', 'model connection test');
1764
+ }