@gmickel/gno 1.27.1 → 1.29.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.
- package/README.md +46 -20
- package/assets/skill/SKILL.md +59 -1
- package/browser-extension/artifacts/gno-browser-clipper-v1.29.0.zip +0 -0
- package/browser-extension/artifacts/gno-browser-clipper-v1.29.0.zip.sha256 +1 -0
- package/browser-extension/dist/chunk-b2zm0jjd.js +50 -0
- package/browser-extension/dist/manifest.json +1 -1
- package/browser-extension/dist/preview.html +1 -1
- package/browser-extension/dist/service-worker.js +6 -6
- package/package.json +2 -2
- package/spec/cli.md +82 -5
- package/spec/db/schema.sql +31 -0
- package/spec/mcp.md +71 -0
- package/spec/output-schemas/ask.schema.json +156 -1
- package/spec/output-schemas/browser-clip-preview.schema.json +30 -0
- package/spec/output-schemas/collection-egress-check.schema.json +91 -0
- package/spec/output-schemas/collection-egress-policy-set.schema.json +56 -0
- package/spec/output-schemas/collection-egress-policy.schema.json +41 -0
- package/spec/output-schemas/context-capsule-v1.schema.json +183 -3
- package/spec/output-schemas/context-capsule-verification.schema.json +1 -1
- package/spec/output-schemas/egress-audit-management.schema.json +88 -0
- package/spec/output-schemas/get.schema.json +94 -0
- package/spec/output-schemas/mcp-http-error.schema.json +113 -2
- package/spec/output-schemas/mcp-job-status.schema.json +28 -0
- package/spec/output-schemas/multi-get.schema.json +128 -0
- package/spec/output-schemas/publish-artifact.schema.json +32 -0
- package/spec/output-schemas/record-import.schema.json +223 -0
- package/spec/output-schemas/retrieval-trace-common.schema.json +31 -0
- package/spec/output-schemas/retrieval-trace-export.schema.json +3 -0
- package/spec/output-schemas/retrieval-trace-qrels.schema.json +3 -0
- package/spec/output-schemas/retrieval-trace-summary.schema.json +4 -0
- package/spec/output-schemas/search-result.schema.json +94 -0
- package/spec/output-schemas/search-results.schema.json +155 -0
- package/spec/project-profile.schema.json +66 -0
- package/src/app/context-format.ts +1 -1
- package/src/app/context-runtime-contract.ts +16 -7
- package/src/cli/commands/ask.ts +7 -0
- package/src/cli/commands/collection/index.ts +5 -0
- package/src/cli/commands/collection/policy.ts +126 -0
- package/src/cli/commands/context-build.ts +5 -0
- package/src/cli/commands/daemon.ts +45 -3
- package/src/cli/commands/egress-audit.ts +68 -0
- package/src/cli/commands/embed.ts +2 -0
- package/src/cli/commands/get.ts +12 -2
- package/src/cli/commands/index-cmd.ts +13 -0
- package/src/cli/commands/multi-get.ts +9 -2
- package/src/cli/commands/query.ts +12 -0
- package/src/cli/commands/replay.ts +13 -3
- package/src/cli/commands/shared.ts +28 -0
- package/src/cli/commands/update.ts +5 -0
- package/src/cli/commands/vsearch.ts +3 -1
- package/src/cli/program.ts +127 -0
- package/src/config/index.ts +9 -0
- package/src/config/project-profile.ts +2 -0
- package/src/config/types.ts +66 -0
- package/src/converters/adapters/browser-export/adapter.ts +199 -0
- package/src/converters/adapters/browser-export/formats.ts +358 -0
- package/src/converters/adapters/email/adapter.ts +429 -0
- package/src/converters/adapters/email/html.ts +162 -0
- package/src/converters/adapters/email/mime.ts +454 -0
- package/src/converters/adapters/email/parameters.ts +77 -0
- package/src/converters/adapters/ical/adapter.ts +475 -0
- package/src/converters/adapters/ical/recurrence.ts +186 -0
- package/src/converters/adapters/jsonl/adapter.ts +238 -0
- package/src/converters/adapters/jsonl/config.ts +105 -0
- package/src/converters/adapters/shared/html-text.ts +165 -0
- package/src/converters/adapters/shared/record-utils.ts +79 -0
- package/src/converters/adapters/shared/utf8-lines.ts +141 -0
- package/src/converters/adapters/transcript/adapter.ts +295 -0
- package/src/converters/adapters/transcript/json.ts +184 -0
- package/src/converters/adapters/transcript/model.ts +171 -0
- package/src/converters/adapters/transcript/text.ts +58 -0
- package/src/converters/adapters/transcript/timed.ts +152 -0
- package/src/converters/index.ts +11 -1
- package/src/converters/mime.ts +8 -0
- package/src/converters/pipeline.ts +15 -1
- package/src/converters/registry.ts +37 -1
- package/src/converters/types.ts +136 -0
- package/src/core/browser-clip.ts +16 -1
- package/src/core/collection-egress-policy-projection.ts +28 -0
- package/src/core/collection-egress-policy-service.ts +443 -0
- package/src/core/collection-egress-policy-validation.ts +242 -0
- package/src/core/config-mutation.ts +31 -19
- package/src/core/context-capsule-schema.ts +198 -1
- package/src/core/context-capsule-validation.ts +4 -4
- package/src/core/context-capsule-verification.ts +5 -1
- package/src/core/context-capsule.ts +177 -112
- package/src/core/context-evidence.ts +93 -15
- package/src/core/destination-classifier.ts +402 -0
- package/src/core/document-capabilities.ts +12 -0
- package/src/core/egress-audit.ts +239 -0
- package/src/core/egress-authorization.ts +50 -0
- package/src/core/egress-enforcement.ts +264 -0
- package/src/core/egress-policy.ts +440 -0
- package/src/core/egress-provenance.ts +336 -0
- package/src/core/job-manager.ts +37 -0
- package/src/core/network-boundary-inventory.ts +261 -0
- package/src/core/project-profile-apply-state.ts +5 -0
- package/src/core/project-profile.ts +4 -0
- package/src/core/record-metadata.ts +49 -0
- package/src/core/retrieval-qrels.ts +6 -0
- package/src/core/retrieval-replay.ts +18 -4
- package/src/core/retrieval-trace-export.ts +23 -4
- package/src/core/retrieval-trace-management-helpers.ts +1 -0
- package/src/core/retrieval-trace-management-types.ts +3 -0
- package/src/core/retrieval-trace-management.ts +9 -1
- package/src/core/retrieval-trace-session.ts +94 -0
- package/src/core/retrieval-trace.ts +22 -0
- package/src/ingestion/record-adapter-canonical.ts +433 -0
- package/src/ingestion/record-adapter.ts +448 -0
- package/src/ingestion/record-container.ts +704 -0
- package/src/ingestion/record-path.ts +20 -0
- package/src/ingestion/record-sync.ts +70 -0
- package/src/ingestion/sync.ts +243 -36
- package/src/ingestion/types.ts +71 -1
- package/src/ingestion/walker.ts +31 -11
- package/src/llm/errors.ts +10 -0
- package/src/llm/http-inference.ts +175 -0
- package/src/llm/http-policy.ts +537 -0
- package/src/llm/httpEmbedding.ts +47 -28
- package/src/llm/httpGeneration.ts +31 -18
- package/src/llm/httpRerank.ts +30 -18
- package/src/llm/index.ts +1 -0
- package/src/llm/nodeLlamaCpp/adapter.ts +55 -20
- package/src/llm/pinned-http-connection.ts +177 -0
- package/src/mcp/context.ts +53 -1
- package/src/mcp/http-egress.ts +220 -0
- package/src/mcp/http-security.ts +32 -21
- package/src/mcp/http-session.ts +13 -2
- package/src/mcp/http-transport.ts +96 -6
- package/src/mcp/sync-egress.ts +24 -0
- package/src/mcp/tools/add-collection.ts +4 -0
- package/src/mcp/tools/ask.ts +1 -1
- package/src/mcp/tools/context.ts +9 -2
- package/src/mcp/tools/egress.ts +247 -0
- package/src/mcp/tools/embed.ts +1 -0
- package/src/mcp/tools/get.ts +10 -2
- package/src/mcp/tools/index-cmd.ts +7 -0
- package/src/mcp/tools/index.ts +98 -0
- package/src/mcp/tools/multi-get.ts +9 -2
- package/src/mcp/tools/query.ts +10 -0
- package/src/mcp/tools/remove-collection.ts +4 -0
- package/src/mcp/tools/sync.ts +6 -0
- package/src/mcp/tools/trace.ts +7 -1
- package/src/mcp/tools/vsearch.ts +1 -0
- package/src/mcp/tools/workspace-write.ts +2 -0
- package/src/pipeline/egress-lineage.ts +124 -0
- package/src/pipeline/filters.ts +1 -1
- package/src/pipeline/graph-retrieval.ts +7 -4
- package/src/pipeline/hybrid.ts +21 -4
- package/src/pipeline/result-context.ts +12 -4
- package/src/pipeline/search.ts +23 -4
- package/src/pipeline/types.ts +6 -0
- package/src/pipeline/vsearch.ts +67 -28
- package/src/publish/artifact.ts +31 -3
- package/src/publish/export-service.ts +25 -0
- package/src/sdk/client.ts +119 -2
- package/src/sdk/documents.ts +13 -5
- package/src/sdk/embed.ts +1 -0
- package/src/sdk/types.ts +33 -0
- package/src/serve/browse-tree.ts +4 -2
- package/src/serve/clipper-capture.ts +5 -1
- package/src/serve/closed-json.ts +61 -0
- package/src/serve/config-sync.ts +4 -1
- package/src/serve/context.ts +1 -0
- package/src/serve/doc-events.ts +110 -39
- package/src/serve/public/components/CollectionEgressCheckPanel.tsx +411 -0
- package/src/serve/public/components/CollectionEgressPolicyEditor.tsx +78 -0
- package/src/serve/public/components/CollectionModelDialog.tsx +93 -9
- package/src/serve/public/components/EgressAuditPanel.tsx +278 -0
- package/src/serve/public/globals.built.css +1 -1
- package/src/serve/public/pages/Collections.tsx +3 -0
- package/src/serve/resident-request.ts +80 -3
- package/src/serve/resident-runtime.ts +63 -1
- package/src/serve/routes/api.ts +237 -65
- package/src/serve/routes/clipper.ts +64 -1
- package/src/serve/routes/mcp.ts +6 -0
- package/src/serve/routes/traces.ts +27 -4
- package/src/serve/server.ts +118 -7
- package/src/store/migrations/022-record-export-lineage.ts +42 -0
- package/src/store/migrations/023-collection-egress-policy.ts +61 -0
- package/src/store/migrations/024-egress-derived-lineage.ts +121 -0
- package/src/store/migrations/025-collection-egress-policy-revision.ts +40 -0
- package/src/store/migrations/index.ts +8 -0
- package/src/store/retrieval-trace-codec.ts +15 -0
- package/src/store/sqlite/adapter.ts +284 -14
- package/src/store/sqlite/change-journal-store.ts +41 -2
- package/src/store/sqlite/egress-audit-store.ts +485 -0
- package/src/store/sqlite/retrieval-trace-management-store.ts +47 -6
- package/src/store/sqlite/retrieval-trace-retention.ts +2 -0
- package/src/store/sqlite/retrieval-trace-rows.ts +8 -1
- package/src/store/sqlite/retrieval-trace-store.ts +104 -5
- package/src/store/types.ts +166 -1
- package/browser-extension/artifacts/gno-browser-clipper-v1.27.1.zip +0 -0
- package/browser-extension/artifacts/gno-browser-clipper-v1.27.1.zip.sha256 +0 -1
- package/browser-extension/dist/chunk-vn5f663b.js +0 -50
|
@@ -3,8 +3,10 @@ import { z } from "zod";
|
|
|
3
3
|
import { canonicalizeIndexName } from "../app/index-name";
|
|
4
4
|
import {
|
|
5
5
|
contextCapsulePayloadV1Schema,
|
|
6
|
-
|
|
6
|
+
contextCapsulePayloadV1_1Schema,
|
|
7
|
+
type ContextCapsulePayload,
|
|
7
8
|
} from "./context-capsule-schema";
|
|
9
|
+
import { createEgressLineage, type EgressLineage } from "./egress-provenance";
|
|
8
10
|
|
|
9
11
|
const sha256Schema = z.string().regex(/^[a-f0-9]{64}$/);
|
|
10
12
|
|
|
@@ -51,116 +53,155 @@ const normalizeSet = (values: readonly string[]): string[] =>
|
|
|
51
53
|
[...new Set(values.map(normalizeText))].sort(compareCodeUnits);
|
|
52
54
|
|
|
53
55
|
const normalizePayload = (
|
|
54
|
-
value:
|
|
55
|
-
):
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
: normalizeText(value.scope.uriPrefix),
|
|
67
|
-
tagsAll: normalizeSet(value.scope.tagsAll),
|
|
68
|
-
tagsAny: normalizeSet(value.scope.tagsAny),
|
|
69
|
-
categories: normalizeSet(value.scope.categories),
|
|
70
|
-
since: normalizeDate(value.scope.since),
|
|
71
|
-
until: normalizeDate(value.scope.until),
|
|
72
|
-
},
|
|
73
|
-
retrieval: {
|
|
74
|
-
...value.retrieval,
|
|
75
|
-
facets: normalizeSet(value.retrieval.facets),
|
|
76
|
-
queryVariants: value.retrieval.queryVariants.map(normalizeText),
|
|
77
|
-
request: {
|
|
78
|
-
...value.retrieval.request,
|
|
79
|
-
author:
|
|
80
|
-
value.retrieval.request.author === null
|
|
56
|
+
value: ContextCapsulePayload
|
|
57
|
+
): ContextCapsulePayload =>
|
|
58
|
+
({
|
|
59
|
+
...value,
|
|
60
|
+
goal: normalizeText(value.goal),
|
|
61
|
+
query: normalizeText(value.query),
|
|
62
|
+
scope: {
|
|
63
|
+
...value.scope,
|
|
64
|
+
indexName: canonicalizeIndexName(value.scope.indexName),
|
|
65
|
+
collections: normalizeSet(value.scope.collections),
|
|
66
|
+
uriPrefix:
|
|
67
|
+
value.scope.uriPrefix === null
|
|
81
68
|
? null
|
|
82
|
-
: normalizeText(value.
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
69
|
+
: normalizeText(value.scope.uriPrefix),
|
|
70
|
+
tagsAll: normalizeSet(value.scope.tagsAll),
|
|
71
|
+
tagsAny: normalizeSet(value.scope.tagsAny),
|
|
72
|
+
categories: normalizeSet(value.scope.categories),
|
|
73
|
+
since: normalizeDate(value.scope.since),
|
|
74
|
+
until: normalizeDate(value.scope.until),
|
|
75
|
+
},
|
|
76
|
+
retrieval: {
|
|
77
|
+
...value.retrieval,
|
|
78
|
+
facets: normalizeSet(value.retrieval.facets),
|
|
79
|
+
queryVariants: value.retrieval.queryVariants.map(normalizeText),
|
|
80
|
+
request: {
|
|
81
|
+
...value.retrieval.request,
|
|
82
|
+
author:
|
|
83
|
+
value.retrieval.request.author === null
|
|
84
|
+
? null
|
|
85
|
+
: normalizeText(value.retrieval.request.author),
|
|
86
|
+
lang:
|
|
87
|
+
value.retrieval.request.lang === null
|
|
88
|
+
? null
|
|
89
|
+
: normalizeText(value.retrieval.request.lang),
|
|
90
|
+
...(value.retrieval.request.intent === undefined
|
|
91
|
+
? {}
|
|
92
|
+
: {
|
|
93
|
+
intent:
|
|
94
|
+
value.retrieval.request.intent === null
|
|
95
|
+
? null
|
|
96
|
+
: normalizeText(value.retrieval.request.intent),
|
|
97
|
+
}),
|
|
98
|
+
...(value.retrieval.request.exclude === undefined
|
|
99
|
+
? {}
|
|
100
|
+
: { exclude: normalizeSet(value.retrieval.request.exclude) }),
|
|
101
|
+
queryModes: value.retrieval.request.queryModes.map((mode) => ({
|
|
102
|
+
...mode,
|
|
103
|
+
text: normalizeText(mode.text),
|
|
104
|
+
})),
|
|
105
|
+
},
|
|
106
|
+
capabilityStates: Object.fromEntries(
|
|
107
|
+
Object.entries(value.retrieval.capabilityStates).map(([key, state]) => [
|
|
108
|
+
key,
|
|
109
|
+
{ ...state, fallbackReasons: normalizeSet(state.fallbackReasons) },
|
|
110
|
+
])
|
|
111
|
+
) as typeof value.retrieval.capabilityStates,
|
|
112
|
+
},
|
|
113
|
+
fallbacks: [...value.fallbacks].sort((left, right) =>
|
|
114
|
+
compareCodeUnits(
|
|
115
|
+
`${left.code}\0${left.capability}`,
|
|
116
|
+
`${right.code}\0${right.capability}`
|
|
117
|
+
)
|
|
118
|
+
),
|
|
119
|
+
...(value.schemaVersion === "1.1"
|
|
120
|
+
? {
|
|
121
|
+
egressLineage: {
|
|
122
|
+
...value.egressLineage,
|
|
123
|
+
sources: [...value.egressLineage.sources],
|
|
124
|
+
},
|
|
125
|
+
}
|
|
126
|
+
: {}),
|
|
127
|
+
evidence: value.evidence.map((item) => ({
|
|
128
|
+
...item,
|
|
129
|
+
title: item.title === null ? null : normalizeText(item.title),
|
|
130
|
+
heading: item.heading === null ? null : normalizeText(item.heading),
|
|
131
|
+
modifiedAt: normalizeDate(item.modifiedAt),
|
|
132
|
+
documentDate: normalizeDocumentDate(item.documentDate),
|
|
133
|
+
observedAt: normalizeDate(item.observedAt),
|
|
134
|
+
contextIds: normalizeSet(item.contextIds),
|
|
135
|
+
...(item.egressLineage === undefined
|
|
136
|
+
? {}
|
|
137
|
+
: {
|
|
138
|
+
egressLineage: {
|
|
139
|
+
...item.egressLineage,
|
|
140
|
+
sources: [...item.egressLineage.sources],
|
|
141
|
+
},
|
|
142
|
+
}),
|
|
143
|
+
...(item.retrievalSources === undefined
|
|
88
144
|
? {}
|
|
89
145
|
: {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
: normalizeText(value.retrieval.request.intent),
|
|
146
|
+
retrievalSources: [...new Set(item.retrievalSources)].sort(
|
|
147
|
+
compareCodeUnits
|
|
148
|
+
),
|
|
94
149
|
}),
|
|
95
|
-
|
|
150
|
+
facets: normalizeSet(item.facets),
|
|
151
|
+
...(item.record === undefined
|
|
96
152
|
? {}
|
|
97
|
-
: {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
153
|
+
: {
|
|
154
|
+
record: {
|
|
155
|
+
...item.record,
|
|
156
|
+
anchors: item.record.anchors.map((anchor) => ({
|
|
157
|
+
...anchor,
|
|
158
|
+
value: normalizeText(anchor.value),
|
|
159
|
+
...(anchor.endValue === undefined
|
|
160
|
+
? {}
|
|
161
|
+
: { endValue: normalizeText(anchor.endValue) }),
|
|
162
|
+
})),
|
|
163
|
+
...(item.record.participants === undefined
|
|
164
|
+
? {}
|
|
165
|
+
: { participants: normalizeSet(item.record.participants) }),
|
|
166
|
+
...(item.record.categories === undefined
|
|
167
|
+
? {}
|
|
168
|
+
: { categories: normalizeSet(item.record.categories) }),
|
|
169
|
+
},
|
|
170
|
+
}),
|
|
171
|
+
})),
|
|
172
|
+
guidance: {
|
|
173
|
+
...value.guidance,
|
|
174
|
+
configuredContexts: [...value.guidance.configuredContexts]
|
|
175
|
+
.map((item) => ({
|
|
176
|
+
...item,
|
|
177
|
+
scopeKey: normalizeText(item.scopeKey),
|
|
178
|
+
text: normalizeText(item.text),
|
|
179
|
+
}))
|
|
180
|
+
.sort((left, right) =>
|
|
181
|
+
compareCodeUnits(left.contextId, right.contextId)
|
|
182
|
+
),
|
|
102
183
|
},
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
observedAt: normalizeDate(item.observedAt),
|
|
123
|
-
contextIds: normalizeSet(item.contextIds),
|
|
124
|
-
...(item.retrievalSources === undefined
|
|
125
|
-
? {}
|
|
126
|
-
: {
|
|
127
|
-
retrievalSources: [...new Set(item.retrievalSources)].sort(
|
|
128
|
-
compareCodeUnits
|
|
129
|
-
),
|
|
130
|
-
}),
|
|
131
|
-
facets: normalizeSet(item.facets),
|
|
132
|
-
})),
|
|
133
|
-
guidance: {
|
|
134
|
-
...value.guidance,
|
|
135
|
-
configuredContexts: [...value.guidance.configuredContexts]
|
|
136
|
-
.map((item) => ({
|
|
137
|
-
...item,
|
|
138
|
-
scopeKey: normalizeText(item.scopeKey),
|
|
139
|
-
text: normalizeText(item.text),
|
|
140
|
-
}))
|
|
141
|
-
.sort((left, right) => compareCodeUnits(left.contextId, right.contextId)),
|
|
142
|
-
},
|
|
143
|
-
coverage: {
|
|
144
|
-
...value.coverage,
|
|
145
|
-
requestedFacets: normalizeSet(value.coverage.requestedFacets),
|
|
146
|
-
coveredFacets: [...value.coverage.coveredFacets]
|
|
147
|
-
.map((item) => ({
|
|
148
|
-
facet: normalizeText(item.facet),
|
|
149
|
-
evidenceIds: normalizeSet(item.evidenceIds),
|
|
150
|
-
}))
|
|
151
|
-
.sort((left, right) => compareCodeUnits(left.facet, right.facet)),
|
|
152
|
-
unresolvedFacets: normalizeSet(value.coverage.unresolvedFacets),
|
|
153
|
-
gaps: [...value.coverage.gaps].sort((left, right) =>
|
|
154
|
-
compareCodeUnits(
|
|
155
|
-
`${left.facet}\0${left.code}`,
|
|
156
|
-
`${right.facet}\0${right.code}`
|
|
157
|
-
)
|
|
184
|
+
coverage: {
|
|
185
|
+
...value.coverage,
|
|
186
|
+
requestedFacets: normalizeSet(value.coverage.requestedFacets),
|
|
187
|
+
coveredFacets: [...value.coverage.coveredFacets]
|
|
188
|
+
.map((item) => ({
|
|
189
|
+
facet: normalizeText(item.facet),
|
|
190
|
+
evidenceIds: normalizeSet(item.evidenceIds),
|
|
191
|
+
}))
|
|
192
|
+
.sort((left, right) => compareCodeUnits(left.facet, right.facet)),
|
|
193
|
+
unresolvedFacets: normalizeSet(value.coverage.unresolvedFacets),
|
|
194
|
+
gaps: [...value.coverage.gaps].sort((left, right) =>
|
|
195
|
+
compareCodeUnits(
|
|
196
|
+
`${left.facet}\0${left.code}`,
|
|
197
|
+
`${right.facet}\0${right.code}`
|
|
198
|
+
)
|
|
199
|
+
),
|
|
200
|
+
},
|
|
201
|
+
warnings: [...value.warnings].sort((left, right) =>
|
|
202
|
+
compareCodeUnits(left.code, right.code)
|
|
158
203
|
),
|
|
159
|
-
}
|
|
160
|
-
warnings: [...value.warnings].sort((left, right) =>
|
|
161
|
-
compareCodeUnits(left.code, right.code)
|
|
162
|
-
),
|
|
163
|
-
});
|
|
204
|
+
}) as ContextCapsulePayload;
|
|
164
205
|
|
|
165
206
|
export type ContextCapsuleErrorCode =
|
|
166
207
|
| "identity_mismatch"
|
|
@@ -247,9 +288,14 @@ const contractError = (
|
|
|
247
288
|
);
|
|
248
289
|
};
|
|
249
290
|
|
|
250
|
-
const
|
|
291
|
+
const contextCapsulePayloadSchema = z.union([
|
|
292
|
+
contextCapsulePayloadV1Schema,
|
|
293
|
+
contextCapsulePayloadV1_1Schema,
|
|
294
|
+
]);
|
|
295
|
+
|
|
296
|
+
const parsePayload = (input: unknown): ContextCapsulePayload => {
|
|
251
297
|
try {
|
|
252
|
-
return
|
|
298
|
+
return contextCapsulePayloadSchema.parse(input);
|
|
253
299
|
} catch (error) {
|
|
254
300
|
throw contractError(input, error);
|
|
255
301
|
}
|
|
@@ -259,7 +305,7 @@ export interface ContextCapsuleCreateOptions {
|
|
|
259
305
|
countTokens?: (accountingJson: string) => number;
|
|
260
306
|
}
|
|
261
307
|
|
|
262
|
-
const identityPayload = (payload:
|
|
308
|
+
const identityPayload = (payload: ContextCapsulePayload) => {
|
|
263
309
|
const {
|
|
264
310
|
usedBytes: _usedBytes,
|
|
265
311
|
usedTokens: _usedTokens,
|
|
@@ -268,7 +314,7 @@ const identityPayload = (payload: ContextCapsulePayloadV1) => {
|
|
|
268
314
|
return { ...payload, budget: stableBudget };
|
|
269
315
|
};
|
|
270
316
|
|
|
271
|
-
const accountingPayload = <T extends
|
|
317
|
+
const accountingPayload = <T extends ContextCapsulePayload>(value: T) => {
|
|
272
318
|
const {
|
|
273
319
|
usedBytes: _usedBytes,
|
|
274
320
|
usedTokens: _usedTokens,
|
|
@@ -292,7 +338,7 @@ const activeTokenCount = (
|
|
|
292
338
|
};
|
|
293
339
|
|
|
294
340
|
const fixedPointCapsule = (
|
|
295
|
-
payloadInput:
|
|
341
|
+
payloadInput: ContextCapsulePayload,
|
|
296
342
|
options: ContextCapsuleCreateOptions
|
|
297
343
|
) => {
|
|
298
344
|
const capsuleId = hashCanonical(identityPayload(payloadInput));
|
|
@@ -342,9 +388,10 @@ const fixedPointCapsule = (
|
|
|
342
388
|
);
|
|
343
389
|
};
|
|
344
390
|
|
|
345
|
-
const contextCapsuleBaseV1Schema =
|
|
346
|
-
capsuleId: sha256Schema,
|
|
347
|
-
})
|
|
391
|
+
const contextCapsuleBaseV1Schema = z.union([
|
|
392
|
+
contextCapsulePayloadV1Schema.extend({ capsuleId: sha256Schema }),
|
|
393
|
+
contextCapsulePayloadV1_1Schema.extend({ capsuleId: sha256Schema }),
|
|
394
|
+
]);
|
|
348
395
|
|
|
349
396
|
export const contextCapsuleV1Schema = contextCapsuleBaseV1Schema.superRefine(
|
|
350
397
|
(value, context) => {
|
|
@@ -450,6 +497,24 @@ export const canonicalContextCapsuleJson = (input: unknown): string =>
|
|
|
450
497
|
export const canonicalContextCapsuleAccountingJson = (input: unknown): string =>
|
|
451
498
|
canonicalJson(accountingPayload(parseContextCapsuleV1(input)));
|
|
452
499
|
|
|
500
|
+
/**
|
|
501
|
+
* Runtime-only conservative projection for legacy 1.0 Capsules. Canonical
|
|
502
|
+
* bytes and capsuleId remain governed by the original schema.
|
|
503
|
+
*/
|
|
504
|
+
export const contextCapsuleEgressLineage = (input: unknown): EgressLineage => {
|
|
505
|
+
const capsule = parseContextCapsuleV1(input);
|
|
506
|
+
if (capsule.schemaVersion === "1.1") return capsule.egressLineage;
|
|
507
|
+
return createEgressLineage(
|
|
508
|
+
[...new Set(capsule.evidence.map(({ collection }) => collection))].map(
|
|
509
|
+
(collection) => ({
|
|
510
|
+
collection,
|
|
511
|
+
policy: "local_only" as const,
|
|
512
|
+
source: "legacy_default" as const,
|
|
513
|
+
})
|
|
514
|
+
)
|
|
515
|
+
);
|
|
516
|
+
};
|
|
517
|
+
|
|
453
518
|
export {
|
|
454
519
|
contextCapsuleVerificationEvidenceSchema,
|
|
455
520
|
contextCapsuleVerificationSchema,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/** Strict indexed-evidence loading for Context Capsule compilation. */
|
|
2
2
|
|
|
3
|
+
import type { EgressPolicy } from "../config/types";
|
|
3
4
|
import type { SearchResults } from "../pipeline/types";
|
|
4
5
|
import type {
|
|
5
6
|
ActivationIndexSnapshot,
|
|
@@ -12,7 +13,7 @@ import type {
|
|
|
12
13
|
ContextCanonicalProjection,
|
|
13
14
|
MaterializedContextCandidate,
|
|
14
15
|
} from "./context-budget";
|
|
15
|
-
import type {
|
|
16
|
+
import type { ContextCapsulePayloadV1_1 } from "./context-capsule-schema";
|
|
16
17
|
import type {
|
|
17
18
|
ContextCanonicalPlanDraft,
|
|
18
19
|
ContextCompilerInput,
|
|
@@ -21,6 +22,8 @@ import type {
|
|
|
21
22
|
ContextRetrievalCandidate,
|
|
22
23
|
ContextRetrievalRequest,
|
|
23
24
|
} from "./context-compiler";
|
|
25
|
+
import type { EgressLineage } from "./egress-provenance";
|
|
26
|
+
import type { RecordEvidenceMetadata } from "./record-metadata";
|
|
24
27
|
|
|
25
28
|
import { decorateUriForIndex, deriveDocid, parseUri } from "../app/constants";
|
|
26
29
|
import { canonicalizeIndexName } from "../app/index-name";
|
|
@@ -35,6 +38,8 @@ import {
|
|
|
35
38
|
} from "./context-capsule-validation";
|
|
36
39
|
import { planContextEvidence } from "./context-compiler";
|
|
37
40
|
import { projectContextEvidenceMetadata } from "./context-evidence-metadata";
|
|
41
|
+
import { createEgressLineage, resolveEgressLineage } from "./egress-provenance";
|
|
42
|
+
import { projectRecordEvidenceMetadata } from "./record-metadata";
|
|
38
43
|
import {
|
|
39
44
|
extractInclusiveLines,
|
|
40
45
|
extractSections,
|
|
@@ -80,6 +85,7 @@ export class ContextEvidenceError extends Error {
|
|
|
80
85
|
|
|
81
86
|
export interface ContextEvidenceSnapshot {
|
|
82
87
|
collections: string[];
|
|
88
|
+
egressLineage: EgressLineage;
|
|
83
89
|
contexts: ContextRow[];
|
|
84
90
|
documents: ContextEvidenceSnapshotDocument[];
|
|
85
91
|
contextFingerprint: string;
|
|
@@ -103,7 +109,9 @@ export interface ContextEvidenceValue {
|
|
|
103
109
|
observedAt: null;
|
|
104
110
|
contextIds: string[];
|
|
105
111
|
trust: "untrusted";
|
|
106
|
-
egress: "unavailable";
|
|
112
|
+
egress: EgressPolicy | "unavailable";
|
|
113
|
+
egressLineage?: EgressLineage;
|
|
114
|
+
record?: RecordEvidenceMetadata;
|
|
107
115
|
}
|
|
108
116
|
|
|
109
117
|
export type ContextEvidenceCompilerInput = Omit<
|
|
@@ -114,6 +122,7 @@ export type ContextEvidenceCompilerInput = Omit<
|
|
|
114
122
|
export interface ContextEvidenceProjectionContext {
|
|
115
123
|
contextFingerprint: string;
|
|
116
124
|
indexFingerprint: string;
|
|
125
|
+
egressLineage: EgressLineage;
|
|
117
126
|
}
|
|
118
127
|
|
|
119
128
|
export interface ContextEvidenceCompilerDeps<P> {
|
|
@@ -205,18 +214,34 @@ export const captureContextEvidenceSnapshot = async (
|
|
|
205
214
|
"context_load_failed",
|
|
206
215
|
"Failed to load configured contexts"
|
|
207
216
|
).map((row) => ({ ...row }));
|
|
217
|
+
const collectionRows = unwrapStore(
|
|
218
|
+
await store.getCollections(),
|
|
219
|
+
"collection_load_failed",
|
|
220
|
+
"Failed to load indexed collections"
|
|
221
|
+
);
|
|
208
222
|
const collections =
|
|
209
223
|
requestedCollections.length > 0
|
|
210
224
|
? [...new Set(requestedCollections)].sort(compareCodeUnits)
|
|
211
|
-
: [
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
225
|
+
: [...new Set(collectionRows.map((row) => row.name))].sort(
|
|
226
|
+
compareCodeUnits
|
|
227
|
+
);
|
|
228
|
+
let egressLineage: EgressLineage;
|
|
229
|
+
try {
|
|
230
|
+
egressLineage = resolveEgressLineage(
|
|
231
|
+
collectionRows.map((row) => ({
|
|
232
|
+
collection: row.name,
|
|
233
|
+
policy: row.egressPolicy,
|
|
234
|
+
source: row.egressPolicySource,
|
|
235
|
+
})),
|
|
236
|
+
collections
|
|
237
|
+
);
|
|
238
|
+
} catch (error) {
|
|
239
|
+
throw new ContextEvidenceError(
|
|
240
|
+
"collection_load_failed",
|
|
241
|
+
"Failed to resolve complete collection policy lineage",
|
|
242
|
+
error
|
|
243
|
+
);
|
|
244
|
+
}
|
|
220
245
|
const indexName = canonicalizeIndexName(indexNameInput);
|
|
221
246
|
const indexSnapshots: ReturnType<typeof canonicalIndexSnapshot>[] = [];
|
|
222
247
|
const documents: ContextEvidenceSnapshotDocument[] = [];
|
|
@@ -245,6 +270,7 @@ export const captureContextEvidenceSnapshot = async (
|
|
|
245
270
|
}
|
|
246
271
|
return {
|
|
247
272
|
collections,
|
|
273
|
+
egressLineage,
|
|
248
274
|
contexts,
|
|
249
275
|
documents: documents.sort(
|
|
250
276
|
(left, right) =>
|
|
@@ -253,7 +279,10 @@ export const captureContextEvidenceSnapshot = async (
|
|
|
253
279
|
compareCodeUnits(left.mirrorHash ?? "", right.mirrorHash ?? "")
|
|
254
280
|
),
|
|
255
281
|
contextFingerprint: fingerprintContextRows(contexts),
|
|
256
|
-
indexFingerprint: hashJson(
|
|
282
|
+
indexFingerprint: hashJson({
|
|
283
|
+
snapshots: indexSnapshots,
|
|
284
|
+
egressLineage,
|
|
285
|
+
}),
|
|
257
286
|
};
|
|
258
287
|
};
|
|
259
288
|
|
|
@@ -283,7 +312,7 @@ const referenceDocument = (
|
|
|
283
312
|
!document.active ||
|
|
284
313
|
!document.mirrorHash ||
|
|
285
314
|
parsedUri?.collection !== document.collection ||
|
|
286
|
-
result.source.relPath !== document.relPath ||
|
|
315
|
+
result.source.relPath !== (document.recordSourcePath ?? document.relPath) ||
|
|
287
316
|
sourceHash !== document.sourceHash ||
|
|
288
317
|
mirrorHash !== document.mirrorHash ||
|
|
289
318
|
deriveDocid(document.sourceHash) !== document.docid
|
|
@@ -310,6 +339,21 @@ export const materializeContextEvidenceCandidates = async (
|
|
|
310
339
|
"document_load_failed",
|
|
311
340
|
"Failed to batch-load Context evidence documents"
|
|
312
341
|
);
|
|
342
|
+
const collectionRows = unwrapStore(
|
|
343
|
+
await store.getCollections(),
|
|
344
|
+
"collection_load_failed",
|
|
345
|
+
"Failed to load Context evidence policies"
|
|
346
|
+
);
|
|
347
|
+
const policyByCollection = new Map(
|
|
348
|
+
collectionRows.map((row) => [
|
|
349
|
+
row.name,
|
|
350
|
+
{
|
|
351
|
+
collection: row.name,
|
|
352
|
+
policy: row.egressPolicy,
|
|
353
|
+
source: row.egressPolicySource,
|
|
354
|
+
},
|
|
355
|
+
])
|
|
356
|
+
);
|
|
313
357
|
const alignedDocuments = candidates.map((candidate) =>
|
|
314
358
|
referenceDocument(documents, candidate, indexName)
|
|
315
359
|
);
|
|
@@ -340,6 +384,24 @@ export const materializeContextEvidenceCandidates = async (
|
|
|
340
384
|
return candidates.map((candidate, index) => {
|
|
341
385
|
const result = candidate.result;
|
|
342
386
|
const document = alignedDocuments[index];
|
|
387
|
+
if (!document) {
|
|
388
|
+
throw new ContextEvidenceError(
|
|
389
|
+
"document_load_failed",
|
|
390
|
+
`Document identity is unavailable for ${result.uri}`
|
|
391
|
+
);
|
|
392
|
+
}
|
|
393
|
+
const fallbackPolicy = policyByCollection.get(document.collection);
|
|
394
|
+
if (!result.egressLineage && !fallbackPolicy) {
|
|
395
|
+
throw new ContextEvidenceError(
|
|
396
|
+
"collection_load_failed",
|
|
397
|
+
`Policy lineage is unavailable for ${result.uri}`
|
|
398
|
+
);
|
|
399
|
+
}
|
|
400
|
+
const egressLineage =
|
|
401
|
+
result.egressLineage ??
|
|
402
|
+
createEgressLineage([
|
|
403
|
+
fallbackPolicy as NonNullable<typeof fallbackPolicy>,
|
|
404
|
+
]);
|
|
343
405
|
const metadata = result[SEARCH_RESULT_PLANNER_METADATA];
|
|
344
406
|
const snippetRange = result.snippetRange;
|
|
345
407
|
if (!document?.mirrorHash || !metadata || !snippetRange) {
|
|
@@ -415,7 +477,11 @@ export const materializeContextEvidenceCandidates = async (
|
|
|
415
477
|
observedAt: null,
|
|
416
478
|
contextIds: [...candidate.contextIds],
|
|
417
479
|
trust: "untrusted",
|
|
418
|
-
egress:
|
|
480
|
+
egress: egressLineage.effectivePolicy,
|
|
481
|
+
egressLineage,
|
|
482
|
+
...(projectRecordEvidenceMetadata(document)
|
|
483
|
+
? { record: projectRecordEvidenceMetadata(document) }
|
|
484
|
+
: {}),
|
|
419
485
|
},
|
|
420
486
|
},
|
|
421
487
|
};
|
|
@@ -435,6 +501,7 @@ export const compileContextEvidence = async <P>(
|
|
|
435
501
|
const fingerprints = {
|
|
436
502
|
contextFingerprint: before.contextFingerprint,
|
|
437
503
|
indexFingerprint: before.indexFingerprint,
|
|
504
|
+
egressLineage: before.egressLineage,
|
|
438
505
|
};
|
|
439
506
|
const plan = await planContextEvidence(
|
|
440
507
|
{ ...input, contextSnapshot: before.contexts, observedAt: null },
|
|
@@ -473,7 +540,16 @@ export const compileContextEvidence = async <P>(
|
|
|
473
540
|
export const toContextCapsuleEvidence = (
|
|
474
541
|
candidate: MaterializedContextCandidate<ContextEvidenceValue>,
|
|
475
542
|
selectionRank: number
|
|
476
|
-
):
|
|
543
|
+
): ContextCapsulePayloadV1_1["evidence"][number] => {
|
|
544
|
+
if (
|
|
545
|
+
candidate.value.egress === "unavailable" ||
|
|
546
|
+
candidate.value.egressLineage === undefined
|
|
547
|
+
) {
|
|
548
|
+
throw new ContextEvidenceError(
|
|
549
|
+
"collection_load_failed",
|
|
550
|
+
`Policy lineage is unavailable for ${candidate.uri}`
|
|
551
|
+
);
|
|
552
|
+
}
|
|
477
553
|
const identity = {
|
|
478
554
|
uri: candidate.uri,
|
|
479
555
|
docid: candidate.docid,
|
|
@@ -487,6 +563,8 @@ export const toContextCapsuleEvidence = (
|
|
|
487
563
|
evidenceId: contextCapsuleEvidenceIdentity(identity),
|
|
488
564
|
...identity,
|
|
489
565
|
...candidate.value,
|
|
566
|
+
egress: candidate.value.egress,
|
|
567
|
+
egressLineage: candidate.value.egressLineage,
|
|
490
568
|
text: candidate.text,
|
|
491
569
|
retrievalRank: candidate.retrievalRank,
|
|
492
570
|
selectionRank,
|