@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.
- package/dist/agents/conversation-agent.js +7 -4
- package/dist/agents/report-session-agent.js +1 -1
- package/dist/agents/sandbox/data-profiler.js +0 -1
- package/dist/agents/sandbox/immune-profiling-agent.js +3 -1
- package/dist/agents/sandbox/network-agent.js +0 -1
- package/dist/agents/sandbox/types.d.ts +1 -1
- package/dist/agents/sandbox/types.js +1 -1
- package/dist/app/data-profile-orientation.d.ts +52 -27
- package/dist/app/data-profile-orientation.js +331 -92
- package/dist/app/data-profile-view.d.ts +70 -0
- package/dist/app/data-profile-view.js +123 -0
- package/dist/app/synthesize-run.js +1 -1
- package/dist/config/resource-limits.d.ts +1 -1
- package/dist/config/resource-limits.js +1 -1
- package/dist/contracts/data-profile.d.ts +276 -25
- package/dist/contracts/index.d.ts +3 -1
- package/dist/contracts/index.js +1 -0
- package/dist/contracts/profile-vocabulary.d.ts +103 -0
- package/dist/contracts/profile-vocabulary.js +449 -0
- package/dist/contracts/schemas/chat-parts.d.ts +12 -12
- package/dist/contracts/severity.d.ts +2 -2
- package/dist/contracts/target-dossier.d.ts +91 -91
- package/dist/data/safety-panel-schema.d.ts +4 -4
- package/dist/execution/input-signature.d.ts +16 -3
- package/dist/execution/input-signature.js +0 -0
- package/dist/execution/post-step-pipeline.js +1 -1
- package/dist/execution/staged-input.d.ts +4 -4
- package/dist/index.d.ts +7 -2
- package/dist/index.js +14 -0
- package/dist/input-scan/clustering.d.ts +63 -0
- package/dist/input-scan/clustering.js +208 -0
- package/dist/input-scan/companions.d.ts +30 -0
- package/dist/input-scan/companions.js +138 -0
- package/dist/input-scan/decoder/container_readout.py +171 -0
- package/dist/input-scan/detect-sets.d.ts +24 -0
- package/dist/input-scan/detect-sets.js +279 -0
- package/dist/input-scan/enrich.d.ts +62 -19
- package/dist/input-scan/enrich.js +132 -187
- package/dist/input-scan/formats.d.ts +13 -5
- package/dist/input-scan/formats.js +13 -5
- package/dist/input-scan/index.d.ts +10 -4
- package/dist/input-scan/index.js +7 -4
- package/dist/input-scan/markers.d.ts +21 -0
- package/dist/input-scan/markers.js +89 -0
- package/dist/input-scan/menu.d.ts +127 -0
- package/dist/input-scan/menu.js +0 -0
- package/dist/input-scan/quarantine.d.ts +17 -0
- package/dist/input-scan/quarantine.js +69 -0
- package/dist/input-scan/readout-budget.d.ts +32 -0
- package/dist/input-scan/readout-budget.js +61 -0
- package/dist/input-scan/readout.d.ts +33 -0
- package/dist/input-scan/readout.js +336 -0
- package/dist/input-scan/scan.d.ts +5 -4
- package/dist/input-scan/scan.js +5 -5
- package/dist/input-scan/set-types.d.ts +209 -0
- package/dist/input-scan/set-types.js +15 -0
- package/dist/input-scan/templates.d.ts +93 -0
- package/dist/input-scan/templates.js +369 -0
- package/dist/input-scan/tokens.d.ts +94 -0
- package/dist/input-scan/tokens.js +267 -0
- package/dist/input-scan/tuning.d.ts +55 -0
- package/dist/input-scan/tuning.js +55 -0
- package/dist/input-scan/types.d.ts +2 -2
- package/dist/loop/run-agent.d.ts +13 -1
- package/dist/loop/run-agent.js +2 -1
- package/dist/prompts/SOUL.d.ts +2 -2
- package/dist/prompts/SOUL.js +17 -1
- package/dist/prompts/conversation.d.ts +1 -1
- package/dist/prompts/conversation.js +45 -71
- package/dist/prompts/planner.js +57 -10
- package/dist/prompts/report-session.d.ts +1 -1
- package/dist/prompts/report-session.js +3 -2
- package/dist/prompts/sandbox/bulk-transcriptomics-agent.d.ts +1 -1
- package/dist/prompts/sandbox/bulk-transcriptomics-agent.js +3 -1
- package/dist/prompts/sandbox/data-profiler.d.ts +10 -1
- package/dist/prompts/sandbox/data-profiler.js +197 -53
- package/dist/prompts/sandbox/dna-methylation-agent.d.ts +1 -1
- package/dist/prompts/sandbox/dna-methylation-agent.js +18 -12
- package/dist/prompts/sandbox/immune-profiling-agent.d.ts +1 -1
- package/dist/prompts/sandbox/immune-profiling-agent.js +6 -2
- package/dist/prompts/sandbox/metabolomics-agent.d.ts +1 -1
- package/dist/prompts/sandbox/metabolomics-agent.js +8 -4
- package/dist/prompts/sandbox/microbiome-agent.d.ts +1 -1
- package/dist/prompts/sandbox/microbiome-agent.js +12 -6
- package/dist/prompts/sandbox/network-agent.d.ts +1 -1
- package/dist/prompts/sandbox/network-agent.js +9 -6
- package/dist/prompts/sandbox/spatial-omics-agent.d.ts +1 -1
- package/dist/prompts/sandbox/spatial-omics-agent.js +4 -2
- package/dist/prompts/sandbox-standards.d.ts +1 -1
- package/dist/prompts/sandbox-standards.js +10 -7
- package/dist/providers/ai-sdk.js +34 -1
- package/dist/providers/reasoning.d.ts +65 -0
- package/dist/providers/reasoning.js +81 -0
- package/dist/providers/types.d.ts +14 -0
- package/dist/schemas/data-profile-schemas.d.ts +947 -84
- package/dist/schemas/data-profile-schemas.js +300 -115
- package/dist/schemas/run-synthesis.d.ts +4 -4
- package/dist/state/data-profile.d.ts +1 -1
- package/dist/state/index.d.ts +1 -1
- package/dist/state/vector-store.d.ts +13 -0
- package/dist/state/vector-store.js +8 -0
- package/dist/tasks/data-profile-absorb.d.ts +78 -0
- package/dist/tasks/data-profile-absorb.js +285 -0
- package/dist/tasks/data-profile-index.d.ts +34 -25
- package/dist/tasks/data-profile-index.js +160 -59
- package/dist/tasks/data-profile-resolve.d.ts +72 -0
- package/dist/tasks/data-profile-resolve.js +639 -0
- package/dist/tasks/data-profile.d.ts +16 -5
- package/dist/tasks/data-profile.js +270 -131
- package/dist/tools/bio/chembl.d.ts +1 -1
- package/dist/tools/bio/chembl.js +15 -10
- package/dist/tools/bio/comptox.js +5 -1
- package/dist/tools/bio/drug-gene-interactions.js +5 -2
- package/dist/tools/bio/gene-disease-evidence.d.ts +19 -9
- package/dist/tools/bio/gene-disease-evidence.js +78 -22
- package/dist/tools/bio/gene-preclinical-profile.d.ts +33 -13
- package/dist/tools/bio/gene-preclinical-profile.js +63 -22
- package/dist/tools/bio/lookup-annotation.d.ts +1 -0
- package/dist/tools/bio/lookup-annotation.js +28 -10
- package/dist/tools/bio/opentargets.d.ts +10 -2
- package/dist/tools/bio/opentargets.js +42 -13
- package/dist/tools/bio/pubchem.js +5 -2
- package/dist/tools/bio/pubmed.js +9 -3
- package/dist/tools/bio/search-clinical-trials.d.ts +25 -25
- package/dist/tools/bio/search-clinical-trials.js +56 -18
- package/dist/tools/bio/search-faers.d.ts +26 -6
- package/dist/tools/bio/search-faers.js +70 -18
- package/dist/tools/bio/search-gene.d.ts +19 -3
- package/dist/tools/bio/search-gene.js +69 -12
- package/dist/tools/bio/search-geo-datasets.js +4 -1
- package/dist/tools/bio/search-interactions.js +6 -2
- package/dist/tools/bio/target-safety.d.ts +2 -2
- package/dist/tools/bio/target-safety.js +3 -2
- package/dist/tools/lib/cbioportal-client.js +25 -6
- package/dist/tools/lib/chembl-client.d.ts +3 -1
- package/dist/tools/lib/chembl-client.js +6 -1
- package/dist/tools/lib/gwas-catalog-client.d.ts +7 -6
- package/dist/tools/lib/gwas-catalog-client.js +18 -6
- package/dist/tools/lib/openfda-client.d.ts +7 -5
- package/dist/tools/lib/openfda-client.js +17 -9
- package/dist/tools/lib/opentargets-client.d.ts +20 -0
- package/dist/tools/lib/opentargets-client.js +45 -0
- package/dist/tools/lib/pathway-client.d.ts +7 -0
- package/dist/tools/lib/pathway-client.js +68 -1
- package/dist/tools/research/context7-docs.js +3 -3
- package/dist/tools/research/generate-analogy-report.js +2 -2
- package/dist/tools/research/generate-plan.d.ts +3 -0
- package/dist/tools/research/generate-plan.js +64 -5
- package/dist/tools/research/inspect-data-profile.d.ts +48 -22
- package/dist/tools/research/inspect-data-profile.js +73 -54
- package/dist/tools/research/resolve-citation.js +8 -3
- package/dist/tools/research/search-arxiv.js +8 -3
- package/dist/tools/research/search-semantic-scholar.js +10 -4
- package/dist/tools/workspace/scan-inputs.d.ts +4 -4
- package/dist/tools/workspace/scan-inputs.js +13 -14
- package/dist/tools/workspace/workspace-search.d.ts +11 -2
- package/dist/tools/workspace/workspace-search.js +44 -16
- package/dist/workflows/sandbox-step.d.ts +6 -0
- package/dist/workflows/sandbox-step.js +31 -14
- package/dist/workflows/target-assessment/assemblers/safety.d.ts +1 -1
- package/dist/workflows/target-assessment/phase4-assemble.d.ts +38 -38
- package/dist/workflows/target-assessment/schemas.d.ts +12 -12
- package/dist/workflows/target-assessment/steps/phase2-aggregate.d.ts +6 -6
- package/dist/workflows/target-assessment/steps/phase3-aggregate.d.ts +6 -6
- package/dist/workflows/target-assessment/synthesis/index.d.ts +12 -12
- package/package.json +5 -3
- package/dist/input-scan/coverage.d.ts +0 -22
- package/dist/input-scan/coverage.js +0 -85
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One reading of a persisted profile, whichever era wrote it.
|
|
3
|
+
*
|
|
4
|
+
* A snapshot carries the fields of its era: rows written under the groups-and-dimensions
|
|
5
|
+
* model carry `groups`/`dimensions`, and rows written before it carry `kinds`/`axes` and
|
|
6
|
+
* a `files` list. There is no version field to consult — optionality is the compatibility
|
|
7
|
+
* mechanism — so a consumer must read both, and reading both in five places is how they
|
|
8
|
+
* drift apart. They read it here instead.
|
|
9
|
+
*
|
|
10
|
+
* The projection is lossy in one direction only: it narrows the newer record to what the
|
|
11
|
+
* older consumers already handled. Nothing it drops is unavailable — the full record is
|
|
12
|
+
* on the row, and consumers that want the resolved structure read it directly.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Every number the observations reported, side by side and de-duplicated.
|
|
16
|
+
*
|
|
17
|
+
* There is no canonical cardinality: a metadata sheet describing one count and files
|
|
18
|
+
* existing for another both stand, so a single number would be a silent judgement between
|
|
19
|
+
* disagreeing sources.
|
|
20
|
+
*/
|
|
21
|
+
export function dimensionCardinalities(dimension) {
|
|
22
|
+
const counts = [];
|
|
23
|
+
for (const observation of dimension.observations) {
|
|
24
|
+
if (observation.kind === "slot")
|
|
25
|
+
counts.push(observation.cardinality);
|
|
26
|
+
else if (observation.kind === "column" && observation.distinctValues !== undefined)
|
|
27
|
+
counts.push(observation.distinctValues);
|
|
28
|
+
else if (observation.kind === "document" && observation.statesCardinality !== undefined)
|
|
29
|
+
counts.push(observation.statesCardinality);
|
|
30
|
+
}
|
|
31
|
+
return [...new Set(counts)];
|
|
32
|
+
}
|
|
33
|
+
function examplesOf(dimension) {
|
|
34
|
+
for (const observation of dimension.observations) {
|
|
35
|
+
if (observation.kind === "slot" && observation.sampleValues.length > 0)
|
|
36
|
+
return observation.sampleValues;
|
|
37
|
+
if (observation.kind === "column" && observation.exampleValues.length > 0)
|
|
38
|
+
return observation.exampleValues;
|
|
39
|
+
}
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
function fromGroup(group) {
|
|
43
|
+
const format = group.formats.length === 1 ? group.formats[0].format : undefined;
|
|
44
|
+
return {
|
|
45
|
+
id: group.id,
|
|
46
|
+
name: group.name,
|
|
47
|
+
memberRepresents: group.memberRepresents,
|
|
48
|
+
description: group.description,
|
|
49
|
+
count: group.count,
|
|
50
|
+
pattern: group.displayPattern,
|
|
51
|
+
...(format ? { format } : {}),
|
|
52
|
+
...(group.slots ? { slotIds: group.slots.map((slot) => slot.id) } : {}),
|
|
53
|
+
...(group.unclassified ? { unclassified: true } : {}),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/** The dataset's structure, from whichever field the snapshot carries it in. */
|
|
57
|
+
export function profileGroups(result) {
|
|
58
|
+
if (result.groups !== undefined)
|
|
59
|
+
return result.groups.map(fromGroup);
|
|
60
|
+
return (result.kinds ?? []).map((kind, index) => ({
|
|
61
|
+
id: `kind-${index + 1}`,
|
|
62
|
+
name: kind.name,
|
|
63
|
+
memberRepresents: kind.memberRepresents,
|
|
64
|
+
description: kind.description,
|
|
65
|
+
count: kind.count,
|
|
66
|
+
pattern: kind.pathPattern,
|
|
67
|
+
...(kind.format ? { format: kind.format } : {}),
|
|
68
|
+
}));
|
|
69
|
+
}
|
|
70
|
+
/** What varies across the dataset, from whichever field the snapshot carries it in. */
|
|
71
|
+
export function profileDimensions(result) {
|
|
72
|
+
if (result.dimensions !== undefined) {
|
|
73
|
+
return result.dimensions.map((dimension) => ({
|
|
74
|
+
label: dimension.label,
|
|
75
|
+
cardinalities: dimensionCardinalities(dimension),
|
|
76
|
+
exampleValues: examplesOf(dimension),
|
|
77
|
+
...(dimension.description ? { description: dimension.description } : {}),
|
|
78
|
+
}));
|
|
79
|
+
}
|
|
80
|
+
return (result.axes ?? []).map((axis) => ({
|
|
81
|
+
label: axis.label,
|
|
82
|
+
cardinalities: [axis.cardinality],
|
|
83
|
+
exampleValues: axis.exampleValues ?? [],
|
|
84
|
+
...(axis.description ? { description: axis.description } : {}),
|
|
85
|
+
}));
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* The files the profile describes individually.
|
|
89
|
+
*
|
|
90
|
+
* On a groups-era row those are the members the agent annotated, which ride on the group
|
|
91
|
+
* they belong to; on an older row they are the `files` list. Either way this is a handful
|
|
92
|
+
* of notable inputs, never the dataset.
|
|
93
|
+
*/
|
|
94
|
+
export function profileFileRecords(result) {
|
|
95
|
+
if (result.groups !== undefined) {
|
|
96
|
+
return result.groups.flatMap((group) => (group.memberAnnotations ?? []).map((annotation) => ({
|
|
97
|
+
path: annotation.path,
|
|
98
|
+
description: annotation.note,
|
|
99
|
+
...(group.formats.length === 1 ? { format: group.formats[0].format } : {}),
|
|
100
|
+
})));
|
|
101
|
+
}
|
|
102
|
+
return result.files ?? [];
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* How many files the dataset holds, as far as the snapshot can establish it.
|
|
106
|
+
*
|
|
107
|
+
* The partition is the authority where present — it is a census, not an estimate. Older
|
|
108
|
+
* rows fall back to coverage, then to summed kind counts, then to `null`: reporting the
|
|
109
|
+
* described-file count would be a dataset size the row cannot support.
|
|
110
|
+
*/
|
|
111
|
+
export function profileDatasetFileCount(result) {
|
|
112
|
+
if (result.partition)
|
|
113
|
+
return result.partition.keptFiles;
|
|
114
|
+
if (result.coverage)
|
|
115
|
+
return result.coverage.total;
|
|
116
|
+
if (result.kinds && result.kinds.length > 0)
|
|
117
|
+
return result.kinds.reduce((sum, kind) => sum + kind.count, 0);
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
/** Dataset-wide findings the agent wrote, from whichever field the snapshot carries them in. */
|
|
121
|
+
export function profileCaveats(result) {
|
|
122
|
+
return result.caveats ?? result.qualityAssessment?.concerns ?? [];
|
|
123
|
+
}
|
|
@@ -78,7 +78,7 @@ export async function synthesizeRun(deps, params) {
|
|
|
78
78
|
unwrapOrThrow(await vectorStore.upsert({
|
|
79
79
|
indexName,
|
|
80
80
|
vectors: [vector],
|
|
81
|
-
metadata: [{ text: synthesisText, type: "synthesis", runId }],
|
|
81
|
+
metadata: [{ text: synthesisText, type: "synthesis", runId, path: `runs/${runId}/synthesis.json` }],
|
|
82
82
|
ids: [`/${analysisId}/runs/${runId}/synthesis.json`],
|
|
83
83
|
}));
|
|
84
84
|
}
|
|
@@ -46,7 +46,7 @@ export type ResourcePolicy = z.infer<typeof ResourcePolicySchema>;
|
|
|
46
46
|
/** Default LLM-turn budget for a sandbox agent step. Covers simple,
|
|
47
47
|
* standard, and complex analyses — extra headroom on simple steps is
|
|
48
48
|
* cheaper than truncating complex ones. */
|
|
49
|
-
export declare const DEFAULT_SANDBOX_MAX_STEPS =
|
|
49
|
+
export declare const DEFAULT_SANDBOX_MAX_STEPS = 200;
|
|
50
50
|
export declare class ResourceLimitsConfigError extends Error {
|
|
51
51
|
constructor(message: string);
|
|
52
52
|
}
|
|
@@ -33,7 +33,7 @@ export const ResourcePolicySchema = z.object({
|
|
|
33
33
|
/** Default LLM-turn budget for a sandbox agent step. Covers simple,
|
|
34
34
|
* standard, and complex analyses — extra headroom on simple steps is
|
|
35
35
|
* cheaper than truncating complex ones. */
|
|
36
|
-
export const DEFAULT_SANDBOX_MAX_STEPS =
|
|
36
|
+
export const DEFAULT_SANDBOX_MAX_STEPS = 200;
|
|
37
37
|
// ── Error ───────────────────────────────────────────────────────────
|
|
38
38
|
export class ResourceLimitsConfigError extends Error {
|
|
39
39
|
constructor(message) {
|
|
@@ -61,10 +61,12 @@ export interface DataProfileFile {
|
|
|
61
61
|
/** Flat, identity-establishing facts (sparsity, delimiter, normalizationState, …). */
|
|
62
62
|
metrics?: Record<string, string | number | boolean>;
|
|
63
63
|
}
|
|
64
|
-
/**
|
|
64
|
+
/**
|
|
65
|
+
* Dataset-wide quality findings, on rows of the era that recorded them. Superseded by
|
|
66
|
+
* `caveats`, which is agent-authored prose and nothing else.
|
|
67
|
+
*/
|
|
65
68
|
export interface DataProfileQualityAssessment {
|
|
66
69
|
concerns: string[];
|
|
67
|
-
strengths: string[];
|
|
68
70
|
}
|
|
69
71
|
/**
|
|
70
72
|
* One repeating set of files — the dataset's structure, as opposed to its contents.
|
|
@@ -97,6 +99,251 @@ export interface DataProfileAxis {
|
|
|
97
99
|
exampleValues?: string[];
|
|
98
100
|
description?: string;
|
|
99
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* A varying position in a group's display template, as the scan observed it.
|
|
104
|
+
*
|
|
105
|
+
* `sampleValues` is bounded and the record carries nothing wider: a full value
|
|
106
|
+
* enumeration would put the file set back in the row this record exists to keep out of
|
|
107
|
+
* it. The id is scan-scoped — it names the slot within the scan that produced this
|
|
108
|
+
* profile, and a dimension's slot observation refers to it.
|
|
109
|
+
*/
|
|
110
|
+
export interface DataProfileGroupSlot {
|
|
111
|
+
id: string;
|
|
112
|
+
location: "directory" | "name";
|
|
113
|
+
index: number;
|
|
114
|
+
tokenClass: string;
|
|
115
|
+
distinctValues: number;
|
|
116
|
+
sampleValues: string[];
|
|
117
|
+
/** The slot this one repeats — one token in both a directory segment and the stem is ONE identity. */
|
|
118
|
+
sameAsSlot?: string;
|
|
119
|
+
}
|
|
120
|
+
/** A member the agent wrote about individually. Never exhaustive — that is the filesystem's job. */
|
|
121
|
+
export interface DataProfileMemberAnnotation {
|
|
122
|
+
path: string;
|
|
123
|
+
note: string;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Companion coverage across a group, computed per member.
|
|
127
|
+
*
|
|
128
|
+
* A machine finding, deliberately structured rather than folded into `caveats`: an
|
|
129
|
+
* average hides the one member whose index is missing, and that is the member a
|
|
130
|
+
* downstream step fails on.
|
|
131
|
+
*/
|
|
132
|
+
export interface DataProfileCompanionCompleteness {
|
|
133
|
+
expectedCompanions: string[];
|
|
134
|
+
completeMembers: number;
|
|
135
|
+
incompleteMembers: number;
|
|
136
|
+
incompleteSample: {
|
|
137
|
+
path: string;
|
|
138
|
+
missingCompanions: string[];
|
|
139
|
+
}[];
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* One declared group — a claim about MEANING, resolved to a membership.
|
|
143
|
+
*
|
|
144
|
+
* `count` counts logical members (a data file and its companions count once); `fileCount`
|
|
145
|
+
* counts the files behind them, and it is `fileCount` that the partition accounting sums.
|
|
146
|
+
* `displayPattern` is the scanner's own template and is display-only: no agent authored
|
|
147
|
+
* it, and nothing computes membership from it.
|
|
148
|
+
*/
|
|
149
|
+
export interface DataProfileGroup {
|
|
150
|
+
/** Stable within the profile, derived from the group's name. */
|
|
151
|
+
id: string;
|
|
152
|
+
name: string;
|
|
153
|
+
/** What ONE member represents. The grouping decision, stated apart from the description. */
|
|
154
|
+
memberRepresents: string;
|
|
155
|
+
description: string;
|
|
156
|
+
role: string;
|
|
157
|
+
category: string;
|
|
158
|
+
/** What the group actually is, when `category` is `other`. */
|
|
159
|
+
categoryLabel?: string;
|
|
160
|
+
subtype?: string;
|
|
161
|
+
/** Why the agent overrode a pre-suggestion, or chose an arguable category. */
|
|
162
|
+
categoryReason?: string;
|
|
163
|
+
/** Why this group was split off, or why these sets are one group. */
|
|
164
|
+
reason?: string;
|
|
165
|
+
count: number;
|
|
166
|
+
fileCount: number;
|
|
167
|
+
totalBytes: number;
|
|
168
|
+
/** The scanner template the members instantiate. Display-only. */
|
|
169
|
+
displayPattern: string;
|
|
170
|
+
formats: {
|
|
171
|
+
format: string;
|
|
172
|
+
count: number;
|
|
173
|
+
}[];
|
|
174
|
+
slots?: DataProfileGroupSlot[];
|
|
175
|
+
memberAnnotations?: DataProfileMemberAnnotation[];
|
|
176
|
+
completeness?: DataProfileCompanionCompleteness;
|
|
177
|
+
/** True for the swept residue — files no operation claimed. Visible by construction. */
|
|
178
|
+
unclassified?: boolean;
|
|
179
|
+
}
|
|
180
|
+
/** A measurement that was actually performed. Absent means unchecked, never "no overlap". */
|
|
181
|
+
export interface DataProfileChecked {
|
|
182
|
+
matched: number;
|
|
183
|
+
of: number;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Where a slot observation points, in terms that survive the scan that produced it.
|
|
187
|
+
*
|
|
188
|
+
* A slot id is per-scan ephemera — the same id names a different slot after a re-scan
|
|
189
|
+
* reorders the sets — so the durable binding is the set's template plus the slot's
|
|
190
|
+
* position within it, exactly as the recipe keys a split. A binding that no longer
|
|
191
|
+
* resolves strands the profile rather than rebinding to whatever now sits at that
|
|
192
|
+
* position.
|
|
193
|
+
*/
|
|
194
|
+
export interface DataProfileSlotBinding {
|
|
195
|
+
template: string;
|
|
196
|
+
slotIndex: number;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* One evidenced sighting of a dimension.
|
|
200
|
+
*
|
|
201
|
+
* A slot observation binds to a scanner slot, and its cardinality and values are computed
|
|
202
|
+
* from the scan rather than asserted; `groupIds` are the groups that carry that slot,
|
|
203
|
+
* derived from the operations. Slot bindings are the only link between a group and a
|
|
204
|
+
* dimension.
|
|
205
|
+
*/
|
|
206
|
+
export type DataProfileObservation = {
|
|
207
|
+
kind: "slot";
|
|
208
|
+
groupIds: string[];
|
|
209
|
+
/** Scan-scoped, and display-only past the scan that wrote it. `binding` is what replays. */
|
|
210
|
+
slotId: string;
|
|
211
|
+
binding?: DataProfileSlotBinding;
|
|
212
|
+
tokenClass: string;
|
|
213
|
+
cardinality: number;
|
|
214
|
+
sampleValues: string[];
|
|
215
|
+
checked?: DataProfileChecked;
|
|
216
|
+
checkedAgainst?: string;
|
|
217
|
+
/**
|
|
218
|
+
* The slot the SCANNER found this one repeats, with the members whose two tokens
|
|
219
|
+
* disagreed. Its own performed measurement, in members rather than values — and
|
|
220
|
+
* the reason `checked` stays absent for such a pair: affix recovery strips literal
|
|
221
|
+
* text off one side, so an exact value-set intersection over two positions the
|
|
222
|
+
* scan matched one-to-one would report them wholly disjoint.
|
|
223
|
+
*/
|
|
224
|
+
sameAsSlot?: string;
|
|
225
|
+
sameAsSlotMismatches?: number;
|
|
226
|
+
note?: string;
|
|
227
|
+
} | {
|
|
228
|
+
kind: "column";
|
|
229
|
+
path: string;
|
|
230
|
+
column: string;
|
|
231
|
+
exampleValues: string[];
|
|
232
|
+
distinctValues?: number;
|
|
233
|
+
checked?: DataProfileChecked;
|
|
234
|
+
checkedAgainst?: string;
|
|
235
|
+
note?: string;
|
|
236
|
+
} | {
|
|
237
|
+
kind: "document";
|
|
238
|
+
path: string;
|
|
239
|
+
citation: string;
|
|
240
|
+
statesCardinality?: number;
|
|
241
|
+
checked?: DataProfileChecked;
|
|
242
|
+
checkedAgainst?: string;
|
|
243
|
+
note?: string;
|
|
244
|
+
};
|
|
245
|
+
/**
|
|
246
|
+
* A dataset-level thing that varies, with the evidence it was seen in.
|
|
247
|
+
*
|
|
248
|
+
* There is no canonical cardinality: observations that disagree both stand, and
|
|
249
|
+
* `reconciliations` carries the delta. A renderer shows the numbers side by side.
|
|
250
|
+
*/
|
|
251
|
+
export interface DataProfileDimension {
|
|
252
|
+
label: string;
|
|
253
|
+
category: string;
|
|
254
|
+
categoryLabel?: string;
|
|
255
|
+
/** Derived from the category, never agent-authored. */
|
|
256
|
+
scope: "biological" | "technical";
|
|
257
|
+
description?: string;
|
|
258
|
+
observations: DataProfileObservation[];
|
|
259
|
+
reconciliations?: {
|
|
260
|
+
note: string;
|
|
261
|
+
delta?: number;
|
|
262
|
+
}[];
|
|
263
|
+
nestsUnder?: {
|
|
264
|
+
dimension: string;
|
|
265
|
+
evidence: string;
|
|
266
|
+
};
|
|
267
|
+
/** Why the dataset deviates from the category's default treatment. */
|
|
268
|
+
treatmentReason?: string;
|
|
269
|
+
}
|
|
270
|
+
/** What the agent found when it looked for one of the standard dimensions. */
|
|
271
|
+
export interface DataProfileProbeReport {
|
|
272
|
+
probe: string;
|
|
273
|
+
outcome: "found" | "not-found" | "found-but-constant" | "attested";
|
|
274
|
+
dimension?: string;
|
|
275
|
+
searched?: string[];
|
|
276
|
+
reason?: string;
|
|
277
|
+
value?: string;
|
|
278
|
+
evidence?: string;
|
|
279
|
+
citation?: string;
|
|
280
|
+
path?: string;
|
|
281
|
+
}
|
|
282
|
+
/** Files the scan removed before structure was observed, with why. */
|
|
283
|
+
export interface DataProfileQuarantine {
|
|
284
|
+
count: number;
|
|
285
|
+
totalBytes: number;
|
|
286
|
+
reasons: {
|
|
287
|
+
reason: string;
|
|
288
|
+
count: number;
|
|
289
|
+
}[];
|
|
290
|
+
sample: string[];
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* The census, derived rather than declared.
|
|
294
|
+
*
|
|
295
|
+
* `keptFiles` equals the sum of every group's `fileCount`, `unclassified` included.
|
|
296
|
+
* Quarantined files are accounted separately, with their reasons. That the numbers sum
|
|
297
|
+
* is what turns "how much did the profile cover" from a question into a fact.
|
|
298
|
+
*/
|
|
299
|
+
export interface DataProfilePartition {
|
|
300
|
+
scannedFiles: number;
|
|
301
|
+
keptFiles: number;
|
|
302
|
+
keptMembers: number;
|
|
303
|
+
groups: number;
|
|
304
|
+
unclassifiedMembers: number;
|
|
305
|
+
unclassifiedFiles: number;
|
|
306
|
+
quarantine: DataProfileQuarantine;
|
|
307
|
+
/**
|
|
308
|
+
* Members more than one operation claimed after the last repair round. Removed from
|
|
309
|
+
* every claimant and swept into `unclassified`, never awarded by precedence — a
|
|
310
|
+
* machine finding, so it is here rather than in the agent's caveats.
|
|
311
|
+
*/
|
|
312
|
+
contested?: {
|
|
313
|
+
members: number;
|
|
314
|
+
sample: string[];
|
|
315
|
+
};
|
|
316
|
+
/** True when the walk stopped at its file ceiling, so the census covers part of the tree. */
|
|
317
|
+
scanTruncated?: boolean;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* One operation, keyed to the scanner TEMPLATES it addressed rather than the menu ids.
|
|
321
|
+
*
|
|
322
|
+
* Menu ids are per-scan ephemera; templates survive a re-scan, so the recipe can be
|
|
323
|
+
* re-resolved against a changed tree.
|
|
324
|
+
*
|
|
325
|
+
* `unclassified` is the one step no agent authored: it records the paths resolution swept
|
|
326
|
+
* because no operation claimed them. It is carried so a replay can tell a file the last
|
|
327
|
+
* profile already declined to classify from a file that is new to the tree — without it
|
|
328
|
+
* an unchanged tree re-absorbs as partial and wakes the agent to re-judge what it already
|
|
329
|
+
* judged.
|
|
330
|
+
*/
|
|
331
|
+
export interface DataProfileRecipeStep {
|
|
332
|
+
op: "use" | "split" | "merge" | "group" | "unclassified";
|
|
333
|
+
/** The templates this step addressed. Empty for an explicit path grouping. */
|
|
334
|
+
templates: string[];
|
|
335
|
+
/** Position of the split slot within the addressed set's slots. */
|
|
336
|
+
slotIndex?: number;
|
|
337
|
+
/** Slot values each resulting group claimed, for a value-mapped split. */
|
|
338
|
+
valueMapping?: {
|
|
339
|
+
groupId: string;
|
|
340
|
+
values: string[];
|
|
341
|
+
}[];
|
|
342
|
+
paths?: string[];
|
|
343
|
+
/** True when `paths` holds a prefix of the step's membership rather than all of it. */
|
|
344
|
+
pathsTruncated?: boolean;
|
|
345
|
+
groupIds: string[];
|
|
346
|
+
}
|
|
100
347
|
/**
|
|
101
348
|
* The comparand identifying WHICH files a profile covered and whether the SAME BYTES
|
|
102
349
|
* were profiled.
|
|
@@ -126,17 +373,6 @@ export interface DataProfileCoverage {
|
|
|
126
373
|
total: number;
|
|
127
374
|
unmatchedSample?: string[];
|
|
128
375
|
}
|
|
129
|
-
/**
|
|
130
|
-
* One profiled input file's legacy drift signature. `fileId` is a path identity (two
|
|
131
|
-
* files at the same path share it regardless of content), so `size` + `mtimeMs` are what
|
|
132
|
-
* let a consumer notice the bytes behind a path changed. Superseded by
|
|
133
|
-
* {@link DataProfileInputSignature}, and still readable on older rows.
|
|
134
|
-
*/
|
|
135
|
-
export interface DataProfileInputFile {
|
|
136
|
-
fileId: string;
|
|
137
|
-
size: number;
|
|
138
|
-
mtimeMs: number;
|
|
139
|
-
}
|
|
140
376
|
/**
|
|
141
377
|
* The profile snapshot stored in `cortex_analysis_state.data_profile_result`.
|
|
142
378
|
*
|
|
@@ -148,25 +384,39 @@ export interface DataProfileInputFile {
|
|
|
148
384
|
* It does NOT carry a record per input file. The workspace filesystem is the
|
|
149
385
|
* authoritative file list — listing, grep, and the vector index all read the live tree —
|
|
150
386
|
* so a copy here would be a stale duplicate on a row detoasted by every reader,
|
|
151
|
-
* including the planner's, which reads a few hundred characters of it. `
|
|
152
|
-
*
|
|
387
|
+
* including the planner's, which reads a few hundred characters of it. `groups` holds the
|
|
388
|
+
* dataset's structure, and the members an agent wrote about individually ride on the
|
|
389
|
+
* group they belong to.
|
|
390
|
+
*
|
|
391
|
+
* The writer emits `groups` and `dimensions`; `kinds`, `axes`, `files`, `coverage`, and
|
|
392
|
+
* `qualityAssessment` are what earlier eras wrote and stay readable. There is no version
|
|
393
|
+
* field: optionality is the compatibility mechanism, and a discriminator would be a
|
|
394
|
+
* second mechanism answering the same question.
|
|
153
395
|
*/
|
|
154
396
|
export interface DataProfileResult {
|
|
155
397
|
summary: string;
|
|
156
|
-
/**
|
|
157
|
-
|
|
158
|
-
/**
|
|
398
|
+
/** The resolved groups the tree partitions into, `unclassified` included. */
|
|
399
|
+
groups?: DataProfileGroup[];
|
|
400
|
+
/** What varies across the dataset, each with its observations. */
|
|
401
|
+
dimensions?: DataProfileDimension[];
|
|
402
|
+
/** One outcome per standard dimension the agent was asked to look for. */
|
|
403
|
+
probes?: DataProfileProbeReport[];
|
|
404
|
+
/** The census. Derived at resolution — kept equals the sum over groups. */
|
|
405
|
+
partition?: DataProfilePartition;
|
|
406
|
+
/** The operations that produced the groups, keyed to scanner templates. */
|
|
407
|
+
recipe?: DataProfileRecipeStep[];
|
|
408
|
+
/** What a planner must know, in the agent's words. Machine findings live in the structured fields. */
|
|
409
|
+
caveats?: string[];
|
|
410
|
+
/** Individually described files — notable singletons on a pre-groups snapshot. */
|
|
411
|
+
files?: DataProfileFile[];
|
|
412
|
+
/** The repeating sets the tree was grouped into, on a snapshot of the kinds era. */
|
|
159
413
|
kinds?: DataProfileKind[];
|
|
160
|
-
/** What varies across those sets
|
|
414
|
+
/** What varies across those sets, on a snapshot of the same era. */
|
|
161
415
|
axes?: DataProfileAxis[];
|
|
162
|
-
/** The drift comparand.
|
|
416
|
+
/** The drift comparand. */
|
|
163
417
|
inputSignature?: DataProfileInputSignature;
|
|
164
|
-
/** How much of the scanned tree the kinds describe
|
|
418
|
+
/** How much of the scanned tree the kinds describe, on a snapshot of the kinds era. Superseded by `partition`. */
|
|
165
419
|
coverage?: DataProfileCoverage;
|
|
166
|
-
/** The legacy identity-list comparand, on rows written before the signature existed. */
|
|
167
|
-
inputFileIds?: string[];
|
|
168
|
-
/** The legacy per-file drift signature, on rows of the same era. */
|
|
169
|
-
inputFiles?: DataProfileInputFile[];
|
|
170
420
|
/** ISO 8601 timestamp of profile completion. */
|
|
171
421
|
profiledAt: string;
|
|
172
422
|
/** Scientific domain (transcriptomics, cheminformatics, clinical, …). */
|
|
@@ -186,6 +436,7 @@ export interface DataProfileResult {
|
|
|
186
436
|
accessions?: string[];
|
|
187
437
|
/** Conditions, groups, comparisons, replicates, pairing. */
|
|
188
438
|
experimentalDesign?: string;
|
|
439
|
+
/** Dataset-wide findings, on a snapshot of the era that recorded them. Superseded by `caveats`. */
|
|
189
440
|
qualityAssessment?: DataProfileQualityAssessment;
|
|
190
441
|
}
|
|
191
442
|
/** The profile's lifecycle, as the ledger records it. */
|
|
@@ -6,7 +6,9 @@ export type { PlanStep, PresentationContent, PresentationPart, PlanPart, RunCard
|
|
|
6
6
|
export type { EventSource, TextDeltaEvent, ToolStartedEvent, ToolFinishedEvent, FinishEvent, ChatErrorEvent, CortexChatEvent } from "./chat-events.js";
|
|
7
7
|
export type { TokenUsageRollup } from "./usage.js";
|
|
8
8
|
export { DATA_PROFILE_RUN_LITERAL } from "./data-profile.js";
|
|
9
|
-
export type { DataProfileAxis, DataProfileCoverage, DataProfileFile,
|
|
9
|
+
export type { DataProfileAxis, DataProfileChecked, DataProfileCompanionCompleteness, DataProfileCoverage, DataProfileDimension, DataProfileFile, DataProfileGroup, DataProfileGroupSlot, DataProfileInputSignature, DataProfileKind, DataProfileLifecycleStatus, DataProfileMemberAnnotation, DataProfileObservation, DataProfileOrganism, DataProfilePartition, DataProfileProbeReport, DataProfileQualityAssessment, DataProfileQuarantine, DataProfileRecipeStep, DataProfileResult, DataProfileSubjectSource, } from "./data-profile.js";
|
|
10
|
+
export { DIMENSION_CATEGORIES, DIMENSION_CATEGORY_IDS, DIMENSION_PROBE_IDS, DIMENSION_PROBES, GROUP_CATEGORIES, GROUP_CATEGORY_IDS, GROUP_ROLE_IDS, GROUP_ROLES, PROBE_OUTCOME_IDS, dimensionCategoryEntry, dimensionScope, groupCategoryEntry, } from "./profile-vocabulary.js";
|
|
11
|
+
export type { DimensionCategory, DimensionCategoryEntry, DimensionProbe, DimensionProbeEntry, DimensionScope, DimensionTreatment, GroupCategory, GroupCategoryEntry, GroupRole, GroupRoleEntry, ProbeOutcome, } from "./profile-vocabulary.js";
|
|
10
12
|
export type { TextPart, ToolCallPart, CortexPart, CortexMessage } from "./message.js";
|
|
11
13
|
export { PART_REGISTRY, isTransient, isReconciling, isSidebarPart } from "./part-registry.js";
|
|
12
14
|
export type { CortexChatPartType, PartDescriptor, PartEmitter, PartConsumer } from "./part-registry.js";
|
package/dist/contracts/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { ORGAN_SYSTEMS, OrganSystemSchema, ORGAN_SYSTEM_LABELS, organSystemLabel } from "./organ-system.js";
|
|
2
2
|
export { SEVERITIES, SeveritySchema } from "./severity.js";
|
|
3
3
|
export { DATA_PROFILE_RUN_LITERAL } from "./data-profile.js";
|
|
4
|
+
export { DIMENSION_CATEGORIES, DIMENSION_CATEGORY_IDS, DIMENSION_PROBE_IDS, DIMENSION_PROBES, GROUP_CATEGORIES, GROUP_CATEGORY_IDS, GROUP_ROLE_IDS, GROUP_ROLES, PROBE_OUTCOME_IDS, dimensionCategoryEntry, dimensionScope, groupCategoryEntry, } from "./profile-vocabulary.js";
|
|
4
5
|
export { PART_REGISTRY, isTransient, isReconciling, isSidebarPart } from "./part-registry.js";
|
|
5
6
|
export { AnalogyCoverageSchema, AnalogyReportSchema, AnalogyReportErrorSchema, AnalogicalReasonerOutputSchema } from "./analogy-report.js";
|
|
6
7
|
export { CoverageSchema, RowCoverageSchema, EntitySchema, ClaimSupportSchema, ClaimEvidenceSchema, LiabilityBulletSchema, LiabilitySummarySchema, TractabilitySchema, IndicationsSchema, DrugInteractionsSchema, ClinicalTrialAttributionSchema, ClinicalDevelopmentSchema, OrganRiskRowSchema, OffTargetRowSchema, OffTargetPanelSchema, RegulatoryActionRowSchema, SafetyFlagSchema, SafetyProfileSchema, OffTissueRowSchema, OffTissueRiskSchema, ReferenceBiologyShape, EvidenceConflictsSchema, EvidenceTimelineSchema, TranslationalChainSchema, AdditionalEvidenceSchema, DiscoveryTrialsSchema, QualityGateStatusSchema, QualityGatesSchema, DerivedSchema, DossierSchema, DossierBodySchema, isDossier, dossierJsonSchema, SECTION_BLURBS, TargetAssessmentPhaseSchema, TargetAssessmentProgressEventSchema, } from "./target-dossier.js";
|
|
@@ -0,0 +1,103 @@
|
|
|
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
|
+
export declare const GROUP_ROLE_IDS: readonly ["data", "metadata", "index", "documentation", "reference"];
|
|
21
|
+
export type GroupRole = (typeof GROUP_ROLE_IDS)[number];
|
|
22
|
+
export interface GroupRoleEntry {
|
|
23
|
+
readonly id: GroupRole;
|
|
24
|
+
readonly definition: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Companions (`.bai`/`.tbi`/per-file `.md5`) take no role — they attach to members. A
|
|
28
|
+
* checksum or inventory file spanning MANY members is not a companion but a member of
|
|
29
|
+
* its own, category `manifest`; `index` is for tables that exist to be joined against,
|
|
30
|
+
* never for binary sidecars.
|
|
31
|
+
*/
|
|
32
|
+
export declare const GROUP_ROLES: readonly GroupRoleEntry[];
|
|
33
|
+
export declare const GROUP_CATEGORY_IDS: readonly ["sequencing-reads", "alignment", "variant-calls", "copy-number", "structural-variants", "association-results", "regions-signal", "expression-matrix", "single-cell-matrix", "methylation", "proteomics", "metabolomics", "cytometry", "chemical-structures", "imaging", "clinical-table", "sample-annotation", "code", "document", "manifest", "reference-data", "other"];
|
|
34
|
+
export type GroupCategory = (typeof GROUP_CATEGORY_IDS)[number];
|
|
35
|
+
export interface GroupCategoryEntry {
|
|
36
|
+
readonly id: GroupCategory;
|
|
37
|
+
readonly definition: string;
|
|
38
|
+
/** The nearest neighbour and the rule that separates them. */
|
|
39
|
+
readonly note: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Coarse on purpose — a free `subtype` refines below the category. Content beats shape:
|
|
43
|
+
* a beta-value matrix is methylation whatever its layout, and a MAF is variant-calls
|
|
44
|
+
* whatever its extension. Grain and meaning decide.
|
|
45
|
+
*/
|
|
46
|
+
export declare const GROUP_CATEGORIES: readonly GroupCategoryEntry[];
|
|
47
|
+
export declare const DIMENSION_CATEGORY_IDS: readonly ["subject", "sample", "organism-species", "model-system", "cohort-arm", "disease-state", "treatment", "timepoint", "tissue-site", "cell-type", "genetic-perturbation", "sex", "age-group", "developmental-stage", "environment", "assay-modality", "assay-target", "variant-origin", "sample-pairing", "processing-level", "assay-version", "batch", "replicate", "tool-variant", "library-prep", "data-partition", "other"];
|
|
48
|
+
export type DimensionCategory = (typeof DIMENSION_CATEGORY_IDS)[number];
|
|
49
|
+
export type DimensionScope = "biological" | "technical";
|
|
50
|
+
/**
|
|
51
|
+
* What the substrate test says for this category by default. `split` means one value's
|
|
52
|
+
* files are typically a different substrate to a downstream step, so the set is split
|
|
53
|
+
* into groups; `dimension` means the values are variants of one substrate and stay a
|
|
54
|
+
* slot, possibly bound to a dimension.
|
|
55
|
+
*/
|
|
56
|
+
export type DimensionTreatment = "split" | "dimension";
|
|
57
|
+
export interface DimensionCategoryEntry {
|
|
58
|
+
readonly id: DimensionCategory;
|
|
59
|
+
readonly scope: DimensionScope;
|
|
60
|
+
readonly definition: string;
|
|
61
|
+
readonly defaultTreatment: DimensionTreatment;
|
|
62
|
+
/** Why the default reads the way it does, and the nearest neighbour it is not. */
|
|
63
|
+
readonly note: string;
|
|
64
|
+
}
|
|
65
|
+
export declare const DIMENSION_CATEGORIES: readonly DimensionCategoryEntry[];
|
|
66
|
+
export declare const DIMENSION_PROBE_IDS: readonly ["subject", "sample", "cohort-arm", "timepoint", "batch"];
|
|
67
|
+
export type DimensionProbe = (typeof DIMENSION_PROBE_IDS)[number];
|
|
68
|
+
/**
|
|
69
|
+
* A probe outcome, exactly one per probe.
|
|
70
|
+
*
|
|
71
|
+
* `not-found` is a correct and complete answer once the searched set is named — that is
|
|
72
|
+
* what removes the completeness pressure that otherwise invents dimensions. `attested`
|
|
73
|
+
* records prose-only evidence and can never justify a split.
|
|
74
|
+
*/
|
|
75
|
+
export declare const PROBE_OUTCOME_IDS: readonly ["found", "not-found", "found-but-constant", "attested"];
|
|
76
|
+
export type ProbeOutcome = (typeof PROBE_OUTCOME_IDS)[number];
|
|
77
|
+
export interface DimensionProbeEntry {
|
|
78
|
+
readonly id: DimensionProbe;
|
|
79
|
+
/** Where a `found` typically comes from. */
|
|
80
|
+
readonly guidance: string;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* The only dimensions the agent actively looks for. The searchable set is bounded and
|
|
84
|
+
* named: files in metadata- or documentation-role groups plus clinical-table and
|
|
85
|
+
* sample-annotation members, up to about ten files. Everything off this list is recorded
|
|
86
|
+
* only when encountered during ordinary orientation reading.
|
|
87
|
+
*
|
|
88
|
+
* Assay-modality and replicate are deliberately absent: varying modality is already
|
|
89
|
+
* surfaced by group categories, and probing for replicates invites inferring replicate
|
|
90
|
+
* structure from sample counts, which is fabrication by another name.
|
|
91
|
+
*/
|
|
92
|
+
export declare const DIMENSION_PROBES: readonly DimensionProbeEntry[];
|
|
93
|
+
export declare function groupCategoryEntry(id: GroupCategory): GroupCategoryEntry;
|
|
94
|
+
export declare function dimensionCategoryEntry(id: DimensionCategory): DimensionCategoryEntry;
|
|
95
|
+
/**
|
|
96
|
+
* The scope a dimension takes.
|
|
97
|
+
*
|
|
98
|
+
* Derived from the category for everything in the catalogue. `other` is by definition
|
|
99
|
+
* outside it, so there is nothing to derive from and the scope is the agent's to declare:
|
|
100
|
+
* a biological thing that varies and has no category is still biological, and pinning
|
|
101
|
+
* every `other` to technical would misfile it. Undeclared, it defaults to technical.
|
|
102
|
+
*/
|
|
103
|
+
export declare function dimensionScope(id: DimensionCategory, declared?: DimensionScope): DimensionScope;
|