@kontourai/survey 0.4.1 → 0.4.3
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
CHANGED
|
@@ -185,11 +185,13 @@ assumed.
|
|
|
185
185
|
|
|
186
186
|
## Source-of-authority observations
|
|
187
187
|
|
|
188
|
-
Use `
|
|
189
|
-
authoritative for the extracted target: an official publication,
|
|
190
|
-
platform page, policy document, contract record, or
|
|
191
|
-
The
|
|
192
|
-
|
|
188
|
+
Use `sourceOfAuthorityObservationBuilder` when a producer treats the raw source
|
|
189
|
+
as authoritative for the extracted target: an official publication,
|
|
190
|
+
registration platform page, policy document, contract record, or
|
|
191
|
+
system-of-record response. The builder does not decide whether the source is
|
|
192
|
+
truly authoritative. It guides producers through the source, extraction,
|
|
193
|
+
source-authority posture, review outcome, and claim fields that make the
|
|
194
|
+
declared source posture auditable.
|
|
193
195
|
|
|
194
196
|
Verified or assumed source-of-authority observations require:
|
|
195
197
|
|
|
@@ -207,14 +209,14 @@ reserved for actor, credential, role, organization, policy, or system authority.
|
|
|
207
209
|
```ts
|
|
208
210
|
import {
|
|
209
211
|
buildSurveyTrustInput,
|
|
210
|
-
|
|
212
|
+
sourceOfAuthorityObservationBuilder,
|
|
211
213
|
SurveyInputBuilder,
|
|
212
214
|
uploadedDocumentSource,
|
|
213
215
|
} from "@kontourai/survey";
|
|
214
216
|
|
|
215
217
|
const observedAt = new Date().toISOString();
|
|
216
218
|
const rawSource = uploadedDocumentSource({
|
|
217
|
-
sourceRef: "https://rules.example.test/
|
|
219
|
+
sourceRef: "https://rules.example.test/thresholds.pdf",
|
|
218
220
|
observedAt,
|
|
219
221
|
checksum: "abc123",
|
|
220
222
|
locatorScheme: "pdf",
|
|
@@ -223,35 +225,36 @@ const rawSource = uploadedDocumentSource({
|
|
|
223
225
|
const surveyInput = new SurveyInputBuilder({
|
|
224
226
|
source: "rule-producer:run-1",
|
|
225
227
|
})
|
|
226
|
-
.addObservation(
|
|
227
|
-
id: "rule.
|
|
228
|
-
field: "
|
|
229
|
-
value:
|
|
230
|
-
|
|
228
|
+
.addObservation(sourceOfAuthorityObservationBuilder({
|
|
229
|
+
id: "rule.threshold.primary.2026",
|
|
230
|
+
field: "regulatedRule.threshold.primary.2026",
|
|
231
|
+
value: 1200,
|
|
232
|
+
})
|
|
233
|
+
.withSourceAuthority({
|
|
231
234
|
authorityClass: "official_publication",
|
|
232
235
|
scope: {
|
|
233
|
-
jurisdiction: "
|
|
236
|
+
jurisdiction: "example",
|
|
234
237
|
productArea: "regulated-rule",
|
|
235
|
-
|
|
238
|
+
effectiveYear: 2026,
|
|
236
239
|
},
|
|
237
240
|
sourceVersion: "2026",
|
|
238
241
|
declaredBy: "rule-producer",
|
|
239
|
-
}
|
|
240
|
-
rawSource
|
|
241
|
-
|
|
242
|
+
})
|
|
243
|
+
.fromSource(rawSource)
|
|
244
|
+
.withExtraction({
|
|
242
245
|
confidence: 0.94,
|
|
243
|
-
locator: "pdf:page=12;table=
|
|
246
|
+
locator: "pdf:page=12;table=thresholds;row=primary",
|
|
244
247
|
extractor: "rule-producer",
|
|
245
248
|
extractedAt: observedAt,
|
|
246
|
-
}
|
|
247
|
-
|
|
249
|
+
})
|
|
250
|
+
.withReviewOutcome({
|
|
248
251
|
status: "verified",
|
|
249
252
|
actor: "rule-reviewer",
|
|
250
253
|
reviewedAt: new Date().toISOString(),
|
|
251
|
-
}
|
|
252
|
-
|
|
254
|
+
})
|
|
255
|
+
.forClaim({
|
|
253
256
|
subjectType: "regulated-rule",
|
|
254
|
-
subjectId: "
|
|
257
|
+
subjectId: "example:threshold:primary:2026",
|
|
255
258
|
surface: "regulated.rules",
|
|
256
259
|
claimType: "regulated.rule-value",
|
|
257
260
|
status: "verified",
|
|
@@ -259,18 +262,25 @@ const surveyInput = new SurveyInputBuilder({
|
|
|
259
262
|
evidenceType: "policy_rule",
|
|
260
263
|
evidenceMethod: "extraction",
|
|
261
264
|
collectedBy: "rule-producer",
|
|
262
|
-
}
|
|
263
|
-
|
|
265
|
+
})
|
|
266
|
+
.build())
|
|
264
267
|
.build();
|
|
265
268
|
|
|
266
269
|
const trustInput = buildSurveyTrustInput(surveyInput);
|
|
267
270
|
```
|
|
268
271
|
|
|
269
|
-
|
|
270
|
-
|
|
272
|
+
`sourceOfAuthorityObservation` remains available as the lower-level object
|
|
273
|
+
factory when a producer already has the full observation input assembled.
|
|
274
|
+
|
|
275
|
+
Contextual claims such as "this submission is compliant" or "this listing is
|
|
276
|
+
eligible for a specific requester" are not source-of-authority observations.
|
|
271
277
|
They are Surface claims with Claim Dependencies on source-of-authority claims
|
|
272
278
|
and other product facts. The vertical product owns that domain logic.
|
|
273
279
|
|
|
280
|
+
For the reusable producer workflow, including manual confirmation state,
|
|
281
|
+
source references, Survey review outcomes, and Surface report boundaries, see
|
|
282
|
+
[Source-Authority Review Pattern](docs/source-authority-review-pattern.md).
|
|
283
|
+
|
|
274
284
|
## Reviewed candidate resolutions
|
|
275
285
|
|
|
276
286
|
Use `reviewedCandidateResolution` when a producer has multiple candidate
|
package/dist/src/index.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export { fieldObservation } from "./field-observation.js";
|
|
|
13
13
|
export type { FieldObservationInput } from "./field-observation.js";
|
|
14
14
|
export { repeatedObservation } from "./repeated-observation.js";
|
|
15
15
|
export type { RepeatedObservationInput } from "./repeated-observation.js";
|
|
16
|
-
export { sourceOfAuthorityObservation } from "./source-of-authority-observation.js";
|
|
17
|
-
export type { SourceAuthorityClass, SourceAuthorityMetadata, SourceOfAuthorityObservationInput, } from "./source-of-authority-observation.js";
|
|
16
|
+
export { sourceOfAuthorityObservation, sourceOfAuthorityObservationBuilder, SourceOfAuthorityObservationBuilder, } from "./source-of-authority-observation.js";
|
|
17
|
+
export type { SourceAuthorityClass, SourceAuthorityMetadata, SourceOfAuthorityObservationBuilderArgs, SourceOfAuthorityObservationInput, } from "./source-of-authority-observation.js";
|
|
18
18
|
export { apiRecordSource, manualEntrySource, uploadedDocumentSource, webPageSource, } from "./raw-source.js";
|
|
19
19
|
export type { ApiRecordSourceInput, ChecksumInput, ManualEntrySourceInput, RawSourceInput, UploadedDocumentSourceInput, WebPageSourceInput, } from "./raw-source.js";
|
package/dist/src/index.js
CHANGED
|
@@ -5,5 +5,5 @@ export { buildSurveyTrustInput } from "./to-surface.js";
|
|
|
5
5
|
export { buildCanonicalReviewProofPayload, buildReviewProofAnchor, canonicalReviewProofJson, hashCanonicalReviewProofPayload, } from "./review-proof.js";
|
|
6
6
|
export { fieldObservation } from "./field-observation.js";
|
|
7
7
|
export { repeatedObservation } from "./repeated-observation.js";
|
|
8
|
-
export { sourceOfAuthorityObservation } from "./source-of-authority-observation.js";
|
|
8
|
+
export { sourceOfAuthorityObservation, sourceOfAuthorityObservationBuilder, SourceOfAuthorityObservationBuilder, } from "./source-of-authority-observation.js";
|
|
9
9
|
export { apiRecordSource, manualEntrySource, uploadedDocumentSource, webPageSource, } from "./raw-source.js";
|
|
@@ -28,4 +28,24 @@ export interface SourceOfAuthorityObservationInput<TValue> {
|
|
|
28
28
|
candidateSet?: SurveyObservationInput["candidateSet"];
|
|
29
29
|
metadata?: Record<string, unknown>;
|
|
30
30
|
}
|
|
31
|
+
export interface SourceOfAuthorityObservationBuilderArgs<TValue> {
|
|
32
|
+
id: string;
|
|
33
|
+
field: string;
|
|
34
|
+
value: TValue;
|
|
35
|
+
}
|
|
36
|
+
export declare class SourceOfAuthorityObservationBuilder<TValue> {
|
|
37
|
+
private readonly state;
|
|
38
|
+
constructor(args: SourceOfAuthorityObservationBuilderArgs<TValue>);
|
|
39
|
+
static create<TValue>(args: SourceOfAuthorityObservationBuilderArgs<TValue>): SourceOfAuthorityObservationBuilder<TValue>;
|
|
40
|
+
withSourceAuthority(sourceAuthority: SourceAuthorityMetadata): this;
|
|
41
|
+
fromSource(rawSource: SourceOfAuthorityObservationInput<TValue>["rawSource"]): this;
|
|
42
|
+
withExtraction(extraction: SourceOfAuthorityObservationInput<TValue>["extraction"]): this;
|
|
43
|
+
withReviewOutcome(reviewOutcome: SourceOfAuthorityObservationInput<TValue>["reviewOutcome"]): this;
|
|
44
|
+
forClaim(claim: SourceOfAuthorityObservationInput<TValue>["claim"]): this;
|
|
45
|
+
withCandidate(candidate: SourceOfAuthorityObservationInput<TValue>["candidate"]): this;
|
|
46
|
+
withCandidateSet(candidateSet: SourceOfAuthorityObservationInput<TValue>["candidateSet"]): this;
|
|
47
|
+
withMetadata(metadata: Record<string, unknown>): this;
|
|
48
|
+
build(): SurveyObservationInput;
|
|
49
|
+
}
|
|
50
|
+
export declare function sourceOfAuthorityObservationBuilder<TValue>(args: SourceOfAuthorityObservationBuilderArgs<TValue>): SourceOfAuthorityObservationBuilder<TValue>;
|
|
31
51
|
export declare function sourceOfAuthorityObservation<TValue>(input: SourceOfAuthorityObservationInput<TValue>): SurveyObservationInput;
|
|
@@ -1,4 +1,51 @@
|
|
|
1
1
|
import { buildObservation } from "./observation-helper.js";
|
|
2
|
+
export class SourceOfAuthorityObservationBuilder {
|
|
3
|
+
state;
|
|
4
|
+
constructor(args) {
|
|
5
|
+
this.state = { ...args };
|
|
6
|
+
}
|
|
7
|
+
static create(args) {
|
|
8
|
+
return new SourceOfAuthorityObservationBuilder(args);
|
|
9
|
+
}
|
|
10
|
+
withSourceAuthority(sourceAuthority) {
|
|
11
|
+
this.state.sourceAuthority = sourceAuthority;
|
|
12
|
+
return this;
|
|
13
|
+
}
|
|
14
|
+
fromSource(rawSource) {
|
|
15
|
+
this.state.rawSource = rawSource;
|
|
16
|
+
return this;
|
|
17
|
+
}
|
|
18
|
+
withExtraction(extraction) {
|
|
19
|
+
this.state.extraction = extraction;
|
|
20
|
+
return this;
|
|
21
|
+
}
|
|
22
|
+
withReviewOutcome(reviewOutcome) {
|
|
23
|
+
this.state.reviewOutcome = reviewOutcome;
|
|
24
|
+
return this;
|
|
25
|
+
}
|
|
26
|
+
forClaim(claim) {
|
|
27
|
+
this.state.claim = claim;
|
|
28
|
+
return this;
|
|
29
|
+
}
|
|
30
|
+
withCandidate(candidate) {
|
|
31
|
+
this.state.candidate = candidate;
|
|
32
|
+
return this;
|
|
33
|
+
}
|
|
34
|
+
withCandidateSet(candidateSet) {
|
|
35
|
+
this.state.candidateSet = candidateSet;
|
|
36
|
+
return this;
|
|
37
|
+
}
|
|
38
|
+
withMetadata(metadata) {
|
|
39
|
+
this.state.metadata = metadata;
|
|
40
|
+
return this;
|
|
41
|
+
}
|
|
42
|
+
build() {
|
|
43
|
+
return sourceOfAuthorityObservation(completeBuilderState(this.state));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
export function sourceOfAuthorityObservationBuilder(args) {
|
|
47
|
+
return SourceOfAuthorityObservationBuilder.create(args);
|
|
48
|
+
}
|
|
2
49
|
export function sourceOfAuthorityObservation(input) {
|
|
3
50
|
assertSourceAuthority(input.sourceAuthority, input.id);
|
|
4
51
|
assertVerifiedPosture(input);
|
|
@@ -26,6 +73,27 @@ export function sourceOfAuthorityObservation(input) {
|
|
|
26
73
|
defaultExcerpt: `${input.field}: ${valueSummary(input.value)}`,
|
|
27
74
|
});
|
|
28
75
|
}
|
|
76
|
+
function completeBuilderState(state) {
|
|
77
|
+
return {
|
|
78
|
+
id: state.id,
|
|
79
|
+
field: state.field,
|
|
80
|
+
value: state.value,
|
|
81
|
+
sourceAuthority: requireBuilderField(state.sourceAuthority, state.id, "sourceAuthority"),
|
|
82
|
+
rawSource: requireBuilderField(state.rawSource, state.id, "rawSource"),
|
|
83
|
+
extraction: requireBuilderField(state.extraction, state.id, "extraction"),
|
|
84
|
+
reviewOutcome: state.reviewOutcome,
|
|
85
|
+
claim: requireBuilderField(state.claim, state.id, "claim"),
|
|
86
|
+
candidate: state.candidate,
|
|
87
|
+
candidateSet: state.candidateSet,
|
|
88
|
+
metadata: state.metadata,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function requireBuilderField(value, observationId, field) {
|
|
92
|
+
if (value === undefined) {
|
|
93
|
+
throw new Error(`Source-of-authority observation ${observationId} builder needs ${field}`);
|
|
94
|
+
}
|
|
95
|
+
return value;
|
|
96
|
+
}
|
|
29
97
|
function assertSourceAuthority(sourceAuthority, observationId) {
|
|
30
98
|
if (!sourceAuthority.authorityClass) {
|
|
31
99
|
throw new Error(`Source-of-authority observation ${observationId} needs sourceAuthority.authorityClass`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kontourai/survey",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.3",
|
|
4
4
|
"description": "Producer-side source, extraction, candidate, and review contracts for projecting verified claims into Surface.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"check:content-boundary": "node scripts/check-content-boundary.cjs"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@kontourai/surface": "
|
|
38
|
+
"@kontourai/surface": "^0.5.1"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@types/node": "^25.6.0",
|