@inflexa-ai/harness 0.28.1 → 0.30.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 (168) hide show
  1. package/dist/agents/conversation-agent.js +7 -4
  2. package/dist/agents/report-session-agent.js +1 -1
  3. package/dist/agents/sandbox/data-profiler.js +0 -1
  4. package/dist/agents/sandbox/immune-profiling-agent.js +3 -1
  5. package/dist/agents/sandbox/network-agent.js +0 -1
  6. package/dist/agents/sandbox/types.d.ts +1 -1
  7. package/dist/agents/sandbox/types.js +1 -1
  8. package/dist/app/data-profile-orientation.d.ts +52 -27
  9. package/dist/app/data-profile-orientation.js +331 -92
  10. package/dist/app/data-profile-view.d.ts +70 -0
  11. package/dist/app/data-profile-view.js +123 -0
  12. package/dist/app/synthesize-run.js +1 -1
  13. package/dist/config/resource-limits.d.ts +1 -1
  14. package/dist/config/resource-limits.js +1 -1
  15. package/dist/contracts/data-profile.d.ts +276 -25
  16. package/dist/contracts/index.d.ts +3 -1
  17. package/dist/contracts/index.js +1 -0
  18. package/dist/contracts/profile-vocabulary.d.ts +103 -0
  19. package/dist/contracts/profile-vocabulary.js +449 -0
  20. package/dist/contracts/schemas/chat-parts.d.ts +12 -12
  21. package/dist/contracts/severity.d.ts +2 -2
  22. package/dist/contracts/target-dossier.d.ts +91 -91
  23. package/dist/data/safety-panel-schema.d.ts +4 -4
  24. package/dist/execution/input-signature.d.ts +16 -3
  25. package/dist/execution/input-signature.js +0 -0
  26. package/dist/execution/post-step-pipeline.js +1 -1
  27. package/dist/execution/staged-input.d.ts +4 -4
  28. package/dist/index.d.ts +7 -2
  29. package/dist/index.js +14 -0
  30. package/dist/input-scan/clustering.d.ts +63 -0
  31. package/dist/input-scan/clustering.js +208 -0
  32. package/dist/input-scan/companions.d.ts +30 -0
  33. package/dist/input-scan/companions.js +138 -0
  34. package/dist/input-scan/decoder/container_readout.py +171 -0
  35. package/dist/input-scan/detect-sets.d.ts +24 -0
  36. package/dist/input-scan/detect-sets.js +279 -0
  37. package/dist/input-scan/enrich.d.ts +62 -19
  38. package/dist/input-scan/enrich.js +132 -187
  39. package/dist/input-scan/formats.d.ts +13 -5
  40. package/dist/input-scan/formats.js +13 -5
  41. package/dist/input-scan/index.d.ts +10 -4
  42. package/dist/input-scan/index.js +7 -4
  43. package/dist/input-scan/markers.d.ts +21 -0
  44. package/dist/input-scan/markers.js +89 -0
  45. package/dist/input-scan/menu.d.ts +127 -0
  46. package/dist/input-scan/menu.js +0 -0
  47. package/dist/input-scan/quarantine.d.ts +17 -0
  48. package/dist/input-scan/quarantine.js +69 -0
  49. package/dist/input-scan/readout-budget.d.ts +32 -0
  50. package/dist/input-scan/readout-budget.js +61 -0
  51. package/dist/input-scan/readout.d.ts +33 -0
  52. package/dist/input-scan/readout.js +336 -0
  53. package/dist/input-scan/scan.d.ts +5 -4
  54. package/dist/input-scan/scan.js +5 -5
  55. package/dist/input-scan/set-types.d.ts +209 -0
  56. package/dist/input-scan/set-types.js +15 -0
  57. package/dist/input-scan/templates.d.ts +93 -0
  58. package/dist/input-scan/templates.js +369 -0
  59. package/dist/input-scan/tokens.d.ts +94 -0
  60. package/dist/input-scan/tokens.js +267 -0
  61. package/dist/input-scan/tuning.d.ts +55 -0
  62. package/dist/input-scan/tuning.js +55 -0
  63. package/dist/input-scan/types.d.ts +2 -2
  64. package/dist/loop/run-agent.d.ts +13 -1
  65. package/dist/loop/run-agent.js +2 -1
  66. package/dist/prompts/SOUL.d.ts +2 -2
  67. package/dist/prompts/SOUL.js +17 -1
  68. package/dist/prompts/conversation.d.ts +1 -1
  69. package/dist/prompts/conversation.js +45 -71
  70. package/dist/prompts/planner.js +57 -10
  71. package/dist/prompts/report-session.d.ts +1 -1
  72. package/dist/prompts/report-session.js +3 -2
  73. package/dist/prompts/sandbox/bulk-transcriptomics-agent.d.ts +1 -1
  74. package/dist/prompts/sandbox/bulk-transcriptomics-agent.js +3 -1
  75. package/dist/prompts/sandbox/data-profiler.d.ts +10 -1
  76. package/dist/prompts/sandbox/data-profiler.js +197 -53
  77. package/dist/prompts/sandbox/dna-methylation-agent.d.ts +1 -1
  78. package/dist/prompts/sandbox/dna-methylation-agent.js +18 -12
  79. package/dist/prompts/sandbox/immune-profiling-agent.d.ts +1 -1
  80. package/dist/prompts/sandbox/immune-profiling-agent.js +6 -2
  81. package/dist/prompts/sandbox/metabolomics-agent.d.ts +1 -1
  82. package/dist/prompts/sandbox/metabolomics-agent.js +8 -4
  83. package/dist/prompts/sandbox/microbiome-agent.d.ts +1 -1
  84. package/dist/prompts/sandbox/microbiome-agent.js +12 -6
  85. package/dist/prompts/sandbox/network-agent.d.ts +1 -1
  86. package/dist/prompts/sandbox/network-agent.js +9 -6
  87. package/dist/prompts/sandbox/spatial-omics-agent.d.ts +1 -1
  88. package/dist/prompts/sandbox/spatial-omics-agent.js +4 -2
  89. package/dist/prompts/sandbox-standards.d.ts +1 -1
  90. package/dist/prompts/sandbox-standards.js +10 -7
  91. package/dist/providers/ai-sdk.js +34 -1
  92. package/dist/providers/reasoning.d.ts +65 -0
  93. package/dist/providers/reasoning.js +81 -0
  94. package/dist/providers/types.d.ts +14 -0
  95. package/dist/schemas/data-profile-schemas.d.ts +947 -84
  96. package/dist/schemas/data-profile-schemas.js +300 -115
  97. package/dist/schemas/run-synthesis.d.ts +4 -4
  98. package/dist/state/data-profile.d.ts +1 -1
  99. package/dist/state/index.d.ts +1 -1
  100. package/dist/state/vector-store.d.ts +13 -0
  101. package/dist/state/vector-store.js +8 -0
  102. package/dist/tasks/data-profile-absorb.d.ts +78 -0
  103. package/dist/tasks/data-profile-absorb.js +285 -0
  104. package/dist/tasks/data-profile-index.d.ts +34 -25
  105. package/dist/tasks/data-profile-index.js +160 -59
  106. package/dist/tasks/data-profile-resolve.d.ts +72 -0
  107. package/dist/tasks/data-profile-resolve.js +639 -0
  108. package/dist/tasks/data-profile.d.ts +16 -5
  109. package/dist/tasks/data-profile.js +270 -131
  110. package/dist/tools/bio/chembl.d.ts +1 -1
  111. package/dist/tools/bio/chembl.js +15 -10
  112. package/dist/tools/bio/comptox.js +5 -1
  113. package/dist/tools/bio/drug-gene-interactions.js +5 -2
  114. package/dist/tools/bio/gene-disease-evidence.d.ts +19 -9
  115. package/dist/tools/bio/gene-disease-evidence.js +78 -22
  116. package/dist/tools/bio/gene-preclinical-profile.d.ts +33 -13
  117. package/dist/tools/bio/gene-preclinical-profile.js +63 -22
  118. package/dist/tools/bio/lookup-annotation.d.ts +1 -0
  119. package/dist/tools/bio/lookup-annotation.js +28 -10
  120. package/dist/tools/bio/opentargets.d.ts +10 -2
  121. package/dist/tools/bio/opentargets.js +42 -13
  122. package/dist/tools/bio/pubchem.js +5 -2
  123. package/dist/tools/bio/pubmed.js +9 -3
  124. package/dist/tools/bio/search-clinical-trials.d.ts +25 -25
  125. package/dist/tools/bio/search-clinical-trials.js +56 -18
  126. package/dist/tools/bio/search-faers.d.ts +26 -6
  127. package/dist/tools/bio/search-faers.js +70 -18
  128. package/dist/tools/bio/search-gene.d.ts +19 -3
  129. package/dist/tools/bio/search-gene.js +69 -12
  130. package/dist/tools/bio/search-geo-datasets.js +4 -1
  131. package/dist/tools/bio/search-interactions.js +6 -2
  132. package/dist/tools/bio/target-safety.d.ts +2 -2
  133. package/dist/tools/bio/target-safety.js +3 -2
  134. package/dist/tools/lib/cbioportal-client.js +25 -6
  135. package/dist/tools/lib/chembl-client.d.ts +3 -1
  136. package/dist/tools/lib/chembl-client.js +6 -1
  137. package/dist/tools/lib/gwas-catalog-client.d.ts +7 -6
  138. package/dist/tools/lib/gwas-catalog-client.js +18 -6
  139. package/dist/tools/lib/openfda-client.d.ts +7 -5
  140. package/dist/tools/lib/openfda-client.js +17 -9
  141. package/dist/tools/lib/opentargets-client.d.ts +20 -0
  142. package/dist/tools/lib/opentargets-client.js +45 -0
  143. package/dist/tools/lib/pathway-client.d.ts +7 -0
  144. package/dist/tools/lib/pathway-client.js +68 -1
  145. package/dist/tools/research/context7-docs.js +3 -3
  146. package/dist/tools/research/generate-analogy-report.js +2 -2
  147. package/dist/tools/research/generate-plan.d.ts +3 -0
  148. package/dist/tools/research/generate-plan.js +64 -5
  149. package/dist/tools/research/inspect-data-profile.d.ts +48 -22
  150. package/dist/tools/research/inspect-data-profile.js +73 -54
  151. package/dist/tools/research/resolve-citation.js +8 -3
  152. package/dist/tools/research/search-arxiv.js +8 -3
  153. package/dist/tools/research/search-semantic-scholar.js +10 -4
  154. package/dist/tools/workspace/scan-inputs.d.ts +4 -4
  155. package/dist/tools/workspace/scan-inputs.js +13 -14
  156. package/dist/tools/workspace/workspace-search.d.ts +11 -2
  157. package/dist/tools/workspace/workspace-search.js +44 -16
  158. package/dist/workflows/sandbox-step.d.ts +6 -0
  159. package/dist/workflows/sandbox-step.js +31 -14
  160. package/dist/workflows/target-assessment/assemblers/safety.d.ts +1 -1
  161. package/dist/workflows/target-assessment/phase4-assemble.d.ts +38 -38
  162. package/dist/workflows/target-assessment/schemas.d.ts +12 -12
  163. package/dist/workflows/target-assessment/steps/phase2-aggregate.d.ts +6 -6
  164. package/dist/workflows/target-assessment/steps/phase3-aggregate.d.ts +6 -6
  165. package/dist/workflows/target-assessment/synthesis/index.d.ts +12 -12
  166. package/package.json +5 -3
  167. package/dist/input-scan/coverage.d.ts +0 -22
  168. package/dist/input-scan/coverage.js +0 -85
@@ -0,0 +1,449 @@
1
+ /**
2
+ * The controlled vocabulary the profiler draws from, as data.
3
+ *
4
+ * One source, two readers: submit validation derives its enums from these lists and
5
+ * prompt assembly renders from the same entries, so the catalogue the agent is shown
6
+ * and the catalogue the validator enforces cannot diverge. Growth is an edit to these
7
+ * lists, measured by how often `other` is reached for.
8
+ *
9
+ * It lives in `contracts/` because the persisted profile carries these ids: a consumer
10
+ * rendering a stored group needs the category's meaning without importing the ledger,
11
+ * the schema module, or zod. Hosts do not extend it — the package owns the catalogue and
12
+ * versions it with the harness.
13
+ *
14
+ * Every category carries its nearest neighbour and the rule that separates them, because
15
+ * a category list without one is a list of labels an author picks by vibe. Every
16
+ * dimension category additionally carries a default treatment: whether a downstream step
17
+ * would TYPICALLY consume one value's files as a different substrate than another's.
18
+ * The agent follows the default and deviates only with a stated reason.
19
+ */
20
+ // ── Group roles ────────────────────────────────────────────────────────────
21
+ export const GROUP_ROLE_IDS = ["data", "metadata", "index", "documentation", "reference"];
22
+ /**
23
+ * Companions (`.bai`/`.tbi`/per-file `.md5`) take no role — they attach to members. A
24
+ * checksum or inventory file spanning MANY members is not a companion but a member of
25
+ * its own, category `manifest`; `index` is for tables that exist to be joined against,
26
+ * never for binary sidecars.
27
+ */
28
+ export const GROUP_ROLES = [
29
+ { id: "data", definition: "The measurements themselves — variant calls, a count matrix, images." },
30
+ { id: "metadata", definition: "Describes other members' meaning or provenance — a sample sheet, a pipeline manifest, config files." },
31
+ { id: "index", definition: "Standalone lookup or join tables — a variable-code dictionary, a file inventory table." },
32
+ { id: "documentation", definition: "Prose for humans — README, dataset card, methods paper, licences." },
33
+ {
34
+ id: "reference",
35
+ definition: "External or canonical inputs the analysis consumes but did not produce — genome build, annotation GTF, compound library, pathway sets.",
36
+ },
37
+ ];
38
+ // ── Group categories ───────────────────────────────────────────────────────
39
+ export const GROUP_CATEGORY_IDS = [
40
+ "sequencing-reads",
41
+ "alignment",
42
+ "variant-calls",
43
+ "copy-number",
44
+ "structural-variants",
45
+ "association-results",
46
+ "regions-signal",
47
+ "expression-matrix",
48
+ "single-cell-matrix",
49
+ "methylation",
50
+ "proteomics",
51
+ "metabolomics",
52
+ "cytometry",
53
+ "chemical-structures",
54
+ "imaging",
55
+ "clinical-table",
56
+ "sample-annotation",
57
+ "code",
58
+ "document",
59
+ "manifest",
60
+ "reference-data",
61
+ "other",
62
+ ];
63
+ /**
64
+ * Coarse on purpose — a free `subtype` refines below the category. Content beats shape:
65
+ * a beta-value matrix is methylation whatever its layout, and a MAF is variant-calls
66
+ * whatever its extension. Grain and meaning decide.
67
+ */
68
+ export const GROUP_CATEGORIES = [
69
+ {
70
+ id: "sequencing-reads",
71
+ definition: "Reads or raw instrument signal — FASTQ, unaligned BAM, FAST5/POD5.",
72
+ note: "vs alignment: mapped-ness decides — an unaligned BAM is reads.",
73
+ },
74
+ {
75
+ id: "alignment",
76
+ definition: "Reads mapped to a reference — BAM/CRAM carrying mapped records.",
77
+ note: "vs sequencing-reads: an unaligned BAM is reads, whatever the container.",
78
+ },
79
+ {
80
+ id: "variant-calls",
81
+ definition: "Per-sample small-variant calls (SNV/indel) — VCF with genotypes, MAF.",
82
+ note: "vs copy-number/structural-variants: those products get their own category whatever the container. vs association-results: per-sample genotypes rather than cohort statistics. vs reference-data: a sites-only population or annotation VCF is reference-data, role reference.",
83
+ },
84
+ {
85
+ id: "copy-number",
86
+ definition: "Copy-number products — segment tables, ratio tracks, CNV calls.",
87
+ note: "vs variant-calls: small variants stay variant-calls.",
88
+ },
89
+ {
90
+ id: "structural-variants",
91
+ definition: "Structural-variant products — breakpoints, SV calls.",
92
+ note: "vs variant-calls: an SV VCF is structural-variants.",
93
+ },
94
+ {
95
+ id: "association-results",
96
+ definition: "Per-variant or per-feature summary statistics without per-sample data — GWAS/QTL sumstats, PLINK output.",
97
+ note: "vs regions-signal: test statistics rather than positions or coverage.",
98
+ },
99
+ {
100
+ id: "regions-signal",
101
+ definition: "Genomic intervals and coverage tracks — BED/narrowPeak/broadPeak, bigWig/bedGraph.",
102
+ note: "vs association-results: positions and coverage rather than test statistics.",
103
+ },
104
+ {
105
+ id: "expression-matrix",
106
+ definition: "Bulk feature × sample abundance tables.",
107
+ note: "vs single-cell-matrix: barcoded per-cell products are single-cell. vs methylation: content beats shape — a beta-value matrix is methylation.",
108
+ },
109
+ {
110
+ id: "single-cell-matrix",
111
+ definition: "Barcoded per-cell products — MEX triplets, h5ad. Spatial omics is a subtype.",
112
+ note: "vs expression-matrix: bulk gene × sample tables are expression.",
113
+ },
114
+ {
115
+ id: "methylation",
116
+ definition: "Methylation measurements — beta/M-value matrices, per-CpG calls.",
117
+ note: "vs expression-matrix: the measured substrate decides, not the table's shape.",
118
+ },
119
+ {
120
+ id: "proteomics",
121
+ definition: "Protein-level measurements. MS rawness is a subtype.",
122
+ note: "vs imaging: an imaging mass-spec run is proteomics with subtype 'imaging MS' — assay substrate wins.",
123
+ },
124
+ {
125
+ id: "metabolomics",
126
+ definition: "Metabolite-level measurements. MS rawness is a subtype.",
127
+ note: "vs proteomics: by measured substrate.",
128
+ },
129
+ {
130
+ id: "cytometry",
131
+ definition: "Flow or mass cytometry — FCS and its derivatives.",
132
+ note: "vs imaging: per-event measurements rather than pixels; vs proteomics: neither.",
133
+ },
134
+ {
135
+ id: "chemical-structures",
136
+ definition: "Compound structures and libraries — SDF, SMILES, MOL.",
137
+ note: "vs reference-data: a screening library the analysis measures against is reference-data, role reference.",
138
+ },
139
+ {
140
+ id: "imaging",
141
+ definition: "Microscopy, radiology, and other pixel data — DICOM, TIFF stacks.",
142
+ note: "vs cytometry: pixels rather than per-event measurements.",
143
+ },
144
+ {
145
+ id: "clinical-table",
146
+ definition: "Facts about subjects over time — diagnoses, medications, outcomes, visits.",
147
+ note: "vs sample-annotation: subject grain rather than specimen grain. When one table does both, prefer sample-annotation only if its grain is the sample.",
148
+ },
149
+ {
150
+ id: "sample-annotation",
151
+ definition: "Specimen or measurement attribute maps — sample sheets, characteristic tables.",
152
+ note: "vs clinical-table: specimen attributes rather than subject history.",
153
+ },
154
+ {
155
+ id: "code",
156
+ definition: "Scripts, notebooks, and workflow definitions arriving as inputs.",
157
+ note: "vs document: executable rather than prose — a notebook is code even when narrated.",
158
+ },
159
+ {
160
+ id: "document",
161
+ definition: "Prose for humans — README, dataset card, methods paper, licence.",
162
+ note: "vs manifest: a dataset card in Markdown is a document; its JSON twin is a manifest.",
163
+ },
164
+ {
165
+ id: "manifest",
166
+ definition: "Machine-readable inventories of these files — checksum lists, file manifests.",
167
+ note: "vs index role: an inventory OF these files is a manifest; a table that exists to be joined against data is index-role.",
168
+ },
169
+ {
170
+ id: "reference-data",
171
+ definition: "Consumed-not-produced canonical inputs — genome builds, GTFs, pathway sets, spectral libraries, sites-only VCFs.",
172
+ note: "vs everything: the analysis consumes it and did not produce it.",
173
+ },
174
+ {
175
+ id: "other",
176
+ definition: "Outside the catalogue — carry a free label saying what it is.",
177
+ note: "A wrong specific category is worse than an honest `other` with a good label. Electrophysiology, phylogenetic trees, model weights, database dumps, and plate-reader tables belong here today.",
178
+ },
179
+ ];
180
+ // ── Dimension categories ───────────────────────────────────────────────────
181
+ export const DIMENSION_CATEGORY_IDS = [
182
+ "subject",
183
+ "sample",
184
+ "organism-species",
185
+ "model-system",
186
+ "cohort-arm",
187
+ "disease-state",
188
+ "treatment",
189
+ "timepoint",
190
+ "tissue-site",
191
+ "cell-type",
192
+ "genetic-perturbation",
193
+ "sex",
194
+ "age-group",
195
+ "developmental-stage",
196
+ "environment",
197
+ "assay-modality",
198
+ "assay-target",
199
+ "variant-origin",
200
+ "sample-pairing",
201
+ "processing-level",
202
+ "assay-version",
203
+ "batch",
204
+ "replicate",
205
+ "tool-variant",
206
+ "library-prep",
207
+ "data-partition",
208
+ "other",
209
+ ];
210
+ export const DIMENSION_CATEGORIES = [
211
+ {
212
+ id: "subject",
213
+ scope: "biological",
214
+ definition: "The individual the data is about — patient, animal, donor. For a xenograft the subject is the donor; the host is genotype context.",
215
+ defaultTreatment: "dimension",
216
+ note: "Never split. Not the specimen — see sample.",
217
+ },
218
+ {
219
+ id: "sample",
220
+ scope: "biological",
221
+ definition: "Physical specimen. Nests under subject where one exists; community and environmental samples have none.",
222
+ defaultTreatment: "dimension",
223
+ note: "Never split. Not the library or aliquot, which is technical — see library-prep.",
224
+ },
225
+ {
226
+ id: "organism-species",
227
+ scope: "biological",
228
+ definition: "Species, when it varies across the dataset.",
229
+ defaultTreatment: "split",
230
+ note: "Species picks the reference genome. A constant organism is an identity field, not a dimension.",
231
+ },
232
+ {
233
+ id: "model-system",
234
+ scope: "biological",
235
+ definition: "Cell line, organoid, or model identity in subject-less panels.",
236
+ defaultTreatment: "dimension",
237
+ note: "A line used as the subject surrogate is still model-system, not subject.",
238
+ },
239
+ {
240
+ id: "cohort-arm",
241
+ scope: "biological",
242
+ definition: "Grouping assigned by design — randomisation, dose groups, discovery/validation cohorts. Assigned-by-design is the sole test.",
243
+ defaultTreatment: "dimension",
244
+ note: "Comparative models consume all arms together. Split only for independent cohorts, as a stated deviation. Observed conditions are disease-state.",
245
+ },
246
+ {
247
+ id: "disease-state",
248
+ scope: "biological",
249
+ definition: "Observed diagnosis or condition varying across subjects, including observational case/control.",
250
+ defaultTreatment: "dimension",
251
+ note: "Assigned-by-design grouping is cohort-arm.",
252
+ },
253
+ {
254
+ id: "treatment",
255
+ scope: "biological",
256
+ definition: "Compound, dose, or intervention as the varying quantity, including protocol-administered diet.",
257
+ defaultTreatment: "dimension",
258
+ note: "Dose-response curves are consumed together. Named designed groups are cohort-arm; ambient exposure is environment.",
259
+ },
260
+ {
261
+ id: "timepoint",
262
+ scope: "biological",
263
+ definition: "When the measurement was taken, in subject or visit time.",
264
+ defaultTreatment: "dimension",
265
+ note: "Known-ambiguous and documented as such. Acquisition, run, and processing dates are batch; duration of exposure is treatment.",
266
+ },
267
+ {
268
+ id: "tissue-site",
269
+ scope: "biological",
270
+ definition: "Organism part, sampling site, biofluid, or subcellular fraction, when it varies.",
271
+ defaultTreatment: "dimension",
272
+ note: "Ambiguous like timepoint. A constant tissue is an identity field.",
273
+ },
274
+ {
275
+ id: "cell-type",
276
+ scope: "biological",
277
+ definition: "Sorted population or annotated type, when it varies across files.",
278
+ defaultTreatment: "dimension",
279
+ note: "Per-cell annotations inside one matrix are file content, not a dimension.",
280
+ },
281
+ {
282
+ id: "genetic-perturbation",
283
+ scope: "biological",
284
+ definition: "Strain, genetic modification, KO/WT, CRISPR guide, shRNA, or ORF per member.",
285
+ defaultTreatment: "dimension",
286
+ note: "Perturbation as the study's designed comparison is cohort-arm.",
287
+ },
288
+ { id: "sex", scope: "biological", definition: "Sex as a varying attribute.", defaultTreatment: "dimension", note: "A constant is an identity field." },
289
+ {
290
+ id: "age-group",
291
+ scope: "biological",
292
+ definition: "Age or age band as a varying attribute.",
293
+ defaultTreatment: "dimension",
294
+ note: "Calendar age; biology is developmental-stage.",
295
+ },
296
+ {
297
+ id: "developmental-stage",
298
+ scope: "biological",
299
+ definition: "Developmental stage as a varying attribute.",
300
+ defaultTreatment: "dimension",
301
+ note: "Age-group is calendar; stage is biology.",
302
+ },
303
+ {
304
+ id: "environment",
305
+ scope: "biological",
306
+ definition: "Diet, stimulus, growth condition, field location.",
307
+ defaultTreatment: "dimension",
308
+ note: "Administered per protocol is treatment; plot or block structure is batch.",
309
+ },
310
+ {
311
+ id: "assay-modality",
312
+ scope: "technical",
313
+ definition: "Which measurement technology — RNA-seq vs proteomics vs imaging.",
314
+ defaultTreatment: "split",
315
+ note: "Different substrates. Different-marker panels are a different modality or target, not a version; a version of one assay is assay-version.",
316
+ },
317
+ {
318
+ id: "assay-target",
319
+ scope: "technical",
320
+ definition: "The molecular target an assay is directed at — a ChIP antibody target, a panel's target set.",
321
+ defaultTreatment: "split",
322
+ note: "Each target's output is a distinct substrate. Modality is the technology; target is what it points at.",
323
+ },
324
+ {
325
+ id: "variant-origin",
326
+ scope: "technical",
327
+ definition: "Somatic vs germline.",
328
+ defaultTreatment: "split",
329
+ note: "The canonical substrate case.",
330
+ },
331
+ {
332
+ id: "sample-pairing",
333
+ scope: "technical",
334
+ definition: "Tumour/normal or matched-pair membership.",
335
+ defaultTreatment: "split",
336
+ note: "Split with the pair id kept on both halves, because paired callers consume both together. Pairing is within-subject; cohort-arm is between-subjects.",
337
+ },
338
+ {
339
+ id: "processing-level",
340
+ scope: "technical",
341
+ definition: "Raw, filtered, and normalised tiers of the same product.",
342
+ defaultTreatment: "split",
343
+ note: "Steps consume one tier. Alternate tools at the same tier are tool-variant.",
344
+ },
345
+ {
346
+ id: "assay-version",
347
+ scope: "technical",
348
+ definition: "Panel, kit, or pipeline version over the same target set.",
349
+ defaultTreatment: "dimension",
350
+ note: "Batch-like. Different marker sets are assay-modality or assay-target.",
351
+ },
352
+ {
353
+ id: "batch",
354
+ scope: "technical",
355
+ definition: "Plate, lane, centre, run or acquisition date.",
356
+ defaultTreatment: "dimension",
357
+ note: "Never split. Subject-visit time is timepoint.",
358
+ },
359
+ {
360
+ id: "replicate",
361
+ scope: "technical",
362
+ definition: "Replicate index. The label must state whether the replication is biological or technical.",
363
+ defaultTreatment: "dimension",
364
+ note: "Never split.",
365
+ },
366
+ {
367
+ id: "tool-variant",
368
+ scope: "technical",
369
+ definition: "Alternate callers or aligners over the same input.",
370
+ defaultTreatment: "dimension",
371
+ note: "Consumed together for consensus. Pipeline versions over time are assay-version.",
372
+ },
373
+ {
374
+ id: "library-prep",
375
+ scope: "technical",
376
+ definition: "Library, label, capture, or aliquot.",
377
+ defaultTreatment: "dimension",
378
+ note: "A biofluid or subcellular fraction is biological — tissue-site.",
379
+ },
380
+ {
381
+ id: "data-partition",
382
+ scope: "technical",
383
+ definition: "Chromosome shard, file chunk, read-pair half, paged export.",
384
+ defaultTreatment: "dimension",
385
+ note: "Never split, rarely promoted — pure mechanics that stays on the set.",
386
+ },
387
+ {
388
+ id: "other",
389
+ scope: "technical",
390
+ definition: "Outside the catalogue — carry a free label saying what varies.",
391
+ defaultTreatment: "dimension",
392
+ note: "Monitored: a wrong specific category is worse than an honest `other`.",
393
+ },
394
+ ];
395
+ // ── Probe list ─────────────────────────────────────────────────────────────
396
+ export const DIMENSION_PROBE_IDS = ["subject", "sample", "cohort-arm", "timepoint", "batch"];
397
+ /**
398
+ * A probe outcome, exactly one per probe.
399
+ *
400
+ * `not-found` is a correct and complete answer once the searched set is named — that is
401
+ * what removes the completeness pressure that otherwise invents dimensions. `attested`
402
+ * records prose-only evidence and can never justify a split.
403
+ */
404
+ export const PROBE_OUTCOME_IDS = ["found", "not-found", "found-but-constant", "attested"];
405
+ /**
406
+ * The only dimensions the agent actively looks for. The searchable set is bounded and
407
+ * named: files in metadata- or documentation-role groups plus clinical-table and
408
+ * sample-annotation members, up to about ten files. Everything off this list is recorded
409
+ * only when encountered during ordinary orientation reading.
410
+ *
411
+ * Assay-modality and replicate are deliberately absent: varying modality is already
412
+ * surfaced by group categories, and probing for replicates invites inferring replicate
413
+ * structure from sample counts, which is fabrication by another name.
414
+ */
415
+ export const DIMENSION_PROBES = [
416
+ {
417
+ id: "subject",
418
+ guidance: "Identifier slots in per-subject trees; subject-ID columns in clinical or sample tables. A reference-only tree is a legitimate not-found — a genome build's species is not a subject.",
419
+ },
420
+ { id: "sample", guidance: "Sample-ID slots or columns; sample sheets. Nests under subject when both exist." },
421
+ {
422
+ id: "cohort-arm",
423
+ guidance: "Arm or group columns whose values are assigned by design. An observed condition or diagnosis column is disease-state — answer not-found and point to where it landed. Observational data typically has no arms.",
424
+ },
425
+ { id: "timepoint", guidance: "Visit, day, or cycle columns; timepoint tokens in names. Acquisition and run dates are batch." },
426
+ { id: "batch", guidance: "Plate, lane, or run columns; run-date tokens; centre identifiers. Subject-visit time is timepoint." },
427
+ ];
428
+ // ── Lookups ────────────────────────────────────────────────────────────────
429
+ const GROUP_CATEGORY_BY_ID = new Map(GROUP_CATEGORIES.map((entry) => [entry.id, entry]));
430
+ const DIMENSION_CATEGORY_BY_ID = new Map(DIMENSION_CATEGORIES.map((entry) => [entry.id, entry]));
431
+ export function groupCategoryEntry(id) {
432
+ return GROUP_CATEGORY_BY_ID.get(id);
433
+ }
434
+ export function dimensionCategoryEntry(id) {
435
+ return DIMENSION_CATEGORY_BY_ID.get(id);
436
+ }
437
+ /**
438
+ * The scope a dimension takes.
439
+ *
440
+ * Derived from the category for everything in the catalogue. `other` is by definition
441
+ * outside it, so there is nothing to derive from and the scope is the agent's to declare:
442
+ * a biological thing that varies and has no category is still biological, and pinning
443
+ * every `other` to technical would misfile it. Undeclared, it defaults to technical.
444
+ */
445
+ export function dimensionScope(id, declared) {
446
+ if (id === "other")
447
+ return declared ?? "technical";
448
+ return DIMENSION_CATEGORY_BY_ID.get(id)?.scope ?? "technical";
449
+ }
@@ -305,9 +305,9 @@ export declare const StepBlockedPartSchema: z.ZodObject<{
305
305
  export declare const RunCompletedFindingSchema: z.ZodObject<{
306
306
  title: z.ZodString;
307
307
  confidence: z.ZodEnum<{
308
- high: "high";
309
- medium: "medium";
310
308
  low: "low";
309
+ medium: "medium";
310
+ high: "high";
311
311
  }>;
312
312
  }, z.core.$strip>;
313
313
  export declare const RunCompletedPartSchema: z.ZodObject<{
@@ -323,9 +323,9 @@ export declare const RunCompletedPartSchema: z.ZodObject<{
323
323
  findings: z.ZodArray<z.ZodObject<{
324
324
  title: z.ZodString;
325
325
  confidence: z.ZodEnum<{
326
- high: "high";
327
- medium: "medium";
328
326
  low: "low";
327
+ medium: "medium";
328
+ high: "high";
329
329
  }>;
330
330
  }, z.core.$strip>>;
331
331
  note: z.ZodOptional<z.ZodString>;
@@ -342,9 +342,9 @@ export declare const SynthesizedFindingSchema: z.ZodObject<{
342
342
  title: z.ZodString;
343
343
  description: z.ZodString;
344
344
  confidence: z.ZodEnum<{
345
- high: "high";
346
- medium: "medium";
347
345
  low: "low";
346
+ medium: "medium";
347
+ high: "high";
348
348
  }>;
349
349
  noveltyStatus: z.ZodEnum<{
350
350
  expected: "expected";
@@ -374,9 +374,9 @@ export declare const RunSynthesisPartSchema: z.ZodObject<{
374
374
  title: z.ZodString;
375
375
  description: z.ZodString;
376
376
  confidence: z.ZodEnum<{
377
- high: "high";
378
- medium: "medium";
379
377
  low: "low";
378
+ medium: "medium";
379
+ high: "high";
380
380
  }>;
381
381
  noveltyStatus: z.ZodEnum<{
382
382
  expected: "expected";
@@ -647,9 +647,9 @@ export declare const CortexChatPartSchema: z.ZodDiscriminatedUnion<[z.ZodObject<
647
647
  title: z.ZodString;
648
648
  description: z.ZodString;
649
649
  confidence: z.ZodEnum<{
650
- high: "high";
651
- medium: "medium";
652
650
  low: "low";
651
+ medium: "medium";
652
+ high: "high";
653
653
  }>;
654
654
  noveltyStatus: z.ZodEnum<{
655
655
  expected: "expected";
@@ -707,9 +707,9 @@ export declare const CortexChatPartSchema: z.ZodDiscriminatedUnion<[z.ZodObject<
707
707
  findings: z.ZodArray<z.ZodObject<{
708
708
  title: z.ZodString;
709
709
  confidence: z.ZodEnum<{
710
- high: "high";
711
- medium: "medium";
712
710
  low: "low";
711
+ medium: "medium";
712
+ high: "high";
713
713
  }>;
714
714
  }, z.core.$strip>>;
715
715
  note: z.ZodOptional<z.ZodString>;
@@ -8,8 +8,8 @@
8
8
  import { z } from "zod";
9
9
  export declare const SEVERITIES: readonly ["high", "medium", "low"];
10
10
  export declare const SeveritySchema: z.ZodEnum<{
11
- high: "high";
12
- medium: "medium";
13
11
  low: "low";
12
+ medium: "medium";
13
+ high: "high";
14
14
  }>;
15
15
  export type Severity = (typeof SEVERITIES)[number];