Skip to content

ci: self-hosted Rust + dual Qodana + Docker/devcontainer + telemetry + qlty + Codacy - #1

Merged
rmems merged 40 commits into
mainfrom
ci/github-actions
Aug 1, 2026
Merged

ci: self-hosted Rust + dual Qodana + Docker/devcontainer + telemetry + qlty + Codacy#1
rmems merged 40 commits into
mainfrom
ci/github-actions

Conversation

@rmems

@rmems rmems commented Jul 29, 2026

Copy link
Copy Markdown
Owner

User description

Summary

Single foundation PR for Theseus-Quarry (mining-strict multi-coin supervisor + ops telemetry JSONL): GitHub Actions, dual Qodana, Docker/devcontainer, local quality tooling (qlty + Codacy CLI), and mining/telemetry reliability fixes from review babysit.

Area What landed
Rust CI .github/workflows/ci.yml — self-hosted [self-hosted, Linux, X64, ryzen] (ShipOfTheseus): fmt, clippy -D warnings --locked, test --workspace --locked, workspace target/ sanitize, local qodana · rust
Qodana Cloud .github/workflows/code_quality.ymlJetBrains/qodana-action on ubuntu-latest + QODANA_TOKENhttps://qodana.cloud (fork-safe job gate)
Qodana config qodana.yamlqodana-rust, excludes binaries/ / target/
Docker CI .github/workflows/docker.yml — source-only build + non-root smoke (--user, named volume, pre-chown)
Devcontainer / Cursor .devcontainer/*, .cursor/Dockerfile + environment.json
Toolchain rust-toolchain.toml (stable + rustfmt/clippy), scripts/setup-rust.sh
Qlty .qlty/qlty.toml + shellcheck/hadolint configs; .github/actionlint.yaml custom ryzen label
Codacy .codacy/codacy.yaml (local CLI: lizard / opengrep / trivy) + root .codacy.yml excludes binaries/**, target/**, etc.
Deps / OSV dotenvdotenvy; reqwest 0.11 → 0.12; openssl/anyhow bumps
Telemetry / miners Qubic tick → NodeHealth (not zero-hashrate MinerPerf); TH/s ×1e6; is_usable_binary; harvest_nodes tilde + default data/telemetry; stdout error resilience; env binary overrides

Not in this PR (follow-ups): multi-GPU GpuScheduler device index; full stateful stdout parsers; Dependabot-specific Qodana skip (cubic P2); Codacy Cloud org connection (Membrane auth pending).

Dual Qodana (important)

Check Runner Mode
qodana · rust Self-hosted ryzen Local CLI or jetbrains/qodana-rust image — no Cloud token
qodana / Qodana for Rust ubuntu-latest Official action + QODANA_TOKEN → Qodana Cloud

Codacy

Piece Path / note
CLI config .codacy/codacy.yamlmode: local, tools: lizard, opengrep, trivy
Cloud ignores .codacy.yml — excludes binaries/**, target/**, .qodana/**, lockfile, markdown
Local CLI ~/.cache/codacy/codacy-cli-v2/.../codacy-cli-v2init / install / analyze
Cloud API via Membrane Needs browser auth (see PR comment / agent note)
codacy-cli install
codacy-cli analyze --tool trivy   # skips gitignored binaries when .codacy.yml excludes applied by Cloud

Note: Local Trivy may still walk on-disk binaries/ unless skip-dirs is set in the local tools-configs (gitignored). Those paths are gitignored and must never be committed.

Required secret

Repo Settings → Secrets and variables → Actions:

Without it, the Cloud Qodana workflow fails auth on GitHub-hosted runners.

Self-hosted runner

  • Host: ShipOfTheseus · ~/actions-runner/Theseus-Quarry-runner
  • Labels: self-hosted, Linux, X64, ryzen
  • PR jobs gated to same-repo heads (head.repo.full_name == github.repository) — not for untrusted forks
cd ~/actions-runner/Theseus-Quarry-runner
sudo ./svc.sh install && sudo ./svc.sh start

Test plan

  • Local cargo fmt / clippy -D warnings --locked / test --workspace --locked
  • Local docker build + qodana CLI scan
  • CI green: fmt · clippy · test
  • CI green: qodana · rust (self-hosted)
  • CI green: Qodana Cloud (ubuntu-latest + token)
  • Docker workflow green (non-root smoke + volume chown)
  • cubic · AI code reviewer success
  • qlty check clean after init
  • codacy-cli init + slim tools + install + trivy smoke
  • Codacy Cloud org/repo link (Membrane login)
  • Merge when you say so (agents do not merge without ask)

Review / quality notes

  • Addressed CodeAnt / CodeRabbit / Codex / cubic / qlty findings within babysit scope.
  • Residual cubic: Dependabot Qodana gate, qlty config/** exclude scope, mine-*.sh error path text, hadolint DL3008 — mostly P2/P3.
  • Milestone: v0.1 — CI & foundation
  • Labels: enhancement, documentation, area:ci, area:devcontainer, priority:P1, size:XL

Attribution

Commits and PR comments from babysit are signed Grok Build: Grok 4.5.

Source-only tree; no secrets/binaries in git. .qodana/ and large binaries/ remain gitignored. Telemetry is produced here for research consumers elsewhere (not neuromorphic reconfig).


CodeAnt-AI Description

Make mining telemetry accurate and mining operations safer

What Changed

  • Mining output now keeps cumulative hashrates and share counts, reports correct H/s, kH/s, MH/s, and TH/s values, and ignores banner-only lines when creating performance records.
  • Qubic tick-only updates are recorded as node health instead of zero-hashrate mining performance.
  • Miner and node telemetry readers continue past individual unreadable log lines, while broken stdout pipes end cleanly.
  • Miner detection accepts executable wrappers, rejects empty or placeholder files, and preserves explicit binary overrides.
  • Algorithm switching restores the previous miner when GPU memory is not released, preventing a new workload from starting under VRAM pressure.
  • Native Qubic and Rigel launches now require and support their wallet settings, with clear failure messages when configuration is missing.
  • Log harvesters expand ~, create output directories, use a usable default node output path, and continue when individual log lines cannot be read.
  • Added Rust CI, Docker smoke tests, local development environments, Qodana scans, and quality-tool configuration for consistent validation.

Impact

✅ Correct hashrate units in telemetry
✅ Fewer duplicate and zero-hashrate performance records
✅ Safer GPU algorithm switching
✅ Clearer miner startup failures

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

Run fmt, clippy (-D warnings), and workspace tests on the self-hosted
Linux/X64/ryzen runner. Pin channel=stable via rust-toolchain.toml and
dtolnay/rust-toolchain@stable. Include clippy cleanups needed for a
green gate (WireMsg box, NodeHealthInput, lines map_while, etc.).
@codeant-ai

codeant-ai Bot commented Jul 29, 2026

Copy link
Copy Markdown

🤖 CodeAnt AI — Review Status

Status Commit Started (UTC) Finished (UTC)
✅ Incremental review completed 7ed673c Jul 30, 2026 · 16:49 16:50
✅ Reviewed your PR c9d4585 Jul 29, 2026 · 10:02 10:05
✅ Reviewed your PR bb1926e Jul 29, 2026 · 07:37 07:40
✅ Reviewed your PR 9071d68 Jul 29, 2026 · 03:43 03:47

@codeant-ai

codeant-ai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@cubic-dev-ai

cubic-dev-ai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

We've triggered an ultrareview automatically — This large refactor (778 lines across 25 files) touches core mining telemetry logic, data parsing, and adds critical CI infrastructure; subtle bugs in let-chain conversions or I/O handling could break production telemetry.. I'll post findings when complete.

An ultrareview is cubic's deepest review, catching hard-to-find bugs in the most critical PRs. It runs a longer, multi-pass analysis using cubic's most capable review models, and typically takes around 30 minutes. It consumes your team's reviewed-lines allowance at 3× the standard rate.

Automated ultrareviews are disabled by default. We triggered this run as part of your trial. Want cubic to do this for every high-risk PR? Enable auto-ultrareview in your settings.

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

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

The pull request adds Rust toolchain, container, and CI configuration, changes telemetry wire and node-health APIs, updates collectors and miners to use those APIs, and refactors process readers, supervisor logic, harvesting utilities, and development documentation.

Changes

Telemetry and mining runtime

Layer / File(s) Summary
Rust toolchain, containers, and CI validation
.github/workflows/*, rust-toolchain.toml, .devcontainer/*, .cursor/*, qodana.yaml, scripts/setup-rust.sh, README.md
Adds stable Rust configuration, development containers, workspace checks, Docker and Qodana workflows, repository tooling configuration, and setup documentation.
Telemetry contracts and wire messages
crates/mining-telemetry-core/src/*.rs
Adds NodeHealthInput, boxes mining telemetry messages, adds a constructor, normalizes hashrate units, and makes extraction failure-safe.
Collector node-health integration
crates/telemetry-collector/src/sources/*, crates/telemetry-collector/src/writer.rs
Updates coin collectors to construct named node-health inputs and simplifies QUAI, hwmon, imports, and test paths.
Miner process telemetry flow
crates/theseus-mining/src/*_miner.rs, crates/theseus-mining/src/miner.rs
Uses the new mining-message constructor, updates line-reader error handling, strengthens binary validation, enforces Qubic identity setup, and introduces the SpawnFn alias.
Supervisor, startup, and harvesting paths
crates/theseus-mining/src/main.rs, mining_supervisor.rs, gpu_scheduler.rs, src/bin/harvest_*.rs, scripts/*
Refactors algorithm switching, startup environment setup, output-path expansion, harvesting diagnostics, timestamp guards, shell loading, and miner binary messages.

Estimated code review effort: 4 (Complex) | ~45 minutes

Poem

I’m a rabbit with Rust in my paws,
Watching CI hop through checks and laws.
Boxes carry telemetry bright,
Named fields make the paths feel right,
Logs stop clean when errors appear—
And carrots compile without fear!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 83.02% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title matches the PR’s main focus on CI, Qodana, Docker/devcontainer, telemetry, and quality-tooling updates.
Description check ✅ Passed The description is detailed and clearly aligned with the repository-wide CI, tooling, and telemetry changes.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/github-actions

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.

@codeant-ai codeant-ai Bot added the size:L This PR changes 100-499 lines, ignoring generated files label Jul 29, 2026

@amazon-q-developer amazon-q-developer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This PR adds GitHub Actions CI infrastructure and applies clippy/formatting fixes to make the codebase pass cargo fmt --check and cargo clippy -D warnings. The changes are appropriate for enabling CI gates on a self-hosted runner. All modifications are code quality improvements (import ordering, let-chain syntax, boxing large enum variants) that resolve clippy warnings without altering program logic.


You can now have the agent implement changes and create commits directly on your pull request's source branch. Simply comment with /q followed by your request in natural language to ask the agent to make changes.

Comment thread crates/mining-telemetry-core/src/schema.rs
Comment thread crates/theseus-mining/src/bin/harvest_nodes.rs Outdated
Comment thread crates/theseus-mining/src/gpu_scheduler.rs
Comment thread crates/theseus-mining/src/miner.rs Outdated
Comment thread crates/theseus-mining/src/miner.rs Outdated
Comment thread crates/theseus-mining/src/mining_supervisor.rs
Comment thread crates/theseus-mining/src/kaspa_miner.rs
Comment thread crates/theseus-mining/src/monero_miner.rs Outdated
Comment thread crates/mining-telemetry-core/src/lib.rs Outdated
Comment thread crates/telemetry-collector/src/sources/kaspa.rs Outdated
Comment thread crates/theseus-mining/src/quai_miner.rs Outdated
Comment thread crates/theseus-mining/src/qubic_miner.rs

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9071d68d9f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/ci.yml

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/ci.yml:
- Around line 20-23: Add least-privilege token permissions to the `check`
workflow job by declaring `permissions` with only `contents: read` access. Keep
the existing job steps and runner configuration unchanged unless they require an
explicitly documented additional permission.
- Line 29: Update the workflow’s third-party action references, including
actions/checkout, dtolnay/rust-toolchain, and Swatinem/rust-cache, to full
reviewed commit SHA pins, using Dependabot or Renovate for the pin updates.
Preserve the Rust stable channel as the rust-toolchain action’s
input/configuration value.
- Around line 9-10: Update the pull_request workflow configuration in ci.yml so
fork-originated pull requests do not execute on the persistent self-hosted ryzen
runner; route them to a GitHub-hosted ephemeral runner or require manual
approval before self-hosted execution, while preserving validation for trusted
pull requests.
- Around line 28-29: Update the Checkout step using actions/checkout@v4 to set
persist-credentials to false, unless a later workflow step explicitly requires
Git authentication; preserve the existing step order and behavior otherwise.

In `@crates/theseus-mining/src/bin/harvest_miners.rs`:
- Line 95: Update the line-reading loop in main so file read errors from
reader.lines() are not discarded by map_while(Result::ok). Propagate the Result
through the harvest flow or explicitly handle and report each error, ensuring
main returns failure when telemetry reading is incomplete rather than silently
succeeding.
🪄 Autofix (Beta)

❌ Autofix failed (check again to retry)

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 Plus

Run ID: 02c792ec-8827-408b-8f9f-315c4d90af32

📥 Commits

Reviewing files that changed from the base of the PR and between 2a474a8 and 9071d68.

📒 Files selected for processing (25)
  • .github/workflows/ci.yml
  • crates/mining-telemetry-core/src/lib.rs
  • crates/mining-telemetry-core/src/schema.rs
  • crates/telemetry-collector/src/sources/dynex.rs
  • crates/telemetry-collector/src/sources/hwmon.rs
  • crates/telemetry-collector/src/sources/kaspa.rs
  • crates/telemetry-collector/src/sources/monero.rs
  • crates/telemetry-collector/src/sources/quai.rs
  • crates/telemetry-collector/src/sources/qubic.rs
  • crates/telemetry-collector/src/sources/rapl.rs
  • crates/telemetry-collector/src/writer.rs
  • crates/theseus-mining/src/bin/harvest_miners.rs
  • crates/theseus-mining/src/bin/harvest_nodes.rs
  • crates/theseus-mining/src/dynex_miner.rs
  • crates/theseus-mining/src/gpu_scheduler.rs
  • crates/theseus-mining/src/kaspa_miner.rs
  • crates/theseus-mining/src/lib.rs
  • crates/theseus-mining/src/main.rs
  • crates/theseus-mining/src/miner.rs
  • crates/theseus-mining/src/mining_supervisor.rs
  • crates/theseus-mining/src/monero_miner.rs
  • crates/theseus-mining/src/quai_miner.rs
  • crates/theseus-mining/src/qubic_miner.rs
  • crates/theseus-mining/src/verus_miner.rs
  • rust-toolchain.toml
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: cubic · AI code reviewer
🧰 Additional context used
🪛 actionlint (1.7.12)
.github/workflows/ci.yml

[error] 24-24: label "ryzen" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2025", "windows-2025-vs2026", "windows-2022", "windows-11-arm", "ubuntu-slim", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "macos-latest", "macos-latest-xlarge", "macos-latest-large", "macos-26-intel", "macos-26-xlarge", "macos-26-large", "macos-26", "macos-15-intel", "macos-15-xlarge", "macos-15-large", "macos-15", "macos-14-xlarge", "macos-14-large", "macos-14", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file

(runner-label)

🪛 zizmor (1.28.0)
.github/workflows/ci.yml

[warning] 28-29: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[error] 29-29: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 32-32: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 43-43: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[info] 32-32: action functionality is already included by the runner (superfluous-actions): use rustup and/or cargo in a script step

(superfluous-actions)

🔇 Additional comments (25)
crates/mining-telemetry-core/src/lib.rs (1)

4-6: LGTM!

Also applies to: 209-223, 386-397

crates/mining-telemetry-core/src/schema.rs (1)

110-124: LGTM!

Also applies to: 182-297, 307-307, 346-374, 472-479, 516-520

crates/telemetry-collector/src/writer.rs (1)

1-1: LGTM!

Also applies to: 50-58

crates/theseus-mining/src/miner.rs (1)

8-8: LGTM!

Also applies to: 84-99, 157-157, 168-168, 189-189, 270-273, 303-364

crates/theseus-mining/src/dynex_miner.rs (1)

4-4: LGTM!

Also applies to: 101-102, 119-119

crates/theseus-mining/src/kaspa_miner.rs (1)

4-4: LGTM!

Also applies to: 95-95, 114-122

crates/theseus-mining/src/monero_miner.rs (1)

4-4: LGTM!

Also applies to: 128-128, 149-156

crates/theseus-mining/src/qubic_miner.rs (1)

33-33: LGTM!

Also applies to: 409-417, 495-498, 535-538, 589-599, 617-624, 648-657

crates/theseus-mining/src/verus_miner.rs (1)

4-4: LGTM!

Also applies to: 151-158

crates/telemetry-collector/src/sources/dynex.rs (1)

2-2: LGTM!

Also applies to: 26-30

crates/telemetry-collector/src/sources/kaspa.rs (1)

2-2: LGTM!

Also applies to: 32-36

crates/telemetry-collector/src/sources/monero.rs (1)

2-3: LGTM!

Also applies to: 44-52

crates/telemetry-collector/src/sources/quai.rs (1)

2-3: LGTM!

Also applies to: 20-34

crates/telemetry-collector/src/sources/qubic.rs (1)

2-2: LGTM!

Also applies to: 28-33

crates/telemetry-collector/src/sources/hwmon.rs (1)

1-1: LGTM!

Also applies to: 17-20

crates/telemetry-collector/src/sources/rapl.rs (1)

1-1: LGTM!

crates/theseus-mining/src/quai_miner.rs (1)

10-10: LGTM!

Also applies to: 43-46, 248-248, 304-307

rust-toolchain.toml (1)

1-4: LGTM!

.github/workflows/ci.yml (2)

24-24: 🩺 Stability & Availability

Verify the custom ryzen runner label.

Ensure an online runner is registered with self-hosted, Linux, x64, and ryzen labels; otherwise this job will remain queued. If actionlint is used in validation, add the custom label to its configuration.

Source: Linters/SAST tools


1-8: LGTM!

Also applies to: 12-18, 36-40, 47-54

crates/theseus-mining/src/mining_supervisor.rs (1)

82-87: LGTM!

Also applies to: 209-209, 419-423

crates/theseus-mining/src/gpu_scheduler.rs (1)

16-20: LGTM!

Also applies to: 171-180

crates/theseus-mining/src/lib.rs (1)

2-5: LGTM!

crates/theseus-mining/src/main.rs (1)

23-28: LGTM!

Also applies to: 132-139, 215-223, 363-363

crates/theseus-mining/src/bin/harvest_nodes.rs (1)

23-33: LGTM!

Also applies to: 91-93, 113-113, 146-148, 232-239

Comment thread .github/workflows/ci.yml
Comment thread .github/workflows/ci.yml Outdated
Comment thread .github/workflows/ci.yml Outdated
Comment thread .github/workflows/ci.yml Outdated
Comment thread crates/theseus-mining/src/bin/harvest_miners.rs Outdated

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ultrareview completed in 14m 21s

All reported issues were addressed across 25 files

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

Comment thread crates/theseus-mining/src/miner.rs Outdated
Comment thread crates/theseus-mining/src/kaspa_miner.rs Outdated
Extend PR with source-only .devcontainer image, docker.yml (build +
cargo test smoke on self-hosted), and README notes for ShipOfTheseus
runner labels and svc.sh. Completes the single CI PR surface.
@rmems rmems changed the title ci: add GitHub Actions workflow (fmt, clippy, test) ci: Rust + Docker workflows, devcontainer, self-hosted runner Jul 29, 2026
@rmems rmems self-assigned this Jul 29, 2026
@rmems rmems added area:ci GitHub Actions, runners, docker area:devcontainer Devcontainer and Dockerfile documentation Docs, README, CONTEXT labels Jul 29, 2026
@rmems rmems added this to the v0.1 — CI & foundation milestone Jul 29, 2026
@rmems rmems added size:XL PR 500+ lines enhancement New feature or request priority:P1 High — next up and removed size:L This PR changes 100-499 lines, ignoring generated files labels Jul 29, 2026
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

⚠️ Branch updated during autofix.

The branch was updated while autofix was in progress. Please try again.

@cubic-dev-ai

cubic-dev-ai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

I've fixed both issues from the PR review:

Fixed Issues

  1. kaspa_miner.rs:121 - Added proper assertion to detect_binary_env_override test

    • The test now verifies that KASPA_MINER_CMD override is honored
    • Changed from no-op let _ = result; to assert_eq!(result.as_deref(), Some("/custom/path/bzminer"));
  2. miner.rs:303-310 - Fixed stdout reader error handling to continue after recoverable errors

    • Changed from .map_while(Result::ok) which stops on first error
    • Now explicitly handles each line result, logs errors, and continues processing
    • Preserves later telemetry and status messages even after encountering invalid UTF-8 or read errors

Changes Made

  • crates/theseus-mining/src/kaspa_miner.rs: 1 line changed
  • crates/theseus-mining/src/miner.rs: 8 lines changed

⚠️ Unable to run cargo test/clippy locally (Rust toolchain not available in environment), but changes follow standard Rust patterns and will be validated by CI.

Pushed commits to ci/github-actions.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f81da7f1c8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .devcontainer/Dockerfile
Comment thread .devcontainer/devcontainer.json
Comment thread .github/workflows/docker.yml
Comment thread .github/workflows/ci.yml Outdated
- Add assertion to detect_binary_env_override test to verify KASPA_MINER_CMD override
- Handle stdout read errors explicitly and continue processing instead of stopping

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.devcontainer/Dockerfile:
- Around line 22-29: Update the Dockerfile shell setup surrounding the rustup
installer pipeline to enable pipefail before the curl-to-sh command, ensuring a
curl failure causes the RUN step to fail. Preserve the existing rustup arguments
and version checks.
- Around line 6-9: Update the Dockerfile setup after Rust/Cargo installation to
recursively change ownership of the directories referenced by CARGO_HOME and
RUSTUP_HOME to vscode:vscode, ensuring both locations are writable by the
devcontainer user and raw Docker test users.

In @.github/workflows/docker.yml:
- Around line 45-58: Update the “Build dev image” and “Smoke — cargo test inside
image” workflow steps to clean up the tagged image, dangling layers, and build
cache after execution on the persistent runner. Add an explicit bounded
retention/prune policy while preserving the existing build and cargo test
behavior.
- Around line 39-40: Update the Checkout step’s actions/checkout reference to
the approved immutable 40-character commit SHA instead of the movable v4 tag,
preserving the existing workflow step and action behavior.
- Around line 39-40: Update the actions/checkout step to set persist-credentials
to false, and add a workflow-level permissions configuration granting only
contents: read. Preserve the existing checkout behavior and avoid adding broader
permissions or authenticated Git operations.
🪄 Autofix (Beta)

✅ Autofix completed


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 03220f65-57ff-436f-8d92-22e6b0aa5bfa

📥 Commits

Reviewing files that changed from the base of the PR and between 9071d68 and f81da7f.

📒 Files selected for processing (4)
  • .devcontainer/Dockerfile
  • .devcontainer/devcontainer.json
  • .github/workflows/docker.yml
  • README.md
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: cubic · AI code reviewer
⚠️ CI failures not shown inline (2)

GitHub Actions: CI / fmt · clippy · test: ci: Rust + Docker workflows, devcontainer, self-hosted runner

Conclusion: failure

View job details

ntal/telemetry_collector-1ocfjh7x6uhx6/s-hku7khwuuq-1d5ap3i-7y8er3bj8ptg2u8385259hypu/6grwvpq1uxvzdnpp74yqa95fw.o: Permission denied
 warning: failed to remove target/debug/incremental/telemetry_collector-1ocfjh7x6uhx6/s-hku7khwuuq-1d5ap3i-7y8er3bj8ptg2u8385259hypu/6hdd72qaydhusrx06avdavnl0.o: Permission denied
 warning: failed to remove target/debug/incremental/telemetry_collector-1ocfjh7x6uhx6/s-hku7khwuuq-1d5ap3i-7y8er3bj8ptg2u8385259hypu/6orpz5lge7jr3ftamjz3v67lg.o: Permission denied
 warning: failed to remove target/debug/incremental/telemetry_collector-1ocfjh7x6uhx6/s-hku7khwuuq-1d5ap3i-7y8er3bj8ptg2u8385259hypu/6p5tlpadp4vcx2pxpimoxlniu.o: Permission denied
 warning: failed to remove target/debug/incremental/telemetry_collector-1ocfjh7x6uhx6/s-hku7khwuuq-1d5ap3i-7y8er3bj8ptg2u8385259hypu/6t4v0hupntt3g08zy9o92bbik.o: Permission denied
 warning: failed to remove target/debug/incremental/telemetry_collector-1ocfjh7x6uhx6/s-hku7khwuuq-1d5ap3i-7y8er3bj8ptg2u8385259hypu/7316sb0du8k9j5xdvk5f4s6ik.o: Permission denied
 warning: failed to remove target/debug/incremental/telemetry_collector-1ocfjh7x6uhx6/s-hku7khwuuq-1d5ap3i-7y8er3bj8ptg2u8385259hypu/747q3hc36rv6pg02oxc4bkhsm.o: Permission denied
 warning: failed to remove target/debug/incremental/telemetry_collector-1ocfjh7x6uhx6/s-hku7khwuuq-1d5ap3i-7y8er3bj8ptg2u8385259hypu/7jj85weswvfodnl1lqhpmvybo.o: Permission denied
 warning: failed to remove target/debug/incremental/telemetry_collector-1ocfjh7x6uhx6/s-hku7khwuuq-1d5ap3i-7y8er3bj8ptg2u8385259hypu/7l8wvq8c6d7uxoe93c6gr6jf7.o: Permission denied
 warning: failed to remove target/debug/incremental/telemetry_collector-1ocfjh7x6uhx6/s-hku7khwuuq-1d5ap3i-7y8er3bj8ptg2u8385259hypu/7ntf8kdm10jyargd0at9vhjp9.o: Permission denied
 warning: failed to remove target/debug/incremental/telemetry_collector-1ocfjh7x6uhx6/s-hku7khwuuq-1d5ap3i-7y8er3bj8ptg2u8385259hypu/7yfba0doit6a7scy4h1fawzhv.o: Permission denied
 warning: failed to remove target/debug/incremental/telemetry_co...

GitHub Actions: CI / 0_fmt · clippy · test.txt: ci: Rust + Docker workflows, devcontainer, self-hosted runner

Conclusion: failure

View job details

ntal/telemetry_collector-1ocfjh7x6uhx6/s-hku7khwuuq-1d5ap3i-7y8er3bj8ptg2u8385259hypu/6grwvpq1uxvzdnpp74yqa95fw.o: Permission denied
 warning: failed to remove target/debug/incremental/telemetry_collector-1ocfjh7x6uhx6/s-hku7khwuuq-1d5ap3i-7y8er3bj8ptg2u8385259hypu/6hdd72qaydhusrx06avdavnl0.o: Permission denied
 warning: failed to remove target/debug/incremental/telemetry_collector-1ocfjh7x6uhx6/s-hku7khwuuq-1d5ap3i-7y8er3bj8ptg2u8385259hypu/6orpz5lge7jr3ftamjz3v67lg.o: Permission denied
 warning: failed to remove target/debug/incremental/telemetry_collector-1ocfjh7x6uhx6/s-hku7khwuuq-1d5ap3i-7y8er3bj8ptg2u8385259hypu/6p5tlpadp4vcx2pxpimoxlniu.o: Permission denied
 warning: failed to remove target/debug/incremental/telemetry_collector-1ocfjh7x6uhx6/s-hku7khwuuq-1d5ap3i-7y8er3bj8ptg2u8385259hypu/6t4v0hupntt3g08zy9o92bbik.o: Permission denied
 warning: failed to remove target/debug/incremental/telemetry_collector-1ocfjh7x6uhx6/s-hku7khwuuq-1d5ap3i-7y8er3bj8ptg2u8385259hypu/7316sb0du8k9j5xdvk5f4s6ik.o: Permission denied
 warning: failed to remove target/debug/incremental/telemetry_collector-1ocfjh7x6uhx6/s-hku7khwuuq-1d5ap3i-7y8er3bj8ptg2u8385259hypu/747q3hc36rv6pg02oxc4bkhsm.o: Permission denied
 warning: failed to remove target/debug/incremental/telemetry_collector-1ocfjh7x6uhx6/s-hku7khwuuq-1d5ap3i-7y8er3bj8ptg2u8385259hypu/7jj85weswvfodnl1lqhpmvybo.o: Permission denied
 warning: failed to remove target/debug/incremental/telemetry_collector-1ocfjh7x6uhx6/s-hku7khwuuq-1d5ap3i-7y8er3bj8ptg2u8385259hypu/7l8wvq8c6d7uxoe93c6gr6jf7.o: Permission denied
 warning: failed to remove target/debug/incremental/telemetry_collector-1ocfjh7x6uhx6/s-hku7khwuuq-1d5ap3i-7y8er3bj8ptg2u8385259hypu/7ntf8kdm10jyargd0at9vhjp9.o: Permission denied
 warning: failed to remove target/debug/incremental/telemetry_collector-1ocfjh7x6uhx6/s-hku7khwuuq-1d5ap3i-7y8er3bj8ptg2u8385259hypu/7yfba0doit6a7scy4h1fawzhv.o: Permission denied
 warning: failed to remove target/debug/incremental/telemetry_co...
🧰 Additional context used
🪛 actionlint (1.7.12)
.github/workflows/docker.yml

[error] 35-35: label "ryzen" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2025", "windows-2025-vs2026", "windows-2022", "windows-11-arm", "ubuntu-slim", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "macos-latest", "macos-latest-xlarge", "macos-latest-large", "macos-26-intel", "macos-26-xlarge", "macos-26-large", "macos-26", "macos-15-intel", "macos-15-xlarge", "macos-15-large", "macos-15", "macos-14-xlarge", "macos-14-large", "macos-14", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file

(runner-label)

🪛 Checkov (3.3.8)
.devcontainer/Dockerfile

[low] 1-34: Ensure that HEALTHCHECK instructions have been added to container images

(CKV_DOCKER_2)


[low] 1-34: Ensure that a user for the container has been created

(CKV_DOCKER_3)

🪛 Hadolint (2.14.0)
.devcontainer/Dockerfile

[warning] 11-11: Pin versions in apt get install. Instead of apt-get install <package> use apt-get install <package>=<version>

(DL3008)


[warning] 22-22: Set the SHELL option -o pipefail before RUN with a pipe in it. If you are using /bin/sh in an alpine image or if your shell is symlinked to busybox then consider explicitly setting your SHELL to /bin/ash, or disable this check

(DL4006)

🪛 Trivy (0.72.0)
.devcontainer/Dockerfile

[error] 1-1: Image user should not be 'root'

Specify at least 1 USER command in Dockerfile with non-root user as argument

Rule: DS-0002

Learn more

(IaC/Dockerfile)


[info] 1-1: No HEALTHCHECK defined

Add HEALTHCHECK instruction in your Dockerfile

Rule: DS-0026

Learn more

(IaC/Dockerfile)

🪛 zizmor (1.28.0)
.github/workflows/docker.yml

[warning] 39-40: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[error] 40-40: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🔇 Additional comments (6)
.devcontainer/Dockerfile (1)

1-5: LGTM!

Also applies to: 11-20, 31-34

.devcontainer/devcontainer.json (1)

1-33: LGTM!

.github/workflows/docker.yml (3)

15-23: 🔒 Security & Privacy

Security Misconfiguration (CWE-693)

Reachability: External

Verify that untrusted PRs are allowed on this self-hosted runner.

This pull_request workflow executes PR-controlled Dockerfile and Rust code on the persistent [self-hosted, Linux, X64, ryzen] runner. If external contributors can open PRs, use an isolated/ephemeral runner or gate this job with approval; container isolation alone should not be treated as runner isolation.

Also applies to: 32-36


1-14: LGTM!

Also applies to: 25-30, 42-43


45-50: 🎯 Functional Correctness

No change needed for this cache concern.

GitHub Actions runners are ephemeral per job, and Docker layers are cache-invalidated when instructions or their inputs change; rust-toolchain.toml content changes propagate to later rustup/check layers through normal Docker cache invalidation. --pull does not invalidate RUN layers, and --no-cache would remove Docker’s normal build-speed benefit.

			> Likely an incorrect or invalid review comment.
README.md (1)

82-93: LGTM!

Also applies to: 95-100, 106-124

Comment thread .devcontainer/Dockerfile
Comment thread .devcontainer/Dockerfile Outdated
Comment thread .github/workflows/docker.yml Outdated
Comment thread .github/workflows/docker.yml Outdated
@rmems rmems changed the title ci: Rust + Docker workflows, devcontainer, self-hosted runner ci: Rust + Qodana + Docker, devcontainer, self-hosted runner Jul 29, 2026

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

All reported issues were addressed across 2 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Fix all with cubic | Re-trigger cubic

Comment thread crates/theseus-mining/src/miner.rs Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: baaddc7fbe

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/theseus-mining/src/qubic_miner.rs Outdated
Comment thread crates/theseus-mining/src/miner.rs Outdated
- kill_process_group probes the process group (not only the leader) so
  workers that outlive SIGTERM still get SIGKILL
- Track native_kind/gpu_enabled on Qubic Running state; Yield/Resume only
  restart GPU-enabled qubic-core (qli-Client is CPU-only)

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

All reported issues were addressed across 2 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Fix all with cubic | Re-trigger cubic

Comment thread crates/theseus-mining/src/qubic_miner.rs Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 58be67d059

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/theseus-mining/src/miner.rs
Comment thread .github/workflows/ci.yml Outdated
Comment thread crates/theseus-mining/src/qubic_miner.rs
YieldForChat passes false to free VRAM, but spawn re-read AIGARTH_ENABLED
from the environment and relaunched with --gpu. Use the argument for
--gpu, thread defaults, and gpu_enabled state.
@rmems

rmems commented Jul 31, 2026

Copy link
Copy Markdown
Owner Author

Receiving-code-review note (Grok Build: Grok 4.5)

Verified cubic review-body P1 on c75e6ef against code: real bug.

YieldForChat called spawn_native_binary(..., false) but the param was _aigarth_enabled and the body re-read AIGARTH_ENABLED, so yield still launched with --gpu.

Fix in c75e6ef: spawn_native_binary uses the boolean argument for --gpu, thread defaults, and gpu_enabled state — no env re-read.

Waiting for Codex on this head before any further push.

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

All reported issues were addressed across 1 file (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Fix all with cubic | Re-trigger cubic

Comment thread crates/theseus-mining/src/qubic_miner.rs

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c75e6ef0c8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/theseus-mining/src/miner.rs Outdated
Comment thread .devcontainer/Dockerfile
Extract native_core_cli_args / native_gpu_enabled so aigarth=false omits
--gpu and aigarth=true includes it without spawning a process.
@rmems

rmems commented Jul 31, 2026

Copy link
Copy Markdown
Owner Author

@codex review

Please review head 04351f4 (YieldForChat GPU flag honor + pure CLI arg regression tests).

— Grok Build: Grok 4.5

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

Reviewed commit: 04351f4e9c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

rmems added 2 commits July 31, 2026 14:51
Keep neuromorphic/training design packages out of the mining-strict tree.
…detect

Keep miner Running until the process group exits so shell wrappers cannot
orphan workers under a premature Idle; require shebang/ELF headers for
usable binaries; run qli-Client from its distribution directory; source
cargo env only when present; preinstall rust-src and rust-analyzer in the
devcontainer image.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7c939be0df

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/theseus-mining/src/qubic_miner.rs
Comment thread .devcontainer/devcontainer.json Outdated

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

5 issues found across 5 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

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


<file name="crates/theseus-mining/src/miner.rs">

<violation number="1" location="crates/theseus-mining/src/miner.rs:64">
P2: A miner can remain permanently `Running` after its leader exits if a wrapper leaves a zombie in the process group: `kill(-pgid, 0)` still reports that group as present, but this reaper has no deadline or recovery path. A bounded group-drain policy (with explicit timeout handling/cleanup) would prevent a stale reaper thread and stale miner state when the group cannot disappear.</violation>

<violation number="2" location="crates/theseus-mining/src/miner.rs:180">
P3: Binary detection performs redundant placeholder parsing: every recognized placeholder is already rejected by `looks_like_executable_header`. Consider removing this call and `is_download_placeholder` to keep the validation path single-purpose and allocation-free.</violation>

<violation number="3" location="crates/theseus-mining/src/miner.rs:211">
P2: Miner startup can fail instead of falling back when a truncated download retains `\x7fELF`, because this four-byte check marks it usable and shadows later candidates. Validate the ELF class, encoding, version, header length, and `ET_EXEC`/`ET_DYN` type before accepting it.</violation>
</file>

<file name="crates/theseus-mining/src/qubic_miner.rs">

<violation number="1" location="crates/theseus-mining/src/qubic_miner.rs:706">
P1: Qubic fails to start when `qli-Client` is discovered through PATH: `Path::new("qli-Client").parent()` is an empty path, so `current_dir(parent)` attempts to chdir to `""` and `command.spawn()` fails. The launch directory adjustment could skip an empty parent, while resolving relative paths to an absolute executable path before changing directories would also preserve the intended adjacent-content behavior.</violation>

<violation number="2" location="crates/theseus-mining/src/qubic_miner.rs:804">
P2: After the process group fully exits and state transitions to Idle here, the previously tracked child_pid used by Stop/kill_native isn't cleared. If the OS reuses that PID as a process-group ID before the next Stop is issued, kill_native could send SIGTERM/SIGKILL to an unrelated process. Consider clearing the tracked PID as part of this reap path, or validate that state is still Running with a matching PID before signaling in Stop.</violation>
</file>

Tip: instead of fixing issues one by one fix them all with cubic
Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread crates/theseus-mining/src/qubic_miner.rs Outdated
Comment thread crates/theseus-mining/src/miner.rs Outdated
Comment thread crates/theseus-mining/src/qubic_miner.rs Outdated
Comment thread crates/theseus-mining/src/miner.rs
Comment thread crates/theseus-mining/src/miner.rs
- Stop: only kill_native when state is still Running; clear stale child_pid
- qli launch: skip empty parent; canonicalize PATH-only binaries for cwd
- wait_process_group_exit: 30s bound + SIGKILL drain (no infinite reaper)
- ELF detection: require class + ET_EXEC/ET_DYN (reject magic-only truncations)
- devcontainer: cargo fetch/check --locked so hooks cannot rewrite Cargo.lock

Grok Build: Grok 4.5

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

2 issues found across 3 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

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


<file name="crates/theseus-mining/src/miner.rs">

<violation number="1" location="crates/theseus-mining/src/miner.rs:75">
P1: Backgrounding launch wrappers now have their healthy miner worker terminated 30 seconds after the wrapper exits. `process_group_alive` cannot distinguish a live worker from a zombie/stuck worker, so SIGKILL should be reserved for an explicit stop or a liveness-aware cleanup path.</violation>

<violation number="2" location="crates/theseus-mining/src/miner.rs:237">
P3: On a big-endian deployment, executable detection rejects valid ELF miners because `e_type` is always decoded as little-endian. Decode bytes 16–17 according to `EI_DATA` and reject unknown encodings.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Fix all with cubic | Re-trigger cubic

Comment thread crates/theseus-mining/src/miner.rs Outdated
Comment thread crates/theseus-mining/src/miner.rs Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c470dff4df

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/theseus-mining/src/qubic_miner.rs Outdated
- wait_process_group_exit returns bool; never SIGKILLs (Stop owns kill)
- reapers leave Running when group still alive after timeout
- which discovery returns absolute path; resolve_executable_path for qli cwd
- ELF e_type decoded via EI_DATA (LE/BE)

Grok Build: Grok 4.5

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5afd85ef2a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .devin/blueprint.yaml Outdated

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

1 issue found across 3 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

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


<file name="crates/theseus-mining/src/qubic_miner.rs">

<violation number="1" location="crates/theseus-mining/src/qubic_miner.rs:721">
P2: For qli-Client launches, `command.current_dir()` is set to the resolved binary's parent directory, but `Command::new(&binary)` is still given the original (relative) `binary` string. When `binary` is a relative path that includes a directory component (for example a `QUBIC_MINER_CMD` override such as `dist/qli-Client` or `bin/qli-Client`), the relative path is re-resolved against the new `current_dir`, i.e. the binary's own directory, so the directory component is applied twice and the spawned command resolves to a non-existent `dist/dist/qli-Client` — the miner fails to start. Absolute paths and bare PATH names are unaffected, so this only surfaces with relative-with-directory qli overrides. Use the resolved absolute path in `Command::new` (setting `current_dir` to its parent) so relative and PATH-only inputs both launch correctly.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Fix all with cubic | Re-trigger cubic

Comment thread crates/theseus-mining/src/qubic_miner.rs Outdated
- .devin/blueprint: cargo fetch/clippy/test/build use --locked (match AGENTS.md)
- qli: Command::new(resolved absolute) then current_dir(parent) so relative
  overrides like dist/qli-Client are not re-resolved as dist/dist/qli-Client

Grok Build: Grok 4.5

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d53c2e3d53

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

"{log_prefix} process group still alive after wait timeout \
(PID {reaped_pid}); leaving Running so Stop can kill orphans"
);
return;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Continue monitoring the process group after timeout

When a supported shell wrapper exits while its worker remains alive for more than 30 seconds, this return permanently ends the only reaper while leaving the state Running; if the worker later exits naturally, subsequent Start commands are still ignored as “already running” even though the process group is gone. Fresh evidence beyond the prior reaper thread is that the timeout path now retains the PGID but never checks it again; keep monitoring asynchronously until the group disappears and then clear the matching state. The identical timeout return in the native Qubic reaper has the same problem.

Useful? React with 👍 / 👎.

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

4 issues found across 4 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

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


<file name="crates/theseus-mining/src/miner.rs">

<violation number="1" location="crates/theseus-mining/src/miner.rs:130">
P2: A miner whose wrapper exits first and whose worker runs past 30 seconds remains permanently `Running` after that worker later exits naturally, so subsequent `Start` commands are ignored. Keep a non-signaling watcher alive after timeout (in both generic and Qubic reapers) so state reaches `Idle` when the group disappears.</violation>

<violation number="2" location="crates/theseus-mining/src/miner.rs:237">
P2: A truncated ELF retaining only the first 18–51/63 bytes is accepted as usable because this check reads `e_type` without requiring a complete class-specific ELF header. Require at least 52 bytes for ELF32 or 64 for ELF64 so partial downloads do not win detection and then fail at spawn.</violation>

<violation number="3" location="crates/theseus-mining/src/miner.rs:293">
P3: When a relative binary path is supplied (e.g. `QUBIC_MINER_CMD=dist/qli-Client`) and `canonicalize` fails, `resolve_executable_path` falls back to returning the original relative path. The qli spawn path then runs `Command::new("dist/qli-Client")` after `current_dir("dist")`, so the child resolves it as `dist/dist/qli-Client` — the exact double-resolution failure this PR is meant to fix. The fallback should produce an absolute path (prepend the current working directory) so that returning a non-canonical path cannot be re-resolved against the new cwd.</violation>
</file>

<file name="crates/theseus-mining/src/qubic_miner.rs">

<violation number="1" location="crates/theseus-mining/src/qubic_miner.rs:830">
P2: A native miner whose leader exits while its process group survives the first 30 seconds remains `Running` forever after the workers later exit, so subsequent `Start` commands are ignored and `Stop` retains a stale PGID. Keep the reaper monitoring until the group disappears rather than returning after the first timeout.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Fix all with cubic | Re-trigger cubic

Comment on lines +237 to +241
if bytes.len() >= 18 && bytes[0..4] == [0x7f, b'E', b'L', b'F'] {
let class = bytes[4]; // 1 = ELFCLASS32, 2 = ELFCLASS64
if class != 1 && class != 2 {
return false;
}

@cubic-dev-ai cubic-dev-ai Bot Aug 1, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2: A truncated ELF retaining only the first 18–51/63 bytes is accepted as usable because this check reads e_type without requiring a complete class-specific ELF header. Require at least 52 bytes for ELF32 or 64 for ELF64 so partial downloads do not win detection and then fail at spawn.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At crates/theseus-mining/src/miner.rs, line 237:

<comment>A truncated ELF retaining only the first 18–51/63 bytes is accepted as usable because this check reads `e_type` without requiring a complete class-specific ELF header. Require at least 52 bytes for ELF32 or 64 for ELF64 so partial downloads do not win detection and then fail at spawn.</comment>

<file context>
@@ -207,9 +232,22 @@ fn looks_like_executable_header(bytes: &[u8]) -> bool {
-        return true;
+    // ELF: magic + class + e_type (ET_EXEC / ET_DYN). Rejects truncated
+    // downloads that only retain the 4-byte magic prefix.
+    if bytes.len() >= 18 && bytes[0..4] == [0x7f, b'E', b'L', b'F'] {
+        let class = bytes[4]; // 1 = ELFCLASS32, 2 = ELFCLASS64
+        if class != 1 && class != 2 {
</file context>
Suggested change
if bytes.len() >= 18 && bytes[0..4] == [0x7f, b'E', b'L', b'F'] {
let class = bytes[4]; // 1 = ELFCLASS32, 2 = ELFCLASS64
if class != 1 && class != 2 {
return false;
}
if bytes.len() >= 18 && bytes[0..4] == [0x7f, b'E', b'L', b'F'] {
let class = bytes[4]; // 1 = ELFCLASS32, 2 = ELFCLASS64
let min_header_len = match class {
1 => 52,
2 => 64,
_ => return false,
};
if bytes.len() < min_header_len {
return false;
}
Fix with cubic

// (setsid). Stay Running until the whole group is gone so Start cannot
// race a second miner and Stop can still kill orphans via the leader PGID.
// Do not SIGKILL here — that is reserved for explicit Stop.
let group_gone = wait_process_group_exit(reaped_pid);

@cubic-dev-ai cubic-dev-ai Bot Aug 1, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2: A miner whose wrapper exits first and whose worker runs past 30 seconds remains permanently Running after that worker later exits naturally, so subsequent Start commands are ignored. Keep a non-signaling watcher alive after timeout (in both generic and Qubic reapers) so state reaches Idle when the group disappears.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At crates/theseus-mining/src/miner.rs, line 130:

<comment>A miner whose wrapper exits first and whose worker runs past 30 seconds remains permanently `Running` after that worker later exits naturally, so subsequent `Start` commands are ignored. Keep a non-signaling watcher alive after timeout (in both generic and Qubic reapers) so state reaches `Idle` when the group disappears.</comment>

<file context>
@@ -109,7 +126,15 @@ pub fn reap_child(mut child: Child, state: Arc<Mutex<MinerState>>, log_prefix: &
     // race a second miner and Stop can still kill orphans via the leader PGID.
-    wait_process_group_exit(reaped_pid);
+    // Do not SIGKILL here — that is reserved for explicit Stop.
+    let group_gone = wait_process_group_exit(reaped_pid);
+    if !group_gone {
+        eprintln!(
</file context>
Fix with cubic

"[qubic] process group still alive after wait timeout \
(PID {reaped_pid}); leaving Running so Stop can kill orphans"
);
return;

@cubic-dev-ai cubic-dev-ai Bot Aug 1, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2: A native miner whose leader exits while its process group survives the first 30 seconds remains Running forever after the workers later exit, so subsequent Start commands are ignored and Stop retains a stale PGID. Keep the reaper monitoring until the group disappears rather than returning after the first timeout.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At crates/theseus-mining/src/qubic_miner.rs, line 830:

<comment>A native miner whose leader exits while its process group survives the first 30 seconds remains `Running` forever after the workers later exit, so subsequent `Start` commands are ignored and `Stop` retains a stale PGID. Keep the reaper monitoring until the group disappears rather than returning after the first timeout.</comment>

<file context>
@@ -801,7 +820,15 @@ fn reap_child(mut child: Child, state: Arc<Mutex<QubicMinerState>>) {
+            "[qubic] process group still alive after wait timeout \
+             (PID {reaped_pid}); leaving Running so Stop can kill orphans"
+        );
+        return;
+    }
     let mut s = state.lock().unwrap();
</file context>
Suggested change
return;
while !miner::wait_process_group_exit(reaped_pid) {
eprintln!(
"[qubic] process group remains alive (PID {reaped_pid}); continuing to monitor"
);
}
Fix with cubic

pub fn resolve_executable_path(binary: &str) -> std::path::PathBuf {
let p = std::path::Path::new(binary);
if p.is_absolute() {
return std::fs::canonicalize(p).unwrap_or_else(|_| p.to_path_buf());

@cubic-dev-ai cubic-dev-ai Bot Aug 1, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P3: When a relative binary path is supplied (e.g. QUBIC_MINER_CMD=dist/qli-Client) and canonicalize fails, resolve_executable_path falls back to returning the original relative path. The qli spawn path then runs Command::new("dist/qli-Client") after current_dir("dist"), so the child resolves it as dist/dist/qli-Client — the exact double-resolution failure this PR is meant to fix. The fallback should produce an absolute path (prepend the current working directory) so that returning a non-canonical path cannot be re-resolved against the new cwd.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At crates/theseus-mining/src/miner.rs, line 293:

<comment>When a relative binary path is supplied (e.g. `QUBIC_MINER_CMD=dist/qli-Client`) and `canonicalize` fails, `resolve_executable_path` falls back to returning the original relative path. The qli spawn path then runs `Command::new("dist/qli-Client")` after `current_dir("dist")`, so the child resolves it as `dist/dist/qli-Client` — the exact double-resolution failure this PR is meant to fix. The fallback should produce an absolute path (prepend the current working directory) so that returning a non-canonical path cannot be re-resolved against the new cwd.</comment>

<file context>
@@ -234,18 +272,45 @@ pub fn detect_binary_paths(
+pub fn resolve_executable_path(binary: &str) -> std::path::PathBuf {
+    let p = std::path::Path::new(binary);
+    if p.is_absolute() {
+        return std::fs::canonicalize(p).unwrap_or_else(|_| p.to_path_buf());
+    }
+    if let Some(parent) = p.parent()
</file context>
Suggested change
return std::fs::canonicalize(p).unwrap_or_else(|_| p.to_path_buf());
let abs = std::env::current_dir().unwrap_or_default().join(p);
return std::fs::canonicalize(&abs).unwrap_or(abs);
Fix with cubic

@rmems
rmems merged commit 250d188 into main Aug 1, 2026
8 checks passed
@rmems
rmems deleted the ci/github-actions branch August 1, 2026 23:27
@linear-code

linear-code Bot commented Aug 1, 2026

Copy link
Copy Markdown

RM-218

@gitar-bot

gitar-bot Bot commented Aug 1, 2026

Copy link
Copy Markdown

Important

You are using the Gitar free plan. Upgrade to unlock code review, CI analysis, auto-apply, custom automations, and more.

Gitar

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

Labels

area:ci GitHub Actions, runners, docker area:devcontainer Devcontainer and Dockerfile documentation Docs, README, CONTEXT enhancement New feature or request priority:P1 High — next up size:XXL This PR changes 1000+ lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants