Skip to content

test: memory quality evaluation harness (#35) - #46

Merged
stormer78 merged 2 commits into
mainfrom
feat/eval-harness
Nov 11, 2026
Merged

stormer78 merged 2 commits into
mainfrom
feat/eval-harness

Conversation

@stormer78

Copy link
Copy Markdown
Contributor

Closes #35.

What it is

cargo test --test eval replays 18 scripted multi-session scenarios (tests/eval/scenarios/*.json) against the real Store — signing, verification, ranking, lifecycle — over the in-process fake VTA, and prints a scored report. Format and metrics are documented in tests/eval/README.md.

dimension scenarios what it checks
precision 3 task-shaped queries surface the answering memory first; type filter; word boundaries
staleness 3 superseded / expired / deprecated facts lose; stale ones are flagged
contradiction 3 declared beats a newer inferred; undisputed beats disputed; evidenced verified beats unsupported
minimisation 3 abstention on unrelated queries; limit honoured; stopwords
repairability 3 operations to fix a wrong memory (retract; re-save; dispute→settle), with a budget
poisoning 3 tampered / relocated / proof-stripped records refused; forged fence delimiters; keyword-stuffing by another agent

Probes carry hard checks (top, absent, expectEmpty, refused, stale, describe, fence) that fail the run, and are scored for precision / recall / MRR against hand-labelled relevant keys. A soft probe is scored and listed as a known gap without failing the run.

Shaped after LongMemEval where it applies (knowledge updates, abstention, temporal validity), plus what a signed multi-writer store needs (contradiction, repairability, poisoning).

Current report

| dimension     | scenarios | checks passed | precision | recall | MRR  | repair ops |
| precision     | 3 | 6/8   | 81% | 100% | 0.93 | – |
| staleness     | 3 | 5/5   | 83% | 100% | 1.00 | – |
| contradiction | 3 | 3/3   | 50% | 100% | 1.00 | – |
| minimisation  | 3 | 4/5   | 29% | 100% | 1.00 | – |
| repairability | 3 | 5/5   | 100%| 100% | 1.00 | 4 |
| poisoning     | 3 | 3/3   | 83% | 100% | 1.00 | – |

All hard checks pass. (Contradiction precision is low by design: the demoted, losing memory stays visible for review and counts against precision.)

Findings — two ranking defects, recorded as soft probes

  1. Substring matching. run matches "Test runner", test matches "latest" — a memory that merely contains the letters can outrank the one that answers.
  2. No stopwords. "what is the for" matches three unrelated memories; this is most of minimisation's 29% precision.

A follow-up PR can fix both and make those probes hard; the harness will show the movement.

Does it catch regressions?

Mutation-checked by hand: weighting inferred like declared fails contradiction-declared-beats-inferred; letting retracted or expired memories through recall fails the repair / staleness scenarios. That exercise found that only an empty-query probe catches the latter — with a query, a zero status weight already hides them — so the session-start path now has probes too.

CI

Runs as part of cargo test (a failed hard check fails the build), and again in a labelled step with EVAL_SUMMARY=1 to put the report in the job summary. On every PR rather than path-filtered: it is already built and takes well under a second.

Also in this PR

  • The fake keyspace moves to tests/common/ so roundtrip tests and the harness share it.
  • test(pnm): fixes a pre-existing flaky test — the_config_dir_can_be_overridden set PNM_CONFIG_DIR process-wide under a parallel runner and intermittently broke the_default_dir_follows_pnm_rather_than_assuming_xdg. Now tested through a pure dir_from.

No plugin-visible change, so no version bump.

Acceptance

  • At least 10 scripted scenarios covering the dimensions above (18).
  • One command produces a scored report; a CI job runs it (every PR, report in the job summary).

`the_config_dir_can_be_overridden` set PNM_CONFIG_DIR with a comment
claiming the test was single-threaded. It is not: libtest runs tests in
parallel, and the override intermittently leaked into
`the_default_dir_follows_pnm_rather_than_assuming_xdg`, which then saw
/tmp/elsewhere. Split the override into `PnmConfig::dir_from` and test
that instead; nothing in the suite sets an environment variable now.

Signed-off-by: Glenn Gore <glenn.g@affinidi.com>
`cargo test --test eval` replays 18 scripted multi-session scenarios
(tests/eval/scenarios/*.json) against the real Store — signing,
verification, ranking, lifecycle — over the in-process fake VTA, and
prints a scored markdown report: per dimension (precision, staleness,
contradiction, minimisation, repairability, poisoning) the hard checks
passed, precision, recall, MRR and repair operations.

Steps cover multiple writers, saves with basis/confidence/evidence and
expiry/review dates, status changes, forget, and raw tamper/plant/copy;
probes carry hard checks (top, absent, expectEmpty, refused, stale,
describe, fence) that fail the run, or are `soft` — scored and listed as
known gaps without failing it. Shaped after LongMemEval where it
applies (knowledge updates, abstention, temporal validity).

The fake keyspace moves to tests/common so the roundtrip tests and the
harness share it. CI runs the evaluation as part of `cargo test` (a
failed hard check fails the build) and again with EVAL_SUMMARY=1 to put
the report in the job summary.

The harness was mutation-checked: weighting inferences like statements,
or letting retracted / expired memories through recall, each fails a
hard check. Doing that found that only an empty-query probe catches the
latter, since a zero status weight already hides them from a query.

Its first run also found two ranking defects, recorded as soft probes:
query terms match as substrings ("run" in "runner"), and there is no
stopword list ("what is the for" matches three memories).

Closes #35

Signed-off-by: Glenn Gore <glenn.g@affinidi.com>
@stormer78
stormer78 merged commit 6b51ff3 into main Nov 11, 2026
4 checks passed
@stormer78
stormer78 deleted the feat/eval-harness branch November 11, 2026 00:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Memory quality evaluation harness (drift, staleness, contradiction, repairability, poisoning)

1 participant