Skip to content

feat(analyze): accept multiple keys in analyze subcommand#91

Open
oritwoen wants to merge 5 commits intomainfrom
feat/analyze-multiple-keys
Open

feat(analyze): accept multiple keys in analyze subcommand#91
oritwoen wants to merge 5 commits intomainfrom
feat/analyze-multiple-keys

Conversation

@oritwoen
Copy link
Copy Markdown
Owner

vuke analyze only took a single key. When investigating a cluster of related keys you had to run the command once per key, which gets tedious fast.

Now it accepts multiple positional args and a --key-file flag:

vuke analyze 0x1a2b 0x3c4d --analyzer milksad
vuke analyze --key-file suspicious_keys.txt --analyzer lcg

Each key runs through the selected analyzers independently. Human output separates keys with blank lines, JSON wraps results in an array when there's more than one key (single key still returns a plain object for backwards compat).

--key-file reads one key per line, same formats parse_private_key already handles (hex, WIF, decimal). Lines starting with # are skipped.

Closes #84

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 26, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4112c20e-1565-4e3a-8a2f-34c8393d7dd8

📥 Commits

Reviewing files that changed from the base of the PR and between 1267098 and 915be59.

📒 Files selected for processing (1)
  • src/main.rs
📜 Recent review details
🧰 Additional context used
📓 Path-based instructions (3)
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Order imports as: external crates → std → blank line → super:: → blank line → crate::
Prefer ? operator over .unwrap() in new code
Use PascalCase for types and structs
Use snake_case for function and method names
Use SCREAMING_SNAKE_CASE for constants
Use snake_case for file and module names

Files:

  • src/main.rs
src/main.rs

📄 CodeRabbit inference engine (AGENTS.md)

src/main.rs: Use anyhow::Result<T> and anyhow::bail!() for CLI and top-level error handling
CLI command and subcommand changes go in src/main.rs using clap derive macros

Files:

  • src/main.rs
src/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.rs: Use indicatif::ProgressBar for long-running operations
Place inline tests in #[cfg(test)] mod tests at the end of each file, using standard assert! and assert_eq! macros
Use tempfile crate for file I/O tests

Files:

  • src/main.rs
🧠 Learnings (25)
📓 Common learnings
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T18:24:52.371Z
Learning: Applies to src/analyze/**/*.rs : Use masked analysis pattern `(full_key & ((1<<N)-1)) | (1<<(N-1))` for puzzle solving
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/*.rs : Add new analyzer by creating `{name}.rs`, adding to `mod.rs`, and extending `AnalyzerType` enum

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-12T18:24:52.371Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T18:24:52.371Z
Learning: Applies to src/main.rs : CLI command and subcommand changes go in `src/main.rs` using clap derive macros

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-12T18:24:52.371Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T18:24:52.371Z
Learning: Applies to src/analyze/**/*.rs : Use masked analysis pattern `(full_key & ((1<<N)-1)) | (1<<(N-1))` for puzzle solving

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/output.rs : Format analysis results as plain text and JSON using utilities in `output.rs`

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:44.316Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/transform/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:44.316Z
Learning: Applies to src/transform/*.rs : Process inputs as batch operations using `&[Input]` as input and `&mut Vec<(String, Key)>` as output, where the first tuple element is a human-readable source description

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/{mt64,xorshift}.rs : Use `config.cascade_targets` for multi-target verification in cascade filtering

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:44.316Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/transform/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:44.316Z
Learning: Applies to src/transform/src/analyze/*.rs : For reversible transforms, create a corresponding analyzer at `src/analyze/{name}.rs` to support key recovery analysis

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/*.rs : Reuse PRNG implementations from `src/{prng}.rs` instead of duplicating shared logic

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-12T18:24:52.371Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T18:24:52.371Z
Learning: Applies to src/{transform,analyze}/mod.rs : Use factory enums with `create()` and `FromStr` for parsing CLI strings in `TransformType` and `AnalyzerType`

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/*.rs : Implement `supports_mask()` method and use `config.mask_bits` for masking support

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-13T13:20:58.369Z
Learnt from: oritwoen
Repo: oritwoen/vuke PR: 76
File: src/source/wordlist.rs:134-143
Timestamp: 2026-03-13T13:20:58.369Z
Learning: Do not flag .ok() calls on output.hit() / output.key() inside Rayon par_chunks().for_each() closures in Rust files (e.g., src/source/wordlist.rs) as bugs. Rayon for_each requires FnMut() -> (), which cannot propagate Result with ?. This is a known limitation discussed in issue `#77`. Treat these .ok() usages in this pattern as intentional and not regressions; focus review on actual logic or error handling outside this specific closure pattern.

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/{milksad,mt64,lcg,xorshift,sha256_chain}.rs : Use `AtomicBool` for early termination flag across threads in parallel brute-force search

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-12T18:24:52.371Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T18:24:52.371Z
Learning: Applies to src/main.rs : Use `anyhow::Result<T>` and `anyhow::bail!()` for CLI and top-level error handling

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-12T18:24:52.371Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T18:24:52.371Z
Learning: Applies to src/analyze/{mt64,xorshift}.rs : Implement cascade filtering for 64-bit seed spaces (mt64, xorshift) with multi-target verification to avoid false positives

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/{milksad,mt64,lcg,xorshift,sha256_chain}.rs : Use Rayon `par_iter()` for CPU parallelism in brute-force operations

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-05T12:40:29.177Z
Learnt from: oritwoen
Repo: oritwoen/vuke PR: 64
File: src/source/mod.rs:26-32
Timestamp: 2026-03-05T12:40:29.177Z
Learning: In `oritwoen/vuke`, `AGENTS.md` and `src/source/AGENTS.md` describe an **aspirational/future** `Source::process` trait signature (generic `T: Transform`, `O: Output`, with `no_gpu: bool` and `progress: Option<&ProgressBar>` parameters). The **current** implementation in `src/source/mod.rs` uses dynamic dispatch: `fn process(&self, transforms: &[Box<dyn Transform>], deriver: &KeyDeriver, matcher: Option<&Matcher>, output: &dyn Output) -> Result<ProcessStats>`. Migrating to the generic form is blocked by object-safety requirements (`Box<dyn Source>` is used in `src/main.rs`) and is a tracked future refactor. Do not flag the current dynamic-dispatch signature as non-conformant with AGENTS.md.

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-12T18:25:01.029Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/output/AGENTS.md:0-0
Timestamp: 2026-03-12T18:25:01.029Z
Learning: Applies to src/output/console.rs : Compact CSV format for file output should be: `source,transform,privkey_hex,address`

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-12T18:24:52.371Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T18:24:52.371Z
Learning: Applies to src/{transform,source,analyze}/**/*.rs : Use `AtomicBool` for early termination signaling across Rayon threads

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-12T18:25:01.029Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/output/AGENTS.md:0-0
Timestamp: 2026-03-12T18:25:01.029Z
Learning: Applies to src/output/**/*.rs : Output trait must implement three methods: `key()`, `hit()`, and `flush()` with specified signatures

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-22T18:38:29.431Z
Learnt from: oritwoen
Repo: oritwoen/vuke PR: 86
File: src/provider.rs:442-443
Timestamp: 2026-03-22T18:38:29.431Z
Learning: In oritwoen/vuke src/provider.rs, the `derived.p2tr == addr` branch in `verify_key_boha` has no test coverage intentionally — no boha puzzles currently have P2TR/Taproot addresses. The branch is forward-compatible for when taproot puzzles are added to boha. Do not flag missing P2TR test coverage in this function.

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-12T18:25:01.029Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/output/AGENTS.md:0-0
Timestamp: 2026-03-12T18:25:01.029Z
Learning: Applies to src/output/**/*.rs : Use `escape_csv_field()` from `mod.rs` for any field written to CSV in the output module

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/{milksad,mt64,lcg,xorshift,sha256_chain}.rs : Use `indicatif::ProgressBar` for progress indication in long-running operations

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/{mt64,xorshift}.rs : 64-bit seed spaces (mt64, xorshift) MUST use cascade filter for verification

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/{milksad,sha256_chain}.rs : Implement `supports_gpu()` and `analyze_gpu()` methods for GPU-accelerated analyzers

Applied to files:

  • src/main.rs
🔇 Additional comments (7)
src/main.rs (7)

1325-1328: JSON buffering still present - memory scales with batch size.

This was flagged in a previous review. All per-key JSON blobs accumulate in json_entries, then join(",\n") allocates another copy. For --key-file big.txt, you'll buffer the entire result set plus one copy before any output appears.

Streaming approach: print [ up front, emit entries as produced with a first flag for comma placement, close with ].

Also applies to: 1472-1478


257-262: CLI args for multi-key support look correct.

Default num_args(0..) on Vec<String> positional allows --key-file-only invocations. No conflicts between positional and file args means they merge, which matches the intended behavior.


449-463: Key merging and empty check look good.

Reads file, skips empty lines and # comments, merges with positional args, bails if empty. The ? on file read is appropriate - can't recover from unreadable key file.


1330-1352: Parse error handling correctly continues batch.

Failed parses push error JSON (escaped properly), set had_error, and continue. Batch keeps running. Exit code reflects failure at the end.


1461-1469: Per-key output with separator logic looks correct.

printed_count tracks actual output, so skipped keys don't produce spurious blank lines. JSON entries collected properly.


1480-1482: Final error handling correct - non-zero exit on any parse failure.

Previous review confirmed removing the multi gate was the right fix. Any had_error now bails regardless of key count.


1355-1412: Error handling is correct — verify_ref errors are batch-level, not per-key

The ? on line 1357 is right. Parse errors skip one key because parse_private_key failures are per-key (one key is malformed, others might work). Verify errors abort because verify_key only fails on bad verify_ref — invalid collection or malformed query — which affects all keys. Fail-fast is correct when the parameter itself is wrong for the entire batch.


📝 Walkthrough

Walkthrough

The analyze command now accepts multiple positional --key values and an optional --key-file; keys from args and file are merged. run_analyze now takes a slice of keys and processes each key independently (parse → optional verify → analyzers), emitting per-key JSON or text and returning an error if any key fails to parse.

Changes

Cohort / File(s) Summary
CLI signature & arg merge
src/main.rs
Command::Analyze now uses key: Vec<String> and key_file: Option<PathBuf>. main reads --key-file (trim, skip empty / lines starting with #), merges into Vec, and bails if no keys provided.
Per-key analyze flow & interfaces
src/main.rs
run_analyze signature changed to key_inputs: &[String]. Outer loop added to iterate keys; per-key parse, per-key metadata rebuild, per-key mask-bit warnings, and per-key verification (with immediate error only for invalid verify-provider refs).
Error handling & output formatting
src/main.rs
Parse failures are handled per-key: in --json mode produce per-key JSON error entries (escaped key + error), otherwise print to stderr. Analyzer execution and result formatting moved inside per-key loop; non-JSON outputs are separated by blank lines; JSON mode collects entries into an array for multi-key runs, single-key prints single object. Overall return Err if any key failed to parse.
Function signature updates
src/main.rs
Updated function types/usages passing &keys (slice) into analyzers and verification helpers.
sequenceDiagram
  participant CLI as Client
  participant Main as Main\n(arg merge)
  participant Parser as KeyParser\n(parse_private_key)
  participant Engine as AnalyzerEngine\n(verify & run)
  participant GPU as GPU\n(optional)

  CLI->>Main: invoke `vuke analyze` (keys + optional key-file)
  Main->>Main: read file lines, trim, filter, merge into Vec<String>
  loop per key
    Main->>Parser: parse key_input
    alt parse OK
      Parser->>Main: KeyMetadata
      Main->>Engine: verify (optional) & run analyzers with metadata
      Engine->>GPU: attempt GPU analyzers (if enabled)
      GPU-->>Engine: results or fallback
      Engine-->>Main: per-key results
      Main->>CLI: emit per-key JSON object or text block
    else parse FAIL
      Parser-->>Main: parse error
      Main->>CLI: emit per-key error (JSON or stderr)
    end
  end
  alt multiple keys
    Main->>CLI: emit aggregated JSON array or separated text sections
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🔑 Keys in rows, from flags and file,
Each one parsed, some stall, some smile,
Verify if asked, analyze in turn,
JSON or text, grouped as you learn,
Batch work done — one small win, worthwhile.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title directly and concisely describes the main change: adding support for multiple keys in the analyze subcommand.
Description check ✅ Passed The description clearly explains the problem, the solution with concrete examples, output behavior changes, and file format details.
Linked Issues check ✅ Passed The PR implementation matches issue #84 requirements: accepts multiple positional keys and --key-file, processes each independently, handles output formatting per key, and supports key file formats with comment skipping.
Out of Scope Changes check ✅ Passed All changes are scoped to accepting multiple keys in analyze: signature updates, per-key iteration loops, and output formatting adjustments align with issue #84 objectives.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/analyze-multiple-keys
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch feat/analyze-multiple-keys

Comment @coderabbitai help to get the list of available commands and usage tips.

@oritwoen oritwoen self-assigned this Mar 26, 2026
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 1 file

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Requires human review: This change involves a significant refactor of the run_analyze function and modifies core subcommand logic to support multiple inputs and file I/O.

Architecture diagram
sequenceDiagram
    participant User
    participant Main as Main (CLI Entry)
    participant FS as File System
    participant Runner as run_analyze()
    participant Parser as parse_private_key()
    participant Analyzer as Analyzers (CPU/GPU)

    User->>Main: vuke analyze [keys...] --key-file [path]
    
    opt NEW: --key-file provided
        Main->>FS: read_to_string(path)
        FS-->>Main: file content
        Main->>Main: NEW: Filter comments (#) and empty lines
        Main->>Main: NEW: Append file keys to positional keys
    end

    Main->>Runner: CHANGED: run_analyze(key_inputs: &[String])
    
    loop NEW: For each key_input in key_inputs
        Runner->>Parser: parse_private_key(key_input)
        Parser-->>Runner: Key object
        
        loop For each enabled analyzer
            Runner->>Analyzer: analyze(key, config)
            Analyzer-->>Runner: Analysis Results
        end

        alt Human Output
            opt NEW: If not first key
                Runner->>User: CHANGED: Print blank line separator
            end
            Runner->>User: Print analysis report for current key
        else JSON Output
            Runner->>Runner: CHANGED: Buffer JSON object for this key
        end
    end

    opt JSON Output
        alt NEW: Multiple keys processed
            Runner->>User: CHANGED: Print results as JSON Array
        else Single key processed
            Runner->>User: Print result as single JSON Object
        end
    end
Loading

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/main.rs`:
- Around line 257-263: The positional `key: Vec<String>` is currently declared
with #[arg(num_args = 1..)] which forces at least one positional and blocks
using --key-file; change the attribute to #[arg(num_args(0..))] or add required
= false so the positional becomes optional, leaving your application-level
empty-check (the existing "no keys provided" validation) to handle missing keys
when --key-file is used instead. Ensure you only modify the attribute on the
`key` field so clap no longer rejects invocations that rely solely on
`key_file`.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 1cc64995-3e7f-47ae-bd72-487265f135ed

📥 Commits

Reviewing files that changed from the base of the PR and between e467e13 and 8683f24.

📒 Files selected for processing (1)
  • src/main.rs
📜 Review details
🧰 Additional context used
📓 Path-based instructions (3)
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Order imports as: external crates → std → blank line → super:: → blank line → crate::
Prefer ? operator over .unwrap() in new code
Use PascalCase for types and structs
Use snake_case for function and method names
Use SCREAMING_SNAKE_CASE for constants
Use snake_case for file and module names

Files:

  • src/main.rs
src/main.rs

📄 CodeRabbit inference engine (AGENTS.md)

src/main.rs: Use anyhow::Result<T> and anyhow::bail!() for CLI and top-level error handling
CLI command and subcommand changes go in src/main.rs using clap derive macros

Files:

  • src/main.rs
src/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.rs: Use indicatif::ProgressBar for long-running operations
Place inline tests in #[cfg(test)] mod tests at the end of each file, using standard assert! and assert_eq! macros
Use tempfile crate for file I/O tests

Files:

  • src/main.rs
🧠 Learnings (13)
📓 Common learnings
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/output.rs : Format analysis results as plain text and JSON using utilities in `output.rs`
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/*.rs : Add new analyzer by creating `{name}.rs`, adding to `mod.rs`, and extending `AnalyzerType` enum

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-12T18:24:52.371Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T18:24:52.371Z
Learning: Applies to src/analyze/**/*.rs : Use masked analysis pattern `(full_key & ((1<<N)-1)) | (1<<(N-1))` for puzzle solving

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-12T18:24:52.371Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T18:24:52.371Z
Learning: Applies to src/main.rs : CLI command and subcommand changes go in `src/main.rs` using clap derive macros

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:44.316Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/transform/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:44.316Z
Learning: Applies to src/transform/*.rs : Process inputs as batch operations using `&[Input]` as input and `&mut Vec<(String, Key)>` as output, where the first tuple element is a human-readable source description

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/output.rs : Format analysis results as plain text and JSON using utilities in `output.rs`

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/{mt64,xorshift}.rs : Use `config.cascade_targets` for multi-target verification in cascade filtering

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:44.316Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/transform/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:44.316Z
Learning: Applies to src/transform/src/analyze/*.rs : For reversible transforms, create a corresponding analyzer at `src/analyze/{name}.rs` to support key recovery analysis

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/*.rs : Reuse PRNG implementations from `src/{prng}.rs` instead of duplicating shared logic

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/{milksad,sha256_chain}.rs : Implement `supports_gpu()` and `analyze_gpu()` methods for GPU-accelerated analyzers

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/*.rs : Implement `supports_mask()` method and use `config.mask_bits` for masking support

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-12T18:24:52.371Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T18:24:52.371Z
Learning: Applies to src/analyze/{mt64,xorshift}.rs : Implement cascade filtering for 64-bit seed spaces (mt64, xorshift) with multi-target verification to avoid false positives

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-13T13:20:58.369Z
Learnt from: oritwoen
Repo: oritwoen/vuke PR: 76
File: src/source/wordlist.rs:134-143
Timestamp: 2026-03-13T13:20:58.369Z
Learning: Do not flag .ok() calls on output.hit() / output.key() inside Rayon par_chunks().for_each() closures in Rust files (e.g., src/source/wordlist.rs) as bugs. Rayon for_each requires FnMut() -> (), which cannot propagate Result with ?. This is a known limitation discussed in issue `#77`. Treat these .ok() usages in this pattern as intentional and not regressions; focus review on actual logic or error handling outside this specific closure pattern.

Applied to files:

  • src/main.rs

…h errors

Drop num_args=1.. so clap doesn't reject --key-file-only invocations.
Bad keys now skip with an error instead of aborting the whole batch.
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/main.rs`:
- Around line 1471-1473: The current logic only bails when had_error && multi,
so single-key parse failures still return success; update the error path so any
parse failure sets a non-zero exit: when had_error is true (regardless of multi)
propagate the error (use anyhow::bail or return Err) so the process exits
non‑zero; modify the conditional around had_error/multi (the block containing
anyhow::bail!("Some keys failed to parse")) to trigger on had_error alone and,
if desired, adjust the error message to indicate whether multiple keys failed
using the multi flag.
- Around line 1352-1371: The manual JSON construction around
matches_json/report/json_entries is unsafe; replace it by defining small
serde-serializable structs (e.g., MatchEntry with fields puzzle_id, address,
address_type, status, prize and ReportEntry with key, total_checked, matches)
derived with #[derive(Serialize)] and then use
serde_json::to_string(&report_entry) (or to_string for each MatchEntry and for
the whole ReportEntry) instead of format! strings; update the code that builds
matches_json and pushes into json_entries to construct these structs from report
and key_input and serialize via serde_json to ensure proper escaping and
Option<...> (prize) handling.
- Around line 1334-1338: The JSON escaping is incomplete in the
json_entries.push call where key_input and e.to_string() are interpolated;
replace the manual string formatting with proper JSON serialization (e.g., build
a small struct like { key: key_input.clone(), error: e.to_string() } or a
serde-serializable tuple and call serde_json::to_string) and push the resulting
serialized string into json_entries so newlines, backslashes and other
characters are correctly escaped; update references around
json_entries.push(...) in main.rs accordingly and import/derive serde Serialize
or call serde_json::to_string where used.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: d7fb34c8-62a1-4171-8985-c07104c6f672

📥 Commits

Reviewing files that changed from the base of the PR and between 8683f24 and c3950eb.

📒 Files selected for processing (1)
  • src/main.rs
📜 Review details
🧰 Additional context used
📓 Path-based instructions (3)
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Order imports as: external crates → std → blank line → super:: → blank line → crate::
Prefer ? operator over .unwrap() in new code
Use PascalCase for types and structs
Use snake_case for function and method names
Use SCREAMING_SNAKE_CASE for constants
Use snake_case for file and module names

Files:

  • src/main.rs
src/main.rs

📄 CodeRabbit inference engine (AGENTS.md)

src/main.rs: Use anyhow::Result<T> and anyhow::bail!() for CLI and top-level error handling
CLI command and subcommand changes go in src/main.rs using clap derive macros

Files:

  • src/main.rs
src/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.rs: Use indicatif::ProgressBar for long-running operations
Place inline tests in #[cfg(test)] mod tests at the end of each file, using standard assert! and assert_eq! macros
Use tempfile crate for file I/O tests

Files:

  • src/main.rs
🧠 Learnings (13)
📚 Learning: 2026-03-12T18:24:52.371Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T18:24:52.371Z
Learning: Applies to src/main.rs : CLI command and subcommand changes go in `src/main.rs` using clap derive macros

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-12T18:24:52.371Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T18:24:52.371Z
Learning: Applies to src/analyze/**/*.rs : Use masked analysis pattern `(full_key & ((1<<N)-1)) | (1<<(N-1))` for puzzle solving

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/*.rs : Add new analyzer by creating `{name}.rs`, adding to `mod.rs`, and extending `AnalyzerType` enum

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/*.rs : Reuse PRNG implementations from `src/{prng}.rs` instead of duplicating shared logic

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/{mt64,xorshift}.rs : Use `config.cascade_targets` for multi-target verification in cascade filtering

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:44.316Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/transform/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:44.316Z
Learning: Applies to src/transform/src/analyze/*.rs : For reversible transforms, create a corresponding analyzer at `src/analyze/{name}.rs` to support key recovery analysis

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/{milksad,sha256_chain}.rs : Implement `supports_gpu()` and `analyze_gpu()` methods for GPU-accelerated analyzers

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:44.316Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/transform/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:44.316Z
Learning: Applies to src/transform/*.rs : Process inputs as batch operations using `&[Input]` as input and `&mut Vec<(String, Key)>` as output, where the first tuple element is a human-readable source description

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/output.rs : Format analysis results as plain text and JSON using utilities in `output.rs`

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/{milksad,mt64,lcg,xorshift,sha256_chain}.rs : Use Rayon `par_iter()` for CPU parallelism in brute-force operations

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/*.rs : Implement `supports_mask()` method and use `config.mask_bits` for masking support

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-12T18:24:52.371Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T18:24:52.371Z
Learning: Applies to src/analyze/{mt64,xorshift}.rs : Implement cascade filtering for 64-bit seed spaces (mt64, xorshift) with multi-target verification to avoid false positives

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-13T13:20:58.369Z
Learnt from: oritwoen
Repo: oritwoen/vuke PR: 76
File: src/source/wordlist.rs:134-143
Timestamp: 2026-03-13T13:20:58.369Z
Learning: Do not flag .ok() calls on output.hit() / output.key() inside Rayon par_chunks().for_each() closures in Rust files (e.g., src/source/wordlist.rs) as bugs. Rayon for_each requires FnMut() -> (), which cannot propagate Result with ?. This is a known limitation discussed in issue `#77`. Treat these .ok() usages in this pattern as intentional and not regressions; focus review on actual logic or error handling outside this specific closure pattern.

Applied to files:

  • src/main.rs
🔇 Additional comments (3)
src/main.rs (3)

257-262: LGTM - The previous num_args=1.. issue is resolved. Positional keys now default to 0+ allowing --key-file only invocations, with the empty check at line 461 catching missing keys at app level.


449-463: LGTM - Key merging logic is clean. File reading with ? operator, proper line filtering for comments/empty lines, and clear error message if no keys provided.


1416-1461: LGTM - Analyzer loop correctly reuses the GPU context across all keys (no per-key initialization overhead). Progress bars, GPU-first-with-fallback, and result collection all look correct.

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 1 file (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/main.rs">

<violation number="1" location="src/main.rs:1471">
P2: Single-key parse failures now return success because the final error check is gated by `multi`. Invalid input should still produce a non-zero exit.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/main.rs`:
- Around line 1340-1343: The JSON being built interpolates key_input raw which
breaks output when the key contains quotes or special chars; add a helper fn
escape_json_string(s: &str) -> String (or reuse the existing escaping used for
err_msg) and call it for key_input before formatting into json_entries (the
json_entries.push(format!(...)) site), so both key_input and err_msg are escaped
consistently and the produced JSON remains valid.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 58b5648a-4f57-46db-a0b1-8c8a545ec9af

📥 Commits

Reviewing files that changed from the base of the PR and between c3950eb and 9095da7.

📒 Files selected for processing (1)
  • src/main.rs
📜 Review details
🧰 Additional context used
📓 Path-based instructions (3)
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Order imports as: external crates → std → blank line → super:: → blank line → crate::
Prefer ? operator over .unwrap() in new code
Use PascalCase for types and structs
Use snake_case for function and method names
Use SCREAMING_SNAKE_CASE for constants
Use snake_case for file and module names

Files:

  • src/main.rs
src/main.rs

📄 CodeRabbit inference engine (AGENTS.md)

src/main.rs: Use anyhow::Result<T> and anyhow::bail!() for CLI and top-level error handling
CLI command and subcommand changes go in src/main.rs using clap derive macros

Files:

  • src/main.rs
src/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.rs: Use indicatif::ProgressBar for long-running operations
Place inline tests in #[cfg(test)] mod tests at the end of each file, using standard assert! and assert_eq! macros
Use tempfile crate for file I/O tests

Files:

  • src/main.rs
🧠 Learnings (21)
📓 Common learnings
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/{milksad,sha256_chain}.rs : Implement `supports_gpu()` and `analyze_gpu()` methods for GPU-accelerated analyzers
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T18:24:52.371Z
Learning: Applies to src/analyze/**/*.rs : Use masked analysis pattern `(full_key & ((1<<N)-1)) | (1<<(N-1))` for puzzle solving
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/transform/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:44.316Z
Learning: Applies to src/transform/src/analyze/*.rs : For reversible transforms, create a corresponding analyzer at `src/analyze/{name}.rs` to support key recovery analysis
📚 Learning: 2026-03-12T18:24:52.371Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T18:24:52.371Z
Learning: Applies to src/analyze/**/*.rs : Use masked analysis pattern `(full_key & ((1<<N)-1)) | (1<<(N-1))` for puzzle solving

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/*.rs : Add new analyzer by creating `{name}.rs`, adding to `mod.rs`, and extending `AnalyzerType` enum

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/{mt64,xorshift}.rs : Use `config.cascade_targets` for multi-target verification in cascade filtering

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:44.316Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/transform/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:44.316Z
Learning: Applies to src/transform/src/analyze/*.rs : For reversible transforms, create a corresponding analyzer at `src/analyze/{name}.rs` to support key recovery analysis

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/{milksad,sha256_chain}.rs : Implement `supports_gpu()` and `analyze_gpu()` methods for GPU-accelerated analyzers

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/*.rs : Reuse PRNG implementations from `src/{prng}.rs` instead of duplicating shared logic

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-12T18:24:52.371Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T18:24:52.371Z
Learning: Applies to src/main.rs : CLI command and subcommand changes go in `src/main.rs` using clap derive macros

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/output.rs : Format analysis results as plain text and JSON using utilities in `output.rs`

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/*.rs : Implement `supports_mask()` method and use `config.mask_bits` for masking support

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:44.316Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/transform/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:44.316Z
Learning: Applies to src/transform/*.rs : Process inputs as batch operations using `&[Input]` as input and `&mut Vec<(String, Key)>` as output, where the first tuple element is a human-readable source description

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-13T13:20:58.369Z
Learnt from: oritwoen
Repo: oritwoen/vuke PR: 76
File: src/source/wordlist.rs:134-143
Timestamp: 2026-03-13T13:20:58.369Z
Learning: Do not flag .ok() calls on output.hit() / output.key() inside Rayon par_chunks().for_each() closures in Rust files (e.g., src/source/wordlist.rs) as bugs. Rayon for_each requires FnMut() -> (), which cannot propagate Result with ?. This is a known limitation discussed in issue `#77`. Treat these .ok() usages in this pattern as intentional and not regressions; focus review on actual logic or error handling outside this specific closure pattern.

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/{milksad,mt64,lcg,xorshift,sha256_chain}.rs : Use `AtomicBool` for early termination flag across threads in parallel brute-force search

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-12T18:24:52.371Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T18:24:52.371Z
Learning: Applies to src/main.rs : Use `anyhow::Result<T>` and `anyhow::bail!()` for CLI and top-level error handling

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-12T18:24:52.371Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T18:24:52.371Z
Learning: Applies to src/analyze/{mt64,xorshift}.rs : Implement cascade filtering for 64-bit seed spaces (mt64, xorshift) with multi-target verification to avoid false positives

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/{milksad,mt64,lcg,xorshift,sha256_chain}.rs : Use Rayon `par_iter()` for CPU parallelism in brute-force operations

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-05T12:40:29.177Z
Learnt from: oritwoen
Repo: oritwoen/vuke PR: 64
File: src/source/mod.rs:26-32
Timestamp: 2026-03-05T12:40:29.177Z
Learning: In `oritwoen/vuke`, `AGENTS.md` and `src/source/AGENTS.md` describe an **aspirational/future** `Source::process` trait signature (generic `T: Transform`, `O: Output`, with `no_gpu: bool` and `progress: Option<&ProgressBar>` parameters). The **current** implementation in `src/source/mod.rs` uses dynamic dispatch: `fn process(&self, transforms: &[Box<dyn Transform>], deriver: &KeyDeriver, matcher: Option<&Matcher>, output: &dyn Output) -> Result<ProcessStats>`. Migrating to the generic form is blocked by object-safety requirements (`Box<dyn Source>` is used in `src/main.rs`) and is a tracked future refactor. Do not flag the current dynamic-dispatch signature as non-conformant with AGENTS.md.

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-12T18:25:01.029Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/output/AGENTS.md:0-0
Timestamp: 2026-03-12T18:25:01.029Z
Learning: Applies to src/output/console.rs : Compact CSV format for file output should be: `source,transform,privkey_hex,address`

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-12T18:24:52.371Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T18:24:52.371Z
Learning: Applies to src/{transform,source,analyze}/**/*.rs : Use `AtomicBool` for early termination signaling across Rayon threads

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-12T18:25:01.029Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/output/AGENTS.md:0-0
Timestamp: 2026-03-12T18:25:01.029Z
Learning: Applies to src/output/**/*.rs : Output trait must implement three methods: `key()`, `hit()`, and `flush()` with specified signatures

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-22T18:38:29.431Z
Learnt from: oritwoen
Repo: oritwoen/vuke PR: 86
File: src/provider.rs:442-443
Timestamp: 2026-03-22T18:38:29.431Z
Learning: In oritwoen/vuke src/provider.rs, the `derived.p2tr == addr` branch in `verify_key_boha` has no test coverage intentionally — no boha puzzles currently have P2TR/Taproot addresses. The branch is forward-compatible for when taproot puzzles are added to boha. Do not flag missing P2TR test coverage in this function.

Applied to files:

  • src/main.rs
🔇 Additional comments (5)
src/main.rs (5)

1357-1376: Verify report JSON still has no escaping

Same issue as flagged before - puzzle_id, address, address_type, status, and key_input (line 1373) are all raw-interpolated. If any field contains a quote or backslash, JSON breaks.

Consider a #[derive(Serialize)] struct and serde_json::to_string() for robust escaping, or at minimum apply the same escape helper to all string fields.


257-262: LGTM - positional keys now optional

The default 0.. lets --key-file work standalone. App-level empty check handles the "nothing provided" case.


449-463: LGTM - key merging logic

Clean file parsing with comment filtering. Early bail with clear message when no keys provided.


1421-1456: LGTM - analyzer execution loop

Per-key analysis with GPU-first fallback. Progress bars for brute-force only. Feature gates are correct.


1468-1478: LGTM - output aggregation and exit handling

Single key → plain JSON object (backwards compatible). Multiple keys → array. Exit code correctly non-zero when any parse fails.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/main.rs`:
- Line 1329: The separator newline logic currently uses the input index (for (i,
key_input) in key_inputs.iter().enumerate()) to decide whether to print a blank
line, which causes a leading blank when earlier inputs only wrote to stderr;
change the logic to track whether any text has actually been printed to stdout
using a boolean (e.g., printed_any_text_output) instead of i > 0, initialize it
false before the loops, check that flag before emitting the separator, and set
it to true whenever you write the first stdout section (update the same pattern
in the other loops that use i > 0 — the blocks referenced around the other
key-input loops — so all separators rely on printed_any_text_output).
- Around line 1326-1327: The current code collects all per-key JSON blobs into
json_entries and uses join(), buffering the entire output in memory; change the
logic in src/main.rs to stream the JSON array instead: emit `[` once before
producing entries, replace accumulating into `json_entries` by writing each
produced JSON entry immediately to stdout (or the chosen writer), use a boolean
first_entry flag to prefix commas only between entries, and then emit `]` at the
end (ensuring had_error is still set/checked appropriately). Remove the final
join() that concatenates the Vec and any code that assumes json_entries exists;
apply the same streaming refactor to the other block around the 1459-1474 range
so large --json runs don’t buffer all results in RAM.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6b221ae9-3de7-4c06-aa08-4ebb3a26f346

📥 Commits

Reviewing files that changed from the base of the PR and between 9095da7 and 1267098.

📒 Files selected for processing (1)
  • src/main.rs
📜 Review details
🧰 Additional context used
📓 Path-based instructions (3)
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Order imports as: external crates → std → blank line → super:: → blank line → crate::
Prefer ? operator over .unwrap() in new code
Use PascalCase for types and structs
Use snake_case for function and method names
Use SCREAMING_SNAKE_CASE for constants
Use snake_case for file and module names

Files:

  • src/main.rs
src/main.rs

📄 CodeRabbit inference engine (AGENTS.md)

src/main.rs: Use anyhow::Result<T> and anyhow::bail!() for CLI and top-level error handling
CLI command and subcommand changes go in src/main.rs using clap derive macros

Files:

  • src/main.rs
src/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.rs: Use indicatif::ProgressBar for long-running operations
Place inline tests in #[cfg(test)] mod tests at the end of each file, using standard assert! and assert_eq! macros
Use tempfile crate for file I/O tests

Files:

  • src/main.rs
🧠 Learnings (25)
📓 Common learnings
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T18:24:52.371Z
Learning: Applies to src/analyze/**/*.rs : Use masked analysis pattern `(full_key & ((1<<N)-1)) | (1<<(N-1))` for puzzle solving
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/*.rs : Add new analyzer by creating `{name}.rs`, adding to `mod.rs`, and extending `AnalyzerType` enum
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/transform/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:44.316Z
Learning: Applies to src/transform/src/analyze/*.rs : For reversible transforms, create a corresponding analyzer at `src/analyze/{name}.rs` to support key recovery analysis
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/{mt64,xorshift}.rs : Use `config.cascade_targets` for multi-target verification in cascade filtering
📚 Learning: 2026-03-12T18:24:52.371Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T18:24:52.371Z
Learning: Applies to src/main.rs : CLI command and subcommand changes go in `src/main.rs` using clap derive macros

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/*.rs : Add new analyzer by creating `{name}.rs`, adding to `mod.rs`, and extending `AnalyzerType` enum

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:44.316Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/transform/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:44.316Z
Learning: Applies to src/transform/src/analyze/*.rs : For reversible transforms, create a corresponding analyzer at `src/analyze/{name}.rs` to support key recovery analysis

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/output.rs : Format analysis results as plain text and JSON using utilities in `output.rs`

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-12T18:24:52.371Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T18:24:52.371Z
Learning: Applies to src/analyze/**/*.rs : Use masked analysis pattern `(full_key & ((1<<N)-1)) | (1<<(N-1))` for puzzle solving

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/{mt64,xorshift}.rs : Use `config.cascade_targets` for multi-target verification in cascade filtering

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/*.rs : Reuse PRNG implementations from `src/{prng}.rs` instead of duplicating shared logic

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/{milksad,sha256_chain}.rs : Implement `supports_gpu()` and `analyze_gpu()` methods for GPU-accelerated analyzers

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-12T18:24:52.371Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T18:24:52.371Z
Learning: Applies to src/{transform,analyze}/mod.rs : Use factory enums with `create()` and `FromStr` for parsing CLI strings in `TransformType` and `AnalyzerType`

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/*.rs : Implement `supports_mask()` method and use `config.mask_bits` for masking support

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-13T13:20:58.369Z
Learnt from: oritwoen
Repo: oritwoen/vuke PR: 76
File: src/source/wordlist.rs:134-143
Timestamp: 2026-03-13T13:20:58.369Z
Learning: Do not flag .ok() calls on output.hit() / output.key() inside Rayon par_chunks().for_each() closures in Rust files (e.g., src/source/wordlist.rs) as bugs. Rayon for_each requires FnMut() -> (), which cannot propagate Result with ?. This is a known limitation discussed in issue `#77`. Treat these .ok() usages in this pattern as intentional and not regressions; focus review on actual logic or error handling outside this specific closure pattern.

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/{milksad,mt64,lcg,xorshift,sha256_chain}.rs : Use `AtomicBool` for early termination flag across threads in parallel brute-force search

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-12T18:24:52.371Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T18:24:52.371Z
Learning: Applies to src/main.rs : Use `anyhow::Result<T>` and `anyhow::bail!()` for CLI and top-level error handling

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-12T18:24:52.371Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T18:24:52.371Z
Learning: Applies to src/analyze/{mt64,xorshift}.rs : Implement cascade filtering for 64-bit seed spaces (mt64, xorshift) with multi-target verification to avoid false positives

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-05T12:40:29.177Z
Learnt from: oritwoen
Repo: oritwoen/vuke PR: 64
File: src/source/mod.rs:26-32
Timestamp: 2026-03-05T12:40:29.177Z
Learning: In `oritwoen/vuke`, `AGENTS.md` and `src/source/AGENTS.md` describe an **aspirational/future** `Source::process` trait signature (generic `T: Transform`, `O: Output`, with `no_gpu: bool` and `progress: Option<&ProgressBar>` parameters). The **current** implementation in `src/source/mod.rs` uses dynamic dispatch: `fn process(&self, transforms: &[Box<dyn Transform>], deriver: &KeyDeriver, matcher: Option<&Matcher>, output: &dyn Output) -> Result<ProcessStats>`. Migrating to the generic form is blocked by object-safety requirements (`Box<dyn Source>` is used in `src/main.rs`) and is a tracked future refactor. Do not flag the current dynamic-dispatch signature as non-conformant with AGENTS.md.

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/{milksad,mt64,lcg,xorshift,sha256_chain}.rs : Use Rayon `par_iter()` for CPU parallelism in brute-force operations

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-12T18:25:01.029Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/output/AGENTS.md:0-0
Timestamp: 2026-03-12T18:25:01.029Z
Learning: Applies to src/output/console.rs : Compact CSV format for file output should be: `source,transform,privkey_hex,address`

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-12T18:24:52.371Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T18:24:52.371Z
Learning: Applies to src/{transform,source,analyze}/**/*.rs : Use `AtomicBool` for early termination signaling across Rayon threads

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-12T18:25:01.029Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/output/AGENTS.md:0-0
Timestamp: 2026-03-12T18:25:01.029Z
Learning: Applies to src/output/**/*.rs : Output trait must implement three methods: `key()`, `hit()`, and `flush()` with specified signatures

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-22T18:38:29.431Z
Learnt from: oritwoen
Repo: oritwoen/vuke PR: 86
File: src/provider.rs:442-443
Timestamp: 2026-03-22T18:38:29.431Z
Learning: In oritwoen/vuke src/provider.rs, the `derived.p2tr == addr` branch in `verify_key_boha` has no test coverage intentionally — no boha puzzles currently have P2TR/Taproot addresses. The branch is forward-compatible for when taproot puzzles are added to boha. Do not flag missing P2TR test coverage in this function.

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-12T18:25:01.029Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/output/AGENTS.md:0-0
Timestamp: 2026-03-12T18:25:01.029Z
Learning: Applies to src/output/**/*.rs : Use `escape_csv_field()` from `mod.rs` for any field written to CSV in the output module

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/{milksad,mt64,lcg,xorshift,sha256_chain}.rs : Use `indicatif::ProgressBar` for progress indication in long-running operations

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:08.405Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/{mt64,xorshift}.rs : 64-bit seed spaces (mt64, xorshift) MUST use cascade filter for verification

Applied to files:

  • src/main.rs
📚 Learning: 2026-03-02T14:18:44.316Z
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/transform/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:44.316Z
Learning: Applies to src/transform/*.rs : Process inputs as batch operations using `&[Input]` as input and `&mut Vec<(String, Key)>` as output, where the first tuple element is a human-readable source description

Applied to files:

  • src/main.rs

Comment on lines +1326 to +1327
let mut json_entries = Vec::new();
let mut had_error = false;
Copy link
Copy Markdown

@coderabbitai coderabbitai bot Mar 26, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

--json batch mode buffers the whole run in RAM.

Every per-key JSON blob stays in json_entries until the end, then join() allocates one more full copy. vuke analyze --json --key-file big.txt now scales memory with total result size and delays all output until the last key finishes. Stream the array instead: print [ once, write each entry as it is produced with a first_entry flag, then close ].

Also applies to: 1459-1474

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main.rs` around lines 1326 - 1327, The current code collects all per-key
JSON blobs into json_entries and uses join(), buffering the entire output in
memory; change the logic in src/main.rs to stream the JSON array instead: emit
`[` once before producing entries, replace accumulating into `json_entries` by
writing each produced JSON entry immediately to stdout (or the chosen writer),
use a boolean first_entry flag to prefix commas only between entries, and then
emit `]` at the end (ensuring had_error is still set/checked appropriately).
Remove the final join() that concatenates the Vec and any code that assumes
json_entries exists; apply the same streaming refactor to the other block around
the 1459-1474 range so large --json runs don’t buffer all results in RAM.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

For a CLI tool processing key files, we're talking hundreds or thousands of keys at most. Buffering a few KB of JSON strings is fine here - streaming would add complexity for no practical gain.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@oritwoen, fair point. For a key-analysis CLI the dataset is naturally bounded by what a human would actually review, so the buffering cost is negligible in practice. The added complexity of streaming isn't worth it here. Acknowledged.


🧠 Learnings used
Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/output.rs : Format analysis results as plain text and JSON using utilities in `output.rs`

Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/transform/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:44.316Z
Learning: Applies to src/transform/*.rs : Process inputs as batch operations using `&[Input]` as input and `&mut Vec<(String, Key)>` as output, where the first tuple element is a human-readable source description

Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/{milksad,mt64,lcg,xorshift,sha256_chain}.rs : Use Rayon `par_iter()` for CPU parallelism in brute-force operations

Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T18:24:52.371Z
Learning: Applies to src/main.rs : CLI command and subcommand changes go in `src/main.rs` using clap derive macros

Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/transform/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:44.316Z
Learning: Applies to src/transform/src/analyze/*.rs : For reversible transforms, create a corresponding analyzer at `src/analyze/{name}.rs` to support key recovery analysis

Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T18:24:52.371Z
Learning: Applies to src/analyze/**/*.rs : Use masked analysis pattern `(full_key & ((1<<N)-1)) | (1<<(N-1))` for puzzle solving

Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/*.rs : Add new analyzer by creating `{name}.rs`, adding to `mod.rs`, and extending `AnalyzerType` enum

Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/{mt64,xorshift}.rs : Use `config.cascade_targets` for multi-target verification in cascade filtering

Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/*.rs : Reuse PRNG implementations from `src/{prng}.rs` instead of duplicating shared logic

Learnt from: CR
Repo: oritwoen/vuke PR: 0
File: src/analyze/AGENTS.md:0-0
Timestamp: 2026-03-02T14:18:08.405Z
Learning: Applies to src/analyze/analyze/{milksad,sha256_chain}.rs : Implement `supports_gpu()` and `analyze_gpu()` methods for GPU-accelerated analyzers

Learnt from: oritwoen
Repo: oritwoen/vuke PR: 76
File: src/source/wordlist.rs:134-143
Timestamp: 2026-03-13T13:20:58.369Z
Learning: Do not flag .ok() calls on output.hit() / output.key() inside Rayon par_chunks().for_each() closures in Rust files (e.g., src/source/wordlist.rs) as bugs. Rayon for_each requires FnMut() -> (), which cannot propagate Result with ?. This is a known limitation discussed in issue `#77`. Treat these .ok() usages in this pattern as intentional and not regressions; focus review on actual logic or error handling outside this specific closure pattern.

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

0 issues found across 1 file (changes from recent commits).

Requires human review: Refactors core logic in run_analyze to support multiple inputs and modifies the CLI output format (JSON array), which is a high-impact change requiring human review.

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 1 file (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/main.rs">

<violation number="1" location="src/main.rs:1342">
P2: `key_input` is written into JSON without escaping, so certain key strings produce invalid JSON output.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

src/main.rs Outdated
.replace('\t', "\\t");
json_entries.push(format!(
r#"{{"key":"{}","error":"{}"}}"#,
key_input, err_msg
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot Mar 26, 2026

Choose a reason for hiding this comment

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

P2: key_input is written into JSON without escaping, so certain key strings produce invalid JSON output.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/main.rs, line 1342:

<comment>`key_input` is written into JSON without escaping, so certain key strings produce invalid JSON output.</comment>

<file context>
@@ -1331,10 +1331,15 @@ fn run_analyze(
                         r#"{{"key":"{}","error":"{}"}}"#,
-                        key_input,
-                        e.to_string().replace('"', "\\\"")
+                        key_input, err_msg
                     ));
                 } else {
</file context>
Fix with Cubic

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

0 issues found across 1 file (changes from recent commits).

Requires human review: This PR introduces a new feature and includes a significant refactor of the 'analyze' command's logic, including file I/O and CLI interface changes.

Sign up for free to 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.

Accept multiple keys in analyze subcommand

1 participant