Skip to content

fix(sonar): resolve monthly code quality findings#475

Merged
yacosta738 merged 15 commits into
mainfrom
feature/dallay-251-recurring-monthly-code-quality-review-sonarqube
Apr 10, 2026
Merged

fix(sonar): resolve monthly code quality findings#475
yacosta738 merged 15 commits into
mainfrom
feature/dallay-251-recurring-monthly-code-quality-review-sonarqube

Conversation

@yacosta738
Copy link
Copy Markdown
Contributor

Related Issues


Summary

  • resolve the current SonarQube findings across web, runtime, Kotlin, workflow, script, and hook surfaces so the monthly code quality review closes with actual debt reduction
  • harden release workflows by moving write permissions to job scope, replacing inherited secrets with explicit mappings, and tightening the release contract checks around executable resolution and sorting stability
  • reduce maintainability debt in Rust, Kotlin, Vue, and TypeScript, including accessibility semantics in dashboard/chat, cognitive complexity reductions, and follow-up fixes required by repository hooks (clippy, flaky lock assertion, and biome formatting)

Tested Information

  • pnpm --dir clients/web --filter @corvus/chat test -- src/composables/useChat.spec.ts
  • pnpm --dir clients/web --filter @corvus/dashboard test -- src/App.spec.ts src/components/config/UpdateSettings.spec.ts src/components/memory/MemoryList.spec.ts src/components/sessions/SessionList.spec.ts src/components/sessions/SessionDetail.spec.ts src/composables/useAdmin.spec.ts
  • node --test scripts/release-contract.test.mjs
  • sh -n gradle/configs/git/hooks/pre-push.sh
  • cargo test --manifest-path clients/agent-runtime/Cargo.toml refresh_fails_fast_when_index_db_is_locked
  • pre-push hook validation passed, including Rust tests, Kotlin compile check, and web checks
  • actionlint when available

Reviewer focus:

  • release workflow permission and secret hardening
  • runtime helper extractions and low-risk complexity reductions
  • dashboard/chat accessibility semantic updates

Documentation Impact

  • Docs updated in:
  • No docs update required because: this PR improves code quality, validation stability, workflow hardening, and semantic markup without changing user-facing setup, APIs, or operating procedures.
  • I verified the documentation matches the current behavior.

Breaking Changes

  • None.

Checklist

  • I have checked that there isn’t already a PR solving the same problem.
  • I have read the Contributing Guidelines.
  • I ensured my code follows the project's style guidelines.
  • I have added or updated tests that prove my fix is effective or that my feature works.
  • I have updated the documentation, or I explained above why no documentation update is needed.
  • I verified the documentation matches the current behavior.
  • I have documented any breaking changes in the Breaking Changes section.
  • I have linked the related issue (if any).

@linear
Copy link
Copy Markdown

linear Bot commented Apr 10, 2026

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 10, 2026

Note

Reviews paused

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

Use the following commands to manage reviews:

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

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This pull request performs systematic refactoring across four main areas: GitHub Actions workflows (moving from secrets: inherit to explicit secret mappings and job-level permissions), agent runtime code (extracting helper functions for tool execution, capability validation, and config loading), mobile/Compose UI (introducing new aggregated data types and composition patterns), and web dashboard (updating accessibility semantics and refactoring request/auth handling).

Changes

Cohort / File(s) Summary
GitHub Actions Workflows
.github/workflows/publish-release.yml, publish-snapshot.yml, release-please.yml
Moved top-level permissions to job-level, replaced secrets: inherit with explicit secret mappings for signing, Maven Central, Cargo, NPM, and Docker credentials. Improves secret isolation and auditability.
Agent Runtime Tool Execution
clients/agent-runtime/src/agent/agent.rs
Refactored execute_tool_call with early-return for unknown tools; extracted handle_tool_result(...) (audit logging, MCP warnings, output construction) and finalize_tool_execution(...) (observer event recording). Consolidates side-effect handling but introduces multiple helper invocations.
Agent Runtime Capability Validation
clients/agent-runtime/src/capabilities/registry.rs
Extracted validate_descriptor validation logic into five helpers (validate_required_fields, validate_metadata_shape, validate_m2_contract, validate_namespace, validate_mcp_metadata); added whitespace-only checks for compatibility entries and MCP metadata fields. Increased test coverage for edge cases.
Agent Runtime Channel & Config Refactoring
clients/agent-runtime/src/channels/cli.rs, channels/mod.rs, config/schema.rs, gateway/admin.rs, gateway/mod.rs, main.rs
Extracted repetitive inline logic into helpers: audio command gating, audio/image preprocessing, config directory resolution, admin view composition, webhook secret resolution, CLI command dispatch. Control-flow and behavior unchanged; improves maintainability.
Agent Runtime Security & Search
clients/agent-runtime/src/security/detect.rs, security/policy.rs, search/discovery.rs, search/tests.rs, tools/shell.rs
Extracted sandbox fallback handling, risk classification, walk-builder configuration, and tool-error construction into helpers; added fork-bomb snippet detection and broadened DB-lock error acceptance in tests.
Mobile/Compose UI Type & Composition Changes
clients/composeApp/src/commonMain/kotlin/.../ChatWorkspace.kt, OnboardingScreen.kt
Breaking changes: Introduced ChatWorkspaceContent (aggregates bridge/session/label data) and BridgeActions (aggregates callbacks); refactored ChatWorkspace signature to accept content + bridgeActions instead of individual parameters. Similarly introduced OnboardingScreenState + OnboardingScreenActions for OnboardingScreen. Improves composable API stability.
Mobile/Compose UI Supporting Changes
clients/composeApp/src/commonMain/kotlin/.../App.kt, MobileRuntimeCoordinator.kt, ChatComponents.kt, ChatBridgeCopy.kt, IosRuntimeBridge.kt
Updated call sites for new ChatWorkspace/OnboardingScreen signatures; extracted message ID helpers and palette styling; added new ChatBridgeCopy.kt with bridge UI text mapping; changed IosRuntimeCompanionClientProvider from interface to fun interface.
Web Dashboard App Navigation
clients/web/apps/dashboard/src/App.vue
Added tabpanel semantics with roving focus (ArrowLeft/Right, Home/End navigation); refactored live regions from <output> to <p> with aria-live; moved webhook card into Config panel. Significant accessibility overhaul. ⚠️ Verify role removal doesn't regress screen-reader behavior.
Web Dashboard Config Components
clients/web/apps/dashboard/src/components/config/*.vue
Removed explicit role="status"/role="alert" from loading/error messages, relying on aria-live values instead. Standardized pattern across ChannelsOverview, CostOverview, HealthDashboard, HeartbeatOverview, McpOverview, ReliabilityOverview, SchedulerStatus, TunnelOverview. ⚠️ Confirm accessibility regression testing.
Web Dashboard Memory & Session Components
clients/web/apps/dashboard/src/components/memory/*.vue, sessions/*.vue
Similar role-attribute removal updates; MemoryList adds destructive action styling (color #ef4444#b42318); MemoryList adds aria-atomic="true" to live regions.
Web Dashboard Config/Settings Refactoring
clients/web/apps/dashboard/src/components/config/CostOverview.vue, UpdateSettings.vue, WebSearchSettings.vue
Extracted governance-reload helper with rejection suppression; added localized toggle formatting; converted validation array to Set. Minor improvements.
Web Dashboard Composables & Types
clients/web/apps/dashboard/src/composables/useAdmin.ts, useChat.ts, useChat.spec.ts, src/types/admin-sessions.ts
Major refactoring in useChat.ts: Introduced PreparedChatRequest, request initialization (beginRequest), credential/approval auth handlers, stream normalization (normalizeStreamChunk, processStreamBuffer). Added approval-payload parsing for 403/401 responses and SSE error frames. Comprehensive test coverage for auth flows. Review stream parsing carefully.
Release & Validation Tooling
gradle/configs/git/hooks/pre-push.sh, scripts/release-contract.test.mjs
Enhanced pre-push hook with intentional case-handling and improved shell parameter safety (IFS/set -f). Added release-contract validation: sortStrings helper, Set-based membership checks, executable resolution from trusted dirs, stricter workflow-content assertions (explicit permissions, forbidden secrets: inherit).

Sequence Diagram(s)

None applicable. The changes are primarily refactoring (extraction of existing logic into helpers), accessibility updates, and composition pattern adjustments—not introducing new feature flows or significant control-flow changes across 3+ distinct components.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

The PR spans four distinct domains with moderate-to-high complexity per domain. The workflow changes are straightforward, but agent-runtime refactoring involves careful logic consolidation across 7+ files; mobile UI introduces breaking type changes; and web dashboard combines accessibility semantics shifts (with regression risk) and substantial auth/stream-parsing logic in useChat.ts. Heterogeneous changes across files require separate reasoning for accessibility impact, type-system compatibility, and behavioral correctness of consolidated helpers and request handlers.

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 22.01% 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
Title check ✅ Passed The title 'fix(sonar): resolve monthly code quality findings' follows Conventional Commit style with proper imperative language, is 49 characters (well under 72), and accurately reflects the main purpose of resolving SonarQube findings.
Description check ✅ Passed The PR description covers all major template sections: Related Issues, Summary, Tested Information, Documentation Impact, Breaking Changes, and Checklist. It provides specific context, testing steps, and reviewer focus areas.
Linked Issues check ✅ Passed The PR addresses the core objective of #432 (Monthly Code Quality Review) by resolving SonarQube findings across Rust, Kotlin, Vue, TypeScript, and workflow configurations, improving code quality and reducing technical debt.
Out of Scope Changes check ✅ Passed All changes align with the stated objectives: workflow hardening (permissions/secrets), code quality improvements (refactoring, complexity reduction), and accessibility semantics. No unrelated or extraneous modifications were introduced.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/dallay-251-recurring-monthly-code-quality-review-sonarqube

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

❤️ Share

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

Comment thread clients/web/apps/chat/src/composables/useChat.ts Fixed
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 10, 2026

✅ Contributor Report

User: @yacosta738
Status: Passed (12/13 metrics passed)

Metric Description Value Threshold Status
PR Merge Rate PRs merged vs closed 90% >= 30%
Repo Quality Repos with ≥100 stars 0 >= 0
Positive Reactions Positive reactions received 10 >= 1
Negative Reactions Negative reactions received 0 <= 5
Account Age GitHub account age 3087 days >= 30 days
Activity Consistency Regular activity over time 108% >= 0%
Issue Engagement Issues with community engagement 0 >= 0
Code Reviews Code reviews given to others 540 >= 0
Merger Diversity Unique maintainers who merged PRs 2 >= 0
Repo History Merge Rate Merge rate in this repo 91% >= 0%
Repo History Min PRs Previous PRs in this repo 223 >= 0
Profile Completeness Profile richness (bio, followers) 90 >= 0
Suspicious Patterns Spam-like activity detection 1 N/A

Contributor Report evaluates based on public GitHub activity. Analysis period: 2025-04-10 to 2026-04-10

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 12

Caution

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

⚠️ Outside diff range comments (4)
clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatComponents.kt (2)

201-207: ⚠️ Potential issue | 🟠 Major

Trim ChatBubbleBody to 5 parameters—currently at 6, exceeding detekt limit.

The function passes 6 parameters when only 5 are allowed. Consolidate contentColor and corvusColors into the ChatBubblePalette or use a props model to bring it back under the detekt threshold.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatComponents.kt`
around lines 201 - 207, ChatBubbleBody currently takes six parameters and
exceeds the detekt limit; collapse contentColor and corvusColors into the
existing ChatBubblePalette (or create a single ChatBubbleProps data class) so
the function signature becomes five parameters. Update the ChatBubblePalette (or
new ChatBubbleProps) to include a Color contentColor and a CorvusColorPalette
corvusColors field, then change all callers of ChatBubbleBody to pass the
updated ChatBubblePalette (or the single props object) instead of separate
contentColor and corvusColors.

482-506: 🧹 Nitpick | 🔵 Trivial

Extract the label formatters to a dedicated utility file.

The onboardingStateLabel() and bridgeStateHeadline() functions are pure string mappers used across multiple files (ConfigPanel, tests). Moving these—along with bridgeStateDescription() and bridgeStateRecovery()—to a dedicated formatter file/object will reduce ChatComponents.kt's function count (currently 13) without touching rendering logic. These functions have no side effects and are straightforward to relocate.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatComponents.kt`
around lines 482 - 506, Move the pure string-mapping formatters into a new
dedicated utility (e.g., an object or file) and update all call sites: extract
onboardingStateLabel(onboardingState: MobileOnboardingState) and
bridgeStateHeadline(bridgeState: MobileBridgeUiState) (and also
bridgeStateDescription() and bridgeStateRecovery() which you should locate) into
that new formatter module, keep their signatures and exact return strings,
remove them from ChatComponents.kt, and update imports/usages in ConfigPanel,
tests and any other files to reference the new formatter to avoid changing
rendering logic or behavior.
clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/onboarding/OnboardingScreen.kt (1)

162-259: ⚠️ Potential issue | 🟠 Major

Unblock detekt on OnboardingScreen.

The composable exceeds the 60-line limit (currently 99 lines) and violates FunctionNaming due to PascalCase. Either extract the function into top/body/footer sections or add the same @file:Suppress("FunctionNaming") suppression used in App.kt and ChatWorkspace.kt.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/onboarding/OnboardingScreen.kt`
around lines 162 - 259, The OnboardingScreen composable (OnboardingScreen)
currently violates detekt rules: it's over the 60-line limit and triggers
FunctionNaming (PascalCase). Fix by either extracting logical parts into smaller
composables (e.g., OnboardingTop/OnboardingBody/OnboardingFooter or
OnboardingSkip/OnboardingContent/OnboardingActions) and call them from
OnboardingScreen to reduce its length below 60 lines, or add the same file-level
suppression used in App.kt/ChatWorkspace.kt: `@file`:Suppress("FunctionNaming") at
the top of this file. Choose extraction for cleaner code; if temporary, add the
suppression to unblock detekt.
clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatWorkspace.kt (1)

195-268: ⚠️ Potential issue | 🟠 Major

Extract header, divider, and conditional panel logic into separate composables.

The ChatWorkspaceScreen function is ~72 lines, exceeding Detekt's LongMethod threshold of 60 lines. Move the header+divider section and the config-vs-chat conditional branch into dedicated composables to reduce the main function body below the threshold.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatWorkspace.kt`
around lines 195 - 268, ChatWorkspaceScreen is too long; extract the
header+divider block and the config-vs-chat conditional branch into two new
composables (e.g., ChatHeaderSection and ChatContentPanel). Move the ChatHeader
call and the Spacer + Box divider into ChatHeaderSection and keep the same
parameters used there (modelName, bridgeState, shouldShowConfig,
actions.onToggleConfig, and any modifiers); replace that code in
ChatWorkspaceScreen with a single call to ChatHeaderSection. Move the
conditional that creates ConfigPanel vs the remembered ChatPanelState +
ChatPanel into ChatContentPanel, ensuring you recreate the remember(...) call
inside ChatContentPanel (use the same keys: workspaceState, bridgeState,
pendingApproval) and forward messages, query, actions, resumableSessions,
activeSessionId, targetLabel, and modifier as needed; then call ChatContentPanel
from ChatWorkspaceScreen in place of the original conditional so the top-level
function falls under Detekt's LongMethod threshold.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@clients/agent-runtime/src/agent/agent.rs`:
- Around line 803-821: finalize_tool_execution currently hardcodes
DispatchAction::Execute in the returned ToolExecutionResult which loses the
original dispatch action (causing ObserverEvent loss in some error paths);
change finalize_tool_execution signature to accept an extra parameter (e.g.,
action: crate::agent::dispatcher::DispatchAction) and use that value for the
ToolExecutionResult.action field instead of DispatchAction::Execute, then update
callers such as execute_tool_call to pass the original dispatch action through
when invoking finalize_tool_execution so the finalizer preserves the true
action.

In `@clients/agent-runtime/src/capabilities/registry.rs`:
- Around line 116-183: Add unit tests that exercise the validation branches in
validate_metadata_shape, validate_m2_contract, validate_namespace, and
validate_mcp_metadata: create CapabilityDescriptor fixtures and assert they
return Err(CapabilityError::...) for (1) a descriptor whose
metadata.parameters_schema is not an object, (2) descriptors with non-Tool
family and non-Executable kind to trigger InvalidFamilyForM2/InvalidKindForM2 in
validate_m2_contract, (3) invalid namespace values for validate_namespace, (4) a
descriptor with namespace starting with "mcp." but missing metadata.mcp to
trigger missing_field("metadata.mcp"), (5) an mcp descriptor with blank
metadata.mcp.server to trigger missing_field("metadata.mcp.server"), and (6) an
"mcp.resource" descriptor missing or blank metadata.mcp.resource_uri to trigger
missing_field("metadata.mcp.resource_uri"); assert the errors contain the
expected id and variant names to lock behavior after refactor.
- Around line 98-111: The validation loop over
descriptor.compatibility.runtime_contracts and
descriptor.compatibility.entrypoint_parity_scope currently only checks for empty
vectors and allows entries that are whitespace-only (e.g., "   "); update the
check so each list must contain at least one non-whitespace entry by iterating
items and using item.trim().is_empty() (or equivalent) to detect whitespace-only
strings and treat the list as missing if all entries are blank, returning
CapabilityError::missing_field(field, id); ensure you reference the same symbols
(descriptor.compatibility.runtime_contracts,
descriptor.compatibility.entrypoint_parity_scope,
CapabilityError::missing_field) when applying the fix.

In `@clients/agent-runtime/src/config/schema.rs`:
- Around line 3824-3827: The code treats whitespace-only CORVUS_WORKSPACE values
as valid; change the match arm to trim the env value first and only treat it as
a custom workspace if trimmed value is non-empty—i.e., when matching
Ok(custom_workspace), call let ws = custom_workspace.trim(); if !ws.is_empty()
then call resolve_config_dir_for_workspace(&PathBuf::from(ws)) otherwise fall
through to the default branch; reference the CORVUS_WORKSPACE env var and the
resolve_config_dir_for_workspace function while making this change.

In `@clients/agent-runtime/src/security/policy.rs`:
- Around line 615-624: The normalize_risk_segments function currently strips
single '&' before high-risk checks, breaking exact-pattern detection (e.g.,
fork-bomb ":(){:|:&};:")—modify normalize_risk_segments so it only normalizes
multi-char operators ("&&", "||") and other separators but does NOT replace the
single '&' character (i.e., remove '&' from the second replacement list), or
alternatively perform contains_high_risk_snippet detection before replacing
single-char '&'; apply the same fix to the similar code at the other occurrence
referenced (lines around contains_high_risk_snippet).

In
`@clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/runtime/MobileRuntimeCoordinator.kt`:
- Around line 247-249: MobileRuntimeCoordinator now exceeds Detekt's
TooManyFunctions because assistantChatMessage was added as a class-level
function; remove the new class method and preserve behavior by inlining its body
at call sites or turning it into a private local function inside the method that
uses it. Replace calls to assistantChatMessage(text, offset) with ChatMessage(id
= nextMessageId(offset), role = ChatRole.Assistant, content = text) (or define a
local val/func inside the containing function that returns that ChatMessage) so
no additional class-level function is introduced while keeping the same
nextMessageId/ChatMessage/ChatRole.Assistant behavior.

In
`@clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatWorkspace.kt`:
- Around line 168-175: The remember call creating actions can capture a stale
onSendMessage via sendMessage because onSendMessage isn't included in the
dependency list; update the remember(...) dependencies for the actions variable
to include onSendMessage along with bridgeState and bridgeActions so
ChatWorkspaceActions (constructed with onSend = ::sendMessage) always uses the
current onSendMessage handler (identify the remember call that constructs
ChatWorkspaceActions, the sendMessage function, and the onSendMessage
parameter).

In `@clients/web/apps/chat/src/composables/useChat.ts`:
- Around line 382-391: In handleStreamAuthFailure, ensure HTTP 401 is handled
immediately by calling throwCredentialInvalid() before attempting to parse
approval errors: check response.status === 401 at the top of the function and
call throwCredentialInvalid(), then proceed to
readJsonPayload/parseApprovalErrorType and only treat approval types as fallback
(e.g., for 403 or other statuses); update any callers such as streamMessage to
rely on this ordering so 401 never falls through to approval handling.

In `@clients/web/apps/dashboard/src/App.vue`:
- Around line 188-216: The tab controls currently use toggle semantics
(aria-pressed) but should be real tabs: change the container div with class
"nav-tabs" to have role="tablist", and update each button (the elements binding
currentPage and using t(...)) to have role="tab" and use aria-selected bound to
(currentPage === '...') instead of aria-pressed; ensure each tab sets
tabindex="0" when selected and tabindex="-1" when not to maintain keyboard focus
order, keeping data-testid and class bindings intact so "nav-tab" and
"nav-tab-active" behavior is preserved.

In `@clients/web/apps/dashboard/src/components/memory/MemoryList.vue`:
- Line 310: MemoryList.vue uses two different hex values for destructive states
(text/confirm CTA set to `#b42318` while destructive border/hover still use
`#ef4444`); unify them by introducing and using a single local token (e.g.,
--color-destructive) inside the component's style and replace all instances of
`#ef4444` and `#b42318` in the confirm CTA, destructive border, and hover selectors
so they reference that token instead, ensuring consistent destructive color
across the confirm button, borders, and hover styles.

In `@gradle/configs/git/hooks/pre-push.sh`:
- Around line 85-89: The lychee invocation uses unquoted DOC_FILES allowing
word-splitting, glob expansion, and option injection; change the call to pass
the filenames safely by quoting the variable (use "$DOC_FILES") or, better,
build an array of changed docs and expand it as "$DOC_ARRAY[@]" before calling
lychee in the pre-push.sh hook (refer to the DOC_FILES variable and the lychee
--config invocation) so filenames with spaces, globs, or leading dashes are
handled correctly.

In `@scripts/release-contract.test.mjs`:
- Around line 217-220: The test currently skips when cargoExecutable is missing
which can hide CI contract breaks; update the block checking cargoExecutable so
that if it is missing and the run is in CI (process.env.CI or equivalent), the
test fails (use t.fail or throw) with a clear error message about missing cargo
rather than t.skip, and only allow t.skip for local/non-CI runs; update the
check around the cargoExecutable resolution in release-contract.test.mjs to
conditionally fail in CI and include a descriptive message so the contract
validation surfaces in CI.

---

Outside diff comments:
In
`@clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatComponents.kt`:
- Around line 201-207: ChatBubbleBody currently takes six parameters and exceeds
the detekt limit; collapse contentColor and corvusColors into the existing
ChatBubblePalette (or create a single ChatBubbleProps data class) so the
function signature becomes five parameters. Update the ChatBubblePalette (or new
ChatBubbleProps) to include a Color contentColor and a CorvusColorPalette
corvusColors field, then change all callers of ChatBubbleBody to pass the
updated ChatBubblePalette (or the single props object) instead of separate
contentColor and corvusColors.
- Around line 482-506: Move the pure string-mapping formatters into a new
dedicated utility (e.g., an object or file) and update all call sites: extract
onboardingStateLabel(onboardingState: MobileOnboardingState) and
bridgeStateHeadline(bridgeState: MobileBridgeUiState) (and also
bridgeStateDescription() and bridgeStateRecovery() which you should locate) into
that new formatter module, keep their signatures and exact return strings,
remove them from ChatComponents.kt, and update imports/usages in ConfigPanel,
tests and any other files to reference the new formatter to avoid changing
rendering logic or behavior.

In
`@clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatWorkspace.kt`:
- Around line 195-268: ChatWorkspaceScreen is too long; extract the
header+divider block and the config-vs-chat conditional branch into two new
composables (e.g., ChatHeaderSection and ChatContentPanel). Move the ChatHeader
call and the Spacer + Box divider into ChatHeaderSection and keep the same
parameters used there (modelName, bridgeState, shouldShowConfig,
actions.onToggleConfig, and any modifiers); replace that code in
ChatWorkspaceScreen with a single call to ChatHeaderSection. Move the
conditional that creates ConfigPanel vs the remembered ChatPanelState +
ChatPanel into ChatContentPanel, ensuring you recreate the remember(...) call
inside ChatContentPanel (use the same keys: workspaceState, bridgeState,
pendingApproval) and forward messages, query, actions, resumableSessions,
activeSessionId, targetLabel, and modifier as needed; then call ChatContentPanel
from ChatWorkspaceScreen in place of the original conditional so the top-level
function falls under Detekt's LongMethod threshold.

In
`@clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/onboarding/OnboardingScreen.kt`:
- Around line 162-259: The OnboardingScreen composable (OnboardingScreen)
currently violates detekt rules: it's over the 60-line limit and triggers
FunctionNaming (PascalCase). Fix by either extracting logical parts into smaller
composables (e.g., OnboardingTop/OnboardingBody/OnboardingFooter or
OnboardingSkip/OnboardingContent/OnboardingActions) and call them from
OnboardingScreen to reduce its length below 60 lines, or add the same file-level
suppression used in App.kt/ChatWorkspace.kt: `@file`:Suppress("FunctionNaming") at
the top of this file. Choose extraction for cleaner code; if temporary, add the
suppression to unblock detekt.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2f114cec-3a00-4347-9046-1113385a4e70

📥 Commits

Reviewing files that changed from the base of the PR and between db3c3db and 5e43913.

📒 Files selected for processing (46)
  • .github/workflows/publish-release.yml
  • .github/workflows/publish-snapshot.yml
  • .github/workflows/release-please.yml
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/capabilities/registry.rs
  • clients/agent-runtime/src/channels/cli.rs
  • clients/agent-runtime/src/channels/mod.rs
  • clients/agent-runtime/src/config/schema.rs
  • clients/agent-runtime/src/gateway/admin.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/search/discovery.rs
  • clients/agent-runtime/src/search/tests.rs
  • clients/agent-runtime/src/security/detect.rs
  • clients/agent-runtime/src/security/policy.rs
  • clients/agent-runtime/src/tools/shell.rs
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/App.kt
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/runtime/MobileRuntimeCoordinator.kt
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatComponents.kt
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatWorkspace.kt
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/onboarding/OnboardingScreen.kt
  • clients/composeApp/src/iosMain/kotlin/com/profiletailors/corvus/runtime/IosRuntimeBridge.kt
  • clients/web/apps/chat/src/App.vue
  • clients/web/apps/chat/src/composables/useChat.spec.ts
  • clients/web/apps/chat/src/composables/useChat.ts
  • clients/web/apps/dashboard/src/App.vue
  • clients/web/apps/dashboard/src/components/config/ChannelsOverview.vue
  • clients/web/apps/dashboard/src/components/config/CostOverview.vue
  • clients/web/apps/dashboard/src/components/config/HealthDashboard.vue
  • clients/web/apps/dashboard/src/components/config/HeartbeatOverview.vue
  • clients/web/apps/dashboard/src/components/config/McpOverview.vue
  • clients/web/apps/dashboard/src/components/config/ReliabilityOverview.vue
  • clients/web/apps/dashboard/src/components/config/SchedulerStatus.vue
  • clients/web/apps/dashboard/src/components/config/TunnelOverview.vue
  • clients/web/apps/dashboard/src/components/config/UpdateSettings.vue
  • clients/web/apps/dashboard/src/components/config/WebSearchSettings.vue
  • clients/web/apps/dashboard/src/components/memory/CerebroSearchPanel.vue
  • clients/web/apps/dashboard/src/components/memory/LocalMemoryExplorerPanel.vue
  • clients/web/apps/dashboard/src/components/memory/MemoryList.vue
  • clients/web/apps/dashboard/src/components/memory/MemoryStats.vue
  • clients/web/apps/dashboard/src/components/sessions/SessionDetail.vue
  • clients/web/apps/dashboard/src/components/sessions/SessionList.vue
  • clients/web/apps/dashboard/src/composables/useAdmin.ts
  • clients/web/apps/dashboard/src/types/admin-sessions.ts
  • gradle/configs/git/hooks/pre-push.sh
  • scripts/release-contract.test.mjs
💤 Files with no reviewable changes (1)
  • clients/web/apps/dashboard/src/components/memory/CerebroSearchPanel.vue
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: pr-checks
  • GitHub Check: sonar
  • GitHub Check: Cloudflare Pages
🧰 Additional context used
📓 Path-based instructions (11)
**/*.vue

⚙️ CodeRabbit configuration file

**/*.vue: Enforce Vue 3 Composition API with <script setup>.
Ensure accessibility (A11y) and proper use of Tailwind CSS classes.
Check for proper prop validation and emitted events documentation.

Files:

  • clients/web/apps/dashboard/src/components/config/ChannelsOverview.vue
  • clients/web/apps/dashboard/src/components/config/HealthDashboard.vue
  • clients/web/apps/dashboard/src/components/config/HeartbeatOverview.vue
  • clients/web/apps/dashboard/src/components/config/McpOverview.vue
  • clients/web/apps/dashboard/src/components/sessions/SessionDetail.vue
  • clients/web/apps/dashboard/src/components/config/SchedulerStatus.vue
  • clients/web/apps/dashboard/src/components/config/ReliabilityOverview.vue
  • clients/web/apps/dashboard/src/components/config/WebSearchSettings.vue
  • clients/web/apps/dashboard/src/components/sessions/SessionList.vue
  • clients/web/apps/dashboard/src/components/memory/LocalMemoryExplorerPanel.vue
  • clients/web/apps/dashboard/src/components/config/TunnelOverview.vue
  • clients/web/apps/chat/src/App.vue
  • clients/web/apps/dashboard/src/components/memory/MemoryStats.vue
  • clients/web/apps/dashboard/src/components/memory/MemoryList.vue
  • clients/web/apps/dashboard/src/components/config/UpdateSettings.vue
  • clients/web/apps/dashboard/src/components/config/CostOverview.vue
  • clients/web/apps/dashboard/src/App.vue
**/*

⚙️ CodeRabbit configuration file

**/*: Security first, performance second.
Validate input boundaries, auth/authz implications, and secret management.
Look for behavioral regressions, missing tests, and contract breaks across modules.

Files:

  • clients/web/apps/dashboard/src/components/config/ChannelsOverview.vue
  • clients/web/apps/dashboard/src/components/config/HealthDashboard.vue
  • clients/web/apps/dashboard/src/components/config/HeartbeatOverview.vue
  • clients/agent-runtime/src/search/tests.rs
  • clients/web/apps/dashboard/src/components/config/McpOverview.vue
  • clients/web/apps/dashboard/src/components/sessions/SessionDetail.vue
  • clients/web/apps/dashboard/src/components/config/SchedulerStatus.vue
  • clients/web/apps/dashboard/src/components/config/ReliabilityOverview.vue
  • clients/web/apps/dashboard/src/components/config/WebSearchSettings.vue
  • clients/web/apps/dashboard/src/components/sessions/SessionList.vue
  • clients/web/apps/dashboard/src/composables/useAdmin.ts
  • clients/web/apps/chat/src/composables/useChat.spec.ts
  • clients/web/apps/dashboard/src/components/memory/LocalMemoryExplorerPanel.vue
  • clients/web/apps/dashboard/src/types/admin-sessions.ts
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/runtime/MobileRuntimeCoordinator.kt
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatComponents.kt
  • clients/web/apps/dashboard/src/components/config/TunnelOverview.vue
  • clients/web/apps/chat/src/App.vue
  • clients/web/apps/dashboard/src/components/memory/MemoryStats.vue
  • clients/agent-runtime/src/search/discovery.rs
  • clients/web/apps/dashboard/src/components/memory/MemoryList.vue
  • gradle/configs/git/hooks/pre-push.sh
  • clients/web/apps/dashboard/src/components/config/UpdateSettings.vue
  • clients/agent-runtime/src/channels/cli.rs
  • clients/web/apps/dashboard/src/components/config/CostOverview.vue
  • clients/agent-runtime/src/security/detect.rs
  • clients/composeApp/src/iosMain/kotlin/com/profiletailors/corvus/runtime/IosRuntimeBridge.kt
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/App.kt
  • clients/agent-runtime/src/capabilities/registry.rs
  • clients/web/apps/dashboard/src/App.vue
  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/tools/shell.rs
  • scripts/release-contract.test.mjs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/security/policy.rs
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatWorkspace.kt
  • clients/agent-runtime/src/agent/agent.rs
  • clients/web/apps/chat/src/composables/useChat.ts
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/onboarding/OnboardingScreen.kt
  • clients/agent-runtime/src/channels/mod.rs
  • clients/agent-runtime/src/config/schema.rs
  • clients/agent-runtime/src/gateway/admin.rs
clients/agent-runtime/src/**/*.rs

📄 CodeRabbit inference engine (clients/agent-runtime/AGENTS.md)

clients/agent-runtime/src/**/*.rs: Never log secrets, tokens, raw credentials, or sensitive payloads in any logging statements
Avoid unnecessary allocations, clones, and blocking operations to maintain performance and efficiency

Files:

  • clients/agent-runtime/src/search/tests.rs
  • clients/agent-runtime/src/search/discovery.rs
  • clients/agent-runtime/src/channels/cli.rs
  • clients/agent-runtime/src/security/detect.rs
  • clients/agent-runtime/src/capabilities/registry.rs
  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/tools/shell.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/security/policy.rs
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/channels/mod.rs
  • clients/agent-runtime/src/config/schema.rs
  • clients/agent-runtime/src/gateway/admin.rs
clients/agent-runtime/**/*.rs

📄 CodeRabbit inference engine (clients/agent-runtime/AGENTS.md)

Run cargo fmt --all -- --check, cargo clippy --all-targets -- -D warnings, and cargo test for code validation, or document which checks were skipped and why

Files:

  • clients/agent-runtime/src/search/tests.rs
  • clients/agent-runtime/src/search/discovery.rs
  • clients/agent-runtime/src/channels/cli.rs
  • clients/agent-runtime/src/security/detect.rs
  • clients/agent-runtime/src/capabilities/registry.rs
  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/tools/shell.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/security/policy.rs
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/channels/mod.rs
  • clients/agent-runtime/src/config/schema.rs
  • clients/agent-runtime/src/gateway/admin.rs
**/*.rs

⚙️ CodeRabbit configuration file

**/*.rs: Focus on Rust idioms, memory safety, and ownership/borrowing correctness.
Flag unnecessary clones, unchecked panics in production paths, and weak error context.
Prioritize unsafe blocks, FFI boundaries, concurrency races, and secret handling.

Files:

  • clients/agent-runtime/src/search/tests.rs
  • clients/agent-runtime/src/search/discovery.rs
  • clients/agent-runtime/src/channels/cli.rs
  • clients/agent-runtime/src/security/detect.rs
  • clients/agent-runtime/src/capabilities/registry.rs
  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/tools/shell.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/security/policy.rs
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/channels/mod.rs
  • clients/agent-runtime/src/config/schema.rs
  • clients/agent-runtime/src/gateway/admin.rs
**/*.kt

⚙️ CodeRabbit configuration file

**/*.kt: Enforce null safety (no !!), structured concurrency, and non-blocking suspend code.
Prefer idiomatic Kotlin (expression bodies, sealed types, value classes when justified).
Verify tests follow TDD intent and use backtick test names where applicable.

Files:

  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/runtime/MobileRuntimeCoordinator.kt
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatComponents.kt
  • clients/composeApp/src/iosMain/kotlin/com/profiletailors/corvus/runtime/IosRuntimeBridge.kt
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/App.kt
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatWorkspace.kt
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/onboarding/OnboardingScreen.kt
clients/agent-runtime/src/channels/**/*.rs

📄 CodeRabbit inference engine (clients/agent-runtime/AGENTS.md)

Implement Channel trait in src/channels/ with consistent send, listen, and health_check semantics and cover auth/allowlist/health behavior with tests

Files:

  • clients/agent-runtime/src/channels/cli.rs
  • clients/agent-runtime/src/channels/mod.rs
clients/agent-runtime/src/{security,gateway,tools}/**/*.rs

📄 CodeRabbit inference engine (clients/agent-runtime/AGENTS.md)

Treat src/security/, src/gateway/, src/tools/ as high-risk surfaces and never broaden filesystem/network execution scope without explicit policy checks

Files:

  • clients/agent-runtime/src/security/detect.rs
  • clients/agent-runtime/src/tools/shell.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/security/policy.rs
  • clients/agent-runtime/src/gateway/admin.rs
clients/agent-runtime/src/{security,gateway,tools,config}/**/*.rs

📄 CodeRabbit inference engine (clients/agent-runtime/AGENTS.md)

Do not silently weaken security policy or access constraints; keep default behavior secure-by-default with deny-by-default where applicable

Files:

  • clients/agent-runtime/src/security/detect.rs
  • clients/agent-runtime/src/tools/shell.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/security/policy.rs
  • clients/agent-runtime/src/config/schema.rs
  • clients/agent-runtime/src/gateway/admin.rs
clients/agent-runtime/src/main.rs

📄 CodeRabbit inference engine (clients/agent-runtime/AGENTS.md)

clients/agent-runtime/src/main.rs: Preserve CLI contract unless change is intentional and documented; prefer explicit errors over silent fallback for unsupported critical paths
Keep startup path lean and avoid heavy initialization in command parsing flow

Files:

  • clients/agent-runtime/src/main.rs
clients/agent-runtime/src/tools/**/*.rs

📄 CodeRabbit inference engine (clients/agent-runtime/AGENTS.md)

Implement Tool trait in src/tools/ with strict parameter schema, validate and sanitize all inputs, and return structured ToolResult without panics in runtime path

Files:

  • clients/agent-runtime/src/tools/shell.rs
🧠 Learnings (12)
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/main.rs : Preserve CLI contract unless change is intentional and documented; prefer explicit errors over silent fallback for unsupported critical paths

Applied to files:

  • clients/agent-runtime/src/search/tests.rs
  • clients/agent-runtime/src/search/discovery.rs
  • clients/agent-runtime/src/channels/cli.rs
  • clients/agent-runtime/src/security/detect.rs
  • clients/agent-runtime/src/capabilities/registry.rs
  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/tools/shell.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/security/policy.rs
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/channels/mod.rs
  • clients/agent-runtime/src/config/schema.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/{security,gateway,tools}/**/*.rs : Treat `src/security/`, `src/gateway/`, `src/tools/` as high-risk surfaces and never broaden filesystem/network execution scope without explicit policy checks

Applied to files:

  • clients/agent-runtime/src/search/discovery.rs
  • clients/agent-runtime/src/security/detect.rs
  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/tools/shell.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/security/policy.rs
  • clients/agent-runtime/src/agent/agent.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/main.rs : Keep startup path lean and avoid heavy initialization in command parsing flow

Applied to files:

  • clients/agent-runtime/src/search/discovery.rs
  • clients/agent-runtime/src/channels/cli.rs
  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/tools/shell.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/security/policy.rs
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/channels/mod.rs
  • clients/agent-runtime/src/config/schema.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/**/*.rs : Run `cargo fmt --all -- --check`, `cargo clippy --all-targets -- -D warnings`, and `cargo test` for code validation, or document which checks were skipped and why

Applied to files:

  • clients/agent-runtime/src/search/discovery.rs
  • clients/agent-runtime/src/capabilities/registry.rs
  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/tools/shell.rs
  • scripts/release-contract.test.mjs
  • clients/agent-runtime/src/security/policy.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/{security,gateway,tools,config}/**/*.rs : Do not silently weaken security policy or access constraints; keep default behavior secure-by-default with deny-by-default where applicable

Applied to files:

  • clients/agent-runtime/src/search/discovery.rs
  • clients/agent-runtime/src/security/detect.rs
  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/tools/shell.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/security/policy.rs
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/config/schema.rs
  • clients/agent-runtime/src/gateway/admin.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/providers/**/*.rs : Implement `Provider` trait in `src/providers/` and register in `src/providers/mod.rs` factory when adding a new provider

Applied to files:

  • clients/agent-runtime/src/capabilities/registry.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/**/*.rs : Avoid unnecessary allocations, clones, and blocking operations to maintain performance and efficiency

Applied to files:

  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/agent/agent.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/**/Cargo.toml : Do not add heavy dependencies for minor convenience; justify new crate additions

Applied to files:

  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/tools/shell.rs
  • clients/agent-runtime/src/config/schema.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/tools/**/*.rs : Implement `Tool` trait in `src/tools/` with strict parameter schema, validate and sanitize all inputs, and return structured `ToolResult` without panics in runtime path

Applied to files:

  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/tools/shell.rs
  • clients/agent-runtime/src/agent/agent.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/channels/**/*.rs : Implement `Channel` trait in `src/channels/` with consistent `send`, `listen`, and `health_check` semantics and cover auth/allowlist/health behavior with tests

Applied to files:

  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/channels/mod.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/**/Cargo.toml : Preserve release-size profile assumptions in `Cargo.toml` and avoid adding heavy dependencies unless clearly justified

Applied to files:

  • clients/agent-runtime/src/main.rs
  • scripts/release-contract.test.mjs
  • clients/agent-runtime/src/config/schema.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Include threat/risk notes and rollback strategy for security, runtime, and gateway changes; add or update tests for boundary checks and failure modes

Applied to files:

  • clients/agent-runtime/src/security/policy.rs
🪛 GitHub Actions: Scan with Detekt
clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/runtime/MobileRuntimeCoordinator.kt

[error] 25-25: detekt [TooManyFunctions]: Class 'MobileRuntimeCoordinator' with '12' functions detected; threshold inside classes is set to '11'.

clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatComponents.kt

[error] 201-201: detekt [LongParameterList]: Function ChatBubbleBody(...) has too many parameters; threshold is 6.


[error] 522-522: detekt [CyclomaticComplexMethod]: Function bridgeStateRecovery is too complex; complexity is 15; threshold is set to 15.


[error] 1-1: detekt [TooManyFunctions]: File has '16' functions detected; threshold inside files is set to '11'.

clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatWorkspace.kt

[error] 195-195: detekt [LongMethod]: Function ChatWorkspaceScreen is too long (64); maximum length is 60.

clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/onboarding/OnboardingScreen.kt

[error] 162-162: detekt [LongMethod]: Function OnboardingScreen is too long (78); maximum length is 60.


[error] 162-162: detekt [FunctionNaming]: Function names should match pattern [a-z][a-zA-Z0-9]*.

🪛 Shellcheck (0.11.0)
gradle/configs/git/hooks/pre-push.sh

[info] 89-89: Double quote to prevent globbing and word splitting.

(SC2086)

🔇 Additional comments (58)
clients/composeApp/src/iosMain/kotlin/com/profiletailors/corvus/runtime/IosRuntimeBridge.kt (1)

5-5: Good Kotlin-idiomatic SAM refinement with no contract break.

Switching to fun interface is safe here and improves call-site ergonomics (lambda support) while preserving existing behavior and nullability contract.

clients/agent-runtime/src/security/policy.rs (1)

247-273: Refactor keeps risk-gate behavior intact.

The extraction makes command_risk_level easier to audit without changing the High→Medium→Low decision shape.

clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/runtime/MobileRuntimeCoordinator.kt (1)

227-230: Assistant event deduplication looks correct.

Line 227–230 keeps assistant chunk/message handling behavior consistent while reducing duplication.

gradle/configs/git/hooks/pre-push.sh (1)

38-38: Good defensive catch-all in case block.

Explicitly handling non-matching paths with a no-op keeps dispatch behavior predictable.

clients/web/apps/dashboard/src/composables/useAdmin.ts (1)

270-273: LGTM: Type assertion removal improves type safety.

Removing the redundant type assertion is correct. The ref's type annotation ref<AdminSessionDetail | null> already enforces that assigned values must be compatible with AdminSessionDetail, so the explicit as cast was unnecessary. TypeScript will now catch any structural mismatches at the assignment point rather than hiding them behind the assertion.

clients/web/apps/dashboard/src/types/admin-sessions.ts (1)

123-123: No breaking changes found. Type broadening is safe and necessary.

The data field is only accessed via JSON.stringify() in the sole consumer (CerebroSessionActions.vue), which safely handles all union types. No code calls .map(), .filter(), or .length on this field, and type guards properly narrow the union before access.

clients/agent-runtime/src/capabilities/registry.rs (1)

57-66: Good extraction of validation pipeline.

This split makes CapabilityRegistry::validate_descriptor easier to reason about and maintain while keeping error construction localized.

.github/workflows/release-please.yml (2)

18-21: Good least-privilege scoping for Actions token permissions.

Moving permissions to job scope is a solid hardening step and preserves required capabilities for release-please.


123-131: Explicit secret forwarding is correctly implemented.

Replacing secrets: inherit with explicit mappings reduces overexposure risk and matches the reusable workflow contract.

.github/workflows/publish-snapshot.yml (2)

17-19: Permissions are appropriately explicit and minimal for snapshot publishing.

contents: read with packages: write is a good least-privilege baseline for this caller job.


24-32: Reusable workflow secret contract is explicitly and safely wired.

This removes implicit inheritance and keeps secret flow auditable.

.github/workflows/publish-release.yml (2)

20-22: Job-level permission scoping looks correct.

This keeps write privileges constrained to the release publisher job.


28-36: Explicit secrets map is correct and improves release-path security.

The mapped values match expected publish credentials and avoid blanket inheritance.

scripts/release-contract.test.mjs (1)

68-110: Contract assertions are stronger and the Set-based checks are a solid cleanup.

Good tightening of release workflow invariants and lower-overhead membership checks.

Also applies to: 146-185

clients/web/apps/dashboard/src/components/config/WebSearchSettings.vue (1)

17-21: Set-based mode validation looks good.

Line 57 now gates updates through Set.has(...), keeping the allowed-mode boundary explicit with no behavior drift from prior accepted values.

Also applies to: 57-60

clients/web/apps/chat/src/composables/useChat.ts (2)

59-159: Helper extraction improves maintainability without changing contract.

The split into normalizeStreamChunk, resetStreamEventState, and processStreamBuffer reduces parser complexity and keeps the stream state machine easier to reason about.


544-609: SSE frame finalization and CRLF normalization are robust.

The line-based parser reset behavior and tail-buffer flush (\n\n append) correctly handle split frames and mixed newline styles.

clients/web/apps/chat/src/composables/useChat.spec.ts (2)

391-414: Good regression coverage for approval_contract webhook mapping.

This test protects the 403 approval-contract compatibility path and verifies the expected approval_required shape end-to-end.


429-453: Good coverage for structured SSE error propagation.

This validates that event: error frames surface provider message text to callers, which matches the updated parser behavior.

clients/web/apps/dashboard/src/components/config/ChannelsOverview.vue (1)

82-83: A11y change is safe.

Keeping aria-live while removing explicit role on these status paragraphs preserves announcement behavior and simplifies markup.

clients/web/apps/dashboard/src/components/config/HealthDashboard.vue (1)

115-116: A11y markup update looks good.

Line 115 and Line 116 retain polite/assertive live-region announcements without redundant ARIA roles.

clients/web/apps/dashboard/src/components/config/HeartbeatOverview.vue (1)

77-78: No regression in live-status messaging.

The loading/error branches still expose the right live-region politeness levels after removing explicit roles.

clients/web/apps/dashboard/src/components/config/SchedulerStatus.vue (1)

72-73: A11y cleanup is consistent and safe.

The component still announces loading/error state changes via aria-live with unchanged conditional flow.

clients/web/apps/dashboard/src/components/memory/MemoryStats.vue (1)

31-35: Template accessibility behavior remains intact.

The loading/error live regions still communicate state changes while removing unnecessary explicit roles.

clients/web/apps/dashboard/src/components/config/TunnelOverview.vue (1)

63-64: A11y live-region cleanup looks good.

Loading/error announcements keep aria-live semantics and preserve rendering flow.

clients/web/apps/dashboard/src/components/config/McpOverview.vue (1)

69-70: Looks good: live-region behavior remains intact.

The loading/error states still provide polite/assertive announcements with no logic regression.

clients/web/apps/dashboard/src/components/memory/LocalMemoryExplorerPanel.vue (1)

91-93: Approved — accessibility signaling is preserved.

aria-live remains in place for both loading and error states.

clients/web/apps/dashboard/src/components/sessions/SessionDetail.vue (1)

51-55: LGTM on the loading/error accessibility update.

Template behavior stays the same while retaining live announcements.

clients/web/apps/dashboard/src/components/config/ReliabilityOverview.vue (1)

72-73: Approved.

A11y status/error messaging remains present with no logic changes.

clients/web/apps/chat/src/App.vue (2)

23-24: Good hardening of restored message validation.

Using shared Set membership keeps validation strict and reduces per-restore overhead.

Also applies to: 297-300


500-500: Blocked-state announcement update is solid.

aria-live="assertive" keeps urgent recovery messaging surfaced for assistive tech.

clients/web/apps/dashboard/src/components/sessions/SessionList.vue (2)

24-24: Per-page validation refactor is correct.

The Set-based guard keeps input boundaries enforced with simpler membership checks.

Also applies to: 51-51


74-74: Loading/error accessibility change is safe.

Live-region signaling is still present and conditional rendering is unchanged.

Also applies to: 77-77

clients/web/apps/dashboard/src/components/memory/MemoryList.vue (1)

124-124: A11y status/error update looks good.

Polite/assertive live-region behavior is preserved.

Also applies to: 127-127

clients/web/apps/dashboard/src/components/config/CostOverview.vue (2)

113-123: Good consolidation of governance refresh triggers.

Using refreshGovernance() for both initial load and prop-driven refresh keeps this path consistent and easier to maintain.


132-136: A11y live-region updates look correct.

Keeping aria-live while removing redundant explicit roles is a clean semantic improvement for these status/error messages.

Also applies to: 294-295

clients/web/apps/dashboard/src/components/config/UpdateSettings.vue (2)

11-22: formatToggle is a solid readability + i18n improvement.

This removes repeated inline logic and standardizes boolean/unknown rendering.


29-70: Template semantics are improved.

Switching to .display-field containers for read-only values is cleaner than label-style wrappers and keeps layout concerns isolated in scoped styles.

Also applies to: 75-86

clients/web/apps/dashboard/src/App.vue (1)

239-273: Live-region messaging changes look good.

Switching these status messages to <p> while preserving aria-live/aria-atomic behavior is a reasonable accessibility-safe cleanup.

clients/agent-runtime/src/channels/cli.rs (1)

263-266: The review comment is incorrect. AudioConfig::max_audio_bytes is bounded by upstream validation in validate_audio_config() at line 3444 of schema.rs, which enforces the constraint 0 < max_audio_bytes <= MAX_AUDIO_BYTES_CEILING where the ceiling is 100 MiB (104,857,600 bytes). This is validated during config initialization and cannot reach u64::MAX. The addition max_size + 1 at line 264 cannot overflow—even at the maximum allowed value of 100 MiB, the result is still trivial within u64 range. The suggested fix is unnecessary.

			> Likely an incorrect or invalid review comment.
clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/App.kt (1)

132-154: Good call-site cleanup.

Bundling ChatWorkspaceContent and BridgeActions here keeps App.kt as the single assembly point and prevents ChatWorkspace from drifting back to a long parameter list.

clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/onboarding/OnboardingScreen.kt (1)

120-128: Nice API cleanup.

Bundling the screen inputs into OnboardingScreenState and OnboardingScreenActions removes prop drift at the only call site and makes this contract easier to evolve.

clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatComponents.kt (1)

522-554: Extract or refactor bridgeStateRecovery to reduce complexity.

The nested when expressions with 15+ decision paths likely exceeds detekt's complexity threshold. Convert to lookup maps or extract the null fallback branch to keep the recovery contract readable and pass CI.

clients/agent-runtime/src/security/detect.rs (2)

19-77: Fail-closed sandbox behavior is preserved through the refactor.

The extraction to shared fallback handlers keeps the explicit-backend contract intact (require=true errors; optional mode degrades to NoopSandbox) and does not weaken sandbox policy behavior.


86-107: Good helper extraction for consistency and reduced drift risk.

Centralizing fallback/error decisions improves maintainability while retaining current security semantics across all backend branches.

clients/agent-runtime/src/search/discovery.rs (3)

162-163: Shared walker/root setup extraction looks correct and low risk.

This keeps discovery behavior centralized and reduces duplicated configuration paths without changing the existing security gating flow.

Also applies to: 225-231


267-311: Helper decomposition improves maintainability while preserving behavior.

The split into workspace_root_for, configured_walk_builder, and apply_overrides keeps concerns isolated and retains clear error context for invalid patterns.


313-323: indexable_path_exists error handling is explicit and appropriate.

NotFound is handled as a non-error path while other filesystem failures are surfaced with context, which keeps diagnostics reliable.

clients/agent-runtime/src/search/tests.rs (1)

445-448: Lock-failure assertion broadening is pragmatic and still scoped.

The expanded substring set keeps the fail-fast lock contract intact while reducing brittle dependency on exact database error phrasing.

clients/agent-runtime/src/config/schema.rs (2)

2948-2957: Good extraction in load_or_init without behavior drift.

The delegation to helper functions keeps the startup flow clearer while preserving permission/decryption/validation sequencing.


3833-3888: Centralized load/decrypt helper is solid.

load_existing_config and decrypt_config_secrets correctly consolidate config parsing, computed field hydration, and secret decryption with contextual errors.

clients/agent-runtime/src/gateway/mod.rs (3)

1148-1148: Good security gate placement in startup path.

Calling ensure_safe_gateway_bind before listener setup keeps the public-bind denial path fail-closed and explicit.

Based on learnings: Applies to clients/agent-runtime/src/{security,gateway,tools,config}/**/*.rs : Do not silently weaken security policy or access constraints; keep default behavior secure-by-default with deny-by-default where applicable.


1167-1167: Helper extraction improves clarity without changing security intent.

Moving webhook and WhatsApp secret derivation behind dedicated helpers keeps run_gateway simpler while preserving secret handling boundaries.

Also applies to: 1178-1178


1376-1386: Security-sensitive helpers look correct and behavior-preserving.

The extracted helpers keep secure defaults intact, trim/ignore empty secret inputs, and avoid plaintext secret exposure.

As per coding guidelines: clients/agent-runtime/src/**/*.rs: Never log secrets, tokens, raw credentials, or sensitive payloads in any logging statements.

Also applies to: 1388-1396, 1398-1420

clients/agent-runtime/src/main.rs (1)

830-856: Dispatch helper extraction preserves command behavior and CLI contract.

The new wrappers keep argument forwarding and result handling unchanged while making dispatch branches cleaner.

Based on learnings: Preserve CLI contract unless change is intentional and documented; prefer explicit errors over silent fallback for unsupported critical paths.

Also applies to: 916-954

clients/agent-runtime/src/gateway/admin.rs (1)

668-695: Helper-based admin_config_view refactor is clean and security-preserving.

This keeps the same admin view shape while retaining secret-safe exposure (has_* flags only), which reduces complexity without changing policy behavior.

As per coding guidelines: Do not silently weaken security policy or access constraints; keep default behavior secure-by-default with deny-by-default where applicable.

Also applies to: 697-923

clients/agent-runtime/src/tools/shell.rs (1)

70-118: Shell execution refactor improves error-path consistency without weakening execution controls.

Centralized tool_error now guarantees structured metadata on build/wrap/exec/timeout failures, and the sanitize-then-wrap flow remains intact.

As per coding guidelines: Implement Tool trait in src/tools/ with strict parameter schema, validate and sanitize all inputs, and return structured ToolResult without panics in runtime path.

Also applies to: 192-271

clients/agent-runtime/src/agent/agent.rs (1)

744-750: Nice consolidation for unknown-tool failures.

Routing the unknown-tool path through the shared finalizer keeps observer accounting aligned with the normal execution path.

Comment thread clients/agent-runtime/src/agent/agent.rs Outdated
Comment thread clients/agent-runtime/src/capabilities/registry.rs
Comment thread clients/agent-runtime/src/capabilities/registry.rs
Comment thread clients/agent-runtime/src/config/schema.rs
Comment thread clients/agent-runtime/src/security/policy.rs
Comment thread clients/web/apps/dashboard/src/composables/useChat.ts
Comment thread clients/web/apps/dashboard/src/App.vue Outdated
Comment thread clients/web/apps/dashboard/src/components/memory/MemoryList.vue
Comment thread gradle/configs/git/hooks/pre-push.sh Outdated
Comment thread scripts/release-contract.test.mjs
@yacosta738 yacosta738 self-assigned this Apr 10, 2026
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Apr 10, 2026

Deploying corvus with  Cloudflare Pages  Cloudflare Pages

Latest commit: 1f6b50a
Status: ✅  Deploy successful!
Preview URL: https://2bfb2a65.corvus-42x.pages.dev
Branch Preview URL: https://feature-dallay-251-recurring.corvus-42x.pages.dev

View logs

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 8

Caution

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

⚠️ Outside diff range comments (2)
clients/web/apps/dashboard/src/App.vue (1)

188-228: ⚠️ Potential issue | 🟠 Major

Add keyboard support for the new tablists.

The new tab pattern uses roving tabindex, but none of these tablists wires Arrow/Home/End key handling. With inactive tabs at -1, keyboard users can only reach the currently selected tab and cannot switch sections or memory views without a mouse.

As per coding guidelines, "Ensure accessibility (A11y) and proper use of Tailwind CSS classes."

Also applies to: 528-555, 565-592

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/web/apps/dashboard/src/App.vue` around lines 188 - 228, The tablist
buttons (e.g., elements with ids dashboard-tab-config, dashboard-tab-sessions,
dashboard-tab-memory and the bound reactive currentPage) implement roving
tabindex but lack keyboard handlers, preventing Arrow/ Home/End navigation; add
a keydown handler on each tab (or a shared method like handleTabKeydown) to
handle ArrowLeft/ArrowRight (move focus to previous/next tab and update
currentPage), Home (focus first tab and set currentPage), and End (focus last
tab and set currentPage), ensure when moving focus you update tabindex values so
only the focused/selected tab has 0 and others -1, and call .focus() on the
target button so keyboard users can navigate the tablist without a mouse.
clients/web/apps/chat/src/composables/useChat.ts (1)

95-118: ⚠️ Potential issue | 🟠 Major

Handle top-level approval payload fields.

parseApprovalErrorType() ignores a top-level code, and createApprovalRequiredResult() ignores top-level tool/reason. But clients/agent-runtime/src/agent/agent.rs emits approval denials as { code, tool, reason } at the top level. In that shape, a valid 403 approval response will fall through to throwCredentialInvalid() and clear good credentials/session state.

Suggested fix
 type ApprovalErrorPayload = {
+  code?: string;
+  tool?: string;
+  reason?: string;
   error?:
     | string
     | {
         code?: string;
         type?: string;
@@
   const response = payload as ApprovalErrorPayload;
+  if (typeof response.code === "string" && response.code.trim()) {
+    return response.code.trim();
+  }
   if (typeof response.type === "string" && response.type.trim()) {
     return response.type.trim();
   }
@@
   return {
       type: "approval_required",
-      tool: errorObj?.tool ?? "",
-      reason: errorObj?.reason ?? "",
+      tool: errorObj?.tool ?? payload.tool ?? "",
+      reason: errorObj?.reason ?? payload.reason ?? "",
       sessionId:
         (errorData as Record<string, unknown>)?.session_id?.toString() ?? currentSessionId.value,
   };

As per coding guidelines, "**/*: Security first, performance second. Validate input boundaries, auth/authz implications, and secret management. Look for behavioral regressions, missing tests, and contract breaks across modules."

Also applies to: 350-379

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/web/apps/chat/src/composables/useChat.ts` around lines 95 - 118,
Update parseApprovalErrorType to also inspect top-level numeric/string code and
top-level tool/reason fields: check payload.code (string or number) and return
its string form if present, and if not present check payload.tool or
payload.reason (string) before falling back to nested error fields; likewise
update createApprovalRequiredResult to recognize top-level tool and reason keys
on the approval payload (in addition to nested error object) so a top-level
{code, tool, reason} denial is converted into an approval-required result
instead of falling through to throwCredentialInvalid; reference
parseApprovalErrorType and createApprovalRequiredResult when making these
changes.
♻️ Duplicate comments (2)
clients/agent-runtime/src/agent/agent.rs (1)

754-758: ⚠️ Potential issue | 🟠 Major

Route audit failures through finalize_tool_execution() too.

The Err(audit_error_result) => return audit_error_result branch still bypasses finalize_tool_execution(), so strict shell-audit failures do not emit ObserverEvent::ToolCall. The new action parameter fixes the dispatch-action loss, but the security-relevant observability gap is still open.

Suggested fix
-        let (result, success) = match tool.execute(call.arguments.clone()).await {
+        let (result, success, action) = match tool.execute(call.arguments.clone()).await {
             Ok(result) => match self.handle_tool_result(call, &result, start.elapsed()) {
-                Ok(output) => (output, result.success),
-                Err(audit_error_result) => return audit_error_result,
+                Ok(output) => (output, result.success, DispatchAction::Execute),
+                Err(audit_error_result) => (
+                    audit_error_result.output,
+                    audit_error_result.success,
+                    audit_error_result.action,
+                ),
             },
-            Err(error) => (format!("Error executing {}: {error}", call.name), false),
+            Err(error) => (
+                format!("Error executing {}: {error}", call.name),
+                false,
+                DispatchAction::Execute,
+            ),
         };
 
         self.finalize_tool_execution(
             call,
             start.elapsed(),
             result,
             success,
-            DispatchAction::Execute,
+            action,
         )

As per coding guidelines, "**/*: Security first, performance second. Validate input boundaries, auth/authz implications, and secret management. Look for behavioral regressions ... across modules."

Also applies to: 810-830

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/agent-runtime/src/agent/agent.rs` around lines 754 - 758, The
audit-error branch currently returns early and bypasses finalize_tool_execution,
so update the Err(audit_error_result) path in the match that handles
tool.execute(...) to call finalize_tool_execution(...) with the same context
(call, start.elapsed(), and the derived action/dispatch info) before returning;
ensure you pass an appropriate failed/empty tool result or error marker that
finalize_tool_execution expects (matching how the Ok branch calls it after
handle_tool_result), and then return the audit_error_result afterward so
ObserverEvent::ToolCall is emitted even on strict-audit failures (apply the same
change in the other occurrence around lines 810–830).
clients/agent-runtime/src/config/schema.rs (1)

2955-2959: ⚠️ Potential issue | 🟡 Minor

Trim CORVUS_WORKSPACE in the later env-override pass too.

This startup path still calls apply_env_overrides(), and apply_workspace_override() only checks !workspace.is_empty(). A whitespace-only CORVUS_WORKSPACE therefore still wins after your new trimmed resolution step and can repoint config_path / workspace_dir to an unintended relative path.

Suggested fix
 fn apply_workspace_override(&mut self) {
     if let Ok(workspace) = std::env::var("CORVUS_WORKSPACE") {
-        if !workspace.is_empty() {
-            let (config_dir, workspace_dir) =
-                resolve_config_dir_for_workspace(&PathBuf::from(workspace));
+        let workspace = workspace.trim();
+        if !workspace.is_empty() {
+            let (config_dir, workspace_dir) =
+                resolve_config_dir_for_workspace(Path::new(workspace));
             self.config_path = config_dir.join("config.toml");
             self.workspace_dir = workspace_dir;
         }
     }
 }

As per coding guidelines: "Security first, performance second. Validate input boundaries, auth/authz implications, and secret management."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/agent-runtime/src/config/schema.rs` around lines 2955 - 2959, The
env-override pass still lets a whitespace-only CORVUS_WORKSPACE win; update
apply_env_overrides() (or specifically apply_workspace_override() called from
it) so that it trims whitespace from the CORVUS_WORKSPACE value before testing
emptiness and applying it to config/workspace_dir (i.e., call .trim() on the env
value and only apply if the trimmed string is non-empty), ensuring the same
trimmed resolution used earlier in load_existing_config is honored.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatBridgeCopy.kt`:
- Around line 60-73: The fallbackRecovery function currently returns "No
recovery action needed." for unknown statuses, which incorrectly covers
MobileOnboardingStatus.BLOCKED; update fallbackRecovery to add a specific branch
for MobileOnboardingStatus.BLOCKED that returns a clear blocked-state message
(e.g., explaining why the onboarding is blocked and what the user should do),
keeping the other branches intact; ensure the call site that passes null to
fallbackRecovery (where recoveryKind is null) continues to call
fallbackRecovery(status) so BLOCKED is handled by the new case.

In
`@clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatComponents.kt`:
- Around line 138-150: The bubblePalette remembered value captures contentColor
(MaterialTheme.colorScheme.onSurface) but the remember keys only include isUser
and corvusColors, which can lead to stale text color on theme changes; update
the remember(...) call that constructs bubblePalette (the remember used to
create ChatBubblePalette) to include contentColor as an additional key so the
remembered ChatBubblePalette (background/accent/shadow/content/title) is
recomputed whenever the onSurface color changes.

In
`@clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/onboarding/OnboardingScreen.kt`:
- Around line 121-127: OnboardingScreenState duplicates footer fields
(currentStepIndex, totalSteps, primaryActionLabel) that already live on
OnboardingStep; remove those three properties from the OnboardingScreenState
data class and change all places that construct or read them to derive values
from the single step property (e.g., use step.currentStepIndex, step.totalSteps,
step.primaryActionLabel). Update callers that pass the removed fields (including
the App.kt call site) to stop supplying them and validate input boundaries where
values are derived to avoid regressions or contract breaks. Ensure any other
duplicated declarations of OnboardingScreenState are similarly cleaned up.

In `@clients/web/apps/chat/src/composables/useChat.ts`:
- Around line 303-317: The function normalizeOutgoingMessage currently may call
startSession(true) before rejecting whitespace-only input; change the logic in
normalizeOutgoingMessage so you trim and validate the message first (compute
normalizedMessage = message.trim() and if empty throw
t("chat.emptyMessageError")), then proceed to check gateway.isGatewayReady.value
and isSessionReady.value and call startSession(true) only after the input is
confirmed non-empty; keep existing error messages (t("chat.connectBeforeChat")
and errorMessage.value || t("chat.sessionUnavailable")) unchanged.

In `@clients/web/apps/dashboard/src/App.vue`:
- Around line 314-315: The section with id "dashboard-panel-config" exposes
role="tabpanel" and aria-labelledby="dashboard-tab-config" even when the related
tab is not rendered because the v-if is on the inner section
(v-if="config.isOperatorReady.value"); move the visibility condition up or guard
the ARIA attributes: either apply v-if="config.isOperatorReady.value" to the
outer <section id="dashboard-panel-config"> or render the role and
aria-labelledby only when config.isOperatorReady.value is true (so the element
is not a tabpanel when the tab is absent).

In `@clients/web/apps/dashboard/src/components/memory/MemoryList.vue`:
- Around line 124-127: MemoryList.vue removed explicit live-region roles which
can reduce announcement reliability; update the two transient paragraphs that
use admin.loading.value and admin.error.value to include role="status" for the
loading message and role="alert" for the error message and also add
aria-atomic="true" to both elements so screen readers reliably announce the full
content when those states change (locate the <p> elements referencing
admin.loading.value and admin.error.value in the MemoryList component and add
the role and aria-atomic attributes).

In `@gradle/configs/git/hooks/pre-push.sh`:
- Around line 85-99: Split the combined condition so docs-detection (HAS_DOCS
and DOC_FILES parsing via DOC_FILES/DOC_FILES handling) runs independently from
the lychee availability check: first, if HAS_DOCS=1 and DOC_FILES is non-empty
(use the existing DOC_FILES parsing logic with IFS and set -f), then check
command -v lychee; if lychee is missing echo a clear message like "lychee not
installed — skipping doc link check" (so skipped checks are visible) and do not
call lychee, otherwise run lychee --config "lychee.toml" --offline --no-progress
"$@" and increment CHECKS_RUN; keep the current DOC_FILES variable and lychee
invocation names (DOC_FILES, HAS_DOCS, lychee, CHECKS_RUN) to locate the code.

In `@scripts/release-contract.test.mjs`:
- Around line 30-38: The env override in resolveExecutable currently accepts any
absolute path from process.env (configuredPath), which can point to arbitrary
binaries; update resolveExecutable to validate configuredPath before using it:
ensure if configuredPath is absolute it must reside in an allowed trusted
directory prefix (e.g., path.join(process.env.HOME, ".cargo", "bin"),
"/usr/bin", "/usr/local/bin", "/opt/homebrew/bin") and/or otherwise be a bare
executable name (no path separators); additionally verify the candidate file
exists and is executable before returning it. Apply this validation to the
configuredPath logic in resolveExecutable (and the same pattern for the other
env-based lookup around lines 40-51).

---

Outside diff comments:
In `@clients/web/apps/chat/src/composables/useChat.ts`:
- Around line 95-118: Update parseApprovalErrorType to also inspect top-level
numeric/string code and top-level tool/reason fields: check payload.code (string
or number) and return its string form if present, and if not present check
payload.tool or payload.reason (string) before falling back to nested error
fields; likewise update createApprovalRequiredResult to recognize top-level tool
and reason keys on the approval payload (in addition to nested error object) so
a top-level {code, tool, reason} denial is converted into an approval-required
result instead of falling through to throwCredentialInvalid; reference
parseApprovalErrorType and createApprovalRequiredResult when making these
changes.

In `@clients/web/apps/dashboard/src/App.vue`:
- Around line 188-228: The tablist buttons (e.g., elements with ids
dashboard-tab-config, dashboard-tab-sessions, dashboard-tab-memory and the bound
reactive currentPage) implement roving tabindex but lack keyboard handlers,
preventing Arrow/ Home/End navigation; add a keydown handler on each tab (or a
shared method like handleTabKeydown) to handle ArrowLeft/ArrowRight (move focus
to previous/next tab and update currentPage), Home (focus first tab and set
currentPage), and End (focus last tab and set currentPage), ensure when moving
focus you update tabindex values so only the focused/selected tab has 0 and
others -1, and call .focus() on the target button so keyboard users can navigate
the tablist without a mouse.

---

Duplicate comments:
In `@clients/agent-runtime/src/agent/agent.rs`:
- Around line 754-758: The audit-error branch currently returns early and
bypasses finalize_tool_execution, so update the Err(audit_error_result) path in
the match that handles tool.execute(...) to call finalize_tool_execution(...)
with the same context (call, start.elapsed(), and the derived action/dispatch
info) before returning; ensure you pass an appropriate failed/empty tool result
or error marker that finalize_tool_execution expects (matching how the Ok branch
calls it after handle_tool_result), and then return the audit_error_result
afterward so ObserverEvent::ToolCall is emitted even on strict-audit failures
(apply the same change in the other occurrence around lines 810–830).

In `@clients/agent-runtime/src/config/schema.rs`:
- Around line 2955-2959: The env-override pass still lets a whitespace-only
CORVUS_WORKSPACE win; update apply_env_overrides() (or specifically
apply_workspace_override() called from it) so that it trims whitespace from the
CORVUS_WORKSPACE value before testing emptiness and applying it to
config/workspace_dir (i.e., call .trim() on the env value and only apply if the
trimmed string is non-empty), ensuring the same trimmed resolution used earlier
in load_existing_config is honored.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: f80b1085-a36b-4b66-b2c0-9fe6140ec1d5

📥 Commits

Reviewing files that changed from the base of the PR and between 5e43913 and ec30eca.

📒 Files selected for processing (15)
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/capabilities/registry.rs
  • clients/agent-runtime/src/config/schema.rs
  • clients/agent-runtime/src/security/policy.rs
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/runtime/MobileRuntimeCoordinator.kt
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatBridgeCopy.kt
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatComponents.kt
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatWorkspace.kt
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/onboarding/OnboardingScreen.kt
  • clients/web/apps/chat/src/composables/useChat.spec.ts
  • clients/web/apps/chat/src/composables/useChat.ts
  • clients/web/apps/dashboard/src/App.vue
  • clients/web/apps/dashboard/src/components/memory/MemoryList.vue
  • gradle/configs/git/hooks/pre-push.sh
  • scripts/release-contract.test.mjs
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: submit-gradle
  • GitHub Check: Cloudflare Pages
🧰 Additional context used
📓 Path-based instructions (8)
**/*.vue

⚙️ CodeRabbit configuration file

**/*.vue: Enforce Vue 3 Composition API with <script setup>.
Ensure accessibility (A11y) and proper use of Tailwind CSS classes.
Check for proper prop validation and emitted events documentation.

Files:

  • clients/web/apps/dashboard/src/components/memory/MemoryList.vue
  • clients/web/apps/dashboard/src/App.vue
**/*

⚙️ CodeRabbit configuration file

**/*: Security first, performance second.
Validate input boundaries, auth/authz implications, and secret management.
Look for behavioral regressions, missing tests, and contract breaks across modules.

Files:

  • clients/web/apps/dashboard/src/components/memory/MemoryList.vue
  • gradle/configs/git/hooks/pre-push.sh
  • clients/web/apps/chat/src/composables/useChat.spec.ts
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/runtime/MobileRuntimeCoordinator.kt
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatWorkspace.kt
  • clients/agent-runtime/src/agent/agent.rs
  • scripts/release-contract.test.mjs
  • clients/web/apps/chat/src/composables/useChat.ts
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatBridgeCopy.kt
  • clients/agent-runtime/src/capabilities/registry.rs
  • clients/agent-runtime/src/security/policy.rs
  • clients/agent-runtime/src/config/schema.rs
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/onboarding/OnboardingScreen.kt
  • clients/web/apps/dashboard/src/App.vue
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatComponents.kt
**/*.kt

⚙️ CodeRabbit configuration file

**/*.kt: Enforce null safety (no !!), structured concurrency, and non-blocking suspend code.
Prefer idiomatic Kotlin (expression bodies, sealed types, value classes when justified).
Verify tests follow TDD intent and use backtick test names where applicable.

Files:

  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/runtime/MobileRuntimeCoordinator.kt
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatWorkspace.kt
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatBridgeCopy.kt
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/onboarding/OnboardingScreen.kt
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatComponents.kt
clients/agent-runtime/src/**/*.rs

📄 CodeRabbit inference engine (clients/agent-runtime/AGENTS.md)

clients/agent-runtime/src/**/*.rs: Never log secrets, tokens, raw credentials, or sensitive payloads in any logging statements
Avoid unnecessary allocations, clones, and blocking operations to maintain performance and efficiency

Files:

  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/capabilities/registry.rs
  • clients/agent-runtime/src/security/policy.rs
  • clients/agent-runtime/src/config/schema.rs
clients/agent-runtime/**/*.rs

📄 CodeRabbit inference engine (clients/agent-runtime/AGENTS.md)

Run cargo fmt --all -- --check, cargo clippy --all-targets -- -D warnings, and cargo test for code validation, or document which checks were skipped and why

Files:

  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/capabilities/registry.rs
  • clients/agent-runtime/src/security/policy.rs
  • clients/agent-runtime/src/config/schema.rs
**/*.rs

⚙️ CodeRabbit configuration file

**/*.rs: Focus on Rust idioms, memory safety, and ownership/borrowing correctness.
Flag unnecessary clones, unchecked panics in production paths, and weak error context.
Prioritize unsafe blocks, FFI boundaries, concurrency races, and secret handling.

Files:

  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/capabilities/registry.rs
  • clients/agent-runtime/src/security/policy.rs
  • clients/agent-runtime/src/config/schema.rs
clients/agent-runtime/src/{security,gateway,tools}/**/*.rs

📄 CodeRabbit inference engine (clients/agent-runtime/AGENTS.md)

Treat src/security/, src/gateway/, src/tools/ as high-risk surfaces and never broaden filesystem/network execution scope without explicit policy checks

Files:

  • clients/agent-runtime/src/security/policy.rs
clients/agent-runtime/src/{security,gateway,tools,config}/**/*.rs

📄 CodeRabbit inference engine (clients/agent-runtime/AGENTS.md)

Do not silently weaken security policy or access constraints; keep default behavior secure-by-default with deny-by-default where applicable

Files:

  • clients/agent-runtime/src/security/policy.rs
  • clients/agent-runtime/src/config/schema.rs
🧠 Learnings (9)
📓 Common learnings
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/{security,gateway,tools,config}/**/*.rs : Do not silently weaken security policy or access constraints; keep default behavior secure-by-default with deny-by-default where applicable
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/**/*.rs : Run `cargo fmt --all -- --check`, `cargo clippy --all-targets -- -D warnings`, and `cargo test` for code validation, or document which checks were skipped and why
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/{security,gateway,tools}/**/*.rs : Treat `src/security/`, `src/gateway/`, `src/tools/` as high-risk surfaces and never broaden filesystem/network execution scope without explicit policy checks
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/tools/**/*.rs : Implement `Tool` trait in `src/tools/` with strict parameter schema, validate and sanitize all inputs, and return structured `ToolResult` without panics in runtime path

Applied to files:

  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/capabilities/registry.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/main.rs : Preserve CLI contract unless change is intentional and documented; prefer explicit errors over silent fallback for unsupported critical paths

Applied to files:

  • clients/agent-runtime/src/agent/agent.rs
  • scripts/release-contract.test.mjs
  • clients/agent-runtime/src/capabilities/registry.rs
  • clients/agent-runtime/src/security/policy.rs
  • clients/agent-runtime/src/config/schema.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/main.rs : Keep startup path lean and avoid heavy initialization in command parsing flow

Applied to files:

  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/security/policy.rs
  • clients/agent-runtime/src/config/schema.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/{security,gateway,tools}/**/*.rs : Treat `src/security/`, `src/gateway/`, `src/tools/` as high-risk surfaces and never broaden filesystem/network execution scope without explicit policy checks

Applied to files:

  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/security/policy.rs
  • clients/agent-runtime/src/config/schema.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/**/*.rs : Avoid unnecessary allocations, clones, and blocking operations to maintain performance and efficiency

Applied to files:

  • clients/agent-runtime/src/agent/agent.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/**/*.rs : Run `cargo fmt --all -- --check`, `cargo clippy --all-targets -- -D warnings`, and `cargo test` for code validation, or document which checks were skipped and why

Applied to files:

  • clients/agent-runtime/src/agent/agent.rs
  • scripts/release-contract.test.mjs
  • clients/agent-runtime/src/capabilities/registry.rs
  • clients/agent-runtime/src/config/schema.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/{security,gateway,tools,config}/**/*.rs : Do not silently weaken security policy or access constraints; keep default behavior secure-by-default with deny-by-default where applicable

Applied to files:

  • clients/agent-runtime/src/agent/agent.rs
  • scripts/release-contract.test.mjs
  • clients/agent-runtime/src/capabilities/registry.rs
  • clients/agent-runtime/src/security/policy.rs
  • clients/agent-runtime/src/config/schema.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/**/Cargo.toml : Preserve release-size profile assumptions in `Cargo.toml` and avoid adding heavy dependencies unless clearly justified

Applied to files:

  • scripts/release-contract.test.mjs
🪛 Shellcheck (0.11.0)
gradle/configs/git/hooks/pre-push.sh

[info] 93-93: Double quote to prevent globbing and word splitting.

(SC2086)

🔇 Additional comments (20)
clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/runtime/MobileRuntimeCoordinator.kt (3)

191-196: Message ID generation remains correct after wrapper removal.

Using computeNextMessageId(state.messages.size) here preserves monotonic user-message IDs and keeps behavior stable.


232-237: Assistant event deduplication preserves ordering and ID continuity.

Consolidating AssistantChunk/AssistantMessage into a shared builder keeps message creation consistent, and the failure path uses the same offset basis for contiguous IDs.

Also applies to: 243-246


255-260: Good extraction to file scope; class-level complexity pressure is reduced.

Keeping assistantChatMessage top-level preserves behavior while avoiding extra class-level function count in MobileRuntimeCoordinator.

clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatWorkspace.kt (2)

169-176: Stale callback routing is fixed here.

Including onSendMessage in the remember(...) keys keeps actions.onSend aligned with the current parent handler. Nice catch.


227-289: Good complexity reduction without state drift.

WorkspaceBody keeps the config/chat branch local and narrows the remembered ChatPanelState inputs to what ChatPanel actually consumes.

clients/agent-runtime/src/capabilities/registry.rs (2)

57-186: Validation refactor keeps the contract tight.

Nice split: the helpers keep the descriptor checks fail-closed, and the trimmed compatibility/MCP validation closes the whitespace boundary hole without weakening accepted inputs.

Based on learnings "Do not silently weaken security policy or access constraints; keep default behavior secure-by-default with deny-by-default where applicable."


301-358: Good regression coverage for the extracted branches.

These tests pin the whitespace, schema-shape, and MCP metadata failures that were moved into helpers, which lowers the refactor risk.

As per coding guidelines **/*: "Look for behavioral regressions, missing tests, and contract breaks across modules."

clients/web/apps/dashboard/src/components/memory/MemoryList.vue (1)

308-310: Destructive color usage is now consistently applied across states.

Good update: Line 308, Line 317, and Line 393-394 now align destructive border/hover/confirm styles to the same color, reducing split visual states.

Also applies to: 317-317, 393-394

clients/web/apps/dashboard/src/App.vue (1)

251-281: Live-region semantic cleanup looks good.

Switching these status messages away from <output> keeps the announcements intact without implying form-calculated output.

scripts/release-contract.test.mjs (2)

216-223: Good CI/local split for cargo resolution failure.

Failing in CI while allowing local t.skip(...) prevents silent contract regressions in protected pipelines.


146-153: Workflow governance assertions are meaningfully hardened.

The explicit permission checks plus secrets: inherit rejection are solid guardrails for release workflow security posture.

Also applies to: 163-165, 171-172, 178-180, 185-185

clients/agent-runtime/src/config/schema.rs (1)

3833-3888: Helper extraction keeps load/save secret handling aligned.

load_existing_config() plus decrypt_config_secrets() still covers the same secret-bearing fields that save() encrypts, which makes this refactor low-risk from a config-compatibility standpoint.

clients/agent-runtime/src/security/policy.rs (3)

248-276: Nice fix for the fork-bomb classification blind spot.

Running the raw snippet check before normalization preserves High classification for exact :(){ :|:& };: payloads without weakening the later segment-based checks.


619-706: Helper extraction keeps the risk policy readable without relaxing it.

Splitting base-command, snippet, and medium-risk matching into dedicated helpers makes this path easier to audit while preserving the existing deny-first behavior.


1251-1259: Good regression coverage for the fork-bomb case.

This test directly locks in both sides of the contract: command_risk_level() stays High, and is_command_allowed() still rejects the payload.

clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatComponents.kt (2)

62-70: Nice refactor: palette extraction reduced branching and improved cohesion.

This is a clean maintainability win; ChatBubbleBody/ChatBubbleHeader now receive focused color inputs instead of re-deriving theme conditionals.

Also applies to: 165-166, 196-240


53-54: Good accessibility consistency improvement.

Using a constant for the settings icon description avoids duplicated literals and keeps accessibility text centralized.

Also applies to: 320-320

clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatBridgeCopy.kt (1)

3-5: Centralizing onboarding/bridge copy in one file is a solid maintainability improvement.

The enum mapping structure is clear and keeps UI copy logic easier to reason about.

Also applies to: 6-61

gradle/configs/git/hooks/pre-push.sh (1)

38-38: Good explicit default case.

Line 38’s *) : ;; makes unmatched paths intentional and keeps the case behavior explicit.

clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/onboarding/OnboardingScreen.kt (1)

163-184: Nice API refactor.

The state / actions split is cohesive, and the only call site in clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/App.kt:112-128 already sources both from runtimeOnboardingStep, so this preserves the current onboarding flow.

Comment thread clients/web/apps/dashboard/src/composables/useChat.ts
Comment thread clients/web/apps/dashboard/src/App.vue Outdated
Comment thread clients/web/apps/dashboard/src/components/memory/MemoryList.vue Outdated
Comment thread gradle/configs/git/hooks/pre-push.sh Outdated
Comment thread scripts/release-contract.test.mjs
@yacosta738 yacosta738 force-pushed the feature/dallay-251-recurring-monthly-code-quality-review-sonarqube branch from ec30eca to 181d6e6 Compare April 10, 2026 14:28
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 14

Caution

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

⚠️ Outside diff range comments (4)
clients/web/apps/dashboard/src/composables/useChat.ts (1)

101-127: ⚠️ Potential issue | 🟠 Major

Don’t let tool/reason override the real approval discriminator.

parseApprovalErrorType() now returns top-level tool/reason before it inspects error.code / error.type. A mixed 403 payload like { tool, reason, error: { code: "approval_required" } } will now be misclassified and fall through to throwCredentialInvalid(), which clears a valid session on an approval response.

Suggested fix
   if (typeof response.type === "string" && response.type.trim()) {
     return response.type.trim();
   }
-  if (typeof response.tool === "string" && response.tool.trim()) {
-    return response.tool.trim();
-  }
-  if (typeof response.reason === "string" && response.reason.trim()) {
-    return response.reason.trim();
-  }

   if (typeof response.error === "string" && response.error.trim()) {
     return response.error.trim();
   }

   if (response.error && typeof response.error === "object") {
     if (typeof response.error.code === "string" && response.error.code.trim()) {
       return response.error.code.trim();
     }
     if (typeof response.error.type === "string" && response.error.type.trim()) {
       return response.error.type.trim();
     }
   }
+
+  if (typeof response.tool === "string" && response.tool.trim()) {
+    return response.tool.trim();
+  }
+  if (typeof response.reason === "string" && response.reason.trim()) {
+    return response.reason.trim();
+  }

As per coding guidelines, "Security first, performance second. Validate input boundaries, auth/authz implications, and secret management."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/web/apps/dashboard/src/composables/useChat.ts` around lines 101 -
127, The parsing currently lets top-level tool/reason override nested error
discriminators; update parseApprovalErrorType to check response.error.code and
response.error.type (and top-level response.code/response.type) before
considering response.tool or response.reason so that nested approval markers
like response.error.code === "approval_required" take precedence and avoid
calling throwCredentialInvalid; keep existing checks for numeric/trimmed strings
and preserve the later fallback to response.error.message or response.error
string only after inspecting nested error fields.
clients/agent-runtime/src/security/policy.rs (1)

247-276: ⚠️ Potential issue | 🔴 Critical

Standalone & chains bypass command policy checks entirely — promote & detection to command_risk_level.

The issue is critical: command_risk_level("ls & echo ok") returns Low because it does not check for single-& chains, and the shell execution path never invokes is_command_allowed (which would block them). This means an unsandboxed command like ls & whoami executes both commands without any policy enforcement.

The flow is:

  1. Shell execution calls validate_command_execution() (line 168 in shell.rs)
  2. That function calls only command_risk_level(), not is_command_allowed()
  3. command_risk_level() lacks the contains_single_ampersand() check
  4. Command proceeds to spawn with no & validation

Add the contains_single_ampersand(command) check to command_risk_level() to mark chains as High risk, ensuring the requires_approval gate blocks them before reaching spawn.

Suggested fix
 pub fn command_risk_level(&self, command: &str) -> CommandRiskLevel {
+    if contains_single_ampersand(command) {
+        return CommandRiskLevel::High;
+    }
+
     if contains_high_risk_snippet(&command.to_ascii_lowercase()) {
         return CommandRiskLevel::High;
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/agent-runtime/src/security/policy.rs` around lines 247 - 276,
command_risk_level currently misses single-ampersand chains, so add a check at
the start of command_risk_level (before normalize_risk_segments is used) that
calls contains_single_ampersand(command) and returns CommandRiskLevel::High if
true; use the original command string (or its lowercase) for the check so
validate_command_execution (which relies only on command_risk_level) will flag
these cases and prevent bypassing is_command_allowed/spawn paths.
clients/web/apps/dashboard/src/App.vue (1)

593-619: ⚠️ Potential issue | 🟠 Major

Add keyboard roving logic to the nested tablists.

These buttons now use role="tab" with inactive tabs forced to tabindex="-1", but only the top-level dashboard tabs got arrow/Home/End handlers. In the memory backend and local-memory subview tablists, keyboard users can focus the active tab and then have no way to move to the inactive one. Reuse the same roving-keyboard handler pattern here, or keep all tabs tabbable until that logic exists.

As per coding guidelines, "Ensure accessibility (A11y) and proper use of Tailwind CSS classes."

Also applies to: 630-657

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/web/apps/dashboard/src/App.vue` around lines 593 - 619, The nested
tablists for memory backends (the element with class "memory-mode-tabs" and its
buttons with ids "memory-mode-tab-local" and "memory-mode-tab-cerebro") lack the
roving keyboard handlers used by the top-level dashboard tabs, so keyboard users
cannot move focus between inactive tabs; either wire up the same roving-keyboard
handlers (arrow keys + Home/End) used by the top-level tab implementation to the
memoryMode tablist and its buttons (and ensure the handler updates memoryMode
and selectedCerebroResult where appropriate), or remove the tabindex="-1" logic
and keep all memory tab buttons tabbable until you add the roving-keyboard
logic; apply the same fix to the nested local-memory subview tablist referenced
in the comment (lines ~630-657).
scripts/release-contract.test.mjs (1)

173-212: 🛠️ Refactor suggestion | 🟠 Major

Assert the full reusable-workflow secret contract, not just the endpoints.

These checks only require SIGNING_IN_MEMORY_KEY and DOCKERHUB_TOKEN. If a middle mapping like NPM_TOKEN or MAVEN_CENTRAL_PASSWORD is dropped, the test still passes even though ./.github/workflows/_publish.yml exposes all 8 secret inputs and the current callers forward all 8. Tighten the contract by asserting every expected secret key in each caller.

Suggested tightening
   assertIncludesAll(
     publishRelease,
     [
       /on:\s*release:\s*types:\s*- published/s,
       /Canonical stable release handoff/i,
       /release: true/,
       /release_tag: \$\{\{ github\.event\.release\.tag_name \}\}/,
       /release_id: \$\{\{ github\.event\.release\.id \}\}/,
       /attach artifacts to the existing canonical GitHub Release/i,
       /permissions:\s+contents: write\s+packages: write/s,
       /secrets:\s+SIGNING_IN_MEMORY_KEY:/,
+      /SIGNING_IN_MEMORY_KEY_PASSWORD:/,
+      /MAVEN_CENTRAL_USERNAME:/,
+      /MAVEN_CENTRAL_PASSWORD:/,
+      /CARGO_REGISTRY_TOKEN:/,
+      /NPM_TOKEN:/,
+      /DOCKERHUB_USERNAME:/,
       /DOCKERHUB_TOKEN:/,
     ],
     "publish-release workflow",
   );
@@
   assertIncludesAll(
     publishSnapshot,
     [
       /Snapshots stay outside stable GitHub Release ownership/,
       /release: false/,
       /permissions:\s+contents: read\s+packages: write/s,
       /secrets:\s+SIGNING_IN_MEMORY_KEY:/,
+      /SIGNING_IN_MEMORY_KEY_PASSWORD:/,
+      /MAVEN_CENTRAL_USERNAME:/,
+      /MAVEN_CENTRAL_PASSWORD:/,
+      /CARGO_REGISTRY_TOKEN:/,
+      /NPM_TOKEN:/,
+      /DOCKERHUB_USERNAME:/,
       /DOCKERHUB_TOKEN:/,
     ],
     "publish-snapshot workflow",
   );
As per coding guidelines: "Security first, performance second. Validate input boundaries, auth/authz implications, and secret management. Look for behavioral regressions, missing tests, and contract breaks across modules."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/release-contract.test.mjs` around lines 173 - 212, The test currently
only checks for SIGNING_IN_MEMORY_KEY and DOCKERHUB_TOKEN in
publishRelease/publishSnapshot but must assert the full reusable-workflow secret
contract; update the assertions that exercise the publish workflow outputs
(variables publishRelease and publishSnapshot, and similar releasePlease checks
if relevant) to include regex assertions for every secret input defined in
./github/workflows/_publish.yml (all 8 secret names such as NPM_TOKEN,
MAVEN_CENTRAL_PASSWORD, etc.), using assertIncludesAll (or equivalent) with
/secrets:\s+<SECRET_NAME>:/ regexes so each caller is verified to forward every
expected secret key.
♻️ Duplicate comments (1)
gradle/configs/git/hooks/pre-push.sh (1)

98-98: ⚠️ Potential issue | 🟠 Major

Add -- before forwarded doc paths in lychee invocation.

At Line 98, "$@" is forwarded without an end-of-options delimiter. A doc filename starting with - can be parsed as a CLI flag instead of a path.

Suggested fix
-            lychee --config "lychee.toml" --offline --no-progress "$@" || true
+            lychee --config "lychee.toml" --offline --no-progress -- "$@" || true
Does the current lychee CLI support `--` as an end-of-options delimiter so paths beginning with `-` are treated as positional file inputs?

As per coding guidelines, "Security first, performance second. Validate input boundaries, auth/authz implications, and secret management."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@gradle/configs/git/hooks/pre-push.sh` at line 98, Update the lychee
invocation in pre-push.sh (the line calling lychee --config "lychee.toml"
--offline --no-progress "$@") to insert an end-of-options delimiter before
forwarding positional args (i.e., place -- immediately before "$@") so any doc
paths beginning with '-' are treated as filenames; verify the lychee CLI accepts
`--` as an end-of-options marker after the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@clients/agent-runtime/src/agent/agent.rs`:
- Around line 789-799: When audit logging via log_shell_audit_event(call,
result, duration) fails, the current branch builds the returned
ToolExecutionResult.output from result.output only and can hide the original
shell failure stored in result.error; update the error-handling branch that
constructs the ToolExecutionResult so it preserves the original shell failure
details by including result.error (when present) alongside result.output (e.g.,
append or merge the original error text into the output) and still append the
"[AUDIT ERROR: ...]" text, and keep other original fields (success,
tool_call_id) intact; adjust the DispatchAction::ApprovalRequired payload to
reference both the audit error and the preserved original error information so
callers can see the true shell failure while noting the audit logging failure.
- Around line 754-771: The Err branch for tool.execute(...) currently formats an
error and returns without running the shell audit logic, so shell failures skip
log_shell_audit_event and related finalization; update the Err(error) arm in
agent.rs to mirror the Ok->handle_tool_result path by calling the same
audit/finalize flow (e.g., invoke log_shell_audit_event or call
finalize_tool_execution with the error output, success=false and proper action)
and return a ToolExecutionResult constructed from that finalized data so shell
invocation errors are audited just like successful tool results; reference
tool.execute, handle_tool_result, log_shell_audit_event,
finalize_tool_execution, and ToolExecutionResult (and check
clients/agent-runtime/src/tools/shell.rs for error payload shape) when applying
the change.

In `@clients/agent-runtime/src/capabilities/registry.rs`:
- Around line 327-358: Update the test rejects_missing_mcp_metadata_requirements
to assert the specific CapabilityError variant/field instead of matching on the
error display string: call
CapabilityRegistry::validate_descriptor(&descriptor).unwrap_err() and use
matches! or an exact equality check against
CapabilityError::MissingField("metadata.mcp".into()) (and similarly for
CapabilityError::MissingField("metadata.mcp.server".into()) and
CapabilityError::MissingField("metadata.mcp.resource_uri".into())) so the test
pins the exact variant and field name produced by
CapabilityRegistry::validate_descriptor.
- Around line 301-312: The test rejects_whitespace_only_compatibility_entries
currently only covers compatibility.runtime_contracts; add the same
whitespace-only regression case for compatibility.entrypoint_parity_scope so the
new helper's validation of both lists is exercised. Modify the test to set
descriptor.compatibility.entrypoint_parity_scope = vec!["   ".to_string()] (or
create a separate assertion) and call
CapabilityRegistry::validate_descriptor(&descriptor).unwrap_err(), then assert
the returned CapabilityError::MissingField and that error.to_string() contains
"compatibility.entrypoint_parity_scope" to lock behavior after the refactor.

In `@clients/agent-runtime/src/channels/cli.rs`:
- Around line 237-273: The function read_audio_bytes currently opens the file
before verifying it's a regular file, which can block on FIFOs/devices; change
the order in read_audio_bytes to call tokio::fs::metadata(path).await first,
validate metadata.file_type().is_file() (and print "Not a regular file: {path}"
and return None if not), then open the file with
tokio::fs::File::open(path).await and continue with the existing size check and
read logic (using self.audio_config.max_audio_bytes, AsyncReadExt::take, and
read_to_end) so the listener won't hang on special file types.

In `@clients/agent-runtime/src/config/schema.rs`:
- Around line 3834-3889: Add a regression test that exercises the load-path
roundtrip for centralized secret decryption: construct a Config with plaintext
values for all nested secret fields referenced in decrypt_config_secrets
(Config.api_key, composio.api_key, browser.computer_use.api_key,
web_search.brave_api_key, memory.cerebro.auth_token, each agent.api_key, and
reliability.account_pools.*.accounts[].api_key), write it via the existing
save/write path so secrets are encrypted, then call Config::load_or_init() or
load_existing_config(...) (using the same corvus_dir/workspace_dir and enabling
encryption) to reload and assert each secret is returned as the original
plaintext; place the test to reference decrypt_config_secrets and
load_existing_config to ensure any missed fields will fail the roundtrip.

In `@clients/agent-runtime/src/gateway/admin.rs`:
- Around line 771-772: Introduce a single constant (e.g., DEFAULT_WEBHOOK_PORT)
and replace the literal 3000 occurrences with it so the default webhook port is
centralized; update the port fallback in the view generation (the expression
using webhook.map(|value| value.port).unwrap_or(3000)), any restart-check logic
that currently uses 3000, and the default config helper(s) that construct
webhook defaults to reference DEFAULT_WEBHOOK_PORT instead of the hard-coded
value.

In `@clients/agent-runtime/src/main.rs`:
- Around line 916-954: Both dispatch_agent_command and dispatch_code_command
unnecessarily allocate pinned boxes for futures before immediately .await-ing
them; remove the Box::pin(...) wrappers and call handle_agent_command(...) and
handle_code_command(...) directly and await those returned futures instead,
i.e., replace Box::pin(handle_agent_command(...)).await with
handle_agent_command(...).await and similarly for handle_code_command to avoid
the extra heap allocation and pinning.

In `@clients/agent-runtime/src/search/discovery.rs`:
- Around line 267-272: The workspace canonicalization logic is duplicated;
update validate_search_root to call the existing helper
workspace_root_for(&security) instead of repeating
security.workspace_dir.canonicalize().unwrap_or_else(|_|
security.workspace_dir.clone()), ensuring both functions use the same PathBuf
resolution behavior and keep only the canonicalization/ fallback logic inside
workspace_root_for.

In
`@clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatComponents.kt`:
- Line 53: Replace the hardcoded English constant SETTINGS_CONTENT_DESCRIPTION
with an i18n-ready string resource: remove the private const val
SETTINGS_CONTENT_DESCRIPTION and instead load the label from shared/localized
resources where used (e.g., use stringResource("settings") or your project's
shared resource accessor in the composable or view where
SETTINGS_CONTENT_DESCRIPTION was referenced), update all usages (including the
other occurrence noted) to fetch the localized string at runtime, and add the
"settings" key and translations to the shared string resources so accessibility
labels are localized across platforms.

In `@clients/web/apps/dashboard/src/components/config/CostOverview.vue`:
- Around line 113-115: The helper refreshGovernance currently swallows all
errors by calling governance.reload().catch(() => undefined); update it to not
mask failures: either return the promise so callers/tests can observe rejections
(e.g., remove the .catch and let governance.reload() propagate), or explicitly
handle/log the error instead of discarding it (call
governance.reload().catch(err => processLogger.error('governance.reload failed',
err)) or rethrow after logging). Modify the refreshGovernance function
accordingly so failures from governance.reload() are visible to
tests/diagnostics.

In `@clients/web/apps/dashboard/src/composables/useChat.spec.ts`:
- Around line 416-465: Add a new test in useChat.spec.ts that covers the
mixed-shape approval payload where the response contains top-level fields (tool,
reason) but the approval indicator is inside error.code (e.g. { tool:
"shell_exec", reason: "x", error: { code: "approval_required" }, session_id }).
Use the same pattern as the existing tests: mock crypto.randomUUID, create a
ready gateway and chat, call chat.createSession(), mock fetchMock to return a
403 JSON Response with that mixed shape, and assert that chat.sendMessage(...)
resolves to the unified approval_required shape (type: "approval_required",
tool, reason, sessionId matching the mocked UUID) to catch the auth/approval
precedence regression.

In `@clients/web/apps/dashboard/src/composables/useChat.ts`:
- Around line 560-568: The SSE parser in processLine only matches "event: " and
"data: " (with a space) so frames like "event:chunk" or "data:{"x":1}" are
ignored; update processLine to split at the first ':' (use line.indexOf(':')),
extract the field = line.slice(0, idx).trim() and the value = line.slice(idx+1)
then trim only a single leading space (or use value = value.startsWith(' ') ?
value.slice(1) : value) before handling; keep the existing branches that set
StreamEventState.currentEvent and append to StreamEventState.currentData when
field === 'event' or 'data' respectively so both "event:data" and "event: data"
formats are accepted.

In `@scripts/release-contract.test.mjs`:
- Around line 47-82: The test currently calls resolveExecutable("cargo") which
will miss Windows executables named "cargo.exe"; update the test so
cargoExecutable is resolved in a platform-aware way by deriving executableName
from process.platform (e.g., "cargo.exe" on win32, "cargo" elsewhere) before
calling resolveExecutable, or alternatively enhance
resolveExecutable/trustedExecutableDirs to also probe platform-specific names
(e.g., try both "cargo" and "cargo.exe" or include Windows cargo install dirs);
reference resolveExecutable, trustedExecutableDirs and cargoExecutable when
making the change.

---

Outside diff comments:
In `@clients/agent-runtime/src/security/policy.rs`:
- Around line 247-276: command_risk_level currently misses single-ampersand
chains, so add a check at the start of command_risk_level (before
normalize_risk_segments is used) that calls contains_single_ampersand(command)
and returns CommandRiskLevel::High if true; use the original command string (or
its lowercase) for the check so validate_command_execution (which relies only on
command_risk_level) will flag these cases and prevent bypassing
is_command_allowed/spawn paths.

In `@clients/web/apps/dashboard/src/App.vue`:
- Around line 593-619: The nested tablists for memory backends (the element with
class "memory-mode-tabs" and its buttons with ids "memory-mode-tab-local" and
"memory-mode-tab-cerebro") lack the roving keyboard handlers used by the
top-level dashboard tabs, so keyboard users cannot move focus between inactive
tabs; either wire up the same roving-keyboard handlers (arrow keys + Home/End)
used by the top-level tab implementation to the memoryMode tablist and its
buttons (and ensure the handler updates memoryMode and selectedCerebroResult
where appropriate), or remove the tabindex="-1" logic and keep all memory tab
buttons tabbable until you add the roving-keyboard logic; apply the same fix to
the nested local-memory subview tablist referenced in the comment (lines
~630-657).

In `@clients/web/apps/dashboard/src/composables/useChat.ts`:
- Around line 101-127: The parsing currently lets top-level tool/reason override
nested error discriminators; update parseApprovalErrorType to check
response.error.code and response.error.type (and top-level
response.code/response.type) before considering response.tool or response.reason
so that nested approval markers like response.error.code === "approval_required"
take precedence and avoid calling throwCredentialInvalid; keep existing checks
for numeric/trimmed strings and preserve the later fallback to
response.error.message or response.error string only after inspecting nested
error fields.

In `@scripts/release-contract.test.mjs`:
- Around line 173-212: The test currently only checks for SIGNING_IN_MEMORY_KEY
and DOCKERHUB_TOKEN in publishRelease/publishSnapshot but must assert the full
reusable-workflow secret contract; update the assertions that exercise the
publish workflow outputs (variables publishRelease and publishSnapshot, and
similar releasePlease checks if relevant) to include regex assertions for every
secret input defined in ./github/workflows/_publish.yml (all 8 secret names such
as NPM_TOKEN, MAVEN_CENTRAL_PASSWORD, etc.), using assertIncludesAll (or
equivalent) with /secrets:\s+<SECRET_NAME>:/ regexes so each caller is verified
to forward every expected secret key.

---

Duplicate comments:
In `@gradle/configs/git/hooks/pre-push.sh`:
- Line 98: Update the lychee invocation in pre-push.sh (the line calling lychee
--config "lychee.toml" --offline --no-progress "$@") to insert an end-of-options
delimiter before forwarding positional args (i.e., place -- immediately before
"$@") so any doc paths beginning with '-' are treated as filenames; verify the
lychee CLI accepts `--` as an end-of-options marker after the change.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: eb364031-589c-449e-ae0d-b3b8be170a3e

📥 Commits

Reviewing files that changed from the base of the PR and between ec30eca and 181d6e6.

📒 Files selected for processing (46)
  • .github/workflows/publish-release.yml
  • .github/workflows/publish-snapshot.yml
  • .github/workflows/release-please.yml
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/capabilities/registry.rs
  • clients/agent-runtime/src/channels/cli.rs
  • clients/agent-runtime/src/channels/mod.rs
  • clients/agent-runtime/src/config/schema.rs
  • clients/agent-runtime/src/gateway/admin.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/search/discovery.rs
  • clients/agent-runtime/src/search/tests.rs
  • clients/agent-runtime/src/security/detect.rs
  • clients/agent-runtime/src/security/policy.rs
  • clients/agent-runtime/src/tools/shell.rs
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/App.kt
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/runtime/MobileRuntimeCoordinator.kt
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatBridgeCopy.kt
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatComponents.kt
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatWorkspace.kt
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/onboarding/OnboardingScreen.kt
  • clients/composeApp/src/iosMain/kotlin/com/profiletailors/corvus/runtime/IosRuntimeBridge.kt
  • clients/web/apps/dashboard/src/App.vue
  • clients/web/apps/dashboard/src/components/config/ChannelsOverview.vue
  • clients/web/apps/dashboard/src/components/config/CostOverview.vue
  • clients/web/apps/dashboard/src/components/config/HealthDashboard.vue
  • clients/web/apps/dashboard/src/components/config/HeartbeatOverview.vue
  • clients/web/apps/dashboard/src/components/config/McpOverview.vue
  • clients/web/apps/dashboard/src/components/config/ReliabilityOverview.vue
  • clients/web/apps/dashboard/src/components/config/SchedulerStatus.vue
  • clients/web/apps/dashboard/src/components/config/TunnelOverview.vue
  • clients/web/apps/dashboard/src/components/config/UpdateSettings.vue
  • clients/web/apps/dashboard/src/components/config/WebSearchSettings.vue
  • clients/web/apps/dashboard/src/components/memory/CerebroSearchPanel.vue
  • clients/web/apps/dashboard/src/components/memory/LocalMemoryExplorerPanel.vue
  • clients/web/apps/dashboard/src/components/memory/MemoryList.vue
  • clients/web/apps/dashboard/src/components/memory/MemoryStats.vue
  • clients/web/apps/dashboard/src/components/sessions/SessionDetail.vue
  • clients/web/apps/dashboard/src/components/sessions/SessionList.vue
  • clients/web/apps/dashboard/src/composables/useAdmin.ts
  • clients/web/apps/dashboard/src/composables/useChat.spec.ts
  • clients/web/apps/dashboard/src/composables/useChat.ts
  • clients/web/apps/dashboard/src/types/admin-sessions.ts
  • gradle/configs/git/hooks/pre-push.sh
  • scripts/release-contract.test.mjs
💤 Files with no reviewable changes (1)
  • clients/web/apps/dashboard/src/components/memory/CerebroSearchPanel.vue
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: report / Contributor Quality Report
  • GitHub Check: pr-checks
  • GitHub Check: Scan
  • GitHub Check: sonar
  • GitHub Check: core-checks
  • GitHub Check: Cloudflare Pages
🧰 Additional context used
📓 Path-based instructions (11)
**/*

⚙️ CodeRabbit configuration file

**/*: Security first, performance second.
Validate input boundaries, auth/authz implications, and secret management.
Look for behavioral regressions, missing tests, and contract breaks across modules.

Files:

  • clients/web/apps/dashboard/src/composables/useAdmin.ts
  • clients/web/apps/dashboard/src/components/sessions/SessionDetail.vue
  • clients/agent-runtime/src/search/tests.rs
  • clients/web/apps/dashboard/src/components/config/SchedulerStatus.vue
  • clients/web/apps/dashboard/src/components/config/HealthDashboard.vue
  • clients/web/apps/dashboard/src/components/config/HeartbeatOverview.vue
  • clients/web/apps/dashboard/src/components/config/ChannelsOverview.vue
  • clients/web/apps/dashboard/src/components/config/CostOverview.vue
  • clients/web/apps/dashboard/src/components/memory/LocalMemoryExplorerPanel.vue
  • clients/web/apps/dashboard/src/components/config/ReliabilityOverview.vue
  • clients/web/apps/dashboard/src/components/sessions/SessionList.vue
  • clients/web/apps/dashboard/src/components/memory/MemoryStats.vue
  • clients/web/apps/dashboard/src/components/config/McpOverview.vue
  • clients/web/apps/dashboard/src/components/config/WebSearchSettings.vue
  • clients/agent-runtime/src/security/detect.rs
  • clients/web/apps/dashboard/src/components/memory/MemoryList.vue
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/runtime/MobileRuntimeCoordinator.kt
  • clients/agent-runtime/src/tools/shell.rs
  • clients/web/apps/dashboard/src/components/config/UpdateSettings.vue
  • gradle/configs/git/hooks/pre-push.sh
  • clients/composeApp/src/iosMain/kotlin/com/profiletailors/corvus/runtime/IosRuntimeBridge.kt
  • clients/agent-runtime/src/main.rs
  • clients/web/apps/dashboard/src/types/admin-sessions.ts
  • scripts/release-contract.test.mjs
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatComponents.kt
  • clients/web/apps/dashboard/src/composables/useChat.spec.ts
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/search/discovery.rs
  • clients/web/apps/dashboard/src/composables/useChat.ts
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/App.kt
  • clients/web/apps/dashboard/src/components/config/TunnelOverview.vue
  • clients/agent-runtime/src/capabilities/registry.rs
  • clients/agent-runtime/src/channels/mod.rs
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatBridgeCopy.kt
  • clients/web/apps/dashboard/src/App.vue
  • clients/agent-runtime/src/config/schema.rs
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatWorkspace.kt
  • clients/agent-runtime/src/gateway/admin.rs
  • clients/agent-runtime/src/agent/agent.rs
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/onboarding/OnboardingScreen.kt
  • clients/agent-runtime/src/channels/cli.rs
  • clients/agent-runtime/src/security/policy.rs
**/*.vue

⚙️ CodeRabbit configuration file

**/*.vue: Enforce Vue 3 Composition API with <script setup>.
Ensure accessibility (A11y) and proper use of Tailwind CSS classes.
Check for proper prop validation and emitted events documentation.

Files:

  • clients/web/apps/dashboard/src/components/sessions/SessionDetail.vue
  • clients/web/apps/dashboard/src/components/config/SchedulerStatus.vue
  • clients/web/apps/dashboard/src/components/config/HealthDashboard.vue
  • clients/web/apps/dashboard/src/components/config/HeartbeatOverview.vue
  • clients/web/apps/dashboard/src/components/config/ChannelsOverview.vue
  • clients/web/apps/dashboard/src/components/config/CostOverview.vue
  • clients/web/apps/dashboard/src/components/memory/LocalMemoryExplorerPanel.vue
  • clients/web/apps/dashboard/src/components/config/ReliabilityOverview.vue
  • clients/web/apps/dashboard/src/components/sessions/SessionList.vue
  • clients/web/apps/dashboard/src/components/memory/MemoryStats.vue
  • clients/web/apps/dashboard/src/components/config/McpOverview.vue
  • clients/web/apps/dashboard/src/components/config/WebSearchSettings.vue
  • clients/web/apps/dashboard/src/components/memory/MemoryList.vue
  • clients/web/apps/dashboard/src/components/config/UpdateSettings.vue
  • clients/web/apps/dashboard/src/components/config/TunnelOverview.vue
  • clients/web/apps/dashboard/src/App.vue
clients/agent-runtime/src/**/*.rs

📄 CodeRabbit inference engine (clients/agent-runtime/AGENTS.md)

clients/agent-runtime/src/**/*.rs: Never log secrets, tokens, raw credentials, or sensitive payloads in any logging statements
Avoid unnecessary allocations, clones, and blocking operations to maintain performance and efficiency

Files:

  • clients/agent-runtime/src/search/tests.rs
  • clients/agent-runtime/src/security/detect.rs
  • clients/agent-runtime/src/tools/shell.rs
  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/search/discovery.rs
  • clients/agent-runtime/src/capabilities/registry.rs
  • clients/agent-runtime/src/channels/mod.rs
  • clients/agent-runtime/src/config/schema.rs
  • clients/agent-runtime/src/gateway/admin.rs
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/channels/cli.rs
  • clients/agent-runtime/src/security/policy.rs
clients/agent-runtime/**/*.rs

📄 CodeRabbit inference engine (clients/agent-runtime/AGENTS.md)

Run cargo fmt --all -- --check, cargo clippy --all-targets -- -D warnings, and cargo test for code validation, or document which checks were skipped and why

Files:

  • clients/agent-runtime/src/search/tests.rs
  • clients/agent-runtime/src/security/detect.rs
  • clients/agent-runtime/src/tools/shell.rs
  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/search/discovery.rs
  • clients/agent-runtime/src/capabilities/registry.rs
  • clients/agent-runtime/src/channels/mod.rs
  • clients/agent-runtime/src/config/schema.rs
  • clients/agent-runtime/src/gateway/admin.rs
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/channels/cli.rs
  • clients/agent-runtime/src/security/policy.rs
**/*.rs

⚙️ CodeRabbit configuration file

**/*.rs: Focus on Rust idioms, memory safety, and ownership/borrowing correctness.
Flag unnecessary clones, unchecked panics in production paths, and weak error context.
Prioritize unsafe blocks, FFI boundaries, concurrency races, and secret handling.

Files:

  • clients/agent-runtime/src/search/tests.rs
  • clients/agent-runtime/src/security/detect.rs
  • clients/agent-runtime/src/tools/shell.rs
  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/search/discovery.rs
  • clients/agent-runtime/src/capabilities/registry.rs
  • clients/agent-runtime/src/channels/mod.rs
  • clients/agent-runtime/src/config/schema.rs
  • clients/agent-runtime/src/gateway/admin.rs
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/channels/cli.rs
  • clients/agent-runtime/src/security/policy.rs
clients/agent-runtime/src/{security,gateway,tools}/**/*.rs

📄 CodeRabbit inference engine (clients/agent-runtime/AGENTS.md)

Treat src/security/, src/gateway/, src/tools/ as high-risk surfaces and never broaden filesystem/network execution scope without explicit policy checks

Files:

  • clients/agent-runtime/src/security/detect.rs
  • clients/agent-runtime/src/tools/shell.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/gateway/admin.rs
  • clients/agent-runtime/src/security/policy.rs
clients/agent-runtime/src/{security,gateway,tools,config}/**/*.rs

📄 CodeRabbit inference engine (clients/agent-runtime/AGENTS.md)

Do not silently weaken security policy or access constraints; keep default behavior secure-by-default with deny-by-default where applicable

Files:

  • clients/agent-runtime/src/security/detect.rs
  • clients/agent-runtime/src/tools/shell.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/config/schema.rs
  • clients/agent-runtime/src/gateway/admin.rs
  • clients/agent-runtime/src/security/policy.rs
**/*.kt

⚙️ CodeRabbit configuration file

**/*.kt: Enforce null safety (no !!), structured concurrency, and non-blocking suspend code.
Prefer idiomatic Kotlin (expression bodies, sealed types, value classes when justified).
Verify tests follow TDD intent and use backtick test names where applicable.

Files:

  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/runtime/MobileRuntimeCoordinator.kt
  • clients/composeApp/src/iosMain/kotlin/com/profiletailors/corvus/runtime/IosRuntimeBridge.kt
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatComponents.kt
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/App.kt
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatBridgeCopy.kt
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatWorkspace.kt
  • clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/onboarding/OnboardingScreen.kt
clients/agent-runtime/src/tools/**/*.rs

📄 CodeRabbit inference engine (clients/agent-runtime/AGENTS.md)

Implement Tool trait in src/tools/ with strict parameter schema, validate and sanitize all inputs, and return structured ToolResult without panics in runtime path

Files:

  • clients/agent-runtime/src/tools/shell.rs
clients/agent-runtime/src/main.rs

📄 CodeRabbit inference engine (clients/agent-runtime/AGENTS.md)

clients/agent-runtime/src/main.rs: Preserve CLI contract unless change is intentional and documented; prefer explicit errors over silent fallback for unsupported critical paths
Keep startup path lean and avoid heavy initialization in command parsing flow

Files:

  • clients/agent-runtime/src/main.rs
clients/agent-runtime/src/channels/**/*.rs

📄 CodeRabbit inference engine (clients/agent-runtime/AGENTS.md)

Implement Channel trait in src/channels/ with consistent send, listen, and health_check semantics and cover auth/allowlist/health behavior with tests

Files:

  • clients/agent-runtime/src/channels/mod.rs
  • clients/agent-runtime/src/channels/cli.rs
🧠 Learnings (11)
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/main.rs : Preserve CLI contract unless change is intentional and documented; prefer explicit errors over silent fallback for unsupported critical paths

Applied to files:

  • clients/agent-runtime/src/search/tests.rs
  • clients/agent-runtime/src/security/detect.rs
  • clients/agent-runtime/src/tools/shell.rs
  • clients/agent-runtime/src/main.rs
  • scripts/release-contract.test.mjs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/search/discovery.rs
  • clients/agent-runtime/src/capabilities/registry.rs
  • clients/agent-runtime/src/channels/mod.rs
  • clients/agent-runtime/src/config/schema.rs
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/channels/cli.rs
  • clients/agent-runtime/src/security/policy.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/{security,gateway,tools,config}/**/*.rs : Do not silently weaken security policy or access constraints; keep default behavior secure-by-default with deny-by-default where applicable

Applied to files:

  • clients/agent-runtime/src/security/detect.rs
  • clients/agent-runtime/src/tools/shell.rs
  • clients/agent-runtime/src/main.rs
  • scripts/release-contract.test.mjs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/search/discovery.rs
  • clients/agent-runtime/src/capabilities/registry.rs
  • clients/agent-runtime/src/config/schema.rs
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/security/policy.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/{security,gateway,tools}/**/*.rs : Treat `src/security/`, `src/gateway/`, `src/tools/` as high-risk surfaces and never broaden filesystem/network execution scope without explicit policy checks

Applied to files:

  • clients/agent-runtime/src/security/detect.rs
  • clients/agent-runtime/src/tools/shell.rs
  • clients/agent-runtime/src/main.rs
  • scripts/release-contract.test.mjs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/search/discovery.rs
  • clients/agent-runtime/src/config/schema.rs
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/security/policy.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/tools/**/*.rs : Implement `Tool` trait in `src/tools/` with strict parameter schema, validate and sanitize all inputs, and return structured `ToolResult` without panics in runtime path

Applied to files:

  • clients/agent-runtime/src/security/detect.rs
  • clients/agent-runtime/src/tools/shell.rs
  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/capabilities/registry.rs
  • clients/agent-runtime/src/config/schema.rs
  • clients/agent-runtime/src/agent/agent.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/main.rs : Keep startup path lean and avoid heavy initialization in command parsing flow

Applied to files:

  • clients/agent-runtime/src/tools/shell.rs
  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/search/discovery.rs
  • clients/agent-runtime/src/channels/mod.rs
  • clients/agent-runtime/src/config/schema.rs
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/channels/cli.rs
  • clients/agent-runtime/src/security/policy.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/**/*.rs : Run `cargo fmt --all -- --check`, `cargo clippy --all-targets -- -D warnings`, and `cargo test` for code validation, or document which checks were skipped and why

Applied to files:

  • clients/agent-runtime/src/tools/shell.rs
  • clients/agent-runtime/src/main.rs
  • scripts/release-contract.test.mjs
  • clients/agent-runtime/src/search/discovery.rs
  • clients/agent-runtime/src/capabilities/registry.rs
  • clients/agent-runtime/src/config/schema.rs
  • clients/agent-runtime/src/agent/agent.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/**/*.rs : Avoid unnecessary allocations, clones, and blocking operations to maintain performance and efficiency

Applied to files:

  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/search/discovery.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/**/Cargo.toml : Do not add heavy dependencies for minor convenience; justify new crate additions

Applied to files:

  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/config/schema.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/channels/**/*.rs : Implement `Channel` trait in `src/channels/` with consistent `send`, `listen`, and `health_check` semantics and cover auth/allowlist/health behavior with tests

Applied to files:

  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/channels/mod.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/**/Cargo.toml : Preserve release-size profile assumptions in `Cargo.toml` and avoid adding heavy dependencies unless clearly justified

Applied to files:

  • scripts/release-contract.test.mjs
  • clients/agent-runtime/src/config/schema.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/providers/**/*.rs : Implement `Provider` trait in `src/providers/` and register in `src/providers/mod.rs` factory when adding a new provider

Applied to files:

  • clients/agent-runtime/src/capabilities/registry.rs
🪛 Shellcheck (0.11.0)
gradle/configs/git/hooks/pre-push.sh

[info] 92-92: Double quote to prevent globbing and word splitting.

(SC2086)

🔇 Additional comments (53)
clients/web/apps/dashboard/src/types/admin-sessions.ts (1)

123-123: Type normalization is safe and non-breaking.

Switching Array<unknown> to unknown[] is equivalent in TypeScript and does not change the API contract.

clients/web/apps/dashboard/src/composables/useAdmin.ts (1)

270-273: Good removal of unnecessary type assertion.

This keeps the same runtime behavior while improving compile-time safety by avoiding a potentially masking cast.

clients/web/apps/dashboard/src/components/config/WebSearchSettings.vue (2)

17-21: Set-based mode allowlist is a solid change.

This keeps the same accepted values and makes membership checks explicit and efficient.

As per coding guidelines, "Security first, performance second. Validate input boundaries, auth/authz implications, and secret management."


57-59: Mode guard still correctly prevents invalid updates.

The has(...) check preserves behavior by only calling updateSecretMode(...) for allowed modes.

As per coding guidelines, "Security first, performance second. Validate input boundaries, auth/authz implications, and secret management."

clients/agent-runtime/src/search/tests.rs (1)

445-448: LGTM: lock-error assertion is more robust across environments.

This keeps the lock-failure intent while reducing brittle message matching, and the fail-fast timing guard remains intact.

clients/web/apps/dashboard/src/components/memory/MemoryList.vue (2)

124-127: A11y live-region semantics look correct.

Good update: role="status"/"alert" + aria-live + aria-atomic="true" improves announcement reliability without changing behavior.

As per coding guidelines, **/*.vue: “Ensure accessibility (A11y) and proper use of Tailwind CSS classes.”


308-310: Destructive-state color usage is now consistent.

The delete button and confirm action now use a unified destructive color, avoiding split visual states.

Also applies to: 317-317, 393-394

clients/agent-runtime/src/security/detect.rs (3)

19-19: Fail-closed behavior is preserved in the disabled path.

Good extraction to a single helper without changing require=true error semantics.
As per coding guidelines: "Do not silently weaken security policy or access constraints; keep default behavior secure-by-default with deny-by-default where applicable."


34-38: Backend unavailability handling is cleanly deduplicated with consistent security semantics.

This keeps the same contract across all explicit backends and avoids branch drift.
Based on learnings: Applies to clients/agent-runtime/src/{security,gateway,tools,config}/**/*.rs — "Do not silently weaken security policy or access constraints; keep default behavior secure-by-default with deny-by-default where applicable."

Also applies to: 47-51, 63-67, 73-77


86-107: Helper extraction improves maintainability without changing runtime contract.

Centralizing this logic reduces duplication and keeps fallback/error behavior consistent.
As per coding guidelines: "clients/agent-runtime/src/**/*.rs: Never log secrets, tokens, raw credentials, or sensitive payloads in any logging statements."

clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatBridgeCopy.kt (1)

63-69: Good blocked-state fallback handling.

The explicit BLOCKED fallback keeps null recoveryKind from producing misleading “no action” guidance.

clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatComponents.kt (2)

138-150: Great recomposition fix for theme-driven text color.

Including contentColor in remember(...) keys prevents stale bubble content color when theme surface text color changes.


62-69: Solid style refactor with ChatBubblePalette.

Centralizing bubble colors into an immutable palette makes the role-based styling path cleaner and reduces branching spread across composables.

Also applies to: 165-165, 196-201, 210-240

gradle/configs/git/hooks/pre-push.sh (1)

38-38: Explicit default case arm is a good no-op guard.

This makes non-matching paths intentionally handled and keeps behavior clear.

clients/composeApp/src/iosMain/kotlin/com/profiletailors/corvus/runtime/IosRuntimeBridge.kt (1)

5-7: fun interface conversion looks safe and useful.

The single-method contract is preserved, and this change cleanly enables SAM-based usage without changing runtime behavior.

clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/runtime/MobileRuntimeCoordinator.kt (2)

191-199: User message ID generation remains consistent after refactor.

The direct computeNextMessageId(state.messages.size) call preserves ordering and avoids regressions in message sequencing.


227-260: Assistant event handling is cleaner with preserved behavior.

Unifying AssistantChunk/AssistantMessage creation through assistantChatMessage(...) reduces duplication while keeping ID progression consistent with failure events.

clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/onboarding/OnboardingScreen.kt (2)

121-123: State/actions model is a strong API improvement.

This removes duplicated footer inputs and reduces the chance of mismatched onboarding UI state.


156-177: Footer now derives from step, which is the right source of truth.

Using state.step.progressIndex, state.step.totalSteps, and state.step.actionLabel avoids split-brain rendering across body/footer.

clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/App.kt (2)

119-121: Onboarding callsite migration is correctly wired.

OnboardingScreenState/OnboardingScreenActions usage is consistent and preserves callback behavior.


128-147: ChatWorkspace content/action wiring is clean and complete.

All bridge/session fields and bridge callbacks are mapped explicitly, which improves callsite clarity without changing behavior.

clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatWorkspace.kt (2)

169-177: Great fix: actions now rebind when onSendMessage changes.

Including onSendMessage in remember(...) dependencies closes the stale callback path.


227-290: WorkspaceBody extraction keeps behavior intact and lowers complexity.

The config/chat branch remains clear, and the split improves maintainability without altering runtime flow.

clients/agent-runtime/src/search/discovery.rs (5)

162-163: LGTM! Clean extraction of builder configuration.

The refactoring centralizes WalkBuilder setup and override application, improving maintainability without changing behavior.


225-225: LGTM! Effective extraction of path validation and builder setup.

The helpers reduce duplication and keep the function focused on its discovery logic. Correct use of immutable builder for single-path traversal.

Also applies to: 227-227, 231-231


274-285: LGTM! Solid centralization of walker configuration.

The helper correctly applies standard filters and respects discovery rules. The require_git(false) default is appropriate for non-git workspace support.


287-311: LGTM! Proper override handling with good error context.

The early return when patterns are empty is a clean optimization. Error messages clearly identify which pattern failed validation.


313-323: LGTM! Clean path existence validation.

The NotFound→false mapping and error context are correct. The helper keeps path validation logic focused and reusable.

clients/web/apps/dashboard/src/composables/useChat.ts (1)

315-330: Good fix: blank input is rejected before session side effects.

This avoids creating/resuming a session for whitespace-only sends and matches the expected side-effect-free behavior.

clients/web/apps/dashboard/src/composables/useChat.spec.ts (1)

557-578: Good regression coverage for the 401 approval-shaped path.

This locks in the correct auth-first behavior so invalid credentials still clear session state even when the body looks like an approval response.

clients/agent-runtime/src/gateway/admin.rs (2)

668-695: Good refactor: sectioned config view construction is clearer and safer to maintain.

Breaking admin_config_view into dedicated builders materially reduces complexity while preserving behavior.


763-775: Webhook projection keeps secret-safe API semantics.

Using has_secret and avoiding secret value serialization here is the right pattern for admin responses in this gateway surface. As per coding guidelines **/*: "Security first, performance second. Validate input boundaries, auth/authz implications, and secret management."

clients/agent-runtime/src/gateway/mod.rs (3)

1148-1148: Good extraction of bind-safety guard with fail-closed behavior preserved.

The helper keeps the same deny-by-default public-bind protection and makes run_gateway easier to audit.

Also applies to: 1376-1386


1167-1167: Webhook secret hashing refactor looks solid.

Centralizing this logic keeps plaintext out of runtime state and preserves the non-empty/trimmed semantics.

Also applies to: 1388-1396


1178-1178: Nice consolidation of WhatsApp app-secret resolution.

The env-first + trimmed fallback flow is clear and avoids empty-value misconfiguration pitfalls.

Also applies to: 1398-1420

clients/agent-runtime/src/main.rs (1)

830-856: Dispatch call-site refactor preserves behavior.

The new match-arm routing cleanly forwards the same arguments and keeps async result propagation unchanged.

clients/agent-runtime/src/config/schema.rs (1)

2948-2956: Good extraction and workspace-override hardening.

Centralizing runtime-dir resolution and trimming CORVUS_WORKSPACE before path selection closes the whitespace-only override hole without changing the intended precedence order.

Also applies to: 3036-3039, 3818-3832

clients/agent-runtime/src/security/policy.rs (1)

1251-1259: Good regression coverage for the fork-bomb pattern.

This test closes the exact blind spot that motivated the refactor and gives the high-risk path a stable guardrail.

clients/web/apps/dashboard/src/components/memory/LocalMemoryExplorerPanel.vue (1)

91-93: A11y live-region update looks good.

Keeping aria-live="polite/assertive" preserves announcement behavior, and this change does not alter rendering logic.

As per coding guidelines, "Ensure accessibility (A11y)" for **/*.vue and "Look for behavioral regressions" for **/*.

clients/web/apps/dashboard/src/components/memory/MemoryStats.vue (1)

31-35: Status/error semantics change is safe.

The live-region intent is still explicit via aria-live, with no behavioral regression in the conditional rendering path.

As per coding guidelines, "Ensure accessibility (A11y)" for **/*.vue and "Look for behavioral regressions" for **/*.

clients/web/apps/dashboard/src/components/config/McpOverview.vue (1)

69-70: No concerns with this accessibility cleanup.

aria-live remains correctly scoped for loading/error updates, and no functional/auth behavior changed.

As per coding guidelines, "Ensure accessibility (A11y)" for **/*.vue and "**/*: Security first, performance second."

clients/web/apps/dashboard/src/components/sessions/SessionDetail.vue (1)

51-55: A11y adjustment is consistent and low risk.

The loading/error announcements remain controlled through aria-live, with unchanged template branching behavior.

As per coding guidelines, "Ensure accessibility (A11y)" for **/*.vue and "Look for behavioral regressions" for **/*.

clients/web/apps/dashboard/src/components/config/SchedulerStatus.vue (1)

72-73: This status messaging change looks good.

aria-live still communicates loading/error priority, and no runtime behavior changed in this segment.

As per coding guidelines, "Ensure accessibility (A11y)" for **/*.vue and "Look for behavioral regressions" for **/*.

clients/web/apps/dashboard/src/components/config/HealthDashboard.vue (1)

115-116: Clean a11y refinement, no regression detected.

The live-region behavior is preserved with no impact to fetch/poll state transitions.

As per coding guidelines, "Ensure accessibility (A11y)" for **/*.vue and "**/*: Security first, performance second."

clients/web/apps/dashboard/src/components/config/TunnelOverview.vue (1)

63-64: LGTM on loading/error live-region cleanup.

Announcement intent is still explicit through aria-live, and the UI state flow is unchanged.

As per coding guidelines, "Ensure accessibility (A11y)" for **/*.vue and "Look for behavioral regressions" for **/*.

clients/web/apps/dashboard/src/components/config/ChannelsOverview.vue (1)

82-83: Approved: accessibility semantics remain intact.

aria-live continues to provide the required loading/error announcements, with no behavioral change.

As per coding guidelines, "Ensure accessibility (A11y)" for **/*.vue and "Look for behavioral regressions" for **/*.

.github/workflows/publish-release.yml (1)

20-22: Good least-privilege hardening here.

Scoping permissions to the reusable-workflow job and replacing secrets: inherit with explicit secret forwarding reduces ambient token/secret exposure without changing the release handoff contract.

Also applies to: 28-36

.github/workflows/publish-snapshot.yml (1)

17-19: Snapshot publish path is hardened correctly.

Job-scoped permissions plus explicit secret forwarding keep this reusable workflow invocation least-privileged and consistent with the _publish.yml contract.

Also applies to: 24-32

.github/workflows/release-please.yml (1)

18-21: Release orchestration permissions/secrets look properly tightened.

This keeps the release-please token scope local to the job and makes the publish handoff secrets explicit, which is the safer contract for the reusable workflow path.

Also applies to: 123-131

scripts/release-contract.test.mjs (2)

7-14: Deterministic ordering check is a solid cleanup.

Extracting sortStrings() and covering numeric ordering makes the optional-dependency assertion less brittle.

Also applies to: 142-157


243-253: Good fix to surface missing cargo in CI.

Failing in CI instead of silently skipping restores the lockfile contract check while still keeping local runs developer-friendly.

clients/agent-runtime/src/channels/mod.rs (1)

678-688: Nice extraction of the media preprocessing branches.

This keeps process_channel_message smaller while preserving the existing fail-closed flow and temp-file cleanup semantics for both audio and image turns.

Also applies to: 715-719, 835-873

clients/agent-runtime/src/channels/cli.rs (1)

80-87: Good split of the /audio readiness checks.

Pulling the gating logic into ensure_audio_command_ready() keeps the command path easier to follow and preserves the existing rejection behavior.

Also applies to: 206-235

Comment thread clients/agent-runtime/src/agent/agent.rs Outdated
Comment thread clients/agent-runtime/src/agent/agent.rs
Comment thread clients/agent-runtime/src/capabilities/registry.rs
Comment thread clients/agent-runtime/src/capabilities/registry.rs
Comment thread clients/agent-runtime/src/channels/cli.rs
internal val DiagnosticsCardShape = RoundedCornerShape(16.dp)
internal val ChatBubbleShape = RoundedCornerShape(18.dp)

private const val SETTINGS_CONTENT_DESCRIPTION = "Settings"
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.

🧹 Nitpick | 🔵 Trivial

Consider localizing the settings accessibility label.

SETTINGS_CONTENT_DESCRIPTION is a hardcoded English literal; moving it to shared string resources would keep a11y text i18n-ready.

Also applies to: 320-320

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatComponents.kt`
at line 53, Replace the hardcoded English constant SETTINGS_CONTENT_DESCRIPTION
with an i18n-ready string resource: remove the private const val
SETTINGS_CONTENT_DESCRIPTION and instead load the label from shared/localized
resources where used (e.g., use stringResource("settings") or your project's
shared resource accessor in the composable or view where
SETTINGS_CONTENT_DESCRIPTION was referenced), update all usages (including the
other occurrence noted) to fetch the localized string at runtime, and add the
"settings" key and translations to the shared string resources so accessibility
labels are localized across platforms.

Comment thread clients/web/apps/dashboard/src/components/config/CostOverview.vue
Comment thread clients/web/apps/dashboard/src/composables/useChat.spec.ts
Comment thread clients/web/apps/dashboard/src/composables/useChat.ts
Comment on lines +47 to +82
function resolveExecutable(executableName) {
const configuredPath = process.env[executableName.toUpperCase()];
const configuredCandidates =
typeof configuredPath === "string" && configuredPath.trim()
? path.isAbsolute(configuredPath)
? isTrustedExecutablePath(configuredPath)
? [configuredPath]
: []
: !configuredPath.includes(path.sep) && !configuredPath.includes("/")
? trustedExecutableDirs().map((trustedDir) => path.join(trustedDir, configuredPath))
: []
: [];
const candidatePaths = [
...configuredCandidates,
...trustedExecutableDirs().map((trustedDir) => path.join(trustedDir, executableName)),
].filter(Boolean);

return candidatePaths.find((candidatePath) => {
if (!path.isAbsolute(candidatePath) || !isTrustedExecutablePath(candidatePath)) {
return false;
}

try {
if (!fs.statSync(candidatePath).isFile()) {
return false;
}
fs.accessSync(candidatePath, fs.constants.X_OK);
return true;
} catch {
return false;
}
});
}

const cargoExecutable = resolveExecutable("cargo");

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.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Where is release-contract.test.mjs invoked? =="
rg -n -C2 'release-contract\.test\.mjs|node\s+--test|pnpm\s+test|npm\s+test' .github workflows scripts package.json pnpm-workspace.yaml || true

echo
echo "== Any Windows runners around those invocations? =="
rg -n -C3 'runs-on:\s*(windows|.*windows.*)|shell:\s*powershell|shell:\s*pwsh' .github || true

echo
echo "== Current cargo executable resolution code =="
sed -n '47,82p' scripts/release-contract.test.mjs

Repository: dallay/corvus

Length of output: 2582


🏁 Script executed:

# First, let's find all workflow files to understand CI setup
find .github/workflows -name "*.yml" -o -name "*.yaml" | head -20

Repository: dallay/corvus

Length of output: 803


🏁 Script executed:

# Search for any reference to release-contract or test execution patterns
rg -l "release-contract|test" --type yml .github/workflows/

Repository: dallay/corvus

Length of output: 84


🏁 Script executed:

# Check if the test file is invoked anywhere
rg -n "release-contract" . --type js --type ts --type json --type yml

Repository: dallay/corvus

Length of output: 84


🏁 Script executed:

# Look at the full context of the release-contract.test.mjs file
wc -l scripts/release-contract.test.mjs

Repository: dallay/corvus

Length of output: 94


🏁 Script executed:

# Read the full test file
cat -n scripts/release-contract.test.mjs

Repository: dallay/corvus

Length of output: 13410


🏁 Script executed:

# Check package.json for test scripts
cat package.json | grep -A 20 '"scripts"'

Repository: dallay/corvus

Length of output: 39


🏁 Script executed:

# Search all YAML files for test invocations
grep -r "release-contract\|node.*test\|pnpm.*test" .github/workflows/ 2>/dev/null || true

Repository: dallay/corvus

Length of output: 482


🏁 Script executed:

# Read the full package.json
cat package.json

Repository: dallay/corvus

Length of output: 344


🏁 Script executed:

# Search for release-contract reference anywhere
rg -n "release-contract" .

Repository: dallay/corvus

Length of output: 4878


🏁 Script executed:

# Check how test files are discovered and run (look for test scripts)
rg -n "test\|scripts" pnpm-workspace.yaml package.json 2>/dev/null | head -50

Repository: dallay/corvus

Length of output: 39


🏁 Script executed:

# Search for where "node --test" or this test file is invoked
rg -n "node\s+--test|release-contract" .github/workflows/ --type yaml

Repository: dallay/corvus

Length of output: 39


🏁 Script executed:

# Check if the test is in core-check workflow
cat .github/workflows/core-check.yml

Repository: dallay/corvus

Length of output: 2138


🏁 Script executed:

# Look for references to this test in any script files
rg -n "release-contract" scripts/

Repository: dallay/corvus

Length of output: 39


🏁 Script executed:

# Search more broadly in all workflow files
grep -r "node\|test" .github/workflows/ | grep -v "node_modules" | head -40

Repository: dallay/corvus

Length of output: 3206


🏁 Script executed:

# Look for where cargo discovery happens in CI
grep -r "cargo\|rust" .github/workflows/ | grep -v "node_modules"

Repository: dallay/corvus

Length of output: 6578


🏁 Script executed:

# Check if there are any scripts that invoke the test
ls -la scripts/*.mjs scripts/*.js 2>/dev/null || true

Repository: dallay/corvus

Length of output: 311


🏁 Script executed:

# Search all workflows for any Node test invocations more carefully
find .github/workflows -name "*.yml" -o -name "*.yaml" | xargs grep -l "node\|test" | xargs cat | grep -B5 -A5 "node.*test\|release-contract"

Repository: dallay/corvus

Length of output: 395


🏁 Script executed:

# Check publish and release workflows
cat .github/workflows/publish-release.yml

Repository: dallay/corvus

Length of output: 1600


🏁 Script executed:

# Check release-please workflow  
cat .github/workflows/release-please.yml 2>/dev/null || echo "Not found"

Repository: dallay/corvus

Length of output: 5328


🏁 Script executed:

# Check if there's a pull-request-check workflow that might run this
cat .github/workflows/pull-request-check.yml

Repository: dallay/corvus

Length of output: 5956


🏁 Script executed:

# Search for any mention of release-contract or where this test might be invoked
rg -n "release-contract\|node.*--test" . --type md --type txt --type json 2>/dev/null | head -30

Repository: dallay/corvus

Length of output: 39


🏁 Script executed:

# Check if there are any other test files or scripts that might invoke this
grep -r "release-contract.test" . --include="*.mjs" --include="*.js" --include="*.json" --include="*.yml" 2>/dev/null | grep -v node_modules | grep -v ".git"

Repository: dallay/corvus

Length of output: 39


🏁 Script executed:

# Let's check if the test is invoked anywhere in the Gradle build or elsewhere
rg -n "release-contract" . --type gradle --type kt --type kts 2>/dev/null || echo "Not in Gradle"

Repository: dallay/corvus

Length of output: 70


🏁 Script executed:

# Check if it might be invoked through a main build task
grep -r "node.*test\|scripts/.*\.test\.mjs" . --include="*.gradle" --include="*.kts" --include="*.json" 2>/dev/null | grep -v node_modules

Repository: dallay/corvus

Length of output: 39


🏁 Script executed:

# Let's verify the actual platform handling in the resolveExecutable function more carefully
cat -n scripts/release-contract.test.mjs | sed -n '30,82p'

Repository: dallay/corvus

Length of output: 2102


🏁 Script executed:

# Check if there's documentation about when/where this test should be run
find . -name "*.md" -type f -exec grep -l "release-contract" {} \; 2>/dev/null | head -10

Repository: dallay/corvus

Length of output: 238


🏁 Script executed:

# Check the test usage more carefully - when does it actually get invoked?
grep -rn "node.*test\|release-contract" .github/workflows/ | head -20

Repository: dallay/corvus

Length of output: 148


🏁 Script executed:

# Look at the actual CI matrix to understand platform coverage
grep -B5 -A5 "matrix:\|os:" .github/workflows/_build-native-binaries.yml | head -40

Repository: dallay/corvus

Length of output: 967


🏁 Script executed:

# Verify what happens on Windows with cargo paths
python3 << 'EOF'
import os
import pathlib

# Simulate Windows behavior
print("=== Windows path simulation ===")
home = pathlib.Path("C:/Users/testuser")
cargo_dir = home / ".cargo" / "bin"
print(f"HOME/.cargo/bin on Windows: {cargo_dir}")

cargo_path = cargo_dir / "cargo"
cargo_exe_path = cargo_dir / "cargo.exe"

print(f"Probing for 'cargo': {cargo_path}")
print(f"Actual file: {cargo_exe_path}")
print(f"These are different: {cargo_path != cargo_exe_path}")

# Check path.sep on different systems
import platform
print(f"\nPath separator varies by OS:")
print(f"Windows: \\")
print(f"Unix: /")

# The code at line 55 checks: !configuredPath.includes(path.sep) && !configuredPath.includes("/")
# On Windows, path.sep is "\", so this might behave unexpectedly with mixed paths
EOF

Repository: dallay/corvus

Length of output: 328


🏁 Script executed:

# Finally, let's verify if any recent changes reference this test or Windows support
git log --oneline --all -- scripts/release-contract.test.mjs | head -10

Repository: dallay/corvus

Length of output: 314


Platform-specific executable discovery will fail on Windows, but test isn't currently executed there.

resolveExecutable("cargo") probes for cargo, not cargo.exe—the test will fail on Windows CI if added to the pipeline. However, this test isn't currently invoked in any GitHub workflow, so there's no immediate breakage. The concern is valid for future-proofing: before including Windows runners for this test (or if they're added elsewhere), either set CARGO environment variable explicitly or probe platform-specific executable names.

The native binaries workflow does build on windows-latest, but it doesn't invoke this test. If Windows is added to the release-contract test suite, add platform handling:

const executableName = process.platform === 'win32' ? 'cargo.exe' : 'cargo';
const cargoExecutable = resolveExecutable(executableName);

Or extend trustedExecutableDirs() to include Windows cargo paths.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/release-contract.test.mjs` around lines 47 - 82, The test currently
calls resolveExecutable("cargo") which will miss Windows executables named
"cargo.exe"; update the test so cargoExecutable is resolved in a platform-aware
way by deriving executableName from process.platform (e.g., "cargo.exe" on
win32, "cargo" elsewhere) before calling resolveExecutable, or alternatively
enhance resolveExecutable/trustedExecutableDirs to also probe platform-specific
names (e.g., try both "cargo" and "cargo.exe" or include Windows cargo install
dirs); reference resolveExecutable, trustedExecutableDirs and cargoExecutable
when making the change.

Comment thread scripts/release-contract.test.mjs Fixed
yacosta738 and others added 3 commits April 10, 2026 18:30
fix(CostOverview): enhance error logging for governance data reload
refactor(policy): add comments for clarity on command risk classification
…tion or class'

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Signed-off-by: Yuniel Acosta Pérez <33158051+yacosta738@users.noreply.github.com>
@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
78.1% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

@yacosta738 yacosta738 merged commit 1099e65 into main Apr 10, 2026
15 of 17 checks passed
@yacosta738 yacosta738 deleted the feature/dallay-251-recurring-monthly-code-quality-review-sonarqube branch April 10, 2026 17:15
@dallay-bot dallay-bot Bot mentioned this pull request May 3, 2026
@dallay-bot dallay-bot Bot mentioned this pull request May 6, 2026
This was referenced May 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Recurring: Monthly Code Quality Review (SonarQube)

1 participant