@inflexa-ai/harness 0.17.0 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (221) hide show
  1. package/dist/agents/report-builder.d.ts +2 -0
  2. package/dist/agents/report-builder.js +2 -0
  3. package/dist/app/spawn-report-session.d.ts +85 -0
  4. package/dist/app/spawn-report-session.js +83 -0
  5. package/dist/contracts/chat-events.d.ts +9 -0
  6. package/dist/contracts/index.d.ts +6 -2
  7. package/dist/contracts/index.js +3 -1
  8. package/dist/contracts/organ-system.d.ts +49 -0
  9. package/dist/contracts/organ-system.js +67 -0
  10. package/dist/contracts/report-blocks.d.ts +564 -0
  11. package/dist/contracts/report-blocks.js +117 -0
  12. package/dist/contracts/report-reference.d.ts +459 -0
  13. package/dist/contracts/report-reference.js +256 -0
  14. package/dist/contracts/schemas/chat-events.d.ts +2 -0
  15. package/dist/contracts/schemas/chat-events.js +2 -0
  16. package/dist/contracts/severity.d.ts +15 -0
  17. package/dist/contracts/severity.js +10 -0
  18. package/dist/contracts/target-dossier.d.ts +8675 -12972
  19. package/dist/contracts/target-dossier.js +534 -591
  20. package/dist/data/safety-panel-schema.d.ts +18 -5
  21. package/dist/data/safety-panel-schema.js +4 -4
  22. package/dist/execution/artifact-metadata.js +1 -0
  23. package/dist/execution/report-runner.js +1 -3
  24. package/dist/execution/run-synthesis.js +2 -0
  25. package/dist/index.d.ts +6 -0
  26. package/dist/index.js +19 -0
  27. package/dist/lib/async-utils.d.ts +16 -4
  28. package/dist/lib/async-utils.js +20 -15
  29. package/dist/lib/host-concurrency.js +1 -0
  30. package/dist/loop/__fixtures__/scripted-provider.js +23 -2
  31. package/dist/loop/run-agent.js +58 -10
  32. package/dist/loop/tool-detail.d.ts +40 -0
  33. package/dist/loop/tool-detail.js +35 -3
  34. package/dist/loop/types.d.ts +13 -0
  35. package/dist/memory/thread-history.d.ts +10 -0
  36. package/dist/memory/thread-history.js +12 -1
  37. package/dist/prompts/target-assessment/briefs/executive-recommendation.d.ts +1 -1
  38. package/dist/prompts/target-assessment/briefs/executive-recommendation.js +5 -5
  39. package/dist/prompts/target-assessment/briefs/liability-bullets.d.ts +1 -1
  40. package/dist/prompts/target-assessment/briefs/liability-bullets.js +1 -1
  41. package/dist/prompts/target-assessment/briefs/target-organ-liabilities.d.ts +1 -1
  42. package/dist/prompts/target-assessment/briefs/target-organ-liabilities.js +11 -3
  43. package/dist/prompts/target-assessment/investigation/adversarial-critique.d.ts +1 -0
  44. package/dist/prompts/target-assessment/investigation/adversarial-critique.js +67 -0
  45. package/dist/prompts/target-assessment/investigation/claim-reverification.d.ts +1 -0
  46. package/dist/prompts/target-assessment/investigation/claim-reverification.js +49 -0
  47. package/dist/prompts/target-assessment/investigation/index.d.ts +3 -0
  48. package/dist/prompts/target-assessment/investigation/index.js +3 -0
  49. package/dist/prompts/target-assessment/investigation/mechanism-proposal.d.ts +1 -0
  50. package/dist/prompts/target-assessment/investigation/mechanism-proposal.js +49 -0
  51. package/dist/prompts/target-assessment/tox-voice/index.d.ts +1 -1
  52. package/dist/prompts/target-assessment/tox-voice/vocabulary.d.ts +8 -5
  53. package/dist/prompts/target-assessment/tox-voice/vocabulary.js +9 -20
  54. package/dist/providers/__fixtures__/session.d.ts +5 -4
  55. package/dist/providers/__fixtures__/session.js +4 -4
  56. package/dist/report-model/block-walk.d.ts +56 -0
  57. package/dist/report-model/block-walk.js +89 -0
  58. package/dist/report-model/draft-finish.d.ts +60 -0
  59. package/dist/report-model/draft-finish.js +56 -0
  60. package/dist/report-model/draft-operations.d.ts +125 -0
  61. package/dist/report-model/draft-operations.js +341 -0
  62. package/dist/report-model/draft-read.d.ts +59 -0
  63. package/dist/report-model/draft-read.js +109 -0
  64. package/dist/report-model/draft.d.ts +51 -0
  65. package/dist/report-model/draft.js +32 -0
  66. package/dist/report-model/fixture-resolver.d.ts +8 -0
  67. package/dist/report-model/fixture-resolver.js +252 -0
  68. package/dist/report-model/mint-snapshot.d.ts +30 -0
  69. package/dist/report-model/mint-snapshot.js +40 -0
  70. package/dist/report-model/reference-resolver.d.ts +113 -0
  71. package/dist/report-model/reference-resolver.js +60 -0
  72. package/dist/report-model/structural-validation.d.ts +22 -0
  73. package/dist/report-model/structural-validation.js +68 -0
  74. package/dist/report-model/validate.d.ts +40 -0
  75. package/dist/report-model/validate.js +80 -0
  76. package/dist/report-render/chart.d.ts +33 -0
  77. package/dist/report-render/chart.js +538 -0
  78. package/dist/report-render/page.d.ts +127 -0
  79. package/dist/report-render/page.js +307 -0
  80. package/dist/report-render/references.d.ts +32 -0
  81. package/dist/report-render/references.js +44 -0
  82. package/dist/report-render/render.d.ts +25 -0
  83. package/dist/report-render/render.js +125 -0
  84. package/dist/report-render/script-json.d.ts +13 -0
  85. package/dist/report-render/script-json.js +15 -0
  86. package/dist/report-render/types.d.ts +39 -0
  87. package/dist/report-render/types.js +10 -0
  88. package/dist/report-render/views/chart-view.d.ts +11 -0
  89. package/dist/report-render/views/chart-view.js +23 -0
  90. package/dist/report-render/views/page-view.d.ts +20 -0
  91. package/dist/report-render/views/page-view.js +49 -0
  92. package/dist/report-render/views/prose.d.ts +28 -0
  93. package/dist/report-render/views/prose.js +75 -0
  94. package/dist/report-render/views/references-view.d.ts +20 -0
  95. package/dist/report-render/views/references-view.js +64 -0
  96. package/dist/report-render/views/values.d.ts +42 -0
  97. package/dist/report-render/views/values.js +43 -0
  98. package/dist/runtime/boot.d.ts +3 -3
  99. package/dist/runtime/boot.js +15 -4
  100. package/dist/runtime/dbos.d.ts +4 -4
  101. package/dist/state/artifacts.d.ts +16 -0
  102. package/dist/state/artifacts.js +18 -0
  103. package/dist/state/init.js +31 -0
  104. package/dist/state/purge-analysis.js +1 -0
  105. package/dist/state/report-versions.d.ts +132 -0
  106. package/dist/state/report-versions.js +194 -0
  107. package/dist/tasks/data-profile.js +1 -0
  108. package/dist/tools/bio/chembl.js +1 -0
  109. package/dist/tools/bio/comptox.js +1 -0
  110. package/dist/tools/bio/drug-gene-interactions.js +1 -0
  111. package/dist/tools/bio/gene-disease-evidence.js +1 -0
  112. package/dist/tools/bio/gene-preclinical-profile.js +1 -0
  113. package/dist/tools/bio/keys.d.ts +3 -2
  114. package/dist/tools/bio/keys.js +3 -2
  115. package/dist/tools/bio/lookup-annotation.js +1 -0
  116. package/dist/tools/bio/opentargets.d.ts +3 -3
  117. package/dist/tools/bio/opentargets.js +4 -3
  118. package/dist/tools/bio/pubchem.js +1 -0
  119. package/dist/tools/bio/search-clinical-trials.js +1 -0
  120. package/dist/tools/bio/search-faers.js +1 -0
  121. package/dist/tools/bio/search-geo-datasets.js +1 -0
  122. package/dist/tools/bio/search-interactions.js +1 -0
  123. package/dist/tools/bio/target-safety.d.ts +4 -6
  124. package/dist/tools/bio/target-safety.js +7 -6
  125. package/dist/tools/define-tool.d.ts +19 -12
  126. package/dist/tools/define-tool.js +4 -2
  127. package/dist/tools/display/show-user.js +1 -0
  128. package/dist/tools/iterate-report.js +2 -0
  129. package/dist/tools/lib/chembl-client.d.ts +2 -0
  130. package/dist/tools/lib/chembl-client.js +1 -0
  131. package/dist/tools/lib/monarch-client.d.ts +42 -0
  132. package/dist/tools/lib/monarch-client.js +100 -0
  133. package/dist/tools/report/build-report.js +1 -0
  134. package/dist/tools/report/mint-preview-url.js +1 -0
  135. package/dist/tools/report/preview-snapshot.js +1 -0
  136. package/dist/tools/report/submit-report.js +1 -0
  137. package/dist/tools/report/version-fs.js +4 -0
  138. package/dist/tools/report-authoring/authoring-tools.d.ts +134 -0
  139. package/dist/tools/report-authoring/authoring-tools.js +352 -0
  140. package/dist/tools/research/context7-docs.js +2 -0
  141. package/dist/tools/research/generate-analogy-report.js +1 -0
  142. package/dist/tools/research/generate-plan.js +3 -0
  143. package/dist/tools/research/inspect-data-profile.js +4 -0
  144. package/dist/tools/research/literature-reviewer.js +1 -0
  145. package/dist/tools/research/search-arxiv.js +1 -0
  146. package/dist/tools/research/search-github-repos.js +1 -0
  147. package/dist/tools/research/search-semantic-scholar.js +1 -0
  148. package/dist/tools/sandbox/list-available-packages.js +23 -0
  149. package/dist/tools/sandbox/list-available-refs.js +36 -0
  150. package/dist/tools/sandbox/report-blocker.js +1 -0
  151. package/dist/tools/sandbox/skills.js +2 -0
  152. package/dist/tools/workspace/file-stat.js +1 -0
  153. package/dist/tools/workspace/show-file.js +2 -0
  154. package/dist/tools/workspace/show-plan.js +1 -0
  155. package/dist/workflows/execute-analysis.d.ts +5 -1
  156. package/dist/workflows/execute-analysis.js +5 -5
  157. package/dist/workflows/execute-target-assessment.d.ts +13 -2
  158. package/dist/workflows/execute-target-assessment.js +78 -16
  159. package/dist/workflows/target-assessment/assemblers/index.d.ts +1 -1
  160. package/dist/workflows/target-assessment/assemblers/index.js +1 -1
  161. package/dist/workflows/target-assessment/assemblers/literature.d.ts +9 -27
  162. package/dist/workflows/target-assessment/assemblers/literature.js +32 -48
  163. package/dist/workflows/target-assessment/assemblers/orchestrator.d.ts +17 -9
  164. package/dist/workflows/target-assessment/assemblers/orchestrator.js +195 -85
  165. package/dist/workflows/target-assessment/assemblers/safety.d.ts +70 -48
  166. package/dist/workflows/target-assessment/assemblers/safety.js +125 -42
  167. package/dist/workflows/target-assessment/collectors/index.d.ts +5 -2
  168. package/dist/workflows/target-assessment/collectors/index.js +48 -5
  169. package/dist/workflows/target-assessment/coverage.d.ts +43 -27
  170. package/dist/workflows/target-assessment/coverage.js +33 -29
  171. package/dist/workflows/target-assessment/fanout/index.js +1 -0
  172. package/dist/workflows/target-assessment/investigation/index.d.ts +97 -0
  173. package/dist/workflows/target-assessment/investigation/index.js +419 -0
  174. package/dist/workflows/target-assessment/lib/approval-precedents.d.ts +26 -5
  175. package/dist/workflows/target-assessment/lib/approval-precedents.js +95 -29
  176. package/dist/workflows/target-assessment/lib/citation-validator.js +1 -1
  177. package/dist/workflows/target-assessment/lib/clinical-consequence-annotator.d.ts +2 -2
  178. package/dist/workflows/target-assessment/lib/clinical-evidence-attribution.d.ts +2 -3
  179. package/dist/workflows/target-assessment/lib/clinical-evidence-attribution.js +0 -4
  180. package/dist/workflows/target-assessment/lib/compute-derived.d.ts +6 -5
  181. package/dist/workflows/target-assessment/lib/compute-derived.js +14 -5
  182. package/dist/workflows/target-assessment/lib/family-complex-supplement.d.ts +5 -6
  183. package/dist/workflows/target-assessment/lib/family-complex-supplement.js +2 -3
  184. package/dist/workflows/target-assessment/lib/fda-label-safety.d.ts +72 -0
  185. package/dist/workflows/target-assessment/lib/fda-label-safety.js +166 -0
  186. package/dist/workflows/target-assessment/lib/heterodimer-filter.d.ts +0 -9
  187. package/dist/workflows/target-assessment/lib/heterodimer-filter.js +0 -10
  188. package/dist/workflows/target-assessment/lib/hpo-organ-map.d.ts +34 -0
  189. package/dist/workflows/target-assessment/lib/hpo-organ-map.js +63 -0
  190. package/dist/workflows/target-assessment/lib/impc-organ-map.d.ts +19 -0
  191. package/dist/workflows/target-assessment/lib/impc-organ-map.js +39 -0
  192. package/dist/workflows/target-assessment/lib/meddra-organ-map.d.ts +24 -14
  193. package/dist/workflows/target-assessment/lib/meddra-organ-map.js +59 -47
  194. package/dist/workflows/target-assessment/lib/recommendation-sanitizer.js +1 -1
  195. package/dist/workflows/target-assessment/lib/regulatory-actions.d.ts +2 -3
  196. package/dist/workflows/target-assessment/lib/regulatory-actions.js +33 -4
  197. package/dist/workflows/target-assessment/lib/safety-corroboration.d.ts +44 -0
  198. package/dist/workflows/target-assessment/lib/safety-corroboration.js +273 -0
  199. package/dist/workflows/target-assessment/lib/target-identity-filter.d.ts +5 -7
  200. package/dist/workflows/target-assessment/lib/target-identity-filter.js +5 -7
  201. package/dist/workflows/target-assessment/metrics.d.ts +1 -6
  202. package/dist/workflows/target-assessment/metrics.js +1 -13
  203. package/dist/workflows/target-assessment/phase4-assemble.d.ts +2147 -807
  204. package/dist/workflows/target-assessment/phase4-assemble.js +19 -19
  205. package/dist/workflows/target-assessment/phase5-persist.d.ts +20 -21
  206. package/dist/workflows/target-assessment/phase5-persist.js +56 -173
  207. package/dist/workflows/target-assessment/schemas.d.ts +46 -1
  208. package/dist/workflows/target-assessment/schemas.js +19 -0
  209. package/dist/workflows/target-assessment/steps/fanout/polypharm-for-one-modulator-step.d.ts +1 -0
  210. package/dist/workflows/target-assessment/steps/fanout/polypharm-for-one-modulator-step.js +2 -0
  211. package/dist/workflows/target-assessment/steps/phase2-aggregate.d.ts +26 -62
  212. package/dist/workflows/target-assessment/steps/phase2-aggregate.js +0 -4
  213. package/dist/workflows/target-assessment/steps/phase3-aggregate.d.ts +27 -154
  214. package/dist/workflows/target-assessment/steps/phase3-aggregate.js +0 -6
  215. package/dist/workflows/target-assessment/steps/synthesis/diagnostics.d.ts +0 -6
  216. package/dist/workflows/target-assessment/steps/synthesis/diagnostics.js +0 -18
  217. package/dist/workflows/target-assessment/sub-workflows/per-modulator-polypharm.d.ts +1 -0
  218. package/dist/workflows/target-assessment/synthesis/index.d.ts +52 -5
  219. package/dist/workflows/target-assessment/synthesis/index.js +4 -1
  220. package/dist/workflows/target-assessment/synthesis-probes.d.ts +3 -3
  221. package/package.json +4 -1
@@ -0,0 +1,564 @@
1
+ /**
2
+ * The composable block tree of a report.
3
+ *
4
+ * A block is one of eight kinds. The shape of each kind carries its grammar. A `text` block has no
5
+ * binding field, thus an unbound claim is unrepresentable. A `metric` value slot admits one scalar
6
+ * reference only, thus a numeric literal cannot sit there. No atom holds a child-block array, thus a
7
+ * chart inside a metric is unrepresentable. The grammar is the shape, and not a separate pass.
8
+ *
9
+ * The tree is recursive: a `section` holds child blocks, and a child can be another section.
10
+ *
11
+ * Every object schema here and in the reference module is strict. A strict object makes an extra field
12
+ * a parse failure, and not a field that the parser strips in silence. Thus a forbidden field, such as a
13
+ * binding on a `text` block or a child-block array on an atom, is rejected. The absence of a field is a
14
+ * rule only when an extra field fails the parse.
15
+ */
16
+ import { z } from "zod";
17
+ /** Prose with no binding. The absence of a binding field is the rule for this kind. */
18
+ export declare const TextBlockSchema: z.ZodObject<{
19
+ kind: z.ZodLiteral<"text">;
20
+ id: z.ZodString;
21
+ content: z.ZodObject<{
22
+ prose: z.ZodString;
23
+ }, z.core.$strict>;
24
+ }, z.core.$strict>;
25
+ /** Prose with at least one reference that justifies it. */
26
+ export declare const ClaimBlockSchema: z.ZodObject<{
27
+ kind: z.ZodLiteral<"claim">;
28
+ id: z.ZodString;
29
+ content: z.ZodObject<{
30
+ prose: z.ZodString;
31
+ }, z.core.$strict>;
32
+ bindings: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
33
+ unit: z.ZodOptional<z.ZodString>;
34
+ format: z.ZodOptional<z.ZodString>;
35
+ locator: z.ZodObject<{
36
+ column: z.ZodString;
37
+ rowFilter: z.ZodOptional<z.ZodObject<{
38
+ column: z.ZodString;
39
+ op: z.ZodLiteral<"eq">;
40
+ value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
41
+ }, z.core.$strict>>;
42
+ row: z.ZodOptional<z.ZodNumber>;
43
+ }, z.core.$strict>;
44
+ assert: z.ZodOptional<z.ZodObject<{
45
+ value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
46
+ tolerance: z.ZodOptional<z.ZodNumber>;
47
+ }, z.core.$strict>>;
48
+ run: z.ZodOptional<z.ZodString>;
49
+ path: z.ZodString;
50
+ hash: z.ZodString;
51
+ snapshot: z.ZodOptional<z.ZodString>;
52
+ kind: z.ZodLiteral<"artifact-value">;
53
+ }, z.core.$strict>, z.ZodObject<{
54
+ unit: z.ZodOptional<z.ZodString>;
55
+ format: z.ZodOptional<z.ZodString>;
56
+ columns: z.ZodOptional<z.ZodArray<z.ZodString>>;
57
+ run: z.ZodOptional<z.ZodString>;
58
+ path: z.ZodString;
59
+ hash: z.ZodString;
60
+ snapshot: z.ZodOptional<z.ZodString>;
61
+ kind: z.ZodLiteral<"artifact-table">;
62
+ }, z.core.$strict>, z.ZodObject<{
63
+ unit: z.ZodOptional<z.ZodString>;
64
+ format: z.ZodOptional<z.ZodString>;
65
+ run: z.ZodOptional<z.ZodString>;
66
+ path: z.ZodString;
67
+ hash: z.ZodString;
68
+ snapshot: z.ZodOptional<z.ZodString>;
69
+ kind: z.ZodLiteral<"artifact-file">;
70
+ }, z.core.$strict>, z.ZodObject<{
71
+ unit: z.ZodOptional<z.ZodString>;
72
+ format: z.ZodOptional<z.ZodString>;
73
+ kind: z.ZodLiteral<"derivation">;
74
+ op: z.ZodEnum<{
75
+ ratio: "ratio";
76
+ delta: "delta";
77
+ pctChange: "pctChange";
78
+ }>;
79
+ inputs: z.ZodArray<z.ZodObject<{
80
+ unit: z.ZodOptional<z.ZodString>;
81
+ format: z.ZodOptional<z.ZodString>;
82
+ locator: z.ZodObject<{
83
+ column: z.ZodString;
84
+ rowFilter: z.ZodOptional<z.ZodObject<{
85
+ column: z.ZodString;
86
+ op: z.ZodLiteral<"eq">;
87
+ value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
88
+ }, z.core.$strict>>;
89
+ row: z.ZodOptional<z.ZodNumber>;
90
+ }, z.core.$strict>;
91
+ assert: z.ZodOptional<z.ZodObject<{
92
+ value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
93
+ tolerance: z.ZodOptional<z.ZodNumber>;
94
+ }, z.core.$strict>>;
95
+ run: z.ZodOptional<z.ZodString>;
96
+ path: z.ZodString;
97
+ hash: z.ZodString;
98
+ snapshot: z.ZodOptional<z.ZodString>;
99
+ kind: z.ZodLiteral<"artifact-value">;
100
+ }, z.core.$strict>>;
101
+ assert: z.ZodOptional<z.ZodObject<{
102
+ value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
103
+ tolerance: z.ZodOptional<z.ZodNumber>;
104
+ }, z.core.$strict>>;
105
+ }, z.core.$strict>, z.ZodObject<{
106
+ unit: z.ZodOptional<z.ZodString>;
107
+ format: z.ZodOptional<z.ZodString>;
108
+ kind: z.ZodLiteral<"citation">;
109
+ idKind: z.ZodEnum<{
110
+ doi: "doi";
111
+ pmid: "pmid";
112
+ arxiv: "arxiv";
113
+ }>;
114
+ id: z.ZodString;
115
+ raw: z.ZodString;
116
+ assert: z.ZodOptional<z.ZodObject<{
117
+ value: z.ZodString;
118
+ }, z.core.$strict>>;
119
+ }, z.core.$strict>], "kind">>;
120
+ }, z.core.$strict>;
121
+ /** A labeled number whose value comes from one scalar reference. */
122
+ export declare const MetricBlockSchema: z.ZodObject<{
123
+ kind: z.ZodLiteral<"metric">;
124
+ id: z.ZodString;
125
+ label: z.ZodString;
126
+ value: z.ZodDiscriminatedUnion<[z.ZodObject<{
127
+ unit: z.ZodOptional<z.ZodString>;
128
+ format: z.ZodOptional<z.ZodString>;
129
+ locator: z.ZodObject<{
130
+ column: z.ZodString;
131
+ rowFilter: z.ZodOptional<z.ZodObject<{
132
+ column: z.ZodString;
133
+ op: z.ZodLiteral<"eq">;
134
+ value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
135
+ }, z.core.$strict>>;
136
+ row: z.ZodOptional<z.ZodNumber>;
137
+ }, z.core.$strict>;
138
+ assert: z.ZodOptional<z.ZodObject<{
139
+ value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
140
+ tolerance: z.ZodOptional<z.ZodNumber>;
141
+ }, z.core.$strict>>;
142
+ run: z.ZodOptional<z.ZodString>;
143
+ path: z.ZodString;
144
+ hash: z.ZodString;
145
+ snapshot: z.ZodOptional<z.ZodString>;
146
+ kind: z.ZodLiteral<"artifact-value">;
147
+ }, z.core.$strict>, z.ZodObject<{
148
+ unit: z.ZodOptional<z.ZodString>;
149
+ format: z.ZodOptional<z.ZodString>;
150
+ kind: z.ZodLiteral<"derivation">;
151
+ op: z.ZodEnum<{
152
+ ratio: "ratio";
153
+ delta: "delta";
154
+ pctChange: "pctChange";
155
+ }>;
156
+ inputs: z.ZodArray<z.ZodObject<{
157
+ unit: z.ZodOptional<z.ZodString>;
158
+ format: z.ZodOptional<z.ZodString>;
159
+ locator: z.ZodObject<{
160
+ column: z.ZodString;
161
+ rowFilter: z.ZodOptional<z.ZodObject<{
162
+ column: z.ZodString;
163
+ op: z.ZodLiteral<"eq">;
164
+ value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
165
+ }, z.core.$strict>>;
166
+ row: z.ZodOptional<z.ZodNumber>;
167
+ }, z.core.$strict>;
168
+ assert: z.ZodOptional<z.ZodObject<{
169
+ value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
170
+ tolerance: z.ZodOptional<z.ZodNumber>;
171
+ }, z.core.$strict>>;
172
+ run: z.ZodOptional<z.ZodString>;
173
+ path: z.ZodString;
174
+ hash: z.ZodString;
175
+ snapshot: z.ZodOptional<z.ZodString>;
176
+ kind: z.ZodLiteral<"artifact-value">;
177
+ }, z.core.$strict>>;
178
+ assert: z.ZodOptional<z.ZodObject<{
179
+ value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
180
+ tolerance: z.ZodOptional<z.ZodNumber>;
181
+ }, z.core.$strict>>;
182
+ }, z.core.$strict>], "kind">;
183
+ }, z.core.$strict>;
184
+ /** A whole-table artifact rendered as a table. */
185
+ export declare const TableBlockSchema: z.ZodObject<{
186
+ kind: z.ZodLiteral<"table">;
187
+ id: z.ZodString;
188
+ title: z.ZodOptional<z.ZodString>;
189
+ binding: z.ZodObject<{
190
+ unit: z.ZodOptional<z.ZodString>;
191
+ format: z.ZodOptional<z.ZodString>;
192
+ columns: z.ZodOptional<z.ZodArray<z.ZodString>>;
193
+ run: z.ZodOptional<z.ZodString>;
194
+ path: z.ZodString;
195
+ hash: z.ZodString;
196
+ snapshot: z.ZodOptional<z.ZodString>;
197
+ kind: z.ZodLiteral<"artifact-table">;
198
+ }, z.core.$strict>;
199
+ caption: z.ZodOptional<z.ZodString>;
200
+ }, z.core.$strict>;
201
+ /** A whole-table artifact rendered as a chart, with the plot form and the channel mapping. */
202
+ export declare const ChartBlockSchema: z.ZodObject<{
203
+ kind: z.ZodLiteral<"chart">;
204
+ id: z.ZodString;
205
+ title: z.ZodOptional<z.ZodString>;
206
+ binding: z.ZodObject<{
207
+ unit: z.ZodOptional<z.ZodString>;
208
+ format: z.ZodOptional<z.ZodString>;
209
+ columns: z.ZodOptional<z.ZodArray<z.ZodString>>;
210
+ run: z.ZodOptional<z.ZodString>;
211
+ path: z.ZodString;
212
+ hash: z.ZodString;
213
+ snapshot: z.ZodOptional<z.ZodString>;
214
+ kind: z.ZodLiteral<"artifact-table">;
215
+ }, z.core.$strict>;
216
+ chartType: z.ZodEnum<{
217
+ line: "line";
218
+ bar: "bar";
219
+ scatter: "scatter";
220
+ histogram: "histogram";
221
+ box: "box";
222
+ heatmap: "heatmap";
223
+ pie: "pie";
224
+ }>;
225
+ encoding: z.ZodObject<{
226
+ x: z.ZodOptional<z.ZodString>;
227
+ y: z.ZodOptional<z.ZodString>;
228
+ group: z.ZodOptional<z.ZodString>;
229
+ value: z.ZodOptional<z.ZodString>;
230
+ }, z.core.$strict>;
231
+ caption: z.ZodOptional<z.ZodString>;
232
+ }, z.core.$strict>;
233
+ /** A static image artifact. An image has no per-cell address, thus it is pinned whole-file. */
234
+ export declare const FigureBlockSchema: z.ZodObject<{
235
+ kind: z.ZodLiteral<"figure">;
236
+ id: z.ZodString;
237
+ binding: z.ZodObject<{
238
+ unit: z.ZodOptional<z.ZodString>;
239
+ format: z.ZodOptional<z.ZodString>;
240
+ run: z.ZodOptional<z.ZodString>;
241
+ path: z.ZodString;
242
+ hash: z.ZodString;
243
+ snapshot: z.ZodOptional<z.ZodString>;
244
+ kind: z.ZodLiteral<"artifact-file">;
245
+ }, z.core.$strict>;
246
+ caption: z.ZodOptional<z.ZodString>;
247
+ }, z.core.$strict>;
248
+ /** An external source, rendered from a citation reference. */
249
+ export declare const CitationBlockSchema: z.ZodObject<{
250
+ kind: z.ZodLiteral<"citation">;
251
+ id: z.ZodString;
252
+ binding: z.ZodObject<{
253
+ unit: z.ZodOptional<z.ZodString>;
254
+ format: z.ZodOptional<z.ZodString>;
255
+ kind: z.ZodLiteral<"citation">;
256
+ idKind: z.ZodEnum<{
257
+ doi: "doi";
258
+ pmid: "pmid";
259
+ arxiv: "arxiv";
260
+ }>;
261
+ id: z.ZodString;
262
+ raw: z.ZodString;
263
+ assert: z.ZodOptional<z.ZodObject<{
264
+ value: z.ZodString;
265
+ }, z.core.$strict>>;
266
+ }, z.core.$strict>;
267
+ note: z.ZodOptional<z.ZodString>;
268
+ }, z.core.$strict>;
269
+ /**
270
+ * The seven atoms, as one tuple.
271
+ *
272
+ * A section is the only kind whose rules differ between a finished report and a draft. Thus the atoms are
273
+ * the shared part, and every union of block kinds spreads this tuple beside its own section member. A
274
+ * ninth kind lands here one time, and each union gets it.
275
+ */
276
+ export declare const ATOM_BLOCK_SCHEMAS: readonly [z.ZodObject<{
277
+ kind: z.ZodLiteral<"text">;
278
+ id: z.ZodString;
279
+ content: z.ZodObject<{
280
+ prose: z.ZodString;
281
+ }, z.core.$strict>;
282
+ }, z.core.$strict>, z.ZodObject<{
283
+ kind: z.ZodLiteral<"claim">;
284
+ id: z.ZodString;
285
+ content: z.ZodObject<{
286
+ prose: z.ZodString;
287
+ }, z.core.$strict>;
288
+ bindings: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
289
+ unit: z.ZodOptional<z.ZodString>;
290
+ format: z.ZodOptional<z.ZodString>;
291
+ locator: z.ZodObject<{
292
+ column: z.ZodString;
293
+ rowFilter: z.ZodOptional<z.ZodObject<{
294
+ column: z.ZodString;
295
+ op: z.ZodLiteral<"eq">;
296
+ value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
297
+ }, z.core.$strict>>;
298
+ row: z.ZodOptional<z.ZodNumber>;
299
+ }, z.core.$strict>;
300
+ assert: z.ZodOptional<z.ZodObject<{
301
+ value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
302
+ tolerance: z.ZodOptional<z.ZodNumber>;
303
+ }, z.core.$strict>>;
304
+ run: z.ZodOptional<z.ZodString>;
305
+ path: z.ZodString;
306
+ hash: z.ZodString;
307
+ snapshot: z.ZodOptional<z.ZodString>;
308
+ kind: z.ZodLiteral<"artifact-value">;
309
+ }, z.core.$strict>, z.ZodObject<{
310
+ unit: z.ZodOptional<z.ZodString>;
311
+ format: z.ZodOptional<z.ZodString>;
312
+ columns: z.ZodOptional<z.ZodArray<z.ZodString>>;
313
+ run: z.ZodOptional<z.ZodString>;
314
+ path: z.ZodString;
315
+ hash: z.ZodString;
316
+ snapshot: z.ZodOptional<z.ZodString>;
317
+ kind: z.ZodLiteral<"artifact-table">;
318
+ }, z.core.$strict>, z.ZodObject<{
319
+ unit: z.ZodOptional<z.ZodString>;
320
+ format: z.ZodOptional<z.ZodString>;
321
+ run: z.ZodOptional<z.ZodString>;
322
+ path: z.ZodString;
323
+ hash: z.ZodString;
324
+ snapshot: z.ZodOptional<z.ZodString>;
325
+ kind: z.ZodLiteral<"artifact-file">;
326
+ }, z.core.$strict>, z.ZodObject<{
327
+ unit: z.ZodOptional<z.ZodString>;
328
+ format: z.ZodOptional<z.ZodString>;
329
+ kind: z.ZodLiteral<"derivation">;
330
+ op: z.ZodEnum<{
331
+ ratio: "ratio";
332
+ delta: "delta";
333
+ pctChange: "pctChange";
334
+ }>;
335
+ inputs: z.ZodArray<z.ZodObject<{
336
+ unit: z.ZodOptional<z.ZodString>;
337
+ format: z.ZodOptional<z.ZodString>;
338
+ locator: z.ZodObject<{
339
+ column: z.ZodString;
340
+ rowFilter: z.ZodOptional<z.ZodObject<{
341
+ column: z.ZodString;
342
+ op: z.ZodLiteral<"eq">;
343
+ value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
344
+ }, z.core.$strict>>;
345
+ row: z.ZodOptional<z.ZodNumber>;
346
+ }, z.core.$strict>;
347
+ assert: z.ZodOptional<z.ZodObject<{
348
+ value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
349
+ tolerance: z.ZodOptional<z.ZodNumber>;
350
+ }, z.core.$strict>>;
351
+ run: z.ZodOptional<z.ZodString>;
352
+ path: z.ZodString;
353
+ hash: z.ZodString;
354
+ snapshot: z.ZodOptional<z.ZodString>;
355
+ kind: z.ZodLiteral<"artifact-value">;
356
+ }, z.core.$strict>>;
357
+ assert: z.ZodOptional<z.ZodObject<{
358
+ value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
359
+ tolerance: z.ZodOptional<z.ZodNumber>;
360
+ }, z.core.$strict>>;
361
+ }, z.core.$strict>, z.ZodObject<{
362
+ unit: z.ZodOptional<z.ZodString>;
363
+ format: z.ZodOptional<z.ZodString>;
364
+ kind: z.ZodLiteral<"citation">;
365
+ idKind: z.ZodEnum<{
366
+ doi: "doi";
367
+ pmid: "pmid";
368
+ arxiv: "arxiv";
369
+ }>;
370
+ id: z.ZodString;
371
+ raw: z.ZodString;
372
+ assert: z.ZodOptional<z.ZodObject<{
373
+ value: z.ZodString;
374
+ }, z.core.$strict>>;
375
+ }, z.core.$strict>], "kind">>;
376
+ }, z.core.$strict>, z.ZodObject<{
377
+ kind: z.ZodLiteral<"metric">;
378
+ id: z.ZodString;
379
+ label: z.ZodString;
380
+ value: z.ZodDiscriminatedUnion<[z.ZodObject<{
381
+ unit: z.ZodOptional<z.ZodString>;
382
+ format: z.ZodOptional<z.ZodString>;
383
+ locator: z.ZodObject<{
384
+ column: z.ZodString;
385
+ rowFilter: z.ZodOptional<z.ZodObject<{
386
+ column: z.ZodString;
387
+ op: z.ZodLiteral<"eq">;
388
+ value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
389
+ }, z.core.$strict>>;
390
+ row: z.ZodOptional<z.ZodNumber>;
391
+ }, z.core.$strict>;
392
+ assert: z.ZodOptional<z.ZodObject<{
393
+ value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
394
+ tolerance: z.ZodOptional<z.ZodNumber>;
395
+ }, z.core.$strict>>;
396
+ run: z.ZodOptional<z.ZodString>;
397
+ path: z.ZodString;
398
+ hash: z.ZodString;
399
+ snapshot: z.ZodOptional<z.ZodString>;
400
+ kind: z.ZodLiteral<"artifact-value">;
401
+ }, z.core.$strict>, z.ZodObject<{
402
+ unit: z.ZodOptional<z.ZodString>;
403
+ format: z.ZodOptional<z.ZodString>;
404
+ kind: z.ZodLiteral<"derivation">;
405
+ op: z.ZodEnum<{
406
+ ratio: "ratio";
407
+ delta: "delta";
408
+ pctChange: "pctChange";
409
+ }>;
410
+ inputs: z.ZodArray<z.ZodObject<{
411
+ unit: z.ZodOptional<z.ZodString>;
412
+ format: z.ZodOptional<z.ZodString>;
413
+ locator: z.ZodObject<{
414
+ column: z.ZodString;
415
+ rowFilter: z.ZodOptional<z.ZodObject<{
416
+ column: z.ZodString;
417
+ op: z.ZodLiteral<"eq">;
418
+ value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
419
+ }, z.core.$strict>>;
420
+ row: z.ZodOptional<z.ZodNumber>;
421
+ }, z.core.$strict>;
422
+ assert: z.ZodOptional<z.ZodObject<{
423
+ value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
424
+ tolerance: z.ZodOptional<z.ZodNumber>;
425
+ }, z.core.$strict>>;
426
+ run: z.ZodOptional<z.ZodString>;
427
+ path: z.ZodString;
428
+ hash: z.ZodString;
429
+ snapshot: z.ZodOptional<z.ZodString>;
430
+ kind: z.ZodLiteral<"artifact-value">;
431
+ }, z.core.$strict>>;
432
+ assert: z.ZodOptional<z.ZodObject<{
433
+ value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
434
+ tolerance: z.ZodOptional<z.ZodNumber>;
435
+ }, z.core.$strict>>;
436
+ }, z.core.$strict>], "kind">;
437
+ }, z.core.$strict>, z.ZodObject<{
438
+ kind: z.ZodLiteral<"table">;
439
+ id: z.ZodString;
440
+ title: z.ZodOptional<z.ZodString>;
441
+ binding: z.ZodObject<{
442
+ unit: z.ZodOptional<z.ZodString>;
443
+ format: z.ZodOptional<z.ZodString>;
444
+ columns: z.ZodOptional<z.ZodArray<z.ZodString>>;
445
+ run: z.ZodOptional<z.ZodString>;
446
+ path: z.ZodString;
447
+ hash: z.ZodString;
448
+ snapshot: z.ZodOptional<z.ZodString>;
449
+ kind: z.ZodLiteral<"artifact-table">;
450
+ }, z.core.$strict>;
451
+ caption: z.ZodOptional<z.ZodString>;
452
+ }, z.core.$strict>, z.ZodObject<{
453
+ kind: z.ZodLiteral<"chart">;
454
+ id: z.ZodString;
455
+ title: z.ZodOptional<z.ZodString>;
456
+ binding: z.ZodObject<{
457
+ unit: z.ZodOptional<z.ZodString>;
458
+ format: z.ZodOptional<z.ZodString>;
459
+ columns: z.ZodOptional<z.ZodArray<z.ZodString>>;
460
+ run: z.ZodOptional<z.ZodString>;
461
+ path: z.ZodString;
462
+ hash: z.ZodString;
463
+ snapshot: z.ZodOptional<z.ZodString>;
464
+ kind: z.ZodLiteral<"artifact-table">;
465
+ }, z.core.$strict>;
466
+ chartType: z.ZodEnum<{
467
+ line: "line";
468
+ bar: "bar";
469
+ scatter: "scatter";
470
+ histogram: "histogram";
471
+ box: "box";
472
+ heatmap: "heatmap";
473
+ pie: "pie";
474
+ }>;
475
+ encoding: z.ZodObject<{
476
+ x: z.ZodOptional<z.ZodString>;
477
+ y: z.ZodOptional<z.ZodString>;
478
+ group: z.ZodOptional<z.ZodString>;
479
+ value: z.ZodOptional<z.ZodString>;
480
+ }, z.core.$strict>;
481
+ caption: z.ZodOptional<z.ZodString>;
482
+ }, z.core.$strict>, z.ZodObject<{
483
+ kind: z.ZodLiteral<"figure">;
484
+ id: z.ZodString;
485
+ binding: z.ZodObject<{
486
+ unit: z.ZodOptional<z.ZodString>;
487
+ format: z.ZodOptional<z.ZodString>;
488
+ run: z.ZodOptional<z.ZodString>;
489
+ path: z.ZodString;
490
+ hash: z.ZodString;
491
+ snapshot: z.ZodOptional<z.ZodString>;
492
+ kind: z.ZodLiteral<"artifact-file">;
493
+ }, z.core.$strict>;
494
+ caption: z.ZodOptional<z.ZodString>;
495
+ }, z.core.$strict>, z.ZodObject<{
496
+ kind: z.ZodLiteral<"citation">;
497
+ id: z.ZodString;
498
+ binding: z.ZodObject<{
499
+ unit: z.ZodOptional<z.ZodString>;
500
+ format: z.ZodOptional<z.ZodString>;
501
+ kind: z.ZodLiteral<"citation">;
502
+ idKind: z.ZodEnum<{
503
+ doi: "doi";
504
+ pmid: "pmid";
505
+ arxiv: "arxiv";
506
+ }>;
507
+ id: z.ZodString;
508
+ raw: z.ZodString;
509
+ assert: z.ZodOptional<z.ZodObject<{
510
+ value: z.ZodString;
511
+ }, z.core.$strict>>;
512
+ }, z.core.$strict>;
513
+ note: z.ZodOptional<z.ZodString>;
514
+ }, z.core.$strict>];
515
+ /** One block of any kind except a section. */
516
+ export type AtomBlock = z.infer<(typeof ATOM_BLOCK_SCHEMAS)[number]>;
517
+ /**
518
+ * The section shape as a plain type. TypeScript cannot infer the block tree through the union cycle,
519
+ * thus the recursive members carry an explicit type. `SectionBlock` and `Block` break the cycle.
520
+ */
521
+ export interface SectionBlock {
522
+ kind: "section";
523
+ id: string;
524
+ title: string;
525
+ blocks: Block[];
526
+ }
527
+ /** One block of any of the eight kinds. An unknown kind fails validation by construction. */
528
+ export type Block = AtomBlock | SectionBlock;
529
+ /**
530
+ * A section holds at least one child block, thus an empty section is invalid. The `blocks` field is a
531
+ * `z.lazy` and not a getter, so the discriminated union reads the `kind` discriminator at construction
532
+ * time without a reference to `BlockSchema` before it exists.
533
+ */
534
+ export declare const SectionBlockSchema: z.ZodObject<{
535
+ kind: z.ZodLiteral<"section">;
536
+ id: z.ZodString;
537
+ title: z.ZodString;
538
+ blocks: z.ZodLazy<z.ZodArray<z.ZodType<Block, unknown, z.core.$ZodTypeInternals<Block, unknown>>>>;
539
+ }, z.core.$strict>;
540
+ /** The block union. A `z.ZodType<Block>` annotation gives the recursive members a stable type. */
541
+ export declare const BlockSchema: z.ZodType<Block>;
542
+ /**
543
+ * The root of a report. It holds at least one section, thus an empty report is invalid.
544
+ *
545
+ * The title carries `min(1)`, because an untitled report is incomplete in the same way that an empty
546
+ * section is. A draft relaxes it, and this schema gates it one time, at the finish.
547
+ */
548
+ export declare const ReportDocumentSchema: z.ZodObject<{
549
+ title: z.ZodString;
550
+ sections: z.ZodArray<z.ZodObject<{
551
+ kind: z.ZodLiteral<"section">;
552
+ id: z.ZodString;
553
+ title: z.ZodString;
554
+ blocks: z.ZodLazy<z.ZodArray<z.ZodType<Block, unknown, z.core.$ZodTypeInternals<Block, unknown>>>>;
555
+ }, z.core.$strict>>;
556
+ }, z.core.$strict>;
557
+ export type TextBlock = z.infer<typeof TextBlockSchema>;
558
+ export type ClaimBlock = z.infer<typeof ClaimBlockSchema>;
559
+ export type MetricBlock = z.infer<typeof MetricBlockSchema>;
560
+ export type TableBlock = z.infer<typeof TableBlockSchema>;
561
+ export type ChartBlock = z.infer<typeof ChartBlockSchema>;
562
+ export type FigureBlock = z.infer<typeof FigureBlockSchema>;
563
+ export type CitationBlock = z.infer<typeof CitationBlockSchema>;
564
+ export type ReportDocument = z.infer<typeof ReportDocumentSchema>;
@@ -0,0 +1,117 @@
1
+ /**
2
+ * The composable block tree of a report.
3
+ *
4
+ * A block is one of eight kinds. The shape of each kind carries its grammar. A `text` block has no
5
+ * binding field, thus an unbound claim is unrepresentable. A `metric` value slot admits one scalar
6
+ * reference only, thus a numeric literal cannot sit there. No atom holds a child-block array, thus a
7
+ * chart inside a metric is unrepresentable. The grammar is the shape, and not a separate pass.
8
+ *
9
+ * The tree is recursive: a `section` holds child blocks, and a child can be another section.
10
+ *
11
+ * Every object schema here and in the reference module is strict. A strict object makes an extra field
12
+ * a parse failure, and not a field that the parser strips in silence. Thus a forbidden field, such as a
13
+ * binding on a `text` block or a child-block array on an atom, is rejected. The absence of a field is a
14
+ * rule only when an extra field fails the parse.
15
+ */
16
+ import { z } from "zod";
17
+ import { ArtifactFileReferenceSchema, ArtifactTableReferenceSchema, CitationReferenceSchema, ReferenceSchema, ScalarReferenceSchema, } from "./report-reference.js";
18
+ /** The chart vocabulary. Each value names one plot form. */
19
+ const ChartTypeSchema = z.enum(["bar", "line", "scatter", "histogram", "box", "heatmap", "pie"]);
20
+ /** The mapping from a data column to a visual channel. Each channel is optional. */
21
+ const ChartEncodingSchema = z.strictObject({
22
+ x: z.string().optional().describe("The column on the x axis."),
23
+ y: z.string().optional().describe("The column on the y axis."),
24
+ group: z.string().optional().describe("The column that splits and colors the series."),
25
+ value: z.string().optional().describe("The value column for a pie or heatmap."),
26
+ });
27
+ /** Prose with no binding. The absence of a binding field is the rule for this kind. */
28
+ export const TextBlockSchema = z.strictObject({
29
+ kind: z.literal("text"),
30
+ id: z.string().min(1).describe("The stable identity of the block."),
31
+ content: z.strictObject({ prose: z.string() }),
32
+ });
33
+ /** Prose with at least one reference that justifies it. */
34
+ export const ClaimBlockSchema = z.strictObject({
35
+ kind: z.literal("claim"),
36
+ id: z.string().min(1).describe("The stable identity of the block."),
37
+ content: z.strictObject({ prose: z.string() }),
38
+ bindings: z.array(ReferenceSchema).min(1).describe("The evidence that justifies the claim."),
39
+ });
40
+ /** A labeled number whose value comes from one scalar reference. */
41
+ export const MetricBlockSchema = z.strictObject({
42
+ kind: z.literal("metric"),
43
+ id: z.string().min(1).describe("The stable identity of the block."),
44
+ label: z.string(),
45
+ value: ScalarReferenceSchema.describe("The one scalar reference that gives the metric value."),
46
+ });
47
+ /** A whole-table artifact rendered as a table. */
48
+ export const TableBlockSchema = z.strictObject({
49
+ kind: z.literal("table"),
50
+ id: z.string().min(1).describe("The stable identity of the block."),
51
+ title: z.string().optional(),
52
+ binding: ArtifactTableReferenceSchema.describe("The whole-table artifact to render."),
53
+ caption: z.string().optional(),
54
+ });
55
+ /** A whole-table artifact rendered as a chart, with the plot form and the channel mapping. */
56
+ export const ChartBlockSchema = z.strictObject({
57
+ kind: z.literal("chart"),
58
+ id: z.string().min(1).describe("The stable identity of the block."),
59
+ title: z.string().optional(),
60
+ binding: ArtifactTableReferenceSchema.describe("The whole-table artifact to plot."),
61
+ chartType: ChartTypeSchema,
62
+ encoding: ChartEncodingSchema,
63
+ caption: z.string().optional(),
64
+ });
65
+ /** A static image artifact. An image has no per-cell address, thus it is pinned whole-file. */
66
+ export const FigureBlockSchema = z.strictObject({
67
+ kind: z.literal("figure"),
68
+ id: z.string().min(1).describe("The stable identity of the block."),
69
+ binding: ArtifactFileReferenceSchema.describe("The image artifact, pinned whole-file by path and hash."),
70
+ caption: z.string().optional(),
71
+ });
72
+ /** An external source, rendered from a citation reference. */
73
+ export const CitationBlockSchema = z.strictObject({
74
+ kind: z.literal("citation"),
75
+ id: z.string().min(1).describe("The stable identity of the block."),
76
+ binding: CitationReferenceSchema,
77
+ note: z.string().optional(),
78
+ });
79
+ /**
80
+ * The seven atoms, as one tuple.
81
+ *
82
+ * A section is the only kind whose rules differ between a finished report and a draft. Thus the atoms are
83
+ * the shared part, and every union of block kinds spreads this tuple beside its own section member. A
84
+ * ninth kind lands here one time, and each union gets it.
85
+ */
86
+ export const ATOM_BLOCK_SCHEMAS = [
87
+ TextBlockSchema,
88
+ ClaimBlockSchema,
89
+ MetricBlockSchema,
90
+ TableBlockSchema,
91
+ ChartBlockSchema,
92
+ FigureBlockSchema,
93
+ CitationBlockSchema,
94
+ ];
95
+ /**
96
+ * A section holds at least one child block, thus an empty section is invalid. The `blocks` field is a
97
+ * `z.lazy` and not a getter, so the discriminated union reads the `kind` discriminator at construction
98
+ * time without a reference to `BlockSchema` before it exists.
99
+ */
100
+ export const SectionBlockSchema = z.strictObject({
101
+ kind: z.literal("section"),
102
+ id: z.string().min(1),
103
+ title: z.string(),
104
+ blocks: z.lazy(() => z.array(BlockSchema).min(1)),
105
+ });
106
+ /** The block union. A `z.ZodType<Block>` annotation gives the recursive members a stable type. */
107
+ export const BlockSchema = z.discriminatedUnion("kind", [SectionBlockSchema, ...ATOM_BLOCK_SCHEMAS]);
108
+ /**
109
+ * The root of a report. It holds at least one section, thus an empty report is invalid.
110
+ *
111
+ * The title carries `min(1)`, because an untitled report is incomplete in the same way that an empty
112
+ * section is. A draft relaxes it, and this schema gates it one time, at the finish.
113
+ */
114
+ export const ReportDocumentSchema = z.strictObject({
115
+ title: z.string().min(1),
116
+ sections: z.array(SectionBlockSchema).min(1).describe("The top-level sections, each with at least one block."),
117
+ });