@inflexa-ai/harness 0.23.0 → 0.25.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 (123) hide show
  1. package/README.md +1 -2
  2. package/dist/agents/conversation-agent.d.ts +0 -9
  3. package/dist/agents/sandbox/__fixtures__/deps.js +6 -0
  4. package/dist/agents/sandbox/data-profiler.js +5 -4
  5. package/dist/agents/sandbox/shared.js +11 -0
  6. package/dist/agents/sandbox/types.d.ts +1 -1
  7. package/dist/app/data-profile-orientation.js +30 -1
  8. package/dist/app/data-profile-policy.d.ts +33 -7
  9. package/dist/app/data-profile-policy.js +31 -9
  10. package/dist/contracts/chat-parts.d.ts +29 -33
  11. package/dist/contracts/content-url.d.ts +7 -41
  12. package/dist/contracts/content-url.js +7 -48
  13. package/dist/contracts/data-profile.d.ts +166 -0
  14. package/dist/contracts/index.d.ts +3 -2
  15. package/dist/contracts/index.js +1 -1
  16. package/dist/contracts/message.d.ts +1 -1
  17. package/dist/contracts/message.js +1 -1
  18. package/dist/contracts/part-registry.js +2 -3
  19. package/dist/contracts/schemas/chat-parts.d.ts +16 -53
  20. package/dist/contracts/schemas/chat-parts.js +15 -25
  21. package/dist/contracts/schemas/index.d.ts +1 -1
  22. package/dist/contracts/schemas/index.js +1 -1
  23. package/dist/execution/input-signature.d.ts +33 -0
  24. package/dist/execution/input-signature.js +0 -0
  25. package/dist/execution/run-authorizer.d.ts +1 -1
  26. package/dist/execution/run-authorizer.js +1 -1
  27. package/dist/index.d.ts +5 -4
  28. package/dist/index.js +5 -2
  29. package/dist/input-scan/coverage.d.ts +22 -0
  30. package/dist/input-scan/coverage.js +85 -0
  31. package/dist/input-scan/enrich.d.ts +41 -0
  32. package/dist/input-scan/enrich.js +227 -0
  33. package/dist/input-scan/formats.d.ts +41 -0
  34. package/dist/input-scan/formats.js +279 -0
  35. package/dist/input-scan/index.d.ts +12 -0
  36. package/dist/input-scan/index.js +11 -0
  37. package/dist/input-scan/scan.d.ts +50 -0
  38. package/dist/input-scan/scan.js +182 -0
  39. package/dist/input-scan/shapes.d.ts +46 -0
  40. package/dist/input-scan/shapes.js +0 -0
  41. package/dist/input-scan/types.d.ts +172 -0
  42. package/dist/input-scan/types.js +12 -0
  43. package/dist/lib/zod-issues.d.ts +2 -3
  44. package/dist/lib/zod-issues.js +2 -3
  45. package/dist/loop/__fixtures__/scripted-provider.js +3 -1
  46. package/dist/loop/run-agent.d.ts +5 -0
  47. package/dist/loop/run-agent.js +10 -1
  48. package/dist/loop/run-to-terminal.d.ts +1 -1
  49. package/dist/loop/run-to-terminal.js +1 -1
  50. package/dist/memory/card-builders.d.ts +0 -27
  51. package/dist/memory/card-builders.js +0 -75
  52. package/dist/memory/conversation-display-backfill.d.ts +2 -4
  53. package/dist/memory/conversation-display-backfill.js +3 -9
  54. package/dist/memory/conversation-display-storage.d.ts +3 -4
  55. package/dist/memory/conversation-display-storage.js +3 -4
  56. package/dist/memory/reconstruct-cards.d.ts +5 -7
  57. package/dist/memory/reconstruct-cards.js +6 -20
  58. package/dist/prompts/sandbox/data-profiler.d.ts +1 -1
  59. package/dist/prompts/sandbox/data-profiler.js +159 -275
  60. package/dist/provenance/exec-frame.js +9 -3
  61. package/dist/runtime/boot.js +2 -12
  62. package/dist/sandbox/client.d.ts +7 -0
  63. package/dist/sandbox/create-sandbox.js +1 -0
  64. package/dist/sandbox/docker-client.d.ts +1 -0
  65. package/dist/sandbox/docker-client.js +20 -15
  66. package/dist/sandbox/k8s-client.d.ts +6 -5
  67. package/dist/sandbox/k8s-client.js +55 -39
  68. package/dist/sandbox/reaper.d.ts +24 -13
  69. package/dist/sandbox/reaper.js +47 -14
  70. package/dist/sandbox/types.d.ts +6 -5
  71. package/dist/schemas/data-profile-schemas.d.ts +62 -0
  72. package/dist/schemas/data-profile-schemas.js +68 -2
  73. package/dist/state/data-profile.d.ts +7 -88
  74. package/dist/state/index.d.ts +1 -1
  75. package/dist/tasks/data-profile-activity.d.ts +8 -0
  76. package/dist/tasks/data-profile-activity.js +1 -0
  77. package/dist/tasks/data-profile-index.d.ts +45 -0
  78. package/dist/tasks/data-profile-index.js +134 -0
  79. package/dist/tasks/data-profile.d.ts +8 -23
  80. package/dist/tasks/data-profile.js +150 -117
  81. package/dist/tools/report-session/preview-report.d.ts +2 -1
  82. package/dist/tools/report-session/preview-report.js +9 -1
  83. package/dist/tools/research/generate-plan.js +1 -1
  84. package/dist/tools/research/inspect-data-profile.d.ts +30 -4
  85. package/dist/tools/research/inspect-data-profile.js +66 -10
  86. package/dist/tools/start-report-session.js +2 -2
  87. package/dist/tools/workspace/scan-inputs.d.ts +38 -0
  88. package/dist/tools/workspace/scan-inputs.js +61 -0
  89. package/dist/tools/workspace/workspace-search.d.ts +1 -1
  90. package/dist/tools/workspace/workspace-search.js +12 -9
  91. package/dist/workspace/filesystem.d.ts +27 -0
  92. package/dist/workspace/filesystem.js +27 -0
  93. package/dist/workspace/paths.d.ts +0 -21
  94. package/dist/workspace/paths.js +0 -37
  95. package/package.json +1 -3
  96. package/dist/agents/report-builder.d.ts +0 -34
  97. package/dist/agents/report-builder.js +0 -34
  98. package/dist/execution/report-render.d.ts +0 -39
  99. package/dist/execution/report-render.js +0 -98
  100. package/dist/execution/report-runner.d.ts +0 -111
  101. package/dist/execution/report-runner.js +0 -230
  102. package/dist/prompts/report-builder.d.ts +0 -1
  103. package/dist/prompts/report-builder.js +0 -174
  104. package/dist/tools/iterate-report.d.ts +0 -227
  105. package/dist/tools/iterate-report.js +0 -883
  106. package/dist/tools/lib/preview-lock.d.ts +0 -20
  107. package/dist/tools/lib/preview-lock.js +0 -35
  108. package/dist/tools/lib/report-preflight.d.ts +0 -39
  109. package/dist/tools/lib/report-preflight.js +0 -283
  110. package/dist/tools/report/build-report.d.ts +0 -13
  111. package/dist/tools/report/build-report.js +0 -27
  112. package/dist/tools/report/index.d.ts +0 -15
  113. package/dist/tools/report/index.js +0 -15
  114. package/dist/tools/report/mint-preview-url.d.ts +0 -26
  115. package/dist/tools/report/mint-preview-url.js +0 -47
  116. package/dist/tools/report/preview-publisher.d.ts +0 -53
  117. package/dist/tools/report/preview-publisher.js +0 -45
  118. package/dist/tools/report/preview-snapshot.d.ts +0 -34
  119. package/dist/tools/report/preview-snapshot.js +0 -98
  120. package/dist/tools/report/submit-report.d.ts +0 -26
  121. package/dist/tools/report/submit-report.js +0 -148
  122. package/dist/tools/report/version-fs.d.ts +0 -15
  123. package/dist/tools/report/version-fs.js +0 -165
@@ -24,3 +24,169 @@
24
24
  * reporting the profile as an unnamed run — a failure with no red test anywhere.
25
25
  */
26
26
  export declare const DATA_PROFILE_RUN_LITERAL: "data-profile";
27
+ /**
28
+ * Where an extracted subject fact came from, so a consumer can judge how much to trust
29
+ * it. Ordered most-direct first in the profiler's own guidance.
30
+ */
31
+ export type DataProfileSubjectSource = "metadata" | "document" | "filename" | "user-context" | "inferred";
32
+ /** The subject organism, with its provenance and the profiler's confidence in it. */
33
+ export interface DataProfileOrganism {
34
+ scientificName: string;
35
+ /** NCBI Taxonomy ID as a string, e.g. `"9606"`. */
36
+ taxonId: string;
37
+ source: DataProfileSubjectSource;
38
+ confidence: "high" | "medium" | "low";
39
+ notes?: string;
40
+ }
41
+ /**
42
+ * One profiled file's persisted record.
43
+ *
44
+ * `path` + `description` are the original pair every snapshot carries; everything below
45
+ * them is optional on read, because a snapshot written before the record was widened
46
+ * carries only the pair.
47
+ */
48
+ export interface DataProfileFile {
49
+ path: string;
50
+ description: string;
51
+ /** Semantic data type (count-matrix, variants, clinical-metadata, document, …). */
52
+ dataType?: string;
53
+ /** File format (CSV, h5ad, VCF, BAM, …). */
54
+ format?: string;
55
+ rows?: number | null;
56
+ cols?: number | null;
57
+ /** Searchable labels the profiler attached. */
58
+ tags?: string[];
59
+ /** Quality issues specific to this file. */
60
+ warnings?: string[];
61
+ /** Flat, identity-establishing facts (sparsity, delimiter, normalizationState, …). */
62
+ metrics?: Record<string, string | number | boolean>;
63
+ }
64
+ /** Dataset-wide quality findings the profiler recorded. */
65
+ export interface DataProfileQualityAssessment {
66
+ concerns: string[];
67
+ strengths: string[];
68
+ }
69
+ /**
70
+ * One repeating set of files — the dataset's structure, as opposed to its contents.
71
+ *
72
+ * A kind is a claim about MEANING, made by the profiler agent: the deterministic input
73
+ * scan establishes that filenames differ only at one position, and cannot establish that
74
+ * the files are the same sort of thing. A singleton is a kind of `count` 1, so a
75
+ * two-file analysis is two kinds and needs no special case.
76
+ */
77
+ export interface DataProfileKind {
78
+ name: string;
79
+ /** What ONE member represents. The grouping decision, stated apart from the description. */
80
+ memberRepresents: string;
81
+ description: string;
82
+ count: number;
83
+ /** Glob the members match, relative to the analysis root. Coverage is computed from it. */
84
+ pathPattern: string;
85
+ format?: string;
86
+ /** Labels of the `axes` that vary across this set's members. */
87
+ axisLabels?: string[];
88
+ }
89
+ /**
90
+ * What varies across a kind's members — the experimental design, as far as it is
91
+ * observable. The scan reports that a filename position varies and which values it
92
+ * takes; what the variation IS is the agent's label.
93
+ */
94
+ export interface DataProfileAxis {
95
+ label: string;
96
+ cardinality: number;
97
+ exampleValues?: string[];
98
+ description?: string;
99
+ }
100
+ /**
101
+ * The comparand identifying WHICH files a profile covered and whether the SAME BYTES
102
+ * were profiled.
103
+ *
104
+ * `digest` is a stable hash over the staged inputs' identities, sizes, and mtimes in a
105
+ * canonical order, so it depends on the set and not on enumeration order. It excludes
106
+ * content hashes deliberately: enumerating those would mean reading every input in full
107
+ * on every parity check. An edit preserving both byte length and mtime is therefore not
108
+ * detected — bounded, and documented.
109
+ */
110
+ export interface DataProfileInputSignature {
111
+ count: number;
112
+ digest: string;
113
+ }
114
+ /**
115
+ * How much of the scanned tree the profile's kinds describe.
116
+ *
117
+ * Computed deterministically by matching the submitted kind patterns against the scanned
118
+ * file set — never self-reported. Low coverage is a distinct failure from drift: a
119
+ * profile that classified a fraction of its inputs used to carry the same comparand as
120
+ * one that classified all of them, so it read as complete and fresh. Coverage does NOT by
121
+ * itself drive a re-profile, because some input sets legitimately resist classification.
122
+ */
123
+ export interface DataProfileCoverage {
124
+ matched: number;
125
+ unmatched: number;
126
+ total: number;
127
+ unmatchedSample?: string[];
128
+ }
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
+ /**
141
+ * The profile snapshot stored in `cortex_analysis_state.data_profile_result`.
142
+ *
143
+ * It carries the profiler's full finding rather than a summary of it: this row is the
144
+ * profile's only durable home, so a field dropped on the way in is not "summarized
145
+ * away", it is destroyed, and the next reader can recover it only by re-reading the raw
146
+ * inputs.
147
+ *
148
+ * It does NOT carry a record per input file. The workspace filesystem is the
149
+ * authoritative file list — listing, grep, and the vector index all read the live tree —
150
+ * 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. `files` holds the
152
+ * individually notable inputs; `kinds` holds the dataset's structure.
153
+ */
154
+ export interface DataProfileResult {
155
+ summary: string;
156
+ /** Individually described files — notable singletons, not the dataset's contents. */
157
+ files: DataProfileFile[];
158
+ /** The repeating sets the tree was grouped into. Absent on a pre-kinds snapshot. */
159
+ kinds?: DataProfileKind[];
160
+ /** What varies across those sets. Absent for the same reason as `kinds`. */
161
+ axes?: DataProfileAxis[];
162
+ /** The drift comparand. Preferred over `inputFileIds`, which it replaces. */
163
+ inputSignature?: DataProfileInputSignature;
164
+ /** How much of the scanned tree the kinds describe. Absent on pre-coverage snapshots. */
165
+ 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
+ /** ISO 8601 timestamp of profile completion. */
171
+ profiledAt: string;
172
+ /** Scientific domain (transcriptomics, cheminformatics, clinical, …). */
173
+ domain?: string;
174
+ /** Specific subtype within the domain (bulk-rna-seq, single-cell, LC-MS/MS, …). */
175
+ subtype?: string;
176
+ /**
177
+ * Explicit `null` is a real, distinct value — the profiler looked and no input
178
+ * identified an organism — as opposed to absent, which means the snapshot predates
179
+ * the field.
180
+ */
181
+ organism?: DataProfileOrganism | null;
182
+ tissue?: string | null;
183
+ cellType?: string | null;
184
+ condition?: string | null;
185
+ /** Public dataset accessions found in any input (GSE/SRP/PRJNA/E-MTAB/phs/EGAS). */
186
+ accessions?: string[];
187
+ /** Conditions, groups, comparisons, replicates, pairing. */
188
+ experimentalDesign?: string;
189
+ qualityAssessment?: DataProfileQualityAssessment;
190
+ }
191
+ /** The profile's lifecycle, as the ledger records it. */
192
+ export type DataProfileLifecycleStatus = "pending" | "running" | "completed" | "failed";
@@ -2,10 +2,11 @@ export { ORGAN_SYSTEMS, OrganSystemSchema, ORGAN_SYSTEM_LABELS, organSystemLabel
2
2
  export type { OrganSystem } from "./organ-system.js";
3
3
  export { SEVERITIES, SeveritySchema } from "./severity.js";
4
4
  export type { Severity } from "./severity.js";
5
- export type { PlanStep, PresentationContent, PresentationPart, PlanPart, RunCardPart, FileReferenceEntry, FileReferencePart, AskPart, RunStartedPart, StepStatus, DagStepState, DagStatePart, StepPhase, StepActivityPart, FileTreeEntry, StepFileTreePart, StepOutputFile, StepOutputPart, StepSummaryPart, StepUsagePart, StepBlockedPart, SynthesizedFinding, BiologicalTheme, RunSynthesisPart, SynthesisPhase, SynthesisProgressPart, RunCompletedFinding, RunCompletedPart, RunFailedPart, PreviewPart, DataPreviewFailedPart, ReportSessionStartedPart, CortexChatPart, } from "./chat-parts.js";
5
+ export type { PlanStep, PresentationContent, PresentationPart, PlanPart, RunCardPart, FileReferenceEntry, FileReferencePart, AskPart, RunStartedPart, StepStatus, DagStepState, DagStatePart, StepPhase, StepActivityPart, FileTreeEntry, StepFileTreePart, StepOutputFile, StepOutputPart, StepSummaryPart, StepUsagePart, StepBlockedPart, SynthesizedFinding, BiologicalTheme, RunSynthesisPart, SynthesisPhase, SynthesisProgressPart, RunCompletedFinding, RunCompletedPart, RunFailedPart, ChildSessionStartedPart, ReportRenderedPart, CortexChatPart, } from "./chat-parts.js";
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, DataProfileInputFile, DataProfileInputSignature, DataProfileKind, DataProfileLifecycleStatus, DataProfileOrganism, DataProfileQualityAssessment, DataProfileResult, DataProfileSubjectSource, } from "./data-profile.js";
9
10
  export type { TextPart, ToolCallPart, CortexPart, CortexMessage } from "./message.js";
10
11
  export { PART_REGISTRY, isTransient, isReconciling, isSidebarPart } from "./part-registry.js";
11
12
  export type { CortexChatPartType, PartDescriptor, PartEmitter, PartConsumer } from "./part-registry.js";
@@ -15,4 +16,4 @@ export { CoverageSchema, RowCoverageSchema, EntitySchema, ClaimSupportSchema, Cl
15
16
  export type { Coverage, RowCoverage, Entity, EvidenceItem, ClaimSupport, ClaimEvidence, LiabilityBullet, LiabilitySummary, TractabilitySection, ClinicalTrialAttribution, ClinicalTrialRow, ClinicalDevelopment, FailedTrialRow, TrialOutcomeRow, OrganRiskRow, OffTargetRow, RegulatoryActionRow, SafetyFlag, SafetyProfile, OffTissueRow, QualityGateStatus, QualityGates, Derived, Dossier, DossierBody, SectionBlurbKey, TargetAssessmentPhase, TargetAssessmentProgressEvent, } from "./target-dossier.js";
16
17
  export { TargetAssessmentStatusSchema, TargetAssessmentErrorSchema, TargetAssessmentListRowSchema, TargetAssessmentRowSchema, } from "./target-assessment-row.js";
17
18
  export type { TargetAssessmentStatus, TargetAssessmentError, TargetAssessmentListRow, TargetAssessmentRow } from "./target-assessment-row.js";
18
- export { buildPreviewUrl, buildReportSessionUrl, previewResourceId, reportSessionResourceId } from "./content-url.js";
19
+ export { buildReportSessionUrl, reportSessionResourceId } from "./content-url.js";
@@ -5,4 +5,4 @@ export { PART_REGISTRY, isTransient, isReconciling, isSidebarPart } from "./part
5
5
  export { AnalogyCoverageSchema, AnalogyReportSchema, AnalogyReportErrorSchema, AnalogicalReasonerOutputSchema } from "./analogy-report.js";
6
6
  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";
7
7
  export { TargetAssessmentStatusSchema, TargetAssessmentErrorSchema, TargetAssessmentListRowSchema, TargetAssessmentRowSchema, } from "./target-assessment-row.js";
8
- export { buildPreviewUrl, buildReportSessionUrl, previewResourceId, reportSessionResourceId } from "./content-url.js";
8
+ export { buildReportSessionUrl, reportSessionResourceId } from "./content-url.js";
@@ -3,7 +3,7 @@
3
3
  * and the public API for everything the chat path exchanges.
4
4
  *
5
5
  * No AI SDK types appear here or anywhere else in the package. The
6
- * discriminant is `type`, so `switch (part.type) { case "data-report-preview": ... }`
6
+ * discriminant is `type`, so `switch (part.type) { case "data-child-session-started": ... }`
7
7
  * narrows the union member without any `as` cast.
8
8
  */
9
9
  import type { ToolCallDetail, ToolCallOutcome } from "./chat-events.js";
@@ -3,7 +3,7 @@
3
3
  * and the public API for everything the chat path exchanges.
4
4
  *
5
5
  * No AI SDK types appear here or anywhere else in the package. The
6
- * discriminant is `type`, so `switch (part.type) { case "data-report-preview": ... }`
6
+ * discriminant is `type`, so `switch (part.type) { case "data-child-session-started": ... }`
7
7
  * narrows the union member without any `as` cast.
8
8
  */
9
9
  export {};
@@ -16,9 +16,8 @@ export const PART_REGISTRY = {
16
16
  "data-synthesis-progress": { emitter: "workflow", consumer: "sidebar", transient: false, reconciling: true },
17
17
  "data-run-completed": { emitter: "workflow", consumer: "sidebar", transient: false, reconciling: false },
18
18
  "data-run-failed": { emitter: "workflow", consumer: "sidebar", transient: false, reconciling: false },
19
- "data-report-preview": { emitter: "conversation", consumer: "conversation", transient: false, reconciling: false },
20
- "data-report-preview-failed": { emitter: "conversation", consumer: "conversation", transient: false, reconciling: false },
21
- "data-report-session-started": { emitter: "conversation", consumer: "conversation", transient: false, reconciling: false },
19
+ "data-child-session-started": { emitter: "conversation", consumer: "conversation", transient: false, reconciling: false },
20
+ "data-report-rendered": { emitter: "conversation", consumer: "conversation", transient: false, reconciling: false },
22
21
  };
23
22
  export function isTransient(type) {
24
23
  return PART_REGISTRY[type].transient;
@@ -441,36 +441,17 @@ export declare const RunFailedPartSchema: z.ZodObject<{
441
441
  error: z.ZodString;
442
442
  reason: z.ZodOptional<z.ZodString>;
443
443
  }, z.core.$strip>;
444
- export declare const PreviewPartSchema: z.ZodObject<{
445
- type: z.ZodLiteral<"data-report-preview">;
446
- id: z.ZodString;
447
- previewId: z.ZodString;
448
- version: z.ZodNumber;
449
- title: z.ZodString;
450
- previewPath: z.ZodString;
451
- format: z.ZodEnum<{
452
- html: "html";
453
- pdf: "pdf";
454
- }>;
455
- }, z.core.$strip>;
456
- export declare const DataPreviewFailedPartSchema: z.ZodObject<{
457
- type: z.ZodLiteral<"data-report-preview-failed">;
458
- id: z.ZodString;
459
- previewId: z.ZodString;
460
- version: z.ZodNumber;
461
- reason: z.ZodString;
462
- errorKind: z.ZodOptional<z.ZodEnum<{
463
- timeout: "timeout";
464
- render: "render";
465
- submit: "submit";
466
- build: "build";
467
- internal: "internal";
468
- }>>;
469
- }, z.core.$strip>;
470
- export declare const ReportSessionStartedPartSchema: z.ZodObject<{
471
- type: z.ZodLiteral<"data-report-session-started">;
444
+ export declare const ChildSessionStartedPartSchema: z.ZodObject<{
445
+ type: z.ZodLiteral<"data-child-session-started">;
472
446
  threadId: z.ZodString;
473
447
  parentThreadId: z.ZodString;
448
+ threadType: z.ZodString;
449
+ }, z.core.$strip>;
450
+ export declare const ReportRenderedPartSchema: z.ZodObject<{
451
+ type: z.ZodLiteral<"data-report-rendered">;
452
+ id: z.ZodString;
453
+ renderedAt: z.ZodString;
454
+ title: z.ZodOptional<z.ZodString>;
474
455
  }, z.core.$strip>;
475
456
  export declare const CortexChatPartSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
476
457
  type: z.ZodLiteral<"data-presentation">;
@@ -745,31 +726,13 @@ export declare const CortexChatPartSchema: z.ZodDiscriminatedUnion<[z.ZodObject<
745
726
  error: z.ZodString;
746
727
  reason: z.ZodOptional<z.ZodString>;
747
728
  }, z.core.$strip>, z.ZodObject<{
748
- type: z.ZodLiteral<"data-report-preview">;
749
- id: z.ZodString;
750
- previewId: z.ZodString;
751
- version: z.ZodNumber;
752
- title: z.ZodString;
753
- previewPath: z.ZodString;
754
- format: z.ZodEnum<{
755
- html: "html";
756
- pdf: "pdf";
757
- }>;
758
- }, z.core.$strip>, z.ZodObject<{
759
- type: z.ZodLiteral<"data-report-preview-failed">;
760
- id: z.ZodString;
761
- previewId: z.ZodString;
762
- version: z.ZodNumber;
763
- reason: z.ZodString;
764
- errorKind: z.ZodOptional<z.ZodEnum<{
765
- timeout: "timeout";
766
- render: "render";
767
- submit: "submit";
768
- build: "build";
769
- internal: "internal";
770
- }>>;
771
- }, z.core.$strip>, z.ZodObject<{
772
- type: z.ZodLiteral<"data-report-session-started">;
729
+ type: z.ZodLiteral<"data-child-session-started">;
773
730
  threadId: z.ZodString;
774
731
  parentThreadId: z.ZodString;
732
+ threadType: z.ZodString;
733
+ }, z.core.$strip>, z.ZodObject<{
734
+ type: z.ZodLiteral<"data-report-rendered">;
735
+ id: z.ZodString;
736
+ renderedAt: z.ZodString;
737
+ title: z.ZodOptional<z.ZodString>;
775
738
  }, z.core.$strip>], "type">;
@@ -275,30 +275,21 @@ export const RunFailedPartSchema = z.object({
275
275
  error: z.string(),
276
276
  reason: z.string().optional(),
277
277
  });
278
- // ── Preview ────────────────────────────────────────────────────────
279
- export const PreviewPartSchema = z.object({
280
- type: z.literal("data-report-preview"),
281
- id: z.string(),
282
- previewId: z.string(),
283
- version: z.number(),
284
- title: z.string(),
285
- previewPath: z.string(),
286
- format: z.enum(["html", "pdf"]),
287
- });
288
- // ── Preview Failed ─────────────────────────────────────────────────
289
- export const DataPreviewFailedPartSchema = z.object({
290
- type: z.literal("data-report-preview-failed"),
291
- id: z.string(),
292
- previewId: z.string(),
293
- version: z.number(),
294
- reason: z.string(),
295
- errorKind: z.enum(["render", "submit", "build", "timeout", "internal"]).optional(),
296
- });
297
- // ── Report Session Started ─────────────────────────────────────────
298
- export const ReportSessionStartedPartSchema = z.object({
299
- type: z.literal("data-report-session-started"),
278
+ // ── Child Session Started ──────────────────────────────────────────
279
+ export const ChildSessionStartedPartSchema = z.object({
280
+ type: z.literal("data-child-session-started"),
300
281
  threadId: z.string(),
301
282
  parentThreadId: z.string(),
283
+ // A plain string, deliberately not an enum: a future session type must
284
+ // not fail validation in an older consumer.
285
+ threadType: z.string(),
286
+ });
287
+ // ── Report Rendered ────────────────────────────────────────────────
288
+ export const ReportRenderedPartSchema = z.object({
289
+ type: z.literal("data-report-rendered"),
290
+ id: z.string(),
291
+ renderedAt: z.string(),
292
+ title: z.string().optional(),
302
293
  });
303
294
  // ── Union ───────────────────────────────────────────────────────────
304
295
  export const CortexChatPartSchema = z.discriminatedUnion("type", [
@@ -319,7 +310,6 @@ export const CortexChatPartSchema = z.discriminatedUnion("type", [
319
310
  SynthesisProgressPartSchema,
320
311
  RunCompletedPartSchema,
321
312
  RunFailedPartSchema,
322
- PreviewPartSchema,
323
- DataPreviewFailedPartSchema,
324
- ReportSessionStartedPartSchema,
313
+ ChildSessionStartedPartSchema,
314
+ ReportRenderedPartSchema,
325
315
  ]);
@@ -1,3 +1,3 @@
1
- export { PlanStepSchema, PresentationContentSchema, PresentationPartSchema, PlanPartSchema, RunCardPartSchema, FileReferenceEntrySchema, FileReferencePartSchema, RunStartedPartSchema, StepStatusSchema, DagStepStateSchema, DagStatePartSchema, StepPhaseSchema, StepActivityPartSchema, FileTreeEntrySchema, StepFileTreePartSchema, StepOutputFileSchema, StepOutputPartSchema, StepSummaryPartSchema, StepUsagePartSchema, StepBlockedPartSchema, SynthesizedFindingSchema, BiologicalThemeSchema, RunSynthesisPartSchema, SynthesisPhaseSchema, SynthesisProgressPartSchema, RunCompletedFindingSchema, RunCompletedPartSchema, RunFailedPartSchema, PreviewPartSchema, DataPreviewFailedPartSchema, CortexChatPartSchema, } from "./chat-parts.js";
1
+ export { PlanStepSchema, PresentationContentSchema, PresentationPartSchema, PlanPartSchema, RunCardPartSchema, FileReferenceEntrySchema, FileReferencePartSchema, RunStartedPartSchema, StepStatusSchema, DagStepStateSchema, DagStatePartSchema, StepPhaseSchema, StepActivityPartSchema, FileTreeEntrySchema, StepFileTreePartSchema, StepOutputFileSchema, StepOutputPartSchema, StepSummaryPartSchema, StepUsagePartSchema, StepBlockedPartSchema, SynthesizedFindingSchema, BiologicalThemeSchema, RunSynthesisPartSchema, SynthesisPhaseSchema, SynthesisProgressPartSchema, RunCompletedFindingSchema, RunCompletedPartSchema, RunFailedPartSchema, CortexChatPartSchema, } from "./chat-parts.js";
2
2
  export { EventSourceSchema, TextDeltaEventSchema, ToolStartedEventSchema, ToolFinishedEventSchema, FinishEventSchema, ChatErrorEventSchema, CortexChatEventSchema, } from "./chat-events.js";
3
3
  export { TokenUsageRollupSchema } from "./usage.js";
@@ -1,3 +1,3 @@
1
- export { PlanStepSchema, PresentationContentSchema, PresentationPartSchema, PlanPartSchema, RunCardPartSchema, FileReferenceEntrySchema, FileReferencePartSchema, RunStartedPartSchema, StepStatusSchema, DagStepStateSchema, DagStatePartSchema, StepPhaseSchema, StepActivityPartSchema, FileTreeEntrySchema, StepFileTreePartSchema, StepOutputFileSchema, StepOutputPartSchema, StepSummaryPartSchema, StepUsagePartSchema, StepBlockedPartSchema, SynthesizedFindingSchema, BiologicalThemeSchema, RunSynthesisPartSchema, SynthesisPhaseSchema, SynthesisProgressPartSchema, RunCompletedFindingSchema, RunCompletedPartSchema, RunFailedPartSchema, PreviewPartSchema, DataPreviewFailedPartSchema, CortexChatPartSchema, } from "./chat-parts.js";
1
+ export { PlanStepSchema, PresentationContentSchema, PresentationPartSchema, PlanPartSchema, RunCardPartSchema, FileReferenceEntrySchema, FileReferencePartSchema, RunStartedPartSchema, StepStatusSchema, DagStepStateSchema, DagStatePartSchema, StepPhaseSchema, StepActivityPartSchema, FileTreeEntrySchema, StepFileTreePartSchema, StepOutputFileSchema, StepOutputPartSchema, StepSummaryPartSchema, StepUsagePartSchema, StepBlockedPartSchema, SynthesizedFindingSchema, BiologicalThemeSchema, RunSynthesisPartSchema, SynthesisPhaseSchema, SynthesisProgressPartSchema, RunCompletedFindingSchema, RunCompletedPartSchema, RunFailedPartSchema, CortexChatPartSchema, } from "./chat-parts.js";
2
2
  export { EventSourceSchema, TextDeltaEventSchema, ToolStartedEventSchema, ToolFinishedEventSchema, FinishEventSchema, ChatErrorEventSchema, CortexChatEventSchema, } from "./chat-events.js";
3
3
  export { TokenUsageRollupSchema } from "./usage.js";
@@ -0,0 +1,33 @@
1
+ /**
2
+ * The input signature — the fixed-width comparand a completed profile persists in
3
+ * place of a per-file identity list.
4
+ *
5
+ * `inputFileIds` had exactly one consumer, the staleness comparison, so a set of
6
+ * several thousand identifiers was persisted, detoasted on every read of the row, and
7
+ * compared element-wise to answer a question 40 bytes answer. The signature covers
8
+ * `size` and `mtimeMs` as well, so it also notices that the bytes behind a path
9
+ * changed — a `fileId` is a path identity and survives an in-place edit unchanged.
10
+ *
11
+ * Order independence is a property of the digest, not of the caller: entries are
12
+ * sorted canonically before hashing, so two enumerations of the same set agree.
13
+ */
14
+ import type { DataProfileInputSignature } from "../state/data-profile.js";
15
+ import type { StagedInput } from "./staged-input.js";
16
+ /** The fields a signature covers. A manifest entry satisfies it structurally. */
17
+ export interface SignableInput {
18
+ readonly fileId: string;
19
+ readonly size: number;
20
+ readonly mtimeMs?: number;
21
+ }
22
+ /**
23
+ * Digest a staged input set.
24
+ *
25
+ * A workflow input persisted before `StagedInput.mtimeMs` existed deserializes without
26
+ * it despite the compile-time type; such an entry contributes `-` in the mtime field
27
+ * rather than omitting the signature entirely. The comparison still notices an added,
28
+ * removed, or resized file, and one re-profile under the current code restores the full
29
+ * signature.
30
+ */
31
+ export declare function computeInputSignature(inputs: readonly SignableInput[]): DataProfileInputSignature;
32
+ /** Convenience over the workflow's own manifest type. */
33
+ export declare function signatureOfStagedInputs(inputs: readonly StagedInput[]): DataProfileInputSignature;
@@ -11,7 +11,7 @@
11
11
  * `RunSession` with no host call, no jti, no revoke. The harness's tools depend only on
12
12
  * this interface and never read a credential.
13
13
  *
14
- * Mirrors the `PreviewPublisher` seam: a narrow interface in the harness, the managed
14
+ * Mirrors the `SessionPagePublisher` seam: a narrow interface in the harness, the managed
15
15
  * realization injected at the composition root.
16
16
  */
17
17
  import type { AuthContext, Provenance, RunFrame, RunSession, Scope } from "../auth/types.js";
@@ -11,7 +11,7 @@
11
11
  * `RunSession` with no host call, no jti, no revoke. The harness's tools depend only on
12
12
  * this interface and never read a credential.
13
13
  *
14
- * Mirrors the `PreviewPublisher` seam: a narrow interface in the harness, the managed
14
+ * Mirrors the `SessionPagePublisher` seam: a narrow interface in the harness, the managed
15
15
  * realization injected at the composition root.
16
16
  */
17
17
  export {};
package/dist/index.d.ts CHANGED
@@ -33,8 +33,6 @@ export { createNoopArtifactRegistry } from "./execution/noop-artifact-registry.j
33
33
  export type { ArtifactRegistry, ArtifactRegistrationInput, ArtifactSyncInput, ExternalRegistrationResult } from "./execution/artifact-registry.js";
34
34
  export type { ArtifactManifestEntry } from "./schemas/artifact-manifest.js";
35
35
  export type { ProvenanceCollector } from "./provenance/collector.js";
36
- export { UnavailablePreviewPublisher } from "./tools/report/preview-publisher.js";
37
- export type { PreviewPublisher, PreviewMintResult } from "./tools/report/preview-publisher.js";
38
36
  export { UnavailableSessionPagePublisher } from "./tools/report-session/session-page-publisher.js";
39
37
  export type { MakeSessionPagePublisher, SessionPagePublisher, SessionPageMintResult } from "./tools/report-session/session-page-publisher.js";
40
38
  export type { ResolvePageUrl, SessionPageAccess } from "./tools/report-session/index.js";
@@ -88,7 +86,7 @@ export type { ConversationDisplayMetadata, ConversationUIData, ConversationUIMes
88
86
  export { storedMessagesToCortex } from "./memory/conversation-display-replay.js";
89
87
  export type { CortexChatEvent, TextDeltaEvent, ToolStartedEvent, ToolFinishedEvent, ToolOutcome, ToolCallOutcome, ToolCallDetail, FinishEvent, ChatErrorEvent, } from "./contracts/chat-events.js";
90
88
  export type { TokenUsageRollup } from "./contracts/usage.js";
91
- export type { CortexChatPart, PresentationPart, PresentationContent, PlanPart, RunCardPart, FileReferencePart, FileReferenceEntry, RunStartedPart, DagStatePart, DagStepState, StepStatus, StepActivityPart, StepPhase, StepFileTreePart, FileTreeEntry, StepOutputPart, StepOutputFile, StepSummaryPart, StepUsagePart, StepBlockedPart, RunSynthesisPart, SynthesizedFinding, BiologicalTheme, SynthesisProgressPart, SynthesisPhase, RunCompletedPart, RunCompletedFinding, RunFailedPart, PreviewPart, DataPreviewFailedPart, } from "./contracts/chat-parts.js";
89
+ export type { CortexChatPart, PresentationPart, PresentationContent, PlanPart, RunCardPart, FileReferencePart, FileReferenceEntry, RunStartedPart, DagStatePart, DagStepState, StepStatus, StepActivityPart, StepPhase, StepFileTreePart, FileTreeEntry, StepOutputPart, StepOutputFile, StepSummaryPart, StepUsagePart, StepBlockedPart, RunSynthesisPart, SynthesizedFinding, BiologicalTheme, SynthesisProgressPart, SynthesisPhase, RunCompletedPart, RunCompletedFinding, RunFailedPart, } from "./contracts/chat-parts.js";
92
90
  export { PART_REGISTRY, isTransient, isReconciling, isSidebarPart } from "./contracts/part-registry.js";
93
91
  export type { CortexChatPartType, PartDescriptor, PartEmitter, PartConsumer } from "./contracts/part-registry.js";
94
92
  export { launchDbos, shutdownDbos, sweepEphemeralWorkflows } from "./runtime/dbos.js";
@@ -117,10 +115,13 @@ export { DATA_PROFILE_RUN_LITERAL } from "./contracts/data-profile.js";
117
115
  export { initCortexState } from "./state/init.js";
118
116
  export { upsertAnalysis } from "./state/analyses.js";
119
117
  export { clearDataProfile, loadDataProfileStatus, tryRetryDataProfile, reconcileOrphanedDataProfile } from "./state/data-profile.js";
120
- export type { DataProfileInputFile, DataProfileResult, DataProfileStatus } from "./state/data-profile.js";
118
+ export type { DataProfileAxis, DataProfileCoverage, DataProfileFile, DataProfileInputFile, DataProfileInputSignature, DataProfileKind, DataProfileLifecycleStatus, DataProfileOrganism, DataProfileQualityAssessment, DataProfileResult, DataProfileSubjectSource, } from "./contracts/data-profile.js";
119
+ export type { DataProfileStatus } from "./state/data-profile.js";
121
120
  export { createAnalysisPurge } from "./state/purge-analysis.js";
122
121
  export type { AnalysisPurge, AnalysisPurgeDeps, AnalysisPurgeOutcome } from "./state/purge-analysis.js";
123
122
  export type { StagedInput } from "./execution/staged-input.js";
123
+ export { computeInputSignature } from "./execution/input-signature.js";
124
+ export type { SignableInput } from "./execution/input-signature.js";
124
125
  export type { ResolveWorkspaceRoot } from "./workspace/paths.js";
125
126
  export { createSandboxClient } from "./sandbox/create-sandbox.js";
126
127
  export type { CreateSandboxClientConfig, SandboxBackendConfig } from "./sandbox/create-sandbox.js";
package/dist/index.js CHANGED
@@ -40,8 +40,6 @@ export { createNoopRunCharge } from "./billing/noop-run-charge.js";
40
40
  export { createNoopUsageRecorder } from "./billing/noop-usage-recorder.js";
41
41
  // Seam: artifact registration.
42
42
  export { createNoopArtifactRegistry } from "./execution/noop-artifact-registry.js";
43
- // Seam: report preview publishing.
44
- export { UnavailablePreviewPublisher } from "./tools/report/preview-publisher.js";
45
43
  // Seam: the hosted view of a report-session page. A managed host serves the URL space
46
44
  // `report-sessions/{analysisId}/{threadId}` and mints access through its own publisher,
47
45
  // thus the seam belongs on the front door. Both seams bind per call over the auth of the
@@ -207,6 +205,11 @@ export { clearDataProfile, loadDataProfileStatus, tryRetryDataProfile, reconcile
207
205
  // Analysis reclamation — `purgeAnalysis` reclaims an analysis's whole Postgres
208
206
  // footprint from its id alone; workspace files stay the embedder's to dispose of.
209
207
  export { createAnalysisPurge } from "./state/purge-analysis.js";
208
+ // The input signature a completed profile persists. Exported because the embedder owns
209
+ // the OTHER side of the comparison — it enumerates the current input set — and a second
210
+ // implementation of the digest would silently disagree with the one on the row, which is
211
+ // the failure a fixed-width comparand exists to prevent.
212
+ export { computeInputSignature } from "./execution/input-signature.js";
210
213
  export { createSandboxClient } from "./sandbox/create-sandbox.js";
211
214
  export { MachineBudgetSchema, ResourceLimitsSchema, ResourcePolicySchema, ResourceSpecSchema, parseResourcePolicy } from "./config/resource-limits.js";
212
215
  export { createWorkspaceFilesystem } from "./workspace/filesystem.js";
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Profile coverage — how much of the scanned tree the agent's kinds actually describe.
3
+ *
4
+ * Measured against the SUBMITTED kinds, never against the scan's own shapes. Computed
5
+ * from the shapes it would report only whether the scan grouped its own observations,
6
+ * which is always yes; measured against the kinds it is a real check, and it is the
7
+ * check that was missing when a profile covering 49 of 3513 files read as complete and
8
+ * fresh.
9
+ *
10
+ * Deterministic by construction: matching declared patterns against a known file set
11
+ * requires no judgement, and a coverage figure a model self-reported would not be a
12
+ * check at all.
13
+ */
14
+ export interface ProfileCoverage {
15
+ /** Files matching at least one declared kind pattern. */
16
+ readonly matched: number;
17
+ readonly unmatched: number;
18
+ readonly total: number;
19
+ readonly unmatchedSample: string[];
20
+ }
21
+ /** Coverage of a scanned file set by a set of declared kind patterns. */
22
+ export declare function computeCoverage(paths: readonly string[], patterns: readonly string[]): ProfileCoverage;
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Profile coverage — how much of the scanned tree the agent's kinds actually describe.
3
+ *
4
+ * Measured against the SUBMITTED kinds, never against the scan's own shapes. Computed
5
+ * from the shapes it would report only whether the scan grouped its own observations,
6
+ * which is always yes; measured against the kinds it is a real check, and it is the
7
+ * check that was missing when a profile covering 49 of 3513 files read as complete and
8
+ * fresh.
9
+ *
10
+ * Deterministic by construction: matching declared patterns against a known file set
11
+ * requires no judgement, and a coverage figure a model self-reported would not be a
12
+ * check at all.
13
+ */
14
+ /** Unmatched paths carried on the snapshot, so a shortfall names examples rather than a bare count. */
15
+ const MAX_UNMATCHED_SAMPLE = 10;
16
+ /**
17
+ * Compile a kind's path pattern to a matcher.
18
+ *
19
+ * `**` crosses directory separators, `*` and `?` do not, and `<0>`-style placeholders —
20
+ * the syntax the manifest renders variable positions in, which an agent may reasonably
21
+ * copy — match one token. Everything else is literal.
22
+ */
23
+ function compilePattern(pattern) {
24
+ let out = "";
25
+ for (let i = 0; i < pattern.length; i++) {
26
+ const char = pattern[i];
27
+ if (char === "*") {
28
+ if (pattern[i + 1] === "*") {
29
+ out += ".*";
30
+ i++;
31
+ // `**/` should also match zero directories, so the slash is optional.
32
+ if (pattern[i + 1] === "/")
33
+ i++;
34
+ continue;
35
+ }
36
+ out += "[^/]*";
37
+ continue;
38
+ }
39
+ if (char === "?") {
40
+ out += "[^/]";
41
+ continue;
42
+ }
43
+ if (char === "<") {
44
+ const close = pattern.indexOf(">", i);
45
+ if (close > i) {
46
+ out += "[^/]*";
47
+ i = close;
48
+ continue;
49
+ }
50
+ }
51
+ out += char.replace(/[.+^${}()|[\]\\]/g, "\\$&");
52
+ }
53
+ return new RegExp(`^${out}$`);
54
+ }
55
+ function normalize(path) {
56
+ return path.replace(/^\.\//, "").replace(/^\/+/, "").replace(/\/+/g, "/");
57
+ }
58
+ /**
59
+ * Whether a path falls under a pattern. A pattern naming a directory covers everything
60
+ * beneath it — agents write `data/inputs/vcf` as often as `data/inputs/vcf/*.vcf.gz`,
61
+ * and reading the first as a zero-file kind would report a coverage failure that is an
62
+ * artefact of notation.
63
+ */
64
+ function matches(path, pattern, compiled) {
65
+ if (compiled.test(path))
66
+ return true;
67
+ const bare = pattern.replace(/\/+$/, "");
68
+ return bare.length > 0 && !/[*?<]/.test(bare) && path.startsWith(`${bare}/`);
69
+ }
70
+ /** Coverage of a scanned file set by a set of declared kind patterns. */
71
+ export function computeCoverage(paths, patterns) {
72
+ const compiled = patterns.map((pattern) => ({ pattern, regex: compilePattern(pattern) }));
73
+ const unmatchedSample = [];
74
+ let matched = 0;
75
+ for (const raw of paths) {
76
+ const path = normalize(raw);
77
+ if (compiled.some(({ pattern, regex }) => matches(path, pattern, regex))) {
78
+ matched++;
79
+ continue;
80
+ }
81
+ if (unmatchedSample.length < MAX_UNMATCHED_SAMPLE)
82
+ unmatchedSample.push(path);
83
+ }
84
+ return { matched, unmatched: paths.length - matched, total: paths.length, unmatchedSample };
85
+ }