feat(bench): cold-start knowledge-growth suite (#963)#967
Merged
Conversation
Add a cold-start knowledge-growth benchmark that measures the platform getting smarter as knowledge accumulates. It boots the a3 arm against an empty enrichment layer (undocumented DataHub, no knowledge pages), teaches a six-lesson curriculum (one fact per S3 trap class, promoted to the same DataHub descriptions and knowledge pages the A2 seed pre-loads), and re-runs the fixed S3 trap suite with a fresh, never-taught evaluator identity after each promotion. The result is a learning curve of accuracy, per-trap-class resistance, and enrichment coverage as promoted knowledge accumulates toward the A2 fact-bearing ceiling, exercising the coupling between the lifecycle and the enrichment layer end to end. - internal/curriculum: curriculum schema, loader, and set hash - internal/coldstart: curriculum runner, fresh-evaluator eval loop, learning-curve metrics, and results model - internal/promote: shared reviewer-promotion path (approve + apply_knowledge + verify), extracted so S5 lifecycle and cold-start share one implementation - gen: empty-DataHub emitter (bench_mces_empty.json) plus the curriculum and scripted-smoke generators; committed artifacts are drift-checked - auditapi: enrichment-coverage ratio (EnrichedCalls/AuditedCalls) - benchrun -cold-start mode; Makefile bench-cold-start / -smoke / -report, bench-seed-datahub-empty, and BENCH_SEED_PAGES=0 for the empty baseline - docs: bench/README, benchmarks.md, llms.txt, llms-full.txt A real learning-curve run is gated by model budget; the whole loop is validated with no API key by make bench-cold-start-smoke.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #967 +/- ##
=======================================
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.
Summary
Adds a cold-start knowledge-growth suite to the agent-effectiveness benchmark (
bench/). Where S1-S3 and S5 ablate the platform with a pre-seeded knowledge base, this suite starts from an empty enrichment layer and measures the platform getting smarter as knowledge accumulates: a learning curve whose independent variable is the amount of promoted, shared knowledge, holding the model, prompt, task set, and dataset constant.It is the highest-value item of the #958 epic (part 1 of 4; siblings #964, #965, #966 remain open).
What it measures
The suite runs on the
a3arm against an empty baseline: an undocumented DataHub (seed/datahub/bench_mces_empty.json, entities present but no descriptions, column docs, tags, or glossary) and no knowledge pages (bench-upwithBENCH_SEED_PAGES=0). Over an ordered curriculum of six lessons, one per S3 trap class, the harness:memory_capture), then promotes it to its sink throughapply_knowledge: a DataHub entity description (units, freshness, deprecation) or a portal knowledge page (net-revenue policy, fiscal calendar, tier definitions). Each lesson teaches the same S3 trap fact the A2 seed pre-loads, so the trap suite reaches its A2 accuracy ceiling once all six are promoted. Capture and promotion are verified through the admin insights and changesets APIs, never inferred from transcripts.searchfor the page-sink facts), so accuracy climbs only because promotion pushed the fact into shared knowledge. This isolates the delivery of promoted knowledge, the coupling between the lifecycle and the enrichment layer, not an evaluator's own memory.The report (
make bench-cold-start-report) is a learning curve: per checkpoint (indexed 0 for the empty baseline through 6 after the last promotion) it prints the eval set's accuracy and enrichment coverage against the count of lessons promoted so far, followed by a per-trap-class baseline-to-final breakdown showing which lesson unlocked which class. Enrichment coverage is the fraction of tool calls whose response carried cross-enrichment, read from the audit trail.Changes
internal/curriculuminternal/coldstartinternal/promoteapply_knowledge+ verify), extracted so S5 lifecycle and cold-start share one implementation (new, 82.4% covered)internal/lifecyclepromotepackage; behavior preserved (the pre-extraction approve note string is retained)internal/genbench_mces_empty.json), curriculum generator, and scripted-smoke generator; committed artifacts are drift-checkedinternal/auditapiMetrics.EnrichmentCoverage()(EnrichedCalls / AuditedCalls), no new audit fieldsbenchrun-cold-startrun mode and-cold-start -summarizeMakefilebench-cold-start/-smoke/-report,bench-seed-datahub-empty, andBENCH_SEED_PAGES=0onbench-upfor the empty baselinedocs/bench/README.md,docs/reference/benchmarks.md,docs/llms.txt,docs/llms-full.txtCommitted generated artifacts:
bench/curriculum/cs-traps.yaml,bench/curriculum/scripted-cold-start-smoke.json,bench/seed/datahub/bench_mces_empty.json. Regenerate withmake bench-gen; a drift test fails if they diverge from the fixed-seed generator.Design notes
The curriculum reuses the exact facts and knowledge-page bodies the A2 seed encodes, so the promoted description text is byte-identical to A2's for the entities it touches and the trap suite's ceiling is the A2 level.
apply_knowledgerestores the fact-bearing description and page channels but not A2's auxiliary aspects (globalTags, the structured deprecation aspect, column-level docs); the S3 traps read the fact text, which is restored.Lesson order is the curve's x-axis, run foundational-first (units before net-revenue, then the calendar / freshness / tier / deprecation facts), so a multi-fact trap flips to correct only once every fact it needs has landed.
Identity assignment keeps teachers and evaluators disjoint: a distinct teacher per lesson (so capture verification is cleanly scoped to that lesson's insight) and fresh evaluators per checkpoint. A run refuses to start when the lessons plus per-checkpoint evaluators exceed the identity pool.
Validation
TestColdStartCurveClimbs) wires the realRunover a fake platform (a real MCP server plus the admin insight/changeset/audit REST) and asserts the curve climbs[0, 0.5, 1]as lessons are promoted, proving the teach -> capture -> promote -> eval loop is correctly assembled.a3platform: 0 harness failures, 6/6 lessons captured and promoted (6 real changesets across both sink types), 25 eval tasks x 7 checkpoints graded.make bench-test(build, vet, race tests) andgolangci-lint run ./...(0 issues),make doc-checkOK.A real model-driven learning-curve run is gated by model budget; the whole loop is validated with no API key by
make bench-cold-start-smoke. The suite supports the subscriptionclaude-clipath as well (make bench-cold-start LLM=claude-cli MODEL=sonnet K=1).How to run
Notes for reviewers
bench/is a separate Go module, deliberately excluded from rootmake verify(same rationale astest/load); its gates aremake bench-testand its owngolangci-lint. This PR touches no root-module Go code.Closes #963.