Skip to content

feat(captcha): add automatic solver cascade (MAT-141)#182

Merged
mpiton merged 7 commits into
mainfrom
feat/mat-141-captcha-solvers
Jul 20, 2026
Merged

feat(captcha): add automatic solver cascade (MAT-141)#182
mpiton merged 7 commits into
mainfrom
feat/mat-141-captcha-solvers

Conversation

@mpiton

@mpiton mpiton commented Jul 20, 2026

Copy link
Copy Markdown
Owner

Summary

Adds the MAT-141 automatic CAPTCHA solver cascade: local OCR, AntiCaptcha, and an assisted browser window, with configurable ordering and a manual fallback.

Changes

  • add a configurable OCR → AntiCaptcha → browser cascade and persist every solver attempt and outcome in captcha_log
  • add a typed, bounded Tesseract broker with trusted system paths, fixed arguments, timeout/process-group cleanup, and no generic subprocess access
  • keep the AntiCaptcha API key exclusively in the OS keyring and redact secrets/solutions from persisted state and debug output
  • add the dedicated Tauri CAPTCHA browser window, solver controls/status in the CAPTCHA settings, and EN/FR copy
  • publish and register vortex-mod-captcha-ocr, vortex-mod-captcha-anticaptcha, and vortex-mod-captcha-browser v1.0.0 using release SHA256SUMS
  • add plugin CI ABI smoke coverage for the three solver contracts

Security notes

  • Tesseract execution is restricted to trusted absolute paths and an exact official-plugin provenance grant.
  • Plugin input/output, image data, subprocess output, API keys, and persisted solver metadata are bounded or redacted.
  • AntiCaptcha credentials are never written to TOML or SQLite.

Verification

  • cargo fmt --check
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo test --workspace — 1,783 unit tests and 4 integration tests passed; 5 environment/format-dependent tests ignored
  • npm run lint
  • npm run typecheck
  • npm test — 741 tests passed
  • npm run build
  • full pre-commit and pre-push gates, including cargo-deny and knip
  • all three plugin main/tag workflows green; downloaded release bundles pass sha256sum --check SHA256SUMS

Plugin releases

Related Issues

Linear: MAT-141

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • CI/CD or tooling changes

Checklist

  • My code follows the project's style guidelines
  • I have performed a self-review of my code
  • cargo fmt and oxlint pass
  • cargo clippy -- -D warnings is clean
  • Tests pass (cargo test + npm test)
  • I have added tests that prove my fix/feature works
  • I have updated CHANGELOG.md under [Unreleased]

Screenshots (if applicable)

Not included: the feature is covered by component tests and the generated Tauri capability schema.


Summary by cubic

Adds the MAT-141 automatic CAPTCHA solver cascade (OCR → AntiCaptcha → assisted browser) with a manual fallback, capability‑scoped windows, and per‑solver attempt history to reduce interruptions while keeping subprocess access locked down.

  • New Features

    • Configurable OCR → vortex-mod-captcha-anticaptchavortex-mod-captcha-browser cascade via captcha_solver_order; per‑solver attempts (outcome, timing) persisted to captcha_log and shown in the CAPTCHA view.
    • Typed Tesseract host broker for vortex-mod-captcha-ocr: trusted absolute paths, fixed args, strict caps/limits; capability only for the verified OCR plugin.
    • Dedicated assisted browser window with the minimal captcha-browser capability and per‑window command ACL; Tauri permissions split into main-window-commands and captcha-browser-commands.
    • AntiCaptcha API key stored only in the OS keyring with set/delete/status commands in Settings.
    • CI/registry: ABI checks for required exports (including get_balance for vortex-mod-captcha-anticaptcha), plugins registered with release SHA256SUMS, and a Windows Tesseract regression that must run exactly once.
  • Bug Fixes

    • Fixed Windows Tesseract broker fixture to exit successfully after emitting its simulated OCR solution; CI now enforces it runs once.
    • Assisted CAPTCHA windows close directly from terminal command flows.
    • Further tightened solver boundaries with capped IPC/WASM payloads and cleared inherited Tesseract paths.

Written for commit 39d0e24. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features
    • Added an automatic CAPTCHA solver cascade with configurable OCR → AntiCaptcha → browser ordering.
    • Added per-solver attempt tracking and display in CAPTCHA details.
    • Added AntiCaptcha API key status, save/delete, and persisted configuration.
    • Added a dedicated human-assisted CAPTCHA browser window flow and solver ordering UI.
    • Added new official CAPTCHA solver plugins to the registry.
  • Bug Fixes
    • Hardened CAPTCHA solving with bounded IO/payloads and safer solver cascade cancellation while preserving full solver audit.
    • Improved CAPTCHA browser window closing and tightened plugin capability/export validation.
  • Documentation
    • Updated unreleased changelog and updated CAPTCHA UI translations for cascade, outcomes, solver attempts, and AntiCaptcha key management.

@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@github-actions github-actions Bot added documentation Improvements or additions to documentation ci rust frontend ui labels Jul 20, 2026
@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds OCR, AntiCaptcha, and browser CAPTCHA plugins with configurable cascading, Tesseract brokering, persisted solver attempts, credential management, and a human-assisted Tauri WebView flow. It updates domain models, SQLite storage, IPC, frontend settings, CAPTCHA views, plugin metadata, and WASM export validation.

Changes

CAPTCHA solver pipeline

Layer / File(s) Summary
Domain contracts and configuration
src-tauri/src/domain/*, src/types/*
Adds validated solutions, solver outcomes and attempt records, configurable solver ordering, interaction contracts, and frontend DTO types.
Plugin OCR protocol and broker
src-tauri/src/adapters/driven/plugin/*
Adds plugin CAPTCHA solving, strict Extism payload parsing, typed Tesseract host access, approved binary discovery, bounded process execution, and timeout handling.
Automated cascade and persistence
src-tauri/src/application/commands/*, src-tauri/src/adapters/driven/sqlite/*
Runs configured solvers asynchronously, records outcomes and durations, supports interaction-required results, and persists attempts in SQLite.
Credential and browser integration
src-tauri/src/adapters/driven/captcha_interaction.rs, src-tauri/src/adapters/driving/tauri_ipc.rs, src-tauri/src/lib.rs, src-tauri/permissions/*
Adds AntiCaptcha credential commands, solver-order IPC fields, Tauri browser-window interaction, capability scopes, and application wiring for plugin solvers.
Frontend settings and CAPTCHA views
src/views/*, src/App.tsx, src/i18n/locales/*, src/types/*
Adds solver ordering controls, credential management, solver-attempt rendering, browser-window rendering, localized status text, and related tests.
Plugin registry and CI validation
registry/registry.toml, .github/workflows/*, CHANGELOG.md
Registers CAPTCHA plugins, validates required WASM exports, runs targeted Windows broker tests, and documents solver capabilities.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant CaptchaCommandHandler
  participant PluginCaptchaSolver
  participant ExtismPluginLoader
  participant TesseractBroker
  participant CaptchaRepository
  User->>CaptchaCommandHandler: enqueue CAPTCHA
  CaptchaCommandHandler->>PluginCaptchaSolver: run configured solver
  PluginCaptchaSolver->>ExtismPluginLoader: solve_captcha
  ExtismPluginLoader->>TesseractBroker: invoke typed OCR capability
  TesseractBroker-->>ExtismPluginLoader: solver outcome
  ExtismPluginLoader-->>PluginCaptchaSolver: CAPTCHA result
  PluginCaptchaSolver-->>CaptchaCommandHandler: solver outcome
  CaptchaCommandHandler->>CaptchaRepository: persist attempt and state
Loading

Possibly related PRs

  • mpiton/vortex#168: Modifies the shared plugin capability-gating and host-function registration path extended here for Tesseract.
  • mpiton/vortex#181: Modifies the CAPTCHA domain, handler, and read-model paths extended here with solver cascades and attempt tracking.

Suggested labels: configuration

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.51% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adding an automatic CAPTCHA solver cascade.

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

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

Actionable comments posted: 3

🧹 Nitpick comments (3)
src-tauri/src/domain/model/captcha.rs (1)

366-379: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

No upper bound on the number of recorded solver attempts.

Every other invariant in this file caps size (MAX_CAPTCHA_ID_BYTES, MAX_CAPTCHA_URL_BYTES, MAX_CAPTCHA_IMAGE_BYTES, MAX_CAPTCHA_SOLUTION_BYTES, and here MAX_CAPTCHA_SOLVER_NAME_BYTES), but record_solver_attempt only bounds the solver name — not the count of attempts pushed into solver_attempts. Since retry() (Line 356) lets a pending challenge be retried indefinitely while extending its deadline, and each retry presumably triggers another solver cascade, solver_attempts can grow unbounded for a long-lived pending challenge. This vector is persisted as JSON in captcha_log.solver_attempts_json (see src-tauri/src/adapters/driven/sqlite/entities/captcha_log.rs), so unbounded growth here becomes unbounded row growth there.

Consider capping the vector (e.g., drop-oldest or reject once a MAX_CAPTCHA_SOLVER_ATTEMPTS threshold is hit) consistent with the other bounded invariants in this file.

♻️ Possible approach
+const MAX_CAPTCHA_SOLVER_ATTEMPTS: usize = 32;
+
     pub fn record_solver_attempt(
         &mut self,
         attempt: CaptchaSolverAttempt,
     ) -> Result<(), DomainError> {
         self.ensure_pending()?;
         if attempt.solver().trim().is_empty()
             || attempt.solver().len() > MAX_CAPTCHA_SOLVER_NAME_BYTES
         {
             return Err(validation("CAPTCHA solver name is invalid"));
         }
+        if self.solver_attempts.len() >= MAX_CAPTCHA_SOLVER_ATTEMPTS {
+            return Err(validation("too many CAPTCHA solver attempts recorded"));
+        }
         self.solver_attempts.push(attempt);
         Ok(())
     }
🤖 Prompt for 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.

In `@src-tauri/src/domain/model/captcha.rs` around lines 366 - 379, Bound the
number of entries accepted by record_solver_attempt by introducing or reusing a
MAX_CAPTCHA_SOLVER_ATTEMPTS limit. When the limit is reached, reject the new
attempt or apply the established bounded-history policy, while preserving the
existing pending-state and solver-name validation behavior.
src-tauri/src/adapters/driven/plugin/tesseract_broker.rs (1)

24-35: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Redact Debug on request/response types carrying CAPTCHA image data and solutions.

PluginTesseractRequest.image_data and TesseractResponse.solution derive plain Debug, so any future {:?} logging (tracing, error context, panic message) would leak the raw base64 image or — more sensitively — the plaintext solved CAPTCHA answer. This is inconsistent with the redaction pattern already used for CaptchaSolution elsewhere in the plugin layer, and contradicts the PR's stated goal of redacting solutions and image data.

🔒 Suggested redacted Debug impls
-#[derive(Debug, serde::Deserialize)]
+#[derive(serde::Deserialize)]
 #[serde(deny_unknown_fields)]
 pub(crate) struct PluginTesseractRequest {
     image_data: String,
 }

-#[derive(Debug, serde::Serialize)]
+#[derive(serde::Serialize)]
 pub(crate) struct TesseractResponse {
     pub(crate) status: &'static str,
     #[serde(skip_serializing_if = "Option::is_none")]
     pub(crate) solution: Option<String>,
 }
+
+impl std::fmt::Debug for PluginTesseractRequest {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        f.debug_struct("PluginTesseractRequest")
+            .field("image_data", &"<redacted>")
+            .finish()
+    }
+}
+
+impl std::fmt::Debug for TesseractResponse {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        f.debug_struct("TesseractResponse")
+            .field("status", &self.status)
+            .field("solution", &self.solution.as_ref().map(|_| "<redacted>"))
+            .finish()
+    }
+}
🤖 Prompt for 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.

In `@src-tauri/src/adapters/driven/plugin/tesseract_broker.rs` around lines 24 -
35, Replace the derived Debug implementations on PluginTesseractRequest and
TesseractResponse with manual redacted Debug implementations. Ensure formatting
never includes PluginTesseractRequest.image_data or TesseractResponse.solution,
while preserving Debug support for the remaining non-sensitive fields and
matching the existing CaptchaSolution redaction pattern.
src-tauri/src/adapters/driven/plugin/provenance.rs (1)

135-138: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Share the OCR plugin-name constant here.
grants_for hardcodes "vortex-mod-captcha-ocr" while tesseract_broker::supports_plugin already uses OCR_PLUGIN_NAME. Point both checks at the same constant so a rename can’t silently disable OCR.

🤖 Prompt for 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.

In `@src-tauri/src/adapters/driven/plugin/provenance.rs` around lines 135 - 138,
Update grants_for to replace the hardcoded "vortex-mod-captcha-ocr" comparison
with the existing OCR_PLUGIN_NAME constant used by
tesseract_broker::supports_plugin, ensuring both OCR checks share the same
plugin-name definition.
🤖 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 `@src-tauri/capabilities/default.json`:
- Line 5: Create a dedicated capability for the CAPTCHA browser window instead
of including "captcha-browser-*" in the default capability’s windows list.
Remove that window pattern from default.json, add a separate CAPTCHA capability
scoped to the window, and grant only the CAPTCHA-related commands it requires
rather than core, tray, notification, or dialog permissions.

In `@src-tauri/src/adapters/driven/config/toml_config_store.rs`:
- Line 168: Ensure the captcha_solver_order field in the relevant configuration
DTOs uses an explicit serde default via default_captcha_solver_order, so legacy
config.toml files missing the field retain the default solver cascade. Update or
add coverage around the legacy-file case referenced by the existing tests, while
preserving normalization for explicitly provided values.

In `@src/views/CaptchaSolverSettings.tsx`:
- Around line 149-164: Update the save action in the captcha settings component
to pass a trimmed API key to saveCredential.mutate, matching the existing
validation used by the Save button while leaving the input value unchanged for
editing.

---

Nitpick comments:
In `@src-tauri/src/adapters/driven/plugin/provenance.rs`:
- Around line 135-138: Update grants_for to replace the hardcoded
"vortex-mod-captcha-ocr" comparison with the existing OCR_PLUGIN_NAME constant
used by tesseract_broker::supports_plugin, ensuring both OCR checks share the
same plugin-name definition.

In `@src-tauri/src/adapters/driven/plugin/tesseract_broker.rs`:
- Around line 24-35: Replace the derived Debug implementations on
PluginTesseractRequest and TesseractResponse with manual redacted Debug
implementations. Ensure formatting never includes
PluginTesseractRequest.image_data or TesseractResponse.solution, while
preserving Debug support for the remaining non-sensitive fields and matching the
existing CaptchaSolution redaction pattern.

In `@src-tauri/src/domain/model/captcha.rs`:
- Around line 366-379: Bound the number of entries accepted by
record_solver_attempt by introducing or reusing a MAX_CAPTCHA_SOLVER_ATTEMPTS
limit. When the limit is reached, reject the new attempt or apply the
established bounded-history policy, while preserving the existing pending-state
and solver-name validation behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 52a08574-c9b9-400e-bd8e-a8115a18e100

📥 Commits

Reviewing files that changed from the base of the PR and between 4a2d6fe and 6333fe0.

⛔ Files ignored due to path filters (1)
  • src-tauri/gen/schemas/capabilities.json is excluded by !**/gen/**
📒 Files selected for processing (54)
  • .github/workflows/plugin-ci.yml
  • CHANGELOG.md
  • registry/registry.toml
  • src-tauri/capabilities/default.json
  • src-tauri/src/adapters/driven/captcha_interaction.rs
  • src-tauri/src/adapters/driven/config/toml_config_store.rs
  • src-tauri/src/adapters/driven/mod.rs
  • src-tauri/src/adapters/driven/plugin/capabilities.rs
  • src-tauri/src/adapters/driven/plugin/captcha_solver.rs
  • src-tauri/src/adapters/driven/plugin/captcha_solver_tests.rs
  • src-tauri/src/adapters/driven/plugin/extism_loader.rs
  • src-tauri/src/adapters/driven/plugin/host_functions.rs
  • src-tauri/src/adapters/driven/plugin/mod.rs
  • src-tauri/src/adapters/driven/plugin/provenance.rs
  • src-tauri/src/adapters/driven/plugin/tesseract_broker.rs
  • src-tauri/src/adapters/driven/plugin/tesseract_broker_tests.rs
  • src-tauri/src/adapters/driven/plugin/ytdlp_broker.rs
  • src-tauri/src/adapters/driven/plugin/ytdlp_broker/platform.rs
  • src-tauri/src/adapters/driven/sqlite/captcha_repo.rs
  • src-tauri/src/adapters/driven/sqlite/captcha_repo_tests.rs
  • src-tauri/src/adapters/driven/sqlite/entities/captcha_log.rs
  • src-tauri/src/adapters/driven/sqlite/migrations/m20260720_000012_add_captcha_solver_attempts.rs
  • src-tauri/src/adapters/driven/sqlite/migrations/mod.rs
  • src-tauri/src/adapters/driving/tauri_ipc.rs
  • src-tauri/src/application/commands/captcha.rs
  • src-tauri/src/application/commands/captcha_credential.rs
  • src-tauri/src/application/commands/captcha_tests.rs
  • src-tauri/src/application/commands/mod.rs
  • src-tauri/src/application/commands/tests_support.rs
  • src-tauri/src/application/read_models/captcha_view.rs
  • src-tauri/src/domain/model/captcha.rs
  • src-tauri/src/domain/model/config.rs
  • src-tauri/src/domain/ports/driven/captcha_interaction.rs
  • src-tauri/src/domain/ports/driven/captcha_solver.rs
  • src-tauri/src/domain/ports/driven/mod.rs
  • src-tauri/src/domain/ports/driven/plugin_loader.rs
  • src-tauri/src/lib.rs
  • src/App.tsx
  • src/components/__tests__/ClipboardIndicator.test.tsx
  • src/hooks/__tests__/useAppEffects.test.ts
  • src/i18n/locales/en.json
  • src/i18n/locales/fr.json
  • src/layouts/__tests__/AppLayout.test.tsx
  • src/stores/__tests__/settingsStore.test.ts
  • src/types/captcha.ts
  • src/types/settings.ts
  • src/views/CaptchaBrowserWindow.tsx
  • src/views/CaptchaChallengePanel.tsx
  • src/views/CaptchaSolverSettings.tsx
  • src/views/LinkGrabberView/__tests__/LinkGrabberView.test.tsx
  • src/views/SettingsView/__tests__/Sections.test.tsx
  • src/views/SettingsView/__tests__/SettingsView.test.tsx
  • src/views/__tests__/CaptchaBrowserWindow.test.tsx
  • src/views/__tests__/CaptchaView.test.tsx

Comment thread src-tauri/capabilities/default.json Outdated
Comment thread src-tauri/src/adapters/driven/config/toml_config_store.rs
Comment thread src/views/CaptchaSolverSettings.tsx
@codspeed-hq

codspeed-hq Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will degrade performance by 18.75%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 1 improved benchmark
❌ 7 regressed benchmarks
✅ 18 untouched benchmarks

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
from_status_code_500 94.7 ns 154.7 ns -38.78%
apply_patch_single_field 3.1 µs 4.2 µs -26.15%
default_config 3.3 µs 4.5 µs -25.74%
apply_patch_many_fields 3.6 µs 4.7 µs -22.09%
create_valid 252.2 ns 310.6 ns -18.78%
from_status_code_404 153.1 ns 183.9 ns -16.77%
full_lifecycle 192.5 ns 221.7 ns -13.16%
reject_invalid 610.3 ns 493.6 ns +23.64%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing feat/mat-141-captcha-solvers (39d0e24) with main (4a2d6fe)

Open in CodSpeed

@cubic-dev-ai cubic-dev-ai 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.

cubic analysis

All reported issues were addressed across 55 files

Linked issue analysis

Linked issue: MAT-141: [Lot 4] Fournir les solvers CAPTCHA automatiques (OCR, service, navigateur)

Status Acceptance criteria Notes
R-01 — OCR solves simple image CAPTCHA when tesseract is installed; absence detected and signaled PR adds a typed Tesseract broker, detection logic and tests that report missing Tesseract; the UI/tests include user-facing detection messaging.
R-02 — Failure of a solver falls through to next configured solver and each attempt is logged in captcha_log with solver used PR records per-solver attempts, adds DB column and migration, updates repo/read-models and command logic to persist solver attempts; cascade/attempt recording is implemented in application code and exposed in views/tests.
R-03 — AntiCaptcha API key stored in OS keyring, never in SQLite or clear config PR adds commands to store/remove AntiCaptcha credential via credential store, includes tests/queries for credential status, and explicitly documents/redacts secrets; DB changes avoid storing solutions in cleartext.
R-04 — No generic subprocess access to plugins; only a typed host function for Tesseract is exposed PR introduces a dedicated run_tesseract host function, enforces provenance grants so only the verified OCR plugin receives that capability, and warns/ignores unproven declarations; no generic subprocess API is granted to plugins.
R-05 — Each plugin builds for wasm32-wasip1 + smoke ABI and is referenced in registry.toml with CI checksums PR adds registry entries with SHA256 checksums for the three plugins, updates plugin CI workflow to include the solvers, and includes release links + verification statements that checksums were validated.

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

Re-trigger cubic

Comment thread src-tauri/src/application/read_models/captcha_view.rs Outdated
Comment thread src-tauri/src/adapters/driven/sqlite/entities/captcha_log.rs
Comment thread src-tauri/src/domain/model/captcha.rs Outdated
Comment thread src-tauri/src/adapters/driving/tauri_ipc.rs
Comment thread src/views/CaptchaBrowserWindow.tsx
Comment thread src-tauri/src/adapters/driven/plugin/tesseract_broker_tests.rs
Comment thread src-tauri/src/domain/model/config.rs
Comment thread src-tauri/src/adapters/driven/plugin/ytdlp_broker/platform.rs
Comment thread src-tauri/src/application/commands/captcha_tests.rs Outdated
Comment thread src-tauri/src/application/commands/captcha_tests.rs
@mpiton

mpiton commented Jul 20, 2026

Copy link
Copy Markdown
Owner Author

Review feedback is addressed in 6e5b46a. The three non-inline CodeRabbit nitpicks are also covered: solver history is drop-oldest bounded at 64 entries, Tesseract request and response Debug output is redacted with regression coverage, and provenance shares OCR_PLUGIN_NAME. Local and pre-push verification passed clippy, cargo-deny, 1796 Rust unit tests plus 4 integration tests, 742 frontend tests, oxlint, formatting, typecheck, and the production frontend build.

@cubic-dev-ai cubic-dev-ai 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.

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

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

Re-trigger cubic

Comment thread src-tauri/permissions/app.toml
Comment thread src-tauri/src/domain/model/captcha.rs Outdated
Comment thread src-tauri/src/application/commands/captcha_tests.rs
Comment thread src-tauri/src/adapters/driven/plugin/tesseract_broker_tests.rs Outdated
Comment thread src-tauri/src/adapters/driven/plugin/registry.rs
Comment thread src-tauri/src/adapters/driven/plugin/tesseract_broker.rs Outdated
Comment thread src-tauri/capabilities/captcha-browser.json Outdated
Comment thread src-tauri/src/adapters/driven/plugin/tesseract_broker_tests.rs Outdated
Comment thread src-tauri/src/adapters/driven/plugin/ytdlp_broker/platform.rs Outdated

@cubic-dev-ai cubic-dev-ai 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.

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

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

Re-trigger cubic

Comment thread .github/workflows/ci.yml Outdated

@cubic-dev-ai cubic-dev-ai 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.

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

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

Re-trigger cubic

Comment thread src-tauri/src/adapters/driven/event/tauri_bridge.rs Outdated
coderabbitai[bot]
coderabbitai Bot previously requested changes Jul 20, 2026

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)
src-tauri/src/domain/model/captcha.rs (1)

367-376: 🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win

Bound persisted solver-attempt history. Line 376 only appends, so captcha_log grows indefinitely; the 64-entry limit is applied only when building the frontend DTO. This conflicts with the stated bounded, drop-oldest persistence contract.

  • src-tauri/src/domain/model/captcha.rs#L367-L376: evict the oldest attempt before appending once the retained-history cap is reached.
  • src-tauri/src/domain/model/captcha.rs#L681-L697: assert 64 retained attempts, beginning with solver-1 and ending with solver-64.
Proposed fix
-        self.solver_attempts.push(attempt);
+        if self.solver_attempts.len() >= MAX_EXPOSED_CAPTCHA_SOLVER_ATTEMPTS {
+            self.solver_attempts.remove(0);
+        }
+        self.solver_attempts.push(attempt);
🤖 Prompt for 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.

In `@src-tauri/src/domain/model/captcha.rs` around lines 367 - 376, Bound
persisted solver-attempt history in record_solver_attempt by evicting the oldest
entry before appending when the retention cap is reached, while preserving
validation behavior. In src-tauri/src/domain/model/captcha.rs lines 367-376,
update the append logic; in lines 681-697, extend the test to assert exactly 64
retained attempts, starting with solver-1 and ending with solver-64.
🤖 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 `@src-tauri/src/application/read_models/captcha_view.rs`:
- Around line 53-56: Bound solver-attempt history in
CaptchaChallenge::record_solver_attempt before persistence by dropping the
oldest entries once the collection exceeds MAX_EXPOSED_CAPTCHA_SOLVER_ATTEMPTS,
while preserving the newest attempts. Keep the exposed_solver_attempts
projection cap in the read model as defense in depth.

---

Outside diff comments:
In `@src-tauri/src/domain/model/captcha.rs`:
- Around line 367-376: Bound persisted solver-attempt history in
record_solver_attempt by evicting the oldest entry before appending when the
retention cap is reached, while preserving validation behavior. In
src-tauri/src/domain/model/captcha.rs lines 367-376, update the append logic; in
lines 681-697, extend the test to assert exactly 64 retained attempts, starting
with solver-1 and ending with solver-64.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: fd6d73fd-ab12-4738-a92a-ae2fb0f2cc6c

📥 Commits

Reviewing files that changed from the base of the PR and between 7528096 and 39d0e24.

⛔ Files ignored due to path filters (1)
  • src-tauri/gen/schemas/capabilities.json is excluded by !**/gen/**
📒 Files selected for processing (20)
  • .github/workflows/ci.yml
  • CHANGELOG.md
  • src-tauri/capabilities/captcha-browser.json
  • src-tauri/src/adapters/captcha_browser.rs
  • src-tauri/src/adapters/driven/captcha_interaction.rs
  • src-tauri/src/adapters/driven/plugin/extism_loader.rs
  • src-tauri/src/adapters/driven/plugin/registry.rs
  • src-tauri/src/adapters/driven/plugin/tesseract_broker.rs
  • src-tauri/src/adapters/driven/plugin/tesseract_broker_tests.rs
  • src-tauri/src/adapters/driven/plugin/ytdlp_broker/platform.rs
  • src-tauri/src/adapters/driven/plugin/ytdlp_broker/tests/platform.rs
  • src-tauri/src/adapters/driving/tauri_ipc.rs
  • src-tauri/src/adapters/mod.rs
  • src-tauri/src/application/commands/captcha.rs
  • src-tauri/src/application/commands/captcha_tests.rs
  • src-tauri/src/application/read_models/captcha_view.rs
  • src-tauri/src/domain/model/captcha.rs
  • src-tauri/src/domain/ports/driven/captcha_interaction.rs
  • src/views/CaptchaBrowserWindow.tsx
  • src/views/__tests__/CaptchaBrowserWindow.test.tsx
💤 Files with no reviewable changes (1)
  • src/views/CaptchaBrowserWindow.tsx
🚧 Files skipped from review as they are similar to previous changes (9)
  • src-tauri/src/domain/ports/driven/captcha_interaction.rs
  • src-tauri/src/adapters/driven/captcha_interaction.rs
  • .github/workflows/ci.yml
  • CHANGELOG.md
  • src-tauri/src/adapters/driven/plugin/registry.rs
  • src-tauri/src/adapters/driven/plugin/ytdlp_broker/platform.rs
  • src-tauri/src/adapters/driven/plugin/extism_loader.rs
  • src-tauri/src/application/commands/captcha.rs
  • src-tauri/src/application/commands/captcha_tests.rs

Comment thread src-tauri/src/application/read_models/captcha_view.rs
@mpiton

mpiton commented Jul 20, 2026

Copy link
Copy Markdown
Owner Author

Review disposition for the latest CodeRabbit request: intentionally not applying the proposed 64-entry persistence cap. MAT-141 R-02 requires every solver attempt to be logged in captcha_log, and Cubic previously identified persisted truncation as an auditability defect; commit 19dc9c9 corrected that defect. The storage/exposure boundary is deliberate: the domain and SQLite audit history remain complete, while CaptchaViewDto exposes only the newest 64 attempts to bound IPC/UI payloads. Each field and each individual attempt is already size-bounded, and one automatic cascade is finite. A separate archival/retention policy could be designed later, but silently evicting audit records here would violate the accepted requirement.

@mpiton
mpiton dismissed coderabbitai[bot]’s stale review July 20, 2026 11:56

Dismissed after documented verification: the requested persistence cap conflicts with MAT-141 R-02 audit logging and reverses the prior auditability fix. The IPC/UI projection remains bounded to 64.

@mpiton
mpiton merged commit e4f01c9 into main Jul 20, 2026
17 of 18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci configuration documentation Improvements or additions to documentation frontend rust ui

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant