@contractspec/example.policy-safe-knowledge-assistant 1.44.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.
Files changed (44) hide show
  1. package/.turbo/turbo-build$colon$bundle.log +35 -0
  2. package/.turbo/turbo-build.log +36 -0
  3. package/CHANGELOG.md +365 -0
  4. package/IMPLEMENTATION_SKETCH.md +40 -0
  5. package/LICENSE +21 -0
  6. package/README.md +23 -0
  7. package/dist/docs/index.d.ts +1 -0
  8. package/dist/docs/index.js +1 -0
  9. package/dist/docs/policy-safe-knowledge-assistant.docblock.d.ts +1 -0
  10. package/dist/docs/policy-safe-knowledge-assistant.docblock.js +35 -0
  11. package/dist/docs/policy-safe-knowledge-assistant.docblock.js.map +1 -0
  12. package/dist/example.d.ts +35 -0
  13. package/dist/example.d.ts.map +1 -0
  14. package/dist/example.js +47 -0
  15. package/dist/example.js.map +1 -0
  16. package/dist/feature.d.ts +7 -0
  17. package/dist/feature.d.ts.map +1 -0
  18. package/dist/feature.js +148 -0
  19. package/dist/feature.js.map +1 -0
  20. package/dist/index.d.ts +5 -0
  21. package/dist/index.js +7 -0
  22. package/dist/orchestrator/buildAnswer.d.ts +53 -0
  23. package/dist/orchestrator/buildAnswer.d.ts.map +1 -0
  24. package/dist/orchestrator/buildAnswer.js +77 -0
  25. package/dist/orchestrator/buildAnswer.js.map +1 -0
  26. package/dist/seed/fixtures.d.ts +35 -0
  27. package/dist/seed/fixtures.d.ts.map +1 -0
  28. package/dist/seed/fixtures.js +34 -0
  29. package/dist/seed/fixtures.js.map +1 -0
  30. package/dist/seed/index.d.ts +2 -0
  31. package/dist/seed/index.js +3 -0
  32. package/package.json +77 -0
  33. package/src/docs/index.ts +1 -0
  34. package/src/docs/policy-safe-knowledge-assistant.docblock.ts +28 -0
  35. package/src/example.ts +29 -0
  36. package/src/feature.ts +58 -0
  37. package/src/index.ts +9 -0
  38. package/src/integration.test.ts +108 -0
  39. package/src/orchestrator/buildAnswer.ts +122 -0
  40. package/src/seed/fixtures.ts +31 -0
  41. package/src/seed/index.ts +1 -0
  42. package/tsconfig.json +19 -0
  43. package/tsconfig.tsbuildinfo +1 -0
  44. package/tsdown.config.js +17 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"example.js","names":[],"sources":["../src/example.ts"],"sourcesContent":["const example = {\n id: 'policy-safe-knowledge-assistant',\n title: 'Policy-safe Knowledge Assistant',\n summary:\n 'All-in-one template: locale/jurisdiction gating + versioned KB snapshots + HITL update pipeline + learning hub.',\n tags: ['assistant', 'knowledge', 'policy', 'hitl', 'learning'],\n kind: 'template',\n visibility: 'public',\n docs: {\n goalDocId: 'docs.examples.policy-safe-knowledge-assistant.goal',\n usageDocId: 'docs.examples.policy-safe-knowledge-assistant.usage',\n },\n entrypoints: {\n packageName: '@contractspec/example.policy-safe-knowledge-assistant',\n feature: './feature',\n docs: './docs',\n },\n surfaces: {\n templates: true,\n sandbox: {\n enabled: true,\n modes: ['playground', 'specs', 'builder', 'markdown', 'evolution'],\n },\n studio: { enabled: true, installable: true },\n mcp: { enabled: true },\n },\n} as const;\n\nexport default example;\n"],"mappings":";AAAA,MAAM,UAAU;CACd,IAAI;CACJ,OAAO;CACP,SACE;CACF,MAAM;EAAC;EAAa;EAAa;EAAU;EAAQ;EAAW;CAC9D,MAAM;CACN,YAAY;CACZ,MAAM;EACJ,WAAW;EACX,YAAY;EACb;CACD,aAAa;EACX,aAAa;EACb,SAAS;EACT,MAAM;EACP;CACD,UAAU;EACR,WAAW;EACX,SAAS;GACP,SAAS;GACT,OAAO;IAAC;IAAc;IAAS;IAAW;IAAY;IAAY;GACnE;EACD,QAAQ;GAAE,SAAS;GAAM,aAAa;GAAM;EAC5C,KAAK,EAAE,SAAS,MAAM;EACvB;CACF;AAED,sBAAe"}
@@ -0,0 +1,7 @@
1
+ import { FeatureModuleSpec } from "@contractspec/lib.contracts";
2
+
3
+ //#region src/feature.d.ts
4
+ declare const PolicySafeKnowledgeAssistantFeature: FeatureModuleSpec;
5
+ //#endregion
6
+ export { PolicySafeKnowledgeAssistantFeature };
7
+ //# sourceMappingURL=feature.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feature.d.ts","names":[],"sources":["../src/feature.ts"],"sourcesContent":[],"mappings":";;;cAEa,qCAAqC"}
@@ -0,0 +1,148 @@
1
+ //#region src/feature.ts
2
+ const PolicySafeKnowledgeAssistantFeature = {
3
+ meta: {
4
+ key: "policy-safe-knowledge-assistant",
5
+ version: 1,
6
+ title: "Policy-safe Knowledge Assistant",
7
+ description: "All-in-one example composing locale/jurisdiction gate + versioned KB + HITL pipeline + learning hub.",
8
+ domain: "knowledge",
9
+ owners: ["@examples"],
10
+ tags: [
11
+ "assistant",
12
+ "knowledge",
13
+ "policy",
14
+ "hitl",
15
+ "learning"
16
+ ],
17
+ stability: "experimental"
18
+ },
19
+ operations: [
20
+ {
21
+ key: "assistant.answer",
22
+ version: 1
23
+ },
24
+ {
25
+ key: "assistant.explainConcept",
26
+ version: 1
27
+ },
28
+ {
29
+ key: "kb.ingestSource",
30
+ version: 1
31
+ },
32
+ {
33
+ key: "kb.upsertRuleVersion",
34
+ version: 1
35
+ },
36
+ {
37
+ key: "kb.approveRuleVersion",
38
+ version: 1
39
+ },
40
+ {
41
+ key: "kb.publishSnapshot",
42
+ version: 1
43
+ },
44
+ {
45
+ key: "kb.search",
46
+ version: 1
47
+ },
48
+ {
49
+ key: "kbPipeline.runWatch",
50
+ version: 1
51
+ },
52
+ {
53
+ key: "kbPipeline.createReviewTask",
54
+ version: 1
55
+ },
56
+ {
57
+ key: "kbPipeline.submitDecision",
58
+ version: 1
59
+ },
60
+ {
61
+ key: "kbPipeline.publishIfReady",
62
+ version: 1
63
+ }
64
+ ],
65
+ events: [
66
+ {
67
+ key: "assistant.answer.requested",
68
+ version: 1
69
+ },
70
+ {
71
+ key: "assistant.answer.blocked",
72
+ version: 1
73
+ },
74
+ {
75
+ key: "assistant.answer.delivered",
76
+ version: 1
77
+ },
78
+ {
79
+ key: "kb.source.ingested",
80
+ version: 1
81
+ },
82
+ {
83
+ key: "kb.ruleVersion.created",
84
+ version: 1
85
+ },
86
+ {
87
+ key: "kb.ruleVersion.approved",
88
+ version: 1
89
+ },
90
+ {
91
+ key: "kb.snapshot.published",
92
+ version: 1
93
+ },
94
+ {
95
+ key: "kb.change.detected",
96
+ version: 1
97
+ },
98
+ {
99
+ key: "kb.review.requested",
100
+ version: 1
101
+ },
102
+ {
103
+ key: "kb.review.decided",
104
+ version: 1
105
+ }
106
+ ],
107
+ presentations: [],
108
+ opToPresentation: [],
109
+ presentationsTargets: [],
110
+ capabilities: { requires: [
111
+ {
112
+ key: "identity",
113
+ version: 1
114
+ },
115
+ {
116
+ key: "audit-trail",
117
+ version: 1
118
+ },
119
+ {
120
+ key: "notifications",
121
+ version: 1
122
+ },
123
+ {
124
+ key: "jobs",
125
+ version: 1
126
+ },
127
+ {
128
+ key: "feature-flags",
129
+ version: 1
130
+ },
131
+ {
132
+ key: "files",
133
+ version: 1
134
+ },
135
+ {
136
+ key: "metering",
137
+ version: 1
138
+ },
139
+ {
140
+ key: "learning-journey",
141
+ version: 1
142
+ }
143
+ ] }
144
+ };
145
+
146
+ //#endregion
147
+ export { PolicySafeKnowledgeAssistantFeature };
148
+ //# sourceMappingURL=feature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feature.js","names":["PolicySafeKnowledgeAssistantFeature: FeatureModuleSpec"],"sources":["../src/feature.ts"],"sourcesContent":["import type { FeatureModuleSpec } from '@contractspec/lib.contracts';\n\nexport const PolicySafeKnowledgeAssistantFeature: FeatureModuleSpec = {\n meta: {\n key: 'policy-safe-knowledge-assistant',\n version: 1,\n title: 'Policy-safe Knowledge Assistant',\n description:\n 'All-in-one example composing locale/jurisdiction gate + versioned KB + HITL pipeline + learning hub.',\n domain: 'knowledge',\n owners: ['@examples'],\n tags: ['assistant', 'knowledge', 'policy', 'hitl', 'learning'],\n stability: 'experimental',\n },\n operations: [\n // Gate\n { key: 'assistant.answer', version: 1 },\n { key: 'assistant.explainConcept', version: 1 },\n // KB\n { key: 'kb.ingestSource', version: 1 },\n { key: 'kb.upsertRuleVersion', version: 1 },\n { key: 'kb.approveRuleVersion', version: 1 },\n { key: 'kb.publishSnapshot', version: 1 },\n { key: 'kb.search', version: 1 },\n // Pipeline\n { key: 'kbPipeline.runWatch', version: 1 },\n { key: 'kbPipeline.createReviewTask', version: 1 },\n { key: 'kbPipeline.submitDecision', version: 1 },\n { key: 'kbPipeline.publishIfReady', version: 1 },\n ],\n events: [\n { key: 'assistant.answer.requested', version: 1 },\n { key: 'assistant.answer.blocked', version: 1 },\n { key: 'assistant.answer.delivered', version: 1 },\n { key: 'kb.source.ingested', version: 1 },\n { key: 'kb.ruleVersion.created', version: 1 },\n { key: 'kb.ruleVersion.approved', version: 1 },\n { key: 'kb.snapshot.published', version: 1 },\n { key: 'kb.change.detected', version: 1 },\n { key: 'kb.review.requested', version: 1 },\n { key: 'kb.review.decided', version: 1 },\n ],\n presentations: [],\n opToPresentation: [],\n presentationsTargets: [],\n capabilities: {\n requires: [\n { key: 'identity', version: 1 },\n { key: 'audit-trail', version: 1 },\n { key: 'notifications', version: 1 },\n { key: 'jobs', version: 1 },\n { key: 'feature-flags', version: 1 },\n { key: 'files', version: 1 },\n { key: 'metering', version: 1 },\n { key: 'learning-journey', version: 1 },\n ],\n },\n};\n"],"mappings":";AAEA,MAAaA,sCAAyD;CACpE,MAAM;EACJ,KAAK;EACL,SAAS;EACT,OAAO;EACP,aACE;EACF,QAAQ;EACR,QAAQ,CAAC,YAAY;EACrB,MAAM;GAAC;GAAa;GAAa;GAAU;GAAQ;GAAW;EAC9D,WAAW;EACZ;CACD,YAAY;EAEV;GAAE,KAAK;GAAoB,SAAS;GAAG;EACvC;GAAE,KAAK;GAA4B,SAAS;GAAG;EAE/C;GAAE,KAAK;GAAmB,SAAS;GAAG;EACtC;GAAE,KAAK;GAAwB,SAAS;GAAG;EAC3C;GAAE,KAAK;GAAyB,SAAS;GAAG;EAC5C;GAAE,KAAK;GAAsB,SAAS;GAAG;EACzC;GAAE,KAAK;GAAa,SAAS;GAAG;EAEhC;GAAE,KAAK;GAAuB,SAAS;GAAG;EAC1C;GAAE,KAAK;GAA+B,SAAS;GAAG;EAClD;GAAE,KAAK;GAA6B,SAAS;GAAG;EAChD;GAAE,KAAK;GAA6B,SAAS;GAAG;EACjD;CACD,QAAQ;EACN;GAAE,KAAK;GAA8B,SAAS;GAAG;EACjD;GAAE,KAAK;GAA4B,SAAS;GAAG;EAC/C;GAAE,KAAK;GAA8B,SAAS;GAAG;EACjD;GAAE,KAAK;GAAsB,SAAS;GAAG;EACzC;GAAE,KAAK;GAA0B,SAAS;GAAG;EAC7C;GAAE,KAAK;GAA2B,SAAS;GAAG;EAC9C;GAAE,KAAK;GAAyB,SAAS;GAAG;EAC5C;GAAE,KAAK;GAAsB,SAAS;GAAG;EACzC;GAAE,KAAK;GAAuB,SAAS;GAAG;EAC1C;GAAE,KAAK;GAAqB,SAAS;GAAG;EACzC;CACD,eAAe,EAAE;CACjB,kBAAkB,EAAE;CACpB,sBAAsB,EAAE;CACxB,cAAc,EACZ,UAAU;EACR;GAAE,KAAK;GAAY,SAAS;GAAG;EAC/B;GAAE,KAAK;GAAe,SAAS;GAAG;EAClC;GAAE,KAAK;GAAiB,SAAS;GAAG;EACpC;GAAE,KAAK;GAAQ,SAAS;GAAG;EAC3B;GAAE,KAAK;GAAiB,SAAS;GAAG;EACpC;GAAE,KAAK;GAAS,SAAS;GAAG;EAC5B;GAAE,KAAK;GAAY,SAAS;GAAG;EAC/B;GAAE,KAAK;GAAoB,SAAS;GAAG;EACxC,EACF;CACF"}
@@ -0,0 +1,5 @@
1
+ import example from "./example.js";
2
+ import { PolicySafeKnowledgeAssistantFeature } from "./feature.js";
3
+ import { DEMO_FIXTURES } from "./seed/fixtures.js";
4
+ import { AssistantAnswerIR, BuildAnswerInput, buildPolicySafeAnswer } from "./orchestrator/buildAnswer.js";
5
+ export { AssistantAnswerIR, BuildAnswerInput, DEMO_FIXTURES, PolicySafeKnowledgeAssistantFeature, buildPolicySafeAnswer, example };
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ import example_default from "./example.js";
2
+ import { PolicySafeKnowledgeAssistantFeature } from "./feature.js";
3
+ import { DEMO_FIXTURES } from "./seed/fixtures.js";
4
+ import { buildPolicySafeAnswer } from "./orchestrator/buildAnswer.js";
5
+ import "./docs/index.js";
6
+
7
+ export { DEMO_FIXTURES, PolicySafeKnowledgeAssistantFeature, buildPolicySafeAnswer, example_default as example };
@@ -0,0 +1,53 @@
1
+ //#region src/orchestrator/buildAnswer.d.ts
2
+ type AllowedScope = 'education_only' | 'generic_info' | 'escalation_required';
3
+ interface AssistantAnswerIR {
4
+ locale: string;
5
+ jurisdiction: string;
6
+ allowedScope: AllowedScope;
7
+ sections: {
8
+ heading: string;
9
+ body: string;
10
+ }[];
11
+ citations: {
12
+ kbSnapshotId: string;
13
+ sourceType: string;
14
+ sourceId: string;
15
+ title?: string;
16
+ excerpt?: string;
17
+ }[];
18
+ disclaimers?: string[];
19
+ riskFlags?: string[];
20
+ refused?: boolean;
21
+ refusalReason?: string;
22
+ }
23
+ interface BuildAnswerInput {
24
+ envelope: {
25
+ traceId: string;
26
+ locale: string;
27
+ kbSnapshotId: string;
28
+ allowedScope: AllowedScope;
29
+ regulatoryContext: {
30
+ jurisdiction: string;
31
+ };
32
+ };
33
+ question: string;
34
+ kbSearch: (input: {
35
+ snapshotId: string;
36
+ jurisdiction: string;
37
+ query: string;
38
+ }) => Promise<{
39
+ items: {
40
+ ruleVersionId: string;
41
+ excerpt?: string;
42
+ }[];
43
+ }>;
44
+ }
45
+ /**
46
+ * Build a policy-safe assistant answer derived from KB search results.
47
+ *
48
+ * Deterministic: no LLM calls; if search yields no results, it refuses.
49
+ */
50
+ declare function buildPolicySafeAnswer(input: BuildAnswerInput): Promise<AssistantAnswerIR>;
51
+ //#endregion
52
+ export { AssistantAnswerIR, BuildAnswerInput, buildPolicySafeAnswer };
53
+ //# sourceMappingURL=buildAnswer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildAnswer.d.ts","names":[],"sources":["../../src/orchestrator/buildAnswer.ts"],"sourcesContent":[],"mappings":";KAMK,YAAA;AAAA,UAEY,iBAAA,CAFA;EAEA,MAAA,EAAA,MAAA;EAkBA,YAAA,EAAA,MAAgB;EAqBX,YAAA,EApCN,YAoC2B;EAClC,QAAA,EAAA;IACE,OAAA,EAAA,MAAA;IAAR,IAAA,EAAA,MAAA;EAAO,CAAA,EAAA;;;;;;;;;;;;;UAvBO,gBAAA;;;;;kBAKC;;;;;;;;;;QAQV;;;;;;;;;;;;iBAQc,qBAAA,QACb,mBACN,QAAQ"}
@@ -0,0 +1,77 @@
1
+ import { enforceAllowedScope, enforceCitations, validateEnvelope } from "@contractspec/example.locale-jurisdiction-gate/policy/guard";
2
+
3
+ //#region src/orchestrator/buildAnswer.ts
4
+ /**
5
+ * Build a policy-safe assistant answer derived from KB search results.
6
+ *
7
+ * Deterministic: no LLM calls; if search yields no results, it refuses.
8
+ */
9
+ async function buildPolicySafeAnswer(input) {
10
+ const env = validateEnvelope(input.envelope);
11
+ if (!env.ok) return {
12
+ locale: input.envelope.locale ?? "en-GB",
13
+ jurisdiction: input.envelope.regulatoryContext?.jurisdiction ?? "UNKNOWN",
14
+ allowedScope: input.envelope.allowedScope ?? "education_only",
15
+ sections: [{
16
+ heading: "Request blocked",
17
+ body: env.error.message
18
+ }],
19
+ citations: [],
20
+ disclaimers: ["This system refuses to answer without a valid envelope."],
21
+ riskFlags: [env.error.code],
22
+ refused: true,
23
+ refusalReason: env.error.code
24
+ };
25
+ const results = await input.kbSearch({
26
+ snapshotId: env.value.kbSnapshotId,
27
+ jurisdiction: env.value.regulatoryContext?.jurisdiction ?? "UNKNOWN",
28
+ query: input.question
29
+ });
30
+ const citations = results.items.map((item) => ({
31
+ kbSnapshotId: env.value.kbSnapshotId,
32
+ sourceType: "ruleVersion",
33
+ sourceId: item.ruleVersionId,
34
+ title: "Curated rule version",
35
+ excerpt: item.excerpt
36
+ }));
37
+ const draft = {
38
+ locale: env.value.locale,
39
+ jurisdiction: env.value.regulatoryContext?.jurisdiction ?? "UNKNOWN",
40
+ allowedScope: env.value.allowedScope,
41
+ sections: [{
42
+ heading: "Answer (KB-derived)",
43
+ body: results.items.length > 0 ? `This answer is derived from ${results.items.length} curated rule version(s) in the referenced snapshot.` : "No curated knowledge found in the referenced snapshot."
44
+ }],
45
+ citations,
46
+ disclaimers: ["Educational demo only."],
47
+ riskFlags: []
48
+ };
49
+ const scope = enforceAllowedScope(env.value.allowedScope, draft);
50
+ if (!scope.ok) return {
51
+ ...draft,
52
+ sections: [{
53
+ heading: "Escalation required",
54
+ body: scope.error.message
55
+ }],
56
+ refused: true,
57
+ refusalReason: scope.error.code,
58
+ riskFlags: [...draft.riskFlags ?? [], scope.error.code]
59
+ };
60
+ const cited = enforceCitations(draft);
61
+ if (!cited.ok) return {
62
+ ...draft,
63
+ sections: [{
64
+ heading: "Request blocked",
65
+ body: cited.error.message
66
+ }],
67
+ citations: [],
68
+ refused: true,
69
+ refusalReason: cited.error.code,
70
+ riskFlags: [...draft.riskFlags ?? [], cited.error.code]
71
+ };
72
+ return draft;
73
+ }
74
+
75
+ //#endregion
76
+ export { buildPolicySafeAnswer };
77
+ //# sourceMappingURL=buildAnswer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildAnswer.js","names":["draft: AssistantAnswerIR"],"sources":["../../src/orchestrator/buildAnswer.ts"],"sourcesContent":["import {\n enforceAllowedScope,\n enforceCitations,\n validateEnvelope,\n} from '@contractspec/example.locale-jurisdiction-gate/policy/guard';\n\ntype AllowedScope = 'education_only' | 'generic_info' | 'escalation_required';\n\nexport interface AssistantAnswerIR {\n locale: string;\n jurisdiction: string;\n allowedScope: AllowedScope;\n sections: { heading: string; body: string }[];\n citations: {\n kbSnapshotId: string;\n sourceType: string;\n sourceId: string;\n title?: string;\n excerpt?: string;\n }[];\n disclaimers?: string[];\n riskFlags?: string[];\n refused?: boolean;\n refusalReason?: string;\n}\n\nexport interface BuildAnswerInput {\n envelope: {\n traceId: string;\n locale: string;\n kbSnapshotId: string;\n allowedScope: AllowedScope;\n regulatoryContext: { jurisdiction: string };\n };\n question: string;\n kbSearch: (input: {\n snapshotId: string;\n jurisdiction: string;\n query: string;\n }) => Promise<{ items: { ruleVersionId: string; excerpt?: string }[] }>;\n}\n\n/**\n * Build a policy-safe assistant answer derived from KB search results.\n *\n * Deterministic: no LLM calls; if search yields no results, it refuses.\n */\nexport async function buildPolicySafeAnswer(\n input: BuildAnswerInput\n): Promise<AssistantAnswerIR> {\n const env = validateEnvelope(input.envelope);\n if (!env.ok) {\n return {\n locale: input.envelope.locale ?? 'en-GB',\n jurisdiction: input.envelope.regulatoryContext?.jurisdiction ?? 'UNKNOWN',\n allowedScope: input.envelope.allowedScope ?? 'education_only',\n sections: [{ heading: 'Request blocked', body: env.error.message }],\n citations: [],\n disclaimers: ['This system refuses to answer without a valid envelope.'],\n riskFlags: [env.error.code],\n refused: true,\n refusalReason: env.error.code,\n };\n }\n\n const results = await input.kbSearch({\n snapshotId: env.value.kbSnapshotId,\n jurisdiction: env.value.regulatoryContext?.jurisdiction ?? 'UNKNOWN',\n query: input.question,\n });\n\n const citations = results.items.map((item) => ({\n kbSnapshotId: env.value.kbSnapshotId,\n sourceType: 'ruleVersion',\n sourceId: item.ruleVersionId,\n title: 'Curated rule version',\n excerpt: item.excerpt,\n }));\n\n const draft: AssistantAnswerIR = {\n locale: env.value.locale,\n jurisdiction: env.value.regulatoryContext?.jurisdiction ?? 'UNKNOWN',\n allowedScope: env.value.allowedScope,\n sections: [\n {\n heading: 'Answer (KB-derived)',\n body:\n results.items.length > 0\n ? `This answer is derived from ${results.items.length} curated rule version(s) in the referenced snapshot.`\n : 'No curated knowledge found in the referenced snapshot.',\n },\n ],\n citations,\n disclaimers: ['Educational demo only.'],\n riskFlags: [],\n };\n\n const scope = enforceAllowedScope(env.value.allowedScope, draft);\n if (!scope.ok) {\n return {\n ...draft,\n sections: [{ heading: 'Escalation required', body: scope.error.message }],\n refused: true,\n refusalReason: scope.error.code,\n riskFlags: [...(draft.riskFlags ?? []), scope.error.code],\n };\n }\n\n const cited = enforceCitations(draft);\n if (!cited.ok) {\n return {\n ...draft,\n sections: [{ heading: 'Request blocked', body: cited.error.message }],\n citations: [],\n refused: true,\n refusalReason: cited.error.code,\n riskFlags: [...(draft.riskFlags ?? []), cited.error.code],\n };\n }\n\n return draft;\n}\n"],"mappings":";;;;;;;;AA+CA,eAAsB,sBACpB,OAC4B;CAC5B,MAAM,MAAM,iBAAiB,MAAM,SAAS;AAC5C,KAAI,CAAC,IAAI,GACP,QAAO;EACL,QAAQ,MAAM,SAAS,UAAU;EACjC,cAAc,MAAM,SAAS,mBAAmB,gBAAgB;EAChE,cAAc,MAAM,SAAS,gBAAgB;EAC7C,UAAU,CAAC;GAAE,SAAS;GAAmB,MAAM,IAAI,MAAM;GAAS,CAAC;EACnE,WAAW,EAAE;EACb,aAAa,CAAC,0DAA0D;EACxE,WAAW,CAAC,IAAI,MAAM,KAAK;EAC3B,SAAS;EACT,eAAe,IAAI,MAAM;EAC1B;CAGH,MAAM,UAAU,MAAM,MAAM,SAAS;EACnC,YAAY,IAAI,MAAM;EACtB,cAAc,IAAI,MAAM,mBAAmB,gBAAgB;EAC3D,OAAO,MAAM;EACd,CAAC;CAEF,MAAM,YAAY,QAAQ,MAAM,KAAK,UAAU;EAC7C,cAAc,IAAI,MAAM;EACxB,YAAY;EACZ,UAAU,KAAK;EACf,OAAO;EACP,SAAS,KAAK;EACf,EAAE;CAEH,MAAMA,QAA2B;EAC/B,QAAQ,IAAI,MAAM;EAClB,cAAc,IAAI,MAAM,mBAAmB,gBAAgB;EAC3D,cAAc,IAAI,MAAM;EACxB,UAAU,CACR;GACE,SAAS;GACT,MACE,QAAQ,MAAM,SAAS,IACnB,+BAA+B,QAAQ,MAAM,OAAO,wDACpD;GACP,CACF;EACD;EACA,aAAa,CAAC,yBAAyB;EACvC,WAAW,EAAE;EACd;CAED,MAAM,QAAQ,oBAAoB,IAAI,MAAM,cAAc,MAAM;AAChE,KAAI,CAAC,MAAM,GACT,QAAO;EACL,GAAG;EACH,UAAU,CAAC;GAAE,SAAS;GAAuB,MAAM,MAAM,MAAM;GAAS,CAAC;EACzE,SAAS;EACT,eAAe,MAAM,MAAM;EAC3B,WAAW,CAAC,GAAI,MAAM,aAAa,EAAE,EAAG,MAAM,MAAM,KAAK;EAC1D;CAGH,MAAM,QAAQ,iBAAiB,MAAM;AACrC,KAAI,CAAC,MAAM,GACT,QAAO;EACL,GAAG;EACH,UAAU,CAAC;GAAE,SAAS;GAAmB,MAAM,MAAM,MAAM;GAAS,CAAC;EACrE,WAAW,EAAE;EACb,SAAS;EACT,eAAe,MAAM,MAAM;EAC3B,WAAW,CAAC,GAAI,MAAM,aAAa,EAAE,EAAG,MAAM,MAAM,KAAK;EAC1D;AAGH,QAAO"}
@@ -0,0 +1,35 @@
1
+ //#region src/seed/fixtures.d.ts
2
+ declare const DEMO_FIXTURES: {
3
+ readonly jurisdictions: readonly ["EU", "FR"];
4
+ readonly locales: readonly ["en-GB", "fr-FR"];
5
+ readonly demoOrgId: "org_demo";
6
+ readonly demoUserId: "user_demo";
7
+ readonly sources: {
8
+ readonly EU_SOURCE_1: {
9
+ readonly jurisdiction: "EU";
10
+ readonly authority: "DemoAuthority";
11
+ readonly title: "EU Demo Source v1";
12
+ readonly fetchedAt: Date;
13
+ readonly hash: "hash_eu_v1";
14
+ readonly fileId: "file_eu_v1";
15
+ };
16
+ readonly EU_SOURCE_2: {
17
+ readonly jurisdiction: "EU";
18
+ readonly authority: "DemoAuthority";
19
+ readonly title: "EU Demo Source v2";
20
+ readonly fetchedAt: Date;
21
+ readonly hash: "hash_eu_v2";
22
+ readonly fileId: "file_eu_v2";
23
+ };
24
+ };
25
+ readonly rules: {
26
+ readonly EU_RULE_TAX: {
27
+ readonly id: "rule_eu_tax";
28
+ readonly jurisdiction: "EU";
29
+ readonly topicKey: "tax_reporting";
30
+ };
31
+ };
32
+ };
33
+ //#endregion
34
+ export { DEMO_FIXTURES };
35
+ //# sourceMappingURL=fixtures.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fixtures.d.ts","names":[],"sources":["../../src/seed/fixtures.ts"],"sourcesContent":[],"mappings":";cAAa;EAAA,SAAA,aA8BH,EAAA,SAAA,CAAA,IAAA,EAAA,IAAA,CAAA;;;;;;;;;0BAAA;;;;;;;;0BAAA"}
@@ -0,0 +1,34 @@
1
+ //#region src/seed/fixtures.ts
2
+ const DEMO_FIXTURES = {
3
+ jurisdictions: ["EU", "FR"],
4
+ locales: ["en-GB", "fr-FR"],
5
+ demoOrgId: "org_demo",
6
+ demoUserId: "user_demo",
7
+ sources: {
8
+ EU_SOURCE_1: {
9
+ jurisdiction: "EU",
10
+ authority: "DemoAuthority",
11
+ title: "EU Demo Source v1",
12
+ fetchedAt: /* @__PURE__ */ new Date("2026-01-01T00:00:00.000Z"),
13
+ hash: "hash_eu_v1",
14
+ fileId: "file_eu_v1"
15
+ },
16
+ EU_SOURCE_2: {
17
+ jurisdiction: "EU",
18
+ authority: "DemoAuthority",
19
+ title: "EU Demo Source v2",
20
+ fetchedAt: /* @__PURE__ */ new Date("2026-02-01T00:00:00.000Z"),
21
+ hash: "hash_eu_v2",
22
+ fileId: "file_eu_v2"
23
+ }
24
+ },
25
+ rules: { EU_RULE_TAX: {
26
+ id: "rule_eu_tax",
27
+ jurisdiction: "EU",
28
+ topicKey: "tax_reporting"
29
+ } }
30
+ };
31
+
32
+ //#endregion
33
+ export { DEMO_FIXTURES };
34
+ //# sourceMappingURL=fixtures.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fixtures.js","names":[],"sources":["../../src/seed/fixtures.ts"],"sourcesContent":["export const DEMO_FIXTURES = {\n jurisdictions: ['EU', 'FR'] as const,\n locales: ['en-GB', 'fr-FR'] as const,\n demoOrgId: 'org_demo',\n demoUserId: 'user_demo',\n sources: {\n EU_SOURCE_1: {\n jurisdiction: 'EU',\n authority: 'DemoAuthority',\n title: 'EU Demo Source v1',\n fetchedAt: new Date('2026-01-01T00:00:00.000Z'),\n hash: 'hash_eu_v1',\n fileId: 'file_eu_v1',\n },\n EU_SOURCE_2: {\n jurisdiction: 'EU',\n authority: 'DemoAuthority',\n title: 'EU Demo Source v2',\n fetchedAt: new Date('2026-02-01T00:00:00.000Z'),\n hash: 'hash_eu_v2',\n fileId: 'file_eu_v2',\n },\n },\n rules: {\n EU_RULE_TAX: {\n id: 'rule_eu_tax',\n jurisdiction: 'EU',\n topicKey: 'tax_reporting',\n },\n },\n} as const;\n"],"mappings":";AAAA,MAAa,gBAAgB;CAC3B,eAAe,CAAC,MAAM,KAAK;CAC3B,SAAS,CAAC,SAAS,QAAQ;CAC3B,WAAW;CACX,YAAY;CACZ,SAAS;EACP,aAAa;GACX,cAAc;GACd,WAAW;GACX,OAAO;GACP,2BAAW,IAAI,KAAK,2BAA2B;GAC/C,MAAM;GACN,QAAQ;GACT;EACD,aAAa;GACX,cAAc;GACd,WAAW;GACX,OAAO;GACP,2BAAW,IAAI,KAAK,2BAA2B;GAC/C,MAAM;GACN,QAAQ;GACT;EACF;CACD,OAAO,EACL,aAAa;EACX,IAAI;EACJ,cAAc;EACd,UAAU;EACX,EACF;CACF"}
@@ -0,0 +1,2 @@
1
+ import { DEMO_FIXTURES } from "./fixtures.js";
2
+ export { DEMO_FIXTURES };
@@ -0,0 +1,3 @@
1
+ import { DEMO_FIXTURES } from "./fixtures.js";
2
+
3
+ export { DEMO_FIXTURES };
package/package.json ADDED
@@ -0,0 +1,77 @@
1
+ {
2
+ "name": "@contractspec/example.policy-safe-knowledge-assistant",
3
+ "version": "1.44.0",
4
+ "description": "All-in-one template example: policy-safe knowledge assistant with locale/jurisdiction gating, versioned KB snapshots, HITL update pipeline, and learning hub.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": "./dist/index.js",
11
+ "./docs": "./dist/docs/index.js",
12
+ "./docs/policy-safe-knowledge-assistant.docblock": "./dist/docs/policy-safe-knowledge-assistant.docblock.js",
13
+ "./example": "./dist/example.js",
14
+ "./feature": "./dist/feature.js",
15
+ "./orchestrator/buildAnswer": "./dist/orchestrator/buildAnswer.js",
16
+ "./seed": "./dist/seed/index.js",
17
+ "./seed/fixtures": "./dist/seed/fixtures.js",
18
+ "./*": "./*"
19
+ },
20
+ "scripts": {
21
+ "publish:pkg": "bun publish --tolerate-republish --ignore-scripts --verbose",
22
+ "publish:pkg:canary": "bun publish:pkg --tag canary",
23
+ "build": "bun build:types && bun build:bundle",
24
+ "build:bundle": "tsdown",
25
+ "build:types": "tsc --noEmit",
26
+ "dev": "bun build:bundle --watch",
27
+ "clean": "rimraf dist .turbo",
28
+ "lint": "bun lint:fix",
29
+ "lint:fix": "eslint src --fix",
30
+ "lint:check": "eslint src",
31
+ "test": "bun test"
32
+ },
33
+ "dependencies": {
34
+ "@contractspec/example.locale-jurisdiction-gate": "1.44.0",
35
+ "@contractspec/example.versioned-knowledge-base": "1.44.0",
36
+ "@contractspec/example.kb-update-pipeline": "1.44.0",
37
+ "@contractspec/example.learning-patterns": "1.44.0",
38
+ "@contractspec/lib.schema": "1.44.0",
39
+ "@contractspec/lib.contracts": "1.44.0",
40
+ "@contractspec/lib.identity-rbac": "1.44.0",
41
+ "@contractspec/lib.jobs": "1.44.0",
42
+ "@contractspec/lib.feature-flags": "1.44.0",
43
+ "@contractspec/lib.files": "1.44.0",
44
+ "@contractspec/lib.metering": "1.44.0",
45
+ "@contractspec/module.audit-trail": "1.44.0",
46
+ "@contractspec/module.notifications": "1.44.0",
47
+ "@contractspec/module.learning-journey": "1.44.0"
48
+ },
49
+ "devDependencies": {
50
+ "@contractspec/tool.tsdown": "1.44.0",
51
+ "@contractspec/tool.typescript": "1.44.0",
52
+ "tsdown": "^0.18.3",
53
+ "typescript": "^5.9.3"
54
+ },
55
+ "publishConfig": {
56
+ "access": "public",
57
+ "exports": {
58
+ ".": "./dist/index.js",
59
+ "./docs": "./dist/docs/index.js",
60
+ "./docs/policy-safe-knowledge-assistant.docblock": "./dist/docs/policy-safe-knowledge-assistant.docblock.js",
61
+ "./example": "./dist/example.js",
62
+ "./feature": "./dist/feature.js",
63
+ "./orchestrator/buildAnswer": "./dist/orchestrator/buildAnswer.js",
64
+ "./seed": "./dist/seed/index.js",
65
+ "./seed/fixtures": "./dist/seed/fixtures.js",
66
+ "./*": "./*"
67
+ },
68
+ "registry": "https://registry.npmjs.org/"
69
+ },
70
+ "license": "MIT",
71
+ "repository": {
72
+ "type": "git",
73
+ "url": "https://github.com/lssm-tech/contractspec.git",
74
+ "directory": "packages/examples/policy-safe-knowledge-assistant"
75
+ },
76
+ "homepage": "https://contractspec.io"
77
+ }
@@ -0,0 +1 @@
1
+ import './policy-safe-knowledge-assistant.docblock';
@@ -0,0 +1,28 @@
1
+ import type { DocBlock } from '@contractspec/lib.contracts/docs';
2
+ import { registerDocBlocks } from '@contractspec/lib.contracts/docs';
3
+
4
+ const docBlocks: DocBlock[] = [
5
+ {
6
+ id: 'docs.examples.policy-safe-knowledge-assistant.goal',
7
+ title: 'Policy-safe Knowledge Assistant — Goal',
8
+ summary:
9
+ 'End-to-end example: versioned KB snapshots + locale/jurisdiction gating + HITL pipeline + learning hub.',
10
+ kind: 'goal',
11
+ visibility: 'public',
12
+ route: '/docs/examples/policy-safe-knowledge-assistant/goal',
13
+ tags: ['assistant', 'knowledge', 'policy', 'hitl', 'learning'],
14
+ body: `## What this template proves\n- Assistant answers are structured and must cite a KB snapshot (or refuse).\n- Locale + jurisdiction are mandatory inputs for every assistant call.\n- Automation proposes KB patches; humans verify; publishing stays blocked until approvals.\n- Learning hub demonstrates drills + coaching + quests without spam.\n\n## Offline-first\n- Seeded fixtures are deterministic and require no external services.\n- Optional non-authoritative fallback can be added behind a single feature flag (disabled by default).`,
15
+ },
16
+ {
17
+ id: 'docs.examples.policy-safe-knowledge-assistant.usage',
18
+ title: 'Policy-safe Knowledge Assistant — Usage',
19
+ summary: '5–10 minute sandbox walkthrough for developers.',
20
+ kind: 'usage',
21
+ visibility: 'public',
22
+ route: '/docs/examples/policy-safe-knowledge-assistant/usage',
23
+ tags: ['assistant', 'knowledge', 'usage'],
24
+ body: `## Demo walkthrough (high level)\n1) Onboard: set locale + jurisdiction.\n2) Publish snapshot: ingest source -> propose rule -> approve -> publish.\n3) Ask assistant: must pass gate and cite snapshot.\n4) Simulate change: watcher -> review -> publish new snapshot.\n5) Learning hub: drills session, ambient tip, quest start + step completion.`,
25
+ },
26
+ ];
27
+
28
+ registerDocBlocks(docBlocks);
package/src/example.ts ADDED
@@ -0,0 +1,29 @@
1
+ const example = {
2
+ id: 'policy-safe-knowledge-assistant',
3
+ title: 'Policy-safe Knowledge Assistant',
4
+ summary:
5
+ 'All-in-one template: locale/jurisdiction gating + versioned KB snapshots + HITL update pipeline + learning hub.',
6
+ tags: ['assistant', 'knowledge', 'policy', 'hitl', 'learning'],
7
+ kind: 'template',
8
+ visibility: 'public',
9
+ docs: {
10
+ goalDocId: 'docs.examples.policy-safe-knowledge-assistant.goal',
11
+ usageDocId: 'docs.examples.policy-safe-knowledge-assistant.usage',
12
+ },
13
+ entrypoints: {
14
+ packageName: '@contractspec/example.policy-safe-knowledge-assistant',
15
+ feature: './feature',
16
+ docs: './docs',
17
+ },
18
+ surfaces: {
19
+ templates: true,
20
+ sandbox: {
21
+ enabled: true,
22
+ modes: ['playground', 'specs', 'builder', 'markdown', 'evolution'],
23
+ },
24
+ studio: { enabled: true, installable: true },
25
+ mcp: { enabled: true },
26
+ },
27
+ } as const;
28
+
29
+ export default example;
package/src/feature.ts ADDED
@@ -0,0 +1,58 @@
1
+ import type { FeatureModuleSpec } from '@contractspec/lib.contracts';
2
+
3
+ export const PolicySafeKnowledgeAssistantFeature: FeatureModuleSpec = {
4
+ meta: {
5
+ key: 'policy-safe-knowledge-assistant',
6
+ version: 1,
7
+ title: 'Policy-safe Knowledge Assistant',
8
+ description:
9
+ 'All-in-one example composing locale/jurisdiction gate + versioned KB + HITL pipeline + learning hub.',
10
+ domain: 'knowledge',
11
+ owners: ['@examples'],
12
+ tags: ['assistant', 'knowledge', 'policy', 'hitl', 'learning'],
13
+ stability: 'experimental',
14
+ },
15
+ operations: [
16
+ // Gate
17
+ { key: 'assistant.answer', version: 1 },
18
+ { key: 'assistant.explainConcept', version: 1 },
19
+ // KB
20
+ { key: 'kb.ingestSource', version: 1 },
21
+ { key: 'kb.upsertRuleVersion', version: 1 },
22
+ { key: 'kb.approveRuleVersion', version: 1 },
23
+ { key: 'kb.publishSnapshot', version: 1 },
24
+ { key: 'kb.search', version: 1 },
25
+ // Pipeline
26
+ { key: 'kbPipeline.runWatch', version: 1 },
27
+ { key: 'kbPipeline.createReviewTask', version: 1 },
28
+ { key: 'kbPipeline.submitDecision', version: 1 },
29
+ { key: 'kbPipeline.publishIfReady', version: 1 },
30
+ ],
31
+ events: [
32
+ { key: 'assistant.answer.requested', version: 1 },
33
+ { key: 'assistant.answer.blocked', version: 1 },
34
+ { key: 'assistant.answer.delivered', version: 1 },
35
+ { key: 'kb.source.ingested', version: 1 },
36
+ { key: 'kb.ruleVersion.created', version: 1 },
37
+ { key: 'kb.ruleVersion.approved', version: 1 },
38
+ { key: 'kb.snapshot.published', version: 1 },
39
+ { key: 'kb.change.detected', version: 1 },
40
+ { key: 'kb.review.requested', version: 1 },
41
+ { key: 'kb.review.decided', version: 1 },
42
+ ],
43
+ presentations: [],
44
+ opToPresentation: [],
45
+ presentationsTargets: [],
46
+ capabilities: {
47
+ requires: [
48
+ { key: 'identity', version: 1 },
49
+ { key: 'audit-trail', version: 1 },
50
+ { key: 'notifications', version: 1 },
51
+ { key: 'jobs', version: 1 },
52
+ { key: 'feature-flags', version: 1 },
53
+ { key: 'files', version: 1 },
54
+ { key: 'metering', version: 1 },
55
+ { key: 'learning-journey', version: 1 },
56
+ ],
57
+ },
58
+ };
package/src/index.ts ADDED
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Policy-safe Knowledge Assistant (all-in-one template) — spec-first exports.
3
+ */
4
+ export * from './feature';
5
+ export * from './seed';
6
+ export * from './orchestrator/buildAnswer';
7
+ export { default as example } from './example';
8
+
9
+ import './docs';