Fix PR #47 review findings - #48
Conversation
- Doppler: abandon horizon doubles when a dropped seed returns; a fixed horizon thrashed once the corpus cycle outlasted it. - Seed-arm corpus memo: hits re-validated by slot identity, misses not memoized; length-keyed memo went stale on in-place trims. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Rvj2gdMAa4HA8MGHULfDJE
Reviewer's GuideFixes two PR #47 review findings: Doppler now self-widens its stale-frame horizon only for returning, previously dropped seeds using bounded memory, while corpus-membership memo hits are validated against list and slot identity so in-place trims and rebuilds cannot produce stale results. Documentation and changelog entries are updated, with regression and adversarial tests for both behaviors. Sequence diagram for Doppler horizon self-wideningsequenceDiagram
participant Scheduler
participant Doppler
participant DroppedKeys
Scheduler->>Doppler: observe(seed_key, hits)
Doppler->>Doppler: _ticks += 1
Doppler->>Doppler: pop open frame
alt frame was dropped previously
Doppler->>DroppedKeys: check seed_key
DroppedKeys-->>Doppler: key found
Doppler->>DroppedKeys: delete seed_key
Doppler->>Doppler: _stale_after *= 2
else frame is new
Doppler->>DroppedKeys: check seed_key
DroppedKeys-->>Doppler: key absent
end
Doppler->>Doppler: _admit()
Doppler-->>Scheduler: record observation or refuse
Sequence diagram for identity-validated corpus memosequenceDiagram
participant Fuzzer
participant Corpus
participant SeedPicker
Fuzzer->>Fuzzer: _in_corpus(parent)
alt memo parent and corpus list match
Fuzzer->>Corpus: validate memoized slot identity
alt slot still contains memoized seed
Corpus-->>Fuzzer: identity valid
Fuzzer-->>Fuzzer: return True
else list was trimmed or replaced
Corpus-->>Fuzzer: identity invalid
end
else no reusable memo hit
Fuzzer->>SeedPicker: _corpus_keys()
SeedPicker-->>Fuzzer: key_to_seed
Fuzzer->>Corpus: index(seed)
alt seed found
Corpus-->>Fuzzer: slot
Fuzzer-->>Fuzzer: memoize parent, list, slot, seed
Fuzzer-->>Fuzzer: return True
else seed absent
Fuzzer-->>Fuzzer: clear memo
Fuzzer-->>Fuzzer: return False
end
end
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Multiple returning dropped seeds can exponentially inflate the global horizon and effectively disable frame abandonment.
Review effort: Balanced
Findings: 1
What changed in this PR
Fixes Doppler slow-cycle handling and stale corpus-membership memoization.
Changes:
- Adapts Doppler’s abandonment horizon for returning seeds.
- Revalidates cached corpus membership by list and slot identity.
- Adds regression tests and documentation.
| File | Description |
|---|---|
src/fuzzer_tool/core/power_doppler.py |
Adds adaptive horizon tracking. |
src/fuzzer_tool/services/fuzzer.py |
Fixes corpus-membership memo validation. |
tests/test_power_doppler.py |
Tests slow cycles and dropped-key bounds. |
tests/test_os_net_scheduler_wiring.py |
Tests corpus replacement and rebuilding. |
docs/DEEP_DIVE.md |
Documents horizon adaptation. |
docs/TODO.md |
Updates Doppler tuning notes. |
CHANGELOG.md |
Records both fixes. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| del self._dropped_keys[seed_key] | ||
| self._stale_after *= 2 |
Each returning dropped seed doubled one shared horizon (N returns -> 2^N), disabling abandonment. The dropped-key memory (max_seeds keys) also forgot keys before large corpora cycled back, so the horizon never widened at all. Now horizon = max(horizon, 2 x measured revisit gap), with 2^15 remembered keys. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Rvj2gdMAa4HA8MGHULfDJE
Fix PR #48 review finding: Doppler horizon compounding

Addresses both Copilot threads on #47.
Doppler horizon thrash (
core/power_doppler.py)Fixed abandon horizon (
max_seeds × ensemble × 4) dropped every frame when the corpus cycle was longer: 13 seeds, 1 slot, ensemble 3 → 12-tick horizon → 0 ensembles forever. Now a bounded LRU of dropped keys (sizemax_seeds); a returning key doubles the horizon, so it converges past the revisit time. Truly abandoned keys leave it unchanged.Stale corpus memo (
services/fuzzer.py::_in_corpus)Memo keyed on
len(corpus)missed same-length in-place trims (corpus_manager.py:1165). Hits now store(parent, corpus list, slot, seed)and re-validate by identity in O(1); misses aren't memoized.Tests (falsification + adversarial each, failing before fix)
test_regression_slow_cycle_beyond_horizon_still_scores,test_adversarial_abandoned_keys_do_not_grow_horizontest_regression_parent_replaced_in_place_not_recorded,test_adversarial_parent_kept_across_corpus_rebuildValidation
🤖 Generated with Claude Code
https://claude.ai/code/session_01Rvj2gdMAa4HA8MGHULfDJE
Generated by Claude Code
Summary by Sourcery
Fix Doppler scheduling across slow corpus cycles and keep corpus-membership decisions valid as the corpus changes.
Bug Fixes:
Documentation:
Tests: