@kontourai/survey 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -79,7 +79,7 @@ const surveyInput = new SurveyInputBuilder({
79
79
  claim: {
80
80
  subjectType: "public-record.entity",
81
81
  subjectId: "listing-123",
82
- surface: "public-record.profile",
82
+ facet: "public-record.profile",
83
83
  claimType: "public-data.field",
84
84
  fieldOrBehavior: "availabilityStatus",
85
85
  impactLevel: "medium",
@@ -143,7 +143,7 @@ function documentClaim(id, target, candidateId, fieldOrBehavior, status) {
143
143
  candidateId: `document:candidate:${candidateId}`,
144
144
  subjectType: "verified-record.period",
145
145
  subjectId: "entity-1:2026",
146
- surface: "document-review",
146
+ facet: "document-review",
147
147
  claimType: "source-field",
148
148
  fieldOrBehavior,
149
149
  status,
@@ -159,7 +159,7 @@ function computationClaim(id, status, inputClaimIds) {
159
159
  candidateId: `document:candidate:statement-position:${id}`,
160
160
  subjectType: "verified-record.period",
161
161
  subjectId: "entity-1:2026",
162
- surface: "document-review",
162
+ facet: "document-review",
163
163
  claimType: "computed-field",
164
164
  fieldOrBehavior: "statementPosition",
165
165
  status,
@@ -45,7 +45,7 @@ export declare const publicDirectoryReviewItemExample: {
45
45
  claimId: string;
46
46
  subjectType: string;
47
47
  subjectId: string;
48
- surface: string;
48
+ facet: string;
49
49
  claimType: string;
50
50
  fieldOrBehavior: string;
51
51
  impactLevel: "medium";
@@ -97,7 +97,7 @@ export declare const publicDirectoryReviewItemExample: {
97
97
  claimId: string;
98
98
  subjectType: string;
99
99
  subjectId: string;
100
- surface: string;
100
+ facet: string;
101
101
  claimType: string;
102
102
  fieldOrBehavior: string;
103
103
  impactLevel: "medium";
@@ -47,7 +47,7 @@ export const publicDirectoryReviewItemExample = {
47
47
  claimId: "public-field.entity-123.availability-status.current",
48
48
  subjectType: "public-record.entity",
49
49
  subjectId: "entity-123",
50
- surface: "public-record.profile",
50
+ facet: "public-record.profile",
51
51
  claimType: "public-data.field",
52
52
  fieldOrBehavior: "availabilityStatus",
53
53
  impactLevel: "medium",
@@ -98,7 +98,7 @@ export const publicDirectoryReviewItemExample = {
98
98
  claimId: "public-field.entity-123.availability-status.proposal-456",
99
99
  subjectType: "public-record.entity",
100
100
  subjectId: "entity-123",
101
- surface: "public-record.profile",
101
+ facet: "public-record.profile",
102
102
  claimType: "public-data.field-candidate",
103
103
  fieldOrBehavior: "availabilityStatus",
104
104
  impactLevel: "medium",
@@ -91,7 +91,7 @@ export const publicFieldReviewExample = {
91
91
  candidateId: "public-field:candidate:approved",
92
92
  subjectType: "public-record.entity",
93
93
  subjectId: "entity-123",
94
- surface: "public-record.profile",
94
+ facet: "public-record.profile",
95
95
  claimType: "public-data.field",
96
96
  fieldOrBehavior: "availabilityStatus",
97
97
  impactLevel: "medium",
@@ -109,7 +109,7 @@ export const publicFieldReviewExample = {
109
109
  candidateId: "public-field:candidate:proposal",
110
110
  subjectType: "public-record.entity",
111
111
  subjectId: "entity-123",
112
- surface: "public-record.profile",
112
+ facet: "public-record.profile",
113
113
  claimType: "public-data.field-candidate",
114
114
  fieldOrBehavior: "availabilityStatus",
115
115
  impactLevel: "medium",
@@ -48,7 +48,7 @@ export declare const regulatedDocumentReviewItemExample: {
48
48
  claimId: string;
49
49
  subjectType: string;
50
50
  subjectId: string;
51
- surface: string;
51
+ facet: string;
52
52
  claimType: string;
53
53
  fieldOrBehavior: string;
54
54
  impactLevel: "high";
@@ -96,7 +96,7 @@ export declare const regulatedDocumentReviewItemExample: {
96
96
  claimId: string;
97
97
  subjectType: string;
98
98
  subjectId: string;
99
- surface: string;
99
+ facet: string;
100
100
  claimType: string;
101
101
  fieldOrBehavior: string;
102
102
  impactLevel: "high";
@@ -50,7 +50,7 @@ export const regulatedDocumentReviewItemExample = {
50
50
  claimId: "document.entity-1.statement-position.original",
51
51
  subjectType: "verified-record.period",
52
52
  subjectId: "entity-1:2026",
53
- surface: "document-review",
53
+ facet: "document-review",
54
54
  claimType: "computed-field",
55
55
  fieldOrBehavior: "statementPosition",
56
56
  impactLevel: "high",
@@ -102,7 +102,7 @@ export const regulatedDocumentReviewItemExample = {
102
102
  claimId: "document.entity-1.statement-position.current",
103
103
  subjectType: "verified-record.period",
104
104
  subjectId: "entity-1:2026",
105
- surface: "document-review",
105
+ facet: "document-review",
106
106
  claimType: "computed-field",
107
107
  fieldOrBehavior: "statementPosition",
108
108
  impactLevel: "high",
@@ -30,7 +30,7 @@ const surveyInput = new SurveyInputBuilder({
30
30
  claim: {
31
31
  subjectType: "public-record.entity",
32
32
  subjectId: "entity-1",
33
- surface: "public-record.profile",
33
+ facet: "public-record.profile",
34
34
  claimType: "public-data.field",
35
35
  fieldOrBehavior: "availabilityStatus",
36
36
  impactLevel: "medium",
@@ -201,7 +201,7 @@ function candidateClaimTarget(args, claimId) {
201
201
  claimId,
202
202
  subjectType: "public-record.entity",
203
203
  subjectId: args.proposal.publicRecordId,
204
- surface: "public-directory.profile",
204
+ facet: "public-directory.profile",
205
205
  claimType: args.role === "current" ? "public-data.field" : "public-data.field-candidate",
206
206
  fieldOrBehavior: args.field,
207
207
  impactLevel: "medium",
@@ -129,7 +129,7 @@ export function utteranceToSurveyInput(utterance, extracted, context) {
129
129
  candidateId,
130
130
  subjectType: statement.target.subjectType,
131
131
  subjectId: statement.target.subjectId,
132
- surface: "agent-utterance.profile",
132
+ facet: "agent-utterance.profile",
133
133
  claimType: "agent-extraction",
134
134
  fieldOrBehavior: statement.target.fieldOrBehavior,
135
135
  value: statement.value,
@@ -33,7 +33,7 @@ export type { MappingProposalRecord, ReviewedMapping, SchemaMappingExtractor, Sc
33
33
  export { buildAuthorizedActionAuthorizing, buildPromptRef, isValidAuthorizing, validateAuthorizing } from "./review-authorizing.js";
34
34
  export type { BuildAuthorizedActionAuthorizingInput, BuildPromptRefInput, ReviewAuthorizingIssue, ReviewAuthorizingIssueCode, } from "./review-authorizing.js";
35
35
  export { confidenceBasisForReview, defineProductVocabulary, stableId } from "./vocabulary.js";
36
- export type { ConfidenceBasisForReviewInput, ProductVocabularyDefinition, } from "./vocabulary.js";
36
+ export type { ConfidenceBasisForReviewInput, ProductVocabularyDefinition, ProductVocabularyInput, } from "./vocabulary.js";
37
37
  export { currentProposedReviewItem } from "./current-proposed-review-item.js";
38
38
  export type { CurrentProposedCandidateInput, CurrentProposedReviewItemInput, } from "./current-proposed-review-item.js";
39
39
  export { deriveOversightMetrics, mergeTrustBundleWithOversightMetrics, oversightMetricsToClaims, } from "./oversight-metrics.js";
@@ -226,7 +226,7 @@ export declare function buildMappingReviewItems(candidateSets: Array<{
226
226
  claimTarget: {
227
227
  subjectType: string;
228
228
  subjectId: string;
229
- surface: string;
229
+ facet: string;
230
230
  claimType: string;
231
231
  fieldOrBehavior: string;
232
232
  impactLevel: "low";
@@ -299,7 +299,7 @@ export function buildMappingReviewItems(candidateSets) {
299
299
  claimTarget: {
300
300
  subjectType: meta?.proposedTarget?.subjectType ?? "inquiry",
301
301
  subjectId: meta?.proposedTarget?.subjectId ?? candidateSet.target,
302
- surface: "inquiry.mapping",
302
+ facet: "inquiry.mapping",
303
303
  claimType: "inquiry-mapping",
304
304
  fieldOrBehavior: meta?.proposedTarget?.fieldOrBehavior ?? meta?.proposedRuleId ?? "unknown",
305
305
  impactLevel: "low",
@@ -113,8 +113,8 @@ export interface OversightMetricsClaimsSubject {
113
113
  readonly subjectType: string;
114
114
  /** Surface subject id (e.g. a session name or actor id). */
115
115
  readonly subjectId: string;
116
- /** Surface name (e.g. "review.oversight"). */
117
- readonly surface: string;
116
+ /** Surface facet (e.g. "review.oversight"). */
117
+ readonly facet: string;
118
118
  /** Actor id to record on events. */
119
119
  readonly actor: string;
120
120
  /** ISO 8601 timestamp for claim created/updated times. */
@@ -217,7 +217,7 @@ export function oversightMetricsToClaims(metrics, subject) {
217
217
  id: claimId,
218
218
  subjectType: subject.subjectType,
219
219
  subjectId: subject.subjectId,
220
- surface: subject.surface,
220
+ facet: subject.facet,
221
221
  claimType: "oversight-quality",
222
222
  fieldOrBehavior,
223
223
  value,
@@ -31,7 +31,7 @@ export interface CanonicalReviewProofPayload {
31
31
  candidateId?: string;
32
32
  subjectType: string;
33
33
  subjectId: string;
34
- surface: string;
34
+ facet: string;
35
35
  claimType: string;
36
36
  fieldOrBehavior: string;
37
37
  };
@@ -92,7 +92,7 @@ export interface CanonicalReviewProofPayload {
92
92
  candidateId?: string;
93
93
  subjectType: string;
94
94
  subjectId: string;
95
- surface: string;
95
+ facet: string;
96
96
  claimType: string;
97
97
  fieldOrBehavior: string;
98
98
  value?: unknown;
@@ -23,7 +23,7 @@ export function buildCanonicalReviewProofPayload(input) {
23
23
  candidateId: input.candidate.id,
24
24
  subjectType: input.claim.subjectType,
25
25
  subjectId: input.claim.subjectId,
26
- surface: input.claim.surface,
26
+ facet: input.claim.facet,
27
27
  claimType: input.claim.claimType,
28
28
  fieldOrBehavior: input.claim.fieldOrBehavior,
29
29
  },
@@ -86,7 +86,7 @@ export function buildCanonicalReviewProofPayload(input) {
86
86
  candidateId: input.claim.candidateId,
87
87
  subjectType: input.claim.subjectType,
88
88
  subjectId: input.claim.subjectId,
89
- surface: input.claim.surface,
89
+ facet: input.claim.facet,
90
90
  claimType: input.claim.claimType,
91
91
  fieldOrBehavior: input.claim.fieldOrBehavior,
92
92
  value: input.claim.value,
@@ -42,7 +42,11 @@ export interface ClaimTargetHint {
42
42
  claimId?: string;
43
43
  subjectType: string;
44
44
  subjectId: string;
45
- surface: string;
45
+ /**
46
+ * Producer-defined grouping or namespace for this claim (Hachure schema 5,
47
+ * surface@2.0.0: Claim.surface -> Claim.facet).
48
+ */
49
+ facet: string;
46
50
  claimType: string;
47
51
  fieldOrBehavior: string;
48
52
  impactLevel: ClaimTarget["impactLevel"];
@@ -46,7 +46,7 @@ export declare const publicDirectoryReviewItemExample: {
46
46
  claimId: string;
47
47
  subjectType: string;
48
48
  subjectId: string;
49
- surface: string;
49
+ facet: string;
50
50
  claimType: string;
51
51
  fieldOrBehavior: string;
52
52
  impactLevel: "medium";
@@ -98,7 +98,7 @@ export declare const publicDirectoryReviewItemExample: {
98
98
  claimId: string;
99
99
  subjectType: string;
100
100
  subjectId: string;
101
- surface: string;
101
+ facet: string;
102
102
  claimType: string;
103
103
  fieldOrBehavior: string;
104
104
  impactLevel: "medium";
@@ -184,7 +184,7 @@ export declare const regulatedRuleConflictReviewItemExample: {
184
184
  claimId: string;
185
185
  subjectType: string;
186
186
  subjectId: string;
187
- surface: string;
187
+ facet: string;
188
188
  claimType: string;
189
189
  fieldOrBehavior: string;
190
190
  impactLevel: "high";
@@ -235,7 +235,7 @@ export declare const regulatedRuleConflictReviewItemExample: {
235
235
  claimId: string;
236
236
  subjectType: string;
237
237
  subjectId: string;
238
- surface: string;
238
+ facet: string;
239
239
  claimType: string;
240
240
  fieldOrBehavior: string;
241
241
  impactLevel: "high";
@@ -334,7 +334,7 @@ export declare const facilityCredentialReviewItemExample: {
334
334
  claimId: string;
335
335
  subjectType: string;
336
336
  subjectId: string;
337
- surface: string;
337
+ facet: string;
338
338
  claimType: string;
339
339
  fieldOrBehavior: string;
340
340
  impactLevel: "high";
@@ -395,7 +395,7 @@ export declare const facilityCredentialReviewItemExample: {
395
395
  claimId: string;
396
396
  subjectType: string;
397
397
  subjectId: string;
398
- surface: string;
398
+ facet: string;
399
399
  claimType: string;
400
400
  fieldOrBehavior: string;
401
401
  impactLevel: "high";
@@ -472,7 +472,7 @@ export declare const reviewWorkbenchQueueExamples: (ReviewItem | {
472
472
  claimId: string;
473
473
  subjectType: string;
474
474
  subjectId: string;
475
- surface: string;
475
+ facet: string;
476
476
  claimType: string;
477
477
  fieldOrBehavior: string;
478
478
  impactLevel: "medium";
@@ -524,7 +524,7 @@ export declare const reviewWorkbenchQueueExamples: (ReviewItem | {
524
524
  claimId: string;
525
525
  subjectType: string;
526
526
  subjectId: string;
527
- surface: string;
527
+ facet: string;
528
528
  claimType: string;
529
529
  fieldOrBehavior: string;
530
530
  impactLevel: "medium";
@@ -609,7 +609,7 @@ export declare const reviewWorkbenchQueueExamples: (ReviewItem | {
609
609
  claimId: string;
610
610
  subjectType: string;
611
611
  subjectId: string;
612
- surface: string;
612
+ facet: string;
613
613
  claimType: string;
614
614
  fieldOrBehavior: string;
615
615
  impactLevel: "high";
@@ -660,7 +660,7 @@ export declare const reviewWorkbenchQueueExamples: (ReviewItem | {
660
660
  claimId: string;
661
661
  subjectType: string;
662
662
  subjectId: string;
663
- surface: string;
663
+ facet: string;
664
664
  claimType: string;
665
665
  fieldOrBehavior: string;
666
666
  impactLevel: "high";
@@ -49,7 +49,7 @@ export const publicDirectoryReviewItemExample = {
49
49
  claimId: "public-field.entity-123.availability-status.current",
50
50
  subjectType: "public-record.entity",
51
51
  subjectId: "entity-123",
52
- surface: "public-record.profile",
52
+ facet: "public-record.profile",
53
53
  claimType: "public-data.field",
54
54
  fieldOrBehavior: "availabilityStatus",
55
55
  impactLevel: "medium",
@@ -100,7 +100,7 @@ export const publicDirectoryReviewItemExample = {
100
100
  claimId: "public-field.entity-123.availability-status.proposal-456",
101
101
  subjectType: "public-record.entity",
102
102
  subjectId: "entity-123",
103
- surface: "public-record.profile",
103
+ facet: "public-record.profile",
104
104
  claimType: "public-data.field-candidate",
105
105
  fieldOrBehavior: "availabilityStatus",
106
106
  impactLevel: "medium",
@@ -187,7 +187,7 @@ export const regulatedRuleConflictReviewItemExample = {
187
187
  claimId: "regulated-rule.example-jurisdiction.2026.standard-threshold.current",
188
188
  subjectType: "regulated-rule-source",
189
189
  subjectId: "example-jurisdiction:2026:standardThreshold",
190
- surface: "regulated.rules",
190
+ facet: "regulated.rules",
191
191
  claimType: "regulated.rule-source-value",
192
192
  fieldOrBehavior: "standardThreshold",
193
193
  impactLevel: "high",
@@ -235,7 +235,7 @@ export const regulatedRuleConflictReviewItemExample = {
235
235
  claimId: "regulated-rule.example-jurisdiction.2026.standard-threshold.proposed",
236
236
  subjectType: "regulated-rule-source",
237
237
  subjectId: "example-jurisdiction:2026:standardThreshold",
238
- surface: "regulated.rules",
238
+ facet: "regulated.rules",
239
239
  claimType: "regulated.rule-source-value",
240
240
  fieldOrBehavior: "standardThreshold",
241
241
  impactLevel: "high",
@@ -332,7 +332,7 @@ export const facilityCredentialReviewItemExample = {
332
332
  claimId: "facility-credential.facility-42.operating-license.current",
333
333
  subjectType: "facility",
334
334
  subjectId: "facility-42",
335
- surface: "facility.credential-profile",
335
+ facet: "facility.credential-profile",
336
336
  claimType: "facility.credential",
337
337
  fieldOrBehavior: "operatingLicenseCredential",
338
338
  impactLevel: "high",
@@ -391,7 +391,7 @@ export const facilityCredentialReviewItemExample = {
391
391
  claimId: "facility-credential.facility-42.operating-license.registry",
392
392
  subjectType: "facility",
393
393
  subjectId: "facility-42",
394
- surface: "facility.credential-profile",
394
+ facet: "facility.credential-profile",
395
395
  claimType: "facility.credential-candidate",
396
396
  fieldOrBehavior: "operatingLicenseCredential",
397
397
  impactLevel: "high",
@@ -1308,7 +1308,7 @@ function isReviewCandidate(value) {
1308
1308
  && isRecord(value.claimTarget)
1309
1309
  && typeof value.claimTarget.subjectType === "string"
1310
1310
  && typeof value.claimTarget.subjectId === "string"
1311
- && typeof value.claimTarget.surface === "string"
1311
+ && typeof value.claimTarget.facet === "string"
1312
1312
  && typeof value.claimTarget.claimType === "string"
1313
1313
  && typeof value.claimTarget.fieldOrBehavior === "string"
1314
1314
  && typeof value.claimTarget.impactLevel === "string";
@@ -198,7 +198,7 @@ export async function surveySchemaMapping(context, extractor, options = {}) {
198
198
  candidateId: selectedCandidate.id,
199
199
  subjectType: "system-field",
200
200
  subjectId: subjectId,
201
- surface: "schema-mapping.profile",
201
+ facet: "schema-mapping.profile",
202
202
  claimType: "schema-mapping.field-link",
203
203
  fieldOrBehavior: "maps-to",
204
204
  value: {
@@ -342,7 +342,7 @@ export function mappingReviewToSurface(reviewedMappings, options = {}) {
342
342
  candidateId: rm.selectedCandidate.id,
343
343
  subjectType: "system-field",
344
344
  subjectId,
345
- surface: "schema-mapping.profile",
345
+ facet: "schema-mapping.profile",
346
346
  claimType: "schema-mapping.field-link",
347
347
  fieldOrBehavior: "maps-to",
348
348
  value: { relation, sourceField, targetField, conversion },
@@ -23,7 +23,7 @@ export function buildSurveyTrustBundle(input, options = {}) {
23
23
  id: projection.id,
24
24
  subjectType: projection.subjectType,
25
25
  subjectId: projection.subjectId,
26
- surface: projection.surface,
26
+ facet: projection.facet,
27
27
  claimType: projection.claimType,
28
28
  fieldOrBehavior: projection.fieldOrBehavior,
29
29
  value: claimValue,
@@ -120,7 +120,7 @@ export function buildSurveyTrustBundle(input, options = {}) {
120
120
  }
121
121
  }
122
122
  return {
123
- schemaVersion: 3,
123
+ schemaVersion: 5,
124
124
  source: input.source,
125
125
  claims,
126
126
  evidence,
@@ -111,7 +111,12 @@ export interface ClaimTarget {
111
111
  candidateId?: string;
112
112
  subjectType: string;
113
113
  subjectId: string;
114
- surface: string;
114
+ /**
115
+ * Producer-defined grouping or namespace for this claim (Hachure schema 5,
116
+ * surface@2.0.0: Claim.surface -> Claim.facet). Projected onto the emitted
117
+ * Claim's `facet` field by {@link buildSurveyTrustBundle}.
118
+ */
119
+ facet: string;
115
120
  claimType: string;
116
121
  fieldOrBehavior: string;
117
122
  value?: unknown;
@@ -11,22 +11,64 @@ import type { ConfidenceBasis, ImpactLevel, TrustStatus } from "@kontourai/surfa
11
11
  */
12
12
  export declare function stableId(parts: ReadonlyArray<string | number>): string;
13
13
  /**
14
- * A product's Survey/Surface vocabulary: the subject type and surface it
14
+ * A product's Survey/Surface vocabulary: the subject type and facet it
15
15
  * projects onto, its claim-type names, and its decision-effect names. Generic
16
16
  * over the caller's claim-type and decision-effect key maps so the concrete
17
17
  * string literals stay visible to callers.
18
+ *
19
+ * `facet` mirrors Surface's `Claim.facet` (Hachure schema 5 facet rename:
20
+ * `Claim.surface` -> `Claim.facet`, surface@2.0.0). The now-deprecated
21
+ * `surface` property is kept, mirroring `facet`, for one release so existing
22
+ * readers of `.surface` do not break; read `.facet` going forward.
18
23
  */
19
24
  export interface ProductVocabularyDefinition<TClaimTypes extends Readonly<Record<string, string>>, TDecisionEffects extends Readonly<Record<string, string>>> {
20
25
  readonly subjectType: string;
26
+ readonly facet: string;
27
+ /**
28
+ * @deprecated Renamed to {@link ProductVocabularyDefinition.facet} (Hachure
29
+ * schema 5 facet rename: `Claim.surface` -> `Claim.facet`). Mirrors `facet`
30
+ * for one release; read `.facet` going forward.
31
+ */
21
32
  readonly surface: string;
22
33
  readonly claimTypes: TClaimTypes;
23
34
  readonly decisionEffects: TDecisionEffects;
24
35
  }
36
+ /**
37
+ * Input accepted by {@link defineProductVocabulary}: `facet` is the
38
+ * canonical name; the deprecated `surface` name is still accepted for one
39
+ * release as a read-compat alias (Hachure schema 5 facet rename). Exactly
40
+ * one of `facet` / `surface` is required — the union below is what makes
41
+ * "at least one of these two" a compile-time requirement rather than a
42
+ * runtime-only check.
43
+ */
44
+ export type ProductVocabularyInput<TClaimTypes extends Readonly<Record<string, string>>, TDecisionEffects extends Readonly<Record<string, string>>> = {
45
+ readonly subjectType: string;
46
+ readonly claimTypes: TClaimTypes;
47
+ readonly decisionEffects: TDecisionEffects;
48
+ } & ({
49
+ readonly facet: string;
50
+ readonly surface?: string;
51
+ } | {
52
+ readonly facet?: undefined;
53
+ /**
54
+ * @deprecated Renamed to `facet` (Hachure schema 5 facet rename:
55
+ * `Claim.surface` -> `Claim.facet`). Accepted for one release; using it
56
+ * without also passing `facet` emits a single deprecation warning per
57
+ * process. Prefer `facet`.
58
+ */
59
+ readonly surface: string;
60
+ });
25
61
  /**
26
62
  * Defines a product vocabulary as a deep-frozen, discoverable value that a
27
63
  * `currentProposedReviewItem` caller can pass instead of loose top-level
28
- * constants. Returns the same shape it received, frozen so callers cannot
29
- * mutate a shared vocabulary at runtime.
64
+ * constants. Returns the same shape it received (plus the mirrored
65
+ * deprecated `surface` alias — see {@link ProductVocabularyDefinition}),
66
+ * frozen so callers cannot mutate a shared vocabulary at runtime.
67
+ *
68
+ * Accepts either the canonical `facet` option or the deprecated `surface`
69
+ * option (not both required — `facet` wins when both are supplied, and
70
+ * using `surface` alone emits a single deprecation warning per process; see
71
+ * {@link ProductVocabularyInput}).
30
72
  *
31
73
  * The type parameters carry the `const` modifier, so `claimTypes` and
32
74
  * `decisionEffects` string properties keep their literal types whether or
@@ -40,7 +82,7 @@ export interface ProductVocabularyDefinition<TClaimTypes extends Readonly<Record
40
82
  * `peerDependencies.typescript` and `docs/upgrade-guide.md`); this is a
41
83
  * types-only floor and does not affect JavaScript consumers.
42
84
  */
43
- export declare function defineProductVocabulary<const TClaimTypes extends Readonly<Record<string, string>>, const TDecisionEffects extends Readonly<Record<string, string>>>(definition: ProductVocabularyDefinition<TClaimTypes, TDecisionEffects>): ProductVocabularyDefinition<TClaimTypes, TDecisionEffects>;
85
+ export declare function defineProductVocabulary<const TClaimTypes extends Readonly<Record<string, string>>, const TDecisionEffects extends Readonly<Record<string, string>>>(definition: ProductVocabularyInput<TClaimTypes, TDecisionEffects>): ProductVocabularyDefinition<TClaimTypes, TDecisionEffects>;
44
86
  export interface ConfidenceBasisForReviewInput {
45
87
  readonly status: TrustStatus;
46
88
  readonly impactLevel: ImpactLevel;
@@ -16,11 +16,35 @@ export function stableId(parts) {
16
16
  .toLowerCase())
17
17
  .join(".");
18
18
  }
19
+ let warnedLegacyVocabularySurfaceOnce = false;
20
+ function warnLegacyVocabularySurfaceOnce() {
21
+ if (warnedLegacyVocabularySurfaceOnce)
22
+ return;
23
+ warnedLegacyVocabularySurfaceOnce = true;
24
+ console.warn("[@kontourai/survey] deprecated: defineProductVocabulary's \"surface\" option is renamed to " +
25
+ "\"facet\" (Hachure schema 5 facet rename: Claim.surface -> Claim.facet, surface@2.0.0). " +
26
+ "Pass \"facet\" instead of \"surface\"; \"surface\" is accepted for one release as a read-compat alias.");
27
+ }
28
+ function resolveFacet(definition) {
29
+ if (definition.facet !== undefined)
30
+ return definition.facet;
31
+ if (definition.surface !== undefined) {
32
+ warnLegacyVocabularySurfaceOnce();
33
+ return definition.surface;
34
+ }
35
+ throw new Error('defineProductVocabulary requires "facet" (or deprecated "surface")');
36
+ }
19
37
  /**
20
38
  * Defines a product vocabulary as a deep-frozen, discoverable value that a
21
39
  * `currentProposedReviewItem` caller can pass instead of loose top-level
22
- * constants. Returns the same shape it received, frozen so callers cannot
23
- * mutate a shared vocabulary at runtime.
40
+ * constants. Returns the same shape it received (plus the mirrored
41
+ * deprecated `surface` alias — see {@link ProductVocabularyDefinition}),
42
+ * frozen so callers cannot mutate a shared vocabulary at runtime.
43
+ *
44
+ * Accepts either the canonical `facet` option or the deprecated `surface`
45
+ * option (not both required — `facet` wins when both are supplied, and
46
+ * using `surface` alone emits a single deprecation warning per process; see
47
+ * {@link ProductVocabularyInput}).
24
48
  *
25
49
  * The type parameters carry the `const` modifier, so `claimTypes` and
26
50
  * `decisionEffects` string properties keep their literal types whether or
@@ -35,9 +59,11 @@ export function stableId(parts) {
35
59
  * types-only floor and does not affect JavaScript consumers.
36
60
  */
37
61
  export function defineProductVocabulary(definition) {
62
+ const facet = resolveFacet(definition);
38
63
  return deepFreeze({
39
64
  subjectType: definition.subjectType,
40
- surface: definition.surface,
65
+ facet,
66
+ surface: facet,
41
67
  claimTypes: { ...definition.claimTypes },
42
68
  decisionEffects: { ...definition.decisionEffects },
43
69
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kontourai/survey",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
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",
@@ -68,7 +68,7 @@
68
68
  "check:generated-css": "node scripts/copy-review-workbench-package-assets.cjs --check"
69
69
  },
70
70
  "dependencies": {
71
- "@kontourai/surface": "^1.3.0"
71
+ "@kontourai/surface": "^2.0.0"
72
72
  },
73
73
  "peerDependencies": {
74
74
  "@anthropic-ai/sdk": ">=0.20.0",