fix(sonar): resolve monthly code quality findings#475
Conversation
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThis pull request performs systematic refactoring across four main areas: GitHub Actions workflows (moving from Changes
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 Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
✅ Contributor ReportUser: @yacosta738
Contributor Report evaluates based on public GitHub activity. Analysis period: 2025-04-10 to 2026-04-10 |
There was a problem hiding this comment.
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 | 🟠 MajorTrim
ChatBubbleBodyto 5 parameters—currently at 6, exceeding detekt limit.The function passes 6 parameters when only 5 are allowed. Consolidate
contentColorandcorvusColorsinto theChatBubblePaletteor 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 | 🔵 TrivialExtract the label formatters to a dedicated utility file.
The
onboardingStateLabel()andbridgeStateHeadline()functions are pure string mappers used across multiple files (ConfigPanel, tests). Moving these—along withbridgeStateDescription()andbridgeStateRecovery()—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 | 🟠 MajorUnblock detekt on
OnboardingScreen.The composable exceeds the 60-line limit (currently 99 lines) and violates
FunctionNamingdue to PascalCase. Either extract the function into top/body/footer sections or add the same@file:Suppress("FunctionNaming")suppression used inApp.ktandChatWorkspace.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 | 🟠 MajorExtract header, divider, and conditional panel logic into separate composables.
The
ChatWorkspaceScreenfunction is ~72 lines, exceeding Detekt'sLongMethodthreshold 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
📒 Files selected for processing (46)
.github/workflows/publish-release.yml.github/workflows/publish-snapshot.yml.github/workflows/release-please.ymlclients/agent-runtime/src/agent/agent.rsclients/agent-runtime/src/capabilities/registry.rsclients/agent-runtime/src/channels/cli.rsclients/agent-runtime/src/channels/mod.rsclients/agent-runtime/src/config/schema.rsclients/agent-runtime/src/gateway/admin.rsclients/agent-runtime/src/gateway/mod.rsclients/agent-runtime/src/main.rsclients/agent-runtime/src/search/discovery.rsclients/agent-runtime/src/search/tests.rsclients/agent-runtime/src/security/detect.rsclients/agent-runtime/src/security/policy.rsclients/agent-runtime/src/tools/shell.rsclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/App.ktclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/runtime/MobileRuntimeCoordinator.ktclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatComponents.ktclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatWorkspace.ktclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/onboarding/OnboardingScreen.ktclients/composeApp/src/iosMain/kotlin/com/profiletailors/corvus/runtime/IosRuntimeBridge.ktclients/web/apps/chat/src/App.vueclients/web/apps/chat/src/composables/useChat.spec.tsclients/web/apps/chat/src/composables/useChat.tsclients/web/apps/dashboard/src/App.vueclients/web/apps/dashboard/src/components/config/ChannelsOverview.vueclients/web/apps/dashboard/src/components/config/CostOverview.vueclients/web/apps/dashboard/src/components/config/HealthDashboard.vueclients/web/apps/dashboard/src/components/config/HeartbeatOverview.vueclients/web/apps/dashboard/src/components/config/McpOverview.vueclients/web/apps/dashboard/src/components/config/ReliabilityOverview.vueclients/web/apps/dashboard/src/components/config/SchedulerStatus.vueclients/web/apps/dashboard/src/components/config/TunnelOverview.vueclients/web/apps/dashboard/src/components/config/UpdateSettings.vueclients/web/apps/dashboard/src/components/config/WebSearchSettings.vueclients/web/apps/dashboard/src/components/memory/CerebroSearchPanel.vueclients/web/apps/dashboard/src/components/memory/LocalMemoryExplorerPanel.vueclients/web/apps/dashboard/src/components/memory/MemoryList.vueclients/web/apps/dashboard/src/components/memory/MemoryStats.vueclients/web/apps/dashboard/src/components/sessions/SessionDetail.vueclients/web/apps/dashboard/src/components/sessions/SessionList.vueclients/web/apps/dashboard/src/composables/useAdmin.tsclients/web/apps/dashboard/src/types/admin-sessions.tsgradle/configs/git/hooks/pre-push.shscripts/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.vueclients/web/apps/dashboard/src/components/config/HealthDashboard.vueclients/web/apps/dashboard/src/components/config/HeartbeatOverview.vueclients/web/apps/dashboard/src/components/config/McpOverview.vueclients/web/apps/dashboard/src/components/sessions/SessionDetail.vueclients/web/apps/dashboard/src/components/config/SchedulerStatus.vueclients/web/apps/dashboard/src/components/config/ReliabilityOverview.vueclients/web/apps/dashboard/src/components/config/WebSearchSettings.vueclients/web/apps/dashboard/src/components/sessions/SessionList.vueclients/web/apps/dashboard/src/components/memory/LocalMemoryExplorerPanel.vueclients/web/apps/dashboard/src/components/config/TunnelOverview.vueclients/web/apps/chat/src/App.vueclients/web/apps/dashboard/src/components/memory/MemoryStats.vueclients/web/apps/dashboard/src/components/memory/MemoryList.vueclients/web/apps/dashboard/src/components/config/UpdateSettings.vueclients/web/apps/dashboard/src/components/config/CostOverview.vueclients/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.vueclients/web/apps/dashboard/src/components/config/HealthDashboard.vueclients/web/apps/dashboard/src/components/config/HeartbeatOverview.vueclients/agent-runtime/src/search/tests.rsclients/web/apps/dashboard/src/components/config/McpOverview.vueclients/web/apps/dashboard/src/components/sessions/SessionDetail.vueclients/web/apps/dashboard/src/components/config/SchedulerStatus.vueclients/web/apps/dashboard/src/components/config/ReliabilityOverview.vueclients/web/apps/dashboard/src/components/config/WebSearchSettings.vueclients/web/apps/dashboard/src/components/sessions/SessionList.vueclients/web/apps/dashboard/src/composables/useAdmin.tsclients/web/apps/chat/src/composables/useChat.spec.tsclients/web/apps/dashboard/src/components/memory/LocalMemoryExplorerPanel.vueclients/web/apps/dashboard/src/types/admin-sessions.tsclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/runtime/MobileRuntimeCoordinator.ktclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatComponents.ktclients/web/apps/dashboard/src/components/config/TunnelOverview.vueclients/web/apps/chat/src/App.vueclients/web/apps/dashboard/src/components/memory/MemoryStats.vueclients/agent-runtime/src/search/discovery.rsclients/web/apps/dashboard/src/components/memory/MemoryList.vuegradle/configs/git/hooks/pre-push.shclients/web/apps/dashboard/src/components/config/UpdateSettings.vueclients/agent-runtime/src/channels/cli.rsclients/web/apps/dashboard/src/components/config/CostOverview.vueclients/agent-runtime/src/security/detect.rsclients/composeApp/src/iosMain/kotlin/com/profiletailors/corvus/runtime/IosRuntimeBridge.ktclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/App.ktclients/agent-runtime/src/capabilities/registry.rsclients/web/apps/dashboard/src/App.vueclients/agent-runtime/src/main.rsclients/agent-runtime/src/tools/shell.rsscripts/release-contract.test.mjsclients/agent-runtime/src/gateway/mod.rsclients/agent-runtime/src/security/policy.rsclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatWorkspace.ktclients/agent-runtime/src/agent/agent.rsclients/web/apps/chat/src/composables/useChat.tsclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/onboarding/OnboardingScreen.ktclients/agent-runtime/src/channels/mod.rsclients/agent-runtime/src/config/schema.rsclients/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.rsclients/agent-runtime/src/search/discovery.rsclients/agent-runtime/src/channels/cli.rsclients/agent-runtime/src/security/detect.rsclients/agent-runtime/src/capabilities/registry.rsclients/agent-runtime/src/main.rsclients/agent-runtime/src/tools/shell.rsclients/agent-runtime/src/gateway/mod.rsclients/agent-runtime/src/security/policy.rsclients/agent-runtime/src/agent/agent.rsclients/agent-runtime/src/channels/mod.rsclients/agent-runtime/src/config/schema.rsclients/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, andcargo testfor code validation, or document which checks were skipped and why
Files:
clients/agent-runtime/src/search/tests.rsclients/agent-runtime/src/search/discovery.rsclients/agent-runtime/src/channels/cli.rsclients/agent-runtime/src/security/detect.rsclients/agent-runtime/src/capabilities/registry.rsclients/agent-runtime/src/main.rsclients/agent-runtime/src/tools/shell.rsclients/agent-runtime/src/gateway/mod.rsclients/agent-runtime/src/security/policy.rsclients/agent-runtime/src/agent/agent.rsclients/agent-runtime/src/channels/mod.rsclients/agent-runtime/src/config/schema.rsclients/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.rsclients/agent-runtime/src/search/discovery.rsclients/agent-runtime/src/channels/cli.rsclients/agent-runtime/src/security/detect.rsclients/agent-runtime/src/capabilities/registry.rsclients/agent-runtime/src/main.rsclients/agent-runtime/src/tools/shell.rsclients/agent-runtime/src/gateway/mod.rsclients/agent-runtime/src/security/policy.rsclients/agent-runtime/src/agent/agent.rsclients/agent-runtime/src/channels/mod.rsclients/agent-runtime/src/config/schema.rsclients/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.ktclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatComponents.ktclients/composeApp/src/iosMain/kotlin/com/profiletailors/corvus/runtime/IosRuntimeBridge.ktclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/App.ktclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatWorkspace.ktclients/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
Channeltrait insrc/channels/with consistentsend,listen, andhealth_checksemantics and cover auth/allowlist/health behavior with tests
Files:
clients/agent-runtime/src/channels/cli.rsclients/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.rsclients/agent-runtime/src/tools/shell.rsclients/agent-runtime/src/gateway/mod.rsclients/agent-runtime/src/security/policy.rsclients/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.rsclients/agent-runtime/src/tools/shell.rsclients/agent-runtime/src/gateway/mod.rsclients/agent-runtime/src/security/policy.rsclients/agent-runtime/src/config/schema.rsclients/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
Tooltrait insrc/tools/with strict parameter schema, validate and sanitize all inputs, and return structuredToolResultwithout 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.rsclients/agent-runtime/src/search/discovery.rsclients/agent-runtime/src/channels/cli.rsclients/agent-runtime/src/security/detect.rsclients/agent-runtime/src/capabilities/registry.rsclients/agent-runtime/src/main.rsclients/agent-runtime/src/tools/shell.rsclients/agent-runtime/src/gateway/mod.rsclients/agent-runtime/src/security/policy.rsclients/agent-runtime/src/agent/agent.rsclients/agent-runtime/src/channels/mod.rsclients/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.rsclients/agent-runtime/src/security/detect.rsclients/agent-runtime/src/main.rsclients/agent-runtime/src/tools/shell.rsclients/agent-runtime/src/gateway/mod.rsclients/agent-runtime/src/security/policy.rsclients/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.rsclients/agent-runtime/src/channels/cli.rsclients/agent-runtime/src/main.rsclients/agent-runtime/src/tools/shell.rsclients/agent-runtime/src/gateway/mod.rsclients/agent-runtime/src/security/policy.rsclients/agent-runtime/src/agent/agent.rsclients/agent-runtime/src/channels/mod.rsclients/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.rsclients/agent-runtime/src/capabilities/registry.rsclients/agent-runtime/src/main.rsclients/agent-runtime/src/tools/shell.rsscripts/release-contract.test.mjsclients/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.rsclients/agent-runtime/src/security/detect.rsclients/agent-runtime/src/main.rsclients/agent-runtime/src/tools/shell.rsclients/agent-runtime/src/gateway/mod.rsclients/agent-runtime/src/security/policy.rsclients/agent-runtime/src/agent/agent.rsclients/agent-runtime/src/config/schema.rsclients/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.rsclients/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.rsclients/agent-runtime/src/tools/shell.rsclients/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.rsclients/agent-runtime/src/tools/shell.rsclients/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.rsclients/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.rsscripts/release-contract.test.mjsclients/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 interfaceis 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_leveleasier 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 incaseblock.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 withAdminSessionDetail, so the explicitascast 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
datafield is only accessed viaJSON.stringify()in the sole consumer (CerebroSessionActions.vue), which safely handles all union types. No code calls.map(),.filter(), or.lengthon 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_descriptoreasier 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: inheritwith 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: readwithpackages: writeis 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, andprocessStreamBufferreduces 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\nappend) correctly handle split frames and mixed newline styles.clients/web/apps/chat/src/composables/useChat.spec.ts (2)
391-414: Good regression coverage forapproval_contractwebhook mapping.This test protects the 403 approval-contract compatibility path and verifies the expected
approval_requiredshape end-to-end.
429-453: Good coverage for structured SSE error propagation.This validates that
event: errorframes 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-livewhile removing explicitroleon 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-livewith 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-livesemantics 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-liveremains 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
Setmembership 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-livewhile 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:formatToggleis a solid readability + i18n improvement.This removes repeated inline logic and standardizes boolean/unknown rendering.
29-70: Template semantics are improved.Switching to
.display-fieldcontainers 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 preservingaria-live/aria-atomicbehavior is a reasonable accessibility-safe cleanup.clients/agent-runtime/src/channels/cli.rs (1)
263-266: The review comment is incorrect.AudioConfig::max_audio_bytesis bounded by upstream validation invalidate_audio_config()at line 3444 of schema.rs, which enforces the constraint0 < max_audio_bytes <= MAX_AUDIO_BYTES_CEILINGwhere the ceiling is 100 MiB (104,857,600 bytes). This is validated during config initialization and cannot reachu64::MAX. The additionmax_size + 1at 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
ChatWorkspaceContentandBridgeActionshere keepsApp.ktas the single assembly point and preventsChatWorkspacefrom 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
OnboardingScreenStateandOnboardingScreenActionsremoves 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 refactorbridgeStateRecoveryto reduce complexity.The nested
whenexpressions 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=trueerrors; optional mode degrades toNoopSandbox) 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, andapply_overrideskeeps concerns isolated and retains clear error context for invalid patterns.
313-323:indexable_path_existserror handling is explicit and appropriate.
NotFoundis 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 inload_or_initwithout 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_configanddecrypt_config_secretscorrectly 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_bindbefore 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_gatewaysimpler 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-basedadmin_config_viewrefactor 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_errornow guarantees structured metadata on build/wrap/exec/timeout failures, and the sanitize-then-wrap flow remains intact.As per coding guidelines: Implement
Tooltrait insrc/tools/with strict parameter schema, validate and sanitize all inputs, and return structuredToolResultwithout 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.
Deploying corvus with
|
| 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 |
There was a problem hiding this comment.
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 | 🟠 MajorAdd 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 | 🟠 MajorHandle top-level approval payload fields.
parseApprovalErrorType()ignores a top-levelcode, andcreateApprovalRequiredResult()ignores top-leveltool/reason. Butclients/agent-runtime/src/agent/agent.rsemits approval denials as{ code, tool, reason }at the top level. In that shape, a valid 403 approval response will fall through tothrowCredentialInvalid()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 | 🟠 MajorRoute audit failures through
finalize_tool_execution()too.The
Err(audit_error_result) => return audit_error_resultbranch still bypassesfinalize_tool_execution(), so strict shell-audit failures do not emitObserverEvent::ToolCall. The newactionparameter 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 | 🟡 MinorTrim
CORVUS_WORKSPACEin the later env-override pass too.This startup path still calls
apply_env_overrides(), andapply_workspace_override()only checks!workspace.is_empty(). A whitespace-onlyCORVUS_WORKSPACEtherefore still wins after your new trimmed resolution step and can repointconfig_path/workspace_dirto 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
📒 Files selected for processing (15)
clients/agent-runtime/src/agent/agent.rsclients/agent-runtime/src/capabilities/registry.rsclients/agent-runtime/src/config/schema.rsclients/agent-runtime/src/security/policy.rsclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/runtime/MobileRuntimeCoordinator.ktclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatBridgeCopy.ktclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatComponents.ktclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatWorkspace.ktclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/onboarding/OnboardingScreen.ktclients/web/apps/chat/src/composables/useChat.spec.tsclients/web/apps/chat/src/composables/useChat.tsclients/web/apps/dashboard/src/App.vueclients/web/apps/dashboard/src/components/memory/MemoryList.vuegradle/configs/git/hooks/pre-push.shscripts/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.vueclients/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.vuegradle/configs/git/hooks/pre-push.shclients/web/apps/chat/src/composables/useChat.spec.tsclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/runtime/MobileRuntimeCoordinator.ktclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatWorkspace.ktclients/agent-runtime/src/agent/agent.rsscripts/release-contract.test.mjsclients/web/apps/chat/src/composables/useChat.tsclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatBridgeCopy.ktclients/agent-runtime/src/capabilities/registry.rsclients/agent-runtime/src/security/policy.rsclients/agent-runtime/src/config/schema.rsclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/onboarding/OnboardingScreen.ktclients/web/apps/dashboard/src/App.vueclients/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.ktclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatWorkspace.ktclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatBridgeCopy.ktclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/onboarding/OnboardingScreen.ktclients/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.rsclients/agent-runtime/src/capabilities/registry.rsclients/agent-runtime/src/security/policy.rsclients/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, andcargo testfor code validation, or document which checks were skipped and why
Files:
clients/agent-runtime/src/agent/agent.rsclients/agent-runtime/src/capabilities/registry.rsclients/agent-runtime/src/security/policy.rsclients/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.rsclients/agent-runtime/src/capabilities/registry.rsclients/agent-runtime/src/security/policy.rsclients/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.rsclients/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.rsclients/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.rsscripts/release-contract.test.mjsclients/agent-runtime/src/capabilities/registry.rsclients/agent-runtime/src/security/policy.rsclients/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.rsclients/agent-runtime/src/security/policy.rsclients/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.rsclients/agent-runtime/src/security/policy.rsclients/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.rsscripts/release-contract.test.mjsclients/agent-runtime/src/capabilities/registry.rsclients/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.rsscripts/release-contract.test.mjsclients/agent-runtime/src/capabilities/registry.rsclients/agent-runtime/src/security/policy.rsclients/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/AssistantMessageinto 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
assistantChatMessagetop-level preserves behavior while avoiding extra class-level function count inMobileRuntimeCoordinator.clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatWorkspace.kt (2)
169-176: Stale callback routing is fixed here.Including
onSendMessagein theremember(...)keys keepsactions.onSendaligned with the current parent handler. Nice catch.
227-289: Good complexity reduction without state drift.
WorkspaceBodykeeps the config/chat branch local and narrows the rememberedChatPanelStateinputs to whatChatPanelactually 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: inheritrejection 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()plusdecrypt_config_secrets()still covers the same secret-bearing fields thatsave()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
Highclassification 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()staysHigh, andis_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/ChatBubbleHeadernow 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 thecasebehavior explicit.clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/onboarding/OnboardingScreen.kt (1)
163-184: Nice API refactor.The
state/actionssplit is cohesive, and the only call site inclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/App.kt:112-128already sources both fromruntimeOnboardingStep, so this preserves the current onboarding flow.
ec30eca to
181d6e6
Compare
There was a problem hiding this comment.
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 | 🟠 MajorDon’t let
tool/reasonoverride the real approval discriminator.
parseApprovalErrorType()now returns top-leveltool/reasonbefore it inspectserror.code/error.type. A mixed 403 payload like{ tool, reason, error: { code: "approval_required" } }will now be misclassified and fall through tothrowCredentialInvalid(), 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 | 🔴 CriticalStandalone
&chains bypass command policy checks entirely — promote & detection tocommand_risk_level.The issue is critical:
command_risk_level("ls & echo ok")returnsLowbecause it does not check for single-&chains, and the shell execution path never invokesis_command_allowed(which would block them). This means an unsandboxed command likels & whoamiexecutes both commands without any policy enforcement.The flow is:
- Shell execution calls
validate_command_execution()(line 168 in shell.rs)- That function calls only
command_risk_level(), notis_command_allowed()command_risk_level()lacks thecontains_single_ampersand()check- Command proceeds to spawn with no
&validationAdd the
contains_single_ampersand(command)check tocommand_risk_level()to mark chains asHighrisk, 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 | 🟠 MajorAdd keyboard roving logic to the nested tablists.
These buttons now use
role="tab"with inactive tabs forced totabindex="-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 | 🟠 MajorAssert the full reusable-workflow secret contract, not just the endpoints.
These checks only require
SIGNING_IN_MEMORY_KEYandDOCKERHUB_TOKEN. If a middle mapping likeNPM_TOKENorMAVEN_CENTRAL_PASSWORDis dropped, the test still passes even though./.github/workflows/_publish.ymlexposes all 8 secret inputs and the current callers forward all 8. Tighten the contract by asserting every expected secret key in each caller.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."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", );🤖 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 | 🟠 MajorAdd
--before forwarded doc paths inlycheeinvocation.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 -- "$@" || trueDoes 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
📒 Files selected for processing (46)
.github/workflows/publish-release.yml.github/workflows/publish-snapshot.yml.github/workflows/release-please.ymlclients/agent-runtime/src/agent/agent.rsclients/agent-runtime/src/capabilities/registry.rsclients/agent-runtime/src/channels/cli.rsclients/agent-runtime/src/channels/mod.rsclients/agent-runtime/src/config/schema.rsclients/agent-runtime/src/gateway/admin.rsclients/agent-runtime/src/gateway/mod.rsclients/agent-runtime/src/main.rsclients/agent-runtime/src/search/discovery.rsclients/agent-runtime/src/search/tests.rsclients/agent-runtime/src/security/detect.rsclients/agent-runtime/src/security/policy.rsclients/agent-runtime/src/tools/shell.rsclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/App.ktclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/runtime/MobileRuntimeCoordinator.ktclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatBridgeCopy.ktclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatComponents.ktclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatWorkspace.ktclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/onboarding/OnboardingScreen.ktclients/composeApp/src/iosMain/kotlin/com/profiletailors/corvus/runtime/IosRuntimeBridge.ktclients/web/apps/dashboard/src/App.vueclients/web/apps/dashboard/src/components/config/ChannelsOverview.vueclients/web/apps/dashboard/src/components/config/CostOverview.vueclients/web/apps/dashboard/src/components/config/HealthDashboard.vueclients/web/apps/dashboard/src/components/config/HeartbeatOverview.vueclients/web/apps/dashboard/src/components/config/McpOverview.vueclients/web/apps/dashboard/src/components/config/ReliabilityOverview.vueclients/web/apps/dashboard/src/components/config/SchedulerStatus.vueclients/web/apps/dashboard/src/components/config/TunnelOverview.vueclients/web/apps/dashboard/src/components/config/UpdateSettings.vueclients/web/apps/dashboard/src/components/config/WebSearchSettings.vueclients/web/apps/dashboard/src/components/memory/CerebroSearchPanel.vueclients/web/apps/dashboard/src/components/memory/LocalMemoryExplorerPanel.vueclients/web/apps/dashboard/src/components/memory/MemoryList.vueclients/web/apps/dashboard/src/components/memory/MemoryStats.vueclients/web/apps/dashboard/src/components/sessions/SessionDetail.vueclients/web/apps/dashboard/src/components/sessions/SessionList.vueclients/web/apps/dashboard/src/composables/useAdmin.tsclients/web/apps/dashboard/src/composables/useChat.spec.tsclients/web/apps/dashboard/src/composables/useChat.tsclients/web/apps/dashboard/src/types/admin-sessions.tsgradle/configs/git/hooks/pre-push.shscripts/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.tsclients/web/apps/dashboard/src/components/sessions/SessionDetail.vueclients/agent-runtime/src/search/tests.rsclients/web/apps/dashboard/src/components/config/SchedulerStatus.vueclients/web/apps/dashboard/src/components/config/HealthDashboard.vueclients/web/apps/dashboard/src/components/config/HeartbeatOverview.vueclients/web/apps/dashboard/src/components/config/ChannelsOverview.vueclients/web/apps/dashboard/src/components/config/CostOverview.vueclients/web/apps/dashboard/src/components/memory/LocalMemoryExplorerPanel.vueclients/web/apps/dashboard/src/components/config/ReliabilityOverview.vueclients/web/apps/dashboard/src/components/sessions/SessionList.vueclients/web/apps/dashboard/src/components/memory/MemoryStats.vueclients/web/apps/dashboard/src/components/config/McpOverview.vueclients/web/apps/dashboard/src/components/config/WebSearchSettings.vueclients/agent-runtime/src/security/detect.rsclients/web/apps/dashboard/src/components/memory/MemoryList.vueclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/runtime/MobileRuntimeCoordinator.ktclients/agent-runtime/src/tools/shell.rsclients/web/apps/dashboard/src/components/config/UpdateSettings.vuegradle/configs/git/hooks/pre-push.shclients/composeApp/src/iosMain/kotlin/com/profiletailors/corvus/runtime/IosRuntimeBridge.ktclients/agent-runtime/src/main.rsclients/web/apps/dashboard/src/types/admin-sessions.tsscripts/release-contract.test.mjsclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatComponents.ktclients/web/apps/dashboard/src/composables/useChat.spec.tsclients/agent-runtime/src/gateway/mod.rsclients/agent-runtime/src/search/discovery.rsclients/web/apps/dashboard/src/composables/useChat.tsclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/App.ktclients/web/apps/dashboard/src/components/config/TunnelOverview.vueclients/agent-runtime/src/capabilities/registry.rsclients/agent-runtime/src/channels/mod.rsclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatBridgeCopy.ktclients/web/apps/dashboard/src/App.vueclients/agent-runtime/src/config/schema.rsclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatWorkspace.ktclients/agent-runtime/src/gateway/admin.rsclients/agent-runtime/src/agent/agent.rsclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/onboarding/OnboardingScreen.ktclients/agent-runtime/src/channels/cli.rsclients/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.vueclients/web/apps/dashboard/src/components/config/SchedulerStatus.vueclients/web/apps/dashboard/src/components/config/HealthDashboard.vueclients/web/apps/dashboard/src/components/config/HeartbeatOverview.vueclients/web/apps/dashboard/src/components/config/ChannelsOverview.vueclients/web/apps/dashboard/src/components/config/CostOverview.vueclients/web/apps/dashboard/src/components/memory/LocalMemoryExplorerPanel.vueclients/web/apps/dashboard/src/components/config/ReliabilityOverview.vueclients/web/apps/dashboard/src/components/sessions/SessionList.vueclients/web/apps/dashboard/src/components/memory/MemoryStats.vueclients/web/apps/dashboard/src/components/config/McpOverview.vueclients/web/apps/dashboard/src/components/config/WebSearchSettings.vueclients/web/apps/dashboard/src/components/memory/MemoryList.vueclients/web/apps/dashboard/src/components/config/UpdateSettings.vueclients/web/apps/dashboard/src/components/config/TunnelOverview.vueclients/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.rsclients/agent-runtime/src/security/detect.rsclients/agent-runtime/src/tools/shell.rsclients/agent-runtime/src/main.rsclients/agent-runtime/src/gateway/mod.rsclients/agent-runtime/src/search/discovery.rsclients/agent-runtime/src/capabilities/registry.rsclients/agent-runtime/src/channels/mod.rsclients/agent-runtime/src/config/schema.rsclients/agent-runtime/src/gateway/admin.rsclients/agent-runtime/src/agent/agent.rsclients/agent-runtime/src/channels/cli.rsclients/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, andcargo testfor code validation, or document which checks were skipped and why
Files:
clients/agent-runtime/src/search/tests.rsclients/agent-runtime/src/security/detect.rsclients/agent-runtime/src/tools/shell.rsclients/agent-runtime/src/main.rsclients/agent-runtime/src/gateway/mod.rsclients/agent-runtime/src/search/discovery.rsclients/agent-runtime/src/capabilities/registry.rsclients/agent-runtime/src/channels/mod.rsclients/agent-runtime/src/config/schema.rsclients/agent-runtime/src/gateway/admin.rsclients/agent-runtime/src/agent/agent.rsclients/agent-runtime/src/channels/cli.rsclients/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.rsclients/agent-runtime/src/security/detect.rsclients/agent-runtime/src/tools/shell.rsclients/agent-runtime/src/main.rsclients/agent-runtime/src/gateway/mod.rsclients/agent-runtime/src/search/discovery.rsclients/agent-runtime/src/capabilities/registry.rsclients/agent-runtime/src/channels/mod.rsclients/agent-runtime/src/config/schema.rsclients/agent-runtime/src/gateway/admin.rsclients/agent-runtime/src/agent/agent.rsclients/agent-runtime/src/channels/cli.rsclients/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.rsclients/agent-runtime/src/tools/shell.rsclients/agent-runtime/src/gateway/mod.rsclients/agent-runtime/src/gateway/admin.rsclients/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.rsclients/agent-runtime/src/tools/shell.rsclients/agent-runtime/src/gateway/mod.rsclients/agent-runtime/src/config/schema.rsclients/agent-runtime/src/gateway/admin.rsclients/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.ktclients/composeApp/src/iosMain/kotlin/com/profiletailors/corvus/runtime/IosRuntimeBridge.ktclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatComponents.ktclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/App.ktclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatBridgeCopy.ktclients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatWorkspace.ktclients/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
Tooltrait insrc/tools/with strict parameter schema, validate and sanitize all inputs, and return structuredToolResultwithout 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
Channeltrait insrc/channels/with consistentsend,listen, andhealth_checksemantics and cover auth/allowlist/health behavior with tests
Files:
clients/agent-runtime/src/channels/mod.rsclients/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.rsclients/agent-runtime/src/security/detect.rsclients/agent-runtime/src/tools/shell.rsclients/agent-runtime/src/main.rsscripts/release-contract.test.mjsclients/agent-runtime/src/gateway/mod.rsclients/agent-runtime/src/search/discovery.rsclients/agent-runtime/src/capabilities/registry.rsclients/agent-runtime/src/channels/mod.rsclients/agent-runtime/src/config/schema.rsclients/agent-runtime/src/agent/agent.rsclients/agent-runtime/src/channels/cli.rsclients/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.rsclients/agent-runtime/src/tools/shell.rsclients/agent-runtime/src/main.rsscripts/release-contract.test.mjsclients/agent-runtime/src/gateway/mod.rsclients/agent-runtime/src/search/discovery.rsclients/agent-runtime/src/capabilities/registry.rsclients/agent-runtime/src/config/schema.rsclients/agent-runtime/src/agent/agent.rsclients/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.rsclients/agent-runtime/src/tools/shell.rsclients/agent-runtime/src/main.rsscripts/release-contract.test.mjsclients/agent-runtime/src/gateway/mod.rsclients/agent-runtime/src/search/discovery.rsclients/agent-runtime/src/config/schema.rsclients/agent-runtime/src/agent/agent.rsclients/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.rsclients/agent-runtime/src/tools/shell.rsclients/agent-runtime/src/main.rsclients/agent-runtime/src/capabilities/registry.rsclients/agent-runtime/src/config/schema.rsclients/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.rsclients/agent-runtime/src/main.rsclients/agent-runtime/src/search/discovery.rsclients/agent-runtime/src/channels/mod.rsclients/agent-runtime/src/config/schema.rsclients/agent-runtime/src/agent/agent.rsclients/agent-runtime/src/channels/cli.rsclients/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.rsclients/agent-runtime/src/main.rsscripts/release-contract.test.mjsclients/agent-runtime/src/search/discovery.rsclients/agent-runtime/src/capabilities/registry.rsclients/agent-runtime/src/config/schema.rsclients/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.rsclients/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.rsclients/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.rsclients/agent-runtime/src/gateway/mod.rsclients/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.mjsclients/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>tounknown[]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 callingupdateSecretMode(...)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=trueerror 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 toclients/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
BLOCKEDfallback keeps nullrecoveryKindfrom 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
contentColorinremember(...)keys prevents stale bubble content color when theme surface text color changes.
62-69: Solid style refactor withChatBubblePalette.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 defaultcasearm 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 interfaceconversion 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/AssistantMessagecreation throughassistantChatMessage(...)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 fromstep, which is the right source of truth.Using
state.step.progressIndex,state.step.totalSteps, andstate.step.actionLabelavoids 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/OnboardingScreenActionsusage is consistent and preserves callback behavior.
128-147:ChatWorkspacecontent/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 whenonSendMessagechanges.Including
onSendMessageinremember(...)dependencies closes the stale callback path.
227-290:WorkspaceBodyextraction 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_viewinto dedicated builders materially reduces complexity while preserving behavior.
763-775: Webhook projection keeps secret-safe API semantics.Using
has_secretand 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_gatewayeasier 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_WORKSPACEbefore 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
**/*.vueand "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
**/*.vueand "Look for behavioral regressions" for**/*.clients/web/apps/dashboard/src/components/config/McpOverview.vue (1)
69-70: No concerns with this accessibility cleanup.
aria-liveremains correctly scoped for loading/error updates, and no functional/auth behavior changed.As per coding guidelines, "Ensure accessibility (A11y)" for
**/*.vueand "**/*: 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
**/*.vueand "Look for behavioral regressions" for**/*.clients/web/apps/dashboard/src/components/config/SchedulerStatus.vue (1)
72-73: This status messaging change looks good.
aria-livestill communicates loading/error priority, and no runtime behavior changed in this segment.As per coding guidelines, "Ensure accessibility (A11y)" for
**/*.vueand "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
**/*.vueand "**/*: 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
**/*.vueand "Look for behavioral regressions" for**/*.clients/web/apps/dashboard/src/components/config/ChannelsOverview.vue (1)
82-83: Approved: accessibility semantics remain intact.
aria-livecontinues to provide the required loading/error announcements, with no behavioral change.As per coding guidelines, "Ensure accessibility (A11y)" for
**/*.vueand "Look for behavioral regressions" for**/*..github/workflows/publish-release.yml (1)
20-22: Good least-privilege hardening here.Scoping
permissionsto the reusable-workflow job and replacingsecrets: inheritwith 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.ymlcontract.Also applies to: 24-32
.github/workflows/release-please.yml (1)
18-21: Release orchestration permissions/secrets look properly tightened.This keeps the
release-pleasetoken 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_messagesmaller 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/audioreadiness 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
| internal val DiagnosticsCardShape = RoundedCornerShape(16.dp) | ||
| internal val ChatBubbleShape = RoundedCornerShape(18.dp) | ||
|
|
||
| private const val SETTINGS_CONTENT_DESCRIPTION = "Settings" |
There was a problem hiding this comment.
🧹 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.
| 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"); | ||
|
|
There was a problem hiding this comment.
🧩 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.mjsRepository: 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 -20Repository: 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 ymlRepository: 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.mjsRepository: dallay/corvus
Length of output: 94
🏁 Script executed:
# Read the full test file
cat -n scripts/release-contract.test.mjsRepository: 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 || trueRepository: dallay/corvus
Length of output: 482
🏁 Script executed:
# Read the full package.json
cat package.jsonRepository: 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 -50Repository: 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 yamlRepository: dallay/corvus
Length of output: 39
🏁 Script executed:
# Check if the test is in core-check workflow
cat .github/workflows/core-check.ymlRepository: 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 -40Repository: 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 || trueRepository: 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.ymlRepository: 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.ymlRepository: 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 -30Repository: 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_modulesRepository: 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 -10Repository: 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 -20Repository: 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 -40Repository: 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
EOFRepository: 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 -10Repository: 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.
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>
|


Related Issues
Summary
Tested Information
pnpm --dir clients/web --filter @corvus/chat test -- src/composables/useChat.spec.tspnpm --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.tsnode --test scripts/release-contract.test.mjssh -n gradle/configs/git/hooks/pre-push.shcargo test --manifest-path clients/agent-runtime/Cargo.toml refresh_fails_fast_when_index_db_is_lockedactionlintwhen availableReviewer focus:
Documentation Impact
Breaking Changes
Checklist