@contractspec/example.policy-safe-knowledge-assistant 0.0.0-canary-20260113170453
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build$colon$bundle.log +55 -0
- package/.turbo/turbo-build.log +56 -0
- package/CHANGELOG.md +585 -0
- package/LICENSE +21 -0
- package/README.md +22 -0
- package/dist/docs/index.d.ts +1 -0
- package/dist/docs/index.js +1 -0
- package/dist/docs/policy-safe-knowledge-assistant.docblock.d.ts +1 -0
- package/dist/docs/policy-safe-knowledge-assistant.docblock.js +35 -0
- package/dist/docs/policy-safe-knowledge-assistant.docblock.js.map +1 -0
- package/dist/example.d.ts +7 -0
- package/dist/example.d.ts.map +1 -0
- package/dist/example.js +54 -0
- package/dist/example.js.map +1 -0
- package/dist/handlers/index.d.ts +2 -0
- package/dist/handlers/index.js +3 -0
- package/dist/handlers/policy-safe-knowledge-assistant.handlers.d.ts +127 -0
- package/dist/handlers/policy-safe-knowledge-assistant.handlers.d.ts.map +1 -0
- package/dist/handlers/policy-safe-knowledge-assistant.handlers.js +264 -0
- package/dist/handlers/policy-safe-knowledge-assistant.handlers.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +10 -0
- package/dist/orchestrator/buildAnswer.d.ts +53 -0
- package/dist/orchestrator/buildAnswer.d.ts.map +1 -0
- package/dist/orchestrator/buildAnswer.js +77 -0
- package/dist/orchestrator/buildAnswer.js.map +1 -0
- package/dist/policy-safe-knowledge-assistant.feature.d.ts +7 -0
- package/dist/policy-safe-knowledge-assistant.feature.d.ts.map +1 -0
- package/dist/policy-safe-knowledge-assistant.feature.js +150 -0
- package/dist/policy-safe-knowledge-assistant.feature.js.map +1 -0
- package/dist/seed/fixtures.d.ts +35 -0
- package/dist/seed/fixtures.d.ts.map +1 -0
- package/dist/seed/fixtures.js +34 -0
- package/dist/seed/fixtures.js.map +1 -0
- package/dist/seed/index.d.ts +2 -0
- package/dist/seed/index.js +3 -0
- package/dist/seeders/index.d.ts +10 -0
- package/dist/seeders/index.d.ts.map +1 -0
- package/dist/seeders/index.js +16 -0
- package/dist/seeders/index.js.map +1 -0
- package/dist/ui/PolicySafeKnowledgeAssistantDashboard.d.ts +7 -0
- package/dist/ui/PolicySafeKnowledgeAssistantDashboard.d.ts.map +1 -0
- package/dist/ui/PolicySafeKnowledgeAssistantDashboard.js +231 -0
- package/dist/ui/PolicySafeKnowledgeAssistantDashboard.js.map +1 -0
- package/dist/ui/hooks/usePolicySafeKnowledgeAssistant.d.ts +55 -0
- package/dist/ui/hooks/usePolicySafeKnowledgeAssistant.d.ts.map +1 -0
- package/dist/ui/hooks/usePolicySafeKnowledgeAssistant.js +193 -0
- package/dist/ui/hooks/usePolicySafeKnowledgeAssistant.js.map +1 -0
- package/dist/ui/index.d.ts +2 -0
- package/dist/ui/index.js +3 -0
- package/package.json +81 -0
- package/src/docs/index.ts +1 -0
- package/src/docs/policy-safe-knowledge-assistant.docblock.ts +28 -0
- package/src/example.ts +36 -0
- package/src/handlers/index.ts +1 -0
- package/src/handlers/policy-safe-knowledge-assistant.handlers.ts +476 -0
- package/src/index.ts +11 -0
- package/src/integration.test.ts +108 -0
- package/src/orchestrator/buildAnswer.ts +122 -0
- package/src/policy-safe-knowledge-assistant.feature.ts +58 -0
- package/src/seed/fixtures.ts +31 -0
- package/src/seed/index.ts +1 -0
- package/src/seeders/index.ts +20 -0
- package/src/ui/PolicySafeKnowledgeAssistantDashboard.tsx +206 -0
- package/src/ui/hooks/usePolicySafeKnowledgeAssistant.ts +229 -0
- package/src/ui/index.ts +1 -0
- package/tsconfig.json +19 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/tsdown.config.js +17 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
4
|
+
import { useTemplateRuntime } from "@contractspec/lib.example-shared-ui";
|
|
5
|
+
|
|
6
|
+
//#region src/ui/hooks/usePolicySafeKnowledgeAssistant.ts
|
|
7
|
+
function isCitationLike(value) {
|
|
8
|
+
if (!value || typeof value !== "object") return false;
|
|
9
|
+
const v = value;
|
|
10
|
+
return typeof v.kbSnapshotId === "string" && typeof v.sourceId === "string";
|
|
11
|
+
}
|
|
12
|
+
function toCitations(value) {
|
|
13
|
+
if (!Array.isArray(value)) return [];
|
|
14
|
+
return value.filter(isCitationLike).map((c) => ({
|
|
15
|
+
kbSnapshotId: c.kbSnapshotId,
|
|
16
|
+
sourceId: c.sourceId,
|
|
17
|
+
excerpt: c.excerpt
|
|
18
|
+
}));
|
|
19
|
+
}
|
|
20
|
+
function usePolicySafeKnowledgeAssistant() {
|
|
21
|
+
const { handlers, projectId } = useTemplateRuntime();
|
|
22
|
+
const api = handlers.policySafeKnowledgeAssistant;
|
|
23
|
+
const [state, setState] = useState({
|
|
24
|
+
context: null,
|
|
25
|
+
loading: true,
|
|
26
|
+
error: null,
|
|
27
|
+
lastAnswer: null,
|
|
28
|
+
lastRuleId: null,
|
|
29
|
+
lastRuleVersionId: null,
|
|
30
|
+
lastSnapshotId: null,
|
|
31
|
+
lastReviewTaskId: null
|
|
32
|
+
});
|
|
33
|
+
const refreshContext = useCallback(async () => {
|
|
34
|
+
try {
|
|
35
|
+
setState((s) => ({
|
|
36
|
+
...s,
|
|
37
|
+
loading: true,
|
|
38
|
+
error: null
|
|
39
|
+
}));
|
|
40
|
+
const ctx = await api.getUserContext({ projectId });
|
|
41
|
+
setState((s) => ({
|
|
42
|
+
...s,
|
|
43
|
+
context: {
|
|
44
|
+
locale: ctx.locale,
|
|
45
|
+
jurisdiction: ctx.jurisdiction,
|
|
46
|
+
allowedScope: ctx.allowedScope,
|
|
47
|
+
kbSnapshotId: ctx.kbSnapshotId
|
|
48
|
+
},
|
|
49
|
+
loading: false
|
|
50
|
+
}));
|
|
51
|
+
} catch (e) {
|
|
52
|
+
setState((s) => ({
|
|
53
|
+
...s,
|
|
54
|
+
loading: false,
|
|
55
|
+
error: e instanceof Error ? e : /* @__PURE__ */ new Error("Unknown error")
|
|
56
|
+
}));
|
|
57
|
+
}
|
|
58
|
+
}, [api, projectId]);
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
refreshContext();
|
|
61
|
+
}, [refreshContext]);
|
|
62
|
+
const setContext = useCallback(async (input) => {
|
|
63
|
+
const ctx = await api.setUserContext({
|
|
64
|
+
projectId,
|
|
65
|
+
...input
|
|
66
|
+
});
|
|
67
|
+
setState((s) => ({
|
|
68
|
+
...s,
|
|
69
|
+
context: {
|
|
70
|
+
locale: ctx.locale,
|
|
71
|
+
jurisdiction: ctx.jurisdiction,
|
|
72
|
+
allowedScope: ctx.allowedScope,
|
|
73
|
+
kbSnapshotId: ctx.kbSnapshotId
|
|
74
|
+
}
|
|
75
|
+
}));
|
|
76
|
+
}, [api, projectId]);
|
|
77
|
+
const askAssistant = useCallback(async (question) => {
|
|
78
|
+
const answerUnknown = await api.answer({
|
|
79
|
+
projectId,
|
|
80
|
+
question
|
|
81
|
+
});
|
|
82
|
+
const answer = answerUnknown;
|
|
83
|
+
setState((s) => ({
|
|
84
|
+
...s,
|
|
85
|
+
lastAnswer: {
|
|
86
|
+
refused: answer.refused,
|
|
87
|
+
refusalReason: answer.refusalReason,
|
|
88
|
+
sections: answer.sections,
|
|
89
|
+
citations: toCitations(answerUnknown.citations)
|
|
90
|
+
}
|
|
91
|
+
}));
|
|
92
|
+
}, [api, projectId]);
|
|
93
|
+
const createDemoRule = useCallback(async () => {
|
|
94
|
+
const rule = await api.createRule({
|
|
95
|
+
projectId,
|
|
96
|
+
jurisdiction: state.context?.jurisdiction ?? "EU",
|
|
97
|
+
topicKey: "tax_reporting"
|
|
98
|
+
});
|
|
99
|
+
setState((s) => ({
|
|
100
|
+
...s,
|
|
101
|
+
lastRuleId: rule.id
|
|
102
|
+
}));
|
|
103
|
+
return rule.id;
|
|
104
|
+
}, [
|
|
105
|
+
api,
|
|
106
|
+
projectId,
|
|
107
|
+
state.context?.jurisdiction
|
|
108
|
+
]);
|
|
109
|
+
const upsertRuleVersion = useCallback(async (input) => {
|
|
110
|
+
const rv = await api.upsertRuleVersion({
|
|
111
|
+
projectId,
|
|
112
|
+
ruleId: input.ruleId,
|
|
113
|
+
content: input.content,
|
|
114
|
+
sourceRefs: [{
|
|
115
|
+
sourceDocumentId: "src_demo",
|
|
116
|
+
excerpt: "demo excerpt"
|
|
117
|
+
}]
|
|
118
|
+
});
|
|
119
|
+
setState((s) => ({
|
|
120
|
+
...s,
|
|
121
|
+
lastRuleVersionId: rv.id
|
|
122
|
+
}));
|
|
123
|
+
return rv.id;
|
|
124
|
+
}, [api, projectId]);
|
|
125
|
+
const approveRuleVersion = useCallback(async (ruleVersionId) => {
|
|
126
|
+
await api.approveRuleVersion({
|
|
127
|
+
ruleVersionId,
|
|
128
|
+
approver: "demo_expert"
|
|
129
|
+
});
|
|
130
|
+
}, [api]);
|
|
131
|
+
const publishSnapshot = useCallback(async () => {
|
|
132
|
+
const snap = await api.publishSnapshot({
|
|
133
|
+
projectId,
|
|
134
|
+
jurisdiction: state.context?.jurisdiction ?? "EU",
|
|
135
|
+
asOfDate: /* @__PURE__ */ new Date("2026-02-01T00:00:00.000Z")
|
|
136
|
+
});
|
|
137
|
+
setState((s) => ({
|
|
138
|
+
...s,
|
|
139
|
+
lastSnapshotId: snap.id
|
|
140
|
+
}));
|
|
141
|
+
await refreshContext();
|
|
142
|
+
return snap.id;
|
|
143
|
+
}, [
|
|
144
|
+
api,
|
|
145
|
+
projectId,
|
|
146
|
+
refreshContext,
|
|
147
|
+
state.context?.jurisdiction
|
|
148
|
+
]);
|
|
149
|
+
const simulateHighRiskChangeAndApprove = useCallback(async (ruleVersionId) => {
|
|
150
|
+
const cand = await api.createChangeCandidate({
|
|
151
|
+
projectId,
|
|
152
|
+
jurisdiction: state.context?.jurisdiction ?? "EU",
|
|
153
|
+
diffSummary: "Simulated change (demo)",
|
|
154
|
+
riskLevel: "high",
|
|
155
|
+
proposedRuleVersionIds: [ruleVersionId]
|
|
156
|
+
});
|
|
157
|
+
const review = await api.createReviewTask({ changeCandidateId: cand.id });
|
|
158
|
+
setState((s) => ({
|
|
159
|
+
...s,
|
|
160
|
+
lastReviewTaskId: review.id
|
|
161
|
+
}));
|
|
162
|
+
await api.submitDecision({
|
|
163
|
+
reviewTaskId: review.id,
|
|
164
|
+
decision: "approve",
|
|
165
|
+
decidedByRole: "expert",
|
|
166
|
+
decidedBy: "demo_expert"
|
|
167
|
+
});
|
|
168
|
+
await api.publishIfReady({ jurisdiction: state.context?.jurisdiction ?? "EU" });
|
|
169
|
+
return review.id;
|
|
170
|
+
}, [
|
|
171
|
+
api,
|
|
172
|
+
projectId,
|
|
173
|
+
state.context?.jurisdiction
|
|
174
|
+
]);
|
|
175
|
+
return {
|
|
176
|
+
state,
|
|
177
|
+
derived: useMemo(() => ({ projectId }), [projectId]),
|
|
178
|
+
actions: {
|
|
179
|
+
refreshContext,
|
|
180
|
+
setContext,
|
|
181
|
+
askAssistant,
|
|
182
|
+
createDemoRule,
|
|
183
|
+
upsertRuleVersion,
|
|
184
|
+
approveRuleVersion,
|
|
185
|
+
publishSnapshot,
|
|
186
|
+
simulateHighRiskChangeAndApprove
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
//#endregion
|
|
192
|
+
export { usePolicySafeKnowledgeAssistant };
|
|
193
|
+
//# sourceMappingURL=usePolicySafeKnowledgeAssistant.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePolicySafeKnowledgeAssistant.js","names":[],"sources":["../../../src/ui/hooks/usePolicySafeKnowledgeAssistant.ts"],"sourcesContent":["'use client';\n\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useTemplateRuntime } from '@contractspec/lib.example-shared-ui';\n\ntype AllowedScope = 'education_only' | 'generic_info' | 'escalation_required';\ntype RiskLevel = 'low' | 'medium' | 'high';\n\nexport interface UsePolicySafeKnowledgeAssistantState {\n context: {\n locale: string;\n jurisdiction: string;\n allowedScope: AllowedScope;\n kbSnapshotId: string | null;\n } | null;\n loading: boolean;\n error: Error | null;\n lastAnswer: {\n refused?: boolean;\n refusalReason?: string;\n sections: { heading: string; body: string }[];\n citations: {\n kbSnapshotId: string;\n sourceId: string;\n excerpt?: string;\n }[];\n } | null;\n lastRuleId: string | null;\n lastRuleVersionId: string | null;\n lastSnapshotId: string | null;\n lastReviewTaskId: string | null;\n}\n\ninterface CitationLike {\n kbSnapshotId: string;\n sourceId: string;\n excerpt?: string;\n}\ninterface AnswerLike {\n refused?: boolean;\n refusalReason?: string;\n sections: { heading: string; body: string }[];\n citations: CitationLike[];\n}\n\nfunction isCitationLike(value: unknown): value is CitationLike {\n if (!value || typeof value !== 'object') return false;\n const v = value as Record<string, unknown>;\n return typeof v.kbSnapshotId === 'string' && typeof v.sourceId === 'string';\n}\n\nfunction toCitations(value: unknown): CitationLike[] {\n if (!Array.isArray(value)) return [];\n return value.filter(isCitationLike).map((c) => ({\n kbSnapshotId: c.kbSnapshotId,\n sourceId: c.sourceId,\n excerpt: c.excerpt,\n }));\n}\n\nimport type { PolicySafeKnowledgeAssistantHandlers } from '../../handlers/policy-safe-knowledge-assistant.handlers';\n\nexport function usePolicySafeKnowledgeAssistant() {\n const { handlers, projectId } = useTemplateRuntime<{\n policySafeKnowledgeAssistant: PolicySafeKnowledgeAssistantHandlers;\n }>();\n const api = handlers.policySafeKnowledgeAssistant;\n\n const [state, setState] = useState<UsePolicySafeKnowledgeAssistantState>({\n context: null,\n loading: true,\n error: null,\n lastAnswer: null,\n lastRuleId: null,\n lastRuleVersionId: null,\n lastSnapshotId: null,\n lastReviewTaskId: null,\n });\n\n const refreshContext = useCallback(async () => {\n try {\n setState((s) => ({ ...s, loading: true, error: null }));\n const ctx = await api.getUserContext({ projectId });\n setState((s) => ({\n ...s,\n context: {\n locale: ctx.locale,\n jurisdiction: ctx.jurisdiction,\n allowedScope: ctx.allowedScope,\n kbSnapshotId: ctx.kbSnapshotId,\n },\n loading: false,\n }));\n } catch (e) {\n setState((s) => ({\n ...s,\n loading: false,\n error: e instanceof Error ? e : new Error('Unknown error'),\n }));\n }\n }, [api, projectId]);\n\n useEffect(() => {\n refreshContext();\n }, [refreshContext]);\n\n const setContext = useCallback(\n async (input: {\n locale: string;\n jurisdiction: string;\n allowedScope: AllowedScope;\n }) => {\n const ctx = await api.setUserContext({ projectId, ...input });\n setState((s) => ({\n ...s,\n context: {\n locale: ctx.locale,\n jurisdiction: ctx.jurisdiction,\n allowedScope: ctx.allowedScope,\n kbSnapshotId: ctx.kbSnapshotId,\n },\n }));\n },\n [api, projectId]\n );\n\n const askAssistant = useCallback(\n async (question: string) => {\n const answerUnknown: unknown = await api.answer({ projectId, question });\n const answer = answerUnknown as AnswerLike;\n setState((s) => ({\n ...s,\n lastAnswer: {\n refused: answer.refused,\n refusalReason: answer.refusalReason,\n sections: answer.sections,\n citations: toCitations(\n (answerUnknown as { citations?: unknown }).citations\n ),\n },\n }));\n },\n [api, projectId]\n );\n\n const createDemoRule = useCallback(async () => {\n const rule = await api.createRule({\n projectId,\n jurisdiction: state.context?.jurisdiction ?? 'EU',\n topicKey: 'tax_reporting',\n });\n setState((s) => ({ ...s, lastRuleId: rule.id }));\n return rule.id as string;\n }, [api, projectId, state.context?.jurisdiction]);\n\n const upsertRuleVersion = useCallback(\n async (input: { ruleId: string; content: string }) => {\n const rv = await api.upsertRuleVersion({\n projectId,\n ruleId: input.ruleId,\n content: input.content,\n sourceRefs: [{ sourceDocumentId: 'src_demo', excerpt: 'demo excerpt' }],\n });\n setState((s) => ({ ...s, lastRuleVersionId: rv.id }));\n return rv.id as string;\n },\n [api, projectId]\n );\n\n const approveRuleVersion = useCallback(\n async (ruleVersionId: string) => {\n await api.approveRuleVersion({ ruleVersionId, approver: 'demo_expert' });\n },\n [api]\n );\n\n const publishSnapshot = useCallback(async () => {\n const snap = await api.publishSnapshot({\n projectId,\n jurisdiction: state.context?.jurisdiction ?? 'EU',\n asOfDate: new Date('2026-02-01T00:00:00.000Z'),\n });\n setState((s) => ({ ...s, lastSnapshotId: snap.id }));\n await refreshContext();\n return snap.id as string;\n }, [api, projectId, refreshContext, state.context?.jurisdiction]);\n\n const simulateHighRiskChangeAndApprove = useCallback(\n async (ruleVersionId: string) => {\n const cand = await api.createChangeCandidate({\n projectId,\n jurisdiction: state.context?.jurisdiction ?? 'EU',\n diffSummary: 'Simulated change (demo)',\n riskLevel: 'high' satisfies RiskLevel,\n proposedRuleVersionIds: [ruleVersionId],\n });\n const review = await api.createReviewTask({ changeCandidateId: cand.id });\n setState((s) => ({ ...s, lastReviewTaskId: review.id }));\n await api.submitDecision({\n reviewTaskId: review.id,\n decision: 'approve',\n decidedByRole: 'expert',\n decidedBy: 'demo_expert',\n });\n await api.publishIfReady({\n jurisdiction: state.context?.jurisdiction ?? 'EU',\n });\n return review.id as string;\n },\n [api, projectId, state.context?.jurisdiction]\n );\n\n const derived = useMemo(() => ({ projectId }), [projectId]);\n\n return {\n state,\n derived,\n actions: {\n refreshContext,\n setContext,\n askAssistant,\n createDemoRule,\n upsertRuleVersion,\n approveRuleVersion,\n publishSnapshot,\n simulateHighRiskChangeAndApprove,\n },\n };\n}\n"],"mappings":"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"}
|
package/dist/ui/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@contractspec/example.policy-safe-knowledge-assistant",
|
|
3
|
+
"version": "0.0.0-canary-20260113170453",
|
|
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
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./dist/index.js",
|
|
9
|
+
"./docs": "./dist/docs/index.js",
|
|
10
|
+
"./docs/policy-safe-knowledge-assistant.docblock": "./dist/docs/policy-safe-knowledge-assistant.docblock.js",
|
|
11
|
+
"./example": "./dist/example.js",
|
|
12
|
+
"./handlers": "./dist/handlers/index.js",
|
|
13
|
+
"./handlers/policy-safe-knowledge-assistant.handlers": "./dist/handlers/policy-safe-knowledge-assistant.handlers.js",
|
|
14
|
+
"./orchestrator/buildAnswer": "./dist/orchestrator/buildAnswer.js",
|
|
15
|
+
"./policy-safe-knowledge-assistant.feature": "./dist/policy-safe-knowledge-assistant.feature.js",
|
|
16
|
+
"./seed": "./dist/seed/index.js",
|
|
17
|
+
"./seed/fixtures": "./dist/seed/fixtures.js",
|
|
18
|
+
"./seeders": "./dist/seeders/index.js",
|
|
19
|
+
"./ui": "./dist/ui/index.js",
|
|
20
|
+
"./ui/hooks/usePolicySafeKnowledgeAssistant": "./dist/ui/hooks/usePolicySafeKnowledgeAssistant.js",
|
|
21
|
+
"./ui/PolicySafeKnowledgeAssistantDashboard": "./dist/ui/PolicySafeKnowledgeAssistantDashboard.js",
|
|
22
|
+
"./*": "./*"
|
|
23
|
+
},
|
|
24
|
+
"scripts": {
|
|
25
|
+
"publish:pkg": "bun publish --tolerate-republish --ignore-scripts --verbose",
|
|
26
|
+
"publish:pkg:canary": "bun publish:pkg --tag canary",
|
|
27
|
+
"build": "bun build:types && bun build:bundle",
|
|
28
|
+
"build:bundle": "tsdown",
|
|
29
|
+
"build:types": "tsc --noEmit",
|
|
30
|
+
"dev": "bun build:bundle --watch",
|
|
31
|
+
"clean": "rimraf dist .turbo",
|
|
32
|
+
"lint": "bun lint:fix",
|
|
33
|
+
"lint:fix": "eslint src --fix",
|
|
34
|
+
"lint:check": "eslint src",
|
|
35
|
+
"test": "bun test"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@contractspec/example.kb-update-pipeline": "0.0.0-canary-20260113170453",
|
|
39
|
+
"@contractspec/example.learning-patterns": "0.0.0-canary-20260113170453",
|
|
40
|
+
"@contractspec/example.locale-jurisdiction-gate": "0.0.0-canary-20260113170453",
|
|
41
|
+
"@contractspec/example.versioned-knowledge-base": "0.0.0-canary-20260113170453",
|
|
42
|
+
"@contractspec/lib.contracts": "0.0.0-canary-20260113170453",
|
|
43
|
+
"@contractspec/lib.design-system": "0.0.0-canary-20260113170453",
|
|
44
|
+
"@contractspec/lib.example-shared-ui": "0.0.0-canary-20260113170453",
|
|
45
|
+
"@contractspec/lib.runtime-sandbox": "0.0.0-canary-20260113170453",
|
|
46
|
+
"@contractspec/lib.ui-kit-web": "0.0.0-canary-20260113170453",
|
|
47
|
+
"@contractspec/module.learning-journey": "0.0.0-canary-20260113170453",
|
|
48
|
+
"react": "19.2.3",
|
|
49
|
+
"react-dom": "19.2.3"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@contractspec/tool.tsdown": "0.0.0-canary-20260113170453",
|
|
53
|
+
"@contractspec/tool.typescript": "0.0.0-canary-20260113170453",
|
|
54
|
+
"tsdown": "^0.19.0",
|
|
55
|
+
"typescript": "^5.9.3",
|
|
56
|
+
"@types/react": "^19.2.8",
|
|
57
|
+
"@types/react-dom": "^19.2.2"
|
|
58
|
+
},
|
|
59
|
+
"publishConfig": {
|
|
60
|
+
"access": "public",
|
|
61
|
+
"exports": {
|
|
62
|
+
".": "./dist/index.js",
|
|
63
|
+
"./docs": "./dist/docs/index.js",
|
|
64
|
+
"./docs/policy-safe-knowledge-assistant.docblock": "./dist/docs/policy-safe-knowledge-assistant.docblock.js",
|
|
65
|
+
"./example": "./dist/example.js",
|
|
66
|
+
"./policy-safe-knowledge-assistant.feature": "./dist/policy-safe-knowledge-assistant.feature.js",
|
|
67
|
+
"./orchestrator/buildAnswer": "./dist/orchestrator/buildAnswer.js",
|
|
68
|
+
"./seed": "./dist/seed/index.js",
|
|
69
|
+
"./seed/fixtures": "./dist/seed/fixtures.js",
|
|
70
|
+
"./*": "./*"
|
|
71
|
+
},
|
|
72
|
+
"registry": "https://registry.npmjs.org/"
|
|
73
|
+
},
|
|
74
|
+
"license": "MIT",
|
|
75
|
+
"repository": {
|
|
76
|
+
"type": "git",
|
|
77
|
+
"url": "https://github.com/lssm-tech/contractspec.git",
|
|
78
|
+
"directory": "packages/examples/policy-safe-knowledge-assistant"
|
|
79
|
+
},
|
|
80
|
+
"homepage": "https://contractspec.io"
|
|
81
|
+
}
|
|
@@ -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,36 @@
|
|
|
1
|
+
import { defineExample } from '@contractspec/lib.contracts';
|
|
2
|
+
|
|
3
|
+
const example = defineExample({
|
|
4
|
+
meta: {
|
|
5
|
+
key: 'policy-safe-knowledge-assistant',
|
|
6
|
+
version: '1.0.0',
|
|
7
|
+
title: 'Policy-safe Knowledge Assistant',
|
|
8
|
+
description:
|
|
9
|
+
'All-in-one template: locale/jurisdiction gating + versioned KB snapshots + HITL update pipeline + learning hub.',
|
|
10
|
+
kind: 'template',
|
|
11
|
+
visibility: 'public',
|
|
12
|
+
stability: 'experimental',
|
|
13
|
+
owners: ['@platform.core'],
|
|
14
|
+
tags: ['assistant', 'knowledge', 'policy', 'hitl', 'learning'],
|
|
15
|
+
},
|
|
16
|
+
docs: {
|
|
17
|
+
goalDocId: 'docs.examples.policy-safe-knowledge-assistant.goal',
|
|
18
|
+
usageDocId: 'docs.examples.policy-safe-knowledge-assistant.usage',
|
|
19
|
+
},
|
|
20
|
+
entrypoints: {
|
|
21
|
+
packageName: '@contractspec/example.policy-safe-knowledge-assistant',
|
|
22
|
+
feature: './policy-safe-knowledge-assistant.feature',
|
|
23
|
+
docs: './docs',
|
|
24
|
+
},
|
|
25
|
+
surfaces: {
|
|
26
|
+
templates: true,
|
|
27
|
+
sandbox: {
|
|
28
|
+
enabled: true,
|
|
29
|
+
modes: ['playground', 'specs', 'builder', 'markdown', 'evolution'],
|
|
30
|
+
},
|
|
31
|
+
studio: { enabled: true, installable: true },
|
|
32
|
+
mcp: { enabled: true },
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
export default example;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './policy-safe-knowledge-assistant.handlers';
|