Skip to content

build: mention @claude in github to get work done#552

Merged
PastaPastaPasta merged 12 commits into
v1.0-devfrom
claude/setup-github-actions-9t98i
Feb 11, 2026
Merged

build: mention @claude in github to get work done#552
PastaPastaPasta merged 12 commits into
v1.0-devfrom
claude/setup-github-actions-9t98i

Conversation

@lklimek
Copy link
Copy Markdown
Contributor

@lklimek lklimek commented Feb 10, 2026

Installs Claude Code so that we can mention @claude during code review and give it some tasks.

Uses my (@lklimek) personal Claude subscription for now. Can be replaced with Claude API key in the future.

This pull request introduces automation and environment setup improvements for Claude Code integration, ensuring consistency between local development and CI environments. It adds a session start hook to install required dependencies and pre-download proto sources, configures Claude Code hooks, and introduces a GitHub Actions workflow for Claude Code. Additionally, it updates development guidelines to enforce conventional commit naming.

Claude Code integration and automation:

  • Added .github/workflows/claude.yml to run Claude Code workflows in response to comments or PR reviews mentioning @claude, ensuring Claude Code automation is triggered appropriately.
  • Added .claude/settings.json to configure a session start hook for Claude Code environments, running the new setup script on startup.

Development environment setup:

  • Introduced .claude/hooks/session-start.sh script to automate installation of required system packages, Rust components, protoc, and to pre-download Tenderdash proto sources, ensuring local environments match CI and builds do not fail due to missing dependencies or network issues.

Development process guidelines:

  • Updated CLAUDE.md to require PRs and commits to follow conventional commit naming rules, promoting consistency in commit history.

Installs protoc v25.2, clippy, rustfmt, and system dependencies
(clang, cmake, libsqlite3-dev, libzmq3-dev) to match CI workflows.
Only runs in Claude Code remote environments.

https://claude.ai/code/session_01SdEvmPYuJkJoAVJejB8Tz9

Summary by CodeRabbit

  • Chores

    • Automated development environment setup for remote coding sessions to streamline prerequisite installation and configuration.
    • Added CI/CD workflow integration for automated code review processes.
  • Documentation

    • Updated development guidelines for commit naming conventions and code formatting standards.

Installs protoc v25.2, clippy, rustfmt, and system dependencies
(clang, cmake, libsqlite3-dev, libzmq3-dev) to match CI workflows.
Only runs in Claude Code remote environments.

https://claude.ai/code/session_01SdEvmPYuJkJoAVJejB8Tz9
The tenderdash-proto build.rs downloads proto sources from GitHub via
ureq/rustls during compilation, which fails in sandboxed environments
where TLS certificate verification doesn't work (InvalidCertificate).

The session-start hook now:
- Pre-downloads the Tenderdash v1.5.3 zip archive via curl (which
  uses the system CA bundle and works in sandboxed environments)
- Extracts sources to /tmp/tenderdash-v1.5.3 (TENDERDASH_DIR)
- Caches the zip at /tmp/tenderdash-cache/ (CARGO_TARGET_DIR for
  the proto-compiler's archive lookup)
- Sets both env vars via ~/.cargo/config.toml [env] so the build
  script finds the cached archive and skips the network download

Validated: cargo build, cargo clippy, and cargo test all pass.

https://claude.ai/code/session_01SdEvmPYuJkJoAVJejB8Tz9
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 10, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds Claude Code integration infrastructure including a session-start Bash script for remote environment setup (protoc, Rust, system packages, pre-downloaded dependencies), configuration file defining hooks, and GitHub Actions workflow enabling Claude Code execution on repository interactions.

Changes

Cohort / File(s) Summary
Claude Code Setup
.claude/hooks/session-start.sh, .claude/settings.json
Session-start script initializes remote environment with idempotent installation of build dependencies (protoc v25.2, Rust components, system packages), pre-downloads Tenderdash proto sources to optimize builds, and configures Cargo environment variables. Settings file defines SessionStart hook configuration with 120-second timeout.
GitHub Integration
.github/workflows/claude.yml
Workflow triggers Claude Code Action on issue comments, PR review comments, issue opens/assigns, and PR review submissions when @claude token is present, with appropriate permissions for repository access.
Documentation
CLAUDE.md
Adds guidelines for conventional commit naming and reminders to run clippy and nightly formatting before finalizing work.

Sequence Diagram

sequenceDiagram
    actor Developer
    participant GitHub as GitHub
    participant Workflow as GitHub Actions
    participant ClaudeAction as Claude Code Action
    participant Remote as Remote Environment
    participant Script as session-start.sh

    Developer->>GitHub: Comment with `@claude`
    GitHub->>Workflow: Trigger workflow
    Workflow->>ClaudeAction: Execute Claude Code Action
    ClaudeAction->>Remote: Connect to remote environment
    Remote->>Script: Execute session-start.sh
    Script->>Script: Install protoc (if needed)
    Script->>Script: Install Rust components
    Script->>Script: Install system packages
    Script->>Script: Pre-download Tenderdash sources
    Script->>Script: Configure Cargo environment
    Script->>Remote: Return ready environment
    Remote->>ClaudeAction: Environment initialized
    ClaudeAction->>Developer: Ready for code operations
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A rabbit hops through CI/CD streams,
With hooks and scripts fulfilling dreams,
Protoc installed, Tenderdash cached below,
Claude's remote garden ready to grow! 🌱

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title mentions @claude and GitHub but is vague about the actual changes; it doesn't clearly convey that this integrates Claude Code automation, adds build environment setup, or configures a session-start hook. Consider a more specific title that describes the primary change, such as: 'build: integrate Claude Code automation and environment setup' or 'ci: add Claude Code workflow and session initialization'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch claude/setup-github-actions-9t98i

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@lklimek
Copy link
Copy Markdown
Contributor Author

lklimek commented Feb 10, 2026

@claude check if this PR builds

Copy link
Copy Markdown
Contributor

@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

🤖 Fix all issues with AI agents
In @.claude/hooks/session-start.sh:
- Around line 103-111: The script appends a second [env] table which produces
invalid TOML if CARGO_CONFIG_FILE already contains an [env] section; update
session-start.sh to detect whether an [env] table exists (searching for a line
matching "^\[env\]") and if present, ensure TENDERDASH_DIR and CARGO_TARGET_DIR
keys are added/updated beneath that existing [env] block (instead of appending a
new [env] header); if no [env] exists, create the [env] block as currently done.
Use CARGO_CONFIG_FILE, TENDERDASH_DIR and TENDERDASH_CACHE_DIR as the target
symbols to find and insert/update the key=value lines atomically (or employ a
TOML-aware tool) so the file remains valid TOML.
🧹 Nitpick comments (1)
.claude/hooks/session-start.sh (1)

60-60: Hardcoded Tenderdash version requires manual sync with build.rs.

The comment on Line 59 notes this must match DEFAULT_VERSION in rs-tenderdash-abci/proto/build.rs. If that version is bumped without updating this script, the pre-download becomes useless and builds will attempt (and potentially fail) network fetches again. Consider extracting this to a shared constant or adding a CI check that validates the versions match.

Comment thread .claude/hooks/session-start.sh
- Add "matcher": "startup" to SessionStart hook so it only runs on
  new sessions, not on resume/clear/compact (deps are persistent)
- Quote $CLAUDE_PROJECT_DIR for paths with spaces
- Add explicit 120s timeout for the hook
- Fix cargo config append to handle pre-existing [env] sections
  without creating duplicate TOML table headers

https://claude.ai/code/session_01SdEvmPYuJkJoAVJejB8Tz9
- Replace archived actions-rs/toolchain@v1 with dtolnay/rust-toolchain
- Replace archived actions-rs/clippy-check@v1 with direct cargo clippy
- Replace archived actions-rs/cargo@v1 with direct cargo commands
- Fix push branch trigger from `main` to `master` (the actual release branch)

https://claude.ai/code/session_01SdEvmPYuJkJoAVJejB8Tz9
@lklimek
Copy link
Copy Markdown
Contributor Author

lklimek commented Feb 10, 2026

Hardcoded Tenderdash version requires manual sync with build.rs.

The comment on Line 59 notes this must match DEFAULT_VERSION in rs-tenderdash-abci/proto/build.rs. If that version is bumped without updating this script, the pre-download becomes useless and builds will attempt (and potentially fail) network fetches again.

@claude Implement a solution that will detect required version of tenderdash automatically.

Adds GitHub Actions integration for Claude Code with OAuth authentication.
The workflow triggers on @claude mentions in issues, PR comments, and reviews.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@lklimek
Copy link
Copy Markdown
Contributor Author

lklimek commented Feb 11, 2026

@claude check if you can build this project

Copy link
Copy Markdown
Contributor

@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

🤖 Fix all issues with AI agents
In @.github/workflows/clippy.yml:
- Around line 56-60: The "Install Rust toolchain" step currently uses
dtolnay/rust-toolchain@master with toolchain: "1.92", which diverges from
tests.yml's dtolnay/rust-toolchain@stable; update the clippy workflow to match
the tests workflow strategy by either switching the "uses" to
dtolnay/rust-toolchain@stable (and remove the explicit "toolchain" pin) or pin
both workflows to the same explicit toolchain string (e.g., change toolchain in
clippy.yml and tests.yml so both use "1.92"), editing the Install Rust toolchain
step (uses and/or toolchain fields) so both workflows run the identical Rust
version.
🧹 Nitpick comments (4)
.github/workflows/clippy.yml (1)

67-74: PROTOC env var is step-scoped — won't be visible during build

The env: PROTOC on lines 73–74 is scoped to the "Install protoc" step only. If any build.rs (e.g., protobuf code generation) checks the PROTOC environment variable rather than searching PATH, it won't find it during the clippy or fmt steps. Since protoc is installed to /usr/local/bin (which is on PATH), this likely works in practice, but it would be cleaner to either move the PROTOC env to the job level or remove it entirely.

Suggested fix: promote to job-level env
 env:
   CARGO_TERM_COLOR: always
+  PROTOC: /usr/local/bin/protoc

and remove the step-level env block on lines 73–74.

.github/workflows/tests.yml (1)

56-57: Consider pinning the Rust toolchain version to match clippy.yml

Using @stable without a version pin means the tests workflow will automatically pick up new stable releases. While this catches forward-compatibility issues early, it also means CI can break unpredictably on a new Rust release day. The clippy workflow pins "1.92" — aligning both would give more deterministic builds.

Suggested change
      - name: Install Rust toolchain
-        uses: dtolnay/rust-toolchain@stable
+        uses: dtolnay/rust-toolchain@master
+        with:
+          toolchain: "1.92"
.github/workflows/claude.yml (2)

21-26: Broad write permissions — ensure this is intentional.

contents: write grants Claude the ability to push commits directly. Combined with pull-requests: write and issues: write, this gives the action significant repository access. This is expected for the Claude Code action workflow, but worth confirming the team is comfortable with this scope — especially since any GitHub user who can comment @claude on a public issue/PR could trigger it.

Consider whether restricting triggers to specific users/teams (e.g., via an additional if check on github.actor) would be appropriate for your threat model.


37-37: User-specific secret creates a bus-factor risk.

CLAUDE_CODE_OAUTH_TOKEN_LKLIMEK is tied to a single developer. If that person leaves or their token is rotated, this workflow silently breaks. Consider using a team/org-level secret (e.g., CLAUDE_CODE_OAUTH_TOKEN) or a machine account token instead.

Comment thread .github/workflows/clippy.yml
…ithub_token

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@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

🤖 Fix all issues with AI agents
In @.github/workflows/claude.yml:
- Around line 21-26: Remove the unnecessary id-token: write permission from the
workflow permissions block (the id-token key) since this job uses direct
Anthropic API authentication via anthropic_api_key rather than cloud provider
authentication; update the permissions list to omit id-token while leaving other
permissions (contents, pull-requests, issues, actions) unchanged to reduce the
workflow's security surface.

Comment thread .github/workflows/claude.yml
@lklimek
Copy link
Copy Markdown
Contributor Author

lklimek commented Feb 11, 2026

@claude in session-start.sh, update protoc to the most recent version

1 similar comment
@lklimek
Copy link
Copy Markdown
Contributor Author

lklimek commented Feb 11, 2026

@claude in session-start.sh, update protoc to the most recent version

@lklimek lklimek changed the title Add Claude Code SessionStart hook for remote environment setup build: add Claude Code SessionStart hook for remote environment setup Feb 11, 2026
@lklimek lklimek changed the title build: add Claude Code SessionStart hook for remote environment setup build: configure github to allow mentioning claude in PRs Feb 11, 2026
@lklimek lklimek changed the title build: configure github to allow mentioning claude in PRs build: mention @claude in github to get work done Feb 11, 2026
Copy link
Copy Markdown
Contributor

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
CLAUDE.md (1)

17-17: ⚠️ Potential issue | 🟡 Minor

Remove nightly requirement from formatting instructions.

Lines 17 and 36 document conflicting formatting commands: line 17 specifies cargo fmt --all, while line 36 specifies cargo +nightly fmt. Since rust-toolchain.toml pins the project to stable Rust 1.92 and no nightly-specific rustfmt configuration exists, the +nightly requirement should be removed.

Change line 36 from cargo +nightly fmt to cargo fmt --all to match line 17.

🧹 Nitpick comments (1)
CLAUDE.md (1)

9-9: Clarify which conventional commit standard to follow.

The guideline mentions "conventional commit naming rules" but doesn't specify which standard. Consider referencing the Conventional Commits specification (e.g., feat:, fix:, docs:, chore:, etc.) or provide examples to make this more actionable for contributors.

📝 Suggested clarification
-- PR and commits should follow conventional commit naming rules.
+- PR and commit messages should follow the [Conventional Commits](https://www.conventionalcommits.org/) specification (e.g., `feat:`, `fix:`, `docs:`, `chore:`).

@PastaPastaPasta PastaPastaPasta merged commit a587956 into v1.0-dev Feb 11, 2026
5 checks passed
@PastaPastaPasta PastaPastaPasta deleted the claude/setup-github-actions-9t98i branch February 11, 2026 14:03
lklimek added a commit that referenced this pull request Feb 12, 2026
Cherry-pick from v1.0-dev to enable @claude mentions in PRs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
lklimek added a commit that referenced this pull request Feb 17, 2026
…561)

* fix: return error instead of panicking on corrupted database blobs (#560)

- Replace `unreachable!()` in `get_scheduled_votes` with warning log and
  default to false for unexpected `executed` column values
- Change `QualifiedIdentity::from_bytes()` to return `Result` instead of
  panicking via `.expect()`
- Propagate deserialization errors as `rusqlite::Error` in all 6 callers
  so corrupted database is surfaced to the user rather than silently
  ignored or crashing the app
- Add `CorruptedBlobError` newtype in database module to eliminate
  repeated `FromSqlConversionFailure` boilerplate

Closes #560

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: impl thiserror

* chore: fmt

* build: add Claude Code GitHub workflow and settings (#552)

Cherry-pick from v1.0-dev to enable @claude mentions in PRs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: fix after merge

* fix: skip corrupted identity blobs in get_wallets instead of aborting

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: fail on corrupted identity

* doc: document error handling in the db

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
PastaPastaPasta added a commit that referenced this pull request Feb 17, 2026
* fix: skip best chain lock polling in SPV mode (#567)

* Initial plan

* Skip chain lock refresh in SPV mode

Co-authored-by: lklimek <842586+lklimek@users.noreply.github.com>

* Document SPV guard intent

Co-authored-by: lklimek <842586+lklimek@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: lklimek <842586+lklimek@users.noreply.github.com>

* fix: compute relative timestamps from actual data (#581)

* fix: compute relative timestamps from actual data

Replace hardcoded display strings like "Received: 1 day ago" with
real relative timestamps computed from document createdAt/updatedAt
fields using chrono::Utc::now().

Fixes #579

* style: fix import ordering per cargo fmt

* refactor: extract format_relative_time to shared dashpay module

Deduplicate the identical format_relative_time function that existed
in both contact_requests.rs and send_payment.rs. Move it to the
dashpay mod.rs as a pub(crate) function and import from both files.

---------

Co-authored-by: PastaClaw <thepastaclaw@users.noreply.github.com>

* fix: update platform for DIP-18 HRP and improve SPV sync progress (#575)

* fix: update dashpay/platform to d6f4eb9 for DIP-18 HRP fix

The previous platform revision used incorrect bech32m HRP prefixes
(evo/tevo) for Platform addresses. The updated commit uses the
correct DIP-0018 prefixes (dash/tdash).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(spv): use dash-spv SyncProgress API directly

Replace the intermediate SyncProgress/DetailedSyncProgress/SyncStage
translation layer with direct use of dash_spv::sync::SyncProgress.
This eliminates ~120 lines of bridge code in spawn_progress_watcher()
and determine_sync_stage(), and lets the UI query per-manager progress
(headers, filter_headers, filters, masternodes, blocks) via the
upstream API.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(spv): improve sync progress accuracy and robustness

- Log headers() error before discarding for easier debugging
- Restore download-window optimization for headers progress on
  checkpoint-resumed syncs (progress starts near 0% not 83%)
- Replace catch-all _ => 0.0 with explicit SyncState variant matches
  so new variants produce compile errors
- Fix filters progress to use current_height/target_height instead of
  downloaded/target_height (session count vs absolute height mismatch)
- Restore peer count in sync status text
- Add "Querying peer heights" label and diffs_processed to masternode
  status for more informative sync messages

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(spv): use height-based blocks progress to prevent bar from jumping

The blocks progress bar was bouncing backward because it used
processed/requested session counters whose denominator grows as filters
discover more matching blocks. Switch to last_processed block height
relative to headers target_height, which only increases. Display
"current / target" heights instead of percentage on the blocks bar.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(spv): improve progress bar resilience across resume and network switch

- Add windowed progress tracking for filters (consistent with headers/filter_headers)
- Reset blocks_stage_start on Error state so recovery gets a fresh window
- Track spv_progress_network to detect network changes and rebuild progress
  state from the new network's sync_progress instead of resetting to zero
- Eliminate redundant clone in progress watcher (move instead of clone twice)
- Consolidate all progress state reset logic into rebuild_spv_progress_state()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* build: add git and cargo permissions to Claude Code workflow (#565)

* build: add git and cargo permissions to Claude Code workflow

Allow Claude to run git fetch/merge/checkout/rebase/push and
cargo build/test/clippy/fmt commands. Switch model to opus.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: use claude_args for model and allowed tools

The `model` and `allowed_tools` inputs are not declared in
claude-code-action@v1 and are silently ignored. Move them to
`claude_args` with --model and --allowedTools flags. Also fix
deprecated colon syntax (`:*`) to space syntax (` *`).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: use single quotes to prevent glob expansion in allowed tools

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* build: sandbox cargo commands and add git permissions for Claude

- Add safe-cargo.sh wrapper that strips CI secrets before running cargo
- Use --allowedTools for git and safe-cargo, --disallowedTools for raw cargo
- Document safe-cargo usage in CLAUDE.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: switch safe-cargo.sh from denylist to allowlist approach

Use `env -i` (start with empty environment, explicitly pass only
what cargo needs) instead of `env -u` (strip known secrets). This
is more robust against future secrets being added to the workflow.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* build: deny Claude from editing CI scripts and workflows

Prevent Claude from modifying .github/scripts/ and .github/workflows/
to ensure the safe-cargo wrapper cannot be tampered with.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: conditionally pass optional env vars in safe-cargo.sh

Empty PROTOC="" caused prost build scripts to fail with
"protoc not found". Now optional vars (PROTOC, CC, CXX, etc.)
are only passed when set and non-empty.

Tested: build, test, fmt all pass through the wrapper.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* rabbit feedback

* build: move safe-cargo.sh to scripts/ and allow +nightly fmt

Move safe-cargo.sh from .github/scripts/ to top-level scripts/ for
better discoverability. Add detailed comment explaining why the wrapper
exists (prevent CI secret exfiltration via build scripts). Update all
references in claude.yml, CLAUDE.md, and permission settings. Add
`+nightly fmt` to allowedTools so Claude can follow CLAUDE.md
formatting instructions in CI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* fix: handle errors instead of panicking on corrupted database blobs (#561)

* fix: return error instead of panicking on corrupted database blobs (#560)

- Replace `unreachable!()` in `get_scheduled_votes` with warning log and
  default to false for unexpected `executed` column values
- Change `QualifiedIdentity::from_bytes()` to return `Result` instead of
  panicking via `.expect()`
- Propagate deserialization errors as `rusqlite::Error` in all 6 callers
  so corrupted database is surfaced to the user rather than silently
  ignored or crashing the app
- Add `CorruptedBlobError` newtype in database module to eliminate
  repeated `FromSqlConversionFailure` boilerplate

Closes #560

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: impl thiserror

* chore: fmt

* build: add Claude Code GitHub workflow and settings (#552)

Cherry-pick from v1.0-dev to enable @claude mentions in PRs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: fix after merge

* fix: skip corrupted identity blobs in get_wallets instead of aborting

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: fail on corrupted identity

* doc: document error handling in the db

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat: track DAPI endpoint availability in connection status (#533)

* fix: connection status not updated

* chore: rabbit feedback

* Initial plan

* Track DAPI connection status and display in tooltips and connection info

- Add dapi_total_endpoints and dapi_available fields to ConnectionStatus
- Factor DAPI availability into overall_connected status (RED when no endpoints available)
- Query SDK AddressList during periodic refresh for endpoint counts and availability
- Display DAPI status in connection indicator tooltip
- Display DAPI status in network chooser Connection Status card (all modes)
- Add dapi_status_label() helper for consistent status text formatting

Co-authored-by: lklimek <842586+lklimek@users.noreply.github.com>

* Address review feedback: store available endpoint count and extract DRY helper

- Changed dapi_available from AtomicBool to AtomicU16 (dapi_available_endpoints) to store
  the count of available endpoints instead of just a boolean
- Display format now shows "Available ({available}/{total} endpoints)"
- Extracted repeated DAPI status rendering into add_dapi_status_label() helper function
  in network_chooser_screen.rs to eliminate code duplication

Co-authored-by: lklimek <842586+lklimek@users.noreply.github.com>

* Fix rustfmt formatting issues in connection_status.rs

- Reorder atomic imports (AtomicU8 before AtomicU16) per rustfmt
- Wrap long .store() call to respect line length
- Wrap long format!() strings to respect line length

Co-authored-by: lklimek <842586+lklimek@users.noreply.github.com>

* Fix borrow checker error: extract DAPI status values before mutable self borrow

The add_dapi_status_label helper was capturing a &ConnectionStatus reference
(derived from self) in closures, which extended the immutable borrow past the
self.render_spv_sync_progress() mutable borrow on line 594.

Fix: change add_dapi_status_label to accept pre-computed owned values
(dapi_total, dapi_available, dapi_label) instead of &ConnectionStatus, and
extract those values early alongside other status fields.

Co-authored-by: lklimek <842586+lklimek@users.noreply.github.com>

* Switch Platform to c2c88e4 and use get_live_addresses() for accurate available count

Updated dash-sdk dependency to Platform commit c2c88e4a988ce930 which adds
AddressList::get_live_addresses() method. Replaced the workaround that used
get_live_address().is_some() (which could only tell if at least one endpoint
was live) with get_live_addresses().len() to get the exact count of available
non-banned DAPI endpoints.

Co-authored-by: lklimek <842586+lklimek@users.noreply.github.com>

* chore: typo + network changes

* chore: apply feedback

* chore: rabbit review

* chore: rabbit feedback

* chore: rabbitting

* Remove overall_connected_with method (deleted upstream in base branch)

Co-authored-by: lklimek <842586+lklimek@users.noreply.github.com>

* Merge v1.0-dev into copilot/update-dapi-connection-status

Resolved modify/delete conflict on src/context.rs: removed the file
since v1.0-dev refactored it into src/context/mod.rs and submodules,
which already include our Arc<ConnectionStatus> changes.

Co-authored-by: lklimek <842586+lklimek@users.noreply.github.com>

* chore: fix platfom versioning issues

* chore: add todo

* chore: fmt

---------

Co-authored-by: Lukasz Klimek <842586+lklimek@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>

* refactor(spv): eliminate separate thread/runtime, improve shutdown and UX (#577)

* fix: update dashpay/platform to d6f4eb9 for DIP-18 HRP fix

The previous platform revision used incorrect bech32m HRP prefixes
(evo/tevo) for Platform addresses. The updated commit uses the
correct DIP-0018 prefixes (dash/tdash).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(spv): use dash-spv SyncProgress API directly

Replace the intermediate SyncProgress/DetailedSyncProgress/SyncStage
translation layer with direct use of dash_spv::sync::SyncProgress.
This eliminates ~120 lines of bridge code in spawn_progress_watcher()
and determine_sync_stage(), and lets the UI query per-manager progress
(headers, filter_headers, filters, masternodes, blocks) via the
upstream API.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(spv): improve sync progress accuracy and robustness

- Log headers() error before discarding for easier debugging
- Restore download-window optimization for headers progress on
  checkpoint-resumed syncs (progress starts near 0% not 83%)
- Replace catch-all _ => 0.0 with explicit SyncState variant matches
  so new variants produce compile errors
- Fix filters progress to use current_height/target_height instead of
  downloaded/target_height (session count vs absolute height mismatch)
- Restore peer count in sync status text
- Add "Querying peer heights" label and diffs_processed to masternode
  status for more informative sync messages

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(spv): use height-based blocks progress to prevent bar from jumping

The blocks progress bar was bouncing backward because it used
processed/requested session counters whose denominator grows as filters
discover more matching blocks. Switch to last_processed block height
relative to headers target_height, which only increases. Display
"current / target" heights instead of percentage on the blocks bar.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(spv): improve progress bar resilience across resume and network switch

- Add windowed progress tracking for filters (consistent with headers/filter_headers)
- Reset blocks_stage_start on Error state so recovery gets a fresh window
- Track spv_progress_network to detect network changes and rebuild progress
  state from the new network's sync_progress instead of resetting to zero
- Eliminate redundant clone in progress watcher (move instead of clone twice)
- Consolidate all progress state reset logic into rebuild_spv_progress_state()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(spv): update ConnectionStatus immediately on connect/disconnect

Propagate SPV status into ConnectionStatus right after start_spv() and
stop_spv() so the UI reflects the change on the next frame instead of
waiting for the next throttled trigger_refresh() cycle (2-10 seconds).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(spv): check cancellation token in listener tasks to prevent shutdown hang

SPV finality and reconcile listeners blocked app shutdown for up to 10s
because they never checked the global cancellation token. Add cancel
branches to their tokio::select! loops so they exit immediately on
shutdown.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: remove log spamming line

* fix(spv): make listener handler calls cancellation-aware and add shutdown trace logging

Wrap reconcile_spv_wallets(), handle_spv_finality_event(), and the
debounce sleep inside tokio::select! with the cancellation token so
shutdown can interrupt them even when blocked on locks held by the
SPV sync thread.

Add trace-level logging to TaskManager::shutdown() for per-task join
timing to aid future shutdown diagnostics.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(spv): disable Disconnect button during stopping and poll status faster

- Disable the Disconnect button while SPV status is Stopping to prevent
  double-clicks and provide visual feedback
- Poll SPV status every 200ms during Stopping instead of the 10s
  connected interval so the Stopped transition is reflected within 1s
- Reset the throttle timer in stop_spv() so fast polling starts
  immediately

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(tasks): add mandatory task names to spawn_sync for shutdown diagnostics

Change spawn_sync() signature to require a &'static str name. The
JoinSet now yields the task name on completion, letting shutdown()
log which tasks finished and which ones timed out.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: log task names

* refactor(spv): eliminate separate OS thread and tokio runtime

Replace the dedicated SPV thread + 4-worker tokio runtime with a
spawned task on the main 12-worker runtime via TaskManager::spawn_sync.

This simplifies shutdown (SPV loop now tracked in unified JoinSet),
removes cross-runtime complexity, and improves debuggability.

Additional changes:
- Fix: zeroize xprv_str after wallet import (security H-1)
- Fix: sanitize devnet_name in build_spv_data_dir to prevent path traversal
- Add 21 integration tests covering lifecycle, concurrency, deadlock
  detection, and live testnet sync

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(spv): derive stop_token as child of global cancel for clean shutdown

The spv_request_handler selected on stop_token, which was independent
of the global cancellation token.  During window-close shutdown only
the global token was cancelled, leaving the request handler running
and causing a ~5s hang until the TaskManager timeout aborted it.

Fix by creating stop_token as a child_token() of the global cancel.
This also simplifies run_spv_loop and run_sync_and_monitor by removing
the redundant global_cancel parameter — a single stop_token now covers
both explicit SpvManager::stop() and application-wide shutdown.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* CLAUDE: minor changes about docs

* fix(spv): bump rust-dashcore to d8bc066 for faster disconnect and add shutdown tracing

Pin rust-dashcore patches to commit d8bc066 which includes:
- sync manager task loop exits on network errors instead of logging indefinitely
- sync coordinator signal_shutdown() cancels tasks before network disconnect
- connection tasks race Peer::connect() against shutdown token

Add debug tracing to SpvManager::stop() and run_sync_and_monitor() to
measure client.stop() duration, and trace-level polling of SPV status
in ConnectionStatus.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: update rust-dashcore rev

* merge: resolve v1.0-dev conflicts for #577 (#585)

* fix: compute relative timestamps from actual data (#581)

* fix: compute relative timestamps from actual data

Replace hardcoded display strings like "Received: 1 day ago" with
real relative timestamps computed from document createdAt/updatedAt
fields using chrono::Utc::now().

Fixes #579

* style: fix import ordering per cargo fmt

* refactor: extract format_relative_time to shared dashpay module

Deduplicate the identical format_relative_time function that existed
in both contact_requests.rs and send_payment.rs. Move it to the
dashpay mod.rs as a pub(crate) function and import from both files.

---------

Co-authored-by: PastaClaw <thepastaclaw@users.noreply.github.com>

* fix: update platform for DIP-18 HRP and improve SPV sync progress (#575)

* fix: update dashpay/platform to d6f4eb9 for DIP-18 HRP fix

The previous platform revision used incorrect bech32m HRP prefixes
(evo/tevo) for Platform addresses. The updated commit uses the
correct DIP-0018 prefixes (dash/tdash).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(spv): use dash-spv SyncProgress API directly

Replace the intermediate SyncProgress/DetailedSyncProgress/SyncStage
translation layer with direct use of dash_spv::sync::SyncProgress.
This eliminates ~120 lines of bridge code in spawn_progress_watcher()
and determine_sync_stage(), and lets the UI query per-manager progress
(headers, filter_headers, filters, masternodes, blocks) via the
upstream API.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(spv): improve sync progress accuracy and robustness

- Log headers() error before discarding for easier debugging
- Restore download-window optimization for headers progress on
  checkpoint-resumed syncs (progress starts near 0% not 83%)
- Replace catch-all _ => 0.0 with explicit SyncState variant matches
  so new variants produce compile errors
- Fix filters progress to use current_height/target_height instead of
  downloaded/target_height (session count vs absolute height mismatch)
- Restore peer count in sync status text
- Add "Querying peer heights" label and diffs_processed to masternode
  status for more informative sync messages

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(spv): use height-based blocks progress to prevent bar from jumping

The blocks progress bar was bouncing backward because it used
processed/requested session counters whose denominator grows as filters
discover more matching blocks. Switch to last_processed block height
relative to headers target_height, which only increases. Display
"current / target" heights instead of percentage on the blocks bar.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(spv): improve progress bar resilience across resume and network switch

- Add windowed progress tracking for filters (consistent with headers/filter_headers)
- Reset blocks_stage_start on Error state so recovery gets a fresh window
- Track spv_progress_network to detect network changes and rebuild progress
  state from the new network's sync_progress instead of resetting to zero
- Eliminate redundant clone in progress watcher (move instead of clone twice)
- Consolidate all progress state reset logic into rebuild_spv_progress_state()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* build: add git and cargo permissions to Claude Code workflow (#565)

* build: add git and cargo permissions to Claude Code workflow

Allow Claude to run git fetch/merge/checkout/rebase/push and
cargo build/test/clippy/fmt commands. Switch model to opus.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: use claude_args for model and allowed tools

The `model` and `allowed_tools` inputs are not declared in
claude-code-action@v1 and are silently ignored. Move them to
`claude_args` with --model and --allowedTools flags. Also fix
deprecated colon syntax (`:*`) to space syntax (` *`).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: use single quotes to prevent glob expansion in allowed tools

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* build: sandbox cargo commands and add git permissions for Claude

- Add safe-cargo.sh wrapper that strips CI secrets before running cargo
- Use --allowedTools for git and safe-cargo, --disallowedTools for raw cargo
- Document safe-cargo usage in CLAUDE.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: switch safe-cargo.sh from denylist to allowlist approach

Use `env -i` (start with empty environment, explicitly pass only
what cargo needs) instead of `env -u` (strip known secrets). This
is more robust against future secrets being added to the workflow.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* build: deny Claude from editing CI scripts and workflows

Prevent Claude from modifying .github/scripts/ and .github/workflows/
to ensure the safe-cargo wrapper cannot be tampered with.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: conditionally pass optional env vars in safe-cargo.sh

Empty PROTOC="" caused prost build scripts to fail with
"protoc not found". Now optional vars (PROTOC, CC, CXX, etc.)
are only passed when set and non-empty.

Tested: build, test, fmt all pass through the wrapper.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* rabbit feedback

* build: move safe-cargo.sh to scripts/ and allow +nightly fmt

Move safe-cargo.sh from .github/scripts/ to top-level scripts/ for
better discoverability. Add detailed comment explaining why the wrapper
exists (prevent CI secret exfiltration via build scripts). Update all
references in claude.yml, CLAUDE.md, and permission settings. Add
`+nightly fmt` to allowedTools so Claude can follow CLAUDE.md
formatting instructions in CI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: PastaClaw <thepastaclaw@users.noreply.github.com>
Co-authored-by: lklimek <842586+lklimek@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* chore: bump rust-dashcore

* chore: imports

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Pasta Lil Claw <pasta+claw@dashboost.org>
Co-authored-by: PastaClaw <thepastaclaw@users.noreply.github.com>
Co-authored-by: PastaPastaPasta <6443210+PastaPastaPasta@users.noreply.github.com>

* ci: cancel in-progress workflow runs on new push (#590)

* ci: cancel in-progress workflow runs on new push

Add concurrency groups to Tests and Clippy workflows so that
previous runs are automatically cancelled when a new commit is
pushed to the same branch or PR.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* trigger ci

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* fix: use correct DashPay profile field "publicMessage" instead of "bio" (#582)

The DashPay contract schema defines the field as "publicMessage",
not "bio". This caused profile bios to never load in contact info.

Co-authored-by: PastaClaw <thepastaclaw@users.noreply.github.com>

---------

Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: lklimek <842586+lklimek@users.noreply.github.com>
Co-authored-by: PastaClaw <thepastaclaw@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: PastaPastaPasta <6443210+PastaPastaPasta@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants