@kontourai/survey 0.1.5 → 0.2.1
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/README.md +74 -4
- package/dist/fixtures/corrected-document-candidates.js +86 -50
- package/dist/src/builder.d.ts +1 -3
- package/dist/src/builder.js +0 -6
- package/dist/src/index.d.ts +3 -1
- package/dist/src/index.js +1 -0
- package/dist/src/raw-source.d.ts +31 -0
- package/dist/src/raw-source.js +48 -0
- package/dist/src/to-surface.js +2 -47
- package/dist/src/types.d.ts +3 -24
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Kontour Survey
|
|
2
2
|
|
|
3
|
-
Survey is the producer-side contract for turning
|
|
4
|
-
Surface-ready
|
|
3
|
+
Survey is the producer-side contract for turning producer observations into
|
|
4
|
+
Surface-ready `TrustInput`.
|
|
5
5
|
|
|
6
6
|
This repo is intentionally small right now. It is a proof package, not an
|
|
7
7
|
ingestion platform:
|
|
@@ -10,8 +10,8 @@ ingestion platform:
|
|
|
10
10
|
- Survey owns source, extraction, candidate, and review record shapes;
|
|
11
11
|
- `buildSurveyTrustInput` projects those records into `@kontourai/surface`
|
|
12
12
|
`TrustInput`;
|
|
13
|
-
- Surface owns
|
|
14
|
-
transparency.
|
|
13
|
+
- Surface owns Claim, Subject, Claim Type, Evidence, Status, Claim Dependency,
|
|
14
|
+
TrustInput, trust reporting, console projections, and downstream transparency.
|
|
15
15
|
|
|
16
16
|
The first success criterion is that generic corrected-document and public-field
|
|
17
17
|
fixtures can pass through Survey and produce valid Surface reports without
|
|
@@ -64,6 +64,60 @@ const trustInput = validateTrustInput(buildSurveyTrustInput(surveyInput));
|
|
|
64
64
|
const report = buildTrustReport(trustInput);
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
+
## Raw sources
|
|
68
|
+
|
|
69
|
+
Use raw-source helpers when a producer wants Survey to shape source identity
|
|
70
|
+
before building observations. The helpers do not fetch, crawl, parse, or judge
|
|
71
|
+
the source; they only produce stable `RawSource` records with explicit source
|
|
72
|
+
references, observed times, locator schemes, checksums, and producer metadata.
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
import {
|
|
76
|
+
apiRecordSource,
|
|
77
|
+
fieldObservation,
|
|
78
|
+
SurveyInputBuilder,
|
|
79
|
+
} from "@kontourai/survey";
|
|
80
|
+
|
|
81
|
+
const rawSource = apiRecordSource({
|
|
82
|
+
sourceRef: "example-records://entity/entity-123",
|
|
83
|
+
observedAt: new Date().toISOString(),
|
|
84
|
+
checksum: "abc123",
|
|
85
|
+
metadata: {
|
|
86
|
+
provider: "example-records",
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
const surveyInput = new SurveyInputBuilder({ source: "example-producer:run-1" })
|
|
91
|
+
.addObservation(fieldObservation({
|
|
92
|
+
id: "entity-123.status.current",
|
|
93
|
+
field: "registrationStatus",
|
|
94
|
+
value: "ACTIVE",
|
|
95
|
+
rawSource,
|
|
96
|
+
extraction: {
|
|
97
|
+
confidence: 0.97,
|
|
98
|
+
locator: "json:$.registrationStatus",
|
|
99
|
+
extractor: "example-extractor",
|
|
100
|
+
extractedAt: new Date().toISOString(),
|
|
101
|
+
},
|
|
102
|
+
claim: {
|
|
103
|
+
subjectType: "public-record.entity",
|
|
104
|
+
subjectId: "entity-123",
|
|
105
|
+
surface: "example.profile",
|
|
106
|
+
claimType: "public-data.field",
|
|
107
|
+
status: "proposed",
|
|
108
|
+
impactLevel: "medium",
|
|
109
|
+
collectedBy: "example-extractor",
|
|
110
|
+
},
|
|
111
|
+
}))
|
|
112
|
+
.build();
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Survey exports `uploadedDocumentSource`, `apiRecordSource`, `webPageSource`,
|
|
116
|
+
and `manualEntrySource`. Producer-provided `id` values are preserved; otherwise
|
|
117
|
+
Survey derives a stable id from source kind and `sourceRef`. Bare checksum
|
|
118
|
+
values are normalized to `sha256:<value>`, while already-prefixed checksum
|
|
119
|
+
values are preserved. Producer metadata is copied through to Surface evidence.
|
|
120
|
+
|
|
67
121
|
## Field observations
|
|
68
122
|
|
|
69
123
|
Use `fieldObservation` when a producer wants to describe one scalar field value
|
|
@@ -295,6 +349,22 @@ shared candidate set while rejecting conflicting duplicate ids. Duplicate
|
|
|
295
349
|
conflict checks assume Survey records are JSON-shaped data, which is the same
|
|
296
350
|
shape expected by Surface validation and reports.
|
|
297
351
|
|
|
352
|
+
A candidate set with status `"conflict"` represents a Survey-side Candidate
|
|
353
|
+
Conflict before review has resolved which candidate should win. When no review
|
|
354
|
+
outcome overrides it, `buildSurveyTrustInput` projects the claim to Surface
|
|
355
|
+
status `"disputed"` and records a `"candidate-conflict"` verification event.
|
|
356
|
+
|
|
357
|
+
## Computed values
|
|
358
|
+
|
|
359
|
+
Computed values are normal `ClaimTarget` entries in `claims`. Producers should
|
|
360
|
+
link them to their inputs with Surface Claim Dependency fields:
|
|
361
|
+
`derivedFrom` for simple claim-id links, or `derivationEdges` when the link
|
|
362
|
+
needs method, role, support-strength, rationale, or metadata.
|
|
363
|
+
|
|
364
|
+
Survey passes those fields through to Surface while keeping the same
|
|
365
|
+
source -> extraction -> candidate -> review -> claim projection path. Surface
|
|
366
|
+
owns dependency semantics such as recompute pressure and status ceilings.
|
|
367
|
+
|
|
298
368
|
## Product Boundary
|
|
299
369
|
|
|
300
370
|
Survey does not crawl pages, parse PDFs, rank candidates, decide review policy,
|
|
@@ -19,16 +19,22 @@ export const correctedDocumentCandidatesFixture = {
|
|
|
19
19
|
checksum: "sha256:corrected",
|
|
20
20
|
locatorScheme: "pdf",
|
|
21
21
|
},
|
|
22
|
+
computationSource("current"),
|
|
23
|
+
computationSource("original"),
|
|
22
24
|
],
|
|
23
25
|
extractions: [
|
|
24
26
|
documentExtraction("original:amount", "document:source:original", "statement.totalAmount", 82000, "pdf:page=1;box=1"),
|
|
25
27
|
documentExtraction("original:credit", "document:source:original", "statement.creditAmount", 8600, "pdf:page=1;box=2"),
|
|
26
28
|
documentExtraction("corrected:amount", "document:source:corrected", "statement.totalAmount", 84000, "pdf:page=1;box=1"),
|
|
27
29
|
documentExtraction("corrected:credit", "document:source:corrected", "statement.creditAmount", 9100, "pdf:page=1;box=2"),
|
|
30
|
+
computationExtraction("current", 84000, 9100),
|
|
31
|
+
computationExtraction("original", 82000, 8600),
|
|
28
32
|
],
|
|
29
33
|
candidateSets: [
|
|
30
34
|
documentCandidateSet("amount", "original:amount", 82000, "corrected:amount", 84000),
|
|
31
35
|
documentCandidateSet("credit", "original:credit", 8600, "corrected:credit", 9100),
|
|
36
|
+
computationCandidateSet("current", 84000, 9100),
|
|
37
|
+
computationCandidateSet("original", 82000, 8600),
|
|
32
38
|
],
|
|
33
39
|
reviewOutcomes: [],
|
|
34
40
|
claims: [
|
|
@@ -36,58 +42,23 @@ export const correctedDocumentCandidatesFixture = {
|
|
|
36
42
|
documentClaim("document.entity-1.statement.credit.original", "credit", "original:credit", "statement.creditAmount", "superseded"),
|
|
37
43
|
documentClaim("document.entity-1.statement.amount.corrected", "amount", "corrected:amount", "statement.totalAmount", "proposed"),
|
|
38
44
|
documentClaim("document.entity-1.statement.credit.corrected", "credit", "corrected:credit", "statement.creditAmount", "proposed"),
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
fieldOrBehavior: "statementPosition",
|
|
48
|
-
value: {
|
|
49
|
-
totalAmount: 84000,
|
|
50
|
-
creditAmount: 9100,
|
|
51
|
-
position: "credit-present",
|
|
52
|
-
},
|
|
53
|
-
status: "proposed",
|
|
54
|
-
impactLevel: "high",
|
|
55
|
-
inputClaimIds: [
|
|
56
|
-
{ claimId: "document.entity-1.statement.amount.corrected", role: "amount-input", supportStrength: "strong" },
|
|
57
|
-
{ claimId: "document.entity-1.statement.credit.corrected", role: "credit-input", supportStrength: "strong" },
|
|
58
|
-
],
|
|
59
|
-
createdAt: generatedAt,
|
|
60
|
-
updatedAt: generatedAt,
|
|
61
|
-
evidenceSummary: "Derived statement position from corrected source fields.",
|
|
62
|
-
sourceRef: "documents://entities/entity-1/periods/2026/resolved-fields/statement",
|
|
63
|
-
collectedBy: "survey-document-fixture",
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
id: "document.entity-1.statement-position.original",
|
|
67
|
-
subjectType: "verified-record.period",
|
|
68
|
-
subjectId: "entity-1:2026",
|
|
69
|
-
surface: "document-review",
|
|
70
|
-
claimType: "derived-field",
|
|
71
|
-
fieldOrBehavior: "statementPosition",
|
|
72
|
-
value: {
|
|
73
|
-
totalAmount: 82000,
|
|
74
|
-
creditAmount: 8600,
|
|
75
|
-
position: "credit-present",
|
|
76
|
-
},
|
|
77
|
-
status: "stale",
|
|
78
|
-
impactLevel: "high",
|
|
79
|
-
inputClaimIds: [
|
|
80
|
-
{ claimId: "document.entity-1.statement.amount.original", role: "amount-input", supportStrength: "strong" },
|
|
81
|
-
{ claimId: "document.entity-1.statement.credit.original", role: "credit-input", supportStrength: "strong" },
|
|
82
|
-
],
|
|
83
|
-
createdAt: generatedAt,
|
|
84
|
-
updatedAt: generatedAt,
|
|
85
|
-
evidenceSummary: "Prior statement position derived from original source fields.",
|
|
86
|
-
sourceRef: "documents://entities/entity-1/periods/2026/resolved-fields/statement",
|
|
87
|
-
collectedBy: "survey-document-fixture",
|
|
88
|
-
},
|
|
45
|
+
computationClaim("current", "proposed", [
|
|
46
|
+
"document.entity-1.statement.amount.corrected",
|
|
47
|
+
"document.entity-1.statement.credit.corrected",
|
|
48
|
+
]),
|
|
49
|
+
computationClaim("original", "stale", [
|
|
50
|
+
"document.entity-1.statement.amount.original",
|
|
51
|
+
"document.entity-1.statement.credit.original",
|
|
52
|
+
]),
|
|
89
53
|
],
|
|
90
54
|
};
|
|
55
|
+
function statementPosition(totalAmount, creditAmount) {
|
|
56
|
+
return {
|
|
57
|
+
totalAmount,
|
|
58
|
+
creditAmount,
|
|
59
|
+
position: "credit-present",
|
|
60
|
+
};
|
|
61
|
+
}
|
|
91
62
|
function documentExtraction(id, sourceId, target, value, locator) {
|
|
92
63
|
return {
|
|
93
64
|
id: `document:extraction:${id}`,
|
|
@@ -126,6 +97,45 @@ function documentCandidateSet(target, originalId, originalValue, correctedId, co
|
|
|
126
97
|
],
|
|
127
98
|
};
|
|
128
99
|
}
|
|
100
|
+
function computationSource(id) {
|
|
101
|
+
return {
|
|
102
|
+
id: `document:source:statement-position:${id}`,
|
|
103
|
+
kind: "manual-entry",
|
|
104
|
+
sourceRef: "documents://entities/entity-1/periods/2026/resolved-fields/statement",
|
|
105
|
+
observedAt: generatedAt,
|
|
106
|
+
locatorScheme: "structured-field",
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function computationExtraction(id, totalAmount, creditAmount) {
|
|
110
|
+
return {
|
|
111
|
+
id: `document:extraction:statement-position:${id}`,
|
|
112
|
+
sourceId: `document:source:statement-position:${id}`,
|
|
113
|
+
target: "statementPosition",
|
|
114
|
+
value: statementPosition(totalAmount, creditAmount),
|
|
115
|
+
confidence: 0.96,
|
|
116
|
+
extractor: "statement-position-rule",
|
|
117
|
+
extractedAt: generatedAt,
|
|
118
|
+
excerpt: `${id} statement position from source fields.`,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
function computationCandidateSet(id, totalAmount, creditAmount) {
|
|
122
|
+
return {
|
|
123
|
+
id: `document:candidates:statement-position:${id}`,
|
|
124
|
+
target: "statementPosition",
|
|
125
|
+
selectedCandidateId: `document:candidate:statement-position:${id}`,
|
|
126
|
+
status: "needs-review",
|
|
127
|
+
rationale: "Statement position is computed from statement amount and credit fields.",
|
|
128
|
+
candidates: [
|
|
129
|
+
{
|
|
130
|
+
id: `document:candidate:statement-position:${id}`,
|
|
131
|
+
extractionId: `document:extraction:statement-position:${id}`,
|
|
132
|
+
value: statementPosition(totalAmount, creditAmount),
|
|
133
|
+
confidence: 0.96,
|
|
134
|
+
sourceRank: 1,
|
|
135
|
+
},
|
|
136
|
+
],
|
|
137
|
+
};
|
|
138
|
+
}
|
|
129
139
|
function documentClaim(id, target, candidateId, fieldOrBehavior, status) {
|
|
130
140
|
return {
|
|
131
141
|
id,
|
|
@@ -141,3 +151,29 @@ function documentClaim(id, target, candidateId, fieldOrBehavior, status) {
|
|
|
141
151
|
collectedBy: "document-field-parser",
|
|
142
152
|
};
|
|
143
153
|
}
|
|
154
|
+
function computationClaim(id, status, inputClaimIds) {
|
|
155
|
+
const roles = ["amount-input", "credit-input"];
|
|
156
|
+
return {
|
|
157
|
+
id: `document.entity-1.statement-position.${id}`,
|
|
158
|
+
candidateSetId: `document:candidates:statement-position:${id}`,
|
|
159
|
+
candidateId: `document:candidate:statement-position:${id}`,
|
|
160
|
+
subjectType: "verified-record.period",
|
|
161
|
+
subjectId: "entity-1:2026",
|
|
162
|
+
surface: "document-review",
|
|
163
|
+
claimType: "computed-field",
|
|
164
|
+
fieldOrBehavior: "statementPosition",
|
|
165
|
+
status,
|
|
166
|
+
impactLevel: "high",
|
|
167
|
+
evidenceType: "calculation_trace",
|
|
168
|
+
evidenceMethod: "validation",
|
|
169
|
+
collectedBy: "survey-document-fixture",
|
|
170
|
+
eventMethod: "rule-application",
|
|
171
|
+
derivedFrom: inputClaimIds,
|
|
172
|
+
derivationEdges: inputClaimIds.map((inputClaimId, index) => ({
|
|
173
|
+
inputClaimId,
|
|
174
|
+
method: "rule-application",
|
|
175
|
+
role: roles[index],
|
|
176
|
+
supportStrength: "strong",
|
|
177
|
+
})),
|
|
178
|
+
};
|
|
179
|
+
}
|
package/dist/src/builder.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CandidateSet, ClaimTarget,
|
|
1
|
+
import type { CandidateSet, ClaimTarget, Extraction, RawSource, ReviewOutcome, SurveyInput } from "./types.js";
|
|
2
2
|
export interface SurveyInputBuilderArgs {
|
|
3
3
|
source: string;
|
|
4
4
|
generatedAt?: string;
|
|
@@ -58,14 +58,12 @@ export declare class SurveyInputBuilder {
|
|
|
58
58
|
private readonly candidateSets;
|
|
59
59
|
private readonly reviewOutcomes;
|
|
60
60
|
private readonly claims;
|
|
61
|
-
private readonly derivedClaims;
|
|
62
61
|
constructor(args: SurveyInputBuilderArgs);
|
|
63
62
|
addRawSource(rawSource: RawSource): this;
|
|
64
63
|
addExtraction(extraction: Extraction): this;
|
|
65
64
|
addCandidateSet(candidateSet: CandidateSet): this;
|
|
66
65
|
addReviewOutcome(reviewOutcome: ReviewOutcome): this;
|
|
67
66
|
addClaim(claim: ClaimTarget): this;
|
|
68
|
-
addDerivedClaim(derivedClaim: DerivedClaimTarget): this;
|
|
69
67
|
addClaimRecord(record: SurveyClaimRecord): this;
|
|
70
68
|
addClaimRecords(records: SurveyClaimRecord[]): this;
|
|
71
69
|
addObservation(observation: SurveyObservationInput): this;
|
package/dist/src/builder.js
CHANGED
|
@@ -6,7 +6,6 @@ export class SurveyInputBuilder {
|
|
|
6
6
|
candidateSets = new Map();
|
|
7
7
|
reviewOutcomes = new Map();
|
|
8
8
|
claims = new Map();
|
|
9
|
-
derivedClaims = new Map();
|
|
10
9
|
constructor(args) {
|
|
11
10
|
this.source = args.source;
|
|
12
11
|
this.generatedAt = args.generatedAt ?? new Date().toISOString();
|
|
@@ -31,10 +30,6 @@ export class SurveyInputBuilder {
|
|
|
31
30
|
addUnique(this.claims, claim, "claim target");
|
|
32
31
|
return this;
|
|
33
32
|
}
|
|
34
|
-
addDerivedClaim(derivedClaim) {
|
|
35
|
-
addUnique(this.derivedClaims, derivedClaim, "derived claim target");
|
|
36
|
-
return this;
|
|
37
|
-
}
|
|
38
33
|
addClaimRecord(record) {
|
|
39
34
|
this.addRecordRawSource(record.rawSource);
|
|
40
35
|
this.addExtraction(record.extraction);
|
|
@@ -66,7 +61,6 @@ export class SurveyInputBuilder {
|
|
|
66
61
|
candidateSets: [...this.candidateSets.values()],
|
|
67
62
|
reviewOutcomes: [...this.reviewOutcomes.values()],
|
|
68
63
|
claims: [...this.claims.values()],
|
|
69
|
-
derivedClaims: [...this.derivedClaims.values()],
|
|
70
64
|
};
|
|
71
65
|
}
|
|
72
66
|
addRecordCandidateSet(candidateSet) {
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type { CandidateSetStatus, Candidate, CandidateSet, ClaimTarget,
|
|
1
|
+
export type { CandidateSetStatus, Candidate, CandidateSet, ClaimTarget, Extraction, LocatorScheme, RawSource, RawSourceKind, ReviewOutcome, ReviewStatus, SurveyInput, } from "./types.js";
|
|
2
2
|
export { candidateReviewRecord, SurveyInputBuilder } from "./builder.js";
|
|
3
3
|
export type { CandidateReviewRecordInput, SurveyClaimRecord, SurveyInputBuilderArgs, SurveyObservationInput, } from "./builder.js";
|
|
4
4
|
export { buildSurveyTrustInput } from "./to-surface.js";
|
|
@@ -6,3 +6,5 @@ export { fieldObservation } from "./field-observation.js";
|
|
|
6
6
|
export type { FieldObservationInput } from "./field-observation.js";
|
|
7
7
|
export { repeatedObservation } from "./repeated-observation.js";
|
|
8
8
|
export type { RepeatedObservationInput } from "./repeated-observation.js";
|
|
9
|
+
export { apiRecordSource, manualEntrySource, uploadedDocumentSource, webPageSource, } from "./raw-source.js";
|
|
10
|
+
export type { ApiRecordSourceInput, ChecksumInput, ManualEntrySourceInput, RawSourceInput, UploadedDocumentSourceInput, WebPageSourceInput, } from "./raw-source.js";
|
package/dist/src/index.js
CHANGED
|
@@ -2,3 +2,4 @@ export { candidateReviewRecord, SurveyInputBuilder } from "./builder.js";
|
|
|
2
2
|
export { buildSurveyTrustInput } from "./to-surface.js";
|
|
3
3
|
export { fieldObservation } from "./field-observation.js";
|
|
4
4
|
export { repeatedObservation } from "./repeated-observation.js";
|
|
5
|
+
export { apiRecordSource, manualEntrySource, uploadedDocumentSource, webPageSource, } from "./raw-source.js";
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { LocatorScheme, RawSource } from "./types.js";
|
|
2
|
+
export type ChecksumInput = string | {
|
|
3
|
+
algorithm?: string;
|
|
4
|
+
value: string;
|
|
5
|
+
};
|
|
6
|
+
export interface RawSourceInput {
|
|
7
|
+
id?: string;
|
|
8
|
+
sourceRef: string;
|
|
9
|
+
observedAt: string;
|
|
10
|
+
fetchedAt?: string;
|
|
11
|
+
checksum?: ChecksumInput;
|
|
12
|
+
locatorScheme: LocatorScheme;
|
|
13
|
+
metadata?: Record<string, unknown>;
|
|
14
|
+
}
|
|
15
|
+
export interface UploadedDocumentSourceInput extends RawSourceInput {
|
|
16
|
+
locatorScheme: LocatorScheme;
|
|
17
|
+
}
|
|
18
|
+
export interface ApiRecordSourceInput extends Omit<RawSourceInput, "locatorScheme"> {
|
|
19
|
+
locatorScheme?: LocatorScheme;
|
|
20
|
+
}
|
|
21
|
+
export interface WebPageSourceInput extends Omit<RawSourceInput, "locatorScheme"> {
|
|
22
|
+
locatorScheme?: LocatorScheme;
|
|
23
|
+
}
|
|
24
|
+
export interface ManualEntrySourceInput extends Omit<RawSourceInput, "checksum" | "locatorScheme"> {
|
|
25
|
+
checksum?: ChecksumInput;
|
|
26
|
+
locatorScheme?: LocatorScheme;
|
|
27
|
+
}
|
|
28
|
+
export declare function uploadedDocumentSource(input: UploadedDocumentSourceInput): RawSource;
|
|
29
|
+
export declare function apiRecordSource(input: ApiRecordSourceInput): RawSource;
|
|
30
|
+
export declare function webPageSource(input: WebPageSourceInput): RawSource;
|
|
31
|
+
export declare function manualEntrySource(input: ManualEntrySourceInput): RawSource;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export function uploadedDocumentSource(input) {
|
|
2
|
+
return rawSource("uploaded-document", input);
|
|
3
|
+
}
|
|
4
|
+
export function apiRecordSource(input) {
|
|
5
|
+
return rawSource("api-record", {
|
|
6
|
+
locatorScheme: "structured-field",
|
|
7
|
+
...input,
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
export function webPageSource(input) {
|
|
11
|
+
return rawSource("web-page", {
|
|
12
|
+
locatorScheme: "html",
|
|
13
|
+
...input,
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
export function manualEntrySource(input) {
|
|
17
|
+
return rawSource("manual-entry", {
|
|
18
|
+
locatorScheme: "structured-field",
|
|
19
|
+
...input,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
function rawSource(kind, input) {
|
|
23
|
+
return {
|
|
24
|
+
id: input.id ?? sourceId(kind, input.sourceRef),
|
|
25
|
+
kind,
|
|
26
|
+
sourceRef: input.sourceRef,
|
|
27
|
+
observedAt: input.observedAt,
|
|
28
|
+
fetchedAt: input.fetchedAt,
|
|
29
|
+
checksum: normalizeChecksum(input.checksum),
|
|
30
|
+
locatorScheme: input.locatorScheme,
|
|
31
|
+
metadata: input.metadata,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function sourceId(kind, sourceRef) {
|
|
35
|
+
return `${kind}:${sourceRef}`;
|
|
36
|
+
}
|
|
37
|
+
function normalizeChecksum(checksum) {
|
|
38
|
+
if (!checksum)
|
|
39
|
+
return undefined;
|
|
40
|
+
if (typeof checksum === "string") {
|
|
41
|
+
if (checksum.includes(":"))
|
|
42
|
+
return checksum;
|
|
43
|
+
return `sha256:${checksum}`;
|
|
44
|
+
}
|
|
45
|
+
if (checksum.value.includes(":"))
|
|
46
|
+
return checksum.value;
|
|
47
|
+
return `${checksum.algorithm ?? "sha256"}:${checksum.value}`;
|
|
48
|
+
}
|
package/dist/src/to-surface.js
CHANGED
|
@@ -30,6 +30,8 @@ export function buildSurveyTrustInput(input) {
|
|
|
30
30
|
createdAt,
|
|
31
31
|
updatedAt,
|
|
32
32
|
impactLevel: projection.impactLevel,
|
|
33
|
+
derivedFrom: projection.derivedFrom,
|
|
34
|
+
derivationEdges: projection.derivationEdges,
|
|
33
35
|
confidenceBasis: {
|
|
34
36
|
sourceQuality: "moderate",
|
|
35
37
|
extractionConfidence: candidate.confidence ?? extraction.confidence,
|
|
@@ -82,9 +84,6 @@ export function buildSurveyTrustInput(input) {
|
|
|
82
84
|
notes: review?.rationale ?? candidateSet.rationale,
|
|
83
85
|
});
|
|
84
86
|
}
|
|
85
|
-
for (const derived of input.derivedClaims ?? []) {
|
|
86
|
-
addDerivedClaim({ derived, claims, evidence, events });
|
|
87
|
-
}
|
|
88
87
|
return {
|
|
89
88
|
schemaVersion: 3,
|
|
90
89
|
source: input.source,
|
|
@@ -94,50 +93,6 @@ export function buildSurveyTrustInput(input) {
|
|
|
94
93
|
events,
|
|
95
94
|
};
|
|
96
95
|
}
|
|
97
|
-
function addDerivedClaim(input) {
|
|
98
|
-
const { derived } = input;
|
|
99
|
-
input.claims.push({
|
|
100
|
-
id: derived.id,
|
|
101
|
-
subjectType: derived.subjectType,
|
|
102
|
-
subjectId: derived.subjectId,
|
|
103
|
-
surface: derived.surface,
|
|
104
|
-
claimType: derived.claimType,
|
|
105
|
-
fieldOrBehavior: derived.fieldOrBehavior,
|
|
106
|
-
value: derived.value,
|
|
107
|
-
status: derived.status,
|
|
108
|
-
createdAt: derived.createdAt,
|
|
109
|
-
updatedAt: derived.updatedAt,
|
|
110
|
-
impactLevel: derived.impactLevel,
|
|
111
|
-
derivationEdges: derived.inputClaimIds.map((edge) => ({
|
|
112
|
-
inputClaimId: edge.claimId,
|
|
113
|
-
method: "rule-application",
|
|
114
|
-
role: edge.role,
|
|
115
|
-
supportStrength: edge.supportStrength,
|
|
116
|
-
})),
|
|
117
|
-
metadata: derived.metadata,
|
|
118
|
-
});
|
|
119
|
-
const evidenceId = `${derived.id}.evidence.calculation`;
|
|
120
|
-
input.evidence.push({
|
|
121
|
-
id: evidenceId,
|
|
122
|
-
claimId: derived.id,
|
|
123
|
-
evidenceType: "calculation_trace",
|
|
124
|
-
method: "validation",
|
|
125
|
-
sourceRef: derived.sourceRef,
|
|
126
|
-
excerptOrSummary: derived.evidenceSummary,
|
|
127
|
-
observedAt: derived.updatedAt,
|
|
128
|
-
collectedBy: derived.collectedBy,
|
|
129
|
-
});
|
|
130
|
-
input.events.push({
|
|
131
|
-
id: `${derived.id}.event.${derived.status}`,
|
|
132
|
-
claimId: derived.id,
|
|
133
|
-
status: derived.status,
|
|
134
|
-
actor: derived.collectedBy,
|
|
135
|
-
method: "rule-application",
|
|
136
|
-
evidenceIds: [evidenceId],
|
|
137
|
-
createdAt: derived.updatedAt,
|
|
138
|
-
verifiedAt: derived.status === "verified" ? derived.updatedAt : undefined,
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
96
|
function statusFor(input) {
|
|
142
97
|
if (input.review)
|
|
143
98
|
return input.review.status;
|
package/dist/src/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ConfidenceBasis, EvidenceMethod, EvidenceType, ImpactLevel, TrustStatus } from "@kontourai/surface";
|
|
1
|
+
import type { ConfidenceBasis, DerivationEdge, EvidenceMethod, EvidenceType, ImpactLevel, TrustStatus } from "@kontourai/surface";
|
|
2
2
|
export type RawSourceKind = "uploaded-document" | "web-page" | "api-record" | "manual-entry";
|
|
3
3
|
export type LocatorScheme = "pdf" | "text" | "html" | "structured-field";
|
|
4
4
|
export interface RawSource {
|
|
@@ -70,33 +70,13 @@ export interface ClaimTarget {
|
|
|
70
70
|
evidenceType?: EvidenceType;
|
|
71
71
|
evidenceMethod?: EvidenceMethod;
|
|
72
72
|
confidenceBasis?: ConfidenceBasis;
|
|
73
|
+
derivedFrom?: string[];
|
|
74
|
+
derivationEdges?: DerivationEdge[];
|
|
73
75
|
collectedBy: string;
|
|
74
76
|
actor?: string;
|
|
75
77
|
eventMethod?: string;
|
|
76
78
|
metadata?: Record<string, unknown>;
|
|
77
79
|
}
|
|
78
|
-
export interface DerivedClaimTarget {
|
|
79
|
-
id: string;
|
|
80
|
-
subjectType: string;
|
|
81
|
-
subjectId: string;
|
|
82
|
-
surface: string;
|
|
83
|
-
claimType: string;
|
|
84
|
-
fieldOrBehavior: string;
|
|
85
|
-
value: unknown;
|
|
86
|
-
status: TrustStatus;
|
|
87
|
-
impactLevel: ImpactLevel;
|
|
88
|
-
inputClaimIds: Array<{
|
|
89
|
-
claimId: string;
|
|
90
|
-
role?: string;
|
|
91
|
-
supportStrength?: "weak" | "moderate" | "strong";
|
|
92
|
-
}>;
|
|
93
|
-
createdAt: string;
|
|
94
|
-
updatedAt: string;
|
|
95
|
-
evidenceSummary: string;
|
|
96
|
-
sourceRef: string;
|
|
97
|
-
collectedBy: string;
|
|
98
|
-
metadata?: Record<string, unknown>;
|
|
99
|
-
}
|
|
100
80
|
export interface SurveyInput {
|
|
101
81
|
source: string;
|
|
102
82
|
generatedAt: string;
|
|
@@ -105,5 +85,4 @@ export interface SurveyInput {
|
|
|
105
85
|
candidateSets: CandidateSet[];
|
|
106
86
|
reviewOutcomes: ReviewOutcome[];
|
|
107
87
|
claims: ClaimTarget[];
|
|
108
|
-
derivedClaims?: DerivedClaimTarget[];
|
|
109
88
|
}
|
package/package.json
CHANGED