@inflexa-ai/harness 0.6.0 → 0.7.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.
@@ -21,6 +21,14 @@ export const ReferenceSha256Schema = z.string().regex(SHA256, "Expected a lowerc
21
21
  * redistributes nothing — so the URL must be a real third-party https endpoint.
22
22
  */
23
23
  const ReferenceArtifactUrlSchema = z.url().refine((value) => value.startsWith("https://"), "Reference artifacts must be fetched over https");
24
+ /**
25
+ * Logical content format, independent of compression: a `.txt.gz` mapping table
26
+ * is `tsv`, not `gz`. Agents pick a reader from this rather than guessing from
27
+ * the extension, so it stays a free token instead of an enum — a new source must
28
+ * remain cheap to add, and an unrecognized format degrades to "unknown reader"
29
+ * rather than failing catalog validation.
30
+ */
31
+ export const ReferenceArtifactFormatSchema = z.string().regex(/^[a-z0-9]+(?:[+-][a-z0-9]+)*$/, "Expected a lowercase format token");
24
32
  /**
25
33
  * One final file distributed for a reference dataset: a stable install-relative
26
34
  * path and the third-party https URL it is fetched from. The catalog carries no
@@ -30,17 +38,32 @@ const ReferenceArtifactUrlSchema = z.url().refine((value) => value.startsWith("h
30
38
  * one uniform trust-on-first-use model; there is deliberately no per-artifact
31
39
  * integrity class, so adding a source is only ever a URL, and no checked-in
32
40
  * digest is ours to maintain or lets go stale when a `current` upstream rebuilds.
41
+ *
42
+ * `format` and `contents` exist because skills name no paths: an agent asked for
43
+ * "a TF-target regulon network" can only match that against an inventory entry if
44
+ * the entry says what it holds and how to read it. `contents` should name the
45
+ * shape a caller must know — key columns, identifier space — not restate the title.
33
46
  */
34
47
  export const ReferenceArtifactSchema = z.strictObject({
35
48
  path: ReferenceArtifactPathSchema,
36
49
  url: ReferenceArtifactUrlSchema,
50
+ format: ReferenceArtifactFormatSchema,
51
+ contents: z.string().min(1),
37
52
  });
53
+ /**
54
+ * Common-name organism the dataset describes, lowercase (`human`, `mouse`, `rat`).
55
+ * Omitted for species-agnostic or multi-species sources. This is the axis a wrong
56
+ * choice is most silently wrong on — human regulons over mouse counts still run —
57
+ * so it is a first-class field rather than something inferred from the id suffix.
58
+ */
59
+ export const ReferenceOrganismSchema = z.string().regex(/^[a-z][a-z0-9]*(?:[ -][a-z0-9]+)*$/, "Expected a lowercase organism common name");
38
60
  /** Provenance and licensing information for one supported reference dataset. */
39
61
  export const ReferenceDatasetSchema = z.object({
40
62
  id: z.string().regex(SAFE_ID, "Expected a stable lowercase dataset id"),
41
63
  version: z.string().regex(SAFE_VERSION, "Expected a safe dataset version path segment"),
42
64
  title: z.string().min(1),
43
65
  description: z.string().min(1),
66
+ organism: ReferenceOrganismSchema.optional(),
44
67
  sourceUrl: z.url(),
45
68
  license: z.object({
46
69
  identifier: z.string().min(1),
@@ -97,9 +120,11 @@ function deepFreeze(value) {
97
120
  /**
98
121
  * Canonical release catalog. Every artifact is fetched directly from the third
99
122
  * party that publishes it; this project hosts, mirrors, and redistributes
100
- * nothing. Entries are added with a real upstream https URL, provenance, and
101
- * licensing data — and nothing else per file: no size, no digest to compute or
102
- * keep in sync.
123
+ * nothing. Entries are added with a real upstream https URL, provenance and
124
+ * licensing data, and a description of what the file holds — but never a size or
125
+ * digest to compute and keep in sync. The descriptive half is what makes a
126
+ * dataset findable: this catalog is the only place that says what a reference
127
+ * file is, so nothing downstream has to encode a path or a filename to use it.
103
128
  *
104
129
  * `version` is the dataset's upstream release identifier. Datasets built on an
105
130
  * upstream that has no immutable release — NCBI regenerates `gene_info` daily,
@@ -114,6 +139,7 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
114
139
  version: "current",
115
140
  title: "NCBI human gene identifiers",
116
141
  description: "Entrez Gene records for Homo sapiens (NCBI taxonomy 9606): identifiers, approved symbols, synonyms, and cross-references (Ensembl, HGNC) in the dbXrefs column. Tab-separated, gzipped. NCBI rebuilds this file in place, so it is verified against what you downloaded rather than a checked-in digest.",
142
+ organism: "human",
117
143
  sourceUrl: "https://ftp.ncbi.nlm.nih.gov/gene/DATA/GENE_INFO/Mammalia/",
118
144
  license: {
119
145
  identifier: "NCBI-Molecular-Data-Usage-Policy",
@@ -124,6 +150,8 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
124
150
  {
125
151
  path: "Homo_sapiens.gene_info.gz",
126
152
  url: "https://ftp.ncbi.nlm.nih.gov/gene/DATA/GENE_INFO/Mammalia/Homo_sapiens.gene_info.gz",
153
+ format: "tsv",
154
+ contents: "One row per gene, gzipped, header line prefixed '#'. Key columns: GeneID (Entrez), Symbol (HGNC), Synonyms, dbXrefs (holds Ensembl: and HGNC: cross-references, '|'-separated), type_of_gene.",
127
155
  },
128
156
  ],
129
157
  },
@@ -132,6 +160,7 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
132
160
  version: "current",
133
161
  title: "NCBI mouse gene identifiers",
134
162
  description: "Entrez Gene records for Mus musculus (NCBI taxonomy 10090): identifiers, approved symbols, synonyms, and cross-references (Ensembl, MGI) in the dbXrefs column. Tab-separated, gzipped. NCBI rebuilds this file in place, so it is verified against what you downloaded rather than a checked-in digest.",
163
+ organism: "mouse",
135
164
  sourceUrl: "https://ftp.ncbi.nlm.nih.gov/gene/DATA/GENE_INFO/Mammalia/",
136
165
  license: {
137
166
  identifier: "NCBI-Molecular-Data-Usage-Policy",
@@ -142,6 +171,8 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
142
171
  {
143
172
  path: "Mus_musculus.gene_info.gz",
144
173
  url: "https://ftp.ncbi.nlm.nih.gov/gene/DATA/GENE_INFO/Mammalia/Mus_musculus.gene_info.gz",
174
+ format: "tsv",
175
+ contents: "One row per gene, gzipped, header line prefixed '#'. Key columns: GeneID (Entrez), Symbol (MGI), Synonyms, dbXrefs (holds Ensembl: and MGI: cross-references, '|'-separated), type_of_gene.",
145
176
  },
146
177
  ],
147
178
  },
@@ -150,6 +181,7 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
150
181
  version: "current",
151
182
  title: "NCBI rat gene identifiers",
152
183
  description: "Entrez Gene records for Rattus norvegicus (NCBI taxonomy 10116): identifiers, approved symbols, synonyms, and cross-references (Ensembl, RGD) in the dbXrefs column. Tab-separated, gzipped. NCBI rebuilds this file in place, so it is verified against what you downloaded rather than a checked-in digest.",
184
+ organism: "rat",
153
185
  sourceUrl: "https://ftp.ncbi.nlm.nih.gov/gene/DATA/GENE_INFO/Mammalia/",
154
186
  license: {
155
187
  identifier: "NCBI-Molecular-Data-Usage-Policy",
@@ -160,6 +192,8 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
160
192
  {
161
193
  path: "Rattus_norvegicus.gene_info.gz",
162
194
  url: "https://ftp.ncbi.nlm.nih.gov/gene/DATA/GENE_INFO/Mammalia/Rattus_norvegicus.gene_info.gz",
195
+ format: "tsv",
196
+ contents: "One row per gene, gzipped, header line prefixed '#'. Key columns: GeneID (Entrez), Symbol (RGD), Synonyms, dbXrefs (holds Ensembl: and RGD: cross-references, '|'-separated), type_of_gene.",
163
197
  },
164
198
  ],
165
199
  },
@@ -176,7 +210,14 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
176
210
  url: "https://www.ncbi.nlm.nih.gov/home/about/policies/",
177
211
  },
178
212
  recommendation: { group: "gene-identifiers", recommended: false },
179
- artifacts: [{ path: "gene2ensembl.gz", url: "https://ftp.ncbi.nlm.nih.gov/gene/DATA/gene2ensembl.gz" }],
213
+ artifacts: [
214
+ {
215
+ path: "gene2ensembl.gz",
216
+ url: "https://ftp.ncbi.nlm.nih.gov/gene/DATA/gene2ensembl.gz",
217
+ format: "tsv",
218
+ contents: "Every species in one gzipped table — filter on #tax_id first (9606 human, 10090 mouse, 10116 rat). Columns: #tax_id, GeneID, Ensembl_gene_identifier, RNA_nucleotide_accession.version, Ensembl_rna_identifier, protein_accession.version, Ensembl_protein_identifier.",
219
+ },
220
+ ],
180
221
  },
181
222
  {
182
223
  // ~2.2 GB all-species monolithic table — the largest catalog entry. Opt-in like reactome-mappings.
@@ -190,13 +231,21 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
190
231
  url: "https://www.ncbi.nlm.nih.gov/home/about/policies/",
191
232
  },
192
233
  recommendation: { group: "gene-identifiers", recommended: false },
193
- artifacts: [{ path: "gene2refseq.gz", url: "https://ftp.ncbi.nlm.nih.gov/gene/DATA/gene2refseq.gz" }],
234
+ artifacts: [
235
+ {
236
+ path: "gene2refseq.gz",
237
+ url: "https://ftp.ncbi.nlm.nih.gov/gene/DATA/gene2refseq.gz",
238
+ format: "tsv",
239
+ contents: "Every species in one gzipped table (~2.2 GB) — filter on #tax_id first, and prefer a streaming read. Columns: #tax_id, GeneID, status, RNA_nucleotide_accession.version, protein_accession.version, genomic_nucleotide_accession.version, Symbol.",
240
+ },
241
+ ],
194
242
  },
195
243
  {
196
244
  id: "uniprot-idmapping-human",
197
245
  version: "current",
198
246
  title: "UniProt human ID mapping",
199
247
  description: "UniProtKB accession ↔ Entrez, Ensembl, RefSeq and other identifiers for Homo sapiens (idmapping_selected, ~61 MB gzipped). UniProt overwrites `current_release` each cycle, so it is verified against what you downloaded rather than a checked-in digest.",
248
+ organism: "human",
200
249
  sourceUrl: "https://ftp.uniprot.org/pub/databases/uniprot/current_release/knowledgebase/idmapping/by_organism/",
201
250
  license: { identifier: "CC-BY-4.0", url: "https://www.uniprot.org/help/license" },
202
251
  recommendation: { group: "gene-identifiers", recommended: true },
@@ -204,6 +253,8 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
204
253
  {
205
254
  path: "HUMAN_9606_idmapping_selected.tab.gz",
206
255
  url: "https://ftp.uniprot.org/pub/databases/uniprot/current_release/knowledgebase/idmapping/by_organism/HUMAN_9606_idmapping_selected.tab.gz",
256
+ format: "tsv",
257
+ contents: "Gzipped, 22 columns, NO header. Positional: 1 UniProtKB-AC, 2 UniProtKB-ID, 3 GeneID (Entrez), 4 RefSeq, 19 Ensembl, 20 Ensembl_TRS, 21 Ensembl_PRO. Multi-valued cells are '; '-separated.",
207
258
  },
208
259
  ],
209
260
  },
@@ -212,6 +263,7 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
212
263
  version: "current",
213
264
  title: "UniProt mouse ID mapping",
214
265
  description: "UniProtKB accession ↔ Entrez, Ensembl, RefSeq and other identifiers for Mus musculus (idmapping_selected, ~18 MB gzipped). UniProt overwrites `current_release` each cycle, so it is verified against what you downloaded rather than a checked-in digest.",
266
+ organism: "mouse",
215
267
  sourceUrl: "https://ftp.uniprot.org/pub/databases/uniprot/current_release/knowledgebase/idmapping/by_organism/",
216
268
  license: { identifier: "CC-BY-4.0", url: "https://www.uniprot.org/help/license" },
217
269
  recommendation: { group: "gene-identifiers", recommended: true },
@@ -219,6 +271,8 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
219
271
  {
220
272
  path: "MOUSE_10090_idmapping_selected.tab.gz",
221
273
  url: "https://ftp.uniprot.org/pub/databases/uniprot/current_release/knowledgebase/idmapping/by_organism/MOUSE_10090_idmapping_selected.tab.gz",
274
+ format: "tsv",
275
+ contents: "Gzipped, 22 columns, NO header. Positional: 1 UniProtKB-AC, 2 UniProtKB-ID, 3 GeneID (Entrez), 4 RefSeq, 19 Ensembl, 20 Ensembl_TRS, 21 Ensembl_PRO. Multi-valued cells are '; '-separated.",
222
276
  },
223
277
  ],
224
278
  },
@@ -227,6 +281,7 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
227
281
  version: "current",
228
282
  title: "UniProt rat ID mapping",
229
283
  description: "UniProtKB accession ↔ Entrez, Ensembl, RefSeq and other identifiers for Rattus norvegicus (idmapping_selected, ~6 MB gzipped). UniProt overwrites `current_release` each cycle, so it is verified against what you downloaded rather than a checked-in digest.",
284
+ organism: "rat",
230
285
  sourceUrl: "https://ftp.uniprot.org/pub/databases/uniprot/current_release/knowledgebase/idmapping/by_organism/",
231
286
  license: { identifier: "CC-BY-4.0", url: "https://www.uniprot.org/help/license" },
232
287
  recommendation: { group: "gene-identifiers", recommended: true },
@@ -234,6 +289,8 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
234
289
  {
235
290
  path: "RAT_10116_idmapping_selected.tab.gz",
236
291
  url: "https://ftp.uniprot.org/pub/databases/uniprot/current_release/knowledgebase/idmapping/by_organism/RAT_10116_idmapping_selected.tab.gz",
292
+ format: "tsv",
293
+ contents: "Gzipped, 22 columns, NO header. Positional: 1 UniProtKB-AC, 2 UniProtKB-ID, 3 GeneID (Entrez), 4 RefSeq, 19 Ensembl, 20 Ensembl_TRS, 21 Ensembl_PRO. Multi-valued cells are '; '-separated.",
237
294
  },
238
295
  ],
239
296
  },
@@ -246,8 +303,18 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
246
303
  license: { identifier: "CC0-1.0", url: "https://reactome.org/license" },
247
304
  recommendation: { group: "pathways", recommended: true },
248
305
  artifacts: [
249
- { path: "ReactomePathways.gmt", url: "https://reactome.org/download/current/ReactomePathways.gmt" },
250
- { path: "ReactomePathways.txt", url: "https://reactome.org/download/current/ReactomePathways.txt" },
306
+ {
307
+ path: "ReactomePathways.gmt",
308
+ url: "https://reactome.org/download/current/ReactomePathways.gmt",
309
+ format: "gmt",
310
+ contents: "One pathway per line, tab-separated: pathway name, Reactome stable ID, then member gene symbols. Covers every Reactome species in one file — filter by pathway name suffix or join ReactomePathways.txt to restrict to one.",
311
+ },
312
+ {
313
+ path: "ReactomePathways.txt",
314
+ url: "https://reactome.org/download/current/ReactomePathways.txt",
315
+ format: "tsv",
316
+ contents: "Pathway index, no header: stable ID, display name, species name. Join on stable ID to restrict the GMT to one species.",
317
+ },
251
318
  ],
252
319
  },
253
320
  {
@@ -266,14 +333,20 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
266
333
  {
267
334
  path: "NCBI2Reactome_All_Levels.txt",
268
335
  url: "https://reactome.org/download/current/NCBI2Reactome_All_Levels.txt",
336
+ format: "tsv",
337
+ contents: "No header, every species: Entrez gene ID, Reactome pathway stable ID, pathway URL, pathway name, evidence code, species name. Filter on the species column.",
269
338
  },
270
339
  {
271
340
  path: "Ensembl2Reactome_All_Levels.txt",
272
341
  url: "https://reactome.org/download/current/Ensembl2Reactome_All_Levels.txt",
342
+ format: "tsv",
343
+ contents: "No header, every species: Ensembl gene ID, Reactome pathway stable ID, pathway URL, pathway name, evidence code, species name. Filter on the species column.",
273
344
  },
274
345
  {
275
346
  path: "UniProt2Reactome_All_Levels.txt",
276
347
  url: "https://reactome.org/download/current/UniProt2Reactome_All_Levels.txt",
348
+ format: "tsv",
349
+ contents: "No header, every species: UniProtKB accession, Reactome pathway stable ID, pathway URL, pathway name, evidence code, species name. Filter on the species column.",
277
350
  },
278
351
  ],
279
352
  },
@@ -282,6 +355,7 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
282
355
  version: "2026.07.10",
283
356
  title: "WikiPathways human pathways",
284
357
  description: "Community-curated Homo sapiens pathway gene sets (GMT) from the immutable 2026-07-10 WikiPathways snapshot.",
358
+ organism: "human",
285
359
  sourceUrl: "https://data.wikipathways.org/20260710/gmt/",
286
360
  license: { identifier: "CC0-1.0", url: "https://www.wikipathways.org/about/terms.html" },
287
361
  recommendation: { group: "pathways", recommended: true },
@@ -289,6 +363,8 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
289
363
  {
290
364
  path: "wikipathways_Homo_sapiens.gmt",
291
365
  url: "https://data.wikipathways.org/20260710/gmt/wikipathways-20260710-gmt-Homo_sapiens.gmt",
366
+ format: "gmt",
367
+ contents: "One pathway per line, tab-separated: '%'-delimited descriptor (name, WikiPathways ID, species), pathway URL, then member gene symbols (HGNC). Split the first field on '%' to recover a readable set name.",
292
368
  },
293
369
  ],
294
370
  },
@@ -297,6 +373,7 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
297
373
  version: "2026.07.10",
298
374
  title: "WikiPathways mouse pathways",
299
375
  description: "Community-curated Mus musculus pathway gene sets (GMT) from the immutable 2026-07-10 WikiPathways snapshot.",
376
+ organism: "mouse",
300
377
  sourceUrl: "https://data.wikipathways.org/20260710/gmt/",
301
378
  license: { identifier: "CC0-1.0", url: "https://www.wikipathways.org/about/terms.html" },
302
379
  recommendation: { group: "pathways", recommended: true },
@@ -304,6 +381,8 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
304
381
  {
305
382
  path: "wikipathways_Mus_musculus.gmt",
306
383
  url: "https://data.wikipathways.org/20260710/gmt/wikipathways-20260710-gmt-Mus_musculus.gmt",
384
+ format: "gmt",
385
+ contents: "One pathway per line, tab-separated: '%'-delimited descriptor (name, WikiPathways ID, species), pathway URL, then member gene symbols (MGI). Split the first field on '%' to recover a readable set name.",
307
386
  },
308
387
  ],
309
388
  },
@@ -312,6 +391,7 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
312
391
  version: "2026.07.10",
313
392
  title: "WikiPathways rat pathways",
314
393
  description: "Community-curated Rattus norvegicus pathway gene sets (GMT) from the immutable 2026-07-10 WikiPathways snapshot.",
394
+ organism: "rat",
315
395
  sourceUrl: "https://data.wikipathways.org/20260710/gmt/",
316
396
  license: { identifier: "CC0-1.0", url: "https://www.wikipathways.org/about/terms.html" },
317
397
  recommendation: { group: "pathways", recommended: true },
@@ -319,6 +399,8 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
319
399
  {
320
400
  path: "wikipathways_Rattus_norvegicus.gmt",
321
401
  url: "https://data.wikipathways.org/20260710/gmt/wikipathways-20260710-gmt-Rattus_norvegicus.gmt",
402
+ format: "gmt",
403
+ contents: "One pathway per line, tab-separated: '%'-delimited descriptor (name, WikiPathways ID, species), pathway URL, then member gene symbols (RGD). Split the first field on '%' to recover a readable set name.",
322
404
  },
323
405
  ],
324
406
  },
@@ -327,6 +409,7 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
327
409
  version: "2026.1",
328
410
  title: "MSigDB human hallmark gene sets",
329
411
  description: "The 50 MSigDB hallmark gene sets for Homo sapiens (symbols GMT) — coherent, well-defined biological states and processes for enrichment. From the immutable MSigDB 2026.1 human release.",
412
+ organism: "human",
330
413
  sourceUrl: "https://data.broadinstitute.org/gsea-msigdb/msigdb/",
331
414
  license: { identifier: "MSigDB-License", url: "https://www.gsea-msigdb.org/gsea/msigdb/license.jsp" },
332
415
  recommendation: { group: "pathways", recommended: true },
@@ -334,6 +417,8 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
334
417
  {
335
418
  path: "h.all.v2026.1.Hs.symbols.gmt",
336
419
  url: "https://data.broadinstitute.org/gsea-msigdb/msigdb/release/2026.1.Hs/h.all.v2026.1.Hs.symbols.gmt",
420
+ format: "gmt",
421
+ contents: "50 hallmark sets, one per line, tab-separated: set name (HALLMARK_*), source URL, then member gene symbols (HGNC). Hallmark only — the C2/C5/C6/C7/C8 collections are not part of this dataset.",
337
422
  },
338
423
  ],
339
424
  },
@@ -342,6 +427,7 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
342
427
  version: "2026.1",
343
428
  title: "MSigDB mouse hallmark gene sets",
344
429
  description: "The MSigDB mouse hallmark gene sets for Mus musculus (symbols GMT) — the murine ortholog-mapped hallmark collection for enrichment. From the immutable MSigDB 2026.1 mouse release.",
430
+ organism: "mouse",
345
431
  sourceUrl: "https://data.broadinstitute.org/gsea-msigdb/msigdb/",
346
432
  license: { identifier: "MSigDB-License", url: "https://www.gsea-msigdb.org/gsea/msigdb/license.jsp" },
347
433
  recommendation: { group: "pathways", recommended: true },
@@ -349,6 +435,8 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
349
435
  {
350
436
  path: "mh.all.v2026.1.Mm.symbols.gmt",
351
437
  url: "https://data.broadinstitute.org/gsea-msigdb/msigdb/release/2026.1.Mm/mh.all.v2026.1.Mm.symbols.gmt",
438
+ format: "gmt",
439
+ contents: "Mouse hallmark sets, one per line, tab-separated: set name, source URL, then member gene symbols (MGI). Hallmark only — the C2/C5/C6/C7/C8 collections are not part of this dataset.",
352
440
  },
353
441
  ],
354
442
  },
@@ -357,6 +445,7 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
357
445
  version: "2.0",
358
446
  title: "CollecTRI human regulatory network",
359
447
  description: "A literature-curated human transcription-factor target interaction network (CSV) from the immutable Zenodo record 8192729.",
448
+ organism: "human",
360
449
  sourceUrl: "https://zenodo.org/records/8192729",
361
450
  license: { identifier: "CC-BY-4.0", url: "https://zenodo.org/records/8192729" },
362
451
  recommendation: { group: "regulatory-networks", recommended: true },
@@ -364,6 +453,83 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
364
453
  {
365
454
  path: "CollecTRI_regulons.csv",
366
455
  url: "https://zenodo.org/records/8192729/files/CollecTRI_regulons.csv",
456
+ format: "csv",
457
+ contents: "TF-target regulons, one interaction per row: source (TF symbol), target (gene symbol), weight (+1 activating, -1 repressing), then curation provenance columns. This is the prior a TF-activity method consumes — read it with a CSV reader and pass the frame directly as decoupler's network argument. It is CSV, not Parquet.",
458
+ },
459
+ ],
460
+ },
461
+ {
462
+ // Sourced from the package repository's data/ directory rather than the OmniPath web
463
+ // service that `dc.op.progeny()` calls: a live query endpoint is not an artifact, and
464
+ // an install that depends on one breaks whenever the service does.
465
+ id: "progeny-human",
466
+ version: "current",
467
+ title: "PROGENy human pathway weights",
468
+ description: "PROGENy footprint-based pathway responsive genes for Homo sapiens — per-gene weights for 14 signalling pathways (EGFR, MAPK, PI3K, TNFa, p53, Hypoxia and others), the standard prior for pathway-activity inference from expression. Tracks the package's default branch, so it is verified against what you downloaded rather than a checked-in digest.",
469
+ organism: "human",
470
+ sourceUrl: "https://github.com/saezlab/progeny",
471
+ license: { identifier: "Apache-2.0", url: "https://github.com/saezlab/progeny/blob/master/LICENSE" },
472
+ recommendation: { group: "pathway-activity", recommended: true },
473
+ artifacts: [
474
+ {
475
+ path: "model_human_full.rda",
476
+ url: "https://raw.githubusercontent.com/saezlab/progeny/master/data/model_human_full.rda",
477
+ format: "rda",
478
+ contents: "R serialized data frame `model_human_full` of pathway weights: columns gene, weight, p.value, pathway. Load in R with load(); from Python read it through rpy2 rather than a pandas reader. Rename to source/target/weight if a decoupler-style network is expected.",
479
+ },
480
+ ],
481
+ },
482
+ {
483
+ id: "progeny-mouse",
484
+ version: "current",
485
+ title: "PROGENy mouse pathway weights",
486
+ description: "PROGENy footprint-based pathway responsive genes for Mus musculus — per-gene weights for 14 signalling pathways, the standard prior for pathway-activity inference from expression. Tracks the package's default branch, so it is verified against what you downloaded rather than a checked-in digest.",
487
+ organism: "mouse",
488
+ sourceUrl: "https://github.com/saezlab/progeny",
489
+ license: { identifier: "Apache-2.0", url: "https://github.com/saezlab/progeny/blob/master/LICENSE" },
490
+ recommendation: { group: "pathway-activity", recommended: true },
491
+ artifacts: [
492
+ {
493
+ path: "model_mouse_full.rda",
494
+ url: "https://raw.githubusercontent.com/saezlab/progeny/master/data/model_mouse_full.rda",
495
+ format: "rda",
496
+ contents: "R serialized data frame `model_mouse_full` of pathway weights: columns gene, weight, p.value, pathway. Load in R with load(); from Python read it through rpy2 rather than a pandas reader. Rename to source/target/weight if a decoupler-style network is expected.",
497
+ },
498
+ ],
499
+ },
500
+ {
501
+ id: "dorothea-human",
502
+ version: "current",
503
+ title: "DoRothEA human TF regulons",
504
+ description: "DoRothEA transcription-factor regulons for Homo sapiens with per-interaction confidence levels A-E, where A is the best-supported. The confidence-filtered alternative to CollecTRI for TF-activity inference; most analyses keep levels A-C. Tracks the package's default branch, so it is verified against what you downloaded rather than a checked-in digest.",
505
+ organism: "human",
506
+ sourceUrl: "https://github.com/saezlab/dorothea",
507
+ license: { identifier: "GPL-3.0", url: "https://github.com/saezlab/dorothea/blob/master/LICENSE" },
508
+ recommendation: { group: "regulatory-networks", recommended: true },
509
+ artifacts: [
510
+ {
511
+ path: "dorothea_hs.rda",
512
+ url: "https://raw.githubusercontent.com/saezlab/dorothea/master/data/dorothea_hs.rda",
513
+ format: "rda",
514
+ contents: "R serialized data frame `dorothea_hs` of TF-target regulons: columns tf, confidence (A-E), target, mor (+1 activating, -1 repressing). Load in R with load(); from Python read it through rpy2. Filter on confidence before use, then rename tf/target/mor to source/target/weight for a decoupler-style network.",
515
+ },
516
+ ],
517
+ },
518
+ {
519
+ id: "dorothea-mouse",
520
+ version: "current",
521
+ title: "DoRothEA mouse TF regulons",
522
+ description: "DoRothEA transcription-factor regulons for Mus musculus with per-interaction confidence levels A-E, where A is the best-supported. The confidence-filtered alternative to CollecTRI for TF-activity inference; most analyses keep levels A-C. Tracks the package's default branch, so it is verified against what you downloaded rather than a checked-in digest.",
523
+ organism: "mouse",
524
+ sourceUrl: "https://github.com/saezlab/dorothea",
525
+ license: { identifier: "GPL-3.0", url: "https://github.com/saezlab/dorothea/blob/master/LICENSE" },
526
+ recommendation: { group: "regulatory-networks", recommended: true },
527
+ artifacts: [
528
+ {
529
+ path: "dorothea_mm.rda",
530
+ url: "https://raw.githubusercontent.com/saezlab/dorothea/master/data/dorothea_mm.rda",
531
+ format: "rda",
532
+ contents: "R serialized data frame `dorothea_mm` of TF-target regulons: columns tf, confidence (A-E), target, mor (+1 activating, -1 repressing). Load in R with load(); from Python read it through rpy2. Filter on confidence before use, then rename tf/target/mor to source/target/weight for a decoupler-style network.",
367
533
  },
368
534
  ],
369
535
  },
@@ -372,6 +538,7 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
372
538
  version: "8",
373
539
  title: "GTEx v8 normal tissue expression",
374
540
  description: "GTEx v8 median gene TPM by tissue (GCT) with the sample attributes table, for normal-reference workflows. Immutable v8 release files.",
541
+ organism: "human",
375
542
  sourceUrl: "https://gtexportal.org/home/downloads/adult-gtex/bulk_tissue_expression",
376
543
  license: { identifier: "GTEx-Portal-Data-License", url: "https://gtexportal.org/home/license" },
377
544
  recommendation: { group: "normal-expression", recommended: true },
@@ -379,10 +546,14 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
379
546
  {
380
547
  path: "GTEx_Analysis_2017-06-05_v8_RNASeQCv1.1.9_gene_median_tpm.gct.gz",
381
548
  url: "https://storage.googleapis.com/adult-gtex/bulk-gex/v8/rna-seq/GTEx_Analysis_2017-06-05_v8_RNASeQCv1.1.9_gene_median_tpm.gct.gz",
549
+ format: "gct",
550
+ contents: "Gzipped GCT: skip 2 header lines, then columns Name (versioned Ensembl gene ID — strip the suffix to join) and Description (symbol), followed by one median-TPM column per tissue.",
382
551
  },
383
552
  {
384
553
  path: "GTEx_Analysis_v8_Annotations_SampleAttributesDS.txt",
385
554
  url: "https://storage.googleapis.com/adult-gtex/annotations/v8/metadata-files/GTEx_Analysis_v8_Annotations_SampleAttributesDS.txt",
555
+ format: "tsv",
556
+ contents: "Per-sample attributes; key columns SAMPID, SMTS (tissue) and SMTSD (detailed tissue). Only needed to interpret or regroup the tissue columns.",
386
557
  },
387
558
  ],
388
559
  },
@@ -391,16 +562,25 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
391
562
  version: "current",
392
563
  title: "Human Protein Atlas",
393
564
  description: "The full Human Protein Atlas table (proteinatlas.tsv.zip, ~7 MB): per-gene RNA/protein tissue expression, tissue specificity, subcellular location, secretome and blood-concentration annotations for Homo sapiens. HPA republishes this file per release, so it is verified against what you downloaded rather than a checked-in digest.",
565
+ organism: "human",
394
566
  sourceUrl: "https://www.proteinatlas.org/about/download",
395
567
  license: { identifier: "CC-BY-SA-3.0", url: "https://www.proteinatlas.org/about/licence" },
396
568
  recommendation: { group: "normal-expression", recommended: true },
397
- artifacts: [{ path: "proteinatlas.tsv.zip", url: "https://www.proteinatlas.org/download/proteinatlas.tsv.zip" }],
569
+ artifacts: [
570
+ {
571
+ path: "proteinatlas.tsv.zip",
572
+ url: "https://www.proteinatlas.org/download/proteinatlas.tsv.zip",
573
+ format: "zip",
574
+ contents: "Zip holding a single proteinatlas.tsv — one row per gene with Ensembl and Gene columns plus RNA/protein tissue expression, tissue specificity, subcellular location, secretome and blood-concentration annotations. Read the member from the archive; do not expect a bare .tsv on disk.",
575
+ },
576
+ ],
398
577
  },
399
578
  {
400
579
  id: "celltypist-immune",
401
580
  version: "2",
402
581
  title: "CellTypist immune cell models",
403
582
  description: "CellTypist Immune All low- and high-resolution models for immune cell-type annotation. Load by absolute path — CellTypist's by-name lookup expects its own cache layout, which the reference store deliberately does not impersonate.",
583
+ organism: "human",
404
584
  sourceUrl: "https://www.celltypist.org/models",
405
585
  license: { identifier: "NOASSERTION" },
406
586
  recommendation: { group: "cell-typing", recommended: true },
@@ -408,10 +588,14 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
408
588
  {
409
589
  path: "Immune_All_Low.pkl",
410
590
  url: "https://celltypist.cog.sanger.ac.uk/models/Pan_Immune_CellTypist/v2/Immune_All_Low.pkl",
591
+ format: "pickle",
592
+ contents: "Trained CellTypist model, fine-grained immune labels. Load by absolute path through CellTypist's model loader; passing the bare name makes it search its own cache and fail.",
411
593
  },
412
594
  {
413
595
  path: "Immune_All_High.pkl",
414
596
  url: "https://celltypist.cog.sanger.ac.uk/models/Pan_Immune_CellTypist/v2/Immune_All_High.pkl",
597
+ format: "pickle",
598
+ contents: "Trained CellTypist model, coarse-grained immune labels. Load by absolute path through CellTypist's model loader; passing the bare name makes it search its own cache and fail.",
415
599
  },
416
600
  ],
417
601
  },
@@ -420,6 +604,7 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
420
604
  version: "2",
421
605
  title: "CellTypist pan-fetal human model",
422
606
  description: "CellTypist Pan_Fetal_Human model — cell-type annotation across human fetal tissues. Load by absolute path; CellTypist's by-name lookup expects its own cache layout, which the reference store deliberately does not impersonate.",
607
+ organism: "human",
423
608
  sourceUrl: "https://www.celltypist.org/models",
424
609
  license: { identifier: "NOASSERTION" },
425
610
  recommendation: { group: "cell-typing", recommended: true },
@@ -427,6 +612,8 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
427
612
  {
428
613
  path: "Pan_Fetal_Human.pkl",
429
614
  url: "https://celltypist.cog.sanger.ac.uk/models/Pan_Fetal_Suo/v2/Pan_Fetal_Human.pkl",
615
+ format: "pickle",
616
+ contents: "Trained CellTypist model covering human fetal tissues. Load by absolute path through CellTypist's model loader; passing the bare name makes it search its own cache and fail.",
430
617
  },
431
618
  ],
432
619
  },
@@ -435,6 +622,7 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
435
622
  version: "1",
436
623
  title: "CellTypist COVID-19 immune model",
437
624
  description: "CellTypist COVID19_Immune_Landscape model — immune cell-type annotation trained on the cross-study COVID-19 immune atlas. Load by absolute path; CellTypist's by-name lookup expects its own cache layout, which the reference store deliberately does not impersonate.",
625
+ organism: "human",
438
626
  sourceUrl: "https://www.celltypist.org/models",
439
627
  license: { identifier: "NOASSERTION" },
440
628
  recommendation: { group: "cell-typing", recommended: true },
@@ -442,6 +630,8 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
442
630
  {
443
631
  path: "COVID19_Immune_Landscape.pkl",
444
632
  url: "https://celltypist.cog.sanger.ac.uk/models/COVID19_Immune_Ren/v1/COVID19_Immune_Landscape.pkl",
633
+ format: "pickle",
634
+ contents: "Trained CellTypist model from the cross-study COVID-19 immune atlas. Load by absolute path through CellTypist's model loader; passing the bare name makes it search its own cache and fail.",
445
635
  },
446
636
  ],
447
637
  },
@@ -457,6 +647,8 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
457
647
  {
458
648
  path: "PanglaoDB_markers_27_Mar_2020.tsv.gz",
459
649
  url: "https://panglaodb.se/markers/PanglaoDB_markers_27_Mar_2020.tsv.gz",
650
+ format: "tsv",
651
+ contents: "Gzipped marker table covering human and mouse together — filter the species column ('Hs', 'Mm', or both) before use. Key columns: species, official gene symbol, cell type, organ, ubiquitousness index.",
460
652
  },
461
653
  ],
462
654
  },
@@ -465,6 +657,7 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
465
657
  version: "1.0.0",
466
658
  title: "Azimuth human PBMC reference",
467
659
  description: "Azimuth annotated reference for human peripheral blood mononuclear cells: the Seurat reference object plus its Annoy nearest-neighbour index, for supervised mapping and cell-type label transfer. Immutable Zenodo release 4546839.",
660
+ organism: "human",
468
661
  sourceUrl: "https://zenodo.org/records/4546839",
469
662
  license: { identifier: "CC-BY-4.0", url: "https://zenodo.org/records/4546839" },
470
663
  recommendation: { group: "cell-typing", recommended: true },
@@ -472,10 +665,14 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
472
665
  {
473
666
  path: "ref.Rds",
474
667
  url: "https://zenodo.org/records/4546839/files/ref.Rds",
668
+ format: "rds",
669
+ contents: "Seurat reference object (PBMC) for Azimuth label transfer, read with readRDS. Requires idx.annoy in the same directory.",
475
670
  },
476
671
  {
477
672
  path: "idx.annoy",
478
673
  url: "https://zenodo.org/records/4546839/files/idx.annoy",
674
+ format: "annoy",
675
+ contents: "Annoy neighbour index paired with ref.Rds. Never opened directly — Azimuth loads it via the reference object, which needs both files side by side.",
479
676
  },
480
677
  ],
481
678
  },
@@ -485,6 +682,7 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
485
682
  version: "1.0.0",
486
683
  title: "Azimuth human tonsil reference",
487
684
  description: "Azimuth annotated reference for human tonsil: the Seurat reference object plus its Annoy nearest-neighbour index, for supervised mapping and cell-type label transfer. Immutable Zenodo release 7032928, roughly 443 MB.",
685
+ organism: "human",
488
686
  sourceUrl: "https://zenodo.org/records/7032928",
489
687
  license: { identifier: "CC-BY-4.0", url: "https://zenodo.org/records/7032928" },
490
688
  recommendation: { group: "cell-typing", recommended: false },
@@ -492,10 +690,14 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
492
690
  {
493
691
  path: "ref.Rds",
494
692
  url: "https://zenodo.org/records/7032928/files/ref.Rds",
693
+ format: "rds",
694
+ contents: "Seurat reference object (tonsil) for Azimuth label transfer, read with readRDS. Requires idx.annoy in the same directory.",
495
695
  },
496
696
  {
497
697
  path: "idx.annoy",
498
698
  url: "https://zenodo.org/records/7032928/files/idx.annoy",
699
+ format: "annoy",
700
+ contents: "Annoy neighbour index paired with ref.Rds. Never opened directly — Azimuth loads it via the reference object, which needs both files side by side.",
499
701
  },
500
702
  ],
501
703
  },
@@ -505,6 +707,7 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
505
707
  version: "GRCh38.p13",
506
708
  title: "PharmCAT GRCh38 reference FASTA",
507
709
  description: "The GRCh38.p13 reference genome FASTA that PharmCAT's VCF preprocessor expects (bgzip'd with a .fai/.gzi faidx), bundled as a tar — roughly 842 MB. Immutable Zenodo release 7288118. Needed only for pharmacogenomics (PharmCAT) workflows.",
710
+ organism: "human",
508
711
  sourceUrl: "https://zenodo.org/records/7288118",
509
712
  license: { identifier: "CC-BY-4.0", url: "https://zenodo.org/records/7288118" },
510
713
  recommendation: { group: "pharmacogenomics", recommended: false },
@@ -512,6 +715,8 @@ export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.pars
512
715
  {
513
716
  path: "PharmCAT_GRCh38_reference_fasta.tar",
514
717
  url: "https://zenodo.org/records/7288118/files/GRCh38_reference_fasta.tar?download=1",
718
+ format: "tar",
719
+ contents: "Tar bundle of the GRCh38.p13 bgzip-compressed FASTA with its .fai and .gzi indexes. Extract to a writable directory first, then point the tool at the extracted .fna.bgz — the store is read-only, and nothing reads this tar in place.",
515
720
  },
516
721
  ],
517
722
  },
@@ -52,6 +52,18 @@ export interface DataProfileDeps {
52
52
  readonly embedding: EmbeddingProvider;
53
53
  /** Absolute path to the skills tree (one subdirectory per skill). */
54
54
  readonly skillsDir: string;
55
+ /**
56
+ * Host path of the library store's `packages.txt`. Omit when the host mounts the
57
+ * store at the sandbox's own path; a host whose store is baked into the image must
58
+ * inject its extracted copy, or the profiler reads the inventory as unknown.
59
+ */
60
+ readonly packagesFile?: string;
61
+ /**
62
+ * Host path of the reference store. Omit only when none is provisioned: the
63
+ * profiler carries reference discovery, and without this it reports an installed
64
+ * store as absent.
65
+ */
66
+ readonly refStorePath?: string;
55
67
  }
56
68
  /**
57
69
  * Workflow input. JSON-serialisable — DBOS persists it as the workflow's
@@ -216,6 +216,8 @@ export async function runDataProfileBody(input, deps) {
216
216
  embedding: deps.embedding,
217
217
  model: deps.model,
218
218
  skillsDir: deps.skillsDir,
219
+ ...(deps.packagesFile ? { packagesFile: deps.packagesFile } : {}),
220
+ ...(deps.refStorePath ? { refStorePath: deps.refStorePath } : {}),
219
221
  bioKeys: deps.bioKeys,
220
222
  step: {
221
223
  sandbox,
@@ -41,6 +41,13 @@ export interface GeneratePlanDeps {
41
41
  * default guidance and validation skips the ceiling check.
42
42
  */
43
43
  readonly resourcePolicy?: ResourcePolicy;
44
+ /**
45
+ * Host path of the reference store, giving the planner reference discovery.
46
+ * Absent, the tool reports the store as unavailable and the planner keeps
47
+ * planning as though nothing is guaranteed present — which is what the prompt
48
+ * already tells it to do.
49
+ */
50
+ readonly refStorePath?: string;
44
51
  }
45
52
  /** Build the `generate_plan` tool bound to its provider and pool. */
46
53
  export declare function createGeneratePlanTool(deps: GeneratePlanDeps): Tool;