Conversation
… it (#1451) #1451 asks for a number: how many of the later successes a semantic dedup key would suppress, against #1328's name-key baseline of 44 killed successes out of 109 blocked proposals. The replay is here; the number is not, and this commit records why in a form that can be re-run. scripts/replay_semantic_dedup.py rebuilds the historical candidate set from the ledger alone (append-only, rotated, retained) and reproduces #1328's published "prior failed outcome on (demand_id, target_path)" row exactly: 122 blocked, 51 later successes, 27 partials, over the same 2026-07-12 to 2026-09-06 window the original measurement used. Narrowing that to the bridge's own real-failure criterion -- the 109/44 row the issue names as the comparison set -- needs bridge._is_real_result applied to each prior's result artifact, and those are pruned. Of the 122 priors, 77 have no surviving artifact (2026-07-21 to 2026-08-17), so the set size is bounded [33, 110] rather than known: an unaudited prior might have been a blocked stub. The audit subcommand reports that and exits non-zero, and score() is not reachable without it, so a partially adjudicable population cannot be scored and presented as the one the issue names. The similarity threshold is fixed in code before any scoring, as a rule rather than a constant: block iff cosine >= the 99th percentile of the corpus's own unrelated-pair null distribution. Reasoning in the module header -- asymmetric cost (#1328: a falsely suppressed live task costs more than a paid duplicate) and model independence. A test asserts the ShinkaEvolve 0.95 appears nowhere in the executable code, which #1451 rules out explicitly. No embedding calls were made: 0 texts, 0 requests. The budgeted ~218 would have scored a population that cannot be shown to be the one the baseline describes. Script and test only. No runtime wiring, no proposer change. Refs #1451, #1328.
3 tasks
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.
Refs #1451. Measurement issue: the deliverable is a number and a recommendation. The replay is here; the number is not, and this PR makes the reason reproducible rather than a claim in a comment.
What the script does
scripts/replay_semantic_dedup.py, four separable stages, all read-only:extractauditembedscoreStage 2 is a gate, not a formality:
scoreis unreachable without it, so a partially adjudicable population cannot be scored and presented as the population the baseline describes.It reproduces #1328 exactly, then stops
122 / 51 / 27 is #1328's published "prior
failedoutcome, same (demand id, path)" row, to the row. The extraction is therefore the same one, not a second invention.The 109 / 44 row the issue names as the comparison set is the stricter one: prior real failure per the bridge's own criterion, which is
bridge._is_real_resultapplied to the prior's result artifact. Those are pruned:The set size is bounded, not known, because an unaudited prior might have been a blocked stub. Detail and the missing field list are in the issue comment.
The threshold, fixed in code before any scoring
NULL_PERCENTILE = 99.0. The rule: block iff cosine ≥ the 99th percentile of the corpus's own unrelated-pair null distribution, where a pair is unrelated when it shares neitherdemand_idnortarget_path.A rule rather than a constant, for two reasons stated in the module header. Asymmetric cost: #1328's standing rule is that a falsely suppressed live task costs more than a paid duplicate, and a percentile states the false-block rate against unrelated work directly. Model independence: a hardcoded cosine silently becomes a different rule when the gateway's embedding model changes, and proposal titles from one repository share vocabulary and paths, so their similarity floor is high and unknown in advance.
#1451 rules out importing 0.95 from the ShinkaEvolve ablation. A test asserts that value appears nowhere in the executable code — the module header names it only to record the refusal, and the test strips comments before checking.
Embedding cost
0 texts, 0 requests, no gateway call. The budgeted ~218 would have scored a population that cannot be shown to be the one the 40.4% baseline describes.
embed_textscounts texts and requests separately (batching reduces requests, never texts) and refuses a short gateway response rather than padding it; both are covered by tests with a fake client.Tests
tests/test_replay_semantic_dedup.py, 31 tests, all passing:skipped-*is the dedup stack working and not a failure, gz archives and the live file are both read, a torn last line is skipped not fatal,--untilreproduces a historical window;is_real_resultagrees withnanobot.runtime.bridge._is_real_resultcase by case (ported so the script runs against a field dump without the runtime on the path, so the agreement is asserted rather than assumed);Script and test only. No runtime wiring, no proposer change, nothing written on the host.
🤖 Generated with Claude Code