@contractspec/example.locale-jurisdiction-gate 3.7.17 → 3.7.18

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 (66) hide show
  1. package/.turbo/turbo-build.log +66 -66
  2. package/CHANGELOG.md +10 -0
  3. package/dist/browser/docs/index.js +3 -27
  4. package/dist/browser/docs/locale-jurisdiction-gate.docblock.js +3 -27
  5. package/dist/browser/entities/index.js +1 -110
  6. package/dist/browser/entities/models.js +1 -110
  7. package/dist/browser/events.js +1 -73
  8. package/dist/browser/example.js +1 -35
  9. package/dist/browser/forms/assistant-context.form.js +1 -213
  10. package/dist/browser/forms/index.js +1 -213
  11. package/dist/browser/handlers/demo.handlers.js +2 -152
  12. package/dist/browser/handlers/index.js +2 -152
  13. package/dist/browser/index.js +4 -844
  14. package/dist/browser/locale-jurisdiction-gate.feature.js +1 -105
  15. package/dist/browser/operations/assistant.js +1 -192
  16. package/dist/browser/operations/index.js +1 -192
  17. package/dist/browser/policy/assistant-gate.policy.js +1 -62
  18. package/dist/browser/policy/guard.js +2 -73
  19. package/dist/browser/policy/index.js +2 -134
  20. package/dist/browser/translations/assistant-gate.en-GB.translation.js +1 -48
  21. package/dist/browser/translations/assistant-gate.en-US.translation.js +1 -50
  22. package/dist/browser/translations/assistant-gate.fr-FR.translation.js +1 -52
  23. package/dist/browser/translations/index.js +1 -148
  24. package/dist/docs/index.js +3 -27
  25. package/dist/docs/locale-jurisdiction-gate.docblock.js +3 -27
  26. package/dist/entities/index.js +1 -110
  27. package/dist/entities/models.js +1 -110
  28. package/dist/events.js +1 -73
  29. package/dist/example.js +1 -35
  30. package/dist/forms/assistant-context.form.js +1 -213
  31. package/dist/forms/index.js +1 -213
  32. package/dist/handlers/demo.handlers.js +2 -152
  33. package/dist/handlers/index.js +2 -152
  34. package/dist/index.js +4 -844
  35. package/dist/locale-jurisdiction-gate.feature.js +1 -105
  36. package/dist/node/docs/index.js +3 -27
  37. package/dist/node/docs/locale-jurisdiction-gate.docblock.js +3 -27
  38. package/dist/node/entities/index.js +1 -110
  39. package/dist/node/entities/models.js +1 -110
  40. package/dist/node/events.js +1 -73
  41. package/dist/node/example.js +1 -35
  42. package/dist/node/forms/assistant-context.form.js +1 -213
  43. package/dist/node/forms/index.js +1 -213
  44. package/dist/node/handlers/demo.handlers.js +2 -152
  45. package/dist/node/handlers/index.js +2 -152
  46. package/dist/node/index.js +4 -844
  47. package/dist/node/locale-jurisdiction-gate.feature.js +1 -105
  48. package/dist/node/operations/assistant.js +1 -192
  49. package/dist/node/operations/index.js +1 -192
  50. package/dist/node/policy/assistant-gate.policy.js +1 -62
  51. package/dist/node/policy/guard.js +2 -73
  52. package/dist/node/policy/index.js +2 -134
  53. package/dist/node/translations/assistant-gate.en-GB.translation.js +1 -48
  54. package/dist/node/translations/assistant-gate.en-US.translation.js +1 -50
  55. package/dist/node/translations/assistant-gate.fr-FR.translation.js +1 -52
  56. package/dist/node/translations/index.js +1 -148
  57. package/dist/operations/assistant.js +1 -192
  58. package/dist/operations/index.js +1 -192
  59. package/dist/policy/assistant-gate.policy.js +1 -62
  60. package/dist/policy/guard.js +2 -73
  61. package/dist/policy/index.js +2 -134
  62. package/dist/translations/assistant-gate.en-GB.translation.js +1 -48
  63. package/dist/translations/assistant-gate.en-US.translation.js +1 -50
  64. package/dist/translations/assistant-gate.fr-FR.translation.js +1 -52
  65. package/dist/translations/index.js +1 -148
  66. package/package.json +5 -5
@@ -1,105 +1 @@
1
- // src/policy/assistant-gate.policy.ts
2
- import {
3
- OwnersEnum,
4
- StabilityEnum,
5
- TagsEnum
6
- } from "@contractspec/lib.contracts-spec/ownership";
7
- import { definePolicy } from "@contractspec/lib.contracts-spec/policy";
8
- var AssistantGatePolicy = definePolicy({
9
- meta: {
10
- key: "locale-jurisdiction-gate.policy.gate",
11
- version: "1.0.0",
12
- title: "Assistant Locale and Jurisdiction Gate",
13
- description: "Requires explicit locale, jurisdiction, knowledge snapshot, and allowed scope before assistant requests may proceed.",
14
- domain: "assistant",
15
- scope: "operation",
16
- owners: [OwnersEnum.PlatformFinance],
17
- tags: [TagsEnum.I18n, "assistant", "policy", "jurisdiction"],
18
- stability: StabilityEnum.Experimental
19
- },
20
- rules: [
21
- {
22
- effect: "deny",
23
- actions: ["assistant.answer", "assistant.explainConcept"],
24
- resource: { type: "assistant-call" },
25
- conditions: [
26
- {
27
- expression: "!context.locale || !context.jurisdiction || !context.kbSnapshotId || !context.allowedScope"
28
- }
29
- ],
30
- reason: "Assistant requests fail closed until locale, jurisdiction, kbSnapshotId, and allowedScope are explicit."
31
- },
32
- {
33
- effect: "deny",
34
- actions: ["assistant.answer", "assistant.explainConcept"],
35
- resource: { type: "assistant-call" },
36
- conditions: [
37
- {
38
- expression: "!['en-US', 'en-GB', 'fr-FR'].includes(context.locale ?? '')"
39
- }
40
- ],
41
- reason: "Only the explicitly reviewed assistant locales are permitted."
42
- },
43
- {
44
- effect: "allow",
45
- actions: ["assistant.answer", "assistant.explainConcept"],
46
- resource: { type: "assistant-call" },
47
- conditions: [
48
- {
49
- expression: "['en-US', 'en-GB', 'fr-FR'].includes(context.locale ?? '') && !!context.jurisdiction && !!context.kbSnapshotId && !!context.allowedScope"
50
- }
51
- ],
52
- reason: "Explicit context is present, so the request may continue to citation and scope validation."
53
- }
54
- ],
55
- pii: {
56
- fields: ["kbSnapshotId"],
57
- retentionDays: 30
58
- }
59
- });
60
-
61
- // src/locale-jurisdiction-gate.feature.ts
62
- import { defineFeature } from "@contractspec/lib.contracts-spec";
63
- var LocaleJurisdictionGateFeature = defineFeature({
64
- meta: {
65
- key: "locale-jurisdiction-gate",
66
- version: "1.0.0",
67
- title: "Locale + Jurisdiction Gate",
68
- description: "Fail-closed gating for assistant calls requiring locale/jurisdiction/snapshot/scope and citations.",
69
- domain: "knowledge",
70
- owners: ["@examples"],
71
- tags: ["assistant", "policy", "locale", "jurisdiction", "knowledge"],
72
- stability: "experimental"
73
- },
74
- operations: [
75
- { key: "assistant.answer", version: "1.0.0" },
76
- { key: "assistant.explainConcept", version: "1.0.0" }
77
- ],
78
- events: [
79
- { key: "assistant.answer.requested", version: "1.0.0" },
80
- { key: "assistant.answer.blocked", version: "1.0.0" },
81
- { key: "assistant.answer.delivered", version: "1.0.0" }
82
- ],
83
- presentations: [],
84
- opToPresentation: [],
85
- presentationsTargets: [],
86
- capabilities: {
87
- requires: [{ key: "knowledge", version: "1.0.0" }]
88
- },
89
- policies: [
90
- {
91
- key: AssistantGatePolicy.meta.key,
92
- version: AssistantGatePolicy.meta.version
93
- }
94
- ],
95
- knowledge: [
96
- { key: "locale-jurisdiction-gate.knowledge.rules", version: "1.0.0" }
97
- ],
98
- docs: [
99
- "docs.examples.locale-jurisdiction-gate.goal",
100
- "docs.examples.locale-jurisdiction-gate.reference"
101
- ]
102
- });
103
- export {
104
- LocaleJurisdictionGateFeature
105
- };
1
+ import{OwnersEnum as j,StabilityEnum as k,TagsEnum as q}from"@contractspec/lib.contracts-spec/ownership";import{definePolicy as v}from"@contractspec/lib.contracts-spec/policy";var h=v({meta:{key:"locale-jurisdiction-gate.policy.gate",version:"1.0.0",title:"Assistant Locale and Jurisdiction Gate",description:"Requires explicit locale, jurisdiction, knowledge snapshot, and allowed scope before assistant requests may proceed.",domain:"assistant",scope:"operation",owners:[j.PlatformFinance],tags:[q.I18n,"assistant","policy","jurisdiction"],stability:k.Experimental},rules:[{effect:"deny",actions:["assistant.answer","assistant.explainConcept"],resource:{type:"assistant-call"},conditions:[{expression:"!context.locale || !context.jurisdiction || !context.kbSnapshotId || !context.allowedScope"}],reason:"Assistant requests fail closed until locale, jurisdiction, kbSnapshotId, and allowedScope are explicit."},{effect:"deny",actions:["assistant.answer","assistant.explainConcept"],resource:{type:"assistant-call"},conditions:[{expression:"!['en-US', 'en-GB', 'fr-FR'].includes(context.locale ?? '')"}],reason:"Only the explicitly reviewed assistant locales are permitted."},{effect:"allow",actions:["assistant.answer","assistant.explainConcept"],resource:{type:"assistant-call"},conditions:[{expression:"['en-US', 'en-GB', 'fr-FR'].includes(context.locale ?? '') && !!context.jurisdiction && !!context.kbSnapshotId && !!context.allowedScope"}],reason:"Explicit context is present, so the request may continue to citation and scope validation."}],pii:{fields:["kbSnapshotId"],retentionDays:30}});import{defineFeature as x}from"@contractspec/lib.contracts-spec";var I=x({meta:{key:"locale-jurisdiction-gate",version:"1.0.0",title:"Locale + Jurisdiction Gate",description:"Fail-closed gating for assistant calls requiring locale/jurisdiction/snapshot/scope and citations.",domain:"knowledge",owners:["@examples"],tags:["assistant","policy","locale","jurisdiction","knowledge"],stability:"experimental"},operations:[{key:"assistant.answer",version:"1.0.0"},{key:"assistant.explainConcept",version:"1.0.0"}],events:[{key:"assistant.answer.requested",version:"1.0.0"},{key:"assistant.answer.blocked",version:"1.0.0"},{key:"assistant.answer.delivered",version:"1.0.0"}],presentations:[],opToPresentation:[],presentationsTargets:[],capabilities:{requires:[{key:"knowledge",version:"1.0.0"}]},policies:[{key:h.meta.key,version:h.meta.version}],knowledge:[{key:"locale-jurisdiction-gate.knowledge.rules",version:"1.0.0"}],docs:["docs.examples.locale-jurisdiction-gate.goal","docs.examples.locale-jurisdiction-gate.reference"]});export{I as LocaleJurisdictionGateFeature};
@@ -1,192 +1 @@
1
- // src/entities/models.ts
2
- import {
3
- defineEnum,
4
- defineSchemaModel,
5
- ScalarTypeEnum
6
- } from "@contractspec/lib.schema";
7
- var AllowedScopeEnum = defineEnum("AllowedScope", [
8
- "education_only",
9
- "generic_info",
10
- "escalation_required"
11
- ]);
12
- var UserProfileModel = defineSchemaModel({
13
- name: "UserProfile",
14
- description: "User profile inputs used to derive regulatory context.",
15
- fields: {
16
- preferredLocale: {
17
- type: ScalarTypeEnum.String_unsecure(),
18
- isOptional: true
19
- },
20
- residencyCountry: {
21
- type: ScalarTypeEnum.String_unsecure(),
22
- isOptional: true
23
- },
24
- taxResidenceCountry: {
25
- type: ScalarTypeEnum.String_unsecure(),
26
- isOptional: true
27
- },
28
- clientType: { type: ScalarTypeEnum.String_unsecure(), isOptional: true }
29
- }
30
- });
31
- var RegulatoryContextModel = defineSchemaModel({
32
- name: "RegulatoryContext",
33
- description: "Explicit regulatory context (no guessing).",
34
- fields: {
35
- jurisdiction: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
36
- region: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
37
- clientType: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
38
- allowedScope: { type: AllowedScopeEnum, isOptional: false }
39
- }
40
- });
41
- var LLMCallEnvelopeModel = defineSchemaModel({
42
- name: "LLMCallEnvelope",
43
- description: "Mandatory envelope for assistant calls. All fields are explicit and required for policy gating.",
44
- fields: {
45
- traceId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
46
- locale: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
47
- regulatoryContext: { type: RegulatoryContextModel, isOptional: false },
48
- kbSnapshotId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
49
- allowedScope: { type: AllowedScopeEnum, isOptional: false }
50
- }
51
- });
52
- var AssistantCitationModel = defineSchemaModel({
53
- name: "AssistantCitation",
54
- description: "Citation referencing a KB snapshot + a specific item within it.",
55
- fields: {
56
- kbSnapshotId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
57
- sourceType: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
58
- sourceId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
59
- title: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
60
- excerpt: { type: ScalarTypeEnum.String_unsecure(), isOptional: true }
61
- }
62
- });
63
- var AssistantAnswerSectionModel = defineSchemaModel({
64
- name: "AssistantAnswerSection",
65
- description: "Structured answer section.",
66
- fields: {
67
- heading: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
68
- body: { type: ScalarTypeEnum.String_unsecure(), isOptional: false }
69
- }
70
- });
71
- var AssistantAnswerIRModel = defineSchemaModel({
72
- name: "AssistantAnswerIR",
73
- description: "Structured assistant answer with mandatory citations and explicit locale/jurisdiction.",
74
- fields: {
75
- locale: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
76
- jurisdiction: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
77
- allowedScope: { type: AllowedScopeEnum, isOptional: false },
78
- sections: {
79
- type: AssistantAnswerSectionModel,
80
- isArray: true,
81
- isOptional: false
82
- },
83
- citations: {
84
- type: AssistantCitationModel,
85
- isArray: true,
86
- isOptional: false
87
- },
88
- disclaimers: {
89
- type: ScalarTypeEnum.String_unsecure(),
90
- isArray: true,
91
- isOptional: true
92
- },
93
- riskFlags: {
94
- type: ScalarTypeEnum.String_unsecure(),
95
- isArray: true,
96
- isOptional: true
97
- },
98
- refused: { type: ScalarTypeEnum.Boolean(), isOptional: true },
99
- refusalReason: { type: ScalarTypeEnum.String_unsecure(), isOptional: true }
100
- }
101
- });
102
-
103
- // src/operations/assistant.ts
104
- import { defineCommand } from "@contractspec/lib.contracts-spec";
105
- import { defineSchemaModel as defineSchemaModel2, ScalarTypeEnum as ScalarTypeEnum2 } from "@contractspec/lib.schema";
106
- var AssistantQuestionInput = defineSchemaModel2({
107
- name: "AssistantQuestionInput",
108
- description: "Input for assistant calls with mandatory envelope.",
109
- fields: {
110
- envelope: { type: LLMCallEnvelopeModel, isOptional: false },
111
- question: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false }
112
- }
113
- });
114
- var AssistantConceptInput = defineSchemaModel2({
115
- name: "AssistantConceptInput",
116
- description: "Input for explaining a concept with mandatory envelope.",
117
- fields: {
118
- envelope: { type: LLMCallEnvelopeModel, isOptional: false },
119
- conceptKey: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false }
120
- }
121
- });
122
- var AssistantAnswerContract = defineCommand({
123
- meta: {
124
- key: "assistant.answer",
125
- version: "1.0.0",
126
- stability: "experimental",
127
- owners: ["@examples"],
128
- tags: ["assistant", "policy", "locale", "jurisdiction", "knowledge"],
129
- description: "Answer a user question using a KB snapshot with strict locale/jurisdiction gating.",
130
- goal: "Provide policy-safe answers that cite a KB snapshot or refuse.",
131
- context: "Called by UI or workflows; must fail-closed if envelope is invalid or citations are missing."
132
- },
133
- io: {
134
- input: AssistantQuestionInput,
135
- output: AssistantAnswerIRModel,
136
- errors: {
137
- LOCALE_REQUIRED: {
138
- description: "Locale is required and must be supported",
139
- http: 400,
140
- gqlCode: "LOCALE_REQUIRED",
141
- when: "locale is missing or unsupported"
142
- },
143
- JURISDICTION_REQUIRED: {
144
- description: "Jurisdiction is required",
145
- http: 400,
146
- gqlCode: "JURISDICTION_REQUIRED",
147
- when: "jurisdiction is missing"
148
- },
149
- KB_SNAPSHOT_REQUIRED: {
150
- description: "KB snapshot id is required",
151
- http: 400,
152
- gqlCode: "KB_SNAPSHOT_REQUIRED",
153
- when: "kbSnapshotId is missing"
154
- },
155
- CITATIONS_REQUIRED: {
156
- description: "Answers must include citations to a KB snapshot",
157
- http: 422,
158
- gqlCode: "CITATIONS_REQUIRED",
159
- when: "answer has no citations"
160
- },
161
- SCOPE_VIOLATION: {
162
- description: "Answer violates allowed scope and must be refused/escalated",
163
- http: 403,
164
- gqlCode: "SCOPE_VIOLATION",
165
- when: "output includes forbidden content under the given allowedScope"
166
- }
167
- }
168
- },
169
- policy: { auth: "user" }
170
- });
171
- var AssistantExplainConceptContract = defineCommand({
172
- meta: {
173
- key: "assistant.explainConcept",
174
- version: "1.0.0",
175
- stability: "experimental",
176
- owners: ["@examples"],
177
- tags: ["assistant", "policy", "knowledge", "concepts"],
178
- description: "Explain a concept using a KB snapshot with strict locale/jurisdiction gating.",
179
- goal: "Explain concepts with citations or refuse.",
180
- context: "Same constraints as assistant.answer."
181
- },
182
- io: {
183
- input: AssistantConceptInput,
184
- output: AssistantAnswerIRModel,
185
- errors: AssistantAnswerContract.io.errors
186
- },
187
- policy: { auth: "user" }
188
- });
189
- export {
190
- AssistantExplainConceptContract,
191
- AssistantAnswerContract
192
- };
1
+ import{defineEnum as l,defineSchemaModel as t,ScalarTypeEnum as e}from"@contractspec/lib.schema";var i=l("AllowedScope",["education_only","generic_info","escalation_required"]),S=t({name:"UserProfile",description:"User profile inputs used to derive regulatory context.",fields:{preferredLocale:{type:e.String_unsecure(),isOptional:!0},residencyCountry:{type:e.String_unsecure(),isOptional:!0},taxResidenceCountry:{type:e.String_unsecure(),isOptional:!0},clientType:{type:e.String_unsecure(),isOptional:!0}}}),p=t({name:"RegulatoryContext",description:"Explicit regulatory context (no guessing).",fields:{jurisdiction:{type:e.String_unsecure(),isOptional:!1},region:{type:e.String_unsecure(),isOptional:!0},clientType:{type:e.String_unsecure(),isOptional:!0},allowedScope:{type:i,isOptional:!1}}}),n=t({name:"LLMCallEnvelope",description:"Mandatory envelope for assistant calls. All fields are explicit and required for policy gating.",fields:{traceId:{type:e.String_unsecure(),isOptional:!1},locale:{type:e.String_unsecure(),isOptional:!1},regulatoryContext:{type:p,isOptional:!1},kbSnapshotId:{type:e.String_unsecure(),isOptional:!1},allowedScope:{type:i,isOptional:!1}}}),u=t({name:"AssistantCitation",description:"Citation referencing a KB snapshot + a specific item within it.",fields:{kbSnapshotId:{type:e.String_unsecure(),isOptional:!1},sourceType:{type:e.String_unsecure(),isOptional:!1},sourceId:{type:e.String_unsecure(),isOptional:!1},title:{type:e.String_unsecure(),isOptional:!0},excerpt:{type:e.String_unsecure(),isOptional:!0}}}),c=t({name:"AssistantAnswerSection",description:"Structured answer section.",fields:{heading:{type:e.String_unsecure(),isOptional:!1},body:{type:e.String_unsecure(),isOptional:!1}}}),r=t({name:"AssistantAnswerIR",description:"Structured assistant answer with mandatory citations and explicit locale/jurisdiction.",fields:{locale:{type:e.String_unsecure(),isOptional:!1},jurisdiction:{type:e.String_unsecure(),isOptional:!1},allowedScope:{type:i,isOptional:!1},sections:{type:c,isArray:!0,isOptional:!1},citations:{type:u,isArray:!0,isOptional:!1},disclaimers:{type:e.String_unsecure(),isArray:!0,isOptional:!0},riskFlags:{type:e.String_unsecure(),isArray:!0,isOptional:!0},refused:{type:e.Boolean(),isOptional:!0},refusalReason:{type:e.String_unsecure(),isOptional:!0}}});import{defineCommand as s}from"@contractspec/lib.contracts-spec";import{defineSchemaModel as o,ScalarTypeEnum as a}from"@contractspec/lib.schema";var y=o({name:"AssistantQuestionInput",description:"Input for assistant calls with mandatory envelope.",fields:{envelope:{type:n,isOptional:!1},question:{type:a.String_unsecure(),isOptional:!1}}}),d=o({name:"AssistantConceptInput",description:"Input for explaining a concept with mandatory envelope.",fields:{envelope:{type:n,isOptional:!1},conceptKey:{type:a.String_unsecure(),isOptional:!1}}}),g=s({meta:{key:"assistant.answer",version:"1.0.0",stability:"experimental",owners:["@examples"],tags:["assistant","policy","locale","jurisdiction","knowledge"],description:"Answer a user question using a KB snapshot with strict locale/jurisdiction gating.",goal:"Provide policy-safe answers that cite a KB snapshot or refuse.",context:"Called by UI or workflows; must fail-closed if envelope is invalid or citations are missing."},io:{input:y,output:r,errors:{LOCALE_REQUIRED:{description:"Locale is required and must be supported",http:400,gqlCode:"LOCALE_REQUIRED",when:"locale is missing or unsupported"},JURISDICTION_REQUIRED:{description:"Jurisdiction is required",http:400,gqlCode:"JURISDICTION_REQUIRED",when:"jurisdiction is missing"},KB_SNAPSHOT_REQUIRED:{description:"KB snapshot id is required",http:400,gqlCode:"KB_SNAPSHOT_REQUIRED",when:"kbSnapshotId is missing"},CITATIONS_REQUIRED:{description:"Answers must include citations to a KB snapshot",http:422,gqlCode:"CITATIONS_REQUIRED",when:"answer has no citations"},SCOPE_VIOLATION:{description:"Answer violates allowed scope and must be refused/escalated",http:403,gqlCode:"SCOPE_VIOLATION",when:"output includes forbidden content under the given allowedScope"}}},policy:{auth:"user"}}),A=s({meta:{key:"assistant.explainConcept",version:"1.0.0",stability:"experimental",owners:["@examples"],tags:["assistant","policy","knowledge","concepts"],description:"Explain a concept using a KB snapshot with strict locale/jurisdiction gating.",goal:"Explain concepts with citations or refuse.",context:"Same constraints as assistant.answer."},io:{input:d,output:r,errors:g.io.errors},policy:{auth:"user"}});export{A as AssistantExplainConceptContract,g as AssistantAnswerContract};
@@ -1,192 +1 @@
1
- // src/entities/models.ts
2
- import {
3
- defineEnum,
4
- defineSchemaModel,
5
- ScalarTypeEnum
6
- } from "@contractspec/lib.schema";
7
- var AllowedScopeEnum = defineEnum("AllowedScope", [
8
- "education_only",
9
- "generic_info",
10
- "escalation_required"
11
- ]);
12
- var UserProfileModel = defineSchemaModel({
13
- name: "UserProfile",
14
- description: "User profile inputs used to derive regulatory context.",
15
- fields: {
16
- preferredLocale: {
17
- type: ScalarTypeEnum.String_unsecure(),
18
- isOptional: true
19
- },
20
- residencyCountry: {
21
- type: ScalarTypeEnum.String_unsecure(),
22
- isOptional: true
23
- },
24
- taxResidenceCountry: {
25
- type: ScalarTypeEnum.String_unsecure(),
26
- isOptional: true
27
- },
28
- clientType: { type: ScalarTypeEnum.String_unsecure(), isOptional: true }
29
- }
30
- });
31
- var RegulatoryContextModel = defineSchemaModel({
32
- name: "RegulatoryContext",
33
- description: "Explicit regulatory context (no guessing).",
34
- fields: {
35
- jurisdiction: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
36
- region: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
37
- clientType: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
38
- allowedScope: { type: AllowedScopeEnum, isOptional: false }
39
- }
40
- });
41
- var LLMCallEnvelopeModel = defineSchemaModel({
42
- name: "LLMCallEnvelope",
43
- description: "Mandatory envelope for assistant calls. All fields are explicit and required for policy gating.",
44
- fields: {
45
- traceId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
46
- locale: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
47
- regulatoryContext: { type: RegulatoryContextModel, isOptional: false },
48
- kbSnapshotId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
49
- allowedScope: { type: AllowedScopeEnum, isOptional: false }
50
- }
51
- });
52
- var AssistantCitationModel = defineSchemaModel({
53
- name: "AssistantCitation",
54
- description: "Citation referencing a KB snapshot + a specific item within it.",
55
- fields: {
56
- kbSnapshotId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
57
- sourceType: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
58
- sourceId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
59
- title: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
60
- excerpt: { type: ScalarTypeEnum.String_unsecure(), isOptional: true }
61
- }
62
- });
63
- var AssistantAnswerSectionModel = defineSchemaModel({
64
- name: "AssistantAnswerSection",
65
- description: "Structured answer section.",
66
- fields: {
67
- heading: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
68
- body: { type: ScalarTypeEnum.String_unsecure(), isOptional: false }
69
- }
70
- });
71
- var AssistantAnswerIRModel = defineSchemaModel({
72
- name: "AssistantAnswerIR",
73
- description: "Structured assistant answer with mandatory citations and explicit locale/jurisdiction.",
74
- fields: {
75
- locale: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
76
- jurisdiction: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
77
- allowedScope: { type: AllowedScopeEnum, isOptional: false },
78
- sections: {
79
- type: AssistantAnswerSectionModel,
80
- isArray: true,
81
- isOptional: false
82
- },
83
- citations: {
84
- type: AssistantCitationModel,
85
- isArray: true,
86
- isOptional: false
87
- },
88
- disclaimers: {
89
- type: ScalarTypeEnum.String_unsecure(),
90
- isArray: true,
91
- isOptional: true
92
- },
93
- riskFlags: {
94
- type: ScalarTypeEnum.String_unsecure(),
95
- isArray: true,
96
- isOptional: true
97
- },
98
- refused: { type: ScalarTypeEnum.Boolean(), isOptional: true },
99
- refusalReason: { type: ScalarTypeEnum.String_unsecure(), isOptional: true }
100
- }
101
- });
102
-
103
- // src/operations/assistant.ts
104
- import { defineCommand } from "@contractspec/lib.contracts-spec";
105
- import { defineSchemaModel as defineSchemaModel2, ScalarTypeEnum as ScalarTypeEnum2 } from "@contractspec/lib.schema";
106
- var AssistantQuestionInput = defineSchemaModel2({
107
- name: "AssistantQuestionInput",
108
- description: "Input for assistant calls with mandatory envelope.",
109
- fields: {
110
- envelope: { type: LLMCallEnvelopeModel, isOptional: false },
111
- question: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false }
112
- }
113
- });
114
- var AssistantConceptInput = defineSchemaModel2({
115
- name: "AssistantConceptInput",
116
- description: "Input for explaining a concept with mandatory envelope.",
117
- fields: {
118
- envelope: { type: LLMCallEnvelopeModel, isOptional: false },
119
- conceptKey: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false }
120
- }
121
- });
122
- var AssistantAnswerContract = defineCommand({
123
- meta: {
124
- key: "assistant.answer",
125
- version: "1.0.0",
126
- stability: "experimental",
127
- owners: ["@examples"],
128
- tags: ["assistant", "policy", "locale", "jurisdiction", "knowledge"],
129
- description: "Answer a user question using a KB snapshot with strict locale/jurisdiction gating.",
130
- goal: "Provide policy-safe answers that cite a KB snapshot or refuse.",
131
- context: "Called by UI or workflows; must fail-closed if envelope is invalid or citations are missing."
132
- },
133
- io: {
134
- input: AssistantQuestionInput,
135
- output: AssistantAnswerIRModel,
136
- errors: {
137
- LOCALE_REQUIRED: {
138
- description: "Locale is required and must be supported",
139
- http: 400,
140
- gqlCode: "LOCALE_REQUIRED",
141
- when: "locale is missing or unsupported"
142
- },
143
- JURISDICTION_REQUIRED: {
144
- description: "Jurisdiction is required",
145
- http: 400,
146
- gqlCode: "JURISDICTION_REQUIRED",
147
- when: "jurisdiction is missing"
148
- },
149
- KB_SNAPSHOT_REQUIRED: {
150
- description: "KB snapshot id is required",
151
- http: 400,
152
- gqlCode: "KB_SNAPSHOT_REQUIRED",
153
- when: "kbSnapshotId is missing"
154
- },
155
- CITATIONS_REQUIRED: {
156
- description: "Answers must include citations to a KB snapshot",
157
- http: 422,
158
- gqlCode: "CITATIONS_REQUIRED",
159
- when: "answer has no citations"
160
- },
161
- SCOPE_VIOLATION: {
162
- description: "Answer violates allowed scope and must be refused/escalated",
163
- http: 403,
164
- gqlCode: "SCOPE_VIOLATION",
165
- when: "output includes forbidden content under the given allowedScope"
166
- }
167
- }
168
- },
169
- policy: { auth: "user" }
170
- });
171
- var AssistantExplainConceptContract = defineCommand({
172
- meta: {
173
- key: "assistant.explainConcept",
174
- version: "1.0.0",
175
- stability: "experimental",
176
- owners: ["@examples"],
177
- tags: ["assistant", "policy", "knowledge", "concepts"],
178
- description: "Explain a concept using a KB snapshot with strict locale/jurisdiction gating.",
179
- goal: "Explain concepts with citations or refuse.",
180
- context: "Same constraints as assistant.answer."
181
- },
182
- io: {
183
- input: AssistantConceptInput,
184
- output: AssistantAnswerIRModel,
185
- errors: AssistantAnswerContract.io.errors
186
- },
187
- policy: { auth: "user" }
188
- });
189
- export {
190
- AssistantExplainConceptContract,
191
- AssistantAnswerContract
192
- };
1
+ import{defineEnum as l,defineSchemaModel as t,ScalarTypeEnum as e}from"@contractspec/lib.schema";var i=l("AllowedScope",["education_only","generic_info","escalation_required"]),S=t({name:"UserProfile",description:"User profile inputs used to derive regulatory context.",fields:{preferredLocale:{type:e.String_unsecure(),isOptional:!0},residencyCountry:{type:e.String_unsecure(),isOptional:!0},taxResidenceCountry:{type:e.String_unsecure(),isOptional:!0},clientType:{type:e.String_unsecure(),isOptional:!0}}}),p=t({name:"RegulatoryContext",description:"Explicit regulatory context (no guessing).",fields:{jurisdiction:{type:e.String_unsecure(),isOptional:!1},region:{type:e.String_unsecure(),isOptional:!0},clientType:{type:e.String_unsecure(),isOptional:!0},allowedScope:{type:i,isOptional:!1}}}),n=t({name:"LLMCallEnvelope",description:"Mandatory envelope for assistant calls. All fields are explicit and required for policy gating.",fields:{traceId:{type:e.String_unsecure(),isOptional:!1},locale:{type:e.String_unsecure(),isOptional:!1},regulatoryContext:{type:p,isOptional:!1},kbSnapshotId:{type:e.String_unsecure(),isOptional:!1},allowedScope:{type:i,isOptional:!1}}}),u=t({name:"AssistantCitation",description:"Citation referencing a KB snapshot + a specific item within it.",fields:{kbSnapshotId:{type:e.String_unsecure(),isOptional:!1},sourceType:{type:e.String_unsecure(),isOptional:!1},sourceId:{type:e.String_unsecure(),isOptional:!1},title:{type:e.String_unsecure(),isOptional:!0},excerpt:{type:e.String_unsecure(),isOptional:!0}}}),c=t({name:"AssistantAnswerSection",description:"Structured answer section.",fields:{heading:{type:e.String_unsecure(),isOptional:!1},body:{type:e.String_unsecure(),isOptional:!1}}}),r=t({name:"AssistantAnswerIR",description:"Structured assistant answer with mandatory citations and explicit locale/jurisdiction.",fields:{locale:{type:e.String_unsecure(),isOptional:!1},jurisdiction:{type:e.String_unsecure(),isOptional:!1},allowedScope:{type:i,isOptional:!1},sections:{type:c,isArray:!0,isOptional:!1},citations:{type:u,isArray:!0,isOptional:!1},disclaimers:{type:e.String_unsecure(),isArray:!0,isOptional:!0},riskFlags:{type:e.String_unsecure(),isArray:!0,isOptional:!0},refused:{type:e.Boolean(),isOptional:!0},refusalReason:{type:e.String_unsecure(),isOptional:!0}}});import{defineCommand as s}from"@contractspec/lib.contracts-spec";import{defineSchemaModel as o,ScalarTypeEnum as a}from"@contractspec/lib.schema";var y=o({name:"AssistantQuestionInput",description:"Input for assistant calls with mandatory envelope.",fields:{envelope:{type:n,isOptional:!1},question:{type:a.String_unsecure(),isOptional:!1}}}),d=o({name:"AssistantConceptInput",description:"Input for explaining a concept with mandatory envelope.",fields:{envelope:{type:n,isOptional:!1},conceptKey:{type:a.String_unsecure(),isOptional:!1}}}),g=s({meta:{key:"assistant.answer",version:"1.0.0",stability:"experimental",owners:["@examples"],tags:["assistant","policy","locale","jurisdiction","knowledge"],description:"Answer a user question using a KB snapshot with strict locale/jurisdiction gating.",goal:"Provide policy-safe answers that cite a KB snapshot or refuse.",context:"Called by UI or workflows; must fail-closed if envelope is invalid or citations are missing."},io:{input:y,output:r,errors:{LOCALE_REQUIRED:{description:"Locale is required and must be supported",http:400,gqlCode:"LOCALE_REQUIRED",when:"locale is missing or unsupported"},JURISDICTION_REQUIRED:{description:"Jurisdiction is required",http:400,gqlCode:"JURISDICTION_REQUIRED",when:"jurisdiction is missing"},KB_SNAPSHOT_REQUIRED:{description:"KB snapshot id is required",http:400,gqlCode:"KB_SNAPSHOT_REQUIRED",when:"kbSnapshotId is missing"},CITATIONS_REQUIRED:{description:"Answers must include citations to a KB snapshot",http:422,gqlCode:"CITATIONS_REQUIRED",when:"answer has no citations"},SCOPE_VIOLATION:{description:"Answer violates allowed scope and must be refused/escalated",http:403,gqlCode:"SCOPE_VIOLATION",when:"output includes forbidden content under the given allowedScope"}}},policy:{auth:"user"}}),A=s({meta:{key:"assistant.explainConcept",version:"1.0.0",stability:"experimental",owners:["@examples"],tags:["assistant","policy","knowledge","concepts"],description:"Explain a concept using a KB snapshot with strict locale/jurisdiction gating.",goal:"Explain concepts with citations or refuse.",context:"Same constraints as assistant.answer."},io:{input:d,output:r,errors:g.io.errors},policy:{auth:"user"}});export{A as AssistantExplainConceptContract,g as AssistantAnswerContract};
@@ -1,62 +1 @@
1
- // src/policy/assistant-gate.policy.ts
2
- import {
3
- OwnersEnum,
4
- StabilityEnum,
5
- TagsEnum
6
- } from "@contractspec/lib.contracts-spec/ownership";
7
- import { definePolicy } from "@contractspec/lib.contracts-spec/policy";
8
- var AssistantGatePolicy = definePolicy({
9
- meta: {
10
- key: "locale-jurisdiction-gate.policy.gate",
11
- version: "1.0.0",
12
- title: "Assistant Locale and Jurisdiction Gate",
13
- description: "Requires explicit locale, jurisdiction, knowledge snapshot, and allowed scope before assistant requests may proceed.",
14
- domain: "assistant",
15
- scope: "operation",
16
- owners: [OwnersEnum.PlatformFinance],
17
- tags: [TagsEnum.I18n, "assistant", "policy", "jurisdiction"],
18
- stability: StabilityEnum.Experimental
19
- },
20
- rules: [
21
- {
22
- effect: "deny",
23
- actions: ["assistant.answer", "assistant.explainConcept"],
24
- resource: { type: "assistant-call" },
25
- conditions: [
26
- {
27
- expression: "!context.locale || !context.jurisdiction || !context.kbSnapshotId || !context.allowedScope"
28
- }
29
- ],
30
- reason: "Assistant requests fail closed until locale, jurisdiction, kbSnapshotId, and allowedScope are explicit."
31
- },
32
- {
33
- effect: "deny",
34
- actions: ["assistant.answer", "assistant.explainConcept"],
35
- resource: { type: "assistant-call" },
36
- conditions: [
37
- {
38
- expression: "!['en-US', 'en-GB', 'fr-FR'].includes(context.locale ?? '')"
39
- }
40
- ],
41
- reason: "Only the explicitly reviewed assistant locales are permitted."
42
- },
43
- {
44
- effect: "allow",
45
- actions: ["assistant.answer", "assistant.explainConcept"],
46
- resource: { type: "assistant-call" },
47
- conditions: [
48
- {
49
- expression: "['en-US', 'en-GB', 'fr-FR'].includes(context.locale ?? '') && !!context.jurisdiction && !!context.kbSnapshotId && !!context.allowedScope"
50
- }
51
- ],
52
- reason: "Explicit context is present, so the request may continue to citation and scope validation."
53
- }
54
- ],
55
- pii: {
56
- fields: ["kbSnapshotId"],
57
- retentionDays: 30
58
- }
59
- });
60
- export {
61
- AssistantGatePolicy
62
- };
1
+ import{OwnersEnum as h,StabilityEnum as j,TagsEnum as k}from"@contractspec/lib.contracts-spec/ownership";import{definePolicy as q}from"@contractspec/lib.contracts-spec/policy";var z=q({meta:{key:"locale-jurisdiction-gate.policy.gate",version:"1.0.0",title:"Assistant Locale and Jurisdiction Gate",description:"Requires explicit locale, jurisdiction, knowledge snapshot, and allowed scope before assistant requests may proceed.",domain:"assistant",scope:"operation",owners:[h.PlatformFinance],tags:[k.I18n,"assistant","policy","jurisdiction"],stability:j.Experimental},rules:[{effect:"deny",actions:["assistant.answer","assistant.explainConcept"],resource:{type:"assistant-call"},conditions:[{expression:"!context.locale || !context.jurisdiction || !context.kbSnapshotId || !context.allowedScope"}],reason:"Assistant requests fail closed until locale, jurisdiction, kbSnapshotId, and allowedScope are explicit."},{effect:"deny",actions:["assistant.answer","assistant.explainConcept"],resource:{type:"assistant-call"},conditions:[{expression:"!['en-US', 'en-GB', 'fr-FR'].includes(context.locale ?? '')"}],reason:"Only the explicitly reviewed assistant locales are permitted."},{effect:"allow",actions:["assistant.answer","assistant.explainConcept"],resource:{type:"assistant-call"},conditions:[{expression:"['en-US', 'en-GB', 'fr-FR'].includes(context.locale ?? '') && !!context.jurisdiction && !!context.kbSnapshotId && !!context.allowedScope"}],reason:"Explicit context is present, so the request may continue to citation and scope validation."}],pii:{fields:["kbSnapshotId"],retentionDays:30}});export{z as AssistantGatePolicy};
@@ -1,73 +1,2 @@
1
- // src/policy/guard.ts
2
- var SUPPORTED_LOCALES = new Set(["en-US", "en-GB", "fr-FR"]);
3
- function err(code, message) {
4
- return { code, message };
5
- }
6
- function validateEnvelope(envelope) {
7
- if (!envelope.locale || !SUPPORTED_LOCALES.has(envelope.locale)) {
8
- return {
9
- ok: false,
10
- error: err("LOCALE_REQUIRED", "locale is required and must be supported")
11
- };
12
- }
13
- if (!envelope.regulatoryContext?.jurisdiction) {
14
- return {
15
- ok: false,
16
- error: err("JURISDICTION_REQUIRED", "jurisdiction is required")
17
- };
18
- }
19
- if (!envelope.kbSnapshotId) {
20
- return {
21
- ok: false,
22
- error: err("KB_SNAPSHOT_REQUIRED", "kbSnapshotId is required")
23
- };
24
- }
25
- if (!envelope.allowedScope) {
26
- return {
27
- ok: false,
28
- error: err("SCOPE_VIOLATION", "allowedScope is required")
29
- };
30
- }
31
- return { ok: true, value: envelope };
32
- }
33
- function enforceCitations(answer) {
34
- const citations = answer.citations ?? [];
35
- if (!Array.isArray(citations) || citations.length === 0) {
36
- return {
37
- ok: false,
38
- error: err("CITATIONS_REQUIRED", "answers must include at least one citation")
39
- };
40
- }
41
- return { ok: true, value: answer };
42
- }
43
- var EDUCATION_ONLY_FORBIDDEN_PATTERNS = [
44
- /\b(buy|sell)\b/i,
45
- /\b(should\s+buy|should\s+sell)\b/i,
46
- /\b(guarantee(d)?|promise(d)?)\b/i
47
- ];
48
- function enforceAllowedScope(allowedScope, answer) {
49
- if (!allowedScope) {
50
- return {
51
- ok: false,
52
- error: err("SCOPE_VIOLATION", "allowedScope is required")
53
- };
54
- }
55
- if (allowedScope !== "education_only") {
56
- return { ok: true, value: answer };
57
- }
58
- const bodies = (answer.sections ?? []).map((s) => s.body).join(`
59
- `);
60
- const violations = EDUCATION_ONLY_FORBIDDEN_PATTERNS.some((re) => re.test(bodies));
61
- if (violations) {
62
- return {
63
- ok: false,
64
- error: err("SCOPE_VIOLATION", "answer violates education_only scope (contains actionable or promotional language)")
65
- };
66
- }
67
- return { ok: true, value: answer };
68
- }
69
- export {
70
- validateEnvelope,
71
- enforceCitations,
72
- enforceAllowedScope
73
- };
1
+ var u=new Set(["en-US","en-GB","fr-FR"]);function j(f,h){return{code:f,message:h}}function z(f){if(!f.locale||!u.has(f.locale))return{ok:!1,error:j("LOCALE_REQUIRED","locale is required and must be supported")};if(!f.regulatoryContext?.jurisdiction)return{ok:!1,error:j("JURISDICTION_REQUIRED","jurisdiction is required")};if(!f.kbSnapshotId)return{ok:!1,error:j("KB_SNAPSHOT_REQUIRED","kbSnapshotId is required")};if(!f.allowedScope)return{ok:!1,error:j("SCOPE_VIOLATION","allowedScope is required")};return{ok:!0,value:f}}function G(f){let h=f.citations??[];if(!Array.isArray(h)||h.length===0)return{ok:!1,error:j("CITATIONS_REQUIRED","answers must include at least one citation")};return{ok:!0,value:f}}var x=[/\b(buy|sell)\b/i,/\b(should\s+buy|should\s+sell)\b/i,/\b(guarantee(d)?|promise(d)?)\b/i];function H(f,h){if(!f)return{ok:!1,error:j("SCOPE_VIOLATION","allowedScope is required")};if(f!=="education_only")return{ok:!0,value:h};let q=(h.sections??[]).map((k)=>k.body).join(`
2
+ `);if(x.some((k)=>k.test(q)))return{ok:!1,error:j("SCOPE_VIOLATION","answer violates education_only scope (contains actionable or promotional language)")};return{ok:!0,value:h}}export{z as validateEnvelope,G as enforceCitations,H as enforceAllowedScope};