refactor(collection): centralize dispatch registry#141
refactor(collection): centralize dispatch registry#141
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (1)
📜 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)
🧰 Additional context used📓 Path-based instructions (1)src/lib.rs📄 CodeRabbit inference engine (AGENTS.md)
Files:
🧠 Learnings (13)📚 Learning: 2026-03-15T22:40:42.886ZApplied to files:
📚 Learning: 2026-03-15T22:40:42.886ZApplied to files:
📚 Learning: 2026-03-15T22:40:42.886ZApplied to files:
📚 Learning: 2026-03-15T19:09:49.536ZApplied to files:
📚 Learning: 2026-03-15T22:40:42.886ZApplied to files:
📚 Learning: 2026-03-15T22:40:42.886ZApplied to files:
📚 Learning: 2026-03-15T22:40:42.886ZApplied to files:
📚 Learning: 2026-03-15T22:40:42.886ZApplied to files:
📚 Learning: 2026-02-21T06:17:19.520ZApplied to files:
📚 Learning: 2026-03-15T22:40:42.886ZApplied to files:
📚 Learning: 2026-03-15T22:40:42.886ZApplied to files:
📚 Learning: 2026-03-15T22:40:42.886ZApplied to files:
📚 Learning: 2026-03-15T22:40:42.886ZApplied to files:
🧬 Code graph analysis (1)src/lib.rs (9)
🔇 Additional comments (6)
📝 WalkthroughWalkthroughCentralized collection dispatch by adding a Changes
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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
✨ Simplify code
Comment |
There was a problem hiding this comment.
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 returningNotFound, which can change user-visible lookup behavior. - The
src/cli.rsissue 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>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
There was a problem hiding this comment.
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
📒 Files selected for processing (10)
src/cli.rssrc/collections/arweave.rssrc/collections/b1000.rssrc/collections/ballet.rssrc/collections/bitaps.rssrc/collections/bitimage.rssrc/collections/gsmg.rssrc/collections/hash_collision.rssrc/collections/zden.rssrc/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 usinginclude!()into src/collections/*.rs files
Files:
src/collections/arweave.rssrc/collections/bitimage.rssrc/collections/ballet.rssrc/collections/b1000.rssrc/collections/gsmg.rssrc/collections/zden.rssrc/collections/bitaps.rssrc/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.rssrc/collections/bitimage.rssrc/collections/ballet.rssrc/collections/b1000.rssrc/collections/gsmg.rssrc/collections/zden.rssrc/collections/bitaps.rssrc/collections/hash_collision.rssrc/cli.rssrc/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.rssrc/collections/bitimage.rssrc/collections/ballet.rssrc/collections/b1000.rssrc/collections/gsmg.rssrc/collections/zden.rssrc/collections/bitaps.rssrc/collections/hash_collision.rssrc/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.rssrc/collections/bitimage.rssrc/collections/ballet.rssrc/collections/b1000.rssrc/collections/gsmg.rssrc/collections/zden.rssrc/collections/bitaps.rssrc/collections/hash_collision.rssrc/cli.rssrc/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.rssrc/collections/bitimage.rssrc/collections/ballet.rssrc/collections/b1000.rssrc/collections/gsmg.rssrc/collections/zden.rssrc/collections/bitaps.rssrc/collections/hash_collision.rssrc/cli.rssrc/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.rssrc/collections/bitimage.rssrc/collections/ballet.rssrc/collections/b1000.rssrc/collections/gsmg.rssrc/collections/zden.rssrc/collections/bitaps.rssrc/collections/hash_collision.rssrc/cli.rssrc/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.rssrc/collections/bitimage.rssrc/collections/ballet.rssrc/collections/b1000.rssrc/collections/gsmg.rssrc/collections/zden.rssrc/collections/bitaps.rssrc/collections/hash_collision.rssrc/cli.rssrc/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.rssrc/collections/bitimage.rssrc/collections/b1000.rssrc/collections/gsmg.rssrc/collections/bitaps.rssrc/collections/hash_collision.rssrc/cli.rssrc/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.rssrc/collections/bitimage.rssrc/collections/ballet.rssrc/collections/gsmg.rssrc/collections/zden.rssrc/collections/bitaps.rssrc/collections/hash_collision.rssrc/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.rssrc/collections/bitimage.rssrc/collections/zden.rssrc/collections/bitaps.rssrc/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.rssrc/cli.rssrc/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.rssrc/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.rssrc/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 withCollection::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: Balletslice()+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.
Copyis right since it's just a discriminant.
48-58: LGTM!
ALLarray lists all 8 variants. Order matches enum declaration which is nice for maintainability.
60-71: LGTM!
const fnis correct here since it's just returning static str slices.
73-85: LGTM!Alias
peter_todd→HashCollisionmatches the PR objectives. Single place to add new collections/aliases now.
87-102: LGTM!
slice()andall()dispatch cleanly. Theall()return typestd::slice::Iter<'static, Puzzle>is concrete which is good for theflat_mapusage in the globalall().
104-115: LGTM!Author dispatch follows the same pattern. Consistent.
136-152: LGTM!The refactored
get()properly delegates toCollection::parseandCollection::get. The special-casing forgsmgandbitaps(no slash in ID) is preserved. Error mapping fromInvalidCollectiontoNotFoundmaintains 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
Collectionfrom boha. Clean.
1149-1152: LGTM!
cmd_searchnow delegates collection parsing to the central helper. TheSome("all") | Nonebranch correctly falls back toboha::all().
1189-1193: LGTM!
cmd_listrefactored to usecollection_or_exit. Logic preserved: "all" uses global iterator, otherwise per-collection.
1256-1258: LGTM!
cmd_authorsimplified.include_all: falseis 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 viaseen.insert(canonical.name())works correctly.
1765-1774: LGTM!Loop body uses
collection.name(),collection.author(), andcollection.all()consistently. Status filtering preserved.
1834-1846: LGTM!Clean helper. Exits with code 1 on invalid collection, shows helpful message with valid options.
| 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), | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
🧹 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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
📒 Files selected for processing (2)
src/cli.rssrc/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.rssrc/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.rssrc/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.rssrc/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.rssrc/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.rssrc/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.rssrc/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.rssrc/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.rssrc/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.rssrc/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/authorcreates one clear registration point and removes mapping drift across call sites.src/cli.rs (2)
1731-1774: Export path canonicalization is solidUsing
collection_or_exitplusseen.insert(canonical.name())correctly dedupes alias inputs likepeter_toddandhash_collision.
1826-1854: Collection help is now source-of-truth drivenBuilding the help list from
Collection::ALLremoves the drift risk between accepted values and printed guidance.
There was a problem hiding this comment.
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.
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:
Closes #119.