@gmickel/gno 1.18.0 → 1.19.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 +5 -3
- package/assets/skill/SKILL.md +27 -0
- package/package.json +2 -1
- package/spec/AGENTS.md +83 -0
- package/spec/CLAUDE.md +83 -0
- package/spec/bench-fixture.schema.json +137 -0
- package/spec/cli.md +2894 -0
- package/spec/db/schema.sql +442 -0
- package/spec/evals-agentic.md +510 -0
- package/spec/evals.md +1106 -0
- package/spec/mcp.md +2229 -0
- package/spec/output-schemas/activation-verification.schema.json +515 -0
- package/spec/output-schemas/ask.schema.json +366 -0
- package/spec/output-schemas/backlinks.schema.json +131 -0
- package/spec/output-schemas/bench-result.schema.json +120 -0
- package/spec/output-schemas/capture-receipt.schema.json +143 -0
- package/spec/output-schemas/collection-list.schema.json +45 -0
- package/spec/output-schemas/context-capsule-v1.schema.json +691 -0
- package/spec/output-schemas/context-capsule-verification.schema.json +1338 -0
- package/spec/output-schemas/context-list.schema.json +21 -0
- package/spec/output-schemas/doctor.schema.json +313 -0
- package/spec/output-schemas/error.schema.json +30 -0
- package/spec/output-schemas/expansion.schema.json +37 -0
- package/spec/output-schemas/get.schema.json +140 -0
- package/spec/output-schemas/graph-query.schema.json +99 -0
- package/spec/output-schemas/graph.schema.json +371 -0
- package/spec/output-schemas/links-list.schema.json +186 -0
- package/spec/output-schemas/mcp-add-collection-result.schema.json +23 -0
- package/spec/output-schemas/mcp-capture-result.schema.json +152 -0
- package/spec/output-schemas/mcp-http-error.schema.json +30 -0
- package/spec/output-schemas/mcp-job-list.schema.json +58 -0
- package/spec/output-schemas/mcp-job-status.schema.json +224 -0
- package/spec/output-schemas/mcp-remove-result.schema.json +39 -0
- package/spec/output-schemas/mcp-sync-result.schema.json +41 -0
- package/spec/output-schemas/mcp-tag-result.schema.json +33 -0
- package/spec/output-schemas/models-list.schema.json +93 -0
- package/spec/output-schemas/multi-get.schema.json +103 -0
- package/spec/output-schemas/process-status.schema.json +119 -0
- package/spec/output-schemas/query-diagnose.schema.json +123 -0
- package/spec/output-schemas/resident-status.schema.json +154 -0
- package/spec/output-schemas/retrieval-trace-common.schema.json +492 -0
- package/spec/output-schemas/retrieval-trace-delete.schema.json +16 -0
- package/spec/output-schemas/retrieval-trace-export.schema.json +61 -0
- package/spec/output-schemas/retrieval-trace-filters.schema.json +139 -0
- package/spec/output-schemas/retrieval-trace-judgment.schema.json +15 -0
- package/spec/output-schemas/retrieval-trace-list.schema.json +18 -0
- package/spec/output-schemas/retrieval-trace-payloads.schema.json +178 -0
- package/spec/output-schemas/retrieval-trace-purge.schema.json +31 -0
- package/spec/output-schemas/retrieval-trace-qrels.schema.json +303 -0
- package/spec/output-schemas/retrieval-trace-replay.schema.json +286 -0
- package/spec/output-schemas/retrieval-trace-show.schema.json +69 -0
- package/spec/output-schemas/retrieval-trace-summary.schema.json +65 -0
- package/spec/output-schemas/search-result.schema.json +154 -0
- package/spec/output-schemas/search-results.schema.json +338 -0
- package/spec/output-schemas/similar.schema.json +84 -0
- package/spec/output-schemas/status.schema.json +676 -0
- package/spec/output-schemas/tags-list.schema.json +48 -0
- package/src/app/context-runtime-types.ts +3 -0
- package/src/app/context-runtime.ts +15 -1
- package/src/cli/commands/ask.ts +106 -36
- package/src/cli/commands/context-build.ts +56 -9
- package/src/cli/commands/get.ts +64 -3
- package/src/cli/commands/query.ts +62 -23
- package/src/cli/commands/replay.ts +140 -0
- package/src/cli/commands/search.ts +48 -3
- package/src/cli/commands/shared.ts +3 -1
- package/src/cli/commands/trace.ts +200 -0
- package/src/cli/commands/vsearch.ts +75 -53
- package/src/cli/program.ts +255 -0
- package/src/config/index.ts +9 -0
- package/src/config/retrieval-traces.ts +56 -0
- package/src/config/types.ts +4 -0
- package/src/core/context-compiler.ts +11 -4
- package/src/core/retrieval-qrels.ts +405 -0
- package/src/core/retrieval-replay-candidate.ts +368 -0
- package/src/core/retrieval-replay-types.ts +109 -0
- package/src/core/retrieval-replay-validation.ts +89 -0
- package/src/core/retrieval-replay.ts +441 -0
- package/src/core/retrieval-trace-evidence-origin.ts +175 -0
- package/src/core/retrieval-trace-export.ts +113 -0
- package/src/core/retrieval-trace-filter-normalization.ts +27 -0
- package/src/core/retrieval-trace-filters.ts +19 -0
- package/src/core/retrieval-trace-management-helpers.ts +247 -0
- package/src/core/retrieval-trace-management-types.ts +132 -0
- package/src/core/retrieval-trace-management.ts +422 -0
- package/src/core/retrieval-trace-request.ts +141 -0
- package/src/core/retrieval-trace-session.ts +494 -0
- package/src/core/retrieval-trace.ts +472 -0
- package/src/mcp/tools/context.ts +59 -8
- package/src/mcp/tools/get.ts +35 -1
- package/src/mcp/tools/index.ts +74 -0
- package/src/mcp/tools/query.ts +95 -64
- package/src/mcp/tools/search.ts +36 -13
- package/src/mcp/tools/trace.ts +143 -0
- package/src/mcp/tools/vsearch.ts +71 -38
- package/src/pipeline/answer.ts +167 -26
- package/src/pipeline/graph-retrieval.ts +15 -1
- package/src/pipeline/hybrid.ts +151 -43
- package/src/pipeline/search.ts +36 -3
- package/src/pipeline/trace-metadata.ts +47 -0
- package/src/pipeline/types.ts +43 -0
- package/src/pipeline/vsearch.ts +101 -38
- package/src/sdk/client.ts +380 -71
- package/src/sdk/documents.ts +48 -1
- package/src/sdk/index.ts +17 -0
- package/src/sdk/types.ts +28 -0
- package/src/serve/context-capsule.ts +67 -8
- package/src/serve/public/app.tsx +12 -1
- package/src/serve/public/globals.built.css +1 -1
- package/src/serve/public/lib/workspace-tabs.ts +2 -0
- package/src/serve/public/pages/Dashboard.tsx +10 -0
- package/src/serve/public/pages/TraceHistory.tsx +478 -0
- package/src/serve/public/pages/trace-history-detail.tsx +224 -0
- package/src/serve/retrieval-trace.ts +28 -0
- package/src/serve/routes/api.ts +366 -72
- package/src/serve/routes/traces.ts +156 -0
- package/src/serve/server.ts +87 -2
- package/src/store/index.ts +31 -0
- package/src/store/migrations/014-retrieval-traces.ts +303 -0
- package/src/store/migrations/index.ts +2 -0
- package/src/store/retrieval-trace-codec.ts +384 -0
- package/src/store/sqlite/adapter.ts +153 -1
- package/src/store/sqlite/retrieval-trace-management-store.ts +341 -0
- package/src/store/sqlite/retrieval-trace-retention.ts +349 -0
- package/src/store/sqlite/retrieval-trace-rows.ts +267 -0
- package/src/store/sqlite/retrieval-trace-store.ts +515 -0
- package/src/store/types.ts +297 -0
- package/src/store/vector/sqlite-vec.ts +76 -1
- package/src/store/vector/types.ts +1 -1
|
@@ -0,0 +1,510 @@
|
|
|
1
|
+
# Agentic Retrieval Evaluation Contract
|
|
2
|
+
|
|
3
|
+
This specification defines GNO's deterministic end-to-end retrieval outcome
|
|
4
|
+
benchmark. It measures whether an agent finds enough evidence, cites it exactly,
|
|
5
|
+
and stops efficiently. It complements ranking evals; it does not replace them.
|
|
6
|
+
|
|
7
|
+
The standard test suite validates fixtures, schemas, hashing, scoring, and
|
|
8
|
+
production ingestion without a model, network access, API key, or global GNO
|
|
9
|
+
configuration. Generation-backed benchmark runs remain local and opt-in.
|
|
10
|
+
|
|
11
|
+
## Versions and layout
|
|
12
|
+
|
|
13
|
+
All contracts currently use `schemaVersion: "1.0"` and closed JSON Schema
|
|
14
|
+
draft-07 objects. Unknown properties fail validation.
|
|
15
|
+
|
|
16
|
+
```text
|
|
17
|
+
evals/agentic/
|
|
18
|
+
types.ts
|
|
19
|
+
canonical.ts
|
|
20
|
+
strict-json.ts
|
|
21
|
+
validation.ts
|
|
22
|
+
fixture-db.ts
|
|
23
|
+
scoring.ts
|
|
24
|
+
promotion.ts
|
|
25
|
+
registry.ts
|
|
26
|
+
report.ts
|
|
27
|
+
report-artifacts.ts
|
|
28
|
+
cli-options.ts
|
|
29
|
+
cli.ts
|
|
30
|
+
adapter.ts
|
|
31
|
+
agent.ts
|
|
32
|
+
fixture-agent.ts
|
|
33
|
+
local-model-agent.ts
|
|
34
|
+
runner.ts
|
|
35
|
+
runner-contract.ts
|
|
36
|
+
runner-receipt.ts
|
|
37
|
+
runner-trial.ts
|
|
38
|
+
runner-validation.ts
|
|
39
|
+
schemas/
|
|
40
|
+
agent-task.schema.json
|
|
41
|
+
hidden-oracle.schema.json
|
|
42
|
+
final-envelope.schema.json
|
|
43
|
+
trajectory-receipt.schema.json
|
|
44
|
+
benchmark-report.schema.json
|
|
45
|
+
|
|
46
|
+
evals/fixtures/agentic-retrieval/
|
|
47
|
+
manifest.json
|
|
48
|
+
tasks/<opaque-task-id>.json
|
|
49
|
+
oracles/<opaque-task-id>.json
|
|
50
|
+
corpus/<opaque-task-id>/<opaque-collection>/<opaque-file>.md
|
|
51
|
+
agent-model.lock.json
|
|
52
|
+
baseline/
|
|
53
|
+
README.md
|
|
54
|
+
fixture-agent/{report.json,canonical.json,observations.json,report.md}
|
|
55
|
+
optional/{qmd,local-model}/ # local opt-in evidence; not authoritative
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
The first fixture version contains 24 original synthetic tasks and 34 Markdown
|
|
59
|
+
documents under the MIT license. It covers exact identifiers, ambiguity,
|
|
60
|
+
multi-document comparisons, meeting decisions, temporal questions, typed
|
|
61
|
+
relationships, code/documentation, multilingual prose, and missing-evidence
|
|
62
|
+
abstention. The manifest hashes the exact bytes of every task, oracle, and
|
|
63
|
+
corpus file. Its separate corpus fingerprint hashes the sorted logical inventory
|
|
64
|
+
of task ID, collection, relative path, and source hash.
|
|
65
|
+
|
|
66
|
+
## Public task and hidden oracle boundary
|
|
67
|
+
|
|
68
|
+
An `AgentTask` contains only:
|
|
69
|
+
|
|
70
|
+
- an opaque ID and category
|
|
71
|
+
- the agent-visible goal and instructions
|
|
72
|
+
- public `claimKey`, tagged `valueType`, required, and substantive flags
|
|
73
|
+
- allowed tool names and call/context budgets
|
|
74
|
+
- opaque collection names available to the task
|
|
75
|
+
|
|
76
|
+
The outer agent receives the result of `projectAgentVisibleTask()` and normalized
|
|
77
|
+
tool results. It never receives the oracle, fixture manifest, setup paths,
|
|
78
|
+
adapter labels, or evaluation metadata.
|
|
79
|
+
|
|
80
|
+
The normalized tool contract is one deeply frozen `search`, `get`, and
|
|
81
|
+
`multi_get` schema shared by every adapter. An adapter declares unsupported or
|
|
82
|
+
unavailable capabilities without changing that schema. Result
|
|
83
|
+
`resultRole` is agent-visible and closed: `candidates` requires a subsequent
|
|
84
|
+
source read, `source` is an exact read, and `evidence_bundle` is complete enough
|
|
85
|
+
to support a one-call final envelope. The fixture agent responds to this role,
|
|
86
|
+
never to an adapter ID. A one-call-budget task may finalize exact candidate
|
|
87
|
+
evidence rather than exceed its budget.
|
|
88
|
+
|
|
89
|
+
A separate `HiddenOracle` contains normalized expected typed values,
|
|
90
|
+
normalizer ID/version, required/optional/forbidden evidence, expected missing
|
|
91
|
+
claims, collection/filter expectations, completion predicates, and hidden leak
|
|
92
|
+
canaries. Every task and oracle filename is an opaque ID. Validation scans every
|
|
93
|
+
agent-visible task, path, and corpus file for the oracle-only canaries.
|
|
94
|
+
|
|
95
|
+
Corpus text necessarily contains the evidence an agent is meant to retrieve;
|
|
96
|
+
the isolation guarantee concerns evaluator answers, normalizers, qrels,
|
|
97
|
+
completion predicates, and other oracle metadata.
|
|
98
|
+
|
|
99
|
+
## Structured final envelope
|
|
100
|
+
|
|
101
|
+
`FinalEnvelope` deliberately has no answer or prose field:
|
|
102
|
+
|
|
103
|
+
```json
|
|
104
|
+
{
|
|
105
|
+
"schemaVersion": "1.0",
|
|
106
|
+
"claims": [
|
|
107
|
+
{
|
|
108
|
+
"claimKey": "launchDate",
|
|
109
|
+
"value": { "type": "date", "value": "2026-09-14" },
|
|
110
|
+
"citations": []
|
|
111
|
+
}
|
|
112
|
+
],
|
|
113
|
+
"gaps": [],
|
|
114
|
+
"abstained": false,
|
|
115
|
+
"stopReason": "complete"
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Claim values are tagged unions: `string`, `number`, `boolean`, `string[]`,
|
|
120
|
+
`date`, or `identifier`. Dates are ISO calendar dates. Gaps use one of
|
|
121
|
+
`missing_evidence`, `conflicting_evidence`, `budget_exhausted`, or
|
|
122
|
+
`tool_unavailable`. Stop reasons are `complete`, `abstained`,
|
|
123
|
+
`budget_exhausted`, `tool_unavailable`, or `error`.
|
|
124
|
+
|
|
125
|
+
Strict parsing rejects comments, trailing commas, duplicate properties at any
|
|
126
|
+
depth, prose, and malformed tagged values. Semantic validation
|
|
127
|
+
then rejects unknown or duplicate claim/gap keys, value types that disagree with
|
|
128
|
+
the public claim definition, missing required claims, and uncited required
|
|
129
|
+
claims. Invalid output is scored as unsupported; it is never ignored.
|
|
130
|
+
|
|
131
|
+
## Exact evidence semantics
|
|
132
|
+
|
|
133
|
+
Evidence coordinates contain:
|
|
134
|
+
|
|
135
|
+
- `gno://<collection>/<relative-path>`
|
|
136
|
+
- lowercase SHA-256 of the source's exact UTF-8 bytes
|
|
137
|
+
- 1-based inclusive `startLine` and `endLine`
|
|
138
|
+
- lowercase SHA-256 of the exact selected span bytes
|
|
139
|
+
- separate source- and span-hash provenance
|
|
140
|
+
|
|
141
|
+
For line selection only, the fixture loader converts CRLF and lone CR to LF.
|
|
142
|
+
It then selects the inclusive lines and joins them with LF. It does not append a
|
|
143
|
+
synthetic final newline, trim whitespace, or normalize Unicode before hashing
|
|
144
|
+
the span. A source hash never performs newline or Unicode normalization.
|
|
145
|
+
|
|
146
|
+
Fixture corpus files are additionally required to already be stable under GNO's
|
|
147
|
+
production Markdown canonicalizer. That keeps production-ingested mirror line
|
|
148
|
+
coordinates aligned without changing the exact source-byte contract.
|
|
149
|
+
|
|
150
|
+
`harness_observed` means the harness derived the hash from exact observed bytes.
|
|
151
|
+
`backend_provided` means the adapter returned the hash. Normalized qmd results
|
|
152
|
+
will preserve these separately rather than synthesizing backend hashes from the
|
|
153
|
+
hidden oracle.
|
|
154
|
+
|
|
155
|
+
## Immutable corpus and native indexes
|
|
156
|
+
|
|
157
|
+
`loadAgenticFixture()` verifies every manifest hash, schema, task/oracle pairing,
|
|
158
|
+
evidence coordinate, span hash, leak canary, and corpus fingerprint. It exposes
|
|
159
|
+
one frozen `CorpusSnapshot` for all adapters.
|
|
160
|
+
|
|
161
|
+
An adapter builds its native immutable index during unmeasured preparation from
|
|
162
|
+
that snapshot. `recordAdapterNativeIndex()` binds each adapter-specific index
|
|
163
|
+
fingerprint and volatile build observations to the same corpus fingerprint.
|
|
164
|
+
Cross-adapter index bytes need not match.
|
|
165
|
+
|
|
166
|
+
`prepareGnoNativeIndex()` is the reference production-ingestion helper. It:
|
|
167
|
+
|
|
168
|
+
1. materializes the exact manifest-pinned bytes into a temporary root once;
|
|
169
|
+
2. opens an explicit temporary SQLite path with the production tokenizer;
|
|
170
|
+
3. registers the complete collection set;
|
|
171
|
+
4. runs production `SyncService` conversion, canonicalization, chunking, FTS,
|
|
172
|
+
tag, link, and relationship projection with deterministic concurrency one;
|
|
173
|
+
5. verifies processed/error counts and active document source hashes;
|
|
174
|
+
6. fingerprints stable URI/source/mirror/index inputs while excluding document
|
|
175
|
+
IDs, timestamps, temp paths, and timings.
|
|
176
|
+
|
|
177
|
+
It never loads or writes global GNO configuration or a production database.
|
|
178
|
+
Cold and warm cohorts for an adapter must reuse the same prepared native index.
|
|
179
|
+
|
|
180
|
+
## Trajectory receipts
|
|
181
|
+
|
|
182
|
+
A `TrajectoryReceipt` has two top-level partitions.
|
|
183
|
+
|
|
184
|
+
### Canonical
|
|
185
|
+
|
|
186
|
+
The canonical partition contains every decision-affecting input and output:
|
|
187
|
+
|
|
188
|
+
- task, adapter, trial, seed, lifecycle, and agent IDs
|
|
189
|
+
- normalized calls, arguments, results, evidence, and stable error codes
|
|
190
|
+
- distinct outer `agentCalls` and internal `backendInvocations`
|
|
191
|
+
- exact model-visible UTF-8 bytes for every tool result, including repeated
|
|
192
|
+
reads and model-visible errors
|
|
193
|
+
- measured token counts and tokenizer fingerprint, or `null` when unavailable
|
|
194
|
+
- structured final envelope, stop reason, and failure class
|
|
195
|
+
- explicit tool/span/token/hash/lifecycle capability states, including
|
|
196
|
+
`unsupported` and `unavailable`
|
|
197
|
+
- corpus, prompt, tools, model, runtime, config, and index fingerprints
|
|
198
|
+
|
|
199
|
+
The exact agent-visible result projection includes status, `resultRole`, content,
|
|
200
|
+
citeable observed coordinates/hashes/provenance, evidence text, and error code.
|
|
201
|
+
Adapter backend hashes, backend-hash diagnostics, call accounting, tokenizer
|
|
202
|
+
accounting, temp paths, and oracle data are excluded from both the agent history
|
|
203
|
+
and its UTF-8 byte count.
|
|
204
|
+
|
|
205
|
+
For Capsule evidence bundles, `content` is byte-for-byte the production MCP
|
|
206
|
+
`gno-context-agent-v1` text projection. Exact evidence is not duplicated in the
|
|
207
|
+
normalized evidence field. The benchmark charges the complete normalized
|
|
208
|
+
agent-visible envelope containing that text once; the full canonical Capsule
|
|
209
|
+
in MCP `structuredContent` is application-only and excluded. This target models
|
|
210
|
+
hosts that keep structured data outside model context. Hosts that expose both
|
|
211
|
+
text and `structuredContent` must charge both and cannot cite this promotion
|
|
212
|
+
result without a separate run.
|
|
213
|
+
|
|
214
|
+
Canonical JSON recursively sorts object keys by code-unit order, preserves array
|
|
215
|
+
order, and rejects `undefined`, non-finite numbers, and non-JSON values. It
|
|
216
|
+
excludes all observations. Unchanged deterministic inputs therefore produce
|
|
217
|
+
byte-identical canonical JSON and SHA-256.
|
|
218
|
+
|
|
219
|
+
`agentCalls` counts every valid outer-agent tool choice, including a choice
|
|
220
|
+
whose adapter call times out or throws, whose returned envelope is malformed,
|
|
221
|
+
or whose result is rejected before delivery by context/token accounting.
|
|
222
|
+
Each canonical call records `deliveredToAgent` and a nullable `failureCode`.
|
|
223
|
+
Undelivered calls retain a valid returned result and known backend invocation
|
|
224
|
+
count when available; otherwise they use a closed synthetic error result. They
|
|
225
|
+
always contribute zero model-visible bytes and have no per-call token
|
|
226
|
+
measurement. Aggregate measured tokens sum delivered calls only, preserving
|
|
227
|
+
any earlier measured context; with no delivered measured call, tokenizer
|
|
228
|
+
comparability remains `null`. The undelivered call is unique, terminal, bound
|
|
229
|
+
to the receipt failure code, and excluded from the outer-agent history.
|
|
230
|
+
`backendInvocations` counts adapter-internal
|
|
231
|
+
retrieval, fetch, rerank, or synthesis operations. Promotion efficiency uses
|
|
232
|
+
`agentCalls`; backend invocations are reported separately and cannot substitute
|
|
233
|
+
for them.
|
|
234
|
+
|
|
235
|
+
### Observations
|
|
236
|
+
|
|
237
|
+
The observations partition contains volatile data:
|
|
238
|
+
|
|
239
|
+
- recording timestamp
|
|
240
|
+
- preparation, startup, model-load, tool, driver, and end-to-end timings
|
|
241
|
+
- process/resource measurements
|
|
242
|
+
- temporary paths and redacted diagnostics, including volatile failure messages
|
|
243
|
+
|
|
244
|
+
Each timing is either `{ valueMs: <non-negative>, unavailableReason: null }` or
|
|
245
|
+
`{ valueMs: null, unavailableReason: <non-empty reason> }`. Changing an
|
|
246
|
+
observation cannot change the canonical receipt fingerprint.
|
|
247
|
+
|
|
248
|
+
Preparation/index build is outside both lifecycle cohorts. Cold end-to-end time
|
|
249
|
+
starts before fresh process startup against the prepared index and includes the
|
|
250
|
+
first scored call. Warm time starts at the first scored agent step after exactly
|
|
251
|
+
one discarded readiness probe on a preserved process/model/index. Reports never
|
|
252
|
+
compare unlike lifecycle states.
|
|
253
|
+
|
|
254
|
+
## Failure and cohort accounting
|
|
255
|
+
|
|
256
|
+
Failures are `harness_error`, `agent_error`, or `product_error`; successful
|
|
257
|
+
receipts use `none`. Harness failures are attempted pairs but are excluded from
|
|
258
|
+
product scoring with an explicit reason. They cannot silently reduce a cohort.
|
|
259
|
+
Malformed tool/final envelopes, duplicate JSON keys, timeouts, and unavailable
|
|
260
|
+
requested adapters fail closed. Adapter calls receive an `AbortSignal`; a timed
|
|
261
|
+
out or state-unknown warm call excludes the remaining cohort explicitly rather
|
|
262
|
+
than running alongside a leaked request. Deterministic agent errors do not
|
|
263
|
+
invalidate later warm pairs.
|
|
264
|
+
|
|
265
|
+
The runner rejects empty, duplicate, or malformed task, adapter, lifecycle, and
|
|
266
|
+
trial schedules before preparation. Every attached adapter must preserve its
|
|
267
|
+
prepared owner identity, config fingerprint, capability contract, and index
|
|
268
|
+
fingerprint. Preparation, reset, tool outcomes, runtime/session identities,
|
|
269
|
+
token measurements, agent steps, and tool arguments are closed runtime-validated
|
|
270
|
+
before they enter a receipt or reach a product adapter. Tool listing, session
|
|
271
|
+
construction, inference, calls, and best-effort disposal are bounded.
|
|
272
|
+
|
|
273
|
+
## Outer-agent lanes and lifecycle
|
|
274
|
+
|
|
275
|
+
The standard fixture agent is a pinned answer-free state machine. It selects one
|
|
276
|
+
preferred lexical cue per public claim, performs `search`, reads returned URIs
|
|
277
|
+
for candidate results, reduces exact observed lines into declared typed claims,
|
|
278
|
+
and stops or abstains within the public budgets. Ordinary candidates require a
|
|
279
|
+
`get` or `multi_get`; a complete evidence bundle can stop after one call.
|
|
280
|
+
|
|
281
|
+
The optional cached-local-model lane is fail-closed. `agent-model.lock.json`
|
|
282
|
+
pins one exact Hugging Face URI, whole-GGUF SHA-256 (also binding its embedded
|
|
283
|
+
tokenizer), tokenizer identifier, step/output budgets, and exactly three unique
|
|
284
|
+
paired trial IDs/seeds. `GNO_AGENTIC_MODEL_PATH` must point at that already
|
|
285
|
+
cached exact file. Preflight performs strict duplicate-safe JSON parsing and a
|
|
286
|
+
streaming SHA-256 check before model initialization. It never resolves a remote
|
|
287
|
+
endpoint, downloads a model, reads an API key, or falls back to the network.
|
|
288
|
+
Model output is one strict JSON tool action or `FinalEnvelope`; prose and
|
|
289
|
+
duplicate keys are agent errors.
|
|
290
|
+
|
|
291
|
+
## Product-faithful GNO MCP comparator
|
|
292
|
+
|
|
293
|
+
The `gno-mcp` adapter measures the shipped stdio MCP process rather than
|
|
294
|
+
importing a retrieval pipeline. Its normalized surface maps `search` to
|
|
295
|
+
`gno_query`, `get` to `gno_get`, and `multi_get` to `gno_multi_get`. The adapter
|
|
296
|
+
lists the real product tools during unmeasured preparation and fails closed if
|
|
297
|
+
any mapped field is missing from the shipped input schemas. It sets
|
|
298
|
+
`lineNumbers: false` on reads so exact returned bytes can be bound to fixture
|
|
299
|
+
line coordinates; this is a public MCP option, not an evaluator shortcut.
|
|
300
|
+
|
|
301
|
+
Preparation materializes the immutable corpus into an isolated config/data/
|
|
302
|
+
cache root, runs production ingestion, and embeds every active chunk before
|
|
303
|
+
scoring. `gno-models.lock.json` pins the exact embed, rerank, expansion, and
|
|
304
|
+
generation GGUF URI, byte size, and SHA-256. `GNO_AGENTIC_GNO_MODEL_DIR` may
|
|
305
|
+
point at a cache containing those exact files. The harness streams and verifies
|
|
306
|
+
all four files, rewrites the isolated config to `file://` URIs, passes
|
|
307
|
+
`--offline`, sets `HF_HUB_OFFLINE=1`, and rejects missing or mismatched vectors.
|
|
308
|
+
It never downloads a model or mutates the user's config/database/model cache.
|
|
309
|
+
|
|
310
|
+
Cold trials create a fresh stdio MCP process against the already prepared
|
|
311
|
+
index. Warm trials preserve one process and first issue exactly one discarded
|
|
312
|
+
`gno_query` readiness probe with `fast: true`; the probe must report
|
|
313
|
+
`vectorsUsed: true`. Process startup and tool latency are measured separately.
|
|
314
|
+
GNO does not expose model-load timing independently from its first query, so
|
|
315
|
+
that observation is explicitly unavailable rather than inferred.
|
|
316
|
+
|
|
317
|
+
Normalized candidate and source payloads strip absolute paths, mtimes, and
|
|
318
|
+
volatile error messages. Non-default-index URI decoration is removed because
|
|
319
|
+
the isolated adapter already owns one explicit index. Citeable evidence is
|
|
320
|
+
emitted only when returned text exactly matches the snapshot's inclusive line
|
|
321
|
+
span. Evidence is line-atomic even when GNO returns a multi-line chunk. Source
|
|
322
|
+
and span hashes are recomputed from observed fixture bytes. Because GNO does
|
|
323
|
+
not return a backend span hash, the closed backend hash pair is explicitly
|
|
324
|
+
unavailable; the product source hash remains in normalized candidate metadata.
|
|
325
|
+
Repeated reads remain repeated calls and bytes. Query backend invocation
|
|
326
|
+
accounting includes lexical/vector retrieval, expansion, reranking, and graph
|
|
327
|
+
stages declared by structured MCP metadata.
|
|
328
|
+
|
|
329
|
+
The native index may contain the whole fixture, but every reset establishes one
|
|
330
|
+
task visibility boundary. Single-collection searches are automatically scoped;
|
|
331
|
+
multi-collection tasks must name one of their declared collections. Foreign
|
|
332
|
+
collections and foreign `get`/`multi_get` URIs are rejected before MCP traffic,
|
|
333
|
+
and any foreign result returned by the product fails the trial without exposing
|
|
334
|
+
its content to the outer agent.
|
|
335
|
+
|
|
336
|
+
Fake-process tests are part of the normal offline suite. The isolated real
|
|
337
|
+
stdio smoke is opt-in with `GNO_AGENTIC_RUN_REAL_MCP=1`; it uses the exact model
|
|
338
|
+
lock and performs no network access. Successful MCP envelopes are validated
|
|
339
|
+
before normalization; malformed or source-hash-mismatched output fails closed.
|
|
340
|
+
Preparation cancellation is threaded through model verification, embedding,
|
|
341
|
+
and MCP preflight, with child termination and isolated-root cleanup.
|
|
342
|
+
|
|
343
|
+
## Optional pinned qmd comparator
|
|
344
|
+
|
|
345
|
+
The `qmd` lane is explicit opt-in and fail-closed. `QMD_REPO` must be an
|
|
346
|
+
absolute, clean checkout at commit
|
|
347
|
+
`e428df76bc0274d9e93eb7ca3e95673315c42e90`. Preflight verifies the exact
|
|
348
|
+
origin, commit, clean tree, package manifest, lockfile, executable entrypoint,
|
|
349
|
+
and the dynamically listed MCP tool name, description, and input-schema
|
|
350
|
+
fingerprints. It also verifies three pinned model identities by URI, filename,
|
|
351
|
+
native cache filename, byte size, and streamed SHA-256:
|
|
352
|
+
|
|
353
|
+
- `hf_ggml-org_embeddinggemma-300M-Q8_0.gguf`
|
|
354
|
+
- `hf_ggml-org_qwen3-reranker-0.6b-q8_0.gguf`
|
|
355
|
+
- `hf_tobil_qmd-query-expansion-1.7B-q4_k_m.gguf`
|
|
356
|
+
|
|
357
|
+
The lock deliberately does not claim a separately verifiable model-repository
|
|
358
|
+
revision: the already-cached GGUF identity is pinned by exact URI, native
|
|
359
|
+
filename, byte size, and whole-file SHA-256. The committed lock's raw bytes are
|
|
360
|
+
also SHA-256 pinned before any checkout or model validation, and that raw lock
|
|
361
|
+
identity is included in the adapter configuration fingerprint.
|
|
362
|
+
|
|
363
|
+
`QMD_MODEL_CACHE` may name an absolute read-only cache containing those exact
|
|
364
|
+
files. The adapter never resolves qmd from `PATH`, uses a global install,
|
|
365
|
+
downloads a model, pulls or checks out the repository, or mutates the checkout
|
|
366
|
+
or supplied cache. Missing, stale, dirty, mismatched, or schema-drifted inputs
|
|
367
|
+
are harness errors, never skips or degraded comparisons. The intentionally
|
|
368
|
+
strict preflight therefore fails until the exact checkout and model artifacts
|
|
369
|
+
have been prepared.
|
|
370
|
+
|
|
371
|
+
Preparation runs qmd's update, embed, and status lifecycle outside measured
|
|
372
|
+
trials, then verifies the native index. `QMD_CONFIG_DIR`, `XDG_CONFIG_HOME`,
|
|
373
|
+
`XDG_CACHE_HOME`, `INDEX_PATH`, and data paths are isolated under one temporary
|
|
374
|
+
root; locked models are copied and reverified there. Cold trials start a fresh
|
|
375
|
+
stdio process on a byte-identical clone of the pristine prepared database.
|
|
376
|
+
Warm trials retain one process after exactly one discarded full query using the
|
|
377
|
+
task goal, declared collections, `rerank: true`, and readiness-only intent so
|
|
378
|
+
models load without colliding with a scored query cache key.
|
|
379
|
+
|
|
380
|
+
qmd result ranges are parsed from the inner `@@` coordinates and accepted only
|
|
381
|
+
when returned bytes exactly match the fixture snapshot. Evidence is emitted as
|
|
382
|
+
atomic lines with harness-observed source and span hashes; backend hashes remain
|
|
383
|
+
the complete null pair with an explicit unavailable reason. The same pre-call
|
|
384
|
+
task scope and post-result isolation rules apply as for GNO. qmd does not expose
|
|
385
|
+
reliable internal backend invocation counts, model-load timing, or token
|
|
386
|
+
measurements, so invocation-accounting capability is `false`, its count is
|
|
387
|
+
zero with a diagnostic, and those observations remain explicitly unavailable.
|
|
388
|
+
|
|
389
|
+
Committed reports record attempted pairs, scored pairs, every exclusion,
|
|
390
|
+
receipts, identity-bearing task scores, Capsule replay proofs, exact
|
|
391
|
+
environment/methodology, and known limitations. The environment includes the
|
|
392
|
+
package and Bun versions, platform/architecture, Git commit/dirty state,
|
|
393
|
+
fixture version/fingerprint, selected agent, and trial schedule.
|
|
394
|
+
|
|
395
|
+
The report `canonicalFingerprint` hashes a non-self-referential projection:
|
|
396
|
+
the fingerprint field itself and volatile receipt observations are excluded;
|
|
397
|
+
environment provenance, methodologies, limitations, native index identities,
|
|
398
|
+
canonical receipts, identity-bearing scores, exclusions, Capsule payload bytes
|
|
399
|
+
and hashes, and promotion results remain included. `report.json` is schema
|
|
400
|
+
valid. `canonical.json` contains that exact projection. `observations.json`
|
|
401
|
+
holds environment, build observations, and full-identity receipt observations;
|
|
402
|
+
committed temporary paths are projected to `<temp>`. `report.md` is the readable
|
|
403
|
+
summary. The four files are staged and directory-renamed as one baseline set.
|
|
404
|
+
|
|
405
|
+
## Deterministic scoring
|
|
406
|
+
|
|
407
|
+
The scorer compares typed claims and exact citations with the hidden oracle. It
|
|
408
|
+
reports:
|
|
409
|
+
|
|
410
|
+
- completed and supported claims
|
|
411
|
+
- unsupported claims and invalid outputs
|
|
412
|
+
- missing required claims/evidence
|
|
413
|
+
- forbidden evidence
|
|
414
|
+
- correct abstention
|
|
415
|
+
- premature `complete` stops
|
|
416
|
+
- unnecessary reads from call/context budgets and, for designated tasks,
|
|
417
|
+
unexpected evidence
|
|
418
|
+
- collection and filter correctness
|
|
419
|
+
- substantive claims linked to complete supporting evidence
|
|
420
|
+
|
|
421
|
+
No LLM judge participates in these gates. Optional model judging may assess
|
|
422
|
+
prose in separate experiments, but cannot override deterministic promotion.
|
|
423
|
+
|
|
424
|
+
## Capsule promotion formulas
|
|
425
|
+
|
|
426
|
+
Promotion compares Capsule and current GNO only over the identical non-harness-
|
|
427
|
+
failed task/trial/seed/lifecycle/agent pair set `P`. Baseline adapter identity
|
|
428
|
+
must be exactly `gno-mcp`; candidate identity must be exactly `capsule`. Corpus,
|
|
429
|
+
prompt, tool, model, and runtime fingerprints must match. Adapter config and
|
|
430
|
+
native index fingerprints may differ by design. Every score record must match
|
|
431
|
+
its receipt identity.
|
|
432
|
+
|
|
433
|
+
For every pair:
|
|
434
|
+
|
|
435
|
+
```text
|
|
436
|
+
success_capsule(p) >= success_gno(p)
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
Aggregate accuracy must also have no loss:
|
|
440
|
+
|
|
441
|
+
```text
|
|
442
|
+
sum(success_capsule) / |P| >= sum(success_gno) / |P|
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
Efficiency gates are:
|
|
446
|
+
|
|
447
|
+
```text
|
|
448
|
+
1 - sum(agentCalls_capsule) / sum(agentCalls_gno) >= 0.25
|
|
449
|
+
1 - sum(modelVisibleUtf8Bytes_capsule) / sum(modelVisibleUtf8Bytes_gno) >= 0.35
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
Claim linkage is:
|
|
453
|
+
|
|
454
|
+
```text
|
|
455
|
+
linkedSupportedClaims_capsule / substantiveClaims_capsule >= 0.95
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
All denominators must be non-zero. Abstention-only tasks use their completion
|
|
459
|
+
predicate and do not fabricate substantive claims. Every fixture-agent Capsule
|
|
460
|
+
task must also emit byte-identical canonical Capsule payload JSON and matching
|
|
461
|
+
SHA-256 across the scored run and one unchanged-input replay. Empty,
|
|
462
|
+
non-canonical, wrong-task, or synthetic sentinel payloads fail. Missing pairs,
|
|
463
|
+
duplicates, identity mismatches,
|
|
464
|
+
pairwise or aggregate accuracy loss, denominator failure, threshold miss, or
|
|
465
|
+
nondeterminism fails promotion.
|
|
466
|
+
|
|
467
|
+
## Commands
|
|
468
|
+
|
|
469
|
+
Contract tests are ordinary offline tests:
|
|
470
|
+
|
|
471
|
+
```bash
|
|
472
|
+
bun test test/eval/agentic
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
The runner is local and opt-in:
|
|
476
|
+
|
|
477
|
+
```bash
|
|
478
|
+
bun run eval:agentic
|
|
479
|
+
bun run eval:agentic -- --adapter gno-mcp,lexical,capsule --task t0a1b2c3 --lifecycle cold --agent fixture --timeout-ms 30000
|
|
480
|
+
QMD_REPO=/path/to/pinned/qmd QMD_MODEL_CACHE=/path/to/cache bun run eval:agentic -- --adapter qmd
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
Filters are CSV lists and reject empty, duplicate, or unknown values before
|
|
484
|
+
adapter preparation. Defaults are all tasks, `gno-mcp,lexical,capsule`, both
|
|
485
|
+
lifecycles, and the fixture agent. qmd is lazily registered and never runs by
|
|
486
|
+
default. A requested unavailable qmd lane produces the complete requested
|
|
487
|
+
harness-error matrix/report and exits `2`; it never disappears or downgrades.
|
|
488
|
+
|
|
489
|
+
Exit `0` means a complete run and, when applicable, passing promotion. Exit `1`
|
|
490
|
+
means the complete Capsule promotion gate failed. Exit `2` means invalid CLI,
|
|
491
|
+
preflight, harness, or requested-adapter failure. `--write` accepts only a full
|
|
492
|
+
24-task/two-lifecycle lane: the fixture-agent three-adapter lane writes the
|
|
493
|
+
authoritative baseline, while qmd and the three-trial cached-local-model lane
|
|
494
|
+
write only under `baseline/optional/`. Filtered or mixed writes are refused and
|
|
495
|
+
can never overwrite the authoritative baseline.
|
|
496
|
+
|
|
497
|
+
## Limitations
|
|
498
|
+
|
|
499
|
+
- The corpus is controlled regression evidence, not a representative claim
|
|
500
|
+
about every agent, domain, or language.
|
|
501
|
+
- The deterministic fixture agent will be narrower than a general model.
|
|
502
|
+
- Model-visible UTF-8 bytes are the primary cross-adapter context measure;
|
|
503
|
+
tokens compare only under one pinned tokenizer.
|
|
504
|
+
- Latency remains environment-specific and only compares matching lifecycle
|
|
505
|
+
cohorts.
|
|
506
|
+
- qmd is an optional exact-revision comparator and is never required by the
|
|
507
|
+
standard test suite.
|
|
508
|
+
- Capsule retrieval/planning remains a deterministic fixture prototype; its
|
|
509
|
+
model-visible serializer and omission accounting are the production MCP
|
|
510
|
+
contract.
|