@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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gmickel/gno",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.29.0",
|
|
4
4
|
"description": "Local semantic search for your documents. Index Markdown, PDF, and Office files with hybrid BM25 + vector search.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"embeddings",
|
|
@@ -220,7 +220,7 @@
|
|
|
220
220
|
"playwright": "1.58.2",
|
|
221
221
|
"pptxgenjs": "4.0.1",
|
|
222
222
|
"ultracite": "7.1.5",
|
|
223
|
-
"vitest": "4.0
|
|
223
|
+
"vitest": "4.1.0",
|
|
224
224
|
"web-tree-sitter": "0.26.8"
|
|
225
225
|
},
|
|
226
226
|
"peerDependencies": {
|
package/spec/cli.md
CHANGED
|
@@ -73,8 +73,8 @@ equivalent files fail closed as ambiguous.
|
|
|
73
73
|
| collection list | yes | no | no | yes | no | terminal |
|
|
74
74
|
| collection remove | no | no | no | no | no | terminal |
|
|
75
75
|
| collection rename | no | no | no | no | no | terminal |
|
|
76
|
-
| update |
|
|
77
|
-
| index |
|
|
76
|
+
| update | yes | no | no | no | no | terminal |
|
|
77
|
+
| index | yes | no | no | no | no | terminal |
|
|
78
78
|
| embed | no | no | no | no | no | terminal |
|
|
79
79
|
| search | yes | yes | yes | yes | yes | terminal |
|
|
80
80
|
| vsearch | yes | yes | yes | yes | yes | terminal |
|
|
@@ -672,6 +672,44 @@ gno collection clear-embeddings <name> [--all] [--json]
|
|
|
672
672
|
|
|
673
673
|
---
|
|
674
674
|
|
|
675
|
+
### gno collection policy
|
|
676
|
+
|
|
677
|
+
Inspect, change, or explain one collection-owned egress boundary.
|
|
678
|
+
|
|
679
|
+
```bash
|
|
680
|
+
gno collection policy get <name>
|
|
681
|
+
gno collection policy set <name> <local_only|lan|remote> [--confirm-relaxation <current-revision>]
|
|
682
|
+
gno collection policy check --action <action> --destination <zone> --content-class <class> [-c <name>...] [--authenticated] [--authorized] [--partial] [--explain-egress]
|
|
683
|
+
```
|
|
684
|
+
|
|
685
|
+
`get` returns the configured value, effective value, provenance source, and a
|
|
686
|
+
durable monotonic revision plus a diagnostic version fingerprint. Tightening is
|
|
687
|
+
immediate. Relaxation requires `--confirm-relaxation` with the exact current
|
|
688
|
+
numeric revision returned by `get`; stale, replayed, cross-collection, and
|
|
689
|
+
cross-target confirmation fails without changing config or the index
|
|
690
|
+
projection.
|
|
691
|
+
`check` and `--explain-egress` perform no action. They return the same
|
|
692
|
+
content-free decision, lineage, partial disclosure, audit metadata, and
|
|
693
|
+
remediation contract.
|
|
694
|
+
|
|
695
|
+
### gno egress-audit
|
|
696
|
+
|
|
697
|
+
Manage local content-free policy decision receipts:
|
|
698
|
+
|
|
699
|
+
```bash
|
|
700
|
+
gno egress-audit list [--limit <n>] [--cursor <cursor>]
|
|
701
|
+
gno egress-audit show <audit-id>
|
|
702
|
+
gno egress-audit status
|
|
703
|
+
gno egress-audit delete <audit-id>
|
|
704
|
+
gno egress-audit purge
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
Pages are newest-first. Delete/purge report truthful SQLite physical cleanup
|
|
708
|
+
status. These local inspection and deletion commands never require a relaxed
|
|
709
|
+
collection policy.
|
|
710
|
+
|
|
711
|
+
---
|
|
712
|
+
|
|
675
713
|
### gno embed
|
|
676
714
|
|
|
677
715
|
Generate embeddings for indexed chunks.
|
|
@@ -772,13 +810,14 @@ Sync files from disk into the index (ingestion without embedding).
|
|
|
772
810
|
**Synopsis:**
|
|
773
811
|
|
|
774
812
|
```bash
|
|
775
|
-
gno update [--git-pull]
|
|
813
|
+
gno update [--git-pull] [--json]
|
|
776
814
|
```
|
|
777
815
|
|
|
778
816
|
**Options:**
|
|
779
817
|
| Option | Type | Description |
|
|
780
818
|
|--------|------|-------------|
|
|
781
819
|
| `--git-pull` | boolean | Run `git pull` in git repositories before scanning |
|
|
820
|
+
| `--json` | boolean | Emit the complete deterministic sync result on stdout |
|
|
782
821
|
|
|
783
822
|
**Behavior:**
|
|
784
823
|
|
|
@@ -789,6 +828,13 @@ gno update [--git-pull]
|
|
|
789
828
|
5. Update FTS index
|
|
790
829
|
6. Mark missing files as inactive
|
|
791
830
|
|
|
831
|
+
**JSON output:** The top-level value is the complete sync result. Each entry in
|
|
832
|
+
`collections[].files[]` may contain a `recordImport` receipt conforming to
|
|
833
|
+
[`record-import@1.0`](./output-schemas/record-import.schema.json). Receipt items
|
|
834
|
+
are sorted deterministically and capped at 1,000; `itemsTruncated` reports
|
|
835
|
+
omitted actions. Partial snapshots expose `warnings[]` even when no individual
|
|
836
|
+
record failure was reported. Human progress and diagnostics remain on stderr.
|
|
837
|
+
|
|
792
838
|
**Exit Codes:**
|
|
793
839
|
|
|
794
840
|
- 0: Success (conversion warnings do not affect exit code)
|
|
@@ -803,7 +849,7 @@ Build or update the index end-to-end (update + embed).
|
|
|
803
849
|
**Synopsis:**
|
|
804
850
|
|
|
805
851
|
```bash
|
|
806
|
-
gno index [
|
|
852
|
+
gno index [collection] [--no-embed] [--models-pull] [--git-pull] [--json] [--yes]
|
|
807
853
|
```
|
|
808
854
|
|
|
809
855
|
**Options:**
|
|
@@ -813,6 +859,7 @@ gno index [--collection <name>] [--no-embed] [--models-pull] [--git-pull] [--yes
|
|
|
813
859
|
| `--no-embed` | boolean | Run ingestion only, skip embedding |
|
|
814
860
|
| `--models-pull` | boolean | Download models if missing (prompts unless `--yes`) |
|
|
815
861
|
| `--git-pull` | boolean | Run `git pull` in git repositories |
|
|
862
|
+
| `--json` | boolean | Emit the complete deterministic sync and embedding result on stdout |
|
|
816
863
|
| `--yes` | boolean | Accept defaults, no prompts |
|
|
817
864
|
|
|
818
865
|
**Behavior:**
|
|
@@ -820,6 +867,13 @@ gno index [--collection <name>] [--no-embed] [--models-pull] [--git-pull] [--yes
|
|
|
820
867
|
- Runs `update` then `embed` by default
|
|
821
868
|
- With `--no-embed`, runs `update` only
|
|
822
869
|
|
|
870
|
+
**JSON output:** Emits `{ syncResult, embedSkipped, embedResult? }`.
|
|
871
|
+
`syncResult.collections[].files[].recordImport`, when present, conforms to
|
|
872
|
+
[`record-import@1.0`](./output-schemas/record-import.schema.json) with the same
|
|
873
|
+
deterministic ordering, bounds, truncation disclosure, and partial-snapshot
|
|
874
|
+
warnings as `gno update --json`. Human progress and diagnostics remain on
|
|
875
|
+
stderr.
|
|
876
|
+
|
|
823
877
|
**Exit Codes:**
|
|
824
878
|
|
|
825
879
|
- 0: Success
|
|
@@ -1034,6 +1088,27 @@ broad-to-specific path-prefix order. The field is absent when no scope matches;
|
|
|
1034
1088
|
`uri` and `docid` remain the exact source identity. The same contract applies to
|
|
1035
1089
|
`vsearch`, `query`, and the `results` array returned by `ask`.
|
|
1036
1090
|
|
|
1091
|
+
Logical documents created from file/export adapters additionally include a
|
|
1092
|
+
bounded `record` object with their opaque record key, exact export locator,
|
|
1093
|
+
people/dates, thread/event/session identity, attachment inventory, and anchors.
|
|
1094
|
+
`source.relPath` names the real export container; `uri` and `docid` address the
|
|
1095
|
+
individual virtual document. The closed `record.adapter` identity contains the
|
|
1096
|
+
adapter ID, version, and configuration fingerprint. `get` and `multi-get`
|
|
1097
|
+
preserve the same fields.
|
|
1098
|
+
|
|
1099
|
+
File/export adapter iteration has a 60-second deadline in addition to the byte,
|
|
1100
|
+
record, metadata, and total-character caps. A partial import that retains valid
|
|
1101
|
+
siblings exits successfully but is never silent: terminal output includes the
|
|
1102
|
+
file, bounded warning count, and snapshot state; `--verbose` adds stable failure
|
|
1103
|
+
codes, bounded source locators, retryability, and redacted messages.
|
|
1104
|
+
`gno update --json`, `gno index --json`, and internal and SDK-facing sync
|
|
1105
|
+
results include a `recordImport` receipt conforming to
|
|
1106
|
+
[`record-import@1.0`](./output-schemas/record-import.schema.json), with adapter
|
|
1107
|
+
identity, configuration fingerprint, snapshot authority, cap state, bytes read,
|
|
1108
|
+
per-action identity/provenance/attachment receipts, truncation disclosure,
|
|
1109
|
+
warnings, and bounded failures. `.gno/records/` is a reserved virtual
|
|
1110
|
+
namespace and is never walked as physical collection content.
|
|
1111
|
+
|
|
1037
1112
|
**Exit Codes:**
|
|
1038
1113
|
|
|
1039
1114
|
- 0: Success (including zero results)
|
|
@@ -3236,7 +3311,9 @@ is blocked.
|
|
|
3236
3311
|
- Starts a headless `/mcp` Streamable HTTP listener; it does not serve the Web UI
|
|
3237
3312
|
- Exposes the same safe REST lifecycle snapshot at `/api/resident/status`;
|
|
3238
3313
|
resident-aware app status at `/api/status` is loopback-only because it
|
|
3239
|
-
includes local index and configuration details
|
|
3314
|
+
includes local index and configuration details. Non-loopback resident status
|
|
3315
|
+
intersects exact Host/Origin and bearer authentication with the current
|
|
3316
|
+
peer zone and all participating collection policies before returning metadata
|
|
3240
3317
|
- On `--detach`: forks a detached child with stdio redirected to `--log-file`, writes pid-file JSON including the MCP gateway `port`, prints `{pid}` on stdout, exits 0
|
|
3241
3318
|
- On `--status`: output matches the [process-status schema](./output-schemas/process-status.schema.json), including the MCP gateway port and a best-effort copy of the live redacted resident snapshot
|
|
3242
3319
|
- On `--stop`: SIGTERM → 10s poll → SIGKILL → 2s poll; the daemon's own signal handler unlinks the pid-file, `--stop` unlinks as fallback
|
package/spec/db/schema.sql
CHANGED
|
@@ -49,6 +49,25 @@ CREATE TABLE IF NOT EXISTS collections (
|
|
|
49
49
|
exclude TEXT, -- JSON array of patterns
|
|
50
50
|
update_cmd TEXT,
|
|
51
51
|
language_hint TEXT, -- BCP-47 or NULL
|
|
52
|
+
-- Migration 023 backfills existing rows as local_only/legacy_default.
|
|
53
|
+
-- Config sync without an explicit value remains local_only/config_default;
|
|
54
|
+
-- only explicit config may persist lan or remote.
|
|
55
|
+
egress_policy TEXT NOT NULL DEFAULT 'local_only'
|
|
56
|
+
CHECK (egress_policy IN ('local_only', 'lan', 'remote')),
|
|
57
|
+
egress_policy_source TEXT NOT NULL DEFAULT 'legacy_default'
|
|
58
|
+
CHECK (
|
|
59
|
+
egress_policy_source IN (
|
|
60
|
+
'explicit',
|
|
61
|
+
'config_default',
|
|
62
|
+
'legacy_default'
|
|
63
|
+
)
|
|
64
|
+
)
|
|
65
|
+
CHECK (
|
|
66
|
+
egress_policy_source = 'explicit'
|
|
67
|
+
OR egress_policy = 'local_only'
|
|
68
|
+
),
|
|
69
|
+
egress_policy_revision INTEGER NOT NULL DEFAULT 0
|
|
70
|
+
CHECK (egress_policy_revision >= 0),
|
|
52
71
|
synced_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
53
72
|
);
|
|
54
73
|
|
|
@@ -92,6 +111,12 @@ CREATE TABLE IF NOT EXISTS documents (
|
|
|
92
111
|
converter_version TEXT,
|
|
93
112
|
language_hint TEXT, -- BCP-47 or NULL
|
|
94
113
|
content_type_source TEXT, -- frontmatter | rules | default | extension | null
|
|
114
|
+
record_key TEXT, -- opaque stable logical-record identity
|
|
115
|
+
record_source_path TEXT, -- collection-relative export/container path
|
|
116
|
+
record_source_locator TEXT, -- bounded exact record/cue/message/event locator
|
|
117
|
+
record_metadata TEXT, -- bounded canonical JSON record metadata
|
|
118
|
+
record_anchors TEXT, -- bounded canonical JSON exact anchors
|
|
119
|
+
record_adapter_fingerprint TEXT, -- config-bound adapter identity for re-import invalidation
|
|
95
120
|
|
|
96
121
|
-- Status
|
|
97
122
|
active INTEGER NOT NULL DEFAULT 1,
|
|
@@ -116,6 +141,12 @@ CREATE INDEX IF NOT EXISTS idx_documents_active ON documents(active);
|
|
|
116
141
|
CREATE INDEX IF NOT EXISTS idx_documents_mirror_hash ON documents(mirror_hash);
|
|
117
142
|
CREATE INDEX IF NOT EXISTS idx_documents_docid ON documents(docid);
|
|
118
143
|
CREATE INDEX IF NOT EXISTS idx_documents_uri ON documents(uri);
|
|
144
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_documents_record_key
|
|
145
|
+
ON documents(collection, record_source_path, record_key)
|
|
146
|
+
WHERE record_source_path IS NOT NULL AND record_key IS NOT NULL;
|
|
147
|
+
CREATE INDEX IF NOT EXISTS idx_documents_record_source_path
|
|
148
|
+
ON documents(collection, record_source_path)
|
|
149
|
+
WHERE record_source_path IS NOT NULL;
|
|
119
150
|
|
|
120
151
|
-- ─────────────────────────────────────────────────────────────────────────────
|
|
121
152
|
-- Content (content-addressed markdown mirrors)
|
package/spec/mcp.md
CHANGED
|
@@ -98,6 +98,26 @@ HTTP MCP remains read-only unless `gateway.enableWrite: true` or
|
|
|
98
98
|
authorize mutation. Unauthorized calls to write tools fail with HTTP 403 before
|
|
99
99
|
SDK dispatch.
|
|
100
100
|
|
|
101
|
+
Every `tools/call`, `resources/list`, `resources/templates/list`, and
|
|
102
|
+
`resources/read` request is also checked against the current socket peer zone
|
|
103
|
+
and the effective policy of every referenced collection before SDK dispatch.
|
|
104
|
+
The check is per request, including batch members and requests that reuse an
|
|
105
|
+
existing session; a session's original peer zone is never reused as authority.
|
|
106
|
+
Non-loopback access therefore requires both a valid bearer token and a
|
|
107
|
+
compatible collection policy. Policy denial returns HTTP 403 with stable
|
|
108
|
+
`EGRESS_DENIED` data and a redacted evaluator audit. Write authorization remains
|
|
109
|
+
an independent additional requirement.
|
|
110
|
+
|
|
111
|
+
The MCP tool and resource registry is paired with a callsite-level
|
|
112
|
+
network-boundary inventory. A TypeScript AST scan covers shipped TS, TSX, JS,
|
|
113
|
+
and JSX and recognizes direct, qualified, bracketed, imported, and aliased
|
|
114
|
+
fetch, EventSource, WebSocket, Bun listener/DNS/socket, HTTP inference, and
|
|
115
|
+
external-process primitives. Every detected invocation has its own stable
|
|
116
|
+
inventory key, so adding a second call in an already-listed file still fails
|
|
117
|
+
the contract test. Browser same-origin calls are classified as client
|
|
118
|
+
transport and name the server route that performs the actual egress check; the
|
|
119
|
+
client scan itself is not treated as content authorization.
|
|
120
|
+
|
|
101
121
|
Boundary failures use the closed
|
|
102
122
|
[`mcp-http-error`](./output-schemas/mcp-http-error.schema.json) body with stable,
|
|
103
123
|
redacted statuses: 401 (authentication), 403 (peer/Host/Origin/write), 413
|
|
@@ -697,6 +717,11 @@ Search result items include `contentType` when available and always include
|
|
|
697
717
|
human-oriented; structured clients should read `structuredContent.results`.
|
|
698
718
|
Structured result items also preserve optional `context` guidance in
|
|
699
719
|
global-to-specific order without changing the result `uri` or `docid`.
|
|
720
|
+
File/export records also include bounded `record` provenance in structured
|
|
721
|
+
search/get/multi-get/Ask output. Their `source.relPath` is the real local export
|
|
722
|
+
container while the unique `uri` remains the required exact retrieval ref. The
|
|
723
|
+
closed `record.adapter` object identifies the adapter ID, version, and
|
|
724
|
+
configuration fingerprint used to produce the logical record.
|
|
700
725
|
When `explain: true`, `structuredContent.meta.explain` includes deterministic
|
|
701
726
|
stage lines and per-result score receipts. Non-neutral configured content-type
|
|
702
727
|
rules add `contentTypeBoost` with base/raw scores, factor, capped contribution,
|
|
@@ -2341,6 +2366,52 @@ MCP Server Status
|
|
|
2341
2366
|
|
|
2342
2367
|
---
|
|
2343
2368
|
|
|
2369
|
+
## Collection Egress Policy and Audit Tools
|
|
2370
|
+
|
|
2371
|
+
Read tools:
|
|
2372
|
+
|
|
2373
|
+
- `gno_egress_policy_get { collection }` returns configured/effective policy,
|
|
2374
|
+
provenance source, current monotonic revision, and diagnostic version.
|
|
2375
|
+
- `gno_egress_check` accepts exact collection scope, action, destination zone,
|
|
2376
|
+
caller authentication/authorization, content class, and partial mode. It
|
|
2377
|
+
performs no action and returns the canonical decision/explanation contract.
|
|
2378
|
+
An explicit scope is a non-empty, duplicate-free list of at most 64 canonical
|
|
2379
|
+
collection names; omitted scope means all configured collections.
|
|
2380
|
+
- `gno_egress_audit_list`, `gno_egress_audit_show`, and
|
|
2381
|
+
`gno_egress_audit_status` expose only content-free local receipts.
|
|
2382
|
+
|
|
2383
|
+
Write-enabled tools:
|
|
2384
|
+
|
|
2385
|
+
- `gno_egress_policy_set` requires confirmation
|
|
2386
|
+
`{ collection, currentPolicy, currentRevision, targetPolicy, acknowledged: true }`
|
|
2387
|
+
for relaxation. The revision is durable and one-use; replayed, stale,
|
|
2388
|
+
cross-collection, and cross-target confirmations fail closed.
|
|
2389
|
+
- `gno_egress_audit_delete` deletes exactly one receipt.
|
|
2390
|
+
- `gno_egress_audit_purge { confirm: true }` deletes only audit receipts.
|
|
2391
|
+
|
|
2392
|
+
Policy does not replace transport authentication or `enableWrite`. Local audit
|
|
2393
|
+
inspection remains available when outbound content is denied. Retrieval-trace
|
|
2394
|
+
export resolves exact trace lineage and checks policy before creating or
|
|
2395
|
+
reusing an export receipt; missing traces return `NOT_FOUND` before policy
|
|
2396
|
+
evaluation.
|
|
2397
|
+
|
|
2398
|
+
All collection-policy and audit tool inputs are closed objects. Unknown
|
|
2399
|
+
top-level fields are rejected by MCP input validation before any handler,
|
|
2400
|
+
mutation, invalidation, or audit operation runs.
|
|
2401
|
+
|
|
2402
|
+
Active resident requests retain their admission authorization epoch. A policy
|
|
2403
|
+
mutation may advance its own request to the new epoch, but older REST and MCP
|
|
2404
|
+
responses are replaced by a content-free `EGRESS_POLICY_CHANGED` retry
|
|
2405
|
+
response/event before protected bytes are emitted, including streaming
|
|
2406
|
+
responses. `/api/events` binds each SSE subscriber to its admission epoch and
|
|
2407
|
+
rechecks it before every document event and heartbeat; a stale subscriber
|
|
2408
|
+
receives only the retry event and is then unsubscribed.
|
|
2409
|
+
|
|
2410
|
+
Schemas: `collection-egress-policy.schema.json`,
|
|
2411
|
+
`collection-egress-policy-set.schema.json`,
|
|
2412
|
+
`collection-egress-check.schema.json`, and
|
|
2413
|
+
`egress-audit-management.schema.json`.
|
|
2414
|
+
|
|
2344
2415
|
## See Also
|
|
2345
2416
|
|
|
2346
2417
|
- [CLI Specification](./cli.md)
|
|
@@ -95,6 +95,35 @@
|
|
|
95
95
|
}
|
|
96
96
|
],
|
|
97
97
|
"$defs": {
|
|
98
|
+
"egressLineage": {
|
|
99
|
+
"type": "object",
|
|
100
|
+
"additionalProperties": false,
|
|
101
|
+
"required": ["effectivePolicy", "digest", "sources"],
|
|
102
|
+
"properties": {
|
|
103
|
+
"effectivePolicy": { "enum": ["local_only", "lan", "remote"] },
|
|
104
|
+
"digest": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
|
|
105
|
+
"sources": {
|
|
106
|
+
"type": "array",
|
|
107
|
+
"minItems": 1,
|
|
108
|
+
"maxItems": 128,
|
|
109
|
+
"items": {
|
|
110
|
+
"type": "object",
|
|
111
|
+
"additionalProperties": false,
|
|
112
|
+
"required": ["collection", "policy", "source"],
|
|
113
|
+
"properties": {
|
|
114
|
+
"collection": {
|
|
115
|
+
"type": "string",
|
|
116
|
+
"pattern": "^[a-z0-9][a-z0-9_-]{0,63}$"
|
|
117
|
+
},
|
|
118
|
+
"policy": { "enum": ["local_only", "lan", "remote"] },
|
|
119
|
+
"source": {
|
|
120
|
+
"enum": ["explicit", "config_default", "legacy_default"]
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
},
|
|
98
127
|
"searchResult": {
|
|
99
128
|
"type": "object",
|
|
100
129
|
"required": ["docid", "score", "uri", "snippet", "source"],
|
|
@@ -127,10 +156,136 @@
|
|
|
127
156
|
"type": "string",
|
|
128
157
|
"description": "Resolved user-configured retrieval guidance, ordered from global to collection to matching path prefixes"
|
|
129
158
|
},
|
|
159
|
+
"egressLineage": { "$ref": "#/$defs/egressLineage" },
|
|
130
160
|
"snippet": {
|
|
131
161
|
"type": "string",
|
|
132
162
|
"description": "Matching text snippet from document mirror"
|
|
133
163
|
},
|
|
164
|
+
"record": {
|
|
165
|
+
"type": "object",
|
|
166
|
+
"additionalProperties": false,
|
|
167
|
+
"description": "Bounded logical-record provenance for a file/export source",
|
|
168
|
+
"required": ["recordKey", "sourceLocator", "anchors", "adapter"],
|
|
169
|
+
"properties": {
|
|
170
|
+
"recordKey": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
|
|
171
|
+
"sourceLocator": {
|
|
172
|
+
"type": "string",
|
|
173
|
+
"minLength": 1,
|
|
174
|
+
"maxLength": 512
|
|
175
|
+
},
|
|
176
|
+
"anchors": {
|
|
177
|
+
"type": "array",
|
|
178
|
+
"maxItems": 256,
|
|
179
|
+
"items": {
|
|
180
|
+
"type": "object",
|
|
181
|
+
"additionalProperties": false,
|
|
182
|
+
"required": ["kind", "value"],
|
|
183
|
+
"properties": {
|
|
184
|
+
"kind": {
|
|
185
|
+
"enum": [
|
|
186
|
+
"line",
|
|
187
|
+
"cue",
|
|
188
|
+
"timestamp",
|
|
189
|
+
"message",
|
|
190
|
+
"event",
|
|
191
|
+
"record"
|
|
192
|
+
]
|
|
193
|
+
},
|
|
194
|
+
"value": {
|
|
195
|
+
"type": "string",
|
|
196
|
+
"minLength": 1,
|
|
197
|
+
"maxLength": 512
|
|
198
|
+
},
|
|
199
|
+
"endValue": {
|
|
200
|
+
"type": "string",
|
|
201
|
+
"minLength": 1,
|
|
202
|
+
"maxLength": 512
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
"adapter": {
|
|
208
|
+
"type": "object",
|
|
209
|
+
"additionalProperties": false,
|
|
210
|
+
"required": ["id", "version", "fingerprint"],
|
|
211
|
+
"properties": {
|
|
212
|
+
"id": { "type": "string", "minLength": 1, "maxLength": 128 },
|
|
213
|
+
"version": {
|
|
214
|
+
"type": "string",
|
|
215
|
+
"minLength": 1,
|
|
216
|
+
"maxLength": 64
|
|
217
|
+
},
|
|
218
|
+
"fingerprint": { "type": "string", "pattern": "^[a-f0-9]{64}$" }
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
"author": { "type": "string", "maxLength": 2048 },
|
|
222
|
+
"participants": {
|
|
223
|
+
"type": "array",
|
|
224
|
+
"maxItems": 256,
|
|
225
|
+
"items": { "type": "string", "minLength": 1, "maxLength": 2048 }
|
|
226
|
+
},
|
|
227
|
+
"categories": {
|
|
228
|
+
"type": "array",
|
|
229
|
+
"maxItems": 256,
|
|
230
|
+
"items": { "type": "string", "minLength": 1, "maxLength": 512 }
|
|
231
|
+
},
|
|
232
|
+
"dateFields": {
|
|
233
|
+
"type": "object",
|
|
234
|
+
"maxProperties": 256,
|
|
235
|
+
"propertyNames": { "type": "string", "maxLength": 128 },
|
|
236
|
+
"additionalProperties": {
|
|
237
|
+
"type": "string",
|
|
238
|
+
"minLength": 1,
|
|
239
|
+
"maxLength": 256
|
|
240
|
+
}
|
|
241
|
+
},
|
|
242
|
+
"messageId": { "type": "string", "maxLength": 2048 },
|
|
243
|
+
"inReplyTo": { "type": "string", "maxLength": 2048 },
|
|
244
|
+
"references": {
|
|
245
|
+
"type": "array",
|
|
246
|
+
"maxItems": 256,
|
|
247
|
+
"items": {
|
|
248
|
+
"type": "string",
|
|
249
|
+
"minLength": 1,
|
|
250
|
+
"maxLength": 2048
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
"threadId": { "type": "string", "maxLength": 2048 },
|
|
254
|
+
"eventId": { "type": "string", "maxLength": 2048 },
|
|
255
|
+
"sessionId": { "type": "string", "maxLength": 2048 },
|
|
256
|
+
"attachments": {
|
|
257
|
+
"type": "array",
|
|
258
|
+
"maxItems": 256,
|
|
259
|
+
"items": {
|
|
260
|
+
"type": "object",
|
|
261
|
+
"additionalProperties": false,
|
|
262
|
+
"required": ["name"],
|
|
263
|
+
"properties": {
|
|
264
|
+
"name": {
|
|
265
|
+
"type": "string",
|
|
266
|
+
"minLength": 1,
|
|
267
|
+
"maxLength": 512
|
|
268
|
+
},
|
|
269
|
+
"mime": {
|
|
270
|
+
"type": "string",
|
|
271
|
+
"minLength": 1,
|
|
272
|
+
"maxLength": 256
|
|
273
|
+
},
|
|
274
|
+
"bytes": {
|
|
275
|
+
"type": "integer",
|
|
276
|
+
"minimum": 0,
|
|
277
|
+
"maximum": 9007199254740991
|
|
278
|
+
},
|
|
279
|
+
"disposition": { "enum": ["inline", "attachment"] },
|
|
280
|
+
"sha256": {
|
|
281
|
+
"type": "string",
|
|
282
|
+
"pattern": "^[a-f0-9]{64}$"
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
},
|
|
134
289
|
"snippetRange": {
|
|
135
290
|
"type": "object",
|
|
136
291
|
"description": "Line range of snippet in mirror content",
|
|
@@ -306,7 +461,7 @@
|
|
|
306
461
|
"schemaVersion": { "const": "1.0" },
|
|
307
462
|
"mode": { "const": "closed_capsule" },
|
|
308
463
|
"capsule": {
|
|
309
|
-
"$ref": "gno://schemas/context-capsule-v1@1.
|
|
464
|
+
"$ref": "gno://schemas/context-capsule-v1@1.1"
|
|
310
465
|
},
|
|
311
466
|
"freshness": {
|
|
312
467
|
"$ref": "gno://schemas/context-capsule-verification@1.0"
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"destination": {
|
|
19
19
|
"$ref": "gno://schemas/browser-clip@1.0#/properties/destination"
|
|
20
20
|
},
|
|
21
|
+
"egressLineage": { "$ref": "#/definitions/egressLineage" },
|
|
21
22
|
"tags": {
|
|
22
23
|
"type": "array",
|
|
23
24
|
"items": { "type": "string" }
|
|
@@ -48,6 +49,35 @@
|
|
|
48
49
|
}
|
|
49
50
|
},
|
|
50
51
|
"definitions": {
|
|
52
|
+
"egressLineage": {
|
|
53
|
+
"type": "object",
|
|
54
|
+
"additionalProperties": false,
|
|
55
|
+
"required": ["effectivePolicy", "digest", "sources"],
|
|
56
|
+
"properties": {
|
|
57
|
+
"effectivePolicy": { "enum": ["local_only", "lan", "remote"] },
|
|
58
|
+
"digest": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
|
|
59
|
+
"sources": {
|
|
60
|
+
"type": "array",
|
|
61
|
+
"minItems": 1,
|
|
62
|
+
"uniqueItems": true,
|
|
63
|
+
"items": {
|
|
64
|
+
"type": "object",
|
|
65
|
+
"additionalProperties": false,
|
|
66
|
+
"required": ["collection", "policy", "source"],
|
|
67
|
+
"properties": {
|
|
68
|
+
"collection": {
|
|
69
|
+
"type": "string",
|
|
70
|
+
"pattern": "^[a-z0-9][a-z0-9_-]{0,63}$"
|
|
71
|
+
},
|
|
72
|
+
"policy": { "enum": ["local_only", "lan", "remote"] },
|
|
73
|
+
"source": {
|
|
74
|
+
"enum": ["explicit", "config_default", "legacy_default"]
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
},
|
|
51
81
|
"source": {
|
|
52
82
|
"type": "object",
|
|
53
83
|
"additionalProperties": false,
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://gno.sh/schemas/collection-egress-check.schema.json",
|
|
4
|
+
"title": "Collection egress check and explanation",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"required": [
|
|
8
|
+
"schemaVersion",
|
|
9
|
+
"mode",
|
|
10
|
+
"allowedCollections",
|
|
11
|
+
"omittedCollections",
|
|
12
|
+
"disclosure",
|
|
13
|
+
"lineage",
|
|
14
|
+
"decision",
|
|
15
|
+
"remediation"
|
|
16
|
+
],
|
|
17
|
+
"properties": {
|
|
18
|
+
"schemaVersion": { "const": "1.0" },
|
|
19
|
+
"mode": { "enum": ["complete", "partial", "denied"] },
|
|
20
|
+
"allowedCollections": {
|
|
21
|
+
"type": "array",
|
|
22
|
+
"items": { "type": "string" },
|
|
23
|
+
"uniqueItems": true
|
|
24
|
+
},
|
|
25
|
+
"omittedCollections": {
|
|
26
|
+
"type": "array",
|
|
27
|
+
"items": {
|
|
28
|
+
"type": "object",
|
|
29
|
+
"additionalProperties": false,
|
|
30
|
+
"required": ["collection", "reason"],
|
|
31
|
+
"properties": {
|
|
32
|
+
"collection": { "type": "string" },
|
|
33
|
+
"reason": { "type": "string" }
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"disclosure": {
|
|
38
|
+
"oneOf": [
|
|
39
|
+
{ "type": "null" },
|
|
40
|
+
{
|
|
41
|
+
"type": "object",
|
|
42
|
+
"additionalProperties": false,
|
|
43
|
+
"required": ["code", "omittedCount", "omittedCollections"],
|
|
44
|
+
"properties": {
|
|
45
|
+
"code": { "const": "EGRESS_PARTIAL_RESULT" },
|
|
46
|
+
"omittedCount": { "type": "integer", "minimum": 1 },
|
|
47
|
+
"omittedCollections": {
|
|
48
|
+
"type": "array",
|
|
49
|
+
"items": { "type": "string" },
|
|
50
|
+
"minItems": 1,
|
|
51
|
+
"uniqueItems": true
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
},
|
|
57
|
+
"lineage": {
|
|
58
|
+
"type": "object",
|
|
59
|
+
"required": ["effectivePolicy", "digest", "sources"],
|
|
60
|
+
"properties": {
|
|
61
|
+
"effectivePolicy": { "enum": ["local_only", "lan", "remote"] },
|
|
62
|
+
"digest": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
|
|
63
|
+
"sources": { "type": "array", "minItems": 1 }
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"decision": {
|
|
67
|
+
"type": "object",
|
|
68
|
+
"required": ["allowed", "code", "reason", "audit"],
|
|
69
|
+
"properties": {
|
|
70
|
+
"allowed": { "type": "boolean" },
|
|
71
|
+
"code": { "enum": ["EGRESS_ALLOWED", "EGRESS_DENIED"] },
|
|
72
|
+
"reason": { "type": "string" },
|
|
73
|
+
"audit": { "type": "object" }
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
"remediation": {
|
|
77
|
+
"oneOf": [
|
|
78
|
+
{ "type": "null" },
|
|
79
|
+
{
|
|
80
|
+
"type": "object",
|
|
81
|
+
"additionalProperties": false,
|
|
82
|
+
"required": ["code", "message"],
|
|
83
|
+
"properties": {
|
|
84
|
+
"code": { "type": "string" },
|
|
85
|
+
"message": { "type": "string", "minLength": 1 }
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
]
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|