@schift-io/knowledge-scope 0.1.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 (62) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +387 -0
  3. package/dist/context-pack.js +4771 -0
  4. package/dist/index.js +8044 -0
  5. package/dist/main.js +7550 -0
  6. package/dist/types/adapters/evidence-policy.d.ts +3 -0
  7. package/dist/types/adapters/gates.d.ts +13 -0
  8. package/dist/types/adapters/http-policy.d.ts +10 -0
  9. package/dist/types/adapters/open-connector.d.ts +20 -0
  10. package/dist/types/adapters/provider-port.d.ts +27 -0
  11. package/dist/types/adapters/response.d.ts +12 -0
  12. package/dist/types/adapters/schift-search-headers.d.ts +2 -0
  13. package/dist/types/adapters/schift-search-identity.d.ts +14 -0
  14. package/dist/types/adapters/schift-search.d.ts +17 -0
  15. package/dist/types/adapters/types.d.ts +136 -0
  16. package/dist/types/api-contract.d.ts +164 -0
  17. package/dist/types/api.d.ts +30 -0
  18. package/dist/types/application-batch.d.ts +4 -0
  19. package/dist/types/application-execution.d.ts +30 -0
  20. package/dist/types/application.d.ts +47 -0
  21. package/dist/types/authorization.d.ts +228 -0
  22. package/dist/types/cli-options.d.ts +6 -0
  23. package/dist/types/cli.d.ts +24 -0
  24. package/dist/types/client-error.d.ts +5 -0
  25. package/dist/types/client-validation.d.ts +8 -0
  26. package/dist/types/client.d.ts +18 -0
  27. package/dist/types/context-pack/bounded-json.d.ts +3 -0
  28. package/dist/types/context-pack/canonical.d.ts +12 -0
  29. package/dist/types/context-pack/index.d.ts +73 -0
  30. package/dist/types/context-pack/knowledge-scope-admission.d.ts +23 -0
  31. package/dist/types/context-pack/knowledge-scope-batch.d.ts +85 -0
  32. package/dist/types/context-pack/knowledge-scope-execution.d.ts +297 -0
  33. package/dist/types/context-pack/knowledge-scope-lock.d.ts +71 -0
  34. package/dist/types/context-pack/knowledge-scope-mount.d.ts +1094 -0
  35. package/dist/types/context-pack/knowledge-scope.d.ts +1843 -0
  36. package/dist/types/context-pack/scalars.d.ts +13 -0
  37. package/dist/types/doctor-config.d.ts +6 -0
  38. package/dist/types/doctor.d.ts +7 -0
  39. package/dist/types/errors.d.ts +8 -0
  40. package/dist/types/evaluation/contracts.d.ts +718 -0
  41. package/dist/types/evaluation.d.ts +20 -0
  42. package/dist/types/index.d.ts +26 -0
  43. package/dist/types/json.d.ts +17 -0
  44. package/dist/types/limits.d.ts +10 -0
  45. package/dist/types/main.d.ts +10 -0
  46. package/dist/types/onboarding-config.d.ts +9 -0
  47. package/dist/types/portable.d.ts +14 -0
  48. package/dist/types/quickstart.d.ts +10 -0
  49. package/dist/types/schema-subset.d.ts +9 -0
  50. package/dist/types/state-contract.d.ts +2867 -0
  51. package/dist/types/state-store.d.ts +29 -0
  52. package/docs/PILOT.md +184 -0
  53. package/examples/batch-consumer.mjs +19 -0
  54. package/examples/consumer.mjs +17 -0
  55. package/examples/evaluation/README.md +34 -0
  56. package/examples/evaluation/run.mjs +21 -0
  57. package/examples/evaluation/synthetic.json +59 -0
  58. package/examples/mount-bindings.json +31 -0
  59. package/examples/support-scope/schemas/query-input.json +6 -0
  60. package/examples/support-scope/schemas/result-row.json +6 -0
  61. package/examples/support-scope/scope.json +48 -0
  62. package/package.json +58 -0
@@ -0,0 +1,29 @@
1
+ import { type KnowledgeScopeState } from "./state-contract.js";
2
+ export type StateMutation<T> = Readonly<{
3
+ state: KnowledgeScopeState;
4
+ value: T;
5
+ }>;
6
+ export interface StateStoreFaults {
7
+ beforeRename(): Promise<void>;
8
+ }
9
+ export type KnowledgeScopeStateStoreOptions = Readonly<{
10
+ home?: string;
11
+ environment?: Readonly<Record<string, string | undefined>>;
12
+ faults?: StateStoreFaults;
13
+ }>;
14
+ export declare const MAX_STATE_BYTES: number;
15
+ export declare const MAX_STATE_DEPTH = 48;
16
+ export declare const MAX_STATE_NODES = 250000;
17
+ export declare class KnowledgeScopeStateStore {
18
+ readonly home: string;
19
+ private readonly statePath;
20
+ private readonly lockPath;
21
+ private readonly faults;
22
+ constructor(options?: KnowledgeScopeStateStoreOptions);
23
+ initialize(): Promise<void>;
24
+ private createInitialState;
25
+ read(): Promise<KnowledgeScopeState>;
26
+ transact<T>(update: (state: KnowledgeScopeState) => StateMutation<T>): Promise<T>;
27
+ private acquireLock;
28
+ private writeAtomically;
29
+ }
package/docs/PILOT.md ADDED
@@ -0,0 +1,184 @@
1
+ # Run a support-context pilot
2
+
3
+ The pilot is for an AI application team, SI, or agency that already has support documents indexed
4
+ in Schift Search. Its first task is to retrieve cited evidence for one support question and pass
5
+ that evidence into its own application. Start with the [README quickstart](../README.md#quickstart).
6
+
7
+ Success means the customer can repeat that retrieval, inspect its sources, and refuse an answer
8
+ when evidence is insufficient. Installing the package or passing synthetic tests does not establish
9
+ customer demand, live-provider compatibility, or better retrieval accuracy.
10
+
11
+ ## Choose one question and one data boundary
12
+
13
+ Ask the customer for a repeated support question whose approved answer is present in the indexed
14
+ corpus. Record the expected document and passage before running retrieval. Select the authorized
15
+ organization and bucket; confirm who may read that bucket.
16
+
17
+ The initial path is:
18
+
19
+ ```text
20
+ Existing indexed support documents
21
+ -> quickstart and local mount
22
+ -> retrieve and admit cited evidence
23
+ -> customer's application
24
+ -> customer verifies the cited passage
25
+ ```
26
+
27
+ The current Search adapter uses the mounted tenant and the Search API's organization/bucket ACL.
28
+ It rejects narrower `namespace`, `subject`, and `session` requests before HTTP because the provider
29
+ does not enforce those fields. An arbitrary tenant label is not a replacement for provider access
30
+ control. Use an appropriately scoped bucket and installation when separate data access is required.
31
+
32
+ Keep API tokens and customer source data outside the portable Pack. The Pack contains the declared
33
+ operation, schemas, and evidence rules; local bindings choose the authorized source.
34
+
35
+ ## Extend to documents plus live records
36
+
37
+ After the document-only path works, select one read-only records operation, such as looking up
38
+ the status of an order. Use `runBatch` to retrieve the document and record operations under one
39
+ mounted policy and release their evidence only after combined admission succeeds.
40
+
41
+ 1. Define the named operation and its input/result schemas. Identify its approved source and
42
+ required evidence, including a stable record ID, revision, freshness, and citation.
43
+ 2. Supply an authorized executor through the injected records port, or configure an Open Connector
44
+ action in `core-dependencies/schift-connector`. The CLI does not create database connections or
45
+ accept raw SQL.
46
+ 3. For Open Connector, allowlist the exact connector, account alias, and read-only action. If the
47
+ operation needs filters or narrower Scope, provide a trusted input mapper that applies those
48
+ restrictions in the provider-native input. Without it, the adapter rejects the request.
49
+ 4. Require one `document` and one `records` evidence item with separate `mustConsider` selectors
50
+ and coverage assertion IDs. Bind each operation to its true source class. Verify that either
51
+ operation alone returns insufficient evidence and no Candidates.
52
+ 5. Send both operations in one `runBatch` request with the same installation, effective Scope,
53
+ and expected revision. Verify both citations and required coverage. An invalid operation must
54
+ fail before provider dispatch; a missing record, provider failure, or intervening unmount must
55
+ not release partial evidence. Recheck admission after restarting the local process.
56
+ 6. Give only admitted evidence to the customer's application. A missing required record or document
57
+ must produce an insufficient-evidence outcome, not a guessed answer.
58
+
59
+ Use the examples as contract samples, not as proof that a customer's helpdesk or database has been
60
+ connected. Actual account authorization and provider behavior must be checked in the pilot.
61
+ Batch execution guarantees atomic admission/output, not a transaction or common snapshot across
62
+ providers. Record each source's own revision and freshness when evaluating consistency. Python
63
+ contract parity does not imply an independent Python provider-execution runtime.
64
+
65
+ ## Measure a useful outcome
66
+
67
+ Before tuning retrieval, collect 30–50 customer questions with human-reviewed expected evidence.
68
+ Include unanswerable questions, stale documents, conflicting sources, and forbidden-source cases.
69
+ Keep a held-out subset out of prompt, Pack, and retrieval tuning.
70
+
71
+ For each capture, retain the question ID, dataset fingerprint, Pack digest, source snapshot,
72
+ retrieved evidence identity and citations, admission result, latency, and measured operating cost
73
+ when available. Avoid storing customer text in public examples or reports.
74
+
75
+ Compare Schift with the customer's current retrieval path on the same questions and frozen source
76
+ snapshot. Compare evidence identities that both paths can produce; adapter-specific SRNs alone
77
+ cannot define a fair cross-adapter ground truth. Record retrieval evidence separately from final
78
+ answer quality, which also depends on the customer's model and prompt.
79
+
80
+ An offline report is a measurement of the supplied captures. It does not establish live ACL
81
+ enforcement or a general accuracy advantage. Publish a comparison only with its sample size,
82
+ dataset scope, metric definitions, failure cases, and reproducible inputs.
83
+
84
+ The SDK's `evaluateRetrieval({ dataset, capture, topK })` evaluates captured results;
85
+ `compareRetrievalReports(baseline, candidate)` reports candidate-minus-baseline deltas. Both reports
86
+ must share dataset, input, Pack, source-snapshot fingerprints, and K. Missing, duplicate, or unknown
87
+ question IDs reject evaluation rather than silently reducing the sample.
88
+
89
+ | Metric | Definition |
90
+ | --- | --- |
91
+ | `recallAtK` | Total expected evidence IDs found in top K, divided by all expected evidence IDs across questions. |
92
+ | `citationMatchRate` | Top-K items matching both expected evidence ID and exact citation, divided by all returned top-K items. |
93
+ | `forbiddenEvidenceCount` | Forbidden evidence IDs across the entire capture, including items below K. |
94
+ | `decisionMatchRate` | Questions whose ready/insufficient decision matches the expected decision, divided by all questions. |
95
+
96
+ A zero evidence denominator yields `null`, not a perfect score. Citation matching checks labels;
97
+ it does not fetch URLs or prove that the cited source supports an answer. Synthetic examples only
98
+ demonstrate this evaluation contract.
99
+
100
+ ## Recover without discarding the project
101
+
102
+ | Outcome | Next action |
103
+ | --- | --- |
104
+ | Configuration is missing | Supply the named environment variable, then retry. Never paste its value into a report. |
105
+ | Workspace already exists | Reuse the existing installation or choose a new directory; do not overwrite it. |
106
+ | Setup reports `artifactsComplete: false` | Inspect the preserved workspace and validate it before mounting; complete or correct the missing files first. |
107
+ | Search is unavailable | Preserve generated files and mount state, restore access, then use the reported recovery command. |
108
+ | Evidence is insufficient | Inspect the expected source, index contents, freshness, and evidence policy. Do not bypass admission to make the demo succeed. |
109
+ | Mount revision changed | Inspect the current installation and use its current revision. |
110
+ | Mount is inactive | Create a new authorized mount; unmount tombstones intentionally stay in state. |
111
+ | State is locked after a crash | Verify that the recorded process is gone before the owner removes the stale lock. Never delete an active writer's lock. |
112
+
113
+ A configuration check does not perform a retrieval. An explicit probe reads the configured
114
+ provider and may consume its normal usage. Keep the distinction in the acceptance record.
115
+
116
+ ## CE and the managed offer
117
+
118
+ CE provides local authoring, validation, mounting, provider execution, admission, and SDK access.
119
+ The customer operates its local state and supplies authorized provider connections.
120
+
121
+ The managed offer to validate is operation of that same boundary: maintained connections,
122
+ indexing/synchronization, hosted persistence, access administration, regression monitoring,
123
+ private deployment, and support. These are proposed commercial scope until the corresponding
124
+ service is implemented and accepted; CE availability does not imply hosted availability.
125
+
126
+ Quote a pilot against an agreed source, question set, access boundary, acceptance test, and support
127
+ period. Do not invent a subscription price, seat fee, accuracy guarantee, or service-level promise
128
+ from this package's test results.
129
+
130
+ ## External pilot gates
131
+
132
+ These are proposed go/no-go gates, not completed customer results. The pilot owner records dated
133
+ evidence and checks each box only after observing the outcome.
134
+
135
+ ### Days 1–30: first independent use
136
+
137
+ - [ ] Three external teams install the artifact and retrieve their own cited evidence.
138
+ - [ ] Each team reaches its first useful result without an engineer editing the package for them.
139
+ - [ ] At least one customer supplies 30–50 reviewed questions and a baseline retrieval path.
140
+ - [ ] Record time to first useful result, failed setup steps, and whether the team uses it again.
141
+
142
+ If teams cannot activate, fix the most frequent setup failure before adding providers. If the
143
+ question set has no repeated customer task behind it, revise the pilot use case.
144
+
145
+ ### Days 31–60: repeatable value
146
+
147
+ - [ ] Two teams use the integration repeatedly across at least two weeks.
148
+ - [ ] Run the frozen, held-out comparison and report regressions as well as improvements.
149
+ - [ ] Verify one real document-plus-records integration using the implemented combined
150
+ retrieval/policy path under customer-approved access.
151
+ - [ ] Identify a buyer and confirm which operating responsibility they want Schift to take over.
152
+
153
+ If users do not return, investigate whether cited evidence changes their actual work. If Schift
154
+ adds integration effort without a measurable benefit, narrow the product or stop that use case.
155
+
156
+ ### Days 61–90: paid continuation
157
+
158
+ - [ ] One customer accepts a paid continuation with written scope and acceptance criteria.
159
+ - [ ] Measure actual support effort and provider/infrastructure cost for that scope.
160
+ - [ ] A second installation repeats the first integration without customer-specific core forks.
161
+ - [ ] Decide whether to invest in the managed service using retention, payment, and support evidence.
162
+
163
+ No paid continuation after qualified pilots is a reason to revisit the offer and target customer,
164
+ not evidence that more infrastructure will create demand.
165
+
166
+ ## Evidence status
167
+
168
+ Release-test observation (2026-09-22): one isolated full-suite run received a non-2xx response in
169
+ the local Search fixture. Its status and listener identity were not captured. A later full run,
170
+ 330 repeated related tests, and 500 controlled same-port server replacements did not reproduce it.
171
+ The fixture now asserts HTTP status and listener identity to make any recurrence diagnosable.
172
+ The cause remains unconfirmed; no production change was made on the basis of this observation.
173
+
174
+ - [x] Local CE contract and adapter lifecycle have automated test coverage.
175
+ - [x] An installable tarball and local fake-provider E2E path exist.
176
+ - [x] Combined document/record retrieval has local contract and installed-artifact checks.
177
+ - [ ] Live customer account certification.
178
+ - [ ] Customer-owned held-out retrieval benchmark.
179
+ - [ ] Proven retrieval advantage over the customer's existing approach.
180
+ - [ ] Three external activations and repeat usage.
181
+ - [ ] Paid continuation and measured operating margin.
182
+
183
+ Implementation status lives in `packages/context-pack/AUTO_SCOPE.md` in the source repository.
184
+ Customer validation remains separate from implementation checkmarks.
@@ -0,0 +1,19 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { createCliDependencies, createKnowledgeScopeClient } from "@schift-io/knowledge-scope";
3
+
4
+ const [installationId, requestPath] = process.argv.slice(2);
5
+ if (!installationId || !requestPath) {
6
+ process.stderr.write("Usage: node batch-consumer.mjs <installation-id> <batch-request.json>\n");
7
+ process.exitCode = 2;
8
+ } else {
9
+ const client = createKnowledgeScopeClient({ application: createCliDependencies().embedded });
10
+ try {
11
+ const request = JSON.parse(await readFile(requestPath, "utf8"));
12
+ const result = await client.runBatch({ ...request, installationId });
13
+ process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
14
+ if (result.status === "insufficient_evidence") process.exitCode = 3;
15
+ } catch (error) {
16
+ process.stderr.write(`${JSON.stringify({ status: "error", code: typeof error?.code === "string" ? error.code : "consumer_failed" })}\n`);
17
+ process.exitCode = 1;
18
+ }
19
+ }
@@ -0,0 +1,17 @@
1
+ import { createCliDependencies, createKnowledgeScopeClient } from "@schift-io/knowledge-scope";
2
+
3
+ const [installationId, tenant, query, operationId = "search"] = process.argv.slice(2);
4
+ if (!installationId || !tenant || !query) {
5
+ process.stderr.write("Usage: node consumer.mjs <installation-id> <tenant> <question> [operation-id]\n");
6
+ process.exitCode = 2;
7
+ } else {
8
+ const client = createKnowledgeScopeClient({ application: createCliDependencies().embedded });
9
+ try {
10
+ const result = await client.run({ installationId, operationId, effectiveScope: { tenant }, input: { query } });
11
+ process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
12
+ if (result.status === "insufficient_evidence") process.exitCode = 3;
13
+ } catch (error) {
14
+ process.stderr.write(`${JSON.stringify({ status: "error", code: typeof error?.code === "string" ? error.code : "consumer_failed" })}\n`);
15
+ process.exitCode = 1;
16
+ }
17
+ }
@@ -0,0 +1,34 @@
1
+ # Offline evidence evaluation
2
+
3
+ From the built package directory run `node examples/evaluation/run.mjs`.
4
+ This example is entirely synthetic, makes no network/model calls, and demonstrates scoring only.
5
+ Its hand-authored better result does not demonstrate a Schift accuracy advantage.
6
+
7
+ `evaluateRetrieval({ dataset, capture, topK })` requires exactly one captured result per unique
8
+ question ID, the dataset fingerprint from `fingerprintRetrievalDataset(dataset)`, the same Pack
9
+ digest and source snapshot digest, and identical per-question input fingerprints. Set the input
10
+ fingerprint to a SHA-256 of the complete request (query, filters and authority context), using the
11
+ same canonicalization in both adapters. Pin the dataset and inputs before collecting results.
12
+ The evaluator checks declared identities, not whether an external provider actually used them.
13
+
14
+ Map both adapters' result IDs to the same dataset `evidenceId`; adapter-specific Candidate SRNs
15
+ are not comparable evidence IDs. Each expected ID maps to its expected citation string.
16
+ Captured citations may be `null` for missing citations. A citation match means exact string and
17
+ evidence-ID agreement; it does not check URL liveness, document validity, or answer correctness.
18
+
19
+ - `recallAtK`: sum of unique expected IDs found in each top-K result / all expected IDs.
20
+ The denominator is not capped at K. Questions with no expected evidence contribute zero to both
21
+ counts; when the entire dataset has no expected evidence the metric is `null`.
22
+ - `citationMatchRate`: expected ID + citation matches in top K / all returned top-K items.
23
+ Missing/wrong citations and unexpected IDs count against this rate. No returned items means `null`.
24
+ - `forbiddenEvidenceCount`: all returned forbidden IDs, including those beyond K.
25
+ - `decisionMatchRate`: matching `ready`/`insufficient_evidence` decisions / all questions.
26
+
27
+ Duplicate result/label IDs, missing or extra questions, unknown fields, and fingerprint drift
28
+ are rejected. The bounded format accepts at most 1,000 questions, 100 evidence items per question,
29
+ and K from 1 to 100. `compareRetrievalReports(left, right)` requires matching snapshots, labels,
30
+ inputs and K. It reports right-minus-left deltas, without selecting a winner or hiding regressions.
31
+
32
+ For customer evaluation use `provenance: "customer_provided"`, held-out questions and manually
33
+ reviewed evidence/citation labels. This flag describes provenance supplied by the caller; it is
34
+ not proof of independent review. Reports are unsigned local measurement artifacts.
@@ -0,0 +1,21 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { evaluateRetrieval, compareRetrievalReports, fingerprintRetrievalDataset } from "@schift-io/knowledge-scope";
3
+
4
+ // Offline synthetic scoring demonstration: these are hand-authored captured results.
5
+ // For a real pilot, pin these fingerprints BEFORE executing either retrieval adapter.
6
+ const fixture = JSON.parse(await readFile(new URL("./synthetic.json", import.meta.url), "utf8"));
7
+ const dataset = fixture.dataset;
8
+ const capture = (adapter, results) => ({
9
+ adapter, results,
10
+ datasetFingerprint: fingerprintRetrievalDataset(dataset),
11
+ packDigest: dataset.packDigest,
12
+ sourceSnapshotDigest: dataset.sourceSnapshotDigest,
13
+ });
14
+ const baseline = evaluateRetrieval({ dataset, capture: capture("synthetic-baseline", fixture.baselineResults), topK: 2 });
15
+ const candidate = evaluateRetrieval({ dataset, capture: capture("synthetic-candidate", fixture.candidateResults), topK: 2 });
16
+ console.log(JSON.stringify({
17
+ notice: fixture.notice,
18
+ baseline,
19
+ candidate,
20
+ comparison: compareRetrievalReports(baseline, candidate),
21
+ }, null, 2));
@@ -0,0 +1,59 @@
1
+ {
2
+ "notice": "SYNTHETIC engineering fixture. Not a real customer golden set or a measured retrieval advantage.",
3
+ "dataset": {
4
+ "datasetId": "synthetic-support-example",
5
+ "provenance": "synthetic",
6
+ "packDigest": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
7
+ "sourceSnapshotDigest": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
8
+ "questions": [
9
+ {
10
+ "questionId": "refund-policy",
11
+ "inputFingerprint": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
12
+ "expectedDecision": "ready",
13
+ "expectedEvidence": [
14
+ { "evidenceId": "refund-window", "citation": "manual:refunds#window" },
15
+ { "evidenceId": "refund-exclusions", "citation": "manual:refunds#exclusions" }
16
+ ],
17
+ "forbiddenEvidenceIds": ["another-tenant-refund"]
18
+ },
19
+ {
20
+ "questionId": "unsupported-topic",
21
+ "inputFingerprint": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd",
22
+ "expectedDecision": "insufficient_evidence",
23
+ "expectedEvidence": [],
24
+ "forbiddenEvidenceIds": ["private-ticket"]
25
+ }
26
+ ]
27
+ },
28
+ "baselineResults": [
29
+ {
30
+ "questionId": "refund-policy",
31
+ "inputFingerprint": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
32
+ "decision": "ready",
33
+ "items": [{ "evidenceId": "refund-window", "citation": "manual:refunds#window" }]
34
+ },
35
+ {
36
+ "questionId": "unsupported-topic",
37
+ "inputFingerprint": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd",
38
+ "decision": "insufficient_evidence",
39
+ "items": []
40
+ }
41
+ ],
42
+ "candidateResults": [
43
+ {
44
+ "questionId": "refund-policy",
45
+ "inputFingerprint": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
46
+ "decision": "ready",
47
+ "items": [
48
+ { "evidenceId": "refund-window", "citation": "manual:refunds#window" },
49
+ { "evidenceId": "refund-exclusions", "citation": "manual:refunds#exclusions" }
50
+ ]
51
+ },
52
+ {
53
+ "questionId": "unsupported-topic",
54
+ "inputFingerprint": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd",
55
+ "decision": "insufficient_evidence",
56
+ "items": []
57
+ }
58
+ ]
59
+ }
@@ -0,0 +1,31 @@
1
+ {
2
+ "scopeAuthority": { "organizationId": "replace-with-organization", "tenant": "replace-with-tenant" },
3
+ "sourceBindings": [
4
+ {
5
+ "authority": "operational",
6
+ "operationIds": ["list-orders"],
7
+ "permissionMode": "live",
8
+ "providerRef": "list-orders",
9
+ "sourceClass": "records",
10
+ "sourceId": "source-orders"
11
+ },
12
+ {
13
+ "authority": "observed",
14
+ "connectorRef": "helpdesk",
15
+ "operationIds": ["fetch-support"],
16
+ "origin": "observed",
17
+ "permissionMode": "live",
18
+ "providerRef": "support-search",
19
+ "sourceClass": "activity_stream",
20
+ "sourceId": "source-helpdesk"
21
+ },
22
+ {
23
+ "authority": "approved",
24
+ "operationIds": ["search-handbook"],
25
+ "permissionMode": "mirrored",
26
+ "providerRef": "support-handbook",
27
+ "sourceClass": "document",
28
+ "sourceId": "source-handbook"
29
+ }
30
+ ]
31
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "additionalProperties": false,
3
+ "properties": { "query": { "minLength": 1, "type": "string" } },
4
+ "required": ["query"],
5
+ "type": "object"
6
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "additionalProperties": true,
3
+ "properties": { "text": { "minLength": 1, "type": "string" } },
4
+ "required": ["text"],
5
+ "type": "object"
6
+ }
@@ -0,0 +1,48 @@
1
+ {
2
+ "authority": {
3
+ "allowed": ["read", "draft"],
4
+ "forbidden": ["send", "approve", "mutate_source", "workflow"],
5
+ "precedence": ["primary", "operational", "approved", "observed", "derived"]
6
+ },
7
+ "capabilities": [
8
+ {
9
+ "allowedFilters": ["status"],
10
+ "inputSchemaRef": "schemas/query-input.json",
11
+ "limits": { "maxResultBytes": 131072, "maxRows": 25 },
12
+ "operationId": "list-orders",
13
+ "provider": { "kind": "records_operation", "operationId": "list-orders" },
14
+ "resultSchemaRef": "schemas/result-row.json"
15
+ },
16
+ {
17
+ "freshness": { "maxAgeSeconds": 3600 },
18
+ "inputSchemaRef": "schemas/query-input.json",
19
+ "limits": { "maxResultBytes": 131072, "maxRows": 25 },
20
+ "operationId": "fetch-support",
21
+ "provider": { "actionId": "support-search", "connectorRef": "helpdesk", "kind": "open_connector_action" },
22
+ "requiredProviderScopes": ["tickets:read"],
23
+ "resultSchemaRef": "schemas/result-row.json"
24
+ },
25
+ {
26
+ "freshness": { "maxAgeSeconds": 86400 },
27
+ "inputSchemaRef": "schemas/query-input.json",
28
+ "limits": { "maxResultBytes": 131072, "maxRows": 25 },
29
+ "operationId": "search-handbook",
30
+ "provider": { "indexRef": "support-handbook", "kind": "schift_search" },
31
+ "resultSchemaRef": "schemas/result-row.json"
32
+ }
33
+ ],
34
+ "contextPolicy": {
35
+ "mayConsider": [{ "id": "activity", "minEvidence": 1, "selector": { "sourceClasses": ["activity_stream"] } }],
36
+ "mustConsider": [{ "id": "support-evidence", "minEvidence": 1, "selector": { "sourceClasses": ["document", "records"] } }],
37
+ "mustNotUse": [{ "id": "derived-only", "selector": { "authorities": ["derived"] } }]
38
+ },
39
+ "evidence": {
40
+ "coverageAssertions": ["support-evidence"],
41
+ "freshness": { "defaultMaxAgeSeconds": 86400 },
42
+ "requireCitation": true
43
+ },
44
+ "packId": "support-scope",
45
+ "responsibility": "support-context",
46
+ "scope": { "descendants": ["namespace", "subject", "session"], "root": "tenant" },
47
+ "version": "0.1.0"
48
+ }
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@schift-io/knowledge-scope",
3
+ "version": "0.1.0",
4
+ "description": "Portable Knowledge Scope authoring and local control plane.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/types/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/types/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ },
13
+ "./context-pack": {
14
+ "types": "./dist/types/context-pack/index.d.ts",
15
+ "import": "./dist/context-pack.js"
16
+ }
17
+ },
18
+ "bin": {
19
+ "schift-ks": "./dist/main.js"
20
+ },
21
+ "files": [
22
+ "dist",
23
+ "README.md",
24
+ "LICENSE",
25
+ "docs",
26
+ "examples"
27
+ ],
28
+ "scripts": {
29
+ "build": "bun ./scripts/build-package.mjs",
30
+ "prepack": "bun run build",
31
+ "test": "bun test",
32
+ "test:package": "bun run build && bun test ./test/package.test.ts",
33
+ "typecheck": "tsc -p tsconfig.json --noEmit",
34
+ "release:verify": "node ./scripts/release-verify.mjs"
35
+ },
36
+ "dependencies": {
37
+ "zod": "3.25.76"
38
+ },
39
+ "devDependencies": {
40
+ "@types/bun": "1.3.11",
41
+ "typescript": "5.5.4"
42
+ },
43
+ "overrides": {
44
+ "@types/node": "22.19.17"
45
+ },
46
+ "engines": {
47
+ "node": ">=20"
48
+ },
49
+ "license": "Apache-2.0",
50
+ "repository": {
51
+ "type": "git",
52
+ "url": "git+https://github.com/schift-io/schift.git",
53
+ "directory": "packages/knowledge-scope-cli"
54
+ },
55
+ "publishConfig": {
56
+ "access": "public"
57
+ }
58
+ }