chore(skill): refresh solana-add-idl for post-#228 VisualizerContext API#281
chore(skill): refresh solana-add-idl for post-#228 VisualizerContext API#281shahan-khatchadourian-anchorage wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
Updates the solana-add-idl Claude skill documentation so newly scaffolded Solana IDL-based presets match the post-#228/#255 VisualizerContext wire-data API and compile under both diagnostics feature configurations.
Changes:
- Switches the recommended template preset from the nonexistent
squads_multisigtodflow_aggregatorand adds guidance for the wire-data accessor pattern (resolve_program_id/resolve_accounts/data). - Refreshes the “required imports” list to align with current preset implementations (e.g.,
BTreeMap,AccountMeta,OnceLock) and documents deterministic named-account ordering. - Expands the verify commands to run clippy/tests with diagnostics both enabled and disabled.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…e instruction skipping (#228) (#255) ## Summary Addresses all review feedback from #230 by refactoring `VisualizerContext` to work directly with transaction wire data (`&CompiledInstruction` + `&[Pubkey]`), eliminating instruction skipping/filtering, and simplifying the diagnostic model. **Supersedes #230** — that PR has the original review discussion and should be closed once this merges. ## What changed - **`VisualizerContext`** holds `&CompiledInstruction` + `&[Pubkey]` instead of an index into a pre-resolved `Vec<Instruction>`. Resolution of indices to pubkeys happens lazily via `ProgramRef`/`AccountRef` enums that distinguish resolved from unresolved. - **No instructions are ever skipped.** Every compiled instruction flows through the visualizer pipeline. `unknown_program` catches instructions with unresolvable program IDs. - **Unified diagnostic model:** 2 rules (`oob_program_id`, `oob_account_index`) replace the old 3-rule model. `oob_account_index_in_skipped_instruction` is eliminated — there is no concept of "skipped instruction." - **Shared `scan_instruction_diagnostics`** function used by both legacy and v0 paths, eliminating code duplication. - **No data copies:** visualizers access instruction data via context methods (`context.data()`, `context.program_id()`, `context.account(n)`) — no `Instruction` struct is constructed. ## Review comments addressed (#230) | # | Comment | Resolution | |---|---------|------------| | Critical #1, #2 | Index mismatch in instructions.rs/v0.rs | Eliminated — no filtered vec, no index to mismatch | | High #3 | Misleading ok-diagnostic for 0 skipped | Rule removed entirely | | High #4 | V0 "Instruction Decoding Note" change | Verified — no dependents | | High #5 | Text/human output untested | Restored solana-text fixture | | High #6 | Shallow diagnostic assertions | Checks rule, level, and instruction_index | | Medium #7 | .unwrap() in Diagnostic serialize | Direct serialize_entry calls | | Medium #8 | &str instead of Severity enum | Accepts Severity | | Medium #9 | Unregistered decode::visualizer_error | Documented as always-on | | Medium #10 | Code duplication legacy/v0 | Shared scan function | | Low #11 | LintConfig::default() twice | Single construction, threaded through | | Low #12 | Doc comment placement | Fixed | ## Review comments addressed (this PR, @prasanna-anchorage) | Concern | Resolution | Commit | |---|---|---| | Drop `docs/superpowers/plans/2026-04-13-pr230-review-fixes.md` (1362-line internal planning artifact) | Removed; added `docs/superpowers/` to `.gitignore` | 0baec56 | | Gate diagnostics behind a Cargo feature, default-on for CLI only | Added `diagnostics` feature on `visualsign` / `visualsign-solana` / `parser_cli`; `parser_app` and `grpc-server` build without it. CI/Makefile split per-package to avoid Cargo feature unification across the workspace. Integration test now strictly asserts `parser_app` emits no `diagnostic` fields. | e468f86 | | Forward-looking nit: `LintConfig` / `Severity` lack `DeterministicOrdering` | Added TODO at `lint.rs` for when lint config lands in `metadata_digest` | 0baec56 | | Optional nit: explicit `assert_deterministic_ordering(&diag)` next to siblings | Added in the compile-time ordering test batch | 0baec56 | ## Branch synced with main (commit 80b076b) `main` advanced with 14 new IDL-based Solana presets (Jupiter Borrow/Earn/Perpetuals, Kamino Borrow/Vault/Farms, MetaDAO Conditional Vault/Futarchy, Meteora DAMM V2/DLMM, Neutral Trade, Onre App, Orca Whirlpool, DFlow Aggregator) authored against the pre-#228 `current_instruction()` API. Migrated each to the wire-data API. - Added `instruction_index: usize` to `VisualizerContext` (cheap, threaded from the dispatcher's `enumerate()`); new presets use it for "Instruction N" labels. - Added two convenience methods: `resolve_program_id()` and `resolve_accounts()` (Err on first unresolved index). IDL-based presets call these; visualizers wanting partial rendering pattern-match on `program_id()` / `account(n)` directly. Doc comment on `VisualizerContext` contrasts the two patterns and points at `unknown_program` as the canonical partial-rendering example. - Reconciled `jupiter_swap`'s `create_jupiter_swap_expanded_fields` signature drift (now takes `&VisualizerContext` instead of separate program_id+data). - Dropped redundant `Some(hex::encode(data))` in `create_raw_data_field` calls — the helper's `None` branch already emits the same lowercase hex. ## Stacked follow-up #281 — refresh the `solana-add-idl` skill template to match the post-#228 API (broken `squads_multisig` template reference, stale imports, redundant hex encoding). ## Test plan - [x] `make build`, `make lint`, `make test` clean in both feature configs (diagnostics on/off) - [x] visualsign-solana: 135 lib tests pass with diagnostics on, 128 without - [x] visualsign: 56 lib tests pass with diagnostics on, 48 without - [x] parser_cli: 28 fixture-based tests pass - [x] Pipeline integration tests pass (9) - [x] Fuzz and proptest workflows green on CI; both fuzz targets verified locally - [x] Integration e2e: `parser_app` strictly emits no `diagnostic` fields (locks in the production payload shape) - [x] Clippy clean with `-D warnings`, `cargo fmt --check` clean 🤖 Generated with [Claude Code](https://claude.com/claude-code)
The skill scaffolds new IDL-based Solana visualizer presets. Two updates: - Replace the broken `squads_multisig` template reference (preset doesn't exist in this repo) with `dflow_aggregator`, which is a real working example of the post-#228 wire-data pattern. - Add explicit guidance for the new accessor pattern at the top of `visualize_tx_commands`: `context.resolve_program_id()?` / `context.resolve_accounts()?` / `context.data()`. These replace the removed `context.current_instruction()` and surface unresolved indices with precise error messages. - Update the "Required imports" list to match real preset code (BTreeMap for deterministic named-accounts ordering, AccountMeta, OnceLock). - Drop the redundant `Some(hex::encode(...))` second arg in `create_raw_data_field` calls — the helper falls back to the same lowercase hex by default. - Verify step now exercises both feature configs (diagnostics on/off) so newly scaffolded presets work for parser_cli and parser_app alike. Stacked on top of #255.
Address Copilot review feedback on PR #281: the rule was overly strict. Reusing a precomputed hex string (e.g. one built for fallback_text, as in dflow_aggregator) is fine; the only thing to avoid is calling hex::encode(data) solely to populate the second arg. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0859fed to
d9b8f05
Compare
| **Important — generic IDL pattern only:** | ||
| - DO NOT copy any squads-specific code (e.g. `VaultTransactionMessage` decoding, inner instruction handling) | ||
| **Generic IDL pattern only:** | ||
| - The generic scaffold uses `build_named_accounts`, `build_parsed_fields`, `build_fallback_fields`, `append_raw_data`, `format_arg_value` — all of which work with any IDL |
There was a problem hiding this comment.
Minor accuracy nit: of the five helpers listed here, dflow_aggregator (the template you point at on line 89) actually defines only build_named_accounts / build_parsed_fields / build_fallback_fields. append_raw_data and format_arg_value live in other IDL presets — e.g. chain_parsers/visualsign-solana/src/presets/kamino_vault/mod.rs:209,217 or jupiter_earn/mod.rs:218,229. Two ways to fix, either is fine:
(a) Trim the helper list to the three that dflow_aggregator actually has, and let users grow their preset to need append_raw_data / format_arg_value only when their IDL has byte-blob args, or
(b) Keep all five but add "(for append_raw_data / format_arg_value, see e.g. kamino_vault)" so the first-time user knows where to copy from.
Not a blocker — newcomers can grep, but the current wording suggests dflow_aggregator alone is a sufficient template, and it is not for any preset that needs those two helpers.
prasanna-anchorage
left a comment
There was a problem hiding this comment.
Approved.
Reviewed in a worktree at d9b8f05. Verified the template's structural claims against main:
chain_parsers/visualsign-solana/src/presets/dflow_aggregator/exists with the imports list this skill prescribes byte-for-byte (BTreeMap,OnceLock,AccountMeta, etc. —mod.rs:1-21).VisualizerContext::resolve_program_id,resolve_accounts,data,instruction_indexare all real methods oncore/mod.rs(151,163,130,104).build_named_accounts/build_parsed_fields/build_fallback_fieldsexist indflow_aggregator/mod.rs:118,151,197.- The "raw-data-field rule" added in d9b8f05 matches what landed in
core/mod.rsafter #228 (the helper'sNonebranch already does lowercase byte-by-byte hex). - The Step 6 verify block now exercises both feature configs, which is the right shape since
parser_appbuilds withoutdiagnosticsandparser_clibuilds with it.
One non-blocking inline nit on line 99 about the helper list (append_raw_data / format_arg_value live in other presets, not in dflow_aggregator). The PR's own "scaffold a fresh preset using the updated skill on a sample IDL" test-plan checkbox is still pending — worth doing once before merge, but the static review of the template against main is clean.
Summary
Stacked on top of #255. Refreshes the
solana-add-idlscaffolding skill so newly-generated presets compile against the wire-dataVisualizerContextintroduced in #255.Changes
squads_multisigtemplate reference (preset doesn't exist in this repo) withdflow_aggregator, a real working example of the post-feat: attested transaction lint diagnostics in SignablePayload #228 pattern.visualize_tx_commands:context.resolve_program_id()?/context.resolve_accounts()?/context.data(). These replace the removedcontext.current_instruction()and surface unresolved indices with precise error messages.BTreeMapfor deterministic named-accounts ordering,AccountMeta,OnceLock).Some(hex::encode(...))second arg increate_raw_data_fieldcalls — the helper falls back to the same lowercase hex by default.Test plan
cargo fmt --check,make lintclean🤖 Generated with Claude Code