Skip to content

refactor(collection): centralize dispatch registry#141

Open
oritwoen wants to merge 3 commits intomainfrom
refactor/collection-dispatch
Open

refactor(collection): centralize dispatch registry#141
oritwoen wants to merge 3 commits intomainfrom
refactor/collection-dispatch

Conversation

@oritwoen
Copy link
Owner

Collection name dispatch lived in several separate match blocks across the library and CLI, which makes adding a new collection easy to miss in one path. #119 calls out that drift directly, and #115 was the shape of bug it can cause.

This introduces a single Collection registry in the library with canonical names, alias parsing, puzzle slices, get, all, and author dispatch. The CLI now goes through that registry for list, search, author, and export instead of maintaining its own copies.

I also added unit coverage for alias parsing and registry iteration so future collection additions have one obvious place to wire in.

Verification:

  • cargo test --all-features
  • cargo fmt --check
  • cargo clippy --all-features -- -D warnings
  • cubic review
  • coderabbit review (interactive TUI launched, no non-interactive verdict available here)

Closes #119.

@oritwoen oritwoen self-assigned this Mar 24, 2026
@coderabbitai
Copy link

coderabbitai bot commented Mar 24, 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: 3a315aa6-a83e-4e46-9961-b3ccae03082c

📥 Commits

Reviewing files that changed from the base of the PR and between 5d1fc19 and cf1d02b.

📒 Files selected for processing (1)
  • src/lib.rs
📜 Recent review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: cubic · AI code reviewer
🧰 Additional context used
📓 Path-based instructions (1)
src/lib.rs

📄 CodeRabbit inference engine (AGENTS.md)

Implement lib.rs public API with three core functions: get(id) for puzzle lookup, all() for iterating puzzles, and stats() for aggregate statistics

Files:

  • src/lib.rs
🧠 Learnings (13)
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to src/lib.rs : Implement lib.rs public API with three core functions: get(id) for puzzle lookup, all() for iterating puzzles, and stats() for aggregate statistics

Applied to files:

  • src/lib.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to data/**/*.jsonc : Use puzzle ID format `collection/identifier` (e.g., b1000/66, bitimage/kitten), with exceptions for gsmg and bitaps (no slash)

Applied to files:

  • src/lib.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to src/collections/*.rs : Generate static `&[Puzzle]` arrays via build.rs using `include!()` into src/collections/*.rs files

Applied to files:

  • src/lib.rs
📚 Learning: 2026-03-15T19:09:49.536Z
Learnt from: oritwoen
Repo: oritwoen/boha PR: 122
File: src/puzzle.rs:104-117
Timestamp: 2026-03-15T19:09:49.536Z
Learning: Applies to {src/puzzle.rs,src/balance.rs}: The `Chain` enum in `src/puzzle.rs` supports: Bitcoin, Ethereum, Litecoin, Monero, Decred, and Arweave (added in PR `#111`) — any new chains must be added to both the enum and `src/balance.rs` API integration. Arweave balance fetching is not yet implemented in `src/balance.rs` (tracked in issue `#123`).

Applied to files:

  • src/lib.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to src/puzzle.rs : Define Puzzle struct with exactly 16 fields covering id, title, description, difficulty, status, author, solver, status_date, reward, addresses, keys, seeds, shares, profiles, and metadata

Applied to files:

  • src/lib.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to tests/author_lineage.rs : In tests/author_lineage.rs, verify funding source tracking and author metadata consistency across all puzzles

Applied to files:

  • src/lib.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: All puzzle data must be compiled to static `&'static` references with no heap allocation at runtime

Applied to files:

  • src/lib.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to src/puzzle.rs : Define Chain enum including Bitcoin, Ethereum, Litecoin, Monero, Decred, and Arweave

Applied to files:

  • src/lib.rs
📚 Learning: 2026-02-21T06:17:19.520Z
Learnt from: oritwoen
Repo: oritwoen/boha PR: 111
File: data/arweave.jsonc:21-21
Timestamp: 2026-02-21T06:17:19.520Z
Learning: In JSONC puzzle data files (data/*.jsonc), the "name" field stores only the puzzle identifier (e.g., "weave1", "kitten", "Level 1"), not the full "collection/identifier" format. The full ID (e.g., "arweave/weave1", "bitimage/kitten") is constructed at build time or runtime by the Rust code in build.rs and collection modules.

Applied to files:

  • src/lib.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to src/puzzle.rs : Use `Option<T>` for all optional fields in puzzle data structures (Address, Key, Seed, Shares, Profile, Author, Solver)

Applied to files:

  • src/lib.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to src/puzzle.rs : Use `&'static str` for all string data in Puzzle structs, never heap-allocated Strings

Applied to files:

  • src/lib.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to src/puzzle.rs : Track both Solver (who revealed/found the key) and Claimer (who swept funds) separately in Puzzle struct, as these may be different people

Applied to files:

  • src/lib.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to tests/validation.rs : In data validation tests (tests/validation.rs), verify cryptographic consistency (h160, script_hash), range validation, and format checks

Applied to files:

  • src/lib.rs
🧬 Code graph analysis (1)
src/lib.rs (9)
src/puzzle.rs (3)
  • name (45-54)
  • name (490-492)
  • collection (486-488)
src/collections/arweave.rs (4)
  • slice (27-29)
  • all (31-33)
  • author (10-12)
  • get (14-25)
src/collections/bitaps.rs (4)
  • slice (19-21)
  • all (23-25)
  • author (11-13)
  • get (15-17)
src/collections/bitimage.rs (4)
  • slice (27-29)
  • all (31-33)
  • author (10-12)
  • get (14-25)
src/collections/gsmg.rs (4)
  • slice (19-21)
  • all (23-25)
  • author (11-13)
  • get (15-17)
src/collections/hash_collision.rs (4)
  • slice (28-30)
  • all (32-34)
  • author (11-13)
  • get (15-26)
src/collections/zden.rs (4)
  • slice (27-29)
  • all (31-33)
  • author (10-12)
  • get (14-25)
src/collections/ballet.rs (4)
  • slice (27-29)
  • all (31-33)
  • author (10-12)
  • get (14-25)
src/collections/b1000.rs (4)
  • slice (29-31)
  • all (33-35)
  • author (14-16)
  • get (18-27)
🔇 Additional comments (6)
src/lib.rs (6)

36-58: Clean enum setup with safety net via tests.

The test at line 229-238 (collection_all_matches_global_iterator) effectively guards against forgetting to add a new variant to ALL - if someone adds a collection module but forgets to update the constant, puzzles would be missing from the registry iterator and the test would fail.


60-115: Solid delegation layer.

Clean 1:1 mapping between enum variants and module functions. The peter_todd alias at line 81 is a nice touch for backward compatibility.


117-146: LGTM.

Singleton handling for Bitaps/Gsmg is clean - require empty name, reject anything else. The B1000 parse-error-to-NotFound behavior (line 123) preserves existing public API semantics per your earlier comment.


148-168: Previous feedback addressed.

Line 157's parts.len() != 2 correctly rejects malformed IDs like b1000/66/extra. The singleton slash rejection at lines 163-165 is a good addition - prevents gsmg/ from accidentally succeeding by hitting the empty-name path.


170-172: Nice simplification.

Previous version likely chained iterators manually. This is clearer and the test at line 229 verifies it produces identical results.


211-299: Test coverage looks solid.

The collection_all_matches_global_iterator test (line 229) is particularly valuable - it'll catch if someone adds a collection but forgets to update Collection::ALL. The singleton edge cases (empty suffix, non-empty suffix, slash forms) are well covered.


📝 Walkthrough

Walkthrough

Centralized collection dispatch by adding a Collection enum and routing library and CLI operations through it; each collection module gained a slice() accessor, all() now uses that slice; CLI helpers replace duplicated per-collection matches; tests added for parsing and dispatch behavior.

Changes

Cohort / File(s) Summary
Core Collection abstraction
src/lib.rs
Added Collection enum with ALL, name, parse, slice, all, author, and get. Refactored crate-level get() and all() to dispatch through Collection. Added unit tests for aliasing, enumeration equivalence, and get() path/format rules.
CLI refactor & helpers
src/cli.rs
Removed per-collection match chains; added collection_help(include_all: bool) and collection_or_exit(name, include_all) helpers. Updated cmd_search, cmd_list, cmd_author, and cmd_export to use centralized Collection parsing/iteration and deduplication.
Collection modules — slice() accessor
src/collections/arweave.rs, src/collections/b1000.rs, src/collections/ballet.rs, src/collections/bitaps.rs, src/collections/bitimage.rs, src/collections/gsmg.rs, src/collections/hash_collision.rs, src/collections/zden.rs
Added pub fn slice() -> &'static [Puzzle] to each module and changed all() to iterate from slice().iter() (replaced PUZZLES.iter()/once(&PUZZLE)). No changes to get(), solved(), unsolved(), or count() behaviors.
Tests
src/lib.rs (tests section)
New tests validating Collection::parse (including alias peter_toddhash_collision), that Collection::ALL flattened equals crate all(), and Collection::get/crate get() acceptance/rejection for singleton and slash-form IDs.
Exports / API behavior
public crate functions
pub fn get(id: &str) now requires exactly one slash and delegates to Collection::get; gsmg/bitaps are treated as singletons (reject slash forms); crate all() now flattens Collection::ALL.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CLI
    participant CollectionEnum as Collection
    participant Module as CollectionModule

    User->>CLI: run command with collection arg (e.g. list/search/export)
    CLI->>CollectionEnum: collection_or_exit(name, include_all)
    alt parse success
        CollectionEnum-->>CLI: Collection
        CLI->>CollectionEnum: if "all" iterate Collection::ALL else use single Collection
        loop per Collection
            CollectionEnum->>Module: call slice() / all()
            Module-->>CollectionEnum: iterator of &'static Puzzle
            CollectionEnum-->>CLI: flattened puzzles stream
        end
        CLI->>User: present results / export
    else parse failure
        CollectionEnum-->>CLI: print error & exit(1)
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • cubic-dev-ai

Poem

Eight collections once matched in many places,
Now one enum brings them to known faces.
Slices revealed, exports deduped neat,
CLI asks once — answers now repeat.
Tests check edges — the dispatch is complete. 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.73% 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 Title directly describes the main refactoring objective: centralizing the collection dispatch registry that was previously scattered across the codebase.
Description check ✅ Passed Description explains the problem (duplicated dispatch logic across 6+ locations), the solution (single Collection registry), and includes verification steps and issue closure.
Linked Issues check ✅ Passed All code requirements from #119 are met: Collection enum created, canonical names/aliases defined, single registry with all/author/get dispatch, CLI refactored to use registry, unit tests added for alias parsing and registry iteration.
Out of Scope Changes check ✅ Passed All changes directly support centralizing collection dispatch. The slice() additions across collection modules are necessary infrastructure for the new registry pattern.

✏️ 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 refactor/collection-dispatch
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch refactor/collection-dispatch

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

@coderabbitai coderabbitai bot added the enhancement New feature or request label Mar 24, 2026
Copy link

@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.

2 issues found across 10 files

Confidence score: 3/5

  • There is a concrete regression risk in src/lib.rs: slash-form IDs for singleton collections (gsmg/<anything>, bitaps/<anything>) now resolve to the singleton puzzle instead of returning NotFound, which can change user-visible lookup behavior.
  • The src/cli.rs issue is lower risk (help-text drift from hardcoded collection names) and is mostly maintainability/documentation impact rather than runtime correctness.
  • Score is 3 because the top issue is medium severity with high confidence and user-facing behavior impact, while the second issue is minor and non-blocking.
  • Pay close attention to src/lib.rs, src/cli.rs - fix singleton path matching semantics first, then align help text with the centralized registry.
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/cli.rs">

<violation number="1" location="src/cli.rs:1826">
P2: `collection_help` hardcodes collection names, so help text can drift from the centralized registry.</violation>
</file>

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

<violation number="1" location="src/lib.rs:151">
P2: Slash-form IDs for singleton collections are now accepted by mistake. `gsmg/<anything>` and `bitaps/<anything>` should still be `NotFound`, but this path returns the singleton puzzle.</violation>
</file>
Architecture diagram
sequenceDiagram
    participant U as User / Caller
    participant CLI as CLI (cli.rs)
    participant R as Registry (Collection Enum)
    participant M as Sub-Modules (arweave, b1000, etc.)

    Note over U,M: Search / List / Author / Export Flow

    U->>CLI: Execute command (e.g., search "peter_todd")
    CLI->>R: CHANGED: Collection::parse(name)
    
    alt Valid Collection Name or Alias
        R-->>CLI: Return Collection variant (e.g., HashCollision)
        CLI->>R: NEW: collection.all() / .author() / .get()
        R->>M: Dispatch to specific module (e.g., hash_collision::slice())
        M-->>R: Return static data / iterator
        R-->>CLI: Return data
        CLI->>U: Format and display results
    else Invalid Collection
        R-->>CLI: Return Error::InvalidCollection
        CLI->>CLI: NEW: collection_or_exit() handles error
        CLI->>U: Print suggested collections & Exit(1)
    end

    Note over U,M: Library Global Access Flow (boha::all)

    U->>R: boha::all()
    loop For each variant in Collection::ALL
        R->>R: NEW: collection.all()
        R->>M: Call module-specific slice().iter()
        M-->>R: Return Iterator
    end
    R-->>U: Return FlatMap Iterator of all puzzles

    Note over U,M: Deep Link Access Flow (boha::get)

    U->>R: boha::get("b1000/66")
    R->>R: CHANGED: Parse prefix into Collection variant
    R->>R: NEW: collection.get("66")
    R->>M: b1000::get(66)
    M-->>R: Return &Puzzle
    R-->>U: Return Result<&Puzzle>
Loading

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

Copy link

@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/cli.rs`:
- Around line 1826-1832: The help string is hardcoded and duplicates
Collection::ALL; change collection_help to build the string from Collection::ALL
instead of a static literal: make fn collection_help(include_all: bool) ->
String, map Collection::ALL.iter().map(|c| c.name()) into a Vec, replace the
"hash_collision" entry with "hash_collision (peter_todd)" (or adjust at
display), push "all" when include_all is true, then join with ", " and return
the String; update any callers expecting &'static str to accept String.

In `@src/lib.rs`:
- Around line 117-134: The B1000 branch in Collection::get currently maps parse
failures from name.parse::<u32>() to Error::NotFound, losing the real cause;
change that branch to convert parse errors into a clear, specific error (e.g.,
Error::InvalidInput or an Error::BadRequest message) that includes the offending
input and parse error details (use map_err(|e|
Error::InvalidInput(format!("invalid B1000 index '{}': {}", name, e))) or add a
new Error variant if needed) before calling b1000::get(num), so callers get a
descriptive error when "foo" is passed instead of a number.
🪄 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: f637c0b7-cdad-4392-852b-906be4f60af3

📥 Commits

Reviewing files that changed from the base of the PR and between 733de37 and 2fa4fa7.

📒 Files selected for processing (10)
  • src/cli.rs
  • src/collections/arweave.rs
  • src/collections/b1000.rs
  • src/collections/ballet.rs
  • src/collections/bitaps.rs
  • src/collections/bitimage.rs
  • src/collections/gsmg.rs
  • src/collections/hash_collision.rs
  • src/collections/zden.rs
  • src/lib.rs
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: cubic · AI code reviewer
🧰 Additional context used
📓 Path-based instructions (3)
src/collections/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

Generate static &[Puzzle] arrays via build.rs using include!() into src/collections/*.rs files

Files:

  • src/collections/arweave.rs
  • src/collections/bitimage.rs
  • src/collections/ballet.rs
  • src/collections/b1000.rs
  • src/collections/gsmg.rs
  • src/collections/zden.rs
  • src/collections/bitaps.rs
  • src/collections/hash_collision.rs
src/cli.rs

📄 CodeRabbit inference engine (AGENTS.md)

src/cli.rs: Implement CLI binary in src/cli.rs using clap derive macros, not src/main.rs, and gate behind --features cli
In src/cli.rs, use clap for argument parsing, tabled for table output, owo-colors for colored output, and human-panic for panic messages

Files:

  • src/cli.rs
src/lib.rs

📄 CodeRabbit inference engine (AGENTS.md)

Implement lib.rs public API with three core functions: get(id) for puzzle lookup, all() for iterating puzzles, and stats() for aggregate statistics

Files:

  • src/lib.rs
🧠 Learnings (20)
📓 Common learnings
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to src/collections/*.rs : Generate static `&[Puzzle]` arrays via build.rs using `include!()` into src/collections/*.rs files
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to src/collections/*.rs : Generate static `&[Puzzle]` arrays via build.rs using `include!()` into src/collections/*.rs files

Applied to files:

  • src/collections/arweave.rs
  • src/collections/bitimage.rs
  • src/collections/ballet.rs
  • src/collections/b1000.rs
  • src/collections/gsmg.rs
  • src/collections/zden.rs
  • src/collections/bitaps.rs
  • src/collections/hash_collision.rs
  • src/cli.rs
  • src/lib.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to src/puzzle.rs : Use `&'static str` for all string data in Puzzle structs, never heap-allocated Strings

Applied to files:

  • src/collections/arweave.rs
  • src/collections/bitimage.rs
  • src/collections/ballet.rs
  • src/collections/b1000.rs
  • src/collections/gsmg.rs
  • src/collections/zden.rs
  • src/collections/bitaps.rs
  • src/collections/hash_collision.rs
  • src/lib.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to src/lib.rs : Implement lib.rs public API with three core functions: get(id) for puzzle lookup, all() for iterating puzzles, and stats() for aggregate statistics

Applied to files:

  • src/collections/arweave.rs
  • src/collections/bitimage.rs
  • src/collections/ballet.rs
  • src/collections/b1000.rs
  • src/collections/gsmg.rs
  • src/collections/zden.rs
  • src/collections/bitaps.rs
  • src/collections/hash_collision.rs
  • src/cli.rs
  • src/lib.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to src/puzzle.rs : Define Puzzle struct with exactly 16 fields covering id, title, description, difficulty, status, author, solver, status_date, reward, addresses, keys, seeds, shares, profiles, and metadata

Applied to files:

  • src/collections/arweave.rs
  • src/collections/bitimage.rs
  • src/collections/ballet.rs
  • src/collections/b1000.rs
  • src/collections/gsmg.rs
  • src/collections/zden.rs
  • src/collections/bitaps.rs
  • src/collections/hash_collision.rs
  • src/cli.rs
  • src/lib.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: All puzzle data must be compiled to static `&'static` references with no heap allocation at runtime

Applied to files:

  • src/collections/arweave.rs
  • src/collections/bitimage.rs
  • src/collections/ballet.rs
  • src/collections/b1000.rs
  • src/collections/gsmg.rs
  • src/collections/zden.rs
  • src/collections/bitaps.rs
  • src/collections/hash_collision.rs
  • src/cli.rs
  • src/lib.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to src/puzzle.rs : Use `Option<T>` for all optional fields in puzzle data structures (Address, Key, Seed, Shares, Profile, Author, Solver)

Applied to files:

  • src/collections/arweave.rs
  • src/collections/bitimage.rs
  • src/collections/ballet.rs
  • src/collections/b1000.rs
  • src/collections/gsmg.rs
  • src/collections/zden.rs
  • src/collections/bitaps.rs
  • src/collections/hash_collision.rs
  • src/cli.rs
  • src/lib.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to src/puzzle.rs : Define Chain enum including Bitcoin, Ethereum, Litecoin, Monero, Decred, and Arweave

Applied to files:

  • src/collections/arweave.rs
  • src/collections/bitimage.rs
  • src/collections/b1000.rs
  • src/collections/gsmg.rs
  • src/collections/bitaps.rs
  • src/collections/hash_collision.rs
  • src/cli.rs
  • src/lib.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to src/puzzle.rs : Track both Solver (who revealed/found the key) and Claimer (who swept funds) separately in Puzzle struct, as these may be different people

Applied to files:

  • src/collections/arweave.rs
  • src/collections/bitimage.rs
  • src/collections/ballet.rs
  • src/collections/gsmg.rs
  • src/collections/zden.rs
  • src/collections/bitaps.rs
  • src/collections/hash_collision.rs
  • src/lib.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Do not add runtime configuration - all puzzle data must be embedded at compile time via build.rs codegen

Applied to files:

  • src/collections/arweave.rs
  • src/collections/bitimage.rs
  • src/collections/zden.rs
  • src/collections/bitaps.rs
  • src/collections/hash_collision.rs
📚 Learning: 2026-03-15T19:09:49.536Z
Learnt from: oritwoen
Repo: oritwoen/boha PR: 122
File: src/puzzle.rs:104-117
Timestamp: 2026-03-15T19:09:49.536Z
Learning: Applies to {src/puzzle.rs,src/balance.rs}: The `Chain` enum in `src/puzzle.rs` supports: Bitcoin, Ethereum, Litecoin, Monero, Decred, and Arweave (added in PR `#111`) — any new chains must be added to both the enum and `src/balance.rs` API integration. Arweave balance fetching is not yet implemented in `src/balance.rs` (tracked in issue `#123`).

Applied to files:

  • src/collections/arweave.rs
  • src/cli.rs
  • src/lib.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to src/puzzle.rs : For Bitcoin/crypto addresses, include kind field with values: P2PKH (legacy), P2SH (script), P2WPKH/P2WSH (SegWit), P2TR (Taproot)

Applied to files:

  • src/collections/bitimage.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to tests/author_lineage.rs : In tests/author_lineage.rs, verify funding source tracking and author metadata consistency across all puzzles

Applied to files:

  • src/collections/bitaps.rs
  • src/lib.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to src/cli.rs : In src/cli.rs, use clap for argument parsing, tabled for table output, owo-colors for colored output, and human-panic for panic messages

Applied to files:

  • src/cli.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to src/cli.rs : Implement CLI binary in src/cli.rs using clap derive macros, not src/main.rs, and gate behind --features cli

Applied to files:

  • src/cli.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to src/balance.rs : In src/balance.rs, implement multi-chain async balance fetching for BTC/LTC/ETH using mempool.space and Etherscan APIs

Applied to files:

  • src/cli.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to src/balance.rs : Use mempool.space API for Bitcoin and Litecoin balance fetching in src/balance.rs

Applied to files:

  • src/cli.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to tests/validation.rs : In data validation tests (tests/validation.rs), verify cryptographic consistency (h160, script_hash), range validation, and format checks

Applied to files:

  • src/cli.rs
  • src/lib.rs
📚 Learning: 2026-02-21T06:17:19.520Z
Learnt from: oritwoen
Repo: oritwoen/boha PR: 111
File: data/arweave.jsonc:21-21
Timestamp: 2026-02-21T06:17:19.520Z
Learning: In JSONC puzzle data files (data/*.jsonc), the "name" field stores only the puzzle identifier (e.g., "weave1", "kitten", "Level 1"), not the full "collection/identifier" format. The full ID (e.g., "arweave/weave1", "bitimage/kitten") is constructed at build time or runtime by the Rust code in build.rs and collection modules.

Applied to files:

  • src/lib.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to data/**/*.jsonc : Use puzzle ID format `collection/identifier` (e.g., b1000/66, bitimage/kitten), with exceptions for gsmg and bitaps (no slash)

Applied to files:

  • src/lib.rs
🧬 Code graph analysis (10)
src/collections/arweave.rs (8)
src/collections/b1000.rs (2)
  • slice (29-31)
  • all (33-35)
src/collections/ballet.rs (2)
  • slice (27-29)
  • all (31-33)
src/collections/bitaps.rs (2)
  • slice (19-21)
  • all (23-25)
src/collections/bitimage.rs (2)
  • slice (27-29)
  • all (31-33)
src/collections/gsmg.rs (2)
  • slice (19-21)
  • all (23-25)
src/collections/hash_collision.rs (2)
  • slice (28-30)
  • all (32-34)
src/collections/zden.rs (2)
  • slice (27-29)
  • all (31-33)
src/lib.rs (3)
  • slice (87-98)
  • all (100-102)
  • all (154-156)
src/collections/bitimage.rs (8)
src/collections/arweave.rs (2)
  • slice (27-29)
  • all (31-33)
src/collections/b1000.rs (2)
  • slice (29-31)
  • all (33-35)
src/collections/ballet.rs (2)
  • slice (27-29)
  • all (31-33)
src/collections/bitaps.rs (2)
  • slice (19-21)
  • all (23-25)
src/collections/gsmg.rs (2)
  • slice (19-21)
  • all (23-25)
src/collections/hash_collision.rs (2)
  • slice (28-30)
  • all (32-34)
src/collections/zden.rs (2)
  • slice (27-29)
  • all (31-33)
src/lib.rs (3)
  • slice (87-98)
  • all (100-102)
  • all (154-156)
src/collections/ballet.rs (8)
src/collections/arweave.rs (2)
  • slice (27-29)
  • all (31-33)
src/collections/b1000.rs (2)
  • slice (29-31)
  • all (33-35)
src/collections/bitaps.rs (2)
  • slice (19-21)
  • all (23-25)
src/collections/bitimage.rs (2)
  • slice (27-29)
  • all (31-33)
src/collections/gsmg.rs (2)
  • slice (19-21)
  • all (23-25)
src/collections/hash_collision.rs (2)
  • slice (28-30)
  • all (32-34)
src/collections/zden.rs (2)
  • slice (27-29)
  • all (31-33)
src/lib.rs (3)
  • slice (87-98)
  • all (100-102)
  • all (154-156)
src/collections/b1000.rs (8)
src/collections/arweave.rs (2)
  • slice (27-29)
  • all (31-33)
src/collections/ballet.rs (2)
  • slice (27-29)
  • all (31-33)
src/collections/bitaps.rs (2)
  • slice (19-21)
  • all (23-25)
src/collections/bitimage.rs (2)
  • slice (27-29)
  • all (31-33)
src/collections/gsmg.rs (2)
  • slice (19-21)
  • all (23-25)
src/collections/hash_collision.rs (2)
  • slice (28-30)
  • all (32-34)
src/collections/zden.rs (2)
  • slice (27-29)
  • all (31-33)
src/lib.rs (3)
  • slice (87-98)
  • all (100-102)
  • all (154-156)
src/collections/gsmg.rs (3)
src/collections/arweave.rs (2)
  • slice (27-29)
  • all (31-33)
src/collections/bitaps.rs (2)
  • slice (19-21)
  • all (23-25)
src/lib.rs (3)
  • slice (87-98)
  • all (100-102)
  • all (154-156)
src/collections/zden.rs (8)
src/collections/arweave.rs (2)
  • slice (27-29)
  • all (31-33)
src/collections/b1000.rs (2)
  • slice (29-31)
  • all (33-35)
src/collections/ballet.rs (2)
  • slice (27-29)
  • all (31-33)
src/collections/bitaps.rs (2)
  • slice (19-21)
  • all (23-25)
src/collections/bitimage.rs (2)
  • slice (27-29)
  • all (31-33)
src/collections/gsmg.rs (2)
  • slice (19-21)
  • all (23-25)
src/collections/hash_collision.rs (2)
  • slice (28-30)
  • all (32-34)
src/lib.rs (3)
  • slice (87-98)
  • all (100-102)
  • all (154-156)
src/collections/bitaps.rs (8)
src/collections/arweave.rs (2)
  • slice (27-29)
  • all (31-33)
src/collections/b1000.rs (2)
  • slice (29-31)
  • all (33-35)
src/collections/ballet.rs (2)
  • slice (27-29)
  • all (31-33)
src/collections/bitimage.rs (2)
  • slice (27-29)
  • all (31-33)
src/collections/gsmg.rs (2)
  • slice (19-21)
  • all (23-25)
src/collections/hash_collision.rs (2)
  • slice (28-30)
  • all (32-34)
src/collections/zden.rs (2)
  • slice (27-29)
  • all (31-33)
src/lib.rs (3)
  • slice (87-98)
  • all (100-102)
  • all (154-156)
src/collections/hash_collision.rs (8)
src/collections/arweave.rs (2)
  • slice (27-29)
  • all (31-33)
src/collections/b1000.rs (2)
  • slice (29-31)
  • all (33-35)
src/collections/ballet.rs (2)
  • slice (27-29)
  • all (31-33)
src/collections/bitaps.rs (2)
  • slice (19-21)
  • all (23-25)
src/collections/bitimage.rs (2)
  • slice (27-29)
  • all (31-33)
src/collections/gsmg.rs (2)
  • slice (19-21)
  • all (23-25)
src/collections/zden.rs (2)
  • slice (27-29)
  • all (31-33)
src/lib.rs (3)
  • slice (87-98)
  • all (100-102)
  • all (154-156)
src/cli.rs (3)
src/puzzle.rs (3)
  • collection (486-488)
  • name (45-54)
  • name (490-492)
tests/cli.rs (1)
  • boha (4-8)
src/lib.rs (6)
  • all (100-102)
  • all (154-156)
  • author (104-115)
  • name (60-71)
  • name (121-122)
  • parse (73-85)
src/lib.rs (9)
src/puzzle.rs (2)
  • name (45-54)
  • name (490-492)
src/collections/arweave.rs (4)
  • slice (27-29)
  • all (31-33)
  • author (10-12)
  • get (14-25)
src/collections/b1000.rs (4)
  • slice (29-31)
  • all (33-35)
  • author (14-16)
  • get (18-27)
src/collections/ballet.rs (4)
  • slice (27-29)
  • all (31-33)
  • author (10-12)
  • get (14-25)
src/collections/bitaps.rs (4)
  • slice (19-21)
  • all (23-25)
  • author (11-13)
  • get (15-17)
src/collections/bitimage.rs (4)
  • slice (27-29)
  • all (31-33)
  • author (10-12)
  • get (14-25)
src/collections/gsmg.rs (4)
  • slice (19-21)
  • all (23-25)
  • author (11-13)
  • get (15-17)
src/collections/hash_collision.rs (4)
  • slice (28-30)
  • all (32-34)
  • author (11-13)
  • get (15-26)
src/collections/zden.rs (4)
  • slice (27-29)
  • all (31-33)
  • author (10-12)
  • get (14-25)
🔇 Additional comments (24)
src/collections/hash_collision.rs (1)

28-30: slice()/all() wiring is correct.

Line 28 exposes a static slice and Line 33 iterates from that source, which keeps behavior unchanged while matching the central registry flow.

Also applies to: 32-33

src/collections/zden.rs (1)

27-29: Good centralization hook for Zden collection.

Using slice().iter() here is the right move for consistency with Collection::slice() dispatch.

Also applies to: 31-32

src/collections/bitimage.rs (1)

27-29: This refactor is clean and safe.

all() now derives from the same canonical slice source, so registry-driven enumeration stays consistent.

Also applies to: 31-32

src/collections/arweave.rs (1)

27-29: Arweave module now matches the shared collection contract.

No behavior break here, and it removes one more direct dependency on module-local iteration style.

Also applies to: 31-32

src/collections/ballet.rs (1)

27-29: Ballet slice() + all() update looks correct.

This keeps iteration behavior stable while standardizing how the registry consumes collection data.

Also applies to: 31-32

src/collections/gsmg.rs (1)

19-21: Single-item slice handling is right here.

std::slice::from_ref(&PUZZLE) is a solid fit for GSMG and keeps the API aligned with multi-item collections.

Also applies to: 23-24

src/collections/bitaps.rs (1)

19-21: Bitaps refactor is correct.

This keeps the one-puzzle module compatible with the same slice()-driven registry path as every other collection.

Also applies to: 23-24

src/collections/b1000.rs (1)

29-31: B1000 integration with the shared collection path is solid.

all() now correctly flows through the same source used by registry-based dispatch.

Also applies to: 33-34

src/lib.rs (9)

36-46: LGTM!

Clean enum definition with appropriate derives. Copy is right since it's just a discriminant.


48-58: LGTM!

ALL array lists all 8 variants. Order matches enum declaration which is nice for maintainability.


60-71: LGTM!

const fn is correct here since it's just returning static str slices.


73-85: LGTM!

Alias peter_toddHashCollision matches the PR objectives. Single place to add new collections/aliases now.


87-102: LGTM!

slice() and all() dispatch cleanly. The all() return type std::slice::Iter<'static, Puzzle> is concrete which is good for the flat_map usage in the global all().


104-115: LGTM!

Author dispatch follows the same pattern. Consistent.


136-152: LGTM!

The refactored get() properly delegates to Collection::parse and Collection::get. The special-casing for gsmg and bitaps (no slash in ID) is preserved. Error mapping from InvalidCollection to NotFound maintains backward compatibility.


154-156: LGTM!

Clean one-liner. Collection::ALL.into_iter().flat_map(Collection::all) is idiomatic.


195-239: LGTM!

Tests cover the key behaviors:

  • Alias parsing (peter_todd)
  • Iterator equivalence between registry-driven and global all()
  • Singleton get (gsmg, bitaps) and numbered puzzle get (b1000)

Good coverage for the new registry.

src/cli.rs (7)

1-3: LGTM!

Import updated to include Collection from boha. Clean.


1149-1152: LGTM!

cmd_search now delegates collection parsing to the central helper. The Some("all") | None branch correctly falls back to boha::all().


1189-1193: LGTM!

cmd_list refactored to use collection_or_exit. Logic preserved: "all" uses global iterator, otherwise per-collection.


1256-1258: LGTM!

cmd_author simplified. include_all: false is correct here since "all" doesn't make sense for author lookup.


1746-1761: LGTM!

Export now uses Collection::ALL.to_vec() for the default/all case. Deduplication via seen.insert(canonical.name()) works correctly.


1765-1774: LGTM!

Loop body uses collection.name(), collection.author(), and collection.all() consistently. Status filtering preserved.


1834-1846: LGTM!

Clean helper. Exits with code 1 on invalid collection, shows helpful message with valid options.

Comment on lines +117 to +134
pub fn get(self, name: &str) -> Result<&'static Puzzle> {
match self {
Self::Arweave => arweave::get(name),
Self::B1000 => {
let num = name
.parse::<u32>()
.map_err(|_| Error::NotFound(format!("{}/{}", self.name(), name)))?;
b1000::get(num)
}
Self::Ballet => ballet::get(name),
Self::Bitaps => Ok(bitaps::get()),
Self::Bitimage => bitimage::get(name),
Self::Gsmg => Ok(gsmg::get()),
Self::HashCollision => hash_collision::get(name),
Self::Zden => zden::get(name),
}
}
}
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

B1000 get() silently converts parse errors to NotFound.

When name.parse::<u32>() fails (e.g., user passes "foo" instead of a number), you return Error::NotFound. This loses the real cause - the input wasn't a number. Not a bug per se, but if someone passes b1000/abc they'll get "not found" when the real issue is "that's not a number".

Singleton collections (Bitaps, Gsmg) ignore the name argument entirely which is fine - calling Collection::Gsmg.get("garbage") still returns the puzzle. Might want to document that behavior or reject non-empty input, but it's harmless.

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

In `@src/lib.rs` around lines 117 - 134, The B1000 branch in Collection::get
currently maps parse failures from name.parse::<u32>() to Error::NotFound,
losing the real cause; change that branch to convert parse errors into a clear,
specific error (e.g., Error::InvalidInput or an Error::BadRequest message) that
includes the offending input and parse error details (use map_err(|e|
Error::InvalidInput(format!("invalid B1000 index '{}': {}", name, e))) or add a
new Error variant if needed) before calling b1000::get(num), so callers get a
descriptive error when "foo" is passed instead of a number.

Copy link
Owner Author

Choose a reason for hiding this comment

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

Leaving this as NotFound. boha::get("b1000/foo") behaved that way before the registry refactor too, so changing it here would widen the public error surface rather than fix a regression from this PR.

@coderabbitai coderabbitai bot added the refactor Code improvement without behavior change label Mar 24, 2026
Copy link

@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/lib.rs`:
- Around line 156-167: The current get(id) logic splits id by '/' and only
checks parts.len() < 2, which allows extra slash segments like "b1000/66/extra"
to be accepted; change the validation to require exactly two segments by
replacing the parts length check to require parts.len() == 2 (return
Err(Error::NotFound(id.to_string())) otherwise) so malformed IDs with extra
slashes are rejected; keep using Collection::parse(parts[0]) and the existing
exclusion for Collection::Gsmg | Collection::Bitaps and then call
collection.get(parts[1]) as before.
🪄 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: d3f4e3ac-7a12-4854-b10d-e7a4f901dd5f

📥 Commits

Reviewing files that changed from the base of the PR and between 2fa4fa7 and 5d1fc19.

📒 Files selected for processing (2)
  • src/cli.rs
  • src/lib.rs
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: cubic · AI code reviewer
🧰 Additional context used
📓 Path-based instructions (2)
src/lib.rs

📄 CodeRabbit inference engine (AGENTS.md)

Implement lib.rs public API with three core functions: get(id) for puzzle lookup, all() for iterating puzzles, and stats() for aggregate statistics

Files:

  • src/lib.rs
src/cli.rs

📄 CodeRabbit inference engine (AGENTS.md)

src/cli.rs: Implement CLI binary in src/cli.rs using clap derive macros, not src/main.rs, and gate behind --features cli
In src/cli.rs, use clap for argument parsing, tabled for table output, owo-colors for colored output, and human-panic for panic messages

Files:

  • src/cli.rs
🧠 Learnings (17)
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to src/lib.rs : Implement lib.rs public API with three core functions: get(id) for puzzle lookup, all() for iterating puzzles, and stats() for aggregate statistics

Applied to files:

  • src/lib.rs
  • src/cli.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to src/collections/*.rs : Generate static `&[Puzzle]` arrays via build.rs using `include!()` into src/collections/*.rs files

Applied to files:

  • src/lib.rs
  • src/cli.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to data/**/*.jsonc : Use puzzle ID format `collection/identifier` (e.g., b1000/66, bitimage/kitten), with exceptions for gsmg and bitaps (no slash)

Applied to files:

  • src/lib.rs
📚 Learning: 2026-03-15T19:09:49.536Z
Learnt from: oritwoen
Repo: oritwoen/boha PR: 122
File: src/puzzle.rs:104-117
Timestamp: 2026-03-15T19:09:49.536Z
Learning: Applies to {src/puzzle.rs,src/balance.rs}: The `Chain` enum in `src/puzzle.rs` supports: Bitcoin, Ethereum, Litecoin, Monero, Decred, and Arweave (added in PR `#111`) — any new chains must be added to both the enum and `src/balance.rs` API integration. Arweave balance fetching is not yet implemented in `src/balance.rs` (tracked in issue `#123`).

Applied to files:

  • src/lib.rs
  • src/cli.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to src/puzzle.rs : Define Puzzle struct with exactly 16 fields covering id, title, description, difficulty, status, author, solver, status_date, reward, addresses, keys, seeds, shares, profiles, and metadata

Applied to files:

  • src/lib.rs
  • src/cli.rs
📚 Learning: 2026-02-21T06:17:19.520Z
Learnt from: oritwoen
Repo: oritwoen/boha PR: 111
File: data/arweave.jsonc:21-21
Timestamp: 2026-02-21T06:17:19.520Z
Learning: In JSONC puzzle data files (data/*.jsonc), the "name" field stores only the puzzle identifier (e.g., "weave1", "kitten", "Level 1"), not the full "collection/identifier" format. The full ID (e.g., "arweave/weave1", "bitimage/kitten") is constructed at build time or runtime by the Rust code in build.rs and collection modules.

Applied to files:

  • src/lib.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to src/puzzle.rs : Define Chain enum including Bitcoin, Ethereum, Litecoin, Monero, Decred, and Arweave

Applied to files:

  • src/lib.rs
  • src/cli.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to src/puzzle.rs : Use `&'static str` for all string data in Puzzle structs, never heap-allocated Strings

Applied to files:

  • src/lib.rs
  • src/cli.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to tests/author_lineage.rs : In tests/author_lineage.rs, verify funding source tracking and author metadata consistency across all puzzles

Applied to files:

  • src/lib.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: All puzzle data must be compiled to static `&'static` references with no heap allocation at runtime

Applied to files:

  • src/lib.rs
  • src/cli.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to src/puzzle.rs : Use `Option<T>` for all optional fields in puzzle data structures (Address, Key, Seed, Shares, Profile, Author, Solver)

Applied to files:

  • src/lib.rs
  • src/cli.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to src/puzzle.rs : Track both Solver (who revealed/found the key) and Claimer (who swept funds) separately in Puzzle struct, as these may be different people

Applied to files:

  • src/lib.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to tests/validation.rs : In data validation tests (tests/validation.rs), verify cryptographic consistency (h160, script_hash), range validation, and format checks

Applied to files:

  • src/lib.rs
  • src/cli.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to src/cli.rs : In src/cli.rs, use clap for argument parsing, tabled for table output, owo-colors for colored output, and human-panic for panic messages

Applied to files:

  • src/cli.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to src/cli.rs : Implement CLI binary in src/cli.rs using clap derive macros, not src/main.rs, and gate behind --features cli

Applied to files:

  • src/cli.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to src/balance.rs : In src/balance.rs, implement multi-chain async balance fetching for BTC/LTC/ETH using mempool.space and Etherscan APIs

Applied to files:

  • src/cli.rs
📚 Learning: 2026-03-15T22:40:42.886Z
Learnt from: CR
Repo: oritwoen/boha PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T22:40:42.886Z
Learning: Applies to src/balance.rs : Use mempool.space API for Bitcoin and Litecoin balance fetching in src/balance.rs

Applied to files:

  • src/cli.rs
🧬 Code graph analysis (2)
src/lib.rs (9)
src/puzzle.rs (3)
  • name (45-54)
  • name (490-492)
  • collection (486-488)
src/collections/ballet.rs (4)
  • slice (27-29)
  • all (31-33)
  • author (10-12)
  • get (14-25)
src/collections/bitaps.rs (4)
  • slice (19-21)
  • all (23-25)
  • author (11-13)
  • get (15-17)
src/collections/arweave.rs (4)
  • slice (27-29)
  • all (31-33)
  • author (10-12)
  • get (14-25)
src/collections/b1000.rs (4)
  • slice (29-31)
  • all (33-35)
  • author (14-16)
  • get (18-27)
src/collections/gsmg.rs (4)
  • slice (19-21)
  • all (23-25)
  • author (11-13)
  • get (15-17)
src/collections/hash_collision.rs (4)
  • slice (28-30)
  • all (32-34)
  • author (11-13)
  • get (15-26)
src/collections/zden.rs (4)
  • slice (27-29)
  • all (31-33)
  • author (10-12)
  • get (14-25)
src/collections/bitimage.rs (4)
  • slice (27-29)
  • all (31-33)
  • author (10-12)
  • get (14-25)
src/cli.rs (1)
src/lib.rs (6)
  • all (100-102)
  • all (170-172)
  • author (104-115)
  • name (60-71)
  • name (121-122)
  • parse (73-85)
🔇 Additional comments (3)
src/lib.rs (1)

48-115: Registry surface is clean

Collection::ALL + name/parse/slice/all/author creates one clear registration point and removes mapping drift across call sites.

src/cli.rs (2)

1731-1774: Export path canonicalization is solid

Using collection_or_exit plus seen.insert(canonical.name()) correctly dedupes alias inputs like peter_todd and hash_collision.


1826-1854: Collection help is now source-of-truth driven

Building the help list from Collection::ALL removes the drift risk between accepted values and printed guidance.

Copy link

@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 2 files (changes from recent commits).

Requires human review: This is a significant refactor centralizing registry logic and modifying the library's API surface, which requires human review per guidelines.

Copy link

@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 is a significant refactor that centralizes core dispatch logic. The instructions categorize reorganizing code or moving logic as high-impact changes requiring human review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request refactor Code improvement without behavior change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Centralize collection dispatch to reduce duplication

1 participant