@gmickel/gno 1.21.0 → 1.23.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 (47) hide show
  1. package/README.md +26 -2
  2. package/assets/skill/SKILL.md +15 -0
  3. package/package.json +2 -1
  4. package/spec/cli.md +80 -20
  5. package/spec/evals-agentic.md +83 -0
  6. package/spec/evals.md +6 -0
  7. package/spec/mcp.md +18 -0
  8. package/spec/output-schemas/publish-artifact.schema.json +284 -0
  9. package/spec/output-schemas/query-diagnose-v1.schema.json +123 -0
  10. package/spec/output-schemas/query-diagnose.schema.json +89 -2
  11. package/src/app/context-runtime-types.ts +3 -0
  12. package/src/app/context-runtime.ts +1 -0
  13. package/src/app/context-surface.ts +4 -2
  14. package/src/cli/commands/ask.ts +31 -20
  15. package/src/cli/commands/context-build.ts +17 -7
  16. package/src/cli/commands/query.ts +58 -37
  17. package/src/cli/commands/search.ts +29 -19
  18. package/src/cli/commands/vsearch.ts +31 -22
  19. package/src/cli/options.ts +39 -0
  20. package/src/cli/program.ts +48 -0
  21. package/src/config/defaults.ts +10 -1
  22. package/src/config/types.ts +71 -0
  23. package/src/core/project-affinity-surface.ts +114 -0
  24. package/src/core/project-affinity.ts +330 -0
  25. package/src/core/validation.ts +20 -1
  26. package/src/mcp/tools/ask.ts +10 -1
  27. package/src/mcp/tools/context.ts +18 -0
  28. package/src/mcp/tools/index.ts +13 -2
  29. package/src/mcp/tools/query.ts +12 -0
  30. package/src/mcp/tools/search.ts +7 -0
  31. package/src/mcp/tools/vsearch.ts +7 -0
  32. package/src/pipeline/diagnose.ts +48 -3
  33. package/src/pipeline/explain.ts +54 -13
  34. package/src/pipeline/hybrid.ts +100 -59
  35. package/src/pipeline/project-affinity.ts +162 -0
  36. package/src/pipeline/search.ts +76 -10
  37. package/src/pipeline/types.ts +9 -0
  38. package/src/pipeline/vsearch.ts +117 -91
  39. package/src/publish/artifact-validation.ts +259 -0
  40. package/src/publish/artifact.ts +234 -118
  41. package/src/publish/export-service.ts +5 -9
  42. package/src/publish/metadata.ts +195 -0
  43. package/src/sdk/client.ts +80 -20
  44. package/src/sdk/index.ts +2 -0
  45. package/src/sdk/types.ts +20 -7
  46. package/src/serve/context-capsule.ts +18 -1
  47. package/src/serve/routes/api.ts +69 -0
package/README.md CHANGED
@@ -17,6 +17,17 @@
17
17
 
18
18
  GNO is a local knowledge engine for notes, code, PDFs, Office docs, meeting transcripts, and reference material. It gives you fast keyword search, semantic retrieval, grounded answers with citations, wiki-style linking, and a real workspace UI, while keeping the whole stack local by default.
19
19
 
20
+ CLI retrieval also uses the current repository/workspace as a transparent soft
21
+ ranking signal. A trusted local cwd or repeatable `--project-root` can add at
22
+ most `+0.03` to matching collection results; `--no-project-affinity` disables
23
+ it, and explicit roots replace cwd inference. It never overrides collection,
24
+ tag, date, exclude, or egress filters. SDK, REST, and MCP `projectHints` are
25
+ opaque, untrusted, limited to 16, and intentionally have zero ranking effect:
26
+ those surfaces never probe caller or server filesystem paths. Trusted local
27
+ diagnose output uses closed `schemaVersion: "1.1"` redacted affinity metadata;
28
+ absent, disabled, and remote/untrusted diagnose requests preserve exact legacy
29
+ v1.0 bytes and omit `affinity`.
30
+
20
31
  Use it when:
21
32
 
22
33
  - your notes live in more than one folder
@@ -94,12 +105,16 @@ gno daemon --detach # headless continuous indexing (background; --status / --st
94
105
 
95
106
  <!-- public-truth:current-version -->
96
107
 
97
- > Current release: **v1.21.0** — see [CHANGELOG.md](./CHANGELOG.md)
108
+ > Current release: **v1.23.0** — see [CHANGELOG.md](./CHANGELOG.md)
98
109
 
99
110
  <!-- /public-truth -->
100
111
 
101
112
  > Full release history: [CHANGELOG.md](./CHANGELOG.md)
102
113
 
114
+ - **Project-aware retrieval affinity**: trusted local CLI searches can use the
115
+ current workspace or explicit `--project-root` values as a transparent,
116
+ explainable `+0.03` soft ranking signal. Filters remain hard, and untrusted
117
+ SDK, REST, MCP, and Web hints never probe paths or affect ranking.
103
118
  - **Retrieval-proven activation**: `gno status`, `gno doctor`, REST, and the
104
119
  Web/Desktop dashboard now share a per-folder lexical retrieval proof. Local
105
120
  semantic readiness remains independent, and installed MCP targets can run an
@@ -710,7 +725,7 @@ GNO is local-first, but sometimes you want a URL to send someone. [**gno.sh**](h
710
725
 
711
726
  ![gno.sh publish reader](./assets/screenshots/publish-reader.jpg)
712
727
 
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.
728
+ 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
729
 
715
730
  ```bash
716
731
  # Export a single note
@@ -745,6 +760,15 @@ Upload the artifact at [gno.sh/studio](https://gno.sh/studio) and pick a visibil
745
760
 
746
761
  **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
762
 
763
+ Public exports also carry a deterministic agent manifest. It lists only the
764
+ sanitized published Markdown projection, with relative Markdown locators,
765
+ content hashes, exact line spans, and Capsule-compatible evidence identities.
766
+ The projection revision is stable while those published bytes and reader
767
+ metadata are unchanged. Secret-link and invite-only exports do not receive
768
+ agent capabilities or manifests. Encrypted exports remain ciphertext-only.
769
+ Reader metadata drops embedded local path or GNO/file URI tokens; canonical
770
+ and image fields accept only uncredentialed public HTTP(S) targets.
771
+
748
772
  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
773
 
750
774
  Encrypted source-backed publish on `gno.sh` is intentionally disabled. For encrypted shares, use:
@@ -108,8 +108,23 @@ Recipe rules:
108
108
  --json JSON output
109
109
  --files URI list output
110
110
  --line-numbers Include line numbers
111
+ --project-root <path> Trusted local root; repeatable and replaces cwd affinity
112
+ --no-project-affinity Disable trusted local project-aware ranking
111
113
  ```
112
114
 
115
+ CLI searches use the current repository/worktree as a soft signal by default.
116
+ A matching collection can receive at most `+0.03`; roots never stack, all
117
+ auxiliary signals share `±0.08`, and collection/tag/date/exclude/egress filters
118
+ stay hard. Use `--project-root` for explicit trusted roots or
119
+ `--no-project-affinity` to disable it.
120
+
121
+ Do not treat MCP/SDK/REST `projectHints` as paths. They are opaque, untrusted,
122
+ limited to 16, never trigger filesystem probing, and currently produce zero
123
+ affinity. Explain uses redacted aliases only. Diagnose preserves exact closed
124
+ v1.0 bytes and omits `affinity` for absent, disabled, and remote/untrusted
125
+ inputs; trusted local diagnose uses closed v1.1 redacted metadata, including an
126
+ explicit unmatched state. The Web UI does not infer a browser project root.
127
+
113
128
  ## Advanced: Structured Query Modes (query/ask only)
114
129
 
115
130
  Use `--query-mode` to combine multiple retrieval strategies in one query (repeatable):
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gmickel/gno",
3
- "version": "1.21.0",
3
+ "version": "1.23.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 |
@@ -748,22 +749,24 @@ gno search <query> [-n <num>] [--min-score <num>] [-c <collection>] [--since <da
748
749
 
749
750
  **Options:**
750
751
 
751
- | Option | Type | Default | Description |
752
- | ------------------ | ------- | ------------------------- | --------------------------------------------------------------------------------------------- |
753
- | `-n` | integer | 5 (20 for --json/--files) | Max results |
754
- | `--min-score` | number | 0 | Minimum score threshold |
755
- | `-c, --collection` | string | all | Filter to collection |
756
- | `--since` | string | none | Modified-at lower bound (ISO date/time or relative token) |
757
- | `--until` | string | none | Modified-at upper bound (ISO date/time or relative token) |
758
- | `--category` | string | none | Filter to docs with matching category/content type (comma-separated) |
759
- | `--author` | string | none | Filter to docs where author contains value (case-insensitive) |
760
- | `--intent` | string | none | Disambiguating context for ambiguous queries; steers snippets without being searched directly |
761
- | `--exclude` | string | none | Hard-prune docs containing any comma-separated term in title/path/body |
762
- | `--tags-all` | string | none | Filter to docs with ALL tags (comma-separated) |
763
- | `--tags-any` | string | none | Filter to docs with ANY tag (comma-separated) |
764
- | `--full` | boolean | false | Include full mirror content instead of snippet |
765
- | `--line-numbers` | boolean | false | Include line numbers in output |
766
- | `--lang` | string | auto | Language filter/hint (BCP-47) |
752
+ | Option | Type | Default | Description |
753
+ | ----------------------- | -------- | ------------------------- | --------------------------------------------------------------------------------------------- |
754
+ | `-n` | integer | 5 (20 for --json/--files) | Max results |
755
+ | `--min-score` | number | 0 | Minimum score threshold |
756
+ | `-c, --collection` | string | all | Filter to collection |
757
+ | `--since` | string | none | Modified-at lower bound (ISO date/time or relative token) |
758
+ | `--until` | string | none | Modified-at upper bound (ISO date/time or relative token) |
759
+ | `--category` | string | none | Filter to docs with matching category/content type (comma-separated) |
760
+ | `--author` | string | none | Filter to docs where author contains value (case-insensitive) |
761
+ | `--intent` | string | none | Disambiguating context for ambiguous queries; steers snippets without being searched directly |
762
+ | `--exclude` | string | none | Hard-prune docs containing any comma-separated term in title/path/body |
763
+ | `--tags-all` | string | none | Filter to docs with ALL tags (comma-separated) |
764
+ | `--tags-any` | string | none | Filter to docs with ANY tag (comma-separated) |
765
+ | `--project-root` | string[] | cwd | Trusted project root; repeatable, replaces default cwd/repository affinity |
766
+ | `--no-project-affinity` | boolean | false | Disable project-aware soft ranking; invalid with `--project-root` |
767
+ | `--full` | boolean | false | Include full mirror content instead of snippet |
768
+ | `--line-numbers` | boolean | false | Include line numbers in output |
769
+ | `--lang` | string | auto | Language filter/hint (BCP-47) |
767
770
 
768
771
  **Scoring:**
769
772
 
@@ -823,7 +826,8 @@ Vector semantic search over indexed documents.
823
826
  gno vsearch <query> [-n <num>] [--min-score <num>] [-c <collection>] [--since <date>] [--until <date>] [--category <values>] [--author <text>] [--intent <text>] [--exclude <values>] [--tags-all <tags>] [--tags-any <tags>] [--full] [--line-numbers] [--lang <bcp47>] [--json|--files|--csv|--md|--xml]
824
827
  ```
825
828
 
826
- **Options:** Same as `gno search` (including temporal/category/author and tag filters)
829
+ **Options:** Same as `gno search` (including temporal/category/author, tag, and
830
+ project-affinity controls).
827
831
 
828
832
  **Scoring:**
829
833
 
@@ -869,6 +873,9 @@ gno query diagnose <query> --target <doc> [-n <num>] [--min-score <num>] [-c <co
869
873
  | `--explain` | boolean | Print retrieval explanation to stderr |
870
874
  | `--target` | ref | Required for `query diagnose`; target document to diagnose |
871
875
 
876
+ `query diagnose` accepts the same `--project-root` and
877
+ `--no-project-affinity` controls as `query`.
878
+
872
879
  **Compatibility / Migration:**
873
880
 
874
881
  - Legacy query invocations remain valid (`gno query "<text>"`, `--fast`, `--thorough`, `--no-expand`, `--no-rerank`).
@@ -881,8 +888,12 @@ gno query diagnose <query> --target <doc> [-n <num>] [--min-score <num>] [-c <co
881
888
  **Diagnose Output:**
882
889
 
883
890
  `gno query diagnose` wraps the shared `diagnoseQueryTarget()` core and emits
884
- `query-diagnose.schema.json` for `--json`. The payload requires
885
- `schemaVersion: "1.0"`, resolves the target first, reports `target.status`
891
+ `query-diagnose.schema.json` for `--json`. No trusted affinity input preserves
892
+ the exact closed `schemaVersion: "1.0"` payload and omits `affinity`; the legacy
893
+ contract remains in `query-diagnose-v1.schema.json`. A resolved trusted CLI cwd
894
+ or explicit project root emits `schemaVersion: "1.1"` and requires closed,
895
+ redacted `affinity` metadata, including unmatched state. The payload resolves
896
+ the target first, reports `target.status`
886
897
  (`not_found|inactive|no_indexed_content|filtered_out|diagnosed`), and only runs
887
898
  stage tracing for `diagnosed` targets. Stages report
888
899
  `present`, `rank`, `score`, `survived`, `dropReason`, `status`, and
@@ -991,6 +1002,8 @@ gno ask <query> [-n <num>] [-c <collection>] [--lang <bcp47>] [--since <date>] [
991
1002
  | `--no-expand` | boolean | false | Disable query expansion |
992
1003
  | `--no-rerank` | boolean | false | Disable cross-encoder reranking |
993
1004
  | `--show-sources` | boolean | false | Show all retrieved sources (not just cited) |
1005
+ | `--project-root` | string[] | cwd | Trusted project root; repeatable, replaces default cwd/repository affinity |
1006
+ | `--no-project-affinity` | boolean | false | Disable project-aware soft ranking; invalid with `--project-root` |
994
1007
 
995
1008
  **Output (JSON):**
996
1009
  See [Output Schemas](./output-schemas/ask.schema.json)
@@ -1314,7 +1327,7 @@ written to stderr.
1314
1327
  **Synopsis:**
1315
1328
 
1316
1329
  ```bash
1317
- gno context build "<goal>" --budget <tokens> [--collection <name>] [--fast|--thorough] [--json|--md] [--output <file>]
1330
+ gno context build "<goal>" --budget <tokens> [--collection <name>] [--project-root <path>]... [--no-project-affinity] [--fast|--thorough] [--json|--md] [--output <file>]
1318
1331
  ```
1319
1332
 
1320
1333
  `--budget` is the global token ceiling. `--bytes` optionally sets a separate
@@ -1327,6 +1340,10 @@ repeatable. Tag filters are NFC-normalized, lowercased, deduplicated, and
1327
1340
  validated before retrieval. Result and candidate limits are global across
1328
1341
  repeated collections: the merged result pool is capped once, while candidate
1329
1342
  work is distributed deterministically in canonical collection order.
1343
+ Project affinity defaults to the trusted process cwd/repository. Repeatable
1344
+ `--project-root` values replace that default, are normalized/deduplicated, and
1345
+ are capped at 16. `--no-project-affinity` disables the soft signal and cannot
1346
+ be combined with explicit roots.
1330
1347
 
1331
1348
  JSON is the canonical V1 payload. Markdown is a readable projection of that
1332
1349
  same payload and hard-delimits each untrusted evidence passage. Passage,
@@ -1558,6 +1575,49 @@ gno models path [--json]
1558
1575
 
1559
1576
  ---
1560
1577
 
1578
+ ### gno publish export
1579
+
1580
+ Build a reader-safe gno.sh artifact from one active collection or document.
1581
+
1582
+ **Synopsis:**
1583
+
1584
+ ```bash
1585
+ gno publish export <target> \
1586
+ [--out <path>] \
1587
+ [--visibility public|secret-link|invite-only|encrypted] \
1588
+ [--passphrase <value>] \
1589
+ [--slug <slug>] \
1590
+ [--title <title>] \
1591
+ [--summary <summary>] \
1592
+ [--preview] \
1593
+ [--json]
1594
+ ```
1595
+
1596
+ Public V1 spaces MUST carry a `manifest` conforming to
1597
+ [`publish-artifact.schema.json`](./output-schemas/publish-artifact.schema.json).
1598
+ The manifest contains schema version `1.0`, a deterministic projection
1599
+ revision, generated time, closed public capabilities, sorted published
1600
+ documents, relative Markdown locators, SHA-256 content hashes, and
1601
+ Capsule-compatible evidence identities. Manifest hashes and revisions MUST be
1602
+ derived only from sanitized notes and metadata present in the published
1603
+ projection. Local collection paths, document source URIs, unpublished
1604
+ documents, and filtered metadata MUST NOT enter artifact bytes or revision
1605
+ inputs. Reader metadata values containing embedded local path or GNO/file URI
1606
+ tokens MUST be filtered. Canonical and image metadata MUST contain
1607
+ uncredentialed public HTTP(S) targets; local hostnames and literal loopback,
1608
+ private, or link-local addresses MUST be filtered.
1609
+
1610
+ Secret-link and invite-only V1 spaces MUST NOT contain a manifest or agent
1611
+ capability field. Encrypted V2 spaces MUST contain only ciphertext parameters,
1612
+ the opaque secret token, route slug, source type, and encrypted visibility; no
1613
+ plaintext manifest or evidence may appear outside the ciphertext. V2 builders
1614
+ MUST emit a closed projection, validate payload strings as non-empty bounded
1615
+ base64, require a positive safe-integer KDF iteration count, and bound the
1616
+ non-blank opaque token. Caller-supplied extension fields MUST NOT enter the
1617
+ artifact.
1618
+
1619
+ ---
1620
+
1561
1621
  ### gno cleanup
1562
1622
 
1563
1623
  Remove orphaned content, chunks, and vectors not referenced by active documents.
@@ -22,8 +22,13 @@ evals/agentic/
22
22
  fixture-db.ts
23
23
  scoring.ts
24
24
  promotion.ts
25
+ project-affinity-contract.ts
26
+ project-affinity-outcome.ts
27
+ project-affinity-promotion.ts
28
+ project-affinity-runtime.ts
25
29
  verified-ask-outcome.ts
26
30
  verified-ask-promotion.ts
31
+ demos/context-capsule.ts
27
32
  registry.ts
28
33
  report.ts
29
34
  report-artifacts.ts
@@ -44,6 +49,7 @@ evals/agentic/
44
49
  final-envelope.schema.json
45
50
  trajectory-receipt.schema.json
46
51
  benchmark-report.schema.json
52
+ context-capsule-demo.schema.json
47
53
 
48
54
  evals/fixtures/agentic-retrieval/
49
55
  manifest.json
@@ -61,8 +67,42 @@ evals/fixtures/agentic-retrieval/
61
67
  verified-ask-promotion.json
62
68
  verified-ask-promotion.md
63
69
  optional/{qmd,local-model}/ # local opt-in evidence; not authoritative
70
+ demos/
71
+ context-capsule.json
72
+ context-capsule.md
64
73
  ```
65
74
 
75
+ ## Separate project-affinity promotion
76
+
77
+ `project-affinity-cases.json` defines two controlled vector-distance pairs over
78
+ the existing `t456ef70` (`c015`/`c115`) and `t567f081`
79
+ (`c016`/`c116`) task/corpus/oracle identities. The separate closed
80
+ `project-affinity-promotion@1.0` artifact hash-binds those manifest identities;
81
+ it does not add tasks to the authoritative 24-task, 144-receipt matrix or
82
+ change `BenchmarkReport@1`.
83
+
84
+ The target collection starts `0.02` behind, then receives one trusted local
85
+ `+0.03` contribution. Promotion requires correct top-1 to strictly improve to
86
+ `2/2`, exact required evidence to remain retained, zero URI-rank/required
87
+ evidence-coverage loss across all 24 hard-collection tasks, and zero loss for
88
+ `t012ab3c`, `t123bc4d`, `te8f901a`, and `tf901a2b`. It also gates hard-filter
89
+ isolation, absent/disabled/unavailable/untrusted exact zero lanes, shared
90
+ auxiliary cap receipts, and structural store-call/candidate bounds. Structural
91
+ receipts record the complete closed StorePort method map, reject unexpected
92
+ methods, enforce per-method maxima, require candidate requests and returns to
93
+ stay within `3×` the output limit, and require returned candidates not to exceed
94
+ requested candidates. Latency is not a gate.
95
+
96
+ The committed artifacts are
97
+ `baseline/fixture-agent/project-affinity-promotion.json` and `.md`. They contain
98
+ only GNO evidence URIs, hashes, scores, raw filter/regression/zero/auxiliary/
99
+ structural receipts, implementation provenance, and redacted aliases—never
100
+ temporary roots, raw project hints, or absolute paths. An independent validator
101
+ rebinds fixture identities, recomputes summaries/gates/fingerprint from those
102
+ receipts, and compares the committed artifact with a fresh deterministic
103
+ production run. The controlled synthetic lane isolates the score seam and makes
104
+ no general workload superiority claim.
105
+
66
106
  The first fixture version contains 24 original synthetic tasks and 34 Markdown
67
107
  documents under the MIT license. It covers exact identifiers, ambiguity,
68
108
  multi-document comparisons, meeting decisions, temporal questions, typed
@@ -412,6 +452,48 @@ summary. The six files are staged and directory-renamed as one baseline set.
412
452
  The verified Ask files are a separate attributable outcome lane; they do not
413
453
  rename the Capsule retrieval promotion in `report.json`.
414
454
 
455
+ ## Reproducible Context Capsule demo
456
+
457
+ `demos/context-capsule.json` is a closed, canonically fingerprinted projection
458
+ of one frozen exact-identifier task from the authoritative fixture-agent
459
+ report. It contains exactly three lanes in fixed order: the lexical-only
460
+ no-GNO baseline, shipped GNO MCP query/get primitives, and the Context Capsule.
461
+ Every lane retains its complete normalized trajectory receipt, score, exact
462
+ evidence coordinates and hashes, final stop outcome, agent/backend call counts,
463
+ model-visible UTF-8 bytes, token availability, and matching-lifecycle latency.
464
+
465
+ All three lanes must share the task, outer agent, trial, seed, lifecycle,
466
+ corpus, prompt, tool, model, runtime, and canonical effective-index
467
+ fingerprints. The generator selects exactly one receipt and score per full
468
+ identity and rejects ambiguous multi-trial input. Adapter configuration
469
+ fingerprints may differ. The Capsule projection additionally retains its
470
+ normalized `retrieval.request`, effective index fingerprint, capability states,
471
+ fallback list, and complete model-visible payload. Validation parses the
472
+ delivered evidence bundle and compares those values, then recomputes every
473
+ displayed lane metric from the embedded receipt and score.
474
+
475
+ Source provenance distinguishes each source run's clean `runGitCommit` from
476
+ the later Git commit that contains the generated demo artifact. The artifact
477
+ does not attempt to embed its own containing commit. Its report and Verified
478
+ Ask fingerprints and projected fields must match the canonical linked source
479
+ artifacts.
480
+
481
+ The readable `context-capsule.md` is generated from the JSON contract. It
482
+ states the single-trial variance limitation, reports tokens as unavailable
483
+ without one pinned comparable tokenizer, and limits its claim to the measured
484
+ controlled task. It discloses that the chosen task is the sole cold
485
+ current-GNO-failure / Capsule-success case in the 24-task authoritative cohort,
486
+ that the Capsule lane is an evaluation-only lexical prototype, and that its
487
+ latency is not shipped-product latency. It cannot be used as a general
488
+ product-superiority claim.
489
+
490
+ The adjacent Verified Ask block is an attributable but separate
491
+ `answer_enforcement` proof. It binds the clean-Git canonical fingerprint of the
492
+ frozen 22-pair `raw_ask`/`verified_ask` artifact, retains the two declared
493
+ missing-evidence exclusions, and exposes only answer-accuracy and unsupported-
494
+ substantive-claim metrics. Those metrics are never merged into or labeled as
495
+ retrieval metrics.
496
+
415
497
  ## Deterministic scoring
416
498
 
417
499
  The scorer compares typed claims and exact citations with the hidden oracle. It
@@ -551,6 +633,7 @@ Contract tests are ordinary offline tests:
551
633
 
552
634
  ```bash
553
635
  bun test test/eval/agentic
636
+ bun run eval:agentic:demo
554
637
  ```
555
638
 
556
639
  The runner is local and opt-in:
package/spec/evals.md CHANGED
@@ -27,6 +27,12 @@ Agent-level evidence sufficiency, exact citation coverage, stopping behavior,
27
27
  and Context Capsule promotion use the separate deterministic
28
28
  [Agentic Retrieval Evaluation Contract](evals-agentic.md).
29
29
 
30
+ That contract also owns a separate closed project-affinity promotion artifact.
31
+ It reuses the immutable 24-task fixture identities while leaving the main task
32
+ inventory and report schema unchanged. The gate records measured top-1,
33
+ evidence, multilingual, hard-filter, zero-lane, score-cap, and structural-call
34
+ outcomes; it does not use a wall-clock threshold.
35
+
30
36
  ## Dependencies
31
37
 
32
38
  ```json
package/spec/mcp.md CHANGED
@@ -218,6 +218,10 @@ Optional fields are `collection`, `limit` (default 5), `minScore`, `lang`,
218
218
  `since`, `until`, `categories`, `author`, `graph`, `noGraph`, `noRerank`,
219
219
  `maxAnswerTokens`, `contextBudgetTokens`, and `contextBudgetBytes`. Input
220
220
  objects are closed.
221
+ `projectHints` is an optional array of at most 16 non-empty caller hints. Hints
222
+ are normalized and deduplicated as opaque values, never resolved against or
223
+ reflected from the MCP server filesystem, and therefore have zero ranking
224
+ effect on the remote channel.
221
225
 
222
226
  `structuredContent` uses the
223
227
  [`ask`](./output-schemas/ask.schema.json) contract. Its `verification` object
@@ -273,6 +277,9 @@ validated before retrieval. `limit` and `candidateLimit` are global across all
273
277
  requested collections: result admission is capped after merging, and
274
278
  rerank/graph candidate work is distributed deterministically in canonical
275
279
  collection order.
280
+ `projectHints` is also accepted as an optional array of at most 16 opaque
281
+ caller hints. It follows the same remote zero-affinity, non-probing, and
282
+ non-reflection contract as all MCP retrieval tools.
276
283
 
277
284
  `structuredContent` is the complete canonical Context Capsule object for
278
285
  application clients. Model-visible text is always one deterministic
@@ -338,6 +345,13 @@ evidence reads. `structuredContent` is the canonical verification receipt.
338
345
 
339
346
  BM25 keyword search over indexed documents.
340
347
 
348
+ All retrieval input schemas (`gno_search`, `gno_vsearch`, `gno_query`, and
349
+ `gno_query_diagnose`) additionally accept optional `projectHints: string[]`
350
+ (maximum 16). Values are trimmed, NFC-normalized, deduplicated, and treated as
351
+ opaque remote hints. The server never stats, realpaths, discovers repositories,
352
+ or infers its cwd from them; remote hints produce redacted zero-affinity
353
+ metadata and no ranking change.
354
+
341
355
  **Input Schema:**
342
356
 
343
357
  ```json
@@ -745,6 +759,10 @@ Structured content includes `schemaVersion`, normalized `query`, `target`
745
759
  metadata/status (`not_found`, `inactive`, `no_indexed_content`,
746
760
  `filtered_out`, or `diagnosed`), `stages` for BM25/vector/fusion/graph/rerank,
747
761
  the selected target `chunk`, and retrieval `meta`.
762
+ MCP inputs are remote and untrusted, so this tool preserves exact v1.0 bytes
763
+ and omits `affinity`, even when `projectHints` are supplied. The shared current
764
+ validation schema is `gno://schemas/query-diagnose@1.1`; its affinity-bearing
765
+ v1.1 branch is reserved for trusted local CLI diagnose requests.
748
766
 
749
767
  Use when an expected target is missing from `gno_query`, when filters may have
750
768
  excluded it, or when an agent needs evidence before raising `candidateLimit`,