Skip to content

Fix 5 single-line confirmed bugs from bugreport - #7

Merged
daedalus merged 2 commits into
masterfrom
copilot/fix-simple-bugs
Aug 24, 2026
Merged

Fix 5 single-line confirmed bugs from bugreport#7
daedalus merged 2 commits into
masterfrom
copilot/fix-simple-bugs

Conversation

CopilotAI commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Fixes 5 confirmed single-line bugs identified in bugreport_2026-08-21_merged.md, with a follow-up commit making the versifier regression test deterministic per code review feedback.

Summary by Sourcery

Fix five confirmed single-line bugs and add deterministic regression coverage for their corrected behavior.

Bug Fixes:

  • Restore persistent-mode execution by resuming stopped targets after each run.
  • Correct GF(2) exponent handling for zero bases.
  • Ensure decimal numbers are emitted by the versifier.
  • Prevent JPEG generation failures for small maximum lengths.
  • Select the TE position with the greatest edge-hit weight.

Documentation:

  • Mark the five confirmed bug-report findings as fixed in the merged bug report.

Tests:

  • Add regression coverage for all five corrected bug-report issues, including deterministic versifier behavior.

CopilotAIand others added 2 commits August 24, 2026 21:27
Co-authored-by: daedalus <115175+daedalus@users.noreply.github.com>
Co-authored-by: daedalus <115175+daedalus@users.noreply.github.com>
@sourcery-ai

sourcery-aiBot commented Aug 24, 2026

Copy link
Copy Markdown

Reviewer's Guide

Fixes five confirmed single-line bugs across persistent execution, GF(2^n) arithmetic, numeric generation, JPEG generation, and test-execution positioning; updates the audit documentation and adds deterministic regression tests covering each corrected behavior.

Sequence diagram for resumed persistent execution

sequenceDiagram
participant Runner
participant PersistentTarget
Runner->>PersistentTarget: run_one(data)
PersistentTarget-->>PersistentTarget: Read return code from SIGSTOP branch
PersistentTarget->>PersistentTarget: os.kill(pid, SIGCONT)
PersistentTarget-->>Runner: return returncode
Loading

Flow diagram for corrected bug-report behaviors

flowchart LR
A[GF2 pow with zero base] --> B[Preserve exponent]
C[Decimal number generation] --> D[Append generated digits]
E[Small JPEG max_len] --> F[Clamp scan length lower bound]
G[TE position selection] --> H[Choose highest edge-hit weight]
Loading

File-Level Changes

ChangeDetailsFiles
Resume persistent targets after collecting stopped-run results.
  • Send SIGCONT in the SIGSTOP handling path after reading the return code.
  • Add a regression test verifying the resume signal is issued.
src/fuzzer_tool/adapters/persistent.py
tests/test_regression_bugreport_easy_fixes.py
Correct GF(2^n) exponent handling for zero bases.
  • Replace the ambiguous augmented-assignment expression with explicit conditional assignment so zero-base exponents remain unchanged.
  • Cover both positive and zero exponents with regression tests.
src/fuzzer_tool/core/gf2_common.py
tests/test_regression_bugreport_easy_fixes.py
Ensure decimal numeric nodes emit their generated digits.
  • Append generated digits for the base-10 generation case.
  • Use a deterministic fake RNG to verify exact decimal output.
src/fuzzer_tool/core/mutations/generic.py
tests/test_regression_bugreport_easy_fixes.py
Prevent JPEG generation from failing for small maximum lengths.
  • Clamp the random scan-length upper bound to at least one.
  • Add coverage for generation with a small max_len.
src/fuzzer_tool/core/mutations/jpeg.py
tests/test_regression_bugreport_easy_fixes.py
Select test-execution positions using weighted edge influence.
  • Choose the byte position with the greatest summed edge-hit weight rather than the greatest offset.
  • Add regression coverage where weighted influence and highest offset differ.
src/fuzzer_tool/services/te_position.py
tests/test_regression_bugreport_easy_fixes.py
Record the five confirmed bug-report findings as fixed.
  • Annotate the persistent execution, JPEG, versifier, GF(2^n), and test-position findings with fix dates and implementation notes.
docs/bugreport_2026-08-21_merged.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@daedalus
daedalus marked this pull request as ready for review August 24, 2026 21:46
CopilotAI lite review requested due to automatic review settings August 24, 2026 21:46
@daedalus
daedalus merged commit 3f72732 into masterAug 24, 2026
1 check passed
@daedalus
daedalus deleted the copilot/fix-simple-bugs branch August 24, 2026 21:46

@sourcery-aisourcery-aiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments### Comment 1
<locationpath="src/fuzzer_tool/services/te_position.py"line_range="46-49" />
<code_context>
if not byte_edges:
return None
- best_pos = max(byte_edges.keys())
+ best_pos = max(byte_edges, key=lambda pos: sum(byte_edges[pos].values()))
return best_pos if best_pos < input_length else None
</code_context>
<issue_to_address>
**issue (bug_risk):** When the highest-weight entry in `byte_edges` has a position at or beyond `input_length`, `max(...)` selects it first and the function returns `None` instead of selecting a lower-weight position that is valid for the current input.
**Triggers:** When stale TE data contains positions from longer inputs and the current input is shorter than the highest-weight position.
**Suggested fix:** Filter `byte_edges` to positions below `input_length` before applying `max`, returning `None` only when no valid positions remain.
```suggestion valid_positions = [pos for pos in byte_edges if pos < input_length] if not valid_positions: return None return max(valid_positions, key=lambda pos: sum(byte_edges[pos].values()))```
</issue_to_address>

Sourcery assessment

Approval pending. 1 finding to address first.

Blocking findings: src/fuzzer_tool/services/te_position.py:49


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines 46 to 49
if not byte_edges:
return None
best_pos = max(byte_edges.keys())
best_pos = max(byte_edges, key=lambda pos: sum(byte_edges[pos].values()))
return best_pos if best_pos < input_length else None

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): When the highest-weight entry in byte_edges has a position at or beyond input_length, max(...) selects it first and the function returns None instead of selecting a lower-weight position that is valid for the current input.

Triggers: When stale TE data contains positions from longer inputs and the current input is shorter than the highest-weight position.

Suggested fix: Filter byte_edges to positions below input_length before applying max, returning None only when no valid positions remain.

Suggested change
ifnotbyte_edges:
returnNone
best_pos=max(byte_edges.keys())
best_pos=max(byte_edges, key=lambdapos: sum(byte_edges[pos].values()))
returnbest_posifbest_pos<input_lengthelseNone
valid_positions= [posforposinbyte_edgesifpos<input_length]
ifnotvalid_positions:
returnNone
returnmax(valid_positions, key=lambdapos: sum(byte_edges[pos].values()))

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new SIGCONT send in PersistentRunner.run_one() can raise ProcessLookupError without handling, potentially crashing the fuzzer loop.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Fixes five audited single-line bugs across the fuzzer’s persistent runner, GF(2^n) math, versifier number emission, JPEG generation, and TE-based mutation targeting, and adds regression tests to lock in the corrected behavior.

Changes:

  • Add a regression test suite covering all five bugreport findings (with deterministic versifier output).
  • Fix TE position selection to use weighted edge influence rather than max byte offset.
  • Fix one-line bugs in persistent SIGCONT resume, GF2 pow(0, e) exponent handling, JPEG scan length clamping, and versifier base-10 emission.
File summaries
FileDescription
tests/test_regression_bugreport_easy_fixes.pyNew regression tests for the five confirmed single-line fixes (incl. deterministic versifier case).
src/fuzzer_tool/services/te_position.pySelect TE mutation position by highest summed edge influence weight.
src/fuzzer_tool/core/mutations/jpeg.pyClamp JPEG scan-length randint upper bound to avoid invalid ranges on small max_len.
src/fuzzer_tool/core/mutations/generic.pyEnsure _NumNode.Generate appends digits for base-10 numbers.
src/fuzzer_tool/core/gf2_common.pyFix conditional exponent reduction so pow(0, e) doesn’t incorrectly reduce e.
src/fuzzer_tool/adapters/persistent.pyResume persistent targets by sending SIGCONT after reading return code on SIGSTOP.
docs/bugreport_2026-08-21_merged.mdMark the five confirmed findings as fixed with brief fix notes.
Review details
  • Files reviewed: 7/7 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +162 to 163
os.kill(self.pid, signal.SIGCONT)
return returncode, ""
@daedalus

Copy link
Copy Markdown
Owner

@copilot Fix the code for all comments in this review thread.

When a review comment includes a suggested change, apply the suggestion exactly.

Do not make changes beyond what is described in the linked review thread.

daedalus added a commit that referenced this pull request Aug 25, 2026
Codifies the pattern reviewers flagged in PRs #7/#8 (f00927a, f5d599a):
tests that loop hoping a randomized code path eventually hits a
condition test luck, not behavior. Full rationale/example lives in
docs/refs/bug-classes.md §Testing.
daedalus added a commit that referenced this pull request Aug 25, 2026
Plan derived from PR #1/#7/#8 review-feedback analysis (see AGENTS.md
Hard Rule 39). Inventories retry-until-random-hit test candidates
across the suite (tiered by confidence) and confirms the
supports_priors capability-flag fix already rolled out to all
scheduler classes.
daedalus added a commit that referenced this pull request Aug 29, 2026
Each of these carried a status table where most rows had closed, which buried
the handful of open ones. Same treatment in all three: the closed rows are
named in one line so nobody re-surveys them, and the per-row justification goes
to git history.
`six_source_technique_port.md` — nine of sixteen rows were "already done", six
of them by machinery better than what the source proposed. Pruned to a
name-only list. Kept the note that four of them left a narrow residue that is
genuinely NOT covered, which is R5 and still open, and the "Read this first"
framing, which is the point of the document: it was drafted from sources alone
and the audit against live code killed most of it.
`tigerbeetle_four_fuzzers_port.md` — P1-3 (scheduler convergence), P1-5
(exhaustive enumeration) and P2-6 (negative space) are done, and their whole
sections are gone. What each of them FOUND is not lost: all three have a
learnings note (`docs/learnings/2026-08-21-scheduler-convergence.md`,
`2026-08-22-exhaustive-pool-p1-5.md`, `2026-08-22-count-class-exhaustive.md`)
and the status block now points at those instead of restating them. The 20
remaining `rng.random() < 0.5` coin-flip sites are promoted out of the P1-5
prose into their own open item, since that is a P1-5 follow-up rather than
unfinished P1-5 and was easy to misread as the latter. "Suggested sequence"
was a seven-step plan whose first three steps are done; rewritten to the five
that remain.
`web_research_port_candidates_2026-08.md` — Tier 1 is closed in its entirety
and pruned. Four rows landed 2026-08-24; #4 trace-div/trace-gep and #5 n-gram
edge coverage shipped after this doc was last touched and were still tabled
here as `L`-effort candidates. #6 (Zest validity channel) and #7 (SGFuzz enum
states) shipped as mechanism — `--reject-code` and `__sfuzz_state` both exist —
but each left one open design question, and those two questions are already
tracked in `docs/TODO.md` under Scheduling, so tracking them here as well was
the duplication. Tier 2/3 are untouched and still unstarted; the note that
their effort estimates are unaudited guesses now cites Tier 1 as the evidence
for why, since two of its seven rows turned out to be near-free.
Status of every pruned row was checked against live source, not against the
row's own marker.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@daedalus