Write each reuse verdict where something actually reads it - #21
Merged
Merged
Conversation
Every verdict this plugin has produced went nowhere. The Proxy forwards /asset/reuse-result to the Hub, the Hub has no such route -- its OpenAPI describes 407 paths under /a2a/ and none of them is this one -- and the Proxy has no ingestor of its own, so nothing was written locally either. On this machine root_events.jsonl holds 1873 value.inject lines and zero value.reuse_* lines: the injection half has been recording all along and the return half never existed. The consumers were never the problem. summarizeReuseOutcomes and pruneCandidates are written and correct, and orchestrator.ts folds their counts into a soft re-order of future candidates under EVOLVER_REUSE_SIGNAL, which defaults on. All of it reads local root events. It was simply starved. So the verdict is now written to both: the Proxy as before, and a root event through evolver-core's Ingestor -- value.reuse_hit for a success, and value.reuse_outcome carrying the verdict otherwise, which is the split the accounting expects. A report counts as delivered when either ledger took it, so a Hub without the route no longer leaves an asset pending forever. This adds the plugin's first runtime dependency. @evomap/evolver-core is not optional for this: Ingestor is the repository's single write entrypoint for root events, and EventStore -- single-writer, file-locked, monotonic seq, fsync, schema-validated, 4096-byte lines -- is deliberately not exported. Hand-rolling the append would be forging the one thing that file guarantees. It is imported lazily inside a catch, so an install that cannot resolve it degrades to the old behaviour instead of breaking a turn. The koffi native dependency it lists is loaded lazily from a benchmark module this path never touches; the global install here does not have koffi at all and works. cycleId is dsh:<sessionId>. deriveReuseEntries drops an entry missing either audit anchor, and a task id is neither. Verified end to end against the live Proxy before wiring: two events written, read back, pruneCandidates naming the failed asset. Three tests cover it; neutering the local write fails the one that matters. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Bugbot is paused — on-demand spend limit reachedBugbot uses usage-based billing for this team and has hit its on-demand spend limit. A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue. |
forrestlinfeng
added a commit
that referenced
this pull request
Sep 23, 2026
The slow-prime test asserted the step returned within 120ms against a server that answers in 150ms -- a 30ms margin on shared CI. It went red on main right after #21 and passed on a rerun, which is the definition of a test that reports the runner's load rather than the code. The assertion below it already proves the thing: a step that waited for the slow search would come back carrying its strategy, so an empty `primed` is the evidence. Raising the wait budget until the step really does wait still fails the test with the stopwatch gone. #21 made the suite heavier -- evolver-core is imported for the root-event write -- so a margin that was always thin was going to keep flaking. Co-authored-by: forrestlinfeng <linfengchen@tencent.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
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.
The problem, in one number
On this machine:
Every verdict this plugin has produced went nowhere:
/asset/reuse-resultto the Hub, and the Hub has no such route — its OpenAPI describes 1353 paths, 407 under/a2a/, none of them this one. A live probe returns{"recorded": false, "reason": "hub 404"}.proxyDaemonhas no ingestor, so nothing was written locally either. Thevalue.reuse_hitwrite lives on the MCP tools path, which this plugin does not use.The consumers were never missing
summarizeReuseOutcomesandpruneCandidatesare written and correct, the actuator is wired, andEVOLVER_REUSE_SIGNALdefaults on. All of it reads local root events, not the Hub. It was simply starved.What changes
Each verdict is written to both ledgers:
successvalue.reuse_hit— the $ railfailed/mismatched/stale/unsafevalue.reuse_outcome— the keep/prune railThat split is what the accounting expects;
summarizeReuseOutcomesreads success from one and the negatives from the other.A report counts as delivered when either ledger took it, so a Hub without the route no longer leaves an asset pending forever.
The first runtime dependency, and why it is not optional
@evomap/evolver-corepinned at2.0.38.Ingestoris the repository's single write entrypoint for root events, andEventStore— single-writer, file-locked, monotonic seq, fsync, schema-validated, 4096-byte lines — is deliberately not exported. Hand-rolling the append would forge the one thing that file guarantees.Mitigations:
koffinative dependency it lists is loaded lazily frombenchmark/referenceNativeRuntime.ts, which this path never touches.events/andops/never reference it, and the global install here does not have koffi at all and works — which matters, since the dsh profile setsallowBuilds: { koffi: false }cycleIdisdsh:<sessionId>.deriveReuseEntriesdrops any entry missing either audit anchor (assetId+cycleId), and a task id is neither.Verification
Before wiring anything, end to end against the real environment:
Three tests. Neutering
recordReuseLocallyfails the one that matters. 92/92.🤖 Generated with Claude Code