@gmickel/gno 2.3.3 → 2.4.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 (88) hide show
  1. package/README.md +13 -2
  2. package/assets/skill/SKILL.md +30 -0
  3. package/assets/skill/cli-reference.md +12 -0
  4. package/assets/skill/examples.md +15 -0
  5. package/assets/skill/mcp-reference.md +16 -0
  6. package/assets/spa-production.json.gz +0 -0
  7. package/browser-extension/artifacts/{gno-browser-clipper-v2.3.3.zip → gno-browser-clipper-v2.4.0.zip} +0 -0
  8. package/browser-extension/artifacts/gno-browser-clipper-v2.4.0.zip.sha256 +1 -0
  9. package/browser-extension/dist/manifest.json +1 -1
  10. package/package.json +1 -1
  11. package/spec/cli.md +30 -0
  12. package/spec/db/schema.sql +2 -0
  13. package/spec/evals.md +48 -0
  14. package/spec/mcp.md +12 -0
  15. package/spec/output-schemas/ask.schema.json +12 -0
  16. package/spec/output-schemas/context-capsule-v1.schema.json +205 -32
  17. package/spec/output-schemas/context-capsule-verification.schema.json +32 -9
  18. package/spec/output-schemas/evidence-fixtures.schema.json +176 -0
  19. package/spec/output-schemas/evidence-report.schema.json +322 -0
  20. package/spec/output-schemas/evidence-run.schema.json +277 -0
  21. package/spec/output-schemas/metadata-predicate.schema.json +460 -0
  22. package/spec/output-schemas/retrieval-trace-filters.schema.json +13 -4
  23. package/spec/output-schemas/search-results.schema.json +12 -0
  24. package/spec/output-schemas/status.schema.json +37 -6
  25. package/src/app/context-runtime-contract.ts +33 -2
  26. package/src/app/context-runtime-input.ts +17 -0
  27. package/src/app/context-runtime-types.ts +2 -0
  28. package/src/app/context-runtime.ts +27 -3
  29. package/src/app/context-surface.ts +2 -0
  30. package/src/app/verified-ask.ts +1 -0
  31. package/src/cli/commands/ask.ts +1 -0
  32. package/src/cli/commands/context-build.ts +1 -0
  33. package/src/cli/commands/search.ts +1 -0
  34. package/src/cli/commands/status.ts +10 -0
  35. package/src/cli/options.ts +19 -0
  36. package/src/cli/program.ts +12 -0
  37. package/src/converters/types.ts +2 -0
  38. package/src/core/context-capsule-retrieval-schema.ts +8 -0
  39. package/src/core/context-capsule-schema.ts +47 -3
  40. package/src/core/context-capsule-validation.ts +14 -2
  41. package/src/core/context-capsule-verification.ts +1 -0
  42. package/src/core/context-capsule.ts +16 -2
  43. package/src/core/context-compiler.ts +3 -0
  44. package/src/core/record-metadata.ts +1 -1
  45. package/src/core/retrieval-replay-candidate.ts +5 -0
  46. package/src/core/retrieval-trace-filter-normalization.ts +4 -0
  47. package/src/core/retrieval-trace-request.ts +1 -0
  48. package/src/core/retrieval-trace-session.ts +5 -1
  49. package/src/core/retrieval-trace.ts +2 -0
  50. package/src/core/typed-metadata.ts +224 -0
  51. package/src/ingestion/record-adapter-canonical.ts +13 -2
  52. package/src/ingestion/record-container.ts +9 -0
  53. package/src/ingestion/sync.ts +11 -1
  54. package/src/ingestion/typed-metadata.ts +55 -0
  55. package/src/mcp/tools/ask.ts +10 -2
  56. package/src/mcp/tools/context.ts +1 -0
  57. package/src/mcp/tools/index.ts +12 -1
  58. package/src/mcp/tools/query.ts +13 -0
  59. package/src/mcp/tools/search.ts +9 -0
  60. package/src/mcp/tools/status.ts +4 -0
  61. package/src/mcp/tools/vsearch.ts +9 -0
  62. package/src/pipeline/diagnose.ts +6 -0
  63. package/src/pipeline/filters.ts +65 -0
  64. package/src/pipeline/graph-retrieval.ts +9 -1
  65. package/src/pipeline/hybrid.ts +22 -2
  66. package/src/pipeline/search.ts +11 -0
  67. package/src/pipeline/types.ts +7 -1
  68. package/src/pipeline/vsearch.ts +21 -1
  69. package/src/sdk/client.ts +29 -1
  70. package/src/sdk/index.ts +4 -0
  71. package/src/sdk/types.ts +7 -0
  72. package/src/serve/context-capsule.ts +1 -0
  73. package/src/serve/public/app.tsx +1 -1
  74. package/src/serve/public/components/MetadataFilter.tsx +186 -0
  75. package/src/serve/public/globals.built.css +1 -1
  76. package/src/serve/public/lib/metadata-filter.ts +28 -0
  77. package/src/serve/public/lib/retrieval-filters.ts +3 -0
  78. package/src/serve/public/pages/Ask.tsx +48 -3
  79. package/src/serve/public/pages/DocView.tsx +33 -0
  80. package/src/serve/public/pages/Search.tsx +44 -1
  81. package/src/serve/routes/api.ts +50 -0
  82. package/src/store/migrations/030-typed-metadata.ts +13 -0
  83. package/src/store/migrations/index.ts +2 -0
  84. package/src/store/sqlite/adapter.ts +55 -4
  85. package/src/store/sqlite/eligibility.ts +12 -0
  86. package/src/store/sqlite/metadata-predicate.ts +71 -0
  87. package/src/store/types.ts +11 -0
  88. package/browser-extension/artifacts/gno-browser-clipper-v2.3.3.zip.sha256 +0 -1
package/README.md CHANGED
@@ -20,6 +20,10 @@ gno agents install --target claude # teach retrieval and writing discipline
20
20
  gno agents verify --target claude
21
21
  ```
22
22
 
23
+ Custom fields such as project, approval status, and numeric confidence can
24
+ constrain retrieval with [typed metadata filters](docs/TYPED-METADATA.md),
25
+ across CLI, MCP, SDK, REST, and the Web UI.
26
+
23
27
  ## What you get
24
28
 
25
29
  **One local index across everything you have.** Markdown, PDFs, Office documents, plain text, source code, and portable mail, calendar and transcript exports. Point it at a folder that mixes all of them and it handles the mix.
@@ -126,7 +130,7 @@ gno daemon --detach # headless indexing + resident MCP gateway
126
130
 
127
131
  <!-- public-truth:current-version -->
128
132
 
129
- > Current source version: **v2.3.3**. See [CHANGELOG.md](./CHANGELOG.md).
133
+ > Current source version: **v2.4.0**. See [CHANGELOG.md](./CHANGELOG.md).
130
134
 
131
135
  <!-- /public-truth -->
132
136
 
@@ -1186,7 +1190,7 @@ bun test
1186
1190
  bun run lint && bun run typecheck
1187
1191
  ```
1188
1192
 
1189
- > **Contributing**: [CONTRIBUTING.md](.github/CONTRIBUTING.md)
1193
+ > **Contributing**: See [checks and release policy](.github/CONTRIBUTING.md). Documentation-only and CI-only changes do not require a product version bump or release.
1190
1194
 
1191
1195
  ### Evals and Benchmark Deltas
1192
1196
 
@@ -1203,6 +1207,13 @@ bun run eval:hybrid:delta
1203
1207
  - Benchmark guide: [evals/README.md](./evals/README.md)
1204
1208
  - Latest baseline snapshot: [evals/fixtures/hybrid-baseline/latest.json](./evals/fixtures/hybrid-baseline/latest.json)
1205
1209
 
1210
+ Document-level benchmark hits do not prove that every answer-bearing passage
1211
+ survives retrieval and a context budget. The opt-in
1212
+ [adversarial evidence gate](./evals/README.md#adversarial-evidence-coverage-development-only)
1213
+ checks complete required source spans, multi-source coverage, and fixed-reader
1214
+ abstention with replay and explicit cached-model native runs. It preserves baseline
1215
+ misses and does not change ranking defaults.
1216
+
1206
1217
  ### Code Embedding Benchmark Harness
1207
1218
 
1208
1219
  GNO also has a dedicated harness for comparing alternate embedding models on code retrieval without touching product defaults:
@@ -647,3 +647,33 @@ MCP-equivalent write tool:
647
647
  | Complete CLI reference (all commands, options, flags) | [cli-reference.md](cli-reference.md) |
648
648
  | MCP server setup and tools | [mcp-reference.md](mcp-reference.md) |
649
649
  | Usage examples and patterns | [examples.md](examples.md) |
650
+
651
+ ## Custom metadata filters
652
+
653
+ Use fixed flags for existing collection/tag/date/author/category fields. Custom
654
+ fields must be indexed from nested YAML `gno.metadata`; arbitrary frontmatter
655
+ keys are not automatically custom fields. CLI retrieval accepts `--filter`
656
+ JSON; MCP/SDK/REST accept the same `filter` object:
657
+
658
+ ```json
659
+ {
660
+ "op": "and",
661
+ "predicates": [
662
+ { "op": "eq", "key": "project", "value": "atlas" },
663
+ { "op": "gte", "key": "confidence", "value": 0.8 }
664
+ ]
665
+ }
666
+ ```
667
+
668
+ Membership operators `in`, `nin`, and `all` use plural `values`, not `value`:
669
+ `{"op":"all","key":"reviewers","values":["ana","sam"]}`.
670
+ Other leaves use singular `value`. `not` uses `predicate`; `and/or` use `predicates`.
671
+
672
+ Strings are case-sensitive and never coerced to numbers or booleans. `eq/ne`
673
+ accept scalars, ordering accepts numbers, `in/nin` test scalar/array membership,
674
+ `all` requires an array, and `exists` takes a boolean. `ne/nin` require presence;
675
+ `not(eq)`/`not(in)` can include missing fields. Invalid metadata is excluded even
676
+ under negation. Never silently remove a requested filter. If coverage is
677
+ incomplete, inspect warnings and diagnose the expected target with the same
678
+ filter before relaxing it; correct source metadata and run `gno update` when
679
+ repair is authorized. Preserve collection, authority, and memory scope.
@@ -1062,3 +1062,15 @@ gno completion output <bash|zsh|fish>
1062
1062
  | 1 | Validation error (bad args) |
1063
1063
  | 2 | Runtime error (IO, DB, model) |
1064
1064
  | 3 | `NOT_RUNNING` — `--status` / `--stop` found no live matching process |
1065
+
1066
+ ## Custom metadata filters
1067
+
1068
+ ```bash
1069
+ gno search "rollout" --filter '{"op":"eq","key":"status","value":"approved"}'
1070
+ gno query diagnose "rollout" --target gno://docs/decision.md --filter '{"op":"gte","key":"confidence","value":0.8}'
1071
+ ```
1072
+
1073
+ The same `--filter` JSON works on `vsearch`, `query`, `ask`, and `context build`.
1074
+ Use only indexed `gno.metadata` fields. See SKILL.md for strict types,
1075
+ missing-field semantics, and diagnose-before-relaxing guidance. Repair metadata
1076
+ with `gno update` when authorized; no predicate expands existing scope.
@@ -467,3 +467,18 @@ Press **N** in `gno serve`, write the note, and open **Source** only when you
467
467
  need provenance fields such as URL, author, observed date, or external id. The
468
468
  success view reports the write result, FTS sync state, and embed state
469
469
  separately.
470
+
471
+ ## Custom metadata filters
472
+
473
+ Find Atlas decisions reviewed by both Ana and Sam:
474
+
475
+ ```bash
476
+ gno query "rollout decision" --filter '{"op":"and","predicates":[{"op":"eq","key":"project","value":"atlas"},{"op":"all","key":"reviewers","values":["ana","sam"]}]}'
477
+ ```
478
+
479
+ This requires indexed nested `gno.metadata` with `project: atlas` and a
480
+ `reviewers` string array. To include documents without a status, use
481
+ `{"op":"not","predicate":{"op":"eq","key":"status","value":"archived"}}`.
482
+ To require a present non-archived string status, use
483
+ `{"op":"ne","key":"status","value":"archived"}`. Invalid metadata matches
484
+ neither; check coverage and diagnose before relaxing the query.
@@ -201,3 +201,19 @@ transport session, never from tool arguments.
201
201
  gno mcp uninstall
202
202
  gno mcp uninstall -t claude-code
203
203
  ```
204
+
205
+ ## Custom metadata filters
206
+
207
+ `gno_search`, `gno_vsearch`, `gno_query`, `gno_ask`, and `gno_context` accept
208
+ `filter` alongside their existing scope fields:
209
+
210
+ ```json
211
+ {
212
+ "query": "rollout",
213
+ "filter": { "op": "gte", "key": "confidence", "value": 0.8 }
214
+ }
215
+ ```
216
+
217
+ Pass the object, not a JSON-encoded string. Preserve the filter on retries;
218
+ inspect coverage warnings rather than silently broadening retrieval. See
219
+ SKILL.md for strict types and missing-field semantics.
Binary file
@@ -0,0 +1 @@
1
+ ae739d8da342a7f932f8097e1d4d852ff7c46b722b8e979303b1213eaf2d76a5 gno-browser-clipper-v2.4.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.3.3"
24
+ "version": "2.4.0"
25
25
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gmickel/gno",
3
- "version": "2.3.3",
3
+ "version": "2.4.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
@@ -4171,3 +4171,33 @@ because reindexing is temporarily unavailable
4171
4171
  - [MCP Specification](./mcp.md)
4172
4172
  - [Output Schemas](./output-schemas/)
4173
4173
  - [PRD](../docs/prd.md)
4174
+
4175
+ ### Typed metadata predicates
4176
+
4177
+ Retrieval commands accept `--filter '<JSON>'`. The same `filter` object is
4178
+ accepted by SDK, MCP and REST retrieval inputs. Metadata comes from the nested
4179
+ YAML `gno.metadata` map; ordinary frontmatter keys remain unchanged.
4180
+
4181
+ The bounded recursive contract is:
4182
+
4183
+ - `{op:"and"|"or", predicates: Predicate[]}` (nonempty).
4184
+ - `{op:"not", predicate: Predicate}`.
4185
+ - `{op:"eq"|"ne", key:string, value:string|number|boolean}`.
4186
+ - `{op:"gt"|"gte"|"lt"|"lte", key:string, value:number}`.
4187
+ - `{op:"in"|"nin"|"all", key:string, values:Scalar[]}` (nonempty, homogeneous).
4188
+ - `{op:"exists", key:string, value:boolean}`.
4189
+
4190
+ Comparison is type-strict and text is exact/case-sensitive. Positive comparisons,
4191
+ `ne` and `nin` require a present field. Logical `not` negates the complete child,
4192
+ so missing fields satisfy `not(eq(...))`. `eq/ne` require scalar fields; `in/nin`
4193
+ accept scalar or array fields; `all` requires an array. Invalid metadata and
4194
+ documents awaiting ingestion repair are ineligible for every typed predicate,
4195
+ including negation. Filtered queries report incomplete coverage until repaired.
4196
+ Limits: 64 metadata keys, 128-character keys, 4096-character strings, 128 array
4197
+ members, 64 KiB serialized metadata/filter, 128 predicate nodes, depth 8.
4198
+ Keys `__proto__`, `prototype`, and `constructor` are reserved.
4199
+
4200
+ For executable examples and the missing-field truth table, see
4201
+ [Typed metadata filters](../docs/TYPED-METADATA.md). `ne` additionally requires
4202
+ the field's scalar type to match the operand; `nin` matches a present scalar or
4203
+ array with no exact typed member match. Ordering never coerces strings.
@@ -121,6 +121,8 @@ CREATE TABLE IF NOT EXISTS contexts (
121
121
  -- ─────────────────────────────────────────────────────────────────────────────
122
122
 
123
123
  CREATE TABLE IF NOT EXISTS documents (
124
+ typed_metadata TEXT, -- validated gno.metadata, NULL until extraction
125
+ metadata_error TEXT, -- bounded path-only extraction diagnostic
124
126
  id INTEGER PRIMARY KEY AUTOINCREMENT,
125
127
  collection TEXT NOT NULL,
126
128
  rel_path TEXT NOT NULL,
package/spec/evals.md CHANGED
@@ -1110,3 +1110,51 @@ ordering, and rerank interaction without LLM or fixture drift.
1110
1110
  - CONTRIBUTING.md updated with DoD eval requirements
1111
1111
  - This spec (spec/evals.md) matches implementation
1112
1112
  ````
1113
+
1114
+ ## Adversarial evidence gate (development only)
1115
+
1116
+ `bun evals/acceptance/evidence-cli.ts --input <observations.json> --output <report.json>`
1117
+ validates and scores a frozen `gno-evidence-run-v1` observation bundle. Native
1118
+ collection is explicit (`--native --output <new-directory>`), uses only cached
1119
+ models and isolated synthetic indexes, and compares current defaults with
1120
+ `noExpand: true`. This is not a public GNO command or a default CI eval.
1121
+
1122
+ The fixture contract `gno-evidence-fixtures-v1` contains documents (URI, title,
1123
+ exact content and SHA-256), verified required spans (stable ID, source hash,
1124
+ 1-based inclusive line range and span hash), and cases. Cases pin query/intent,
1125
+ collection, family, usable token budget, independent UTF-8 byte cap, acceptable
1126
+ alternative sets of required span IDs, answerability, expected literal answer
1127
+ values, and a must-cover flag. Empty answerable evidence sets, invalid ranges,
1128
+ duplicate IDs, stale hashes, unknown span references and answer-bearing names
1129
+ in synthetic paths are rejected. Fixture bytes are pinned separately; baseline
1130
+ pins are never regenerated to hide a failure.
1131
+
1132
+ Every observation names a case, arm (`current` or `noExpand`), fixture digest,
1133
+ runtime/model/settings identity, native coverage and invalid-run reasons. Its
1134
+ stages (`retrieval`, `fusion`, `rerank_input`, `delivery`) contain observed
1135
+ passages with URI, source hash, UTF-16 source offsets, exact text and an input
1136
+ identity. Stages not captured are null, not empty successful stages. Clipping
1137
+ metadata retains the original selected extent when known. Passage validity is
1138
+ checked against the pinned source. A required span survives only when verified
1139
+ passages in one actual input together cover every character; separate reranker
1140
+ inputs cannot pool coverage. Partial, clipped, split-across-inputs, missing and
1141
+ unknown outcomes remain distinct. Duplicate appearances cannot add coverage.
1142
+
1143
+ The `gno-evidence-report-v1` output retains per-span/stage outcomes, all-required
1144
+ and any-required evidence coverage, first observed loss stage, fixed-reader
1145
+ answer/abstention outcome, UTF-8 bytes, declared-estimator token cost, exact native
1146
+ tokenization observations when available, elapsed time and resource samples.
1147
+ Actual tokenizer observations are not mislabeled as total inference billing;
1148
+ missing observations remain null. Reader outcomes use delivered verified spans,
1149
+ expected fixture values and the actual answer verification result, not document
1150
+ hits or reconstructed snippets. Retrieval-only runs have a null reader outcome.
1151
+
1152
+ Comparison requires exactly one observation per case/arm, matching fixture,
1153
+ model/runtime identity and budgets; only the declared noExpand setting differs.
1154
+ Native fallback or missing required model execution invalidates a native pair.
1155
+ Replay success never certifies native execution. Both arms and baseline misses
1156
+ are retained. Candidate adoption requires all deterministic guard cases and
1157
+ must-cover cases, no reduction in held-out complete evidence or fixed-reader
1158
+ success, and valid comparisons. A baseline miss is a finding; this gate does not
1159
+ change ranking defaults to make itself green. The exact strict JSON schemas
1160
+ ship beside the other evaluation output schemas.
package/spec/mcp.md CHANGED
@@ -3054,3 +3054,15 @@ Schemas: `collection-egress-policy.schema.json`,
3054
3054
  - [CLI Specification](./cli.md)
3055
3055
  - [Output Schemas](./output-schemas/)
3056
3056
  - [MCP Protocol Specification](https://modelcontextprotocol.io/specification/)
3057
+
3058
+ ### Typed metadata retrieval filter
3059
+
3060
+ Applicable retrieval tools accept the same bounded `filter` predicate documented
3061
+ in `spec/cli.md`. Invalid filters fail validation with a field path. Predicates
3062
+ intersect caller scope before candidate limits and never expand authority.
3063
+
3064
+ `gno_search`, `gno_vsearch`, `gno_query`, `gno_ask`, and `gno_context` expose
3065
+ `filter`. The strict discriminated contract is recorded in
3066
+ [metadata-predicate.schema.json](output-schemas/metadata-predicate.schema.json).
3067
+ See [Typed metadata filters](../docs/TYPED-METADATA.md) for exact membership,
3068
+ missing-field, invalid-document, and bounded-input semantics.
@@ -28,6 +28,18 @@
28
28
  "type": "object",
29
29
  "required": ["verificationRequested", "abstained"],
30
30
  "properties": {
31
+ "warnings": {
32
+ "type": "array",
33
+ "items": {
34
+ "type": "object",
35
+ "additionalProperties": false,
36
+ "required": ["code", "message"],
37
+ "properties": {
38
+ "code": { "type": "string" },
39
+ "message": { "type": "string" }
40
+ }
41
+ }
42
+ },
31
43
  "verificationRequested": { "const": true },
32
44
  "abstained": {}
33
45
  }