@gmickel/gno 2.6.0 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/README.md +1 -1
  2. package/assets/skill/SKILL.md +5 -3
  3. package/assets/skill/cli-reference.md +9 -2
  4. package/assets/skill/mcp-reference.md +2 -1
  5. package/assets/spa-production.json.gz +0 -0
  6. package/browser-extension/artifacts/{gno-browser-clipper-v2.6.0.zip → gno-browser-clipper-v2.7.0.zip} +0 -0
  7. package/browser-extension/artifacts/gno-browser-clipper-v2.7.0.zip.sha256 +1 -0
  8. package/browser-extension/dist/manifest.json +1 -1
  9. package/package.json +1 -1
  10. package/spec/cli.md +109 -18
  11. package/spec/mcp.md +36 -2
  12. package/spec/output-schemas/ask.schema.json +1 -1
  13. package/spec/output-schemas/capture-receipt.schema.json +1 -1
  14. package/spec/output-schemas/doctor.schema.json +88 -0
  15. package/spec/output-schemas/error.schema.json +11 -2
  16. package/spec/output-schemas/get.schema.json +1 -1
  17. package/spec/output-schemas/mcp-capture-result.schema.json +1 -2
  18. package/spec/output-schemas/memory-remember.schema.json +2 -2
  19. package/spec/output-schemas/multi-get.schema.json +4 -1
  20. package/spec/output-schemas/peek.schema.json +2 -9
  21. package/spec/output-schemas/resident-status.schema.json +22 -0
  22. package/spec/output-schemas/search-result.schema.json +1 -1
  23. package/spec/output-schemas/search-results.schema.json +1 -1
  24. package/spec/output-schemas/status.schema.json +98 -0
  25. package/src/cli/commands/doctor.ts +54 -20
  26. package/src/cli/commands/embed.ts +41 -3
  27. package/src/cli/commands/query.ts +5 -0
  28. package/src/cli/commands/status.ts +63 -5
  29. package/src/cli/commands/vec.ts +54 -0
  30. package/src/cli/detach.ts +29 -1
  31. package/src/cli/errors.ts +13 -9
  32. package/src/cli/program.ts +53 -1
  33. package/src/core/capture-sync.ts +9 -2
  34. package/src/core/host-paths.ts +31 -0
  35. package/src/core/memory-remember.ts +4 -3
  36. package/src/core/shutdown-budget.ts +6 -0
  37. package/src/core/vector-partition-status.ts +52 -0
  38. package/src/embed/backlog.ts +124 -18
  39. package/src/embed/fingerprint.ts +6 -3
  40. package/src/embed/retry.ts +66 -27
  41. package/src/embed/variant-backlog.ts +15 -10
  42. package/src/embed/variant-retry.ts +31 -22
  43. package/src/index.ts +21 -2
  44. package/src/llm/native-worker/dispatcher.ts +2 -0
  45. package/src/llm/native-worker/embedding-identity.ts +42 -0
  46. package/src/llm/native-worker/protocol.ts +1 -0
  47. package/src/llm/types.ts +3 -0
  48. package/src/mcp/context.ts +9 -0
  49. package/src/mcp/resources/index.ts +6 -5
  50. package/src/mcp/tool-descriptions-core.ts +1 -1
  51. package/src/mcp/tools/capture.ts +1 -3
  52. package/src/mcp/tools/index.ts +11 -4
  53. package/src/mcp/tools/memory-remember.ts +1 -1
  54. package/src/mcp/tools/status.ts +4 -0
  55. package/src/pipeline/hybrid.ts +37 -7
  56. package/src/pipeline/vsearch.ts +14 -2
  57. package/src/serve/embed-scheduler.ts +133 -19
  58. package/src/serve/host-path-redaction.ts +79 -0
  59. package/src/serve/public/components/sessions/SessionSearch.tsx +2 -2
  60. package/src/serve/public/globals.built.css +1 -1
  61. package/src/serve/public/hooks/use-api.ts +17 -2
  62. package/src/serve/public/lib/request-intent.ts +8 -0
  63. package/src/serve/public/{components/sessions → lib}/snippet.tsx +2 -3
  64. package/src/serve/public/pages/Dashboard.tsx +12 -9
  65. package/src/serve/public/pages/DocView.tsx +10 -5
  66. package/src/serve/public/pages/DocumentEditor.tsx +91 -14
  67. package/src/serve/public/pages/Search.tsx +1 -41
  68. package/src/serve/resident-runtime.ts +26 -1
  69. package/src/serve/resident-status.ts +13 -1
  70. package/src/serve/server.ts +10 -9
  71. package/src/serve/status-model.ts +16 -0
  72. package/src/serve/status.ts +2 -0
  73. package/src/serve/watch-reconciliation-shared.ts +3 -0
  74. package/src/serve/watch-service-events.ts +3 -2
  75. package/src/serve/watch-service-run-flush.ts +35 -2
  76. package/src/serve/watch-service.ts +5 -0
  77. package/src/store/migrations/031-runtime-independent-vectors.ts +29 -0
  78. package/src/store/migrations/032-vector-runtime-callers.ts +17 -0
  79. package/src/store/migrations/index.ts +4 -0
  80. package/src/store/sqlite/adapter.ts +22 -1
  81. package/src/store/types.ts +11 -1
  82. package/src/store/vector/lazy.ts +46 -43
  83. package/src/store/vector/runtime-compat.ts +651 -0
  84. package/src/store/vector/sqlite-vec.ts +20 -2
  85. package/src/store/vector/status.ts +276 -35
  86. package/src/store/vector/types.ts +2 -0
  87. package/src/store/vector/variant-search.ts +71 -23
  88. package/src/store/vector/variants.ts +49 -14
  89. package/browser-extension/artifacts/gno-browser-clipper-v2.6.0.zip.sha256 +0 -1
package/README.md CHANGED
@@ -139,7 +139,7 @@ See the [guide](docs/COMPILED-CONTEXT.md).
139
139
 
140
140
  <!-- public-truth:current-version -->
141
141
 
142
- > Current source version: **v2.6.0**. See [CHANGELOG.md](./CHANGELOG.md).
142
+ > Current source version: **v2.7.0**. See [CHANGELOG.md](./CHANGELOG.md).
143
143
 
144
144
  <!-- /public-truth -->
145
145
 
@@ -130,8 +130,9 @@ Open without fetching content via `gno get`:
130
130
  `#anchor`). Take `serveUrl` from peek `serve.url` when `serve.running` is
131
131
  true.
132
132
  - **Source file**: peek `recent[].absPath`, or search `--json`
133
- `results[].source.absPath`. If `absPath` is absent, show the URI tail and
134
- do not offer file-open for that row.
133
+ `results[].source.absPath`. If `absPath` is absent (always for remote REST
134
+ and HTTP MCP callers), show the URI tail and do not offer file-open for
135
+ that row.
135
136
 
136
137
  ## Search Modes
137
138
 
@@ -557,7 +558,8 @@ Programmatic capture uses the same receipt contract:
557
558
 
558
559
  MCP capture writes structured `source:` frontmatter, runs under the MCP write
559
560
  lock, syncs the file for FTS, and preserves legacy MCP fields (`docid`,
560
- `absPath`, `overwritten`, `serverInstanceId`) alongside the shared receipt. It
561
+ `absPath` over stdio only, `overwritten`, `serverInstanceId`) alongside the
562
+ shared receipt. It
561
563
  does not auto-embed.
562
564
 
563
565
  For an explicit browser capture, use the local unpacked Chromium clipper with
@@ -117,9 +117,15 @@ gno collection clear-embeddings <name> [--all] [--json]
117
117
  ### gno embed
118
118
 
119
119
  ```bash
120
- gno embed [collection] [--collection <name>] [--force] [--model <uri>] [--batch-size <n>] [--dry-run]
120
+ gno embed [collection] [--collection <name>] [--force] [--model <uri>] [--batch-size <n>] [--dry-run] [--new-partition]
121
121
  ```
122
122
 
123
+ Switching `GNO_LLAMA_GPU`, Bun version or thread count resumes the existing
124
+ vector partition when a measured sample of stored chunks matches. If it does
125
+ not, embed refuses to build a separate partition without `--new-partition`
126
+ (`--yes` alone never confirms); queries from that runtime fall back to lexical
127
+ retrieval with a `vector_runtime_incompatible` warning.
128
+
123
129
  ## Indexing
124
130
 
125
131
  ### gno update
@@ -150,7 +156,7 @@ gno index [options]
150
156
  Generate embeddings only.
151
157
 
152
158
  ```bash
153
- gno embed [--force] [--model <uri>] [--batch-size <n>] [--dry-run]
159
+ gno embed [--force] [--model <uri>] [--batch-size <n>] [--dry-run] [--new-partition]
154
160
  ```
155
161
 
156
162
  ## Project Profiles
@@ -857,6 +863,7 @@ Vector index maintenance. Use when `gno similar` returns empty despite embedding
857
863
  ```bash
858
864
  gno vec sync # Fast incremental sync
859
865
  gno vec rebuild # Full rebuild
866
+ gno vec drop <partition> # Drop an abandoned shadow partition (id prefix from gno status)
860
867
  ```
861
868
 
862
869
  | Option | Description |
@@ -156,7 +156,8 @@ CLI-only.
156
156
  `GNO_MCP_ENABLE_WRITE=1`. It writes quick notes with structured `source:`
157
157
  frontmatter and returns the same provenance receipt shape as CLI, REST, and SDK
158
158
  capture, plus legacy MCP fields (`docid`, `absPath`, `overwritten`,
159
- `serverInstanceId`).
159
+ `serverInstanceId`). `absPath` is stdio-only: HTTP MCP callers never receive
160
+ host paths and address the note by `uri` + `relPath`.
160
161
 
161
162
  `presetId` accepts `blank`, `project-note`, `research-note`, `decision-note`,
162
163
  `prompt-pattern`, `source-summary`, `idea-original`, `person`,
Binary file
@@ -0,0 +1 @@
1
+ 2116eeada49b4479ac5967ec1bb79d1288b70529aba691b2b4ddaf33d131bc2e gno-browser-clipper-v2.7.0.zip
@@ -21,5 +21,5 @@
21
21
  "content_security_policy": {
22
22
  "extension_pages": "script-src 'self'; object-src 'none'; connect-src http://127.0.0.1:*"
23
23
  },
24
- "version": "2.6.0"
24
+ "version": "2.7.0"
25
25
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gmickel/gno",
3
- "version": "2.6.0",
3
+ "version": "2.7.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",
package/spec/cli.md CHANGED
@@ -9,13 +9,14 @@ This document specifies the command-line interface for GNO, a local knowledge in
9
9
 
10
10
  ### Exit Codes
11
11
 
12
- | Code | Name | Description |
13
- | ---- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
14
- | 0 | SUCCESS | Command completed successfully |
15
- | 1 | VALIDATION | Validation or usage error (bad args, missing required params) |
16
- | 2 | RUNTIME | Runtime failure (IO, DB, conversion, model, network) |
17
- | 3 | NOT_RUNNING | `--status`/`--stop` found no live matching process |
18
- | 4 | BUSY | Write-lease contention on `index` / `update` / `embed`; a lost `remember --supersede` race; a concurrent `sessions import`; a request ID still in progress (`REQUEST_PENDING`) |
12
+ | Code | Name | Description |
13
+ | ---- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
14
+ | 0 | SUCCESS | Command completed successfully |
15
+ | 1 | VALIDATION | Validation or usage error (bad args, missing required params) |
16
+ | 2 | RUNTIME | Runtime failure (IO, DB, conversion, model, network) |
17
+ | 3 | NOT_RUNNING | `--status`/`--stop` found no live matching process; `CONTEXT_STALE`: a saved Context Capsule is stale |
18
+ | 4 | BUSY | Write-lease contention on `index` / `update` / `embed`; a lost `remember --supersede` race; a concurrent `sessions import`; a request ID still in progress (`REQUEST_PENDING`); `AUDIT_FINDINGS`: `gno audit` found findings; `CONTEXT_CONFLICT`: a saved Context Capsule conflicts |
19
+ | 5 | AUDIT_PARTIAL | `gno audit` evidence is partial |
19
20
 
20
21
  ### Global Flags
21
22
 
@@ -226,9 +227,20 @@ setup and emits `setup-profile-result@1.0`.
226
227
 
227
228
  Display index status and health information.
228
229
 
229
- Embedding backlog follows the last verified partition for the selected model
230
- when exact-input storage is authoritative, counting pending document/chunk
231
- owners. Per-collection chunk totals remain deduplicated by canonical chunk;
230
+ Embedding backlog follows the partition this runtime's retrieval reads (the
231
+ caller's recorded identity under the shared selection rule; before any query or
232
+ embed has resolved it, the activated runtime-independent partition) when
233
+ exact-input storage is authoritative, counting pending document/chunk owners.
234
+ `vectorRuntime` reports `{label, state: vectors|unavailable|unresolved,
235
+ partition, reason?}` for the calling process.
236
+ `vectorPartitions` (omitted when no partition exists) lists every partition of
237
+ the model with `id`, `model`, `dimensions`, `state` (`active`|`shadow`),
238
+ `legacy` (pre-runtime-independent key), `retrieval` (this runtime reads it),
239
+ `droppable` (`gno vec drop` accepts it), `owners` (current chunks),
240
+ `provenance` (building runtime, e.g. `CUDA, Bun 1.4.2`),
241
+ `compatibleRuntimes` (runtimes that read it) and `incompatibleRuntimes`.
242
+ Terminal output prints a `Vector partitions:` block
243
+ unless there is exactly one healthy partition. Per-collection chunk totals remain deduplicated by canonical chunk;
232
244
  embedded counts require matching current inputs for every active owner within
233
245
  that collection. Status reads persisted identity and coverage without loading
234
246
  models. Legacy storage remains the fallback before variant authority; ambiguous
@@ -259,6 +271,21 @@ gno status [--json|--md]
259
271
  "totalDocuments": 100,
260
272
  "totalChunks": 500,
261
273
  "embeddingBacklog": 0,
274
+ "vectorPartitions": [
275
+ {
276
+ "id": "3f2a9c1b2d4e...",
277
+ "model": "hf:Qwen/Qwen3-Embedding-0.6B-GGUF/Qwen3-Embedding-0.6B-Q8_0.gguf",
278
+ "dimensions": 1024,
279
+ "state": "active",
280
+ "legacy": false,
281
+ "retrieval": true,
282
+ "droppable": false,
283
+ "owners": 500,
284
+ "provenance": "CUDA, Bun 1.4.2",
285
+ "compatibleRuntimes": ["CUDA, Bun 1.4.2", "CPU, Bun 1.3.14"],
286
+ "incompatibleRuntimes": []
287
+ }
288
+ ],
262
289
  "lastUpdated": "2025-12-23T10:00:00Z",
263
290
  "healthy": true,
264
291
  "activation": {
@@ -328,6 +355,32 @@ truthful about its lifecycle: `mode:"direct-cli"`, `resident:false`, no
328
355
  listener, and zero resident counters. It does not imply attachment to a live
329
356
  `serve` or `daemon`.
330
357
 
358
+ When a detached `serve` or `daemon` (found through its pid-file) has a
359
+ background job in trouble, JSON output adds `backgroundIssues`; the key is
360
+ absent otherwise. Each item is a resident-status `backgroundIssue` plus the
361
+ process that reported it:
362
+
363
+ ```json
364
+ "backgroundIssues": [
365
+ {
366
+ "process": "serve",
367
+ "pid": 41234,
368
+ "job": "embed",
369
+ "state": "parked",
370
+ "consecutiveFailures": 5,
371
+ "runningSeconds": null
372
+ }
373
+ ]
374
+ ```
375
+
376
+ `state` is `failing` (background embed passes failing and retrying with
377
+ backoff), `parked` (retries stopped after 5 failed passes; pending chunks wait
378
+ for new changes or `gno embed`), `overrunning` (one pass running longer than 15
379
+ minutes, `runningSeconds` set), or `unresponsive` (`job:"resident"`: the process
380
+ is alive but did not answer its status request within 500ms). Each resident is
381
+ asked once with that 500ms budget, so `gno status` never waits on a hung
382
+ resident. Terminal output lists the same issues under `Background issues:`.
383
+
331
384
  Local activation fingerprints use active-document identifiers and source/mirror
332
385
  hashes plus schema, tokenizer, and owned FTS synchronization metadata. Passive
333
386
  status never selects or compares stored markdown or FTS bodies. On a receipt
@@ -1006,7 +1059,7 @@ gno update [--git-pull] [--json] [--lock-wait <duration>] [--no-wait]
1006
1059
  | `--lock-wait <duration>` | duration | How long to wait for the index write lease (default: `120s`). Accepts `120`, `120s`, or `2m`. |
1007
1060
  | `--no-wait` | boolean | Do not wait; fail immediately if another writer holds the lease |
1008
1061
 
1009
- **Concurrency:** One writer at a time on the shared index database. `update` waits up to `--lock-wait` for the lease (the same `.mcp-write.lock` MCP write tools use); `index`, `embed`, `cleanup`, `vec sync`, `vec rebuild`, `collection clear-embeddings`, `tags add`, and `tags rm` follow the same contract; `capture` takes the same lock internally, and single-row writes such as `collection policy set` are absorbed by `busy_timeout`. `--no-wait` opts out. Reads (`search`, `query`, `get`) never take the lease. External serialising wrappers are no longer required for CLI-vs-CLI and CLI-vs-MCP overlap. Residual window: a resident (`gno serve`/`gno daemon`) watch or embed flush writes without the lease; those short transactions are absorbed by the raised `busy_timeout` and the SQLITE_BUSY retry, and a deferred chunk is reported as contention, never as an embedding failure.
1062
+ **Concurrency:** One writer at a time on the shared index database. `update` waits up to `--lock-wait` for the lease (the same `.mcp-write.lock` MCP write tools use); `index`, `embed`, `cleanup`, `vec sync`, `vec rebuild`, `vec drop`, `collection clear-embeddings`, `tags add`, and `tags rm` follow the same contract; `capture` takes the same lock internally, and single-row writes such as `collection policy set` are absorbed by `busy_timeout`. `--no-wait` opts out. Reads (`search`, `query`, `get`) never take the lease. External serialising wrappers are no longer required for CLI-vs-CLI and CLI-vs-MCP overlap. A resident (`gno serve`/`gno daemon`) takes the same lease without waiting around each watcher sync, embed preparation, background-embedding page write (never around inference), and the final vector activation; when the lease is held it defers that work (watcher retry after 5s, embed pass rescheduled) instead of writing, so resident background writes never hold a SQLite write lock outside the lease. The resident's own SQLite busy wait is capped at 500ms so a stop signal is always handled within the stop grace.
1010
1063
 
1011
1064
  **Behavior:**
1012
1065
 
@@ -1135,9 +1188,20 @@ memory pressure prevents creating the full pool.
1135
1188
  **Synopsis:**
1136
1189
 
1137
1190
  ```bash
1138
- gno embed [--force] [--model <uri>] [--batch-size <n>] [--dry-run] [--yes] [--json] [--lock-wait <duration>] [--no-wait]
1191
+ gno embed [--force] [--model <uri>] [--batch-size <n>] [--dry-run] [--yes] [--new-partition] [--json] [--lock-wait <duration>] [--no-wait]
1139
1192
  ```
1140
1193
 
1194
+ Vector partitions are keyed on model weights, formatter, dimensions, context
1195
+ size and truncation policy. Runtime details (Bun, `node-llama-cpp`, GPU/CPU
1196
+ backend, threads) are provenance. A runtime meeting a partition for the first
1197
+ time re-embeds up to 8 stored chunks; every one must reach cosine 0.99 against
1198
+ its stored vector, and the verdict is cached per (partition, runtime). A
1199
+ compatible runtime resumes the backlog in that partition. An incompatible one
1200
+ (or an ambiguous one-time re-key of pre-existing partitions) would build a
1201
+ separate partition: embed then states the full chunk count and an estimate and
1202
+ requires confirmation, interactively or with `--new-partition`. `--yes` alone
1203
+ never confirms; without confirmation embed exits 2 and writes nothing.
1204
+
1141
1205
  **Options:**
1142
1206
 
1143
1207
  | Option | Type | Default | Description |
@@ -1146,7 +1210,8 @@ gno embed [--force] [--model <uri>] [--batch-size <n>] [--dry-run] [--yes] [--js
1146
1210
  | `--model` | string | config | Override embedding model URI |
1147
1211
  | `--batch-size` | integer | 32 | Chunks per batch |
1148
1212
  | `--dry-run` | boolean | false | Show what would be embedded without doing it |
1149
- | `--yes`, `-y` | boolean | false | Skip confirmation prompts |
1213
+ | `--yes`, `-y` | boolean | false | Skip confirmation prompts (never confirms a separate vector partition) |
1214
+ | `--new-partition` | boolean | false | Confirm building a separate vector partition for an incompatible runtime |
1150
1215
  | `--json` | boolean | false | Output result as JSON |
1151
1216
  | `--lock-wait <duration>` | duration | `120s` | How long to wait for the index write lease. Accepts `120`, `120s`, or `2m`. |
1152
1217
  | `--no-wait` | boolean | false | Do not wait; fail immediately if another writer holds the lease |
@@ -1316,7 +1381,9 @@ by default when the collection root and `source.relPath` can be joined; search
1316
1381
  has no `--source` flag. When `absPath` is absent (unresolvable collection path,
1317
1382
  missing relPath, or a hit without a filesystem file), consumers display the URI
1318
1383
  tail and must disable file-open for that row — do not call `gno get` just to
1319
- recover a path.
1384
+ recover a path. The CLI always runs on the owner's machine; the same result shape over
1385
+ remote REST or HTTP MCP omits `absPath` (see
1386
+ [docs/API.md](../docs/API.md#host-paths-and-remote-callers)).
1320
1387
 
1321
1388
  Every structured search result may include `context`, the matching
1322
1389
  user-configured guidance joined in deterministic global, collection, then
@@ -2705,6 +2772,31 @@ content, asset descriptors, source references, nor raster bytes.
2705
2772
 
2706
2773
  ---
2707
2774
 
2775
+ ### gno vec drop
2776
+
2777
+ Drop an abandoned shadow vector partition (legacy shadows included) the calling runtime's
2778
+ retrieval does not read, with its vectors, owners and runtime verdicts.
2779
+
2780
+ **Synopsis:**
2781
+
2782
+ ```bash
2783
+ gno vec drop <partition> [--json] [--lock-wait <duration>] [--no-wait]
2784
+ ```
2785
+
2786
+ `<partition>` is an id prefix of at least 8 characters from `gno status`
2787
+ (`vectorPartitions[].id`). Only partitions with `droppable: true` are accepted:
2788
+ shadow partitions this runtime does not read; every active partition, legacy
2789
+ included, is refused. JSON output is
2790
+ `{"dropped": <vectorPartitions item>}`.
2791
+
2792
+ **Exit Codes:**
2793
+
2794
+ - 0: Dropped
2795
+ - 1: Unknown, ambiguous or protected partition
2796
+ - 4: Write lease busy with `--no-wait`
2797
+
2798
+ ---
2799
+
2708
2800
  ### gno cleanup
2709
2801
 
2710
2802
  Remove orphaned content, chunks, and vectors not referenced by active documents.
@@ -4436,15 +4528,14 @@ Errors are written to stderr. With `--json` flag, errors are also returned as:
4436
4528
  }
4437
4529
  ```
4438
4530
 
4439
- Error codes match exit codes: `VALIDATION` (exit 1), `RUNTIME` (exit 2), `NOT_RUNNING` (exit 3), `BUSY` (exit 4).
4531
+ Error codes and their exit codes: `VALIDATION` (1), `RUNTIME` (2), `NOT_RUNNING` (3), `CONTEXT_STALE` (3), `BUSY` (4), `AUDIT_FINDINGS` (4), `CONTEXT_CONFLICT` (4), `AUDIT_PARTIAL` (5). `error.schema.json` lists exactly this set.
4532
+ `AUDIT_FINDINGS`, `AUDIT_PARTIAL`, `CONTEXT_STALE`, and `CONTEXT_CONFLICT` signal through the exit code alone, after the command's own output; they write no envelope.
4440
4533
  Request ID errors keep their stable request code in `details.requestCode`
4441
4534
  (see [gno request-status](#gno-request-status)).
4442
4535
 
4443
4536
  Write-lease contention on `index` / `update` / `embed` does not use the generic envelope. Text mode writes the dedicated "index is busy" message to stderr; `--json` writes `{ success: false, error, contention }` to stdout. Both exit 4. `gno audit` also uses exit 4 for findings.
4444
4537
 
4445
- **`NOT_RUNNING` is not an error envelope.**
4446
-
4447
- **`NOT_RUNNING` is not an error envelope.** `gno serve|daemon --status --json` returns a `process-status`-shaped payload on stdout with exit 3 when no live matching process is found (it reports observable state, not failure). `--stop` exits 3 silently when there is nothing to stop and does not accept `--json`. The error envelope above is reserved for `VALIDATION` and `RUNTIME` failures where the command could not produce its structured output at all.
4538
+ **`NOT_RUNNING` is not a failure payload.** `gno serve|daemon --status --json` returns a `process-status`-shaped payload on stdout with exit 3 when no live matching process is found (it reports observable state, not failure); the `NOT_RUNNING` envelope goes to stderr only. `--stop` exits 3 silently when there is nothing to stop and does not accept `--json`. The error envelope above is reserved for `VALIDATION`, `RUNTIME`, and `BUSY` failures where the command could not produce its structured output at all.
4448
4539
 
4449
4540
  ---
4450
4541
 
package/spec/mcp.md CHANGED
@@ -267,6 +267,15 @@ Because `gno serve` shares this listener with its Web UI and REST API, it
267
267
  remains loopback-only. Use the headless `gno daemon` command for an explicitly
268
268
  authenticated non-loopback MCP listener.
269
269
 
270
+ HTTP MCP results never carry a host absolute path, whatever the peer zone:
271
+ every `absPath` field (`source.absPath` on search/query/ask/get/multi-get
272
+ results, top-level `absPath` on `gno_capture` and `gno_remember` receipts,
273
+ `similar[].absPath`, peek `recent[].absPath`) is removed from both
274
+ `structuredContent` and the text content, and a resource header's `source:`
275
+ line names the collection-relative path. Callers address documents by `uri`
276
+ and `relPath`. Stdio callers keep host paths. The field inventory lives in
277
+ [docs/API.md](../docs/API.md#host-paths-and-remote-callers).
278
+
270
279
  HTTP MCP remains read-only unless `gateway.enableWrite: true` or
271
280
  `--mcp-enable-write` is explicitly set. Bearer authentication alone does not
272
281
  authorize mutation. Unauthorized calls to write tools fail with HTTP 403 before
@@ -1343,6 +1352,21 @@ counters; it never claims attachment to another process.
1343
1352
  "totalDocuments": 150,
1344
1353
  "totalChunks": 800,
1345
1354
  "embeddingBacklog": 0,
1355
+ "vectorPartitions": [
1356
+ {
1357
+ "id": "3f2a9c1b2d4e...",
1358
+ "model": "hf:Qwen/Qwen3-Embedding-0.6B-GGUF/Qwen3-Embedding-0.6B-Q8_0.gguf",
1359
+ "dimensions": 1024,
1360
+ "state": "active",
1361
+ "legacy": false,
1362
+ "retrieval": true,
1363
+ "droppable": false,
1364
+ "owners": 500,
1365
+ "provenance": "CUDA, Bun 1.4.2",
1366
+ "compatibleRuntimes": ["CUDA, Bun 1.4.2", "CPU, Bun 1.3.14"],
1367
+ "incompatibleRuntimes": []
1368
+ }
1369
+ ],
1346
1370
  "contentTypeBoost": {
1347
1371
  "rulesFingerprint": "<sha256>",
1348
1372
  "rules": [{ "id": "decision", "searchBoost": 2 }]
@@ -1352,6 +1376,16 @@ counters; it never claims attachment to another process.
1352
1376
  }
1353
1377
  ```
1354
1378
 
1379
+ `vectorPartitions` (omitted when none exist) lists the embedding model's
1380
+ vector partitions; `embeddingBacklog` and per-collection embedded counts use
1381
+ the one with `retrieval: true`, the partition this server process's queries
1382
+ read under the same selection rule as retrieval (`vectorRuntime` reports
1383
+ `vectors`, `unavailable` with a reason, or `unresolved` before its first query
1384
+ or embed). `droppable` marks what `gno vec drop` accepts. Other partitions carry `state`, `owners` and a
1385
+ readable `provenance`; `compatibleRuntimes` names the runtimes that read a
1386
+ partition and `incompatibleRuntimes` names runtimes measured unable to
1387
+ reproduce the stored vectors, whose queries use lexical retrieval only.
1388
+
1355
1389
  `contentTypeBoost` is a redacted ranking-status projection. It exposes only
1356
1390
  normalized IDs/factors plus the rules fingerprint; path prefixes are never
1357
1391
  returned.
@@ -1682,7 +1716,7 @@ file edits update existing notes, `gno_remember` upserts a fact.
1682
1716
  fact, nothing written
1683
1717
  - `outcome: "candidates"` — likely matches and no `decision`; `candidates[]`
1684
1718
  carry `similarity` and `match` (`exact` | `likely` | `weak`), nothing written
1685
- - `outcome: "added" | "superseded"` — `record`, `absPath`, and
1719
+ - `outcome: "added" | "superseded"` — `record`, `absPath` (stdio only), and
1686
1720
  `sync.status` (`completed` before the call returns; the fact is lexically
1687
1721
  searchable)
1688
1722
  - `matching` — `mode` (`semantic` | `lexical`), `threshold`, and
@@ -2915,7 +2949,7 @@ Content includes optional header comment:
2915
2949
  |-------|-------------|
2916
2950
  | URI | Full gno:// URI |
2917
2951
  | docid | Document ID |
2918
- | source | Absolute path to source file |
2952
+ | source | Absolute path to source file (stdio); collection-relative path over HTTP |
2919
2953
  | mime | Source file MIME type |
2920
2954
  | language | Document language hint (if available) |
2921
2955
 
@@ -322,7 +322,7 @@
322
322
  "properties": {
323
323
  "absPath": {
324
324
  "type": "string",
325
- "description": "Absolute path (included with --source or in MCP)"
325
+ "description": "Absolute source path. Host path: local callers only (CLI, stdio MCP, same-host Web UI/REST); omitted for remote REST and HTTP MCP callers, which identify the document by uri + relPath."
326
326
  },
327
327
  "relPath": {
328
328
  "type": "string",
@@ -43,7 +43,7 @@
43
43
  },
44
44
  "absPath": {
45
45
  "type": "string",
46
- "description": "Absolute path when the local surface exposes it."
46
+ "description": "Absolute path of the written file. Host path: local callers only (CLI, stdio MCP, same-host Web UI/REST); omitted for remote REST and HTTP MCP callers, which identify the document by uri + relPath."
47
47
  },
48
48
  "serverInstanceId": {
49
49
  "type": "string"
@@ -243,6 +243,94 @@
243
243
  "type": "string"
244
244
  }
245
245
  },
246
+ "vectorPartitions": {
247
+ "type": "array",
248
+ "description": "Vector partitions (vector-partitions check); `retrieval` marks the one status and search use",
249
+ "items": {
250
+ "type": "object",
251
+ "additionalProperties": false,
252
+ "required": [
253
+ "id",
254
+ "model",
255
+ "dimensions",
256
+ "state",
257
+ "legacy",
258
+ "retrieval",
259
+ "droppable",
260
+ "owners",
261
+ "provenance",
262
+ "compatibleRuntimes",
263
+ "incompatibleRuntimes"
264
+ ],
265
+ "properties": {
266
+ "id": {
267
+ "type": "string"
268
+ },
269
+ "model": {
270
+ "type": "string"
271
+ },
272
+ "dimensions": {
273
+ "type": "integer",
274
+ "minimum": 1
275
+ },
276
+ "state": {
277
+ "type": "string",
278
+ "enum": ["active", "shadow"]
279
+ },
280
+ "legacy": {
281
+ "type": "boolean"
282
+ },
283
+ "retrieval": {
284
+ "type": "boolean"
285
+ },
286
+ "droppable": {
287
+ "type": "boolean"
288
+ },
289
+ "owners": {
290
+ "type": "integer",
291
+ "minimum": 0
292
+ },
293
+ "provenance": {
294
+ "type": "string"
295
+ },
296
+ "compatibleRuntimes": {
297
+ "type": "array",
298
+ "items": {
299
+ "type": "string"
300
+ }
301
+ },
302
+ "incompatibleRuntimes": {
303
+ "type": "array",
304
+ "items": {
305
+ "type": "string"
306
+ }
307
+ }
308
+ }
309
+ }
310
+ },
311
+ "vectorRuntime": {
312
+ "type": "object",
313
+ "additionalProperties": false,
314
+ "required": ["label", "state", "partition"],
315
+ "description": "This process's runtime, resolved by the same selection rule its queries use",
316
+ "properties": {
317
+ "label": {
318
+ "type": ["string", "null"],
319
+ "description": "Runtime recorded by this caller's last query or embed"
320
+ },
321
+ "state": {
322
+ "type": "string",
323
+ "enum": ["vectors", "unavailable", "unresolved"],
324
+ "description": "vectors: queries read `partition`; unavailable: lexical retrieval only; unresolved: no query or embed has resolved this caller yet"
325
+ },
326
+ "partition": {
327
+ "type": ["string", "null"]
328
+ },
329
+ "reason": {
330
+ "type": "string"
331
+ }
332
+ }
333
+ },
246
334
  "embeddingFingerprint": {
247
335
  "type": "object",
248
336
  "description": "Embedding freshness fingerprint diagnostics",
@@ -12,8 +12,17 @@
12
12
  "properties": {
13
13
  "code": {
14
14
  "type": "string",
15
- "description": "Error code matching exit code",
16
- "enum": ["VALIDATION", "RUNTIME"]
15
+ "description": "CLI error code; each maps to one exit code (see spec/cli.md Error Output)",
16
+ "enum": [
17
+ "VALIDATION",
18
+ "RUNTIME",
19
+ "NOT_RUNNING",
20
+ "BUSY",
21
+ "AUDIT_FINDINGS",
22
+ "AUDIT_PARTIAL",
23
+ "CONTEXT_STALE",
24
+ "CONTEXT_CONFLICT"
25
+ ]
17
26
  },
18
27
  "message": {
19
28
  "type": "string",
@@ -62,7 +62,7 @@
62
62
  "properties": {
63
63
  "absPath": {
64
64
  "type": "string",
65
- "description": "Absolute path to source file"
65
+ "description": "Absolute path to source file. Host path: local callers only (CLI, stdio MCP, same-host Web UI/REST); omitted for remote REST and HTTP MCP callers, which identify the document by uri + relPath."
66
66
  },
67
67
  "relPath": {
68
68
  "type": "string",
@@ -7,7 +7,6 @@
7
7
  "required": [
8
8
  "docid",
9
9
  "uri",
10
- "absPath",
11
10
  "collection",
12
11
  "relPath",
13
12
  "created",
@@ -34,7 +33,7 @@
34
33
  },
35
34
  "absPath": {
36
35
  "type": "string",
37
- "description": "Absolute path to the created file"
36
+ "description": "Absolute path to the created file. Stdio callers only; omitted for HTTP MCP callers, which identify the file by uri + relPath."
38
37
  },
39
38
  "collection": {
40
39
  "type": "string",
@@ -34,13 +34,13 @@
34
34
  {
35
35
  "type": "object",
36
36
  "additionalProperties": false,
37
- "required": ["outcome", "record", "absPath", "sync", "matching"],
37
+ "required": ["outcome", "record", "sync", "matching"],
38
38
  "properties": {
39
39
  "outcome": { "enum": ["added", "superseded"] },
40
40
  "record": { "$ref": "#/$defs/fact" },
41
41
  "absPath": {
42
42
  "type": "string",
43
- "description": "Absolute path of the fact file that was written."
43
+ "description": "Absolute path of the fact file that was written. Host path: local callers only (CLI, stdio MCP, same-host Web UI/REST); omitted for remote REST and HTTP MCP callers, which identify the document by uri + relPath."
44
44
  },
45
45
  "sync": { "$ref": "#/$defs/sync" },
46
46
  "matching": { "$ref": "#/$defs/matching" },
@@ -40,7 +40,10 @@
40
40
  "type": "object",
41
41
  "required": ["relPath", "mime", "ext"],
42
42
  "properties": {
43
- "absPath": { "type": "string" },
43
+ "absPath": {
44
+ "type": "string",
45
+ "description": "Absolute path to source file. Host path: local callers only (CLI, stdio MCP, same-host Web UI/REST); omitted for remote REST and HTTP MCP callers, which identify the document by uri + relPath."
46
+ },
44
47
  "relPath": { "type": "string" },
45
48
  "mime": { "type": "string" },
46
49
  "ext": { "type": "string", "pattern": "^\\.[a-zA-Z0-9]+$" }
@@ -99,14 +99,7 @@
99
99
  "items": {
100
100
  "type": "object",
101
101
  "additionalProperties": false,
102
- "required": [
103
- "docid",
104
- "uri",
105
- "title",
106
- "collection",
107
- "absPath",
108
- "modifiedAt"
109
- ],
102
+ "required": ["docid", "uri", "title", "collection", "modifiedAt"],
110
103
  "properties": {
111
104
  "docid": {
112
105
  "type": "string",
@@ -129,7 +122,7 @@
129
122
  "absPath": {
130
123
  "type": "string",
131
124
  "minLength": 1,
132
- "description": "Absolute source path (collection root + relative path)"
125
+ "description": "Absolute source path (collection root + relative path). CLI and stdio MCP only; omitted for HTTP MCP callers."
133
126
  },
134
127
  "modifiedAt": {
135
128
  "type": "string",
@@ -128,6 +128,28 @@
128
128
  "content": { "type": "integer", "minimum": 0 },
129
129
  "index": { "type": "integer", "minimum": 0 }
130
130
  }
131
+ },
132
+ "backgroundIssues": {
133
+ "description": "Present only while a background job is in trouble: failing passes, retries parked, a pass overrunning, or (client-side) a resident that did not answer its status request",
134
+ "type": "array",
135
+ "minItems": 1,
136
+ "items": { "$ref": "#/definitions/backgroundIssue" }
137
+ }
138
+ },
139
+ "definitions": {
140
+ "backgroundIssue": {
141
+ "type": "object",
142
+ "additionalProperties": false,
143
+ "required": ["job", "state", "consecutiveFailures", "runningSeconds"],
144
+ "properties": {
145
+ "job": { "type": "string", "enum": ["embed", "resident"] },
146
+ "state": {
147
+ "type": "string",
148
+ "enum": ["failing", "parked", "overrunning", "unresponsive"]
149
+ },
150
+ "consecutiveFailures": { "type": "integer", "minimum": 0 },
151
+ "runningSeconds": { "type": ["integer", "null"], "minimum": 0 }
152
+ }
131
153
  }
132
154
  },
133
155
  "allOf": [