@gmickel/gno 2.5.1 → 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 (160) hide show
  1. package/README.md +60 -5
  2. package/assets/skill/README.md +5 -1
  3. package/assets/skill/SKILL.md +80 -4
  4. package/assets/skill/cli-reference.md +132 -2
  5. package/assets/skill/examples.md +30 -0
  6. package/assets/skill/mcp-reference.md +54 -1
  7. package/assets/skill/recipes/capture-and-file.md +6 -0
  8. package/assets/skill/recipes/memory-file-decision.md +6 -0
  9. package/assets/skill/recipes/memory-supersede-fact.md +5 -0
  10. package/assets/skill/recipes/session-evidence-lookup.md +98 -0
  11. package/assets/spa-production.json.gz +0 -0
  12. package/browser-extension/artifacts/{gno-browser-clipper-v2.5.1.zip → gno-browser-clipper-v2.7.0.zip} +0 -0
  13. package/browser-extension/artifacts/gno-browser-clipper-v2.7.0.zip.sha256 +1 -0
  14. package/browser-extension/dist/manifest.json +1 -1
  15. package/package.json +2 -1
  16. package/spec/cli.md +449 -35
  17. package/spec/mcp.md +234 -4
  18. package/spec/output-schemas/ask.schema.json +1 -1
  19. package/spec/output-schemas/capture-receipt.schema.json +4 -1
  20. package/spec/output-schemas/doctor.schema.json +88 -0
  21. package/spec/output-schemas/error.schema.json +11 -2
  22. package/spec/output-schemas/get.schema.json +1 -1
  23. package/spec/output-schemas/mcp-capture-result.schema.json +4 -2
  24. package/spec/output-schemas/memory-remember.schema.json +10 -4
  25. package/spec/output-schemas/multi-get.schema.json +4 -1
  26. package/spec/output-schemas/peek.schema.json +2 -9
  27. package/spec/output-schemas/request-status.schema.json +113 -0
  28. package/spec/output-schemas/resident-status.schema.json +22 -0
  29. package/spec/output-schemas/search-result.schema.json +1 -1
  30. package/spec/output-schemas/search-results.schema.json +1 -1
  31. package/spec/output-schemas/sessions-automation-run.schema.json +46 -0
  32. package/spec/output-schemas/sessions-discovery.schema.json +38 -0
  33. package/spec/output-schemas/sessions-import-receipt.schema.json +156 -0
  34. package/spec/output-schemas/sessions-status.schema.json +432 -0
  35. package/spec/output-schemas/status.schema.json +98 -0
  36. package/src/cli/commands/ask.ts +14 -2
  37. package/src/cli/commands/capture.ts +55 -96
  38. package/src/cli/commands/daemon.ts +41 -0
  39. package/src/cli/commands/doctor.ts +54 -20
  40. package/src/cli/commands/embed.ts +41 -3
  41. package/src/cli/commands/ls.ts +3 -0
  42. package/src/cli/commands/memory.ts +12 -3
  43. package/src/cli/commands/query.ts +5 -0
  44. package/src/cli/commands/request-status.ts +59 -0
  45. package/src/cli/commands/reset.ts +39 -5
  46. package/src/cli/commands/sessions.ts +713 -0
  47. package/src/cli/commands/shared.ts +14 -1
  48. package/src/cli/commands/status.ts +63 -5
  49. package/src/cli/commands/vec.ts +54 -0
  50. package/src/cli/detach.ts +29 -1
  51. package/src/cli/errors.ts +13 -9
  52. package/src/cli/program.ts +441 -2
  53. package/src/cli/session-binding.ts +49 -0
  54. package/src/config/types.ts +8 -0
  55. package/src/core/capture-publish.ts +239 -0
  56. package/src/core/capture-sync.ts +12 -2
  57. package/src/core/host-paths.ts +31 -0
  58. package/src/core/memory-remember.ts +234 -122
  59. package/src/core/memory-types.ts +11 -0
  60. package/src/core/network-boundary-inventory.ts +8 -0
  61. package/src/core/request-receipts.ts +671 -0
  62. package/src/core/shutdown-budget.ts +6 -0
  63. package/src/core/vector-partition-status.ts +52 -0
  64. package/src/embed/backlog.ts +124 -18
  65. package/src/embed/fingerprint.ts +6 -3
  66. package/src/embed/retry.ts +66 -27
  67. package/src/embed/variant-backlog.ts +15 -10
  68. package/src/embed/variant-retry.ts +31 -22
  69. package/src/index.ts +30 -2
  70. package/src/llm/native-worker/dispatcher.ts +2 -0
  71. package/src/llm/native-worker/embedding-identity.ts +42 -0
  72. package/src/llm/native-worker/protocol.ts +1 -0
  73. package/src/llm/types.ts +3 -0
  74. package/src/mcp/context.ts +17 -0
  75. package/src/mcp/http-egress.ts +4 -0
  76. package/src/mcp/http-transport.ts +2 -0
  77. package/src/mcp/resources/index.ts +6 -5
  78. package/src/mcp/tool-descriptions-core.ts +1 -1
  79. package/src/mcp/tools/capture.ts +87 -85
  80. package/src/mcp/tools/index.ts +77 -4
  81. package/src/mcp/tools/memory-remember.ts +8 -1
  82. package/src/mcp/tools/memory-shared.ts +7 -1
  83. package/src/mcp/tools/request-status.ts +73 -0
  84. package/src/mcp/tools/sessions.ts +208 -0
  85. package/src/mcp/tools/status.ts +4 -0
  86. package/src/pipeline/hybrid.ts +37 -7
  87. package/src/pipeline/vsearch.ts +14 -2
  88. package/src/sdk/client.ts +180 -84
  89. package/src/sdk/index.ts +6 -0
  90. package/src/sdk/types.ts +54 -2
  91. package/src/serve/capture-service.ts +98 -32
  92. package/src/serve/config-sync.ts +3 -2
  93. package/src/serve/embed-scheduler.ts +133 -19
  94. package/src/serve/host-path-redaction.ts +79 -0
  95. package/src/serve/public/app.tsx +4 -1
  96. package/src/serve/public/components/CaptureModal.tsx +26 -8
  97. package/src/serve/public/components/sessions/AutomationPanel.tsx +800 -0
  98. package/src/serve/public/components/sessions/ImportReceipt.tsx +238 -0
  99. package/src/serve/public/components/sessions/SessionSearch.tsx +286 -0
  100. package/src/serve/public/components/sessions/SourcesPanel.tsx +541 -0
  101. package/src/serve/public/components/sessions/api.ts +40 -0
  102. package/src/serve/public/globals.built.css +1 -1
  103. package/src/serve/public/hooks/use-api.ts +26 -3
  104. package/src/serve/public/lib/request-intent.ts +77 -0
  105. package/src/serve/public/lib/snippet.tsx +52 -0
  106. package/src/serve/public/lib/workspace-actions.ts +12 -1
  107. package/src/serve/public/lib/workspace-tabs.ts +2 -0
  108. package/src/serve/public/pages/Dashboard.tsx +22 -9
  109. package/src/serve/public/pages/DocView.tsx +25 -6
  110. package/src/serve/public/pages/DocumentEditor.tsx +224 -104
  111. package/src/serve/public/pages/Search.tsx +1 -41
  112. package/src/serve/public/pages/Sessions.tsx +350 -0
  113. package/src/serve/resident-runtime.ts +69 -4
  114. package/src/serve/resident-status.ts +13 -1
  115. package/src/serve/routes/api.ts +476 -147
  116. package/src/serve/routes/sessions.ts +766 -0
  117. package/src/serve/security.ts +9 -0
  118. package/src/serve/server.ts +215 -10
  119. package/src/serve/session-automation.ts +146 -0
  120. package/src/serve/status-model.ts +16 -0
  121. package/src/serve/status.ts +2 -0
  122. package/src/serve/watch-reconciliation-shared.ts +3 -0
  123. package/src/serve/watch-service-events.ts +3 -2
  124. package/src/serve/watch-service-run-flush.ts +35 -2
  125. package/src/serve/watch-service.ts +5 -0
  126. package/src/sessions/archive.ts +348 -0
  127. package/src/sessions/automation-state.ts +444 -0
  128. package/src/sessions/automation-status.ts +239 -0
  129. package/src/sessions/automation.ts +1169 -0
  130. package/src/sessions/binding.ts +105 -0
  131. package/src/sessions/claude-hook.ts +240 -0
  132. package/src/sessions/config.ts +176 -0
  133. package/src/sessions/format.ts +191 -0
  134. package/src/sessions/import-child-env.ts +8 -0
  135. package/src/sessions/import-child.ts +152 -0
  136. package/src/sessions/parsers/claude-code.ts +259 -0
  137. package/src/sessions/parsers/codex.ts +303 -0
  138. package/src/sessions/parsers/hermes.ts +248 -0
  139. package/src/sessions/parsers/openclaw.ts +496 -0
  140. package/src/sessions/parsers/shared.ts +184 -0
  141. package/src/sessions/sanitize.ts +222 -0
  142. package/src/sessions/service.ts +1533 -0
  143. package/src/sessions/setup.ts +477 -0
  144. package/src/sessions/sources.ts +518 -0
  145. package/src/sessions/state.ts +118 -0
  146. package/src/sessions/types.ts +457 -0
  147. package/src/store/migrations/031-runtime-independent-vectors.ts +29 -0
  148. package/src/store/migrations/032-vector-runtime-callers.ts +17 -0
  149. package/src/store/migrations/index.ts +4 -0
  150. package/src/store/sqlite/adapter.ts +76 -16
  151. package/src/store/sqlite/scoped-index.ts +9 -0
  152. package/src/store/types.ts +11 -1
  153. package/src/store/vector/lazy.ts +46 -43
  154. package/src/store/vector/runtime-compat.ts +651 -0
  155. package/src/store/vector/sqlite-vec.ts +20 -2
  156. package/src/store/vector/status.ts +276 -35
  157. package/src/store/vector/types.ts +2 -0
  158. package/src/store/vector/variant-search.ts +71 -23
  159. package/src/store/vector/variants.ts +49 -14
  160. package/browser-extension/artifacts/gno-browser-clipper-v2.5.1.zip.sha256 +0 -1
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 |
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
 
@@ -85,7 +86,9 @@ equivalent files fail closed as ambiguous.
85
86
  | ask | yes | no | no | yes | no | terminal |
86
87
  | capture | yes | no | no | no | no | terminal |
87
88
  | remember | yes | no | no | no | no | terminal |
89
+ | request-status | yes | no | no | no | no | terminal |
88
90
  | recall | yes | no | no | no | no | terminal |
91
+ | sessions | yes | no | no | no | no | terminal |
89
92
  | get | yes | no | no | yes | no | terminal |
90
93
  | multi-get | yes | yes | no | yes | no | terminal |
91
94
  | ls | yes | yes | no | yes | no | terminal |
@@ -224,9 +227,20 @@ setup and emits `setup-profile-result@1.0`.
224
227
 
225
228
  Display index status and health information.
226
229
 
227
- Embedding backlog follows the last verified partition for the selected model
228
- when exact-input storage is authoritative, counting pending document/chunk
229
- 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;
230
244
  embedded counts require matching current inputs for every active owner within
231
245
  that collection. Status reads persisted identity and coverage without loading
232
246
  models. Legacy storage remains the fallback before variant authority; ambiguous
@@ -257,6 +271,21 @@ gno status [--json|--md]
257
271
  "totalDocuments": 100,
258
272
  "totalChunks": 500,
259
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
+ ],
260
289
  "lastUpdated": "2025-12-23T10:00:00Z",
261
290
  "healthy": true,
262
291
  "activation": {
@@ -326,6 +355,32 @@ truthful about its lifecycle: `mode:"direct-cli"`, `resident:false`, no
326
355
  listener, and zero resident counters. It does not imply attachment to a live
327
356
  `serve` or `daemon`.
328
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
+
329
384
  Local activation fingerprints use active-document identifiers and source/mirror
330
385
  hashes plus schema, tokenizer, and owned FTS synchronization metadata. Passive
331
386
  status never selects or compares stored markdown or FTS bodies. On a receipt
@@ -1004,7 +1059,7 @@ gno update [--git-pull] [--json] [--lock-wait <duration>] [--no-wait]
1004
1059
  | `--lock-wait <duration>` | duration | How long to wait for the index write lease (default: `120s`). Accepts `120`, `120s`, or `2m`. |
1005
1060
  | `--no-wait` | boolean | Do not wait; fail immediately if another writer holds the lease |
1006
1061
 
1007
- **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.
1008
1063
 
1009
1064
  **Behavior:**
1010
1065
 
@@ -1133,9 +1188,20 @@ memory pressure prevents creating the full pool.
1133
1188
  **Synopsis:**
1134
1189
 
1135
1190
  ```bash
1136
- 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]
1137
1192
  ```
1138
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
+
1139
1205
  **Options:**
1140
1206
 
1141
1207
  | Option | Type | Default | Description |
@@ -1144,7 +1210,8 @@ gno embed [--force] [--model <uri>] [--batch-size <n>] [--dry-run] [--yes] [--js
1144
1210
  | `--model` | string | config | Override embedding model URI |
1145
1211
  | `--batch-size` | integer | 32 | Chunks per batch |
1146
1212
  | `--dry-run` | boolean | false | Show what would be embedded without doing it |
1147
- | `--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 |
1148
1215
  | `--json` | boolean | false | Output result as JSON |
1149
1216
  | `--lock-wait <duration>` | duration | `120s` | How long to wait for the index write lease. Accepts `120`, `120s`, or `2m`. |
1150
1217
  | `--no-wait` | boolean | false | Do not wait; fail immediately if another writer holds the lease |
@@ -1314,7 +1381,9 @@ by default when the collection root and `source.relPath` can be joined; search
1314
1381
  has no `--source` flag. When `absPath` is absent (unresolvable collection path,
1315
1382
  missing relPath, or a hit without a filesystem file), consumers display the URI
1316
1383
  tail and must disable file-open for that row — do not call `gno get` just to
1317
- 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)).
1318
1387
 
1319
1388
  Every structured search result may include `context`, the matching
1320
1389
  user-configured guidance joined in deterministic global, collection, then
@@ -1628,7 +1697,7 @@ Capture a note into an editable collection with structured provenance.
1628
1697
  **Synopsis:**
1629
1698
 
1630
1699
  ```bash
1631
- gno capture [content...] [--stdin|--file <path>] [--collection <name>] [--title <title>] [--path <relPath>] [--folder <relPath>] [--preset <id>] [--tags <tags>] [--collision-policy <policy>] [--source-kind <kind>] [--source-url <url>] [--source-title <title>] [--source-author <author>] [--source-date <date>] [--source-id <id>] [--json]
1700
+ gno capture [content...] [--stdin|--file <path>] [--collection <name>] [--title <title>] [--path <relPath>] [--folder <relPath>] [--preset <id>] [--tags <tags>] [--collision-policy <policy>] [--source-kind <kind>] [--source-url <url>] [--source-title <title>] [--source-author <author>] [--source-date <date>] [--source-id <id>] [--request-id <id>] [--json]
1632
1701
  ```
1633
1702
 
1634
1703
  **Content Sources:**
@@ -1684,8 +1753,33 @@ gno capture "thought to remember"
1684
1753
  gno capture --stdin --collection notes --preset source-summary --tags inbox,gno
1685
1754
  gno capture --file ./clip.md --source-url https://example.com --source-kind web --json
1686
1755
  gno capture "meeting note" --quiet
1756
+ gno capture "Release moves to Friday" --collection notes --request-id 0f8e5c1a-3c1e-4d0b-9a57-2f4f3b8f2c11 --json
1687
1757
  ```
1688
1758
 
1759
+ **Write and sync:**
1760
+
1761
+ - Planning, the write, and lexical sync run under the shared write lease
1762
+ (`.mcp-write.lock`), the same leased publication MCP `gno_capture` and REST
1763
+ `POST /api/capture` use. A lease held past the wait window fails with the
1764
+ busy error; nothing is written.
1765
+ - Without `--request-id`, a written file whose lexical sync fails still exits 0
1766
+ with `sync.status: "failed"` and `sync.error` in the receipt; `gno update`
1767
+ indexes it. `open_existing` on a file that is on disk but not indexed yet
1768
+ returns `sync.status: "skipped"` (`Existing file is not indexed yet.`).
1769
+
1770
+ **Request IDs:**
1771
+
1772
+ - `--request-id <id>` (1-128 of `A-Z a-z 0-9 . _ : -`, starting with a letter
1773
+ or digit) makes a retry of the same command safe.
1774
+ - With an ID, a written file whose lexical sync fails exits `RUNTIME` (2) and
1775
+ the request stays pending; rerunning with the same ID finishes it.
1776
+ - With an ID, `--json` adds
1777
+ `request: { requestId, status: "committed", replayed, committedAt }` to the
1778
+ capture receipt; terminal output adds `Request: <id> committed`, plus
1779
+ `(replayed, nothing written again)` on a replay.
1780
+ - Request error codes and exits: see [gno request-status](#gno-request-status).
1781
+ Semantics: `docs/guides/retries-and-request-ids.md`.
1782
+
1689
1783
  ---
1690
1784
 
1691
1785
  ### gno remember
@@ -1697,7 +1791,7 @@ write lease directly.
1697
1791
  **Synopsis:**
1698
1792
 
1699
1793
  ```bash
1700
- gno remember <text> --scope <scope> [--scope <scope>...] [--collection <name>] [--decision add|supersede | --add | --supersede <uri>] [--predecessor <uri>] [--predecessor-hash <hash>] [--receipt <path>] [--derived-from <uri>...] [--source <text>] [--caller <id>] [--session <id>] [--json]
1794
+ gno remember <text> --scope <scope> [--scope <scope>...] [--collection <name>] [--decision add|supersede | --add | --supersede <uri>] [--predecessor <uri>] [--predecessor-hash <hash>] [--receipt <path>] [--derived-from <uri>...] [--source <text>] [--caller <id>] [--session <id>] [--request-id <id>] [--json]
1701
1795
  ```
1702
1796
 
1703
1797
  **Scope and collection (fail-closed):**
@@ -1731,6 +1825,16 @@ gno remember <text> --scope <scope> [--scope <scope>...] [--collection <name>] [
1731
1825
  - A write returns success only after the file exists and lexical sync
1732
1826
  completed; the fact is retrievable before the command exits.
1733
1827
 
1828
+ **Request IDs:**
1829
+
1830
+ - `--request-id <id>` applies to writes only (`--add`, `--supersede`, or
1831
+ `--decision`); without a decision it fails `VALIDATION`
1832
+ (`REQUEST_ID_INVALID`). Rerunning the same write with the same ID is safe.
1833
+ - With an ID, `--json` adds
1834
+ `request: { requestId, status: "committed", replayed, committedAt }`;
1835
+ terminal output adds `Request: <id> committed`.
1836
+ - Semantics (replay, recovery, conflicts): `docs/guides/retries-and-request-ids.md`.
1837
+
1734
1838
  **Context fencing:**
1735
1839
 
1736
1840
  - `--receipt <path>` presents a recall receipt (the `recall --json` output or
@@ -1762,7 +1866,8 @@ predecessor, and fence errors; `BUSY` (4) when another writer holds the lease
1762
1866
  (`MEMORY_SUPERSEDE_CONFLICT`); `RUNTIME` (2) when the file was written but
1763
1867
  lexical sync failed (`MEMORY_SYNC_FAILED`) or the successor's `supersedes`
1764
1868
  edge did not project (`MEMORY_SUPERSEDE_PROJECTION_FAILED`). The JSON envelope carries the core code in
1765
- `details.memoryCode`.
1869
+ `details.memoryCode`. Request ID errors map as listed under
1870
+ [gno request-status](#gno-request-status) and carry `details.requestCode`.
1766
1871
 
1767
1872
  **Examples:**
1768
1873
 
@@ -1770,6 +1875,86 @@ edge did not project (`MEMORY_SUPERSEDE_PROJECTION_FAILED`). The JSON envelope c
1770
1875
  gno remember "Finn's kindergarten starts at 08:30" --scope family --add
1771
1876
  gno remember "Prod deploys from main only" --scope project:gno --scope ops
1772
1877
  gno remember "Prod deploys from release/*" --scope project:gno --supersede gno://memory/facts/2026/... --predecessor-hash <hash> --json
1878
+ gno remember "Prod deploys from main only" --scope project:gno --add --request-id 7d2e4b90-1f7a-4c2e-8f55-0b9c1d3e6a42 --json
1879
+ ```
1880
+
1881
+ ---
1882
+
1883
+ ### gno request-status
1884
+
1885
+ Look up a request ID sent with `gno capture`, `gno remember`, or a REST/Web UI
1886
+ document save before retrying the write. Read-only; takes no write lease.
1887
+
1888
+ **Synopsis:**
1889
+
1890
+ ```bash
1891
+ gno request-status <request-id> [--json]
1892
+ ```
1893
+
1894
+ **Behavior:**
1895
+
1896
+ - Reads the index's private request ledger in the local-owner namespace.
1897
+ Honors the global `--index` flag.
1898
+ - Returns a content-free pointer, never note or fact text. Status meanings and
1899
+ namespaces: `docs/guides/retries-and-request-ids.md`.
1900
+
1901
+ **Output:**
1902
+
1903
+ `--json` prints the [`request-status`](./output-schemas/request-status.schema.json)
1904
+ result:
1905
+
1906
+ ```json
1907
+ {
1908
+ "requestId": "0f8e5c1a-3c1e-4d0b-9a57-2f4f3b8f2c11",
1909
+ "status": "committed",
1910
+ "operation": "capture",
1911
+ "createdAt": "2026-09-24T08:00:00.000Z",
1912
+ "updatedAt": "2026-09-24T08:00:00.120Z",
1913
+ "result": {
1914
+ "uri": "gno://notes/inbox/2026-09-24/capture-3f9c.md",
1915
+ "docid": "#a1b2c3",
1916
+ "contentHash": "<sha256>"
1917
+ }
1918
+ }
1919
+ ```
1920
+
1921
+ - `status`: `pending` | `committed` | `expired` | `not_found`.
1922
+ - `operation`: `capture` | `remember` | `document.update`; `createdAt`,
1923
+ `updatedAt`, and `operation` are absent for `not_found`.
1924
+ - `result` only for `committed`: `uri`, `docid`, and `contentHash` (capture,
1925
+ remember) or `sourceHash` (document update).
1926
+
1927
+ Terminal output prints `Request:`, `Status:`, and, when present,
1928
+ `Operation:`, `Updated:`, and `URI:` lines, then one next-step line:
1929
+
1930
+ | Status | Next-step line |
1931
+ | ----------- | ------------------------------------------------------------------------------------------------- |
1932
+ | `committed` | `Committed: do not resend; the retained outcome replays.` |
1933
+ | `pending` | `Pending: retry the same command with the same --request-id to finish it.` |
1934
+ | `expired` | `Expired: this ID already ran and will not run again; check current state before using a new ID.` |
1935
+ | `not_found` | `Not found: nothing was accepted under this ID.` |
1936
+
1937
+ **Request error codes** (every CLI surface that takes a request ID; the JSON
1938
+ error envelope carries the request code in `details.requestCode`):
1939
+
1940
+ | Request code | CLI code | Exit |
1941
+ | ---------------------------- | ------------ | ---- |
1942
+ | `REQUEST_ID_INVALID` | `VALIDATION` | 1 |
1943
+ | `REQUEST_ID_CONFLICT` | `VALIDATION` | 1 |
1944
+ | `REQUEST_EXPIRED` | `VALIDATION` | 1 |
1945
+ | `REQUEST_PENDING` | `BUSY` | 4 |
1946
+ | `REQUEST_RECOVERY_CONFLICT` | `RUNTIME` | 2 |
1947
+ | `REQUEST_CAPACITY_EXHAUSTED` | `RUNTIME` | 2 |
1948
+ | `REQUEST_LEDGER_UNAVAILABLE` | `RUNTIME` | 2 |
1949
+
1950
+ `gno request-status` itself exits `VALIDATION` (1) for a malformed ID and
1951
+ `RUNTIME` (2) when the ledger exists but cannot be opened.
1952
+
1953
+ **Examples:**
1954
+
1955
+ ```bash
1956
+ gno request-status 0f8e5c1a-3c1e-4d0b-9a57-2f4f3b8f2c11
1957
+ gno request-status 0f8e5c1a-3c1e-4d0b-9a57-2f4f3b8f2c11 --json
1773
1958
  ```
1774
1959
 
1775
1960
  ---
@@ -1823,6 +2008,206 @@ gno recall "kindergarten" --scope family --max-facts 3 --json > receipt.json
1823
2008
 
1824
2009
  ---
1825
2010
 
2011
+ ### gno sessions
2012
+
2013
+ Discover and manually import local agent sessions (Codex, Claude Code,
2014
+ OpenClaw, Hermes) into a dedicated session archive. Thin adapters over the
2015
+ core sessions service (`src/sessions/service.ts`). A fresh installation
2016
+ imports, watches, hooks and schedules nothing; every import is an explicit
2017
+ invocation.
2018
+
2019
+ **Archive pair (binding):**
2020
+
2021
+ - A session archive is one dedicated config file (carrying a `sessions`
2022
+ block) paired with one named index. Every archive command passes both
2023
+ explicitly: `gno --config <archive.yml> --index <name> sessions ...`.
2024
+ - `sessions init` refuses the default config file and the `default` index.
2025
+ - Before every command (all of `gno`, not only `sessions`), a config whose
2026
+ `sessions.index` differs from `--index` exits `VALIDATION`
2027
+ (`SESSIONS_BINDING_MISMATCH`), and an index recorded as an archive exits
2028
+ `VALIDATION` when opened with any other config (including cross-index
2029
+ `get`). Plain `gno update` on the default config therefore never reads the
2030
+ archive.
2031
+ - The archive root must lie outside GNO's config/data/cache directories so
2032
+ `gno reset`, index cleanup or uninstall cannot remove it, and outside every
2033
+ folder the default config indexes (`SESSIONS_UNSAFE_PATH`).
2034
+
2035
+ **Synopsis:**
2036
+
2037
+ ```bash
2038
+ gno sessions [discover] [--json]
2039
+ gno --config <archive.yml> --index <name> sessions init --archive <dir> --collection <name> [--json]
2040
+ gno --config <archive.yml> --index <name> sessions source add <id> --harness <codex|claude-code|openclaw|hermes> --path <root> --collection <name> [--project <prefix>=<collection>...] [--json]
2041
+ gno --config <archive.yml> --index <name> sessions source remove <id> [--json]
2042
+ gno --config <archive.yml> --index <name> sessions import (--source <id> | <paths...> --collection <name>) [--format <harness>] [--dry-run] [--limit <n>] [--json]
2043
+ gno --config <archive.yml> --index <name> sessions status [--json]
2044
+ gno --config <archive.yml> --index <name> sessions prune --source <id> [--apply] [--json]
2045
+ gno --config <archive.yml> --index <name> sessions automation set <profile> --source <id>... [--cadence <n>s|m|h|d] [--limit <n>] [--retries <n>] [--json]
2046
+ gno --config <archive.yml> --index <name> sessions automation preview <profile> [--settings <file>] [--json]
2047
+ gno --config <archive.yml> --index <name> sessions automation enable <profile> [--hook claude-code [--settings <file>]] [--schedule --cadence <n>s|m|h|d] [--json]
2048
+ gno --config <archive.yml> --index <name> sessions automation disable <profile> [--hook] [--schedule] [--json]
2049
+ gno --config <archive.yml> --index <name> sessions automation remove <profile> [--json]
2050
+ gno --config <archive.yml> --index <name> sessions automation run <profile> [--json]
2051
+ gno --config <archive.yml> --index <name> sessions hook claude-code --profile <id>
2052
+ ```
2053
+
2054
+ **discover** (default): previews supported local roots (`$CODEX_HOME` or
2055
+ `~/.codex/sessions`; `~/.claude/projects` and `$CLAUDE_CONFIG_DIR/projects`;
2056
+ `$OPENCLAW_STATE_DIR` or `~/.openclaw`; `$HERMES_HOME` or `~/.hermes`) with
2057
+ unit counts, sizes and sampled format versions. Never imports and needs no
2058
+ archive. Output: `sessions-discovery` schema.
2059
+
2060
+ **init**: creates or extends the archive config (idempotent). Adds the
2061
+ `sessions` block (`index`, `archiveRoot`) and one archive collection at
2062
+ `<archive>/<collection>` with the JSONL record mapping. A config already bound
2063
+ to another index or root is never retargeted.
2064
+
2065
+ **source add / remove**: registers an owner-approved source root, file or
2066
+ database with a default archive collection (created under the archive root
2067
+ when missing). `--project <prefix>=<collection>` maps recorded working
2068
+ directories under `prefix` to another archive collection. Removing a source
2069
+ keeps its archive. Registration never imports.
2070
+
2071
+ **import**: parses the selected source (or explicit paths), classifies turns
2072
+ structurally, redacts, and writes one sanitized JSONL archive file per
2073
+ thread, then syncs the changed files through the ordinary JSONL record
2074
+ adapter.
2075
+
2076
+ - Selection is required: `--source <id>` (uses the registered collection and
2077
+ project mappings) or explicit absolute paths plus `--collection`.
2078
+ `--collection` with `--source` is rejected.
2079
+ - `--format` overrides structural detection for path imports.
2080
+ - `--dry-run` parses and reports without writing archive files, checkpoint
2081
+ state or index rows.
2082
+ - `--limit <n>` bounds the number of changed units processed; unchanged units
2083
+ do not count; the rest are reported as `deferredUnits`.
2084
+ - Reruns are idempotent: a unit whose fingerprint, parser, redaction and
2085
+ archive format are unchanged is skipped; a changed unit is re-rendered and
2086
+ compared with the archived bytes. Turn IDs are stable across appends.
2087
+ - A unit whose final line is cut mid-write, or whose structure drifted (for
2088
+ example assistant turns without any recognised human turn), is
2089
+ `incomplete`: its readable threads are archived but its checkpoint does not
2090
+ advance, and the next run retries it.
2091
+ - A thread whose recorded working directories map to different collections
2092
+ is quarantined (`skipped_policy`, reason `mixed_domain`) instead of being
2093
+ written to the less restricted one.
2094
+ - A unit is identified by source ID plus its safe locator, so moving a file
2095
+ within the source root or re-registering the source at a new path keeps
2096
+ its archive files; two units with the same locator fail the second one
2097
+ (`unit_conflict`). Archive files are namespaced per unit, so two units
2098
+ reporting the same thread ID never overwrite each other.
2099
+ - A unit is re-imported when its routing settings (collection or project
2100
+ mappings) change, so a quarantined thread is imported once it is mapped.
2101
+ - Units are recorded complete only after the lexical sync of the changed
2102
+ archive files succeeds; a failed or interrupted sync is retried by the next
2103
+ run. Units with malformed records stay `incomplete` (`malformed_records`).
2104
+ - A thread withheld by policy (`mixed_domain`, `over_limit`; a thread at the
2105
+ turn limit is skipped whole) has any earlier archive copy moved to
2106
+ `<archive>/.gno-sessions/withheld/` and removed from the index.
2107
+ - A registered source whose root is missing or cannot be listed still gets
2108
+ archive-only maintenance (redaction rescans), then the import fails with
2109
+ `SESSIONS_SOURCE_UNAVAILABLE` (exit 2). A directory or unit file inside a
2110
+ source that cannot be read is a `failed` unit (`permission_denied`,
2111
+ `source_missing` or `read_failed`; directories use the locator `.`), so the
2112
+ receipt is never `nothing_to_do`, and its checkpoint does not advance.
2113
+ - Imports on one archive serialize on `<archive>/.gno-sessions/import.lock`;
2114
+ a concurrent run exits `BUSY` (`SESSIONS_BUSY`).
2115
+ - A source file that disappears keeps its archive; `status` reports it as
2116
+ `sourceUnavailable`. When the redaction rules or the configured literals
2117
+ (`sessions.redaction.literals`) change, units with a source are re-rendered
2118
+ and archives without a source are rescanned in place; a parser change
2119
+ cannot reparse a missing source and is reported instead.
2120
+ - Output: `sessions-import-receipt` schema. `status` is `complete`,
2121
+ `partial` (any incomplete, failed, unsupported or deferred unit, or failed
2122
+ lexical sync), `failed` (nothing archived or unchanged and nothing
2123
+ incomplete, for example every selected unit unsupported or failed) or
2124
+ `nothing_to_do`. Units skipped as already current count their archived
2125
+ threads as `unchanged`; an unsupported unit selected as a file is reported
2126
+ by its (redacted) file name.
2127
+ Receipts carry counts, per-unit outcomes with safe locators (never host
2128
+ paths), lexical readiness and the embedding backlog. Embeddings are not
2129
+ generated by import; run `gno embed` on the archive pair.
2130
+
2131
+ **status**: archive collections with thread counts, and per source its
2132
+ availability (`false` when the root is missing or cannot be read), unit counts (complete, incomplete, failed, pending),
2133
+ `sourceUnavailable`, `staleParser` and last import time, plus the
2134
+ `automation` block (daemon state, per-profile state, triggers, pending and
2135
+ running work, last run, last success, next due time only with a live
2136
+ daemon, recovery action). Output: `sessions-status` schema.
2137
+
2138
+ **automation** (opt-in; nothing is enabled by install, upgrade, repair or
2139
+ restart):
2140
+
2141
+ - `set` creates or reconfigures a profile in `sessions.automation` of the
2142
+ archive config: registered `--source` IDs (1-64), optional `--cadence`
2143
+ (`<n>s|m|h|d`, 1m..30d), `--limit` (changed units per source per run,
2144
+ default 200) and `--retries` (0-10, default 3). Triggers keep their state;
2145
+ a new profile has none. Unknown sources exit `VALIDATION`
2146
+ (`SESSIONS_UNKNOWN_SOURCE`). Output: the preview object.
2147
+ - `preview` prints sources with host paths, destination collections, the
2148
+ hook command and target settings file (`--settings`, else
2149
+ `$CLAUDE_CONFIG_DIR/settings.json` or `~/.claude/settings.json`), the
2150
+ schedule, the budget, and the daemon prerequisite. Local only.
2151
+ - `enable --hook claude-code` installs exactly one owned SessionEnd entry
2152
+ (identified by its command for this config and profile; other entries are
2153
+ preserved; a `.bak` copy is kept; invalid JSON is left untouched and exits
2154
+ `VALIDATION`) and then sets `hook.enabled`. Other harnesses exit
2155
+ `VALIDATION` with `SESSIONS_UNSUPPORTED_INTEGRATION`. `enable --schedule`
2156
+ requires a cadence (flag or profile); the first run is due one cadence
2157
+ later. Enabling never installs or starts a service.
2158
+ - `disable` switches the selected triggers off (both when none is named),
2159
+ removes the owned hook entry, and clears pending work admitted by those
2160
+ triggers; a run in progress finishes. `remove` uninstalls the owned entry
2161
+ (failing closed when the settings file cannot be read) and deletes the
2162
+ profile and its run state. Archives are never deleted.
2163
+ - `run` admits a manual trigger and runs the profile through the importer
2164
+ (`sessions import --source` per source, bounded by `limit`). Output:
2165
+ `sessions-automation-run` schema; exit `BUSY` (4, `SESSIONS_BUSY`) when the
2166
+ run failed with reason `busy` (another import, lease holder or a locked
2167
+ index; the busy run is recorded), exit `RUNTIME` (2) when the outcome is
2168
+ `failed`.
2169
+
2170
+ **hook**: `sessions hook claude-code --profile <id>` is the command an
2171
+ installed hook runs. It reads the event JSON on stdin (at most 64 KiB), skips
2172
+ anything other than `SessionEnd`, rechecks under the marker lock that the
2173
+ profile's hook is enabled, and durably records one pending generation. It
2174
+ never imports, parses sessions or uses the network, and waits at most 1 s for
2175
+ the lock. Output is one content-free line: `accepted (…pending, not yet
2176
+ archived…)`, `skipped (…)` (exit 0), or `not accepted (…)` (exit 2).
2177
+ `GNO_SESSIONS_HOOKS=off` or `0` skips immediately. An unknown profile is
2178
+ reported as `skipped (… unknown_profile)`, a profile whose hook is off as
2179
+ `skipped (… hook_disabled)`. An explicit `--settings` other than the default
2180
+ location must name an existing file (`VALIDATION`).
2181
+
2182
+ **prune**: lists archived units whose source is gone (preview by default);
2183
+ `--apply` deletes exactly those archive files and syncs the index, never a
2184
+ file a still-present unit references. It requires a complete listing of the
2185
+ source and fails with `SESSIONS_SOURCE_UNAVAILABLE` when part of it cannot be
2186
+ read or the listing was truncated. It plans under the archive lock; when
2187
+ the index sync fails it records nothing, returns `applied: false` with an
2188
+ `error`, and the next prune retries. Source deletion alone never removes
2189
+ archive files.
2190
+
2191
+ **Exit codes:** `VALIDATION` (1) for selection, destination, binding,
2192
+ unknown source/collection, unsafe path and unsupported format errors;
2193
+ `BUSY` (4) for `SESSIONS_BUSY`; `RUNTIME` (2) for an import or automation
2194
+ run whose status is `failed` and for a hook that was not accepted, except `VALIDATION` (1, `SESSIONS_UNSUPPORTED_FORMAT`) when no
2195
+ selected unit is a supported format. The JSON error envelope carries the core code in
2196
+ `details.sessionsCode`.
2197
+
2198
+ **Examples:**
2199
+
2200
+ ```bash
2201
+ gno sessions
2202
+ gno --config ~/gno-sessions/archive.yml --index sessions sessions init --archive ~/gno-sessions/archive --collection sessions-work
2203
+ gno --config ~/gno-sessions/archive.yml --index sessions sessions source add codex --harness codex --path ~/.codex/sessions --collection sessions-work
2204
+ gno --config ~/gno-sessions/archive.yml --index sessions sessions import --source codex --dry-run
2205
+ gno --config ~/gno-sessions/archive.yml --index sessions sessions import --source codex --json
2206
+ gno --config ~/gno-sessions/archive.yml --index sessions query "why did we pick sqlite" --category harness/codex --author human
2207
+ ```
2208
+
2209
+ ---
2210
+
1826
2211
  ### gno get
1827
2212
 
1828
2213
  Retrieve a single document by reference.
@@ -2387,6 +2772,31 @@ content, asset descriptors, source references, nor raster bytes.
2387
2772
 
2388
2773
  ---
2389
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
+
2390
2800
  ### gno cleanup
2391
2801
 
2392
2802
  Remove orphaned content, chunks, and vectors not referenced by active documents.
@@ -4118,32 +4528,36 @@ Errors are written to stderr. With `--json` flag, errors are also returned as:
4118
4528
  }
4119
4529
  ```
4120
4530
 
4121
- 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.
4533
+ Request ID errors keep their stable request code in `details.requestCode`
4534
+ (see [gno request-status](#gno-request-status)).
4122
4535
 
4123
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.
4124
4537
 
4125
- **`NOT_RUNNING` is not an error envelope.**
4126
-
4127
- **`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.
4128
4539
 
4129
4540
  ---
4130
4541
 
4131
4542
  ## Environment Variables
4132
4543
 
4133
- | Variable | Description |
4134
- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
4135
- | `GNO_CONFIG_DIR` | Override config directory |
4136
- | `GNO_DATA_DIR` | Override data directory (DB location) |
4137
- | `GNO_CACHE_DIR` | Override cache directory (models) |
4138
- | `NO_COLOR` | Disable colored output (standard) |
4139
- | `PAGER` | Pager for long output (default: less -R on Unix, built-in on Windows) |
4140
- | `GNO_SKILLS_HOME_OVERRIDE` | Override home dir for skill user scope (testing) |
4141
- | `GNO_MEMORY_CALLER` | Default `--caller` identity for `gno remember` / `gno recall` |
4142
- | `GNO_MEMORY_SESSION` | Default `--session` identity for `gno remember` / `gno recall` |
4143
- | `CLAUDE_SKILLS_DIR` | Override Claude skills directory |
4144
- | `CODEX_SKILLS_DIR` | Override Codex skills directory |
4145
- | `CLAUDE_CONFIG_DIR` | Claude Code config dir; `gno agents` resolves Claude's instruction file under it (suppressed by an explicit home override) |
4146
- | `CODEX_HOME` | Codex config dir; same rule as `CLAUDE_CONFIG_DIR` |
4544
+ | Variable | Description |
4545
+ | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
4546
+ | `GNO_CONFIG_DIR` | Override config directory |
4547
+ | `GNO_DATA_DIR` | Override data directory (DB location) |
4548
+ | `GNO_CACHE_DIR` | Override cache directory (models) |
4549
+ | `NO_COLOR` | Disable colored output (standard) |
4550
+ | `PAGER` | Pager for long output (default: less -R on Unix, built-in on Windows) |
4551
+ | `GNO_SKILLS_HOME_OVERRIDE` | Override home dir for skill user scope (testing) |
4552
+ | `GNO_MEMORY_CALLER` | Default `--caller` identity for `gno remember` / `gno recall` |
4553
+ | `GNO_MEMORY_SESSION` | Default `--session` identity for `gno remember` / `gno recall` |
4554
+ | `CLAUDE_SKILLS_DIR` | Override Claude skills directory |
4555
+ | `CODEX_SKILLS_DIR` | Override Codex skills directory |
4556
+ | `CLAUDE_CONFIG_DIR` | Claude Code config dir; `gno agents` resolves Claude's instruction file under it (suppressed by an explicit home override); `gno sessions discover` also checks its `projects/` |
4557
+ | `CODEX_HOME` | Codex config dir; same rule as `CLAUDE_CONFIG_DIR`; `gno sessions discover` checks its `sessions/` |
4558
+ | `OPENCLAW_STATE_DIR` | OpenClaw state dir checked by `gno sessions discover` (else `$OPENCLAW_HOME/.openclaw` or `~/.openclaw`) |
4559
+ | `HERMES_HOME` | Hermes home checked by `gno sessions discover` (else `~/.hermes`) |
4560
+ | `GNO_SESSIONS_HOOKS` | `off` or `0` makes every installed `gno sessions hook` return immediately without admitting work |
4147
4561
 
4148
4562
  ---
4149
4563