@gmickel/gno 1.21.0 → 1.22.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 CHANGED
@@ -94,7 +94,7 @@ gno daemon --detach # headless continuous indexing (background; --status / --st
94
94
 
95
95
  <!-- public-truth:current-version -->
96
96
 
97
- > Current release: **v1.21.0** — see [CHANGELOG.md](./CHANGELOG.md)
97
+ > Current release: **v1.22.0** — see [CHANGELOG.md](./CHANGELOG.md)
98
98
 
99
99
  <!-- /public-truth -->
100
100
 
@@ -710,7 +710,7 @@ GNO is local-first, but sometimes you want a URL to send someone. [**gno.sh**](h
710
710
 
711
711
  ![gno.sh publish reader](./assets/screenshots/publish-reader.jpg)
712
712
 
713
- The workflow is deliberately explicit: **export locally → upload artifact → share URL**. Your private notes and metadata stay on your machine. Only what you export leaves.
713
+ The workflow is deliberately explicit: **export locally → upload artifact → share URL**. Private and `publish: false` notes stay on your machine. Exported artifacts omit local collection paths and source URIs.
714
714
 
715
715
  ```bash
716
716
  # Export a single note
@@ -745,6 +745,15 @@ Upload the artifact at [gno.sh/studio](https://gno.sh/studio) and pick a visibil
745
745
 
746
746
  **Reader experience**: editorial serif typography, drop caps, hanging punctuation, table of contents, keyboard shortcuts (`j/k`, `/`), scoped Pagefind-style search, and backlinks restricted to the published subset. Nothing leaks that you didn't publish.
747
747
 
748
+ Public exports also carry a deterministic agent manifest. It lists only the
749
+ sanitized published Markdown projection, with relative Markdown locators,
750
+ content hashes, exact line spans, and Capsule-compatible evidence identities.
751
+ The projection revision is stable while those published bytes and reader
752
+ metadata are unchanged. Secret-link and invite-only exports do not receive
753
+ agent capabilities or manifests. Encrypted exports remain ciphertext-only.
754
+ Reader metadata drops embedded local path or GNO/file URI tokens; canonical
755
+ and image fields accept only uncredentialed public HTTP(S) targets.
756
+
748
757
  Republishing a public, secret-link, or invite-only artifact updates the same URL. Encrypted shares should be replaced from a fresh local export so the server never needs your plaintext.
749
758
 
750
759
  Encrypted source-backed publish on `gno.sh` is intentionally disabled. For encrypted shares, use:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gmickel/gno",
3
- "version": "1.21.0",
3
+ "version": "1.22.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",
@@ -83,6 +83,7 @@
83
83
  "eval:retrieval-candidates": "bun scripts/retrieval-candidate-benchmark.ts",
84
84
  "eval:retrieval-candidates:write": "bun scripts/retrieval-candidate-benchmark.ts --write",
85
85
  "eval:agentic": "bun evals/agentic/cli.ts",
86
+ "eval:agentic:demo": "bun evals/agentic/demos/generate-context-capsule.ts",
86
87
  "eval:watch": "bun --bun evalite watch",
87
88
  "research:finetune:bootstrap": "bun research/finetune/scripts/bootstrap-promotion-fixtures.ts",
88
89
  "research:finetune:autonomous:noop": "bun research/finetune/autonomous/scripts/noop-run.ts",
package/spec/cli.md CHANGED
@@ -95,6 +95,7 @@ equivalent files fail closed as ambiguous.
95
95
  | models pull | no | no | no | no | no | terminal |
96
96
  | models clear | no | no | no | no | no | terminal |
97
97
  | models path | yes | no | no | no | no | terminal |
98
+ | publish export | yes | no | no | no | no | terminal |
98
99
  | cleanup | no | no | no | no | no | terminal |
99
100
  | doctor | yes | no | no | yes | no | terminal |
100
101
  | mcp | no | no | no | no | no | stdio |
@@ -1558,6 +1559,49 @@ gno models path [--json]
1558
1559
 
1559
1560
  ---
1560
1561
 
1562
+ ### gno publish export
1563
+
1564
+ Build a reader-safe gno.sh artifact from one active collection or document.
1565
+
1566
+ **Synopsis:**
1567
+
1568
+ ```bash
1569
+ gno publish export <target> \
1570
+ [--out <path>] \
1571
+ [--visibility public|secret-link|invite-only|encrypted] \
1572
+ [--passphrase <value>] \
1573
+ [--slug <slug>] \
1574
+ [--title <title>] \
1575
+ [--summary <summary>] \
1576
+ [--preview] \
1577
+ [--json]
1578
+ ```
1579
+
1580
+ Public V1 spaces MUST carry a `manifest` conforming to
1581
+ [`publish-artifact.schema.json`](./output-schemas/publish-artifact.schema.json).
1582
+ The manifest contains schema version `1.0`, a deterministic projection
1583
+ revision, generated time, closed public capabilities, sorted published
1584
+ documents, relative Markdown locators, SHA-256 content hashes, and
1585
+ Capsule-compatible evidence identities. Manifest hashes and revisions MUST be
1586
+ derived only from sanitized notes and metadata present in the published
1587
+ projection. Local collection paths, document source URIs, unpublished
1588
+ documents, and filtered metadata MUST NOT enter artifact bytes or revision
1589
+ inputs. Reader metadata values containing embedded local path or GNO/file URI
1590
+ tokens MUST be filtered. Canonical and image metadata MUST contain
1591
+ uncredentialed public HTTP(S) targets; local hostnames and literal loopback,
1592
+ private, or link-local addresses MUST be filtered.
1593
+
1594
+ Secret-link and invite-only V1 spaces MUST NOT contain a manifest or agent
1595
+ capability field. Encrypted V2 spaces MUST contain only ciphertext parameters,
1596
+ the opaque secret token, route slug, source type, and encrypted visibility; no
1597
+ plaintext manifest or evidence may appear outside the ciphertext. V2 builders
1598
+ MUST emit a closed projection, validate payload strings as non-empty bounded
1599
+ base64, require a positive safe-integer KDF iteration count, and bound the
1600
+ non-blank opaque token. Caller-supplied extension fields MUST NOT enter the
1601
+ artifact.
1602
+
1603
+ ---
1604
+
1561
1605
  ### gno cleanup
1562
1606
 
1563
1607
  Remove orphaned content, chunks, and vectors not referenced by active documents.
@@ -24,6 +24,7 @@ evals/agentic/
24
24
  promotion.ts
25
25
  verified-ask-outcome.ts
26
26
  verified-ask-promotion.ts
27
+ demos/context-capsule.ts
27
28
  registry.ts
28
29
  report.ts
29
30
  report-artifacts.ts
@@ -44,6 +45,7 @@ evals/agentic/
44
45
  final-envelope.schema.json
45
46
  trajectory-receipt.schema.json
46
47
  benchmark-report.schema.json
48
+ context-capsule-demo.schema.json
47
49
 
48
50
  evals/fixtures/agentic-retrieval/
49
51
  manifest.json
@@ -61,6 +63,9 @@ evals/fixtures/agentic-retrieval/
61
63
  verified-ask-promotion.json
62
64
  verified-ask-promotion.md
63
65
  optional/{qmd,local-model}/ # local opt-in evidence; not authoritative
66
+ demos/
67
+ context-capsule.json
68
+ context-capsule.md
64
69
  ```
65
70
 
66
71
  The first fixture version contains 24 original synthetic tasks and 34 Markdown
@@ -412,6 +417,48 @@ summary. The six files are staged and directory-renamed as one baseline set.
412
417
  The verified Ask files are a separate attributable outcome lane; they do not
413
418
  rename the Capsule retrieval promotion in `report.json`.
414
419
 
420
+ ## Reproducible Context Capsule demo
421
+
422
+ `demos/context-capsule.json` is a closed, canonically fingerprinted projection
423
+ of one frozen exact-identifier task from the authoritative fixture-agent
424
+ report. It contains exactly three lanes in fixed order: the lexical-only
425
+ no-GNO baseline, shipped GNO MCP query/get primitives, and the Context Capsule.
426
+ Every lane retains its complete normalized trajectory receipt, score, exact
427
+ evidence coordinates and hashes, final stop outcome, agent/backend call counts,
428
+ model-visible UTF-8 bytes, token availability, and matching-lifecycle latency.
429
+
430
+ All three lanes must share the task, outer agent, trial, seed, lifecycle,
431
+ corpus, prompt, tool, model, runtime, and canonical effective-index
432
+ fingerprints. The generator selects exactly one receipt and score per full
433
+ identity and rejects ambiguous multi-trial input. Adapter configuration
434
+ fingerprints may differ. The Capsule projection additionally retains its
435
+ normalized `retrieval.request`, effective index fingerprint, capability states,
436
+ fallback list, and complete model-visible payload. Validation parses the
437
+ delivered evidence bundle and compares those values, then recomputes every
438
+ displayed lane metric from the embedded receipt and score.
439
+
440
+ Source provenance distinguishes each source run's clean `runGitCommit` from
441
+ the later Git commit that contains the generated demo artifact. The artifact
442
+ does not attempt to embed its own containing commit. Its report and Verified
443
+ Ask fingerprints and projected fields must match the canonical linked source
444
+ artifacts.
445
+
446
+ The readable `context-capsule.md` is generated from the JSON contract. It
447
+ states the single-trial variance limitation, reports tokens as unavailable
448
+ without one pinned comparable tokenizer, and limits its claim to the measured
449
+ controlled task. It discloses that the chosen task is the sole cold
450
+ current-GNO-failure / Capsule-success case in the 24-task authoritative cohort,
451
+ that the Capsule lane is an evaluation-only lexical prototype, and that its
452
+ latency is not shipped-product latency. It cannot be used as a general
453
+ product-superiority claim.
454
+
455
+ The adjacent Verified Ask block is an attributable but separate
456
+ `answer_enforcement` proof. It binds the clean-Git canonical fingerprint of the
457
+ frozen 22-pair `raw_ask`/`verified_ask` artifact, retains the two declared
458
+ missing-evidence exclusions, and exposes only answer-accuracy and unsupported-
459
+ substantive-claim metrics. Those metrics are never merged into or labeled as
460
+ retrieval metrics.
461
+
415
462
  ## Deterministic scoring
416
463
 
417
464
  The scorer compares typed claims and exact citations with the hidden oracle. It
@@ -551,6 +598,7 @@ Contract tests are ordinary offline tests:
551
598
 
552
599
  ```bash
553
600
  bun test test/eval/agentic
601
+ bun run eval:agentic:demo
554
602
  ```
555
603
 
556
604
  The runner is local and opt-in:
@@ -0,0 +1,284 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "gno://schemas/publish-artifact@1.0",
4
+ "title": "GNO publish artifact",
5
+ "oneOf": [
6
+ { "$ref": "#/definitions/artifactV1" },
7
+ { "$ref": "#/definitions/artifactV2" }
8
+ ],
9
+ "definitions": {
10
+ "artifactV1": {
11
+ "type": "object",
12
+ "additionalProperties": false,
13
+ "required": ["version", "source", "exportedAt", "spaces"],
14
+ "properties": {
15
+ "version": { "const": 1 },
16
+ "source": { "$ref": "#/definitions/slug" },
17
+ "exportedAt": { "type": "string", "format": "date-time" },
18
+ "spaces": {
19
+ "type": "array",
20
+ "minItems": 1,
21
+ "items": {
22
+ "oneOf": [
23
+ { "$ref": "#/definitions/publicSpace" },
24
+ { "$ref": "#/definitions/restrictedSpace" }
25
+ ]
26
+ }
27
+ }
28
+ }
29
+ },
30
+ "artifactV2": {
31
+ "type": "object",
32
+ "additionalProperties": false,
33
+ "required": ["version", "source", "exportedAt", "spaces"],
34
+ "properties": {
35
+ "version": { "const": 2 },
36
+ "source": { "$ref": "#/definitions/slug" },
37
+ "exportedAt": { "type": "string", "format": "date-time" },
38
+ "spaces": {
39
+ "type": "array",
40
+ "minItems": 1,
41
+ "items": { "$ref": "#/definitions/encryptedSpace" }
42
+ }
43
+ }
44
+ },
45
+ "slug": {
46
+ "type": "string",
47
+ "pattern": "^[a-z0-9](?:[a-z0-9-]{0,78}[a-z0-9])?$",
48
+ "maxLength": 80
49
+ },
50
+ "hash": {
51
+ "type": "string",
52
+ "pattern": "^[a-f0-9]{64}$"
53
+ },
54
+ "docid": {
55
+ "type": "string",
56
+ "pattern": "^#[a-f0-9]{8}$"
57
+ },
58
+ "metadata": {
59
+ "type": "object",
60
+ "additionalProperties": {
61
+ "oneOf": [
62
+ { "type": "string" },
63
+ {
64
+ "type": "array",
65
+ "items": { "type": "string" }
66
+ }
67
+ ]
68
+ }
69
+ },
70
+ "note": {
71
+ "type": "object",
72
+ "additionalProperties": false,
73
+ "required": ["markdown", "slug", "summary", "title"],
74
+ "properties": {
75
+ "markdown": { "type": "string" },
76
+ "metadata": { "$ref": "#/definitions/metadata" },
77
+ "slug": { "$ref": "#/definitions/slug" },
78
+ "summary": { "type": "string" },
79
+ "title": { "type": "string", "minLength": 1 }
80
+ }
81
+ },
82
+ "publicSpace": {
83
+ "type": "object",
84
+ "additionalProperties": false,
85
+ "required": [
86
+ "notes",
87
+ "routeSlug",
88
+ "sourceType",
89
+ "summary",
90
+ "title",
91
+ "visibility",
92
+ "manifest"
93
+ ],
94
+ "properties": {
95
+ "homeNoteSlug": { "$ref": "#/definitions/slug" },
96
+ "notes": {
97
+ "type": "array",
98
+ "minItems": 1,
99
+ "items": { "$ref": "#/definitions/note" }
100
+ },
101
+ "routeSlug": { "$ref": "#/definitions/slug" },
102
+ "sourceType": { "enum": ["note", "collection"] },
103
+ "summary": { "type": "string" },
104
+ "title": { "type": "string", "minLength": 1 },
105
+ "visibility": { "const": "public" },
106
+ "manifest": { "$ref": "#/definitions/publicManifest" }
107
+ }
108
+ },
109
+ "restrictedSpace": {
110
+ "type": "object",
111
+ "additionalProperties": false,
112
+ "required": [
113
+ "notes",
114
+ "routeSlug",
115
+ "sourceType",
116
+ "summary",
117
+ "title",
118
+ "visibility"
119
+ ],
120
+ "properties": {
121
+ "homeNoteSlug": { "$ref": "#/definitions/slug" },
122
+ "notes": {
123
+ "type": "array",
124
+ "minItems": 1,
125
+ "items": { "$ref": "#/definitions/note" }
126
+ },
127
+ "routeSlug": { "$ref": "#/definitions/slug" },
128
+ "sourceType": { "enum": ["note", "collection"] },
129
+ "summary": { "type": "string" },
130
+ "title": { "type": "string", "minLength": 1 },
131
+ "visibility": { "enum": ["secret-link", "invite-only"] }
132
+ }
133
+ },
134
+ "publicManifest": {
135
+ "type": "object",
136
+ "additionalProperties": false,
137
+ "required": [
138
+ "schemaVersion",
139
+ "projectionRevision",
140
+ "generatedAt",
141
+ "visibility",
142
+ "capabilities",
143
+ "documents"
144
+ ],
145
+ "properties": {
146
+ "schemaVersion": { "const": "1.0" },
147
+ "projectionRevision": { "$ref": "#/definitions/hash" },
148
+ "generatedAt": { "type": "string", "format": "date-time" },
149
+ "visibility": { "const": "public" },
150
+ "capabilities": {
151
+ "type": "object",
152
+ "additionalProperties": false,
153
+ "required": [
154
+ "capsuleEvidence",
155
+ "exactLineCitations",
156
+ "llmsTxt",
157
+ "markdownDocuments"
158
+ ],
159
+ "properties": {
160
+ "capsuleEvidence": { "const": true },
161
+ "exactLineCitations": { "const": true },
162
+ "llmsTxt": { "const": true },
163
+ "markdownDocuments": { "const": true }
164
+ }
165
+ },
166
+ "documents": {
167
+ "type": "array",
168
+ "minItems": 1,
169
+ "items": { "$ref": "#/definitions/publicDocument" }
170
+ }
171
+ }
172
+ },
173
+ "publicDocument": {
174
+ "type": "object",
175
+ "additionalProperties": false,
176
+ "required": [
177
+ "slug",
178
+ "title",
179
+ "summary",
180
+ "markdownPath",
181
+ "contentHash",
182
+ "byteLength",
183
+ "lineCount",
184
+ "evidence"
185
+ ],
186
+ "properties": {
187
+ "slug": { "$ref": "#/definitions/slug" },
188
+ "title": { "type": "string", "minLength": 1 },
189
+ "summary": { "type": "string" },
190
+ "markdownPath": {
191
+ "type": "string",
192
+ "pattern": "^\\./[a-z0-9](?:[a-z0-9-]{0,78}[a-z0-9])?\\.md$"
193
+ },
194
+ "contentHash": { "$ref": "#/definitions/hash" },
195
+ "byteLength": { "type": "integer", "minimum": 0 },
196
+ "lineCount": { "type": "integer", "minimum": 1 },
197
+ "evidence": { "$ref": "#/definitions/publicEvidence" }
198
+ }
199
+ },
200
+ "publicEvidence": {
201
+ "type": "object",
202
+ "additionalProperties": false,
203
+ "required": [
204
+ "evidenceId",
205
+ "uri",
206
+ "docid",
207
+ "startLine",
208
+ "endLine",
209
+ "sourceHash",
210
+ "mirrorHash",
211
+ "passageHash",
212
+ "locator"
213
+ ],
214
+ "properties": {
215
+ "evidenceId": { "$ref": "#/definitions/hash" },
216
+ "uri": {
217
+ "type": "string",
218
+ "pattern": "^gno://public/[a-z0-9][a-z0-9-]{0,79}/[a-z0-9][a-z0-9-]{0,79}\\.md$"
219
+ },
220
+ "docid": { "$ref": "#/definitions/docid" },
221
+ "startLine": { "const": 1 },
222
+ "endLine": { "type": "integer", "minimum": 1 },
223
+ "sourceHash": { "$ref": "#/definitions/hash" },
224
+ "mirrorHash": { "$ref": "#/definitions/hash" },
225
+ "passageHash": { "$ref": "#/definitions/hash" },
226
+ "locator": {
227
+ "type": "string",
228
+ "pattern": "^\\./[a-z0-9][a-z0-9-]{0,79}\\.md#L1-L[1-9][0-9]*$"
229
+ }
230
+ }
231
+ },
232
+ "encryptedSpace": {
233
+ "type": "object",
234
+ "additionalProperties": false,
235
+ "required": [
236
+ "encryptedPayload",
237
+ "routeSlug",
238
+ "secretToken",
239
+ "sourceType",
240
+ "visibility"
241
+ ],
242
+ "properties": {
243
+ "encryptedPayload": {
244
+ "type": "object",
245
+ "additionalProperties": false,
246
+ "required": ["ciphertext", "iterations", "iv", "salt"],
247
+ "properties": {
248
+ "ciphertext": {
249
+ "type": "string",
250
+ "minLength": 1,
251
+ "maxLength": 67108864,
252
+ "pattern": "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$"
253
+ },
254
+ "iterations": {
255
+ "type": "integer",
256
+ "minimum": 1,
257
+ "maximum": 9007199254740991
258
+ },
259
+ "iv": {
260
+ "type": "string",
261
+ "minLength": 1,
262
+ "maxLength": 1024,
263
+ "pattern": "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$"
264
+ },
265
+ "salt": {
266
+ "type": "string",
267
+ "minLength": 1,
268
+ "maxLength": 1024,
269
+ "pattern": "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$"
270
+ }
271
+ }
272
+ },
273
+ "routeSlug": { "$ref": "#/definitions/slug" },
274
+ "secretToken": {
275
+ "type": "string",
276
+ "minLength": 1,
277
+ "maxLength": 512
278
+ },
279
+ "sourceType": { "enum": ["note", "collection"] },
280
+ "visibility": { "const": "encrypted" }
281
+ }
282
+ }
283
+ }
284
+ }