@kontourai/survey 0.4.23 → 0.5.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 (39) hide show
  1. package/README.md +86 -872
  2. package/dist/example-data/corrected-document-candidates.d.ts +2 -0
  3. package/dist/{fixtures → example-data}/corrected-document-candidates.js +3 -3
  4. package/dist/{fixtures → example-data}/downstream-public-directory-proposal.d.ts +1 -1
  5. package/dist/{fixtures → example-data}/downstream-public-directory-proposal.js +1 -1
  6. package/dist/{fixtures → example-data}/public-directory-review-resource.d.ts +2 -2
  7. package/dist/{fixtures → example-data}/public-directory-review-resource.js +2 -2
  8. package/dist/example-data/public-field-review.d.ts +2 -0
  9. package/dist/{fixtures → example-data}/public-field-review.js +2 -2
  10. package/dist/{fixtures → example-data}/regulated-document-review-resource.d.ts +1 -1
  11. package/dist/{fixtures → example-data}/regulated-document-review-resource.js +3 -3
  12. package/dist/examples/public-field-observation.js +4 -4
  13. package/dist/examples/review-workbench/downstream-public-directory-adapter.d.ts +1 -1
  14. package/dist/examples/review-workbench/facility-credential-consumer.d.ts +2 -2
  15. package/dist/examples/review-workbench/facility-credential-consumer.js +8 -8
  16. package/dist/examples/review-workbench/server-apply-consumer.d.ts +1 -1
  17. package/dist/examples/review-workbench/server-apply-consumer.js +3 -3
  18. package/dist/src/agent-utterance.d.ts +166 -0
  19. package/dist/src/agent-utterance.js +373 -0
  20. package/dist/src/anthropic.d.ts +104 -0
  21. package/dist/src/anthropic.js +383 -0
  22. package/dist/src/index.d.ts +10 -2
  23. package/dist/src/index.js +5 -1
  24. package/dist/src/inquiry-mapping.d.ts +256 -0
  25. package/dist/src/inquiry-mapping.js +385 -0
  26. package/dist/src/review-workbench/review-queue-session.js +3 -3
  27. package/dist/src/review-workbench/review-surface-preview.js +1 -1
  28. package/dist/src/review-workbench/review-workbench-data.d.ts +4 -4
  29. package/dist/src/review-workbench/review-workbench-data.js +14 -14
  30. package/dist/src/schema-mapping.d.ts +196 -0
  31. package/dist/src/schema-mapping.js +486 -0
  32. package/dist/src/to-flow-artifact.d.ts +41 -0
  33. package/dist/src/to-flow-artifact.js +31 -0
  34. package/dist/src/to-surface.d.ts +3 -3
  35. package/dist/src/to-surface.js +1 -1
  36. package/dist/src/types.d.ts +2 -2
  37. package/package.json +25 -9
  38. package/dist/fixtures/corrected-document-candidates.d.ts +0 -2
  39. package/dist/fixtures/public-field-review.d.ts +0 -2
@@ -0,0 +1,2 @@
1
+ import type { SurveyInput } from "../src/index.js";
2
+ export declare const correctedDocumentCandidatesExample: SurveyInput;
@@ -1,6 +1,6 @@
1
1
  const generatedAt = "2026-05-31T16:00:00.000Z";
2
- export const correctedDocumentCandidatesFixture = {
3
- source: "survey.fixture.corrected-document-candidates",
2
+ export const correctedDocumentCandidatesExample = {
3
+ source: "survey.example.corrected-document-candidates",
4
4
  generatedAt,
5
5
  rawSources: [
6
6
  {
@@ -166,7 +166,7 @@ function computationClaim(id, status, inputClaimIds) {
166
166
  impactLevel: "high",
167
167
  evidenceType: "calculation_trace",
168
168
  evidenceMethod: "validation",
169
- collectedBy: "survey-document-fixture",
169
+ collectedBy: "survey-document-example",
170
170
  eventMethod: "rule-application",
171
171
  derivedFrom: inputClaimIds,
172
172
  derivationEdges: inputClaimIds.map((inputClaimId, index) => ({
@@ -39,7 +39,7 @@ export interface DownstreamPublicDirectoryProposal {
39
39
  crawlTrigger?: string;
40
40
  crawlTriggeredBy?: string | null;
41
41
  }
42
- export declare const downstreamPublicDirectoryProposalFixture: {
42
+ export declare const downstreamPublicDirectoryProposalExample: {
43
43
  id: string;
44
44
  publicRecordId: string;
45
45
  crawlRunId: string;
@@ -1,4 +1,4 @@
1
- export const downstreamPublicDirectoryProposalFixture = {
1
+ export const downstreamPublicDirectoryProposalExample = {
2
2
  id: "proposal-public-456",
3
3
  publicRecordId: "record-123",
4
4
  crawlRunId: "crawl-run-2026-05-31",
@@ -1,4 +1,4 @@
1
- export declare const publicDirectoryReviewItemFixture: {
1
+ export declare const publicDirectoryReviewItemExample: {
2
2
  apiVersion: "survey.kontourai.io/v1alpha1";
3
3
  kind: "ReviewItem";
4
4
  metadata: {
@@ -128,7 +128,7 @@ export declare const publicDirectoryReviewItemFixture: {
128
128
  reviewDecisionName: string;
129
129
  };
130
130
  };
131
- export declare const publicDirectoryReviewDecisionFixture: {
131
+ export declare const publicDirectoryReviewDecisionExample: {
132
132
  apiVersion: "survey.kontourai.io/v1alpha1";
133
133
  kind: "ReviewDecision";
134
134
  metadata: {
@@ -1,5 +1,5 @@
1
1
  import { reviewResourceApiVersion } from "../src/index.js";
2
- export const publicDirectoryReviewItemFixture = {
2
+ export const publicDirectoryReviewItemExample = {
3
3
  apiVersion: reviewResourceApiVersion,
4
4
  kind: "ReviewItem",
5
5
  metadata: {
@@ -129,7 +129,7 @@ export const publicDirectoryReviewItemFixture = {
129
129
  reviewDecisionName: "public-directory-availability-operator-decision",
130
130
  },
131
131
  };
132
- export const publicDirectoryReviewDecisionFixture = {
132
+ export const publicDirectoryReviewDecisionExample = {
133
133
  apiVersion: reviewResourceApiVersion,
134
134
  kind: "ReviewDecision",
135
135
  metadata: {
@@ -0,0 +1,2 @@
1
+ import type { SurveyInput } from "../src/index.js";
2
+ export declare const publicFieldReviewExample: SurveyInput;
@@ -1,6 +1,6 @@
1
1
  const generatedAt = "2026-05-31T16:00:00.000Z";
2
- export const publicFieldReviewFixture = {
3
- source: "survey.fixture.public-field-review",
2
+ export const publicFieldReviewExample = {
3
+ source: "survey.example.public-field-review",
4
4
  generatedAt,
5
5
  rawSources: [
6
6
  {
@@ -1,4 +1,4 @@
1
- export declare const regulatedDocumentReviewItemFixture: {
1
+ export declare const regulatedDocumentReviewItemExample: {
2
2
  apiVersion: "survey.kontourai.io/v1alpha1";
3
3
  kind: "ReviewItem";
4
4
  metadata: {
@@ -1,5 +1,5 @@
1
1
  import { reviewResourceApiVersion } from "../src/index.js";
2
- export const regulatedDocumentReviewItemFixture = {
2
+ export const regulatedDocumentReviewItemExample = {
3
3
  apiVersion: reviewResourceApiVersion,
4
4
  kind: "ReviewItem",
5
5
  metadata: {
@@ -56,7 +56,7 @@ export const regulatedDocumentReviewItemFixture = {
56
56
  impactLevel: "high",
57
57
  evidenceType: "calculation_trace",
58
58
  evidenceMethod: "validation",
59
- collectedBy: "survey-document-fixture",
59
+ collectedBy: "survey-document-example",
60
60
  derivedFrom: [
61
61
  "document.entity-1.statement.amount.original",
62
62
  "document.entity-1.statement.credit.original",
@@ -108,7 +108,7 @@ export const regulatedDocumentReviewItemFixture = {
108
108
  impactLevel: "high",
109
109
  evidenceType: "calculation_trace",
110
110
  evidenceMethod: "validation",
111
- collectedBy: "survey-document-fixture",
111
+ collectedBy: "survey-document-example",
112
112
  derivedFrom: [
113
113
  "document.entity-1.statement.amount.corrected",
114
114
  "document.entity-1.statement.credit.corrected",
@@ -1,5 +1,5 @@
1
- import { buildTrustReport, validateTrustInput } from "@kontourai/surface";
2
- import { buildSurveyTrustInput, SurveyInputBuilder } from "../src/index.js";
1
+ import { buildTrustReport, validateTrustBundle } from "@kontourai/surface";
2
+ import { buildSurveyTrustBundle, SurveyInputBuilder } from "../src/index.js";
3
3
  const observedAt = "2026-05-31T16:00:00.000Z";
4
4
  const surveyInput = new SurveyInputBuilder({
5
5
  source: "example-producer:public-field",
@@ -38,6 +38,6 @@ const surveyInput = new SurveyInputBuilder({
38
38
  },
39
39
  })
40
40
  .build();
41
- const trustInput = validateTrustInput(buildSurveyTrustInput(surveyInput));
42
- const report = buildTrustReport(trustInput);
41
+ const trustBundle = validateTrustBundle(buildSurveyTrustBundle(surveyInput));
42
+ const report = buildTrustReport(trustBundle);
43
43
  console.log(JSON.stringify(report.summary, null, 2));
@@ -1,3 +1,3 @@
1
1
  import { type ReviewItem } from "../../src/review-resource.js";
2
- import type { DownstreamPublicDirectoryProposal } from "../../fixtures/downstream-public-directory-proposal.js";
2
+ import type { DownstreamPublicDirectoryProposal } from "../../example-data/downstream-public-directory-proposal.js";
3
3
  export declare function downstreamPublicDirectoryProposalToReviewItem(proposal: DownstreamPublicDirectoryProposal, field?: string): ReviewItem;
@@ -1,11 +1,11 @@
1
- import { facilityCredentialReviewItemFixture } from "../../src/review-workbench/review-workbench-data.js";
1
+ import { facilityCredentialReviewItemExample } from "../../src/review-workbench/review-workbench-data.js";
2
2
  import { buildReviewItemPresentation, buildReviewResultPresentation, buildSurfaceProjectionPreview, deriveReviewSessionApplyResultForSnapshot, initialReviewQueueSessionState, type ReviewPresentationAdapter } from "../../src/review-workbench/review-workbench.js";
3
3
  import type { ReviewSessionEvent } from "../../src/review-resource.js";
4
4
  export declare const facilityCredentialPresentationAdapter: ReviewPresentationAdapter;
5
5
  export declare function buildFacilityCredentialConsumerExample(): Promise<FacilityCredentialConsumerExample>;
6
6
  export declare const facilityCredentialConsumerExample: FacilityCredentialConsumerExample;
7
7
  export interface FacilityCredentialConsumerExample {
8
- readonly reviewItem: typeof facilityCredentialReviewItemFixture;
8
+ readonly reviewItem: typeof facilityCredentialReviewItemExample;
9
9
  readonly reviewSessionSnapshot: ReturnType<typeof initialReviewQueueSessionState>;
10
10
  readonly reviewedSnapshot: ReturnType<typeof initialReviewQueueSessionState>;
11
11
  readonly eventsToPersist: readonly ReviewSessionEvent[];
@@ -1,4 +1,4 @@
1
- import { facilityCredentialReviewItemFixture } from "../../src/review-workbench/review-workbench-data.js";
1
+ import { facilityCredentialReviewItemExample } from "../../src/review-workbench/review-workbench-data.js";
2
2
  import { buildReviewItemPresentation, buildReviewResultPresentation, buildReviewSessionEvents, buildSurfaceProjectionPreview, deriveReviewSessionApplyResultForSnapshot, initialReviewQueueSessionState, persistReviewSessionEvents, } from "../../src/review-workbench/review-workbench.js";
3
3
  export const facilityCredentialPresentationAdapter = {
4
4
  labelForTarget: (target) => target === "operatingLicenseCredential"
@@ -46,17 +46,17 @@ export const facilityCredentialPresentationAdapter = {
46
46
  };
47
47
  export async function buildFacilityCredentialConsumerExample() {
48
48
  const reviewSessionSnapshot = {
49
- ...initialReviewQueueSessionState([facilityCredentialReviewItemFixture]),
49
+ ...initialReviewQueueSessionState([facilityCredentialReviewItemExample]),
50
50
  actorId: "review-operator@example.test",
51
51
  reviewedAt: "2026-01-17T16:15:00.000Z",
52
52
  };
53
53
  const reviewedSnapshot = {
54
54
  ...reviewSessionSnapshot,
55
55
  decisionsByItemName: {
56
- [facilityCredentialReviewItemFixture.metadata.name]: "accept-proposed",
56
+ [facilityCredentialReviewItemExample.metadata.name]: "accept-proposed",
57
57
  },
58
58
  notesByItemName: {
59
- [facilityCredentialReviewItemFixture.metadata.name]: "Registry credential supersedes the managed snapshot.",
59
+ [facilityCredentialReviewItemExample.metadata.name]: "Registry credential supersedes the managed snapshot.",
60
60
  },
61
61
  };
62
62
  const eventsToPersist = buildReviewSessionEvents(reviewedSnapshot);
@@ -85,14 +85,14 @@ export async function buildFacilityCredentialConsumerExample() {
85
85
  if (!result) {
86
86
  throw new Error("Expected the reviewed credential snapshot to produce one review result.");
87
87
  }
88
- const itemPresentation = buildReviewItemPresentation(facilityCredentialReviewItemFixture, facilityCredentialPresentationAdapter);
89
- const resultPresentation = buildReviewResultPresentation(result, facilityCredentialReviewItemFixture, facilityCredentialPresentationAdapter);
90
- const surfaceProjectionPreview = buildSurfaceProjectionPreview(facilityCredentialReviewItemFixture, result.reviewDecision, facilityCredentialPresentationAdapter);
88
+ const itemPresentation = buildReviewItemPresentation(facilityCredentialReviewItemExample, facilityCredentialPresentationAdapter);
89
+ const resultPresentation = buildReviewResultPresentation(result, facilityCredentialReviewItemExample, facilityCredentialPresentationAdapter);
90
+ const surfaceProjectionPreview = buildSurfaceProjectionPreview(facilityCredentialReviewItemExample, result.reviewDecision, facilityCredentialPresentationAdapter);
91
91
  if (!surfaceProjectionPreview) {
92
92
  throw new Error("Expected the reviewed credential result to produce a Surface projection preview.");
93
93
  }
94
94
  return {
95
- reviewItem: facilityCredentialReviewItemFixture,
95
+ reviewItem: facilityCredentialReviewItemExample,
96
96
  reviewSessionSnapshot,
97
97
  reviewedSnapshot,
98
98
  eventsToPersist,
@@ -27,4 +27,4 @@ export declare function prepareFacilityCredentialServerApply(input: {
27
27
  readonly actorId: string;
28
28
  readonly appliedAt: string;
29
29
  }): FacilityCredentialApplyPreparation;
30
- export declare const facilityCredentialCurrentRecordFixture: FacilityCredentialRecord;
30
+ export declare const facilityCredentialCurrentRecordExample: FacilityCredentialRecord;
@@ -1,4 +1,4 @@
1
- import { facilityCredentialReviewItemFixture } from "../../src/review-workbench/review-workbench-data.js";
1
+ import { facilityCredentialReviewItemExample } from "../../src/review-workbench/review-workbench-data.js";
2
2
  import { deriveReviewSessionApplyResultForSnapshot, } from "../../src/review-workbench/review-workbench.js";
3
3
  export function prepareFacilityCredentialServerApply(input) {
4
4
  const applyResult = deriveReviewSessionApplyResultForSnapshot({
@@ -40,8 +40,8 @@ export function prepareFacilityCredentialServerApply(input) {
40
40
  },
41
41
  };
42
42
  }
43
- export const facilityCredentialCurrentRecordFixture = {
43
+ export const facilityCredentialCurrentRecordExample = {
44
44
  id: "facility-credential-record-1",
45
- credential: facilityCredentialReviewItemFixture.spec.candidates.find((candidate) => candidate.role === "current")?.value,
45
+ credential: facilityCredentialReviewItemExample.spec.candidates.find((candidate) => candidate.role === "current")?.value,
46
46
  appliedReviewItemNames: [],
47
47
  };
@@ -0,0 +1,166 @@
1
+ /**
2
+ * Agent-utterance producer profile — ADR 0003 step 6.
3
+ *
4
+ * This module implements Survey as a producer pointed at agent utterances
5
+ * instead of web sources. Each factual statement in agent prose is extracted
6
+ * as a candidate claim and run through the Inquiry pipeline.
7
+ *
8
+ * Integration point: surveyAgentUtterance is the clean entry point for
9
+ * consumers wanting to "spell-check" an agent's output for evidence. Flow-agent
10
+ * hook wiring (connecting this function to a live agent's output pipeline) is
11
+ * out of scope for this module and lives in the flow-agents repo.
12
+ *
13
+ * Hard constraint (ADR 0003 §4): nothing here silently decides. The
14
+ * UtteranceClaimExtractor is a pluggable interface; implementations may be
15
+ * deterministic or model-backed, but they are always extractors — their output
16
+ * has full provenance (excerpt, span, extractor name, confidence) and is
17
+ * run through the Inquiry pipeline rather than treated as authoritative.
18
+ */
19
+ import type { DerivationRule, InquiryRecord, TrustBundle } from "@kontourai/surface";
20
+ import type { CanonicalClaimTarget } from "@kontourai/surface";
21
+ import type { Candidate, CandidateSet, Extraction, RawSource, SurveyInput } from "./types.js";
22
+ import type { InquiryMapping } from "./inquiry-mapping.js";
23
+ /**
24
+ * A single extracted statement from an utterance.
25
+ */
26
+ export interface ExtractedStatement {
27
+ /** The canonical claim target this statement is about. */
28
+ target: CanonicalClaimTarget;
29
+ /** The value claimed (if parseable). */
30
+ value?: unknown;
31
+ /** The verbatim text segment that contains this claim. */
32
+ excerpt: string;
33
+ /** Character-offset span within the utterance (0-indexed). */
34
+ span?: {
35
+ start: number;
36
+ end: number;
37
+ };
38
+ /** Extractor confidence (0–1). */
39
+ confidence: number;
40
+ }
41
+ /**
42
+ * Pluggable interface for extracting canonical claim statements from
43
+ * agent-generated text.
44
+ *
45
+ * Implementations may be deterministic (like the reference extractor below),
46
+ * regex-based, NLP-based, or LLM-backed — but they are always extractors:
47
+ * their output carries full provenance and goes through the Inquiry pipeline
48
+ * rather than being treated as an authoritative answer.
49
+ */
50
+ export interface UtteranceClaimExtractor {
51
+ name: string;
52
+ extract(utterance: string): ExtractedStatement[] | Promise<ExtractedStatement[]>;
53
+ }
54
+ /**
55
+ * Badge values for each extracted statement, derived from the inquiry outcome
56
+ * and the answer status.
57
+ *
58
+ * - "verified": inquiry matched/derived and answer status is "verified"
59
+ * - "assumed": inquiry matched/derived and answer status is "assumed"
60
+ * - "stale": inquiry matched/derived and answer status is "stale"
61
+ * - "disputed": inquiry matched/derived and answer status is "disputed"
62
+ * - "rejected": inquiry matched/derived and answer status is "rejected"
63
+ * - "unsupported": inquiry outcome is "unsupported" (no mapping or no registered claim)
64
+ */
65
+ export type StatementBadge = "verified" | "assumed" | "stale" | "disputed" | "rejected" | "unsupported";
66
+ export interface UtteranceStatement {
67
+ excerpt: string;
68
+ span?: {
69
+ start: number;
70
+ end: number;
71
+ };
72
+ target: CanonicalClaimTarget;
73
+ inquiryRecord: InquiryRecord;
74
+ badge: StatementBadge;
75
+ }
76
+ /**
77
+ * The result of surveying an agent utterance.
78
+ *
79
+ * source: the RawSource representing the utterance (kind: "agent-utterance").
80
+ * statements: per-statement verdicts, each with full provenance.
81
+ *
82
+ * This is the "spell-check for evidence" projection. Flow-agent hook wiring
83
+ * is out of scope for this module (lives in flow-agents repo).
84
+ */
85
+ export interface UtteranceTrustReport {
86
+ source: RawSource;
87
+ statements: UtteranceStatement[];
88
+ }
89
+ /**
90
+ * Full set of Survey records generated for a single extracted statement.
91
+ * These are produced for provenance but not projected to Surface directly —
92
+ * the report is the consumer-facing artifact.
93
+ */
94
+ export interface UtteranceStatementRecords {
95
+ extraction: Extraction;
96
+ candidate: Candidate;
97
+ candidateSet: CandidateSet;
98
+ }
99
+ /**
100
+ * Project an agent utterance and its extracted statements into the standard
101
+ * SurveyInput shape so they can flow into buildSurveyTrustBundle.
102
+ *
103
+ * Each extracted statement lands as:
104
+ * RawSource (agent-utterance) → Extraction (with text-span locator) →
105
+ * Candidate → CandidateSet (needs-review, no review outcome) → ClaimTarget
106
+ *
107
+ * Status discipline (ADR 0003 §4, to-surface.ts producer rules):
108
+ * - All claims project as "proposed" — unreviewed extractions are proposals,
109
+ * never authoritative. assertProducerDiscipline forbids verified/assumed
110
+ * without a review outcome.
111
+ * - agent-utterance is not a manual-entry source, so extraction.locator is
112
+ * required. Span-located statements use text-span:start-end; span-less
113
+ * statements use text-span derived from the excerpt offset in the utterance
114
+ * (best-effort, 0-based).
115
+ *
116
+ * The returned SurveyInput can be passed directly to buildSurveyTrustBundle
117
+ * to produce a TrustBundle with full provenance in the Trust Bundle metadata.
118
+ *
119
+ * @param utterance - The raw agent utterance text.
120
+ * @param extracted - ExtractedStatements produced by a UtteranceClaimExtractor.
121
+ * @param context - agentId, extractor name, optional now timestamp.
122
+ */
123
+ export declare function utteranceToSurveyInput(utterance: string, extracted: ExtractedStatement[], context: {
124
+ agentId: string;
125
+ extractorName: string;
126
+ now?: Date;
127
+ source?: string;
128
+ }): SurveyInput;
129
+ /**
130
+ * Survey an agent utterance, returning a trust report for each extracted claim.
131
+ *
132
+ * Steps:
133
+ * 1. Build a RawSource for the utterance (kind: "agent-utterance").
134
+ * 2. Run the extractor → project each statement into Survey records with full
135
+ * provenance (excerpt, span locator, extractor name, confidence).
136
+ * 3. Resolve each extracted claim against the bundle via resolveInquiry or
137
+ * resolveQuestion (if mappings are provided).
138
+ * 4. Return an UtteranceTrustReport with per-statement badges.
139
+ *
140
+ * This function is the integration point for consumers. Flow-agent hook wiring
141
+ * lives in the flow-agents repo.
142
+ */
143
+ export declare function surveyAgentUtterance(utterance: string, extractor: UtteranceClaimExtractor, context: {
144
+ bundle: TrustBundle;
145
+ mappings?: InquiryMapping[];
146
+ rules?: DerivationRule[];
147
+ now?: Date;
148
+ agentId: string;
149
+ }): Promise<UtteranceTrustReport>;
150
+ /**
151
+ * Reference UtteranceClaimExtractor for tests.
152
+ *
153
+ * REFERENCE IMPLEMENTATION ONLY — not suitable for production extraction.
154
+ *
155
+ * Parsing strategy: looks for statements matching the pattern:
156
+ * "<subjectId> <fieldOrBehavior> is <value>"
157
+ * or
158
+ * "<subjectId> <fieldOrBehavior>: <value>"
159
+ *
160
+ * where subjectId and fieldOrBehavior are single words. This intentionally
161
+ * simple and transparent pattern lets tests be deterministic.
162
+ *
163
+ * The subjectType is always "unknown" since it cannot be inferred from text
164
+ * alone in this reference implementation.
165
+ */
166
+ export declare const referenceUtteranceExtractor: UtteranceClaimExtractor;