@gmickel/gno 1.28.0 → 1.29.1

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 (143) hide show
  1. package/README.md +46 -20
  2. package/assets/skill/SKILL.md +33 -0
  3. package/browser-extension/artifacts/gno-browser-clipper-v1.29.1.zip +0 -0
  4. package/browser-extension/artifacts/gno-browser-clipper-v1.29.1.zip.sha256 +1 -0
  5. package/browser-extension/dist/chunk-b2zm0jjd.js +50 -0
  6. package/browser-extension/dist/manifest.json +1 -1
  7. package/browser-extension/dist/preview.html +1 -1
  8. package/browser-extension/dist/service-worker.js +6 -6
  9. package/package.json +1 -1
  10. package/spec/cli.md +41 -1
  11. package/spec/db/schema.sql +19 -0
  12. package/spec/mcp.md +66 -0
  13. package/spec/output-schemas/ask.schema.json +31 -1
  14. package/spec/output-schemas/browser-clip-preview.schema.json +30 -0
  15. package/spec/output-schemas/collection-egress-check.schema.json +91 -0
  16. package/spec/output-schemas/collection-egress-policy-set.schema.json +56 -0
  17. package/spec/output-schemas/collection-egress-policy.schema.json +41 -0
  18. package/spec/output-schemas/context-capsule-v1.schema.json +89 -2
  19. package/spec/output-schemas/context-capsule-verification.schema.json +1 -1
  20. package/spec/output-schemas/egress-audit-management.schema.json +88 -0
  21. package/spec/output-schemas/mcp-http-error.schema.json +113 -2
  22. package/spec/output-schemas/publish-artifact.schema.json +32 -0
  23. package/spec/output-schemas/record-import.schema.json +30 -0
  24. package/spec/output-schemas/retrieval-trace-common.schema.json +31 -0
  25. package/spec/output-schemas/retrieval-trace-export.schema.json +3 -0
  26. package/spec/output-schemas/retrieval-trace-qrels.schema.json +3 -0
  27. package/spec/output-schemas/retrieval-trace-summary.schema.json +4 -0
  28. package/spec/output-schemas/search-results.schema.json +30 -0
  29. package/src/app/context-runtime-contract.ts +16 -7
  30. package/src/cli/commands/ask.ts +7 -0
  31. package/src/cli/commands/collection/index.ts +5 -0
  32. package/src/cli/commands/collection/policy.ts +126 -0
  33. package/src/cli/commands/context-build.ts +5 -0
  34. package/src/cli/commands/daemon.ts +45 -3
  35. package/src/cli/commands/egress-audit.ts +68 -0
  36. package/src/cli/commands/embed.ts +2 -0
  37. package/src/cli/commands/query.ts +12 -0
  38. package/src/cli/commands/replay.ts +13 -3
  39. package/src/cli/commands/vsearch.ts +3 -1
  40. package/src/cli/program.ts +123 -0
  41. package/src/config/index.ts +9 -0
  42. package/src/config/types.ts +50 -0
  43. package/src/core/browser-clip.ts +16 -1
  44. package/src/core/collection-egress-policy-projection.ts +28 -0
  45. package/src/core/collection-egress-policy-service.ts +443 -0
  46. package/src/core/collection-egress-policy-validation.ts +242 -0
  47. package/src/core/config-mutation.ts +31 -19
  48. package/src/core/context-capsule-schema.ts +111 -1
  49. package/src/core/context-capsule-validation.ts +4 -4
  50. package/src/core/context-capsule-verification.ts +5 -1
  51. package/src/core/context-capsule.ts +177 -132
  52. package/src/core/context-evidence.ts +86 -14
  53. package/src/core/destination-classifier.ts +402 -0
  54. package/src/core/egress-audit.ts +239 -0
  55. package/src/core/egress-authorization.ts +50 -0
  56. package/src/core/egress-enforcement.ts +264 -0
  57. package/src/core/egress-policy.ts +440 -0
  58. package/src/core/egress-provenance.ts +336 -0
  59. package/src/core/job-manager.ts +37 -0
  60. package/src/core/network-boundary-inventory.ts +261 -0
  61. package/src/core/retrieval-qrels.ts +6 -0
  62. package/src/core/retrieval-replay.ts +18 -4
  63. package/src/core/retrieval-trace-export.ts +23 -4
  64. package/src/core/retrieval-trace-management-helpers.ts +1 -0
  65. package/src/core/retrieval-trace-management-types.ts +3 -0
  66. package/src/core/retrieval-trace-management.ts +9 -1
  67. package/src/core/retrieval-trace-session.ts +94 -0
  68. package/src/core/retrieval-trace.ts +22 -0
  69. package/src/ingestion/record-adapter.ts +12 -1
  70. package/src/ingestion/record-container.ts +38 -22
  71. package/src/ingestion/sync.ts +15 -0
  72. package/src/ingestion/types.ts +2 -0
  73. package/src/llm/errors.ts +10 -0
  74. package/src/llm/http-inference.ts +175 -0
  75. package/src/llm/http-policy.ts +537 -0
  76. package/src/llm/httpEmbedding.ts +47 -28
  77. package/src/llm/httpGeneration.ts +31 -18
  78. package/src/llm/httpRerank.ts +30 -18
  79. package/src/llm/index.ts +1 -0
  80. package/src/llm/nodeLlamaCpp/adapter.ts +55 -20
  81. package/src/llm/pinned-http-connection.ts +177 -0
  82. package/src/mcp/context.ts +53 -1
  83. package/src/mcp/http-egress.ts +220 -0
  84. package/src/mcp/http-security.ts +32 -21
  85. package/src/mcp/http-session.ts +13 -2
  86. package/src/mcp/http-transport.ts +96 -6
  87. package/src/mcp/sync-egress.ts +24 -0
  88. package/src/mcp/tools/add-collection.ts +4 -0
  89. package/src/mcp/tools/ask.ts +1 -1
  90. package/src/mcp/tools/context.ts +9 -2
  91. package/src/mcp/tools/egress.ts +247 -0
  92. package/src/mcp/tools/embed.ts +1 -0
  93. package/src/mcp/tools/index-cmd.ts +7 -0
  94. package/src/mcp/tools/index.ts +98 -0
  95. package/src/mcp/tools/query.ts +10 -0
  96. package/src/mcp/tools/remove-collection.ts +4 -0
  97. package/src/mcp/tools/sync.ts +6 -0
  98. package/src/mcp/tools/trace.ts +7 -1
  99. package/src/mcp/tools/vsearch.ts +1 -0
  100. package/src/pipeline/egress-lineage.ts +124 -0
  101. package/src/pipeline/hybrid.ts +14 -0
  102. package/src/pipeline/search.ts +12 -0
  103. package/src/pipeline/types.ts +3 -0
  104. package/src/pipeline/vsearch.ts +41 -20
  105. package/src/publish/artifact.ts +31 -3
  106. package/src/publish/export-service.ts +25 -0
  107. package/src/sdk/client.ts +119 -2
  108. package/src/sdk/embed.ts +1 -0
  109. package/src/sdk/types.ts +33 -0
  110. package/src/serve/clipper-capture.ts +5 -1
  111. package/src/serve/closed-json.ts +61 -0
  112. package/src/serve/config-sync.ts +4 -1
  113. package/src/serve/context.ts +1 -0
  114. package/src/serve/doc-events.ts +110 -39
  115. package/src/serve/public/components/CollectionEgressCheckPanel.tsx +411 -0
  116. package/src/serve/public/components/CollectionEgressPolicyEditor.tsx +78 -0
  117. package/src/serve/public/components/CollectionModelDialog.tsx +93 -9
  118. package/src/serve/public/components/EgressAuditPanel.tsx +278 -0
  119. package/src/serve/public/globals.built.css +1 -1
  120. package/src/serve/public/pages/Collections.tsx +3 -0
  121. package/src/serve/resident-request.ts +80 -3
  122. package/src/serve/resident-runtime.ts +63 -1
  123. package/src/serve/routes/api.ts +174 -0
  124. package/src/serve/routes/clipper.ts +64 -1
  125. package/src/serve/routes/mcp.ts +6 -0
  126. package/src/serve/routes/traces.ts +27 -4
  127. package/src/serve/server.ts +118 -7
  128. package/src/store/migrations/023-collection-egress-policy.ts +61 -0
  129. package/src/store/migrations/024-egress-derived-lineage.ts +121 -0
  130. package/src/store/migrations/025-collection-egress-policy-revision.ts +40 -0
  131. package/src/store/migrations/index.ts +6 -0
  132. package/src/store/retrieval-trace-codec.ts +15 -0
  133. package/src/store/sqlite/adapter.ts +170 -7
  134. package/src/store/sqlite/change-journal-store.ts +41 -2
  135. package/src/store/sqlite/egress-audit-store.ts +485 -0
  136. package/src/store/sqlite/retrieval-trace-management-store.ts +47 -6
  137. package/src/store/sqlite/retrieval-trace-retention.ts +2 -0
  138. package/src/store/sqlite/retrieval-trace-rows.ts +8 -1
  139. package/src/store/sqlite/retrieval-trace-store.ts +104 -5
  140. package/src/store/types.ts +126 -1
  141. package/browser-extension/artifacts/gno-browser-clipper-v1.28.0.zip +0 -0
  142. package/browser-extension/artifacts/gno-browser-clipper-v1.28.0.zip.sha256 +0 -1
  143. package/browser-extension/dist/chunk-vn5f663b.js +0 -50
@@ -0,0 +1,88 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://gno.sh/schemas/egress-audit-management.schema.json",
4
+ "title": "Egress audit management output",
5
+ "oneOf": [
6
+ {
7
+ "type": "object",
8
+ "additionalProperties": false,
9
+ "required": ["schemaVersion", "receipts", "nextCursor"],
10
+ "properties": {
11
+ "schemaVersion": { "const": "1.0" },
12
+ "receipts": { "type": "array" },
13
+ "nextCursor": { "type": ["string", "null"] }
14
+ }
15
+ },
16
+ {
17
+ "type": "object",
18
+ "additionalProperties": false,
19
+ "required": ["schemaVersion", "receipt"],
20
+ "properties": {
21
+ "schemaVersion": { "const": "1.0" },
22
+ "receipt": { "type": "object" }
23
+ }
24
+ },
25
+ {
26
+ "type": "object",
27
+ "additionalProperties": false,
28
+ "required": [
29
+ "schemaVersion",
30
+ "retention",
31
+ "receipts",
32
+ "bytes",
33
+ "oldestCreatedAtMs",
34
+ "newestCreatedAtMs"
35
+ ],
36
+ "properties": {
37
+ "schemaVersion": { "const": "1.0" },
38
+ "retention": { "type": "object" },
39
+ "receipts": { "type": "integer", "minimum": 0 },
40
+ "bytes": { "type": "integer", "minimum": 0 },
41
+ "oldestCreatedAtMs": { "type": ["integer", "null"] },
42
+ "newestCreatedAtMs": { "type": ["integer", "null"] }
43
+ }
44
+ },
45
+ {
46
+ "type": "object",
47
+ "additionalProperties": false,
48
+ "required": [
49
+ "schemaVersion",
50
+ "auditId",
51
+ "deleted",
52
+ "physicalCleanup",
53
+ "checkpointedFrames",
54
+ "remainingWalFrames"
55
+ ],
56
+ "properties": {
57
+ "schemaVersion": { "const": "1.0" },
58
+ "auditId": { "type": "string" },
59
+ "deleted": { "const": 1 },
60
+ "physicalCleanup": {
61
+ "enum": ["completed", "wal_busy", "failed"]
62
+ },
63
+ "checkpointedFrames": { "type": "integer" },
64
+ "remainingWalFrames": { "type": "integer" }
65
+ }
66
+ },
67
+ {
68
+ "type": "object",
69
+ "additionalProperties": false,
70
+ "required": [
71
+ "schemaVersion",
72
+ "deleted",
73
+ "physicalCleanup",
74
+ "checkpointedFrames",
75
+ "remainingWalFrames"
76
+ ],
77
+ "properties": {
78
+ "schemaVersion": { "const": "1.0" },
79
+ "deleted": { "type": "integer", "minimum": 0 },
80
+ "physicalCleanup": {
81
+ "enum": ["completed", "wal_busy", "failed"]
82
+ },
83
+ "checkpointedFrames": { "type": "integer" },
84
+ "remainingWalFrames": { "type": "integer" }
85
+ }
86
+ }
87
+ ]
88
+ }
@@ -13,18 +13,129 @@
13
13
  "additionalProperties": false,
14
14
  "required": ["code", "message"],
15
15
  "properties": {
16
- "code": { "const": -32000 },
16
+ "code": { "enum": [-32000, -32003] },
17
17
  "message": {
18
18
  "enum": [
19
19
  "Unauthorized",
20
20
  "Forbidden",
21
+ "Operation blocked by collection egress policy",
21
22
  "Request body too large",
22
23
  "Too many requests",
23
24
  "Resident runtime unavailable"
24
25
  ]
26
+ },
27
+ "data": {
28
+ "type": "object",
29
+ "additionalProperties": false,
30
+ "required": ["code", "message", "reason", "audit"],
31
+ "properties": {
32
+ "code": { "const": "EGRESS_DENIED" },
33
+ "message": {
34
+ "const": "Operation blocked by collection egress policy"
35
+ },
36
+ "reason": {
37
+ "enum": [
38
+ "LOCAL_DESTINATION",
39
+ "LAN_POLICY_AUTHENTICATED",
40
+ "REMOTE_POLICY_AUTHENTICATED",
41
+ "INVALID_INPUT",
42
+ "NO_COLLECTION_POLICY",
43
+ "COLLECTION_LIMIT_EXCEEDED",
44
+ "INVALID_COLLECTION",
45
+ "UNKNOWN_ACTION",
46
+ "UNKNOWN_DESTINATION",
47
+ "ACTION_DESTINATION_MISMATCH",
48
+ "UNKNOWN_CONTENT_CLASS",
49
+ "UNKNOWN_POLICY",
50
+ "UNKNOWN_POLICY_SOURCE",
51
+ "INVALID_POLICY_SOURCE_PAIR",
52
+ "INVALID_CALLER",
53
+ "CALLER_NOT_AUTHORIZED",
54
+ "AUTHENTICATION_REQUIRED",
55
+ "POLICY_LOCAL_ONLY",
56
+ "POLICY_LAN_ONLY"
57
+ ]
58
+ },
59
+ "audit": {
60
+ "type": "object",
61
+ "additionalProperties": false,
62
+ "required": [
63
+ "action",
64
+ "destinationZone",
65
+ "contentClass",
66
+ "collectionCount",
67
+ "collections",
68
+ "effectivePolicy",
69
+ "effectivePolicySource",
70
+ "callerAuthenticated",
71
+ "callerOperationAuthorized"
72
+ ],
73
+ "properties": {
74
+ "action": {
75
+ "enum": [
76
+ "retrieve",
77
+ "serve",
78
+ "publish",
79
+ "remote_inference",
80
+ "export",
81
+ "clip_write",
82
+ "unknown"
83
+ ]
84
+ },
85
+ "destinationZone": {
86
+ "enum": [
87
+ "local_process",
88
+ "loopback",
89
+ "lan",
90
+ "remote",
91
+ "unknown"
92
+ ]
93
+ },
94
+ "contentClass": {
95
+ "enum": [
96
+ "source",
97
+ "snippet",
98
+ "metadata",
99
+ "attachment",
100
+ "embedding",
101
+ "capsule",
102
+ "audit_log",
103
+ "retrieval_trace",
104
+ "unknown"
105
+ ]
106
+ },
107
+ "collectionCount": { "type": "integer", "minimum": 0 },
108
+ "collections": {
109
+ "type": "array",
110
+ "items": { "type": "string" },
111
+ "maxItems": 64
112
+ },
113
+ "effectivePolicy": {
114
+ "enum": ["local_only", "lan", "remote", "unknown"]
115
+ },
116
+ "effectivePolicySource": {
117
+ "enum": [
118
+ "explicit",
119
+ "config_default",
120
+ "legacy_default",
121
+ "mixed",
122
+ "unknown"
123
+ ]
124
+ },
125
+ "callerAuthenticated": {
126
+ "anyOf": [{ "type": "boolean" }, { "type": "null" }]
127
+ },
128
+ "callerOperationAuthorized": {
129
+ "anyOf": [{ "type": "boolean" }, { "type": "null" }]
130
+ }
131
+ }
132
+ }
133
+ }
25
134
  }
26
135
  }
27
136
  },
28
- "id": { "type": "null" }
137
+ "id": {
138
+ "anyOf": [{ "type": "null" }, { "type": "integer" }, { "type": "string" }]
139
+ }
29
140
  }
30
141
  }
@@ -13,6 +13,7 @@
13
13
  "required": ["version", "source", "exportedAt", "spaces"],
14
14
  "properties": {
15
15
  "version": { "const": 1 },
16
+ "egressLineage": { "$ref": "#/definitions/egressLineage" },
16
17
  "source": { "$ref": "#/definitions/slug" },
17
18
  "exportedAt": { "type": "string", "format": "date-time" },
18
19
  "spaces": {
@@ -33,6 +34,7 @@
33
34
  "required": ["version", "source", "exportedAt", "spaces"],
34
35
  "properties": {
35
36
  "version": { "const": 2 },
37
+ "egressLineage": { "$ref": "#/definitions/egressLineage" },
36
38
  "source": { "$ref": "#/definitions/slug" },
37
39
  "exportedAt": { "type": "string", "format": "date-time" },
38
40
  "spaces": {
@@ -51,6 +53,35 @@
51
53
  "type": "string",
52
54
  "pattern": "^[a-f0-9]{64}$"
53
55
  },
56
+ "egressLineage": {
57
+ "type": "object",
58
+ "additionalProperties": false,
59
+ "required": ["effectivePolicy", "digest", "sources"],
60
+ "properties": {
61
+ "effectivePolicy": { "enum": ["local_only", "lan", "remote"] },
62
+ "digest": { "$ref": "#/definitions/hash" },
63
+ "sources": {
64
+ "type": "array",
65
+ "minItems": 1,
66
+ "uniqueItems": true,
67
+ "items": {
68
+ "type": "object",
69
+ "additionalProperties": false,
70
+ "required": ["collection", "policy", "source"],
71
+ "properties": {
72
+ "collection": {
73
+ "type": "string",
74
+ "pattern": "^[a-z0-9][a-z0-9_-]{0,63}$"
75
+ },
76
+ "policy": { "enum": ["local_only", "lan", "remote"] },
77
+ "source": {
78
+ "enum": ["explicit", "config_default", "legacy_default"]
79
+ }
80
+ }
81
+ }
82
+ }
83
+ }
84
+ },
54
85
  "docid": {
55
86
  "type": "string",
56
87
  "pattern": "^#[a-f0-9]{8}$"
@@ -145,6 +176,7 @@
145
176
  "properties": {
146
177
  "schemaVersion": { "const": "1.0" },
147
178
  "projectionRevision": { "$ref": "#/definitions/hash" },
179
+ "egressLineage": { "$ref": "#/definitions/egressLineage" },
148
180
  "generatedAt": { "type": "string", "format": "date-time" },
149
181
  "visibility": { "const": "public" },
150
182
  "capabilities": {
@@ -26,6 +26,7 @@
26
26
  "type": "string",
27
27
  "pattern": "^[a-f0-9]{64}$"
28
28
  },
29
+ "egressLineage": { "$ref": "#/$defs/egressLineage" },
29
30
  "snapshotState": { "enum": ["complete", "partial"] },
30
31
  "authoritative": { "type": "boolean" },
31
32
  "stoppedByCap": { "type": "boolean" },
@@ -78,6 +79,35 @@
78
79
  }
79
80
  },
80
81
  "$defs": {
82
+ "egressLineage": {
83
+ "type": "object",
84
+ "additionalProperties": false,
85
+ "required": ["effectivePolicy", "digest", "sources"],
86
+ "properties": {
87
+ "effectivePolicy": { "enum": ["local_only", "lan", "remote"] },
88
+ "digest": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
89
+ "sources": {
90
+ "type": "array",
91
+ "minItems": 1,
92
+ "uniqueItems": true,
93
+ "items": {
94
+ "type": "object",
95
+ "additionalProperties": false,
96
+ "required": ["collection", "policy", "source"],
97
+ "properties": {
98
+ "collection": {
99
+ "type": "string",
100
+ "pattern": "^[a-z0-9][a-z0-9_-]{0,63}$"
101
+ },
102
+ "policy": { "enum": ["local_only", "lan", "remote"] },
103
+ "source": {
104
+ "enum": ["explicit", "config_default", "legacy_default"]
105
+ }
106
+ }
107
+ }
108
+ }
109
+ }
110
+ },
81
111
  "attachment": {
82
112
  "type": "object",
83
113
  "additionalProperties": false,
@@ -27,6 +27,35 @@
27
27
  "index": { "$ref": "#/definitions/sha256" }
28
28
  }
29
29
  },
30
+ "egressLineage": {
31
+ "type": "object",
32
+ "additionalProperties": false,
33
+ "required": ["effectivePolicy", "digest", "sources"],
34
+ "properties": {
35
+ "effectivePolicy": { "enum": ["local_only", "lan", "remote"] },
36
+ "digest": { "$ref": "#/definitions/sha256" },
37
+ "sources": {
38
+ "type": "array",
39
+ "minItems": 1,
40
+ "uniqueItems": true,
41
+ "items": {
42
+ "type": "object",
43
+ "additionalProperties": false,
44
+ "required": ["collection", "policy", "source"],
45
+ "properties": {
46
+ "collection": {
47
+ "type": "string",
48
+ "pattern": "^[a-z0-9][a-z0-9_-]{0,63}$"
49
+ },
50
+ "policy": { "enum": ["local_only", "lan", "remote"] },
51
+ "source": {
52
+ "enum": ["explicit", "config_default", "legacy_default"]
53
+ }
54
+ }
55
+ }
56
+ }
57
+ }
58
+ },
30
59
  "summary": { "$ref": "gno://schemas/retrieval-trace-summary@1.0" },
31
60
  "trace": {
32
61
  "type": "object",
@@ -79,6 +108,7 @@
79
108
  }
80
109
  ]
81
110
  },
111
+ "egressLineage": { "$ref": "#/definitions/egressLineage" },
82
112
  "fingerprints": { "$ref": "#/definitions/fingerprints" },
83
113
  "createdAtMs": { "type": "integer", "minimum": 0 },
84
114
  "updatedAtMs": { "type": "integer", "minimum": 0 },
@@ -465,6 +495,7 @@
465
495
  },
466
496
  "format": { "enum": ["agentic-receipt", "qrels"] },
467
497
  "artifactHash": { "$ref": "#/definitions/sha256" },
498
+ "egressLineage": { "$ref": "#/definitions/egressLineage" },
468
499
  "createdAtMs": { "type": "integer", "minimum": 0 }
469
500
  }
470
501
  },
@@ -20,6 +20,9 @@
20
20
  "properties": {
21
21
  "schemaVersion": { "const": "1.0" },
22
22
  "format": { "const": "agentic-receipt" },
23
+ "egressLineage": {
24
+ "$ref": "gno://schemas/retrieval-trace-common@1.0#/definitions/egressLineage"
25
+ },
23
26
  "traces": {
24
27
  "type": "array",
25
28
  "minItems": 1,
@@ -8,6 +8,9 @@
8
8
  "properties": {
9
9
  "schemaVersion": { "const": "1.0" },
10
10
  "format": { "const": "qrels" },
11
+ "egressLineage": {
12
+ "$ref": "gno://schemas/retrieval-trace-common@1.0#/definitions/egressLineage"
13
+ },
11
14
  "cases": {
12
15
  "type": "array",
13
16
  "minItems": 1,
@@ -26,6 +26,9 @@
26
26
  "config": { "$ref": "#/definitions/sha256" },
27
27
  "index": { "$ref": "#/definitions/sha256" }
28
28
  }
29
+ },
30
+ "egressLineage": {
31
+ "$ref": "gno://schemas/retrieval-trace-common@1.0#/definitions/egressLineage"
29
32
  }
30
33
  },
31
34
  "type": "object",
@@ -55,6 +58,7 @@
55
58
  },
56
59
  "queryShape": { "$ref": "#/definitions/textShape" },
57
60
  "goalShape": { "$ref": "#/definitions/textShape" },
61
+ "egressLineage": { "$ref": "#/definitions/egressLineage" },
58
62
  "fingerprints": { "$ref": "#/definitions/fingerprints" },
59
63
  "createdAtMs": { "type": "integer", "minimum": 0 },
60
64
  "updatedAtMs": { "type": "integer", "minimum": 0 },
@@ -6,6 +6,35 @@
6
6
  "type": "object",
7
7
  "required": ["results", "meta"],
8
8
  "$defs": {
9
+ "egressLineage": {
10
+ "type": "object",
11
+ "additionalProperties": false,
12
+ "required": ["effectivePolicy", "digest", "sources"],
13
+ "properties": {
14
+ "effectivePolicy": { "enum": ["local_only", "lan", "remote"] },
15
+ "digest": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
16
+ "sources": {
17
+ "type": "array",
18
+ "minItems": 1,
19
+ "maxItems": 128,
20
+ "items": {
21
+ "type": "object",
22
+ "additionalProperties": false,
23
+ "required": ["collection", "policy", "source"],
24
+ "properties": {
25
+ "collection": {
26
+ "type": "string",
27
+ "pattern": "^[a-z0-9][a-z0-9_-]{0,63}$"
28
+ },
29
+ "policy": { "enum": ["local_only", "lan", "remote"] },
30
+ "source": {
31
+ "enum": ["explicit", "config_default", "legacy_default"]
32
+ }
33
+ }
34
+ }
35
+ }
36
+ }
37
+ },
9
38
  "searchResult": {
10
39
  "type": "object",
11
40
  "required": ["docid", "score", "uri", "snippet", "source"],
@@ -54,6 +83,7 @@
54
83
  "type": "string",
55
84
  "description": "Resolved user-configured retrieval guidance, ordered from global to collection to matching path prefixes"
56
85
  },
86
+ "egressLineage": { "$ref": "#/$defs/egressLineage" },
57
87
  "snippet": {
58
88
  "type": "string",
59
89
  "description": "Matching text snippet from document mirror"
@@ -3,7 +3,7 @@
3
3
  import type { ContextCanonicalProjection } from "../core/context-budget";
4
4
  import type { ContextCapsuleV1 } from "../core/context-capsule";
5
5
  import type { ContextCapabilityState } from "../core/context-capsule-retrieval-schema";
6
- import type { ContextCapsulePayloadV1 } from "../core/context-capsule-schema";
6
+ import type { ContextCapsulePayloadV1_1 } from "../core/context-capsule-schema";
7
7
  import type { ContextCanonicalPlanDraft } from "../core/context-compiler";
8
8
  import type { ContextEvidenceValue } from "../core/context-evidence";
9
9
  import type { NormalizedContextBuildInput } from "./context-runtime-input";
@@ -19,6 +19,7 @@ import {
19
19
  toContextCapsuleEvidence,
20
20
  } from "../core/context-evidence";
21
21
  import { canonicalVerifierJson } from "../core/context-verifier-canonical";
22
+ import { mergeEgressLineages } from "../core/egress-provenance";
22
23
  import { resolveModelUri } from "../llm/registry";
23
24
 
24
25
  const fingerprint = (value: unknown): string =>
@@ -104,13 +105,13 @@ const capsuleCapabilities = (
104
105
  graphExpansion: states.graphExpansion.outcome === "used",
105
106
  exactTokenCount: exactTokens,
106
107
  configuredContext,
107
- egressPolicy: false,
108
+ egressPolicy: true,
108
109
  });
109
110
 
110
111
  const capsuleFallbacks = (
111
112
  capabilities: ReturnType<typeof capsuleCapabilities>,
112
113
  states: ReturnType<typeof capsuleCapabilityStates>
113
- ): ContextCapsulePayloadV1["fallbacks"] => [
114
+ ): ContextCapsulePayloadV1_1["fallbacks"] => [
114
115
  ...(states.semanticSearch.outcome === "unavailable"
115
116
  ? [
116
117
  {
@@ -143,12 +144,15 @@ const capsuleFallbacks = (
143
144
  capability: "token_count" as const,
144
145
  },
145
146
  ]),
146
- { code: "egress_policy_unavailable", capability: "egress_policy" },
147
147
  ];
148
148
 
149
149
  export const projectContextCapsule = (
150
150
  draft: ContextCanonicalPlanDraft<ContextEvidenceValue>,
151
- snapshots: { indexFingerprint: string; contextFingerprint: string },
151
+ snapshots: {
152
+ indexFingerprint: string;
153
+ contextFingerprint: string;
154
+ egressLineage: ContextCapsulePayloadV1_1["egressLineage"];
155
+ },
152
156
  input: NormalizedContextBuildInput,
153
157
  deps: ContextCapsuleRuntimeDeps
154
158
  ): ContextCanonicalProjection<ContextCapsuleV1> | null => {
@@ -156,6 +160,10 @@ export const projectContextCapsule = (
156
160
  const evidence = draft.selection.selected.map((candidate, index) =>
157
161
  toContextCapsuleEvidence(candidate, index + 1)
158
162
  );
163
+ const egressLineage = mergeEgressLineages([
164
+ snapshots.egressLineage,
165
+ ...evidence.map((item) => item.egressLineage),
166
+ ]);
159
167
  const evidenceIdsByFacet = new Map<string, string[]>();
160
168
  for (const item of evidence) {
161
169
  for (const facet of item.facets) {
@@ -173,7 +181,7 @@ export const projectContextCapsule = (
173
181
  draft.configuredContexts.length > 0
174
182
  );
175
183
  const base = {
176
- schemaVersion: "1.0" as const,
184
+ schemaVersion: "1.1" as const,
177
185
  coordinateSpace: "canonical_mirror" as const,
178
186
  goal: draft.goal,
179
187
  query: draft.query,
@@ -213,7 +221,7 @@ export const projectContextCapsule = (
213
221
  },
214
222
  capabilities,
215
223
  };
216
- const payload: ContextCapsulePayloadV1 = {
224
+ const payload: ContextCapsulePayloadV1_1 = {
217
225
  ...base,
218
226
  budget: {
219
227
  authority: "canonical_json",
@@ -246,6 +254,7 @@ export const projectContextCapsule = (
246
254
  instructionBoundary: "hard_delimited",
247
255
  configuredContexts: draft.configuredContexts,
248
256
  },
257
+ egressLineage,
249
258
  evidence,
250
259
  coverage: {
251
260
  complete: draft.selection.coverage.unresolvedFacets.length === 0,
@@ -165,6 +165,9 @@ export async function ask(
165
165
  }
166
166
  traceSession = traceStart.value ?? undefined;
167
167
  const llm = new LlmAdapter(config);
168
+ const egressCollections = options.collection
169
+ ? [options.collection]
170
+ : ("all" as const);
168
171
 
169
172
  // Resolve download policy from env/flags
170
173
  const policy = resolveDownloadPolicy(process.env, {
@@ -179,6 +182,7 @@ export async function ask(
179
182
 
180
183
  // Create embedding port
181
184
  const embedResult = await llm.createEmbeddingPort(embedUri, {
185
+ egressCollections,
182
186
  policy,
183
187
  onProgress: downloadProgress
184
188
  ? (progress) => downloadProgress("embed", progress)
@@ -191,6 +195,7 @@ export async function ask(
191
195
  // Create expansion port when expansion is enabled.
192
196
  if (expandUri) {
193
197
  const genResult = await llm.createExpansionPort(expandUri, {
198
+ egressCollections,
194
199
  policy,
195
200
  onProgress: downloadProgress
196
201
  ? (progress) => downloadProgress("expand", progress)
@@ -204,6 +209,7 @@ export async function ask(
204
209
  // Create answer generation port when answers are requested.
205
210
  if (answerUri) {
206
211
  const genResult = await llm.createGenerationPort(answerUri, {
212
+ egressCollections,
207
213
  policy,
208
214
  onProgress: downloadProgress
209
215
  ? (progress) => downloadProgress("gen", progress)
@@ -217,6 +223,7 @@ export async function ask(
217
223
  // Create rerank port (unless --fast or --no-rerank)
218
224
  if (rerankUri) {
219
225
  const rerankResult = await llm.createRerankPort(rerankUri, {
226
+ egressCollections,
220
227
  policy,
221
228
  onProgress: downloadProgress
222
229
  ? (progress) => downloadProgress("rerank", progress)
@@ -7,5 +7,10 @@
7
7
  export { collectionAdd } from "./add";
8
8
  export { collectionClearEmbeddings } from "./clear-embeddings";
9
9
  export { collectionList } from "./list";
10
+ export {
11
+ collectionPolicyCheck,
12
+ collectionPolicyGet,
13
+ collectionPolicySet,
14
+ } from "./policy";
10
15
  export { collectionRemove } from "./remove";
11
16
  export { collectionRename } from "./rename";