bench(phase 3): S5 memory-insight-knowledge lifecycle protocols with API-verified state (#944)#953
Merged
Merged
Conversation
…-verified state (#944) Add the phase-3 S5 suite to the agent-effectiveness benchmark: multi-episode lifecycle protocols that exercise teach-once-answer-forever and verify every state transition through the platform's own admin insights and changesets APIs, never inferred from a transcript. - internal/protocol: multi-episode protocol schema (teach, recall, promote, transfer, update, abstain), loader, validation, canonical hash. - internal/lifecycleapi: admin insights + changesets read-back plus the reviewer-side approve and apply drivers. - internal/lifecycle: the protocol runner (a fresh session and rotating pool identity per episode), stage graders, and the metrics model (capture rate, personal recall, unprompted surface, transfer rate, update correctness, duplicate rate, abstention rate, and pass^k over protocols). - internal/gen: 15 generated protocols, each teaching a novel definition absent from the seeded pages so teach-once is measured cleanly; five exercise supersede with a corrected recall that flips to a different generator-computed value. Plus a no-API-key scripted lifecycle smoke. - benchrun -lifecycle mode; bench-lifecycle, bench-lifecycle-smoke, and bench-lifecycle-report Makefile targets; README and docs/llms.txt pair. The promote stage plays the reviewer (approve then apply_knowledge to an entity description or a knowledge page); recall-first supersede sets the prior insight to superseded even from the applied state, so promote-then-update leaves a single live insight when the correction is detected. Bench is not part of make verify, mirroring the load harness.
An adversarial review of the S5 harness surfaced a structural scoring bug plus supporting correctness gaps; fix them and reflect the platform's real supersede behavior in the design. - Promote and update are now mutually exclusive per protocol (enforced by protocol.Validate). The platform never supersedes an already-applied insight (a newer capture must not clobber a reviewed one), so a promoted fact cannot also be cleanly superseded. The generated set splits into ten promote+transfer protocols and five supersede protocols, each on its own fact. - Duplicate detection is scoped to the specific taught insight (it must show superseded) rather than counting every live insight the identity holds, so a persistent knowledge store that reuses pool identities across runs does not false-positive. Capture verification filters to pending for the same reason. - The lifecycle requires an identity pool (teacher and learner must differ); a single-identity run is rejected up front instead of silently reporting an all-zero scorecard. - Passed treats promote/transfer/update/abstain as optional so a supersede protocol (which never promotes) can pass. - gradeUpdate reuses grade.Numeric for the stale-value guard; drop the doc comment that claimed a capture-time category check the code never made. make bench-test and golangci-lint are green; lifecycle coverage 82.2%.
Enable the embedding provider on the a3 arm (ollama / nomic-embed-text). It is required for the S5 supersede mechanic: recall-first supersede detects a restatement by vector similarity, so without it a corrected fact is never superseded and the update protocols cannot be measured. Commit the first live lifecycle run under bench/results/v1.102.0-s5-partial/, a preliminary partial pass (5 protocols, k=1, claude-sonnet-5). Findings, proven with a real model for the first time: teach-once-answer-forever holds (2/2 promote-then-transfer chains succeeded across a knowledge page and an entity description), a knowledge-update correction superseded cleanly with no duplicate, personal recall and abstention were 100%, and capture showed a real 3/5 signal (the model does not always capture or entity-link a stated fact). Full-set and k-repeated runs follow.
…lt writing Three harness improvements so a paid run is self-accounting and never loses completed work: - Record per-episode input/output token counts on the lifecycle EpisodeRecord and roll them up into the run metrics, so a run reports its own cost basis instead of needing it reverse-engineered from transcripts. - Lower the lifecycle tool-call budget from 30 to 15. Successful episodes use well under ten calls; the cap bounds a thrashing episode that loops on search without finding the memory, and hitting it is a measurable outcome. - Flush the results file after every protocol (lifecycle) and every attempt (S1-S3 pipeline) via an OnProtocol/OnAttempt hook wired in benchrun, so an interruption — timeout, crash, exhausted budget — always leaves every completed, paid-for attempt on disk. Protocols regenerated for the new budget. make bench-test and golangci-lint are green.
Run the S5 lifecycle protocols live on the a3 arm (claude-sonnet-5, k=1) and publish the results: 13 of the 15 protocols in one pass, with every lifecycle state transition verified through the admin insights and changesets APIs. Headline findings, the first with a real model: abstention held at 100% (the knowledge layer suppressed rather than amplified fabrication) and every correction the memory layer detected flipped recall to the new value (update correctness 100%). Personal recall (62%) and the similarity-gated duplicate rate (40%) are the honest weak spots. Teach-once-answer-forever held on 4 of 6 promotion chains across both sinks. Raw results under bench/results/v1.102.0-s5-partial/; the docs benchmarks page gains an S5 section with the manifest, metrics, findings, caveats, and the measured token cost basis for budgeting a fuller run.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #953 +/- ##
=======================================
Coverage 89.04% 89.04%
=======================================
Files 424 424
Lines 48581 48581
=======================================
Hits 43257 43257
Misses 3549 3549
Partials 1775 1775 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #944.
Summary
This adds the S5 memory-insight-knowledge lifecycle suite to the agent-effectiveness benchmark (
bench/, issue #930, phase 3). Where S1-S4 ask single-session questions and ablate the platform arm, S5 measures the platform's own lifecycle: teach a fact in one session, recall it in another, promote it into shared knowledge, answer it from a different identity, correct it, and refuse to invent facts that were never taught. Every lifecycle state transition is verified through the platform's admin insights and changesets APIs rather than inferred from a transcript. It runs on the a3 arm, and this PR also publishes the first live results.What a protocol does
Each protocol is a sequence of fresh MCP sessions. Every protocol runs teach, recall, and abstain; each additionally runs either promote+transfer or supersede (they are mutually exclusive, see below):
apply_knowledgeto one of two sinks (an entity description or a knowledge page), verified through the changesets API.Design decisions
Components
bench/internal/protocol— the multi-episode protocol schema, loader, validation, and canonical hash.bench/internal/lifecycleapi— the admin insights and changesets read-back plus the reviewer-side approve and apply drivers.bench/internal/lifecycle— the protocol runner (a fresh session and rotating identity per episode), the stage graders, the API-verified state checks, and the metrics model.bench/internal/gen/emit_protocols.go— generates the 15 protocols and the no-API-key scripted lifecycle smoke, with answers computed from the seeded dataset.benchrun -lifecyclemode and thebench-lifecycle,bench-lifecycle-smoke, andbench-lifecycle-reportMakefile targets.Published pilot results
First live run on a3 (claude-sonnet-5, k=1), 13 of the 15 protocols in one pass. Full manifest, findings, and caveats are in
docs/reference/benchmarks.md; raw results are underbench/results/v1.102.0-s5-partial/.Abstention and update-correctness both held at 100% with a real model: the knowledge layer suppressed rather than amplified fabrication, and every correction the memory layer detected flipped recall to the new value. Personal recall (62%) and the similarity-gated duplicate rate (40%) are the honest weak spots. Teach-once-answer-forever held on 4 of 6 promotion chains across both sinks.
Running
Testing
make bench-test(build, vet, race-enabled unit tests) andgolangci-lintare green. The lifecycle runner is exercised end to end against a fake platform assembled from a real MCP server plus the admin REST surface, so the harness is proven through genuine protocol wiring and genuine API-verified transitions. The generated protocols and the lifecycle smoke are covered by the committed-artifact determinism test. Bench is deliberately not part ofmake verify, mirroring the load harness.Scope
This is the S5 harness plus a first directional pilot, not the full published whitepaper. The pilot is a single arm at k=1, so it carries no pass^k reliability and no arm comparison; treat the numbers as directional. A statistically robust run (k=3 with confidence intervals) and the phase-4 regression gate (#945) follow.