@contractspec/example.locale-jurisdiction-gate 3.7.6 → 3.7.7

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/.turbo/turbo-build.log +3 -3
  2. package/AGENTS.md +50 -27
  3. package/README.md +57 -24
  4. package/dist/browser/entities/index.js +2 -2
  5. package/dist/browser/entities/models.js +2 -2
  6. package/dist/browser/events.js +1 -1
  7. package/dist/browser/index.js +42 -41
  8. package/dist/browser/operations/assistant.js +3 -3
  9. package/dist/browser/operations/index.js +3 -3
  10. package/dist/entities/index.js +2 -2
  11. package/dist/entities/models.js +2 -2
  12. package/dist/events.js +1 -1
  13. package/dist/index.d.ts +3 -3
  14. package/dist/index.js +42 -41
  15. package/dist/node/entities/index.js +2 -2
  16. package/dist/node/entities/models.js +2 -2
  17. package/dist/node/events.js +1 -1
  18. package/dist/node/index.js +42 -41
  19. package/dist/node/operations/assistant.js +3 -3
  20. package/dist/node/operations/index.js +3 -3
  21. package/dist/operations/assistant.js +3 -3
  22. package/dist/operations/index.js +3 -3
  23. package/dist/policy/index.d.ts +1 -1
  24. package/package.json +4 -4
  25. package/src/docs/locale-jurisdiction-gate.docblock.ts +21 -21
  26. package/src/entities/models.ts +87 -87
  27. package/src/events.ts +55 -55
  28. package/src/example.ts +28 -28
  29. package/src/handlers/demo.handlers.test.ts +46 -46
  30. package/src/handlers/demo.handlers.ts +133 -133
  31. package/src/index.ts +3 -3
  32. package/src/locale-jurisdiction-gate.feature.ts +34 -34
  33. package/src/operations/assistant.ts +82 -82
  34. package/src/policy/guard.test.ts +18 -18
  35. package/src/policy/guard.ts +75 -75
  36. package/src/policy/index.ts +1 -1
  37. package/src/policy/types.ts +12 -12
  38. package/tsconfig.json +7 -15
  39. package/tsdown.config.js +7 -13
@@ -43,9 +43,9 @@ var docBlocks = [
43
43
  registerDocBlocks(docBlocks);
44
44
  // src/entities/models.ts
45
45
  import {
46
- ScalarTypeEnum,
47
46
  defineEnum,
48
- defineSchemaModel
47
+ defineSchemaModel,
48
+ ScalarTypeEnum
49
49
  } from "@contractspec/lib.schema";
50
50
  var AllowedScopeEnum = defineEnum("AllowedScope", [
51
51
  "education_only",
@@ -144,7 +144,7 @@ var AssistantAnswerIRModel = defineSchemaModel({
144
144
  });
145
145
  // src/events.ts
146
146
  import { defineEvent } from "@contractspec/lib.contracts-spec";
147
- import { ScalarTypeEnum as ScalarTypeEnum2, defineSchemaModel as defineSchemaModel2 } from "@contractspec/lib.schema";
147
+ import { defineSchemaModel as defineSchemaModel2, ScalarTypeEnum as ScalarTypeEnum2 } from "@contractspec/lib.schema";
148
148
  var AssistantAnswerRequestedPayload = defineSchemaModel2({
149
149
  name: "AssistantAnswerRequestedPayload",
150
150
  description: "Emitted when an assistant answer is requested (pre-gate).",
@@ -393,9 +393,47 @@ function createDemoAssistantHandlers() {
393
393
  }
394
394
  return { answer, explainConcept };
395
395
  }
396
+ // src/locale-jurisdiction-gate.feature.ts
397
+ import { defineFeature } from "@contractspec/lib.contracts-spec";
398
+ var LocaleJurisdictionGateFeature = defineFeature({
399
+ meta: {
400
+ key: "locale-jurisdiction-gate",
401
+ version: "1.0.0",
402
+ title: "Locale + Jurisdiction Gate",
403
+ description: "Fail-closed gating for assistant calls requiring locale/jurisdiction/snapshot/scope and citations.",
404
+ domain: "knowledge",
405
+ owners: ["@examples"],
406
+ tags: ["assistant", "policy", "locale", "jurisdiction", "knowledge"],
407
+ stability: "experimental"
408
+ },
409
+ operations: [
410
+ { key: "assistant.answer", version: "1.0.0" },
411
+ { key: "assistant.explainConcept", version: "1.0.0" }
412
+ ],
413
+ events: [
414
+ { key: "assistant.answer.requested", version: "1.0.0" },
415
+ { key: "assistant.answer.blocked", version: "1.0.0" },
416
+ { key: "assistant.answer.delivered", version: "1.0.0" }
417
+ ],
418
+ presentations: [],
419
+ opToPresentation: [],
420
+ presentationsTargets: [],
421
+ capabilities: {
422
+ requires: [{ key: "knowledge", version: "1.0.0" }]
423
+ },
424
+ policies: [{ key: "locale-jurisdiction-gate.policy.gate", version: "1.0.0" }],
425
+ knowledge: [
426
+ { key: "locale-jurisdiction-gate.knowledge.rules", version: "1.0.0" }
427
+ ],
428
+ docs: [
429
+ "docs.examples.locale-jurisdiction-gate.goal",
430
+ "docs.examples.locale-jurisdiction-gate.reference"
431
+ ]
432
+ });
433
+
396
434
  // src/operations/assistant.ts
397
435
  import { defineCommand } from "@contractspec/lib.contracts-spec";
398
- import { ScalarTypeEnum as ScalarTypeEnum3, defineSchemaModel as defineSchemaModel3 } from "@contractspec/lib.schema";
436
+ import { defineSchemaModel as defineSchemaModel3, ScalarTypeEnum as ScalarTypeEnum3 } from "@contractspec/lib.schema";
399
437
  var AssistantQuestionInput = defineSchemaModel3({
400
438
  name: "AssistantQuestionInput",
401
439
  description: "Input for assistant calls with mandatory envelope.",
@@ -479,43 +517,6 @@ var AssistantExplainConceptContract = defineCommand({
479
517
  },
480
518
  policy: { auth: "user" }
481
519
  });
482
- // src/locale-jurisdiction-gate.feature.ts
483
- import { defineFeature } from "@contractspec/lib.contracts-spec";
484
- var LocaleJurisdictionGateFeature = defineFeature({
485
- meta: {
486
- key: "locale-jurisdiction-gate",
487
- version: "1.0.0",
488
- title: "Locale + Jurisdiction Gate",
489
- description: "Fail-closed gating for assistant calls requiring locale/jurisdiction/snapshot/scope and citations.",
490
- domain: "knowledge",
491
- owners: ["@examples"],
492
- tags: ["assistant", "policy", "locale", "jurisdiction", "knowledge"],
493
- stability: "experimental"
494
- },
495
- operations: [
496
- { key: "assistant.answer", version: "1.0.0" },
497
- { key: "assistant.explainConcept", version: "1.0.0" }
498
- ],
499
- events: [
500
- { key: "assistant.answer.requested", version: "1.0.0" },
501
- { key: "assistant.answer.blocked", version: "1.0.0" },
502
- { key: "assistant.answer.delivered", version: "1.0.0" }
503
- ],
504
- presentations: [],
505
- opToPresentation: [],
506
- presentationsTargets: [],
507
- capabilities: {
508
- requires: [{ key: "knowledge", version: "1.0.0" }]
509
- },
510
- policies: [{ key: "locale-jurisdiction-gate.policy.gate", version: "1.0.0" }],
511
- knowledge: [
512
- { key: "locale-jurisdiction-gate.knowledge.rules", version: "1.0.0" }
513
- ],
514
- docs: [
515
- "docs.examples.locale-jurisdiction-gate.goal",
516
- "docs.examples.locale-jurisdiction-gate.reference"
517
- ]
518
- });
519
520
  export {
520
521
  validateEnvelope,
521
522
  example_default as example,
@@ -1,8 +1,8 @@
1
1
  // src/entities/models.ts
2
2
  import {
3
- ScalarTypeEnum,
4
3
  defineEnum,
5
- defineSchemaModel
4
+ defineSchemaModel,
5
+ ScalarTypeEnum
6
6
  } from "@contractspec/lib.schema";
7
7
  var AllowedScopeEnum = defineEnum("AllowedScope", [
8
8
  "education_only",
@@ -102,7 +102,7 @@ var AssistantAnswerIRModel = defineSchemaModel({
102
102
 
103
103
  // src/operations/assistant.ts
104
104
  import { defineCommand } from "@contractspec/lib.contracts-spec";
105
- import { ScalarTypeEnum as ScalarTypeEnum2, defineSchemaModel as defineSchemaModel2 } from "@contractspec/lib.schema";
105
+ import { defineSchemaModel as defineSchemaModel2, ScalarTypeEnum as ScalarTypeEnum2 } from "@contractspec/lib.schema";
106
106
  var AssistantQuestionInput = defineSchemaModel2({
107
107
  name: "AssistantQuestionInput",
108
108
  description: "Input for assistant calls with mandatory envelope.",
@@ -1,8 +1,8 @@
1
1
  // src/entities/models.ts
2
2
  import {
3
- ScalarTypeEnum,
4
3
  defineEnum,
5
- defineSchemaModel
4
+ defineSchemaModel,
5
+ ScalarTypeEnum
6
6
  } from "@contractspec/lib.schema";
7
7
  var AllowedScopeEnum = defineEnum("AllowedScope", [
8
8
  "education_only",
@@ -102,7 +102,7 @@ var AssistantAnswerIRModel = defineSchemaModel({
102
102
 
103
103
  // src/operations/assistant.ts
104
104
  import { defineCommand } from "@contractspec/lib.contracts-spec";
105
- import { ScalarTypeEnum as ScalarTypeEnum2, defineSchemaModel as defineSchemaModel2 } from "@contractspec/lib.schema";
105
+ import { defineSchemaModel as defineSchemaModel2, ScalarTypeEnum as ScalarTypeEnum2 } from "@contractspec/lib.schema";
106
106
  var AssistantQuestionInput = defineSchemaModel2({
107
107
  name: "AssistantQuestionInput",
108
108
  description: "Input for assistant calls with mandatory envelope.",
@@ -1,9 +1,9 @@
1
1
  // @bun
2
2
  // src/entities/models.ts
3
3
  import {
4
- ScalarTypeEnum,
5
4
  defineEnum,
6
- defineSchemaModel
5
+ defineSchemaModel,
6
+ ScalarTypeEnum
7
7
  } from "@contractspec/lib.schema";
8
8
  var AllowedScopeEnum = defineEnum("AllowedScope", [
9
9
  "education_only",
@@ -103,7 +103,7 @@ var AssistantAnswerIRModel = defineSchemaModel({
103
103
 
104
104
  // src/operations/assistant.ts
105
105
  import { defineCommand } from "@contractspec/lib.contracts-spec";
106
- import { ScalarTypeEnum as ScalarTypeEnum2, defineSchemaModel as defineSchemaModel2 } from "@contractspec/lib.schema";
106
+ import { defineSchemaModel as defineSchemaModel2, ScalarTypeEnum as ScalarTypeEnum2 } from "@contractspec/lib.schema";
107
107
  var AssistantQuestionInput = defineSchemaModel2({
108
108
  name: "AssistantQuestionInput",
109
109
  description: "Input for assistant calls with mandatory envelope.",
@@ -1,9 +1,9 @@
1
1
  // @bun
2
2
  // src/entities/models.ts
3
3
  import {
4
- ScalarTypeEnum,
5
4
  defineEnum,
6
- defineSchemaModel
5
+ defineSchemaModel,
6
+ ScalarTypeEnum
7
7
  } from "@contractspec/lib.schema";
8
8
  var AllowedScopeEnum = defineEnum("AllowedScope", [
9
9
  "education_only",
@@ -103,7 +103,7 @@ var AssistantAnswerIRModel = defineSchemaModel({
103
103
 
104
104
  // src/operations/assistant.ts
105
105
  import { defineCommand } from "@contractspec/lib.contracts-spec";
106
- import { ScalarTypeEnum as ScalarTypeEnum2, defineSchemaModel as defineSchemaModel2 } from "@contractspec/lib.schema";
106
+ import { defineSchemaModel as defineSchemaModel2, ScalarTypeEnum as ScalarTypeEnum2 } from "@contractspec/lib.schema";
107
107
  var AssistantQuestionInput = defineSchemaModel2({
108
108
  name: "AssistantQuestionInput",
109
109
  description: "Input for assistant calls with mandatory envelope.",
@@ -1,2 +1,2 @@
1
- export * from './types';
2
1
  export * from './guard';
2
+ export * from './types';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contractspec/example.locale-jurisdiction-gate",
3
- "version": "3.7.6",
3
+ "version": "3.7.7",
4
4
  "description": "Example: enforce locale + jurisdiction + kbSnapshotId + allowed scope for assistant calls (fail-closed).",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
@@ -120,14 +120,14 @@
120
120
  "dev": "contractspec-bun-build dev",
121
121
  "clean": "rimraf dist .turbo",
122
122
  "lint": "bun lint:fix",
123
- "lint:fix": "eslint src --fix",
124
- "lint:check": "eslint src",
123
+ "lint:fix": "biome check --write --unsafe --only=nursery/useSortedClasses . && biome check --write .",
124
+ "lint:check": "biome check .",
125
125
  "test": "bun test",
126
126
  "prebuild": "contractspec-bun-build prebuild",
127
127
  "typecheck": "tsc --noEmit"
128
128
  },
129
129
  "dependencies": {
130
- "@contractspec/lib.contracts-spec": "3.7.6",
130
+ "@contractspec/lib.contracts-spec": "4.0.0",
131
131
  "@contractspec/lib.schema": "3.7.6"
132
132
  },
133
133
  "devDependencies": {
@@ -2,16 +2,16 @@ import type { DocBlock } from '@contractspec/lib.contracts-spec/docs';
2
2
  import { registerDocBlocks } from '@contractspec/lib.contracts-spec/docs';
3
3
 
4
4
  const docBlocks: DocBlock[] = [
5
- {
6
- id: 'docs.examples.locale-jurisdiction-gate.goal',
7
- title: 'Locale/Jurisdiction Gate — Goal',
8
- summary:
9
- 'Fail-closed gate that forces locale + jurisdiction + kbSnapshotId + allowedScope for assistant calls.',
10
- kind: 'goal',
11
- visibility: 'public',
12
- route: '/docs/examples/locale-jurisdiction-gate/goal',
13
- tags: ['assistant', 'policy', 'locale', 'jurisdiction', 'knowledge'],
14
- body: `## Why it matters
5
+ {
6
+ id: 'docs.examples.locale-jurisdiction-gate.goal',
7
+ title: 'Locale/Jurisdiction Gate — Goal',
8
+ summary:
9
+ 'Fail-closed gate that forces locale + jurisdiction + kbSnapshotId + allowedScope for assistant calls.',
10
+ kind: 'goal',
11
+ visibility: 'public',
12
+ route: '/docs/examples/locale-jurisdiction-gate/goal',
13
+ tags: ['assistant', 'policy', 'locale', 'jurisdiction', 'knowledge'],
14
+ body: `## Why it matters
15
15
  - Forces all assistant behavior to be bound to explicit inputs (no guessing).
16
16
  - Requires KB snapshot citations to make answers traceable and regenerable.
17
17
 
@@ -19,16 +19,16 @@ const docBlocks: DocBlock[] = [
19
19
  - Missing locale/jurisdiction/snapshot/scope => refuse (structured).
20
20
  - Missing citations => refuse.
21
21
  - Scope violations under education_only => refuse/escalate.`,
22
- },
23
- {
24
- id: 'docs.examples.locale-jurisdiction-gate.reference',
25
- title: 'Locale/Jurisdiction Gate — Reference',
26
- summary: 'Contracts, models, and events exposed by the gate example.',
27
- kind: 'reference',
28
- visibility: 'public',
29
- route: '/docs/examples/locale-jurisdiction-gate',
30
- tags: ['assistant', 'policy', 'reference'],
31
- body: `## Contracts
22
+ },
23
+ {
24
+ id: 'docs.examples.locale-jurisdiction-gate.reference',
25
+ title: 'Locale/Jurisdiction Gate — Reference',
26
+ summary: 'Contracts, models, and events exposed by the gate example.',
27
+ kind: 'reference',
28
+ visibility: 'public',
29
+ route: '/docs/examples/locale-jurisdiction-gate',
30
+ tags: ['assistant', 'policy', 'reference'],
31
+ body: `## Contracts
32
32
  - assistant.answer (v1)
33
33
  - assistant.explainConcept (v1)
34
34
 
@@ -40,7 +40,7 @@ const docBlocks: DocBlock[] = [
40
40
  - assistant.answer.requested
41
41
  - assistant.answer.blocked
42
42
  - assistant.answer.delivered`,
43
- },
43
+ },
44
44
  ];
45
45
 
46
46
  registerDocBlocks(docBlocks);
@@ -1,110 +1,110 @@
1
1
  import {
2
- ScalarTypeEnum,
3
- defineEnum,
4
- defineSchemaModel,
2
+ defineEnum,
3
+ defineSchemaModel,
4
+ ScalarTypeEnum,
5
5
  } from '@contractspec/lib.schema';
6
6
 
7
7
  export const AllowedScopeEnum = defineEnum('AllowedScope', [
8
- 'education_only',
9
- 'generic_info',
10
- 'escalation_required',
8
+ 'education_only',
9
+ 'generic_info',
10
+ 'escalation_required',
11
11
  ]);
12
12
 
13
13
  export const UserProfileModel = defineSchemaModel({
14
- name: 'UserProfile',
15
- description: 'User profile inputs used to derive regulatory context.',
16
- fields: {
17
- preferredLocale: {
18
- type: ScalarTypeEnum.String_unsecure(),
19
- isOptional: true,
20
- },
21
- residencyCountry: {
22
- type: ScalarTypeEnum.String_unsecure(),
23
- isOptional: true,
24
- },
25
- taxResidenceCountry: {
26
- type: ScalarTypeEnum.String_unsecure(),
27
- isOptional: true,
28
- },
29
- clientType: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
30
- },
14
+ name: 'UserProfile',
15
+ description: 'User profile inputs used to derive regulatory context.',
16
+ fields: {
17
+ preferredLocale: {
18
+ type: ScalarTypeEnum.String_unsecure(),
19
+ isOptional: true,
20
+ },
21
+ residencyCountry: {
22
+ type: ScalarTypeEnum.String_unsecure(),
23
+ isOptional: true,
24
+ },
25
+ taxResidenceCountry: {
26
+ type: ScalarTypeEnum.String_unsecure(),
27
+ isOptional: true,
28
+ },
29
+ clientType: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
30
+ },
31
31
  });
32
32
 
33
33
  export const RegulatoryContextModel = defineSchemaModel({
34
- name: 'RegulatoryContext',
35
- description: 'Explicit regulatory context (no guessing).',
36
- fields: {
37
- jurisdiction: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
38
- region: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
39
- clientType: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
40
- allowedScope: { type: AllowedScopeEnum, isOptional: false },
41
- },
34
+ name: 'RegulatoryContext',
35
+ description: 'Explicit regulatory context (no guessing).',
36
+ fields: {
37
+ jurisdiction: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
38
+ region: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
39
+ clientType: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
40
+ allowedScope: { type: AllowedScopeEnum, isOptional: false },
41
+ },
42
42
  });
43
43
 
44
44
  export const LLMCallEnvelopeModel = defineSchemaModel({
45
- name: 'LLMCallEnvelope',
46
- description:
47
- 'Mandatory envelope for assistant calls. All fields are explicit and required for policy gating.',
48
- fields: {
49
- traceId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
50
- locale: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
51
- regulatoryContext: { type: RegulatoryContextModel, isOptional: false },
52
- kbSnapshotId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
53
- allowedScope: { type: AllowedScopeEnum, isOptional: false },
54
- },
45
+ name: 'LLMCallEnvelope',
46
+ description:
47
+ 'Mandatory envelope for assistant calls. All fields are explicit and required for policy gating.',
48
+ fields: {
49
+ traceId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
50
+ locale: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
51
+ regulatoryContext: { type: RegulatoryContextModel, isOptional: false },
52
+ kbSnapshotId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
53
+ allowedScope: { type: AllowedScopeEnum, isOptional: false },
54
+ },
55
55
  });
56
56
 
57
57
  export const AssistantCitationModel = defineSchemaModel({
58
- name: 'AssistantCitation',
59
- description:
60
- 'Citation referencing a KB snapshot + a specific item within it.',
61
- fields: {
62
- kbSnapshotId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
63
- sourceType: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
64
- sourceId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
65
- title: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
66
- excerpt: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
67
- },
58
+ name: 'AssistantCitation',
59
+ description:
60
+ 'Citation referencing a KB snapshot + a specific item within it.',
61
+ fields: {
62
+ kbSnapshotId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
63
+ sourceType: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
64
+ sourceId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
65
+ title: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
66
+ excerpt: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
67
+ },
68
68
  });
69
69
 
70
70
  export const AssistantAnswerSectionModel = defineSchemaModel({
71
- name: 'AssistantAnswerSection',
72
- description: 'Structured answer section.',
73
- fields: {
74
- heading: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
75
- body: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
76
- },
71
+ name: 'AssistantAnswerSection',
72
+ description: 'Structured answer section.',
73
+ fields: {
74
+ heading: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
75
+ body: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
76
+ },
77
77
  });
78
78
 
79
79
  export const AssistantAnswerIRModel = defineSchemaModel({
80
- name: 'AssistantAnswerIR',
81
- description:
82
- 'Structured assistant answer with mandatory citations and explicit locale/jurisdiction.',
83
- fields: {
84
- locale: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
85
- jurisdiction: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
86
- allowedScope: { type: AllowedScopeEnum, isOptional: false },
87
- sections: {
88
- type: AssistantAnswerSectionModel,
89
- isArray: true,
90
- isOptional: false,
91
- },
92
- citations: {
93
- type: AssistantCitationModel,
94
- isArray: true,
95
- isOptional: false,
96
- },
97
- disclaimers: {
98
- type: ScalarTypeEnum.String_unsecure(),
99
- isArray: true,
100
- isOptional: true,
101
- },
102
- riskFlags: {
103
- type: ScalarTypeEnum.String_unsecure(),
104
- isArray: true,
105
- isOptional: true,
106
- },
107
- refused: { type: ScalarTypeEnum.Boolean(), isOptional: true },
108
- refusalReason: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
109
- },
80
+ name: 'AssistantAnswerIR',
81
+ description:
82
+ 'Structured assistant answer with mandatory citations and explicit locale/jurisdiction.',
83
+ fields: {
84
+ locale: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
85
+ jurisdiction: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
86
+ allowedScope: { type: AllowedScopeEnum, isOptional: false },
87
+ sections: {
88
+ type: AssistantAnswerSectionModel,
89
+ isArray: true,
90
+ isOptional: false,
91
+ },
92
+ citations: {
93
+ type: AssistantCitationModel,
94
+ isArray: true,
95
+ isOptional: false,
96
+ },
97
+ disclaimers: {
98
+ type: ScalarTypeEnum.String_unsecure(),
99
+ isArray: true,
100
+ isOptional: true,
101
+ },
102
+ riskFlags: {
103
+ type: ScalarTypeEnum.String_unsecure(),
104
+ isArray: true,
105
+ isOptional: true,
106
+ },
107
+ refused: { type: ScalarTypeEnum.Boolean(), isOptional: true },
108
+ refusalReason: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
109
+ },
110
110
  });
package/src/events.ts CHANGED
@@ -1,74 +1,74 @@
1
1
  import { defineEvent } from '@contractspec/lib.contracts-spec';
2
- import { ScalarTypeEnum, defineSchemaModel } from '@contractspec/lib.schema';
2
+ import { defineSchemaModel, ScalarTypeEnum } from '@contractspec/lib.schema';
3
3
 
4
4
  const AssistantAnswerRequestedPayload = defineSchemaModel({
5
- name: 'AssistantAnswerRequestedPayload',
6
- description: 'Emitted when an assistant answer is requested (pre-gate).',
7
- fields: {
8
- traceId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
9
- locale: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
10
- jurisdiction: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
11
- kbSnapshotId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
12
- allowedScope: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
13
- },
5
+ name: 'AssistantAnswerRequestedPayload',
6
+ description: 'Emitted when an assistant answer is requested (pre-gate).',
7
+ fields: {
8
+ traceId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
9
+ locale: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
10
+ jurisdiction: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
11
+ kbSnapshotId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
12
+ allowedScope: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
13
+ },
14
14
  });
15
15
 
16
16
  export const AssistantAnswerRequestedEvent = defineEvent({
17
- meta: {
18
- key: 'assistant.answer.requested',
19
- version: '1.0.0',
20
- description: 'Assistant answer requested (policy gate will run).',
21
- stability: 'experimental',
22
- owners: ['@examples'],
23
- tags: ['assistant', 'policy'],
24
- },
25
- payload: AssistantAnswerRequestedPayload,
17
+ meta: {
18
+ key: 'assistant.answer.requested',
19
+ version: '1.0.0',
20
+ description: 'Assistant answer requested (policy gate will run).',
21
+ stability: 'experimental',
22
+ owners: ['@examples'],
23
+ tags: ['assistant', 'policy'],
24
+ },
25
+ payload: AssistantAnswerRequestedPayload,
26
26
  });
27
27
 
28
28
  const AssistantAnswerBlockedPayload = defineSchemaModel({
29
- name: 'AssistantAnswerBlockedPayload',
30
- description: 'Emitted when a request is blocked by the gate.',
31
- fields: {
32
- traceId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
33
- reasonCode: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
34
- reason: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
35
- },
29
+ name: 'AssistantAnswerBlockedPayload',
30
+ description: 'Emitted when a request is blocked by the gate.',
31
+ fields: {
32
+ traceId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
33
+ reasonCode: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
34
+ reason: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
35
+ },
36
36
  });
37
37
 
38
38
  export const AssistantAnswerBlockedEvent = defineEvent({
39
- meta: {
40
- key: 'assistant.answer.blocked',
41
- version: '1.0.0',
42
- description: 'Assistant answer blocked (fail-closed).',
43
- stability: 'experimental',
44
- owners: ['@examples'],
45
- tags: ['assistant', 'policy', 'blocked'],
46
- },
47
- payload: AssistantAnswerBlockedPayload,
39
+ meta: {
40
+ key: 'assistant.answer.blocked',
41
+ version: '1.0.0',
42
+ description: 'Assistant answer blocked (fail-closed).',
43
+ stability: 'experimental',
44
+ owners: ['@examples'],
45
+ tags: ['assistant', 'policy', 'blocked'],
46
+ },
47
+ payload: AssistantAnswerBlockedPayload,
48
48
  });
49
49
 
50
50
  const AssistantAnswerDeliveredPayload = defineSchemaModel({
51
- name: 'AssistantAnswerDeliveredPayload',
52
- description: 'Emitted when a structured, cited answer is delivered.',
53
- fields: {
54
- traceId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
55
- locale: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
56
- jurisdiction: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
57
- kbSnapshotId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
58
- allowedScope: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
59
- citationsCount: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },
60
- },
51
+ name: 'AssistantAnswerDeliveredPayload',
52
+ description: 'Emitted when a structured, cited answer is delivered.',
53
+ fields: {
54
+ traceId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
55
+ locale: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
56
+ jurisdiction: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
57
+ kbSnapshotId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
58
+ allowedScope: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
59
+ citationsCount: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },
60
+ },
61
61
  });
62
62
 
63
63
  export const AssistantAnswerDeliveredEvent = defineEvent({
64
- meta: {
65
- key: 'assistant.answer.delivered',
66
- version: '1.0.0',
67
- description:
68
- 'Assistant answer delivered (must include KB snapshot citations).',
69
- stability: 'experimental',
70
- owners: ['@examples'],
71
- tags: ['assistant', 'policy', 'delivered'],
72
- },
73
- payload: AssistantAnswerDeliveredPayload,
64
+ meta: {
65
+ key: 'assistant.answer.delivered',
66
+ version: '1.0.0',
67
+ description:
68
+ 'Assistant answer delivered (must include KB snapshot citations).',
69
+ stability: 'experimental',
70
+ owners: ['@examples'],
71
+ tags: ['assistant', 'policy', 'delivered'],
72
+ },
73
+ payload: AssistantAnswerDeliveredPayload,
74
74
  });