Skip to content

refactor(agent-runtime): extract core contracts into corvus-traits (#485)#505

Merged
yacosta738 merged 15 commits into
mainfrom
feature/capability-architecture
Apr 11, 2026
Merged

refactor(agent-runtime): extract core contracts into corvus-traits (#485)#505
yacosta738 merged 15 commits into
mainfrom
feature/capability-architecture

Conversation

@yacosta738
Copy link
Copy Markdown
Contributor

This pull request introduces a new crate, corvus-traits, to the workspace, providing shared runtime contracts for messaging channels, memory, and sandboxing. The new crate defines core traits and data structures for multimodal messaging, memory/session management, and pluggable OS-level sandboxing, along with comprehensive unit tests and scaffolding for future contract compliance tests.

The most important changes are:

Workspace and Dependency Integration

  • Added the new crate corvus-traits to the workspace members in Cargo.toml and included it as a dependency for the agent runtime crate. [1] [2]

New Crate: corvus-traits

  • Created the corvus-traits crate with metadata, dependencies, and a modular structure including channels, memory, security, and testing modules. [1] [2]

Messaging Channel Contracts

  • Implemented the Channel trait and supporting types in channels.rs, supporting multimodal messages, draft updates, typing indicators, and helper methods for handling text, image, and audio parts. Includes thorough unit tests.

Memory and Session Management

  • Defined the Memory trait and associated data types in memory.rs for storing, recalling, and managing memory entries and sessions, with support for categories, statistics, and validation. Includes serialization, deserialization, and unit tests.

Sandboxing and Testing Infrastructure

  • Added the Sandbox trait and a no-op implementation in security.rs for OS-level isolation, with full test coverage. Introduced a placeholder TraitHarness in testing.rs for future contract-compliance testing. [1] [2]

@yacosta738 yacosta738 marked this pull request as draft April 11, 2026 06:24
@yacosta738 yacosta738 self-assigned this Apr 11, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 11, 2026

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added TOML-based agent composition system enabling configuration-driven agent creation without code.
    • Introduced CLI commands for agent scaffolding, validation, and management via templates.
    • Added pre-built agent templates for chatbots, code assistants, ops agents, research agents, and support agents.
  • Documentation

    • Added comprehensive guide for composing agents via manifest configuration.

Walkthrough

Extracts many runtime trait/type implementations (channels, providers, memory, tools, security, multimedia) into a new workspace crate corvus-traits, adds registry crates (corvus-*-registry) that re-export those types, and introduces an agent composer (manifest schema, validation, CLI integration) plus template files and API-compatibility tests. Legacy modules now re-export from corvus-traits.

Changes

Cohort / File(s) Summary
Workspace & manifests
clients/agent-runtime/Cargo.toml, clients/agent-runtime/crates/*/Cargo.toml
Added new workspace members and crate manifests: corvus-traits, corvus-providers, corvus-channels, corvus-tools, corvus-memory, corvus-security, corvus-composer. Updated agent-runtime to depend on these via local path.
Core traits crate
clients/agent-runtime/crates/corvus-traits/*, .../src/{channels.rs,memory.rs,providers.rs,tools.rs,multimedia.rs,security.rs,testing.rs}
New centralized definitions for Channel, Memory, Provider, Tool, multimedia types, Sandbox, test macros, and helpers. Includes many structs/enums, async traits with defaults, helpers, and unit tests.
Runtime re-exports / compatibility shims
clients/agent-runtime/src/{channels/traits.rs,memory/traits.rs,providers/traits.rs,security/traits.rs,tools/traits.rs}, clients/agent-runtime/src/channels/{media.rs,audio_media.rs}
Replaced large in-file trait/type implementations with single-line pub use corvus_traits::... re-exports; updated media staging/cleanup to call centralized helpers.
Registries re-export crates
clients/agent-runtime/crates/{corvus-channels,corvus-providers,corvus-tools,corvus-memory,corvus-security}/src/lib.rs
New small registry crates that re-export trait types from corvus-traits and expose Info structs (ChannelInfo, ProviderInfo, ToolInfo, MemoryInfo, SecurityInfo).
Composer feature & CLI
clients/agent-runtime/crates/corvus-composer/src/lib.rs, clients/agent-runtime/src/composer.rs, clients/agent-runtime/src/lib.rs, clients/agent-runtime/src/main.rs
Added AgentManifest schema, AgentComposer with validation and capability reporting, composer CLI commands (build/run/new), CLI wiring to main runtime; validation rules and many unit tests.
Agent templates & docs
clients/agent-runtime/agents/templates/*.toml, clients/agent-runtime/docs/composing-agents.md
Added multiple agent template TOML files (chat-bot, code-assistant, minimal, ops, research, support) and comprehensive composer documentation.
Tests
clients/agent-runtime/tests/traits_api_compat.rs, updated unit tests across channels/providers/etc.
New API-compatibility integration test verifying TypeId/method dispatch across legacy and extracted trait paths; many unit tests adapted to re-exported types and centralized helpers.
Small runtime updates
clients/agent-runtime/src/{channels/mod.rs,channels/discord.rs,channels/slack.rs,providers/*}
Replaced staged.cleanup() calls with media::cleanup_staged_image, adjusted audio history construction call sites, and updated test-only provider wrapper types in provider tests.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant CLI as CLI (corvus)
participant Composer as AgentComposer
participant Validator as ValidationLogic
participant Registry as KnownRegistries
participant FS as Filesystem
CLI->>Composer: Build/Run/New command + manifest/template
Composer->>FS: load manifest or template file
Composer->>Validator: validate(manifest)
Validator->>Registry: check known providers/channels/tools/sandboxes
Registry-->>Validator: capability presence/availability
Validator-->>Composer: validation result + warnings
Composer->>FS: write output (New) / emit validation errors (Build/Run)
Composer-->>CLI: success/failure + messages

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Title check ⚠️ Warning The title 'refactor(agent-runtime): extract core contracts into corvus-traits (#485)' exceeds the 72-character limit at 73 characters and clearly describes the PR's main purpose. Remove the issue number '#485' from the title to stay within the 72-character limit, e.g., 'refactor(agent-runtime): extract core contracts into corvus-traits'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description check ✅ Passed The PR description is comprehensive and covers all major template sections including purpose, testing, documentation impact, and breaking changes confirmation.
Docstring Coverage ✅ Passed Docstring coverage is 80.70% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/capability-architecture

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

❤️ Share

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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 11, 2026

✅ Contributor Report

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

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

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🤖 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/crates/corvus-traits/Cargo.toml`:
- Around line 10-15: The tokio features are too broad for the library: keep
tokio in [dependencies] with only the "sync" feature (since the public API only
exposes tokio::sync::mpsc::Sender), remove the "rt" feature entirely, and move
the "macros" feature into [dev-dependencies] (it's only needed for tests like
the #[tokio::test] used in the test at/near line 295); update Cargo.toml
accordingly so production deps declare tokio = { version = "1.42",
default-features = false, features = ["sync"] } and dev-dependencies declare
tokio = { version = "1.42", features = ["macros"] }.

In `@clients/agent-runtime/crates/corvus-traits/src/channels.rs`:
- Around line 106-146: SendMessage and Channel::send are limited to text; change
the SendMessage.payload (currently content: String) to carry multimodal data
(e.g., Vec<ContentPart> or a single ContentPart enum) and update the
constructors (SendMessage::new and SendMessage::with_subject) to build that
multimodal payload, then update the Channel trait signature async fn send(&self,
message: &SendMessage) -> anyhow::Result<()> to accept the new SendMessage shape
so all channel implementations can send images/audio; ensure any usages of
SendMessage and Channel::send (including ChannelMessage conversions) are updated
to construct and consume the new ContentPart-based payload.
- Around line 49-70: The text_projection method currently returns an empty
string when self.parts is non-empty but filters out to no text (e.g., only
uncaptained ContentPart::Image/Audio), dropping the compatibility projection in
self.content; update text_projection (function text_projection on the type with
fields parts and content) to check after collecting blocks if blocks.is_empty()
and, if so, return self.content.clone() as a fallback; otherwise continue to
join blocks as now. Ensure you reference ContentPart::Text, ContentPart::Image,
and ContentPart::Audio in the same filter_map logic and only change the
post-filter empty-case behavior.

In `@clients/agent-runtime/crates/corvus-traits/src/memory.rs`:
- Around line 169-222: The default implementations for session-related trait
methods (upsert_session, end_session, update_session_activity, list_sessions,
get_session, list_sessions_for_token, memory_stats) currently return
success/empty results which hides unsupported backends; change these defaults to
return a clear error (e.g., Err(anyhow::anyhow!("session management not
supported by this backend")) ) so callers can detect lack of support, or
alternatively extract these methods into a separate extension trait (e.g.,
SessionStore) and remove default no-op implementations from the main trait;
update the trait definition to either return the explicit Err for each of the
listed methods or move them to the new extension trait so unsupported
implementations fail fast.

In `@clients/agent-runtime/crates/corvus-traits/src/testing.rs`:
- Around line 3-5: TraitHarness is currently exported publicly but is only a
placeholder; to avoid committing a public API, change its visibility to internal
by making the struct non-public (e.g., replace `pub struct TraitHarness` with
`pub(crate) struct TraitHarness` or simply `struct TraitHarness`) or gate the
entire testing module behind a feature flag so the harness does not become part
of the crate's public surface; update the declaration in testing.rs (the
`TraitHarness` type) accordingly and adjust any local references to match the
new visibility.

In `@clients/agent-runtime/tests/traits_api_compat.rs`:
- Around line 50-98: DummyMemory implementation of corvus_traits::memory::Memory
is missing the required memory_stats method; implement async fn
memory_stats(&self) -> anyhow::Result<MemoryStats> on DummyMemory (matching the
signature declared in corvus_traits::memory::Memory) and return an appropriate
dummy MemoryStats value (or Ok with default/constructed MemoryStats) so the
trait is satisfied; reference the trait name corvus_traits::memory::Memory, the
struct DummyMemory and the missing method memory_stats and the type MemoryStats
when adding the method.
🪄 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: 7dc2bbac-3cb9-4e64-bb1a-6d743f8ffc73

📥 Commits

Reviewing files that changed from the base of the PR and between 32d0410 and cef3193.

⛔ Files ignored due to path filters (1)
  • clients/agent-runtime/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (11)
  • clients/agent-runtime/Cargo.toml
  • clients/agent-runtime/crates/corvus-traits/Cargo.toml
  • clients/agent-runtime/crates/corvus-traits/src/channels.rs
  • clients/agent-runtime/crates/corvus-traits/src/lib.rs
  • clients/agent-runtime/crates/corvus-traits/src/memory.rs
  • clients/agent-runtime/crates/corvus-traits/src/security.rs
  • clients/agent-runtime/crates/corvus-traits/src/testing.rs
  • clients/agent-runtime/src/channels/traits.rs
  • clients/agent-runtime/src/memory/traits.rs
  • clients/agent-runtime/src/security/traits.rs
  • clients/agent-runtime/tests/traits_api_compat.rs
📜 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). (4)
  • GitHub Check: sonar
  • GitHub Check: pr-checks
  • GitHub Check: submit-gradle
  • GitHub Check: Cloudflare Pages
🧰 Additional context used
📓 Path-based instructions (8)
clients/agent-runtime/**/*.rs

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

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

Files:

  • clients/agent-runtime/crates/corvus-traits/src/testing.rs
  • clients/agent-runtime/crates/corvus-traits/src/lib.rs
  • clients/agent-runtime/tests/traits_api_compat.rs
  • clients/agent-runtime/src/security/traits.rs
  • clients/agent-runtime/crates/corvus-traits/src/security.rs
  • clients/agent-runtime/src/memory/traits.rs
  • clients/agent-runtime/src/channels/traits.rs
  • clients/agent-runtime/crates/corvus-traits/src/channels.rs
  • clients/agent-runtime/crates/corvus-traits/src/memory.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/crates/corvus-traits/src/testing.rs
  • clients/agent-runtime/crates/corvus-traits/src/lib.rs
  • clients/agent-runtime/tests/traits_api_compat.rs
  • clients/agent-runtime/src/security/traits.rs
  • clients/agent-runtime/crates/corvus-traits/src/security.rs
  • clients/agent-runtime/src/memory/traits.rs
  • clients/agent-runtime/src/channels/traits.rs
  • clients/agent-runtime/crates/corvus-traits/src/channels.rs
  • clients/agent-runtime/crates/corvus-traits/src/memory.rs
**/*

⚙️ 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/agent-runtime/crates/corvus-traits/src/testing.rs
  • clients/agent-runtime/Cargo.toml
  • clients/agent-runtime/crates/corvus-traits/src/lib.rs
  • clients/agent-runtime/crates/corvus-traits/Cargo.toml
  • clients/agent-runtime/tests/traits_api_compat.rs
  • clients/agent-runtime/src/security/traits.rs
  • clients/agent-runtime/crates/corvus-traits/src/security.rs
  • clients/agent-runtime/src/memory/traits.rs
  • clients/agent-runtime/src/channels/traits.rs
  • clients/agent-runtime/crates/corvus-traits/src/channels.rs
  • clients/agent-runtime/crates/corvus-traits/src/memory.rs
clients/agent-runtime/**/Cargo.toml

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

clients/agent-runtime/**/Cargo.toml: Preserve release-size profile assumptions in Cargo.toml and avoid adding heavy dependencies unless clearly justified
Do not add heavy dependencies for minor convenience; justify new crate additions

Files:

  • clients/agent-runtime/Cargo.toml
  • clients/agent-runtime/crates/corvus-traits/Cargo.toml
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/traits.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/security/traits.rs
  • clients/agent-runtime/src/memory/traits.rs
  • clients/agent-runtime/src/channels/traits.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/traits.rs
clients/agent-runtime/src/channels/**/*.rs

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

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

Files:

  • clients/agent-runtime/src/channels/traits.rs
🧠 Learnings (11)
📓 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/channels/**/*.rs : Implement `Channel` trait in `src/channels/` with consistent `send`, `listen`, and `health_check` semantics and cover auth/allowlist/health behavior with tests
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
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
📚 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/crates/corvus-traits/src/testing.rs
  • clients/agent-runtime/Cargo.toml
  • clients/agent-runtime/tests/traits_api_compat.rs
  • clients/agent-runtime/src/security/traits.rs
  • clients/agent-runtime/crates/corvus-traits/src/security.rs
  • clients/agent-runtime/src/memory/traits.rs
  • clients/agent-runtime/src/channels/traits.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/Cargo.toml
  • clients/agent-runtime/crates/corvus-traits/src/lib.rs
  • clients/agent-runtime/crates/corvus-traits/Cargo.toml
  • clients/agent-runtime/tests/traits_api_compat.rs
  • clients/agent-runtime/src/security/traits.rs
  • clients/agent-runtime/crates/corvus-traits/src/security.rs
  • clients/agent-runtime/src/memory/traits.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/Cargo.toml
  • clients/agent-runtime/crates/corvus-traits/Cargo.toml
  • clients/agent-runtime/tests/traits_api_compat.rs
  • clients/agent-runtime/src/memory/traits.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/Cargo.toml
  • clients/agent-runtime/crates/corvus-traits/Cargo.toml
  • clients/agent-runtime/tests/traits_api_compat.rs
  • clients/agent-runtime/src/security/traits.rs
  • clients/agent-runtime/crates/corvus-traits/src/security.rs
  • clients/agent-runtime/src/memory/traits.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/crates/corvus-traits/src/lib.rs
  • clients/agent-runtime/tests/traits_api_compat.rs
  • clients/agent-runtime/src/memory/traits.rs
  • clients/agent-runtime/src/channels/traits.rs
  • clients/agent-runtime/crates/corvus-traits/src/channels.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/crates/corvus-traits/src/lib.rs
  • clients/agent-runtime/tests/traits_api_compat.rs
  • clients/agent-runtime/src/security/traits.rs
  • clients/agent-runtime/crates/corvus-traits/src/security.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/crates/corvus-traits/src/lib.rs
  • clients/agent-runtime/tests/traits_api_compat.rs
  • clients/agent-runtime/src/security/traits.rs
  • clients/agent-runtime/crates/corvus-traits/src/security.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/crates/corvus-traits/src/lib.rs
  • clients/agent-runtime/tests/traits_api_compat.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/tests/traits_api_compat.rs
  • clients/agent-runtime/src/security/traits.rs
  • clients/agent-runtime/crates/corvus-traits/src/security.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/tests/traits_api_compat.rs
  • clients/agent-runtime/src/memory/traits.rs
🔇 Additional comments (3)
clients/agent-runtime/src/memory/traits.rs (1)

1-6: Compat re-export looks clean.

This keeps the legacy path intact without duplicating the contract types in two places.

clients/agent-runtime/crates/corvus-traits/src/channels.rs (1)

228-319: Good focused contract tests.

These cover the projection/filter helpers and the default trait behavior well enough to protect the extracted surface from obvious regressions.

clients/agent-runtime/crates/corvus-traits/src/memory.rs (1)

229-283: Nice coverage on the public helpers.

The Display/FromStr and serde round-trip tests are a good fit for an extracted contract crate.

Comment thread clients/agent-runtime/crates/corvus-traits/Cargo.toml Outdated
Comment thread clients/agent-runtime/crates/corvus-traits/src/channels.rs Outdated
Comment on lines +106 to +146
pub struct SendMessage {
pub content: String,
pub recipient: String,
pub subject: Option<String>,
}

impl SendMessage {
/// Create a new message with content and recipient.
pub fn new(content: impl Into<String>, recipient: impl Into<String>) -> Self {
Self {
content: content.into(),
recipient: recipient.into(),
subject: None,
}
}

/// Create a new message with content, recipient, and subject.
pub fn with_subject(
content: impl Into<String>,
recipient: impl Into<String>,
subject: impl Into<String>,
) -> Self {
Self {
content: content.into(),
recipient: recipient.into(),
subject: Some(subject.into()),
}
}
}

/// Core channel trait — implement for any messaging platform.
#[async_trait]
pub trait Channel: Send + Sync {
/// Human-readable channel name.
fn name(&self) -> &str;

/// Send a message through this channel.
async fn send(&self, message: &SendMessage) -> anyhow::Result<()>;

/// Start listening for incoming messages (long-running).
async fn listen(&self, tx: tokio::sync::mpsc::Sender<ChannelMessage>) -> anyhow::Result<()>;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

The shared send contract is still text-only.

ContentPart makes multimodal turns first-class, but SendMessage and Channel::send can only carry a String. New channel implementations built on this trait still have no way to send images or audio through the shared API, which locks in an incomplete contract at extraction time. As per coding guidelines, "Look for behavioral regressions, missing tests, and contract breaks across modules."

Proposed direction
 #[derive(Debug, Clone)]
 pub struct SendMessage {
     pub content: String,
+    pub parts: Vec<ContentPart>,
     pub recipient: String,
     pub subject: Option<String>,
 }
 
 impl SendMessage {
     /// Create a new message with content and recipient.
     pub fn new(content: impl Into<String>, recipient: impl Into<String>) -> Self {
         Self {
             content: content.into(),
+            parts: vec![],
             recipient: recipient.into(),
             subject: None,
         }
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/agent-runtime/crates/corvus-traits/src/channels.rs` around lines 106
- 146, SendMessage and Channel::send are limited to text; change the
SendMessage.payload (currently content: String) to carry multimodal data (e.g.,
Vec<ContentPart> or a single ContentPart enum) and update the constructors
(SendMessage::new and SendMessage::with_subject) to build that multimodal
payload, then update the Channel trait signature async fn send(&self, message:
&SendMessage) -> anyhow::Result<()> to accept the new SendMessage shape so all
channel implementations can send images/audio; ensure any usages of SendMessage
and Channel::send (including ChannelMessage conversions) are updated to
construct and consume the new ContentPart-based payload.

Comment on lines +169 to +222
/// Create or touch a session record (idempotent).
async fn upsert_session(
&self,
_session_id: &str,
_token_hash: Option<&str>,
) -> anyhow::Result<()> {
Ok(())
}

/// Mark a session as ended (idempotent — no-op if already ended).
async fn end_session(&self, _session_id: &str) -> anyhow::Result<()> {
Ok(())
}

/// Increment message count and update last_activity for an active session.
async fn update_session_activity(
&self,
_session_id: &str,
_token_hash: Option<&str>,
) -> anyhow::Result<()> {
Ok(())
}

/// List sessions with optional status filter, pagination, sort, and order.
async fn list_sessions(
&self,
_status: Option<SessionStatus>,
_limit: u32,
_offset: u32,
_sort: &str,
_order: &str,
) -> anyhow::Result<(Vec<SessionEntry>, u64)> {
Ok((vec![], 0))
}

/// Get a single session by ID.
async fn get_session(&self, _session_id: &str) -> anyhow::Result<Option<SessionEntry>> {
Ok(None)
}

/// List sessions scoped to a specific token hash, with pagination.
async fn list_sessions_for_token(
&self,
_token_hash: &str,
_limit: u32,
_offset: u32,
) -> anyhow::Result<(Vec<SessionEntry>, u64)> {
Ok((vec![], 0))
}

/// Return aggregated memory and session statistics.
async fn memory_stats(&self) -> anyhow::Result<MemoryStats> {
Ok(MemoryStats::default())
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Default session methods should not silently succeed.

These defaults make unsupported session management indistinguishable from successful session management. A backend can now drop session writes, always return empty listings, and still satisfy the trait, which is a bad failure mode for a shared contract. Return an error by default or split session support into a separate extension trait. As per coding guidelines, "Look for behavioral regressions, missing tests, and contract breaks across modules."

Proposed direction
     async fn upsert_session(
         &self,
         _session_id: &str,
         _token_hash: Option<&str>,
     ) -> anyhow::Result<()> {
-        Ok(())
+        anyhow::bail!("session management is not supported by this memory backend")
     }
 
     /// Mark a session as ended (idempotent — no-op if already ended).
     async fn end_session(&self, _session_id: &str) -> anyhow::Result<()> {
-        Ok(())
+        anyhow::bail!("session management is not supported by this memory backend")
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/// Create or touch a session record (idempotent).
async fn upsert_session(
&self,
_session_id: &str,
_token_hash: Option<&str>,
) -> anyhow::Result<()> {
Ok(())
}
/// Mark a session as ended (idempotent — no-op if already ended).
async fn end_session(&self, _session_id: &str) -> anyhow::Result<()> {
Ok(())
}
/// Increment message count and update last_activity for an active session.
async fn update_session_activity(
&self,
_session_id: &str,
_token_hash: Option<&str>,
) -> anyhow::Result<()> {
Ok(())
}
/// List sessions with optional status filter, pagination, sort, and order.
async fn list_sessions(
&self,
_status: Option<SessionStatus>,
_limit: u32,
_offset: u32,
_sort: &str,
_order: &str,
) -> anyhow::Result<(Vec<SessionEntry>, u64)> {
Ok((vec![], 0))
}
/// Get a single session by ID.
async fn get_session(&self, _session_id: &str) -> anyhow::Result<Option<SessionEntry>> {
Ok(None)
}
/// List sessions scoped to a specific token hash, with pagination.
async fn list_sessions_for_token(
&self,
_token_hash: &str,
_limit: u32,
_offset: u32,
) -> anyhow::Result<(Vec<SessionEntry>, u64)> {
Ok((vec![], 0))
}
/// Return aggregated memory and session statistics.
async fn memory_stats(&self) -> anyhow::Result<MemoryStats> {
Ok(MemoryStats::default())
}
/// Create or touch a session record (idempotent).
async fn upsert_session(
&self,
_session_id: &str,
_token_hash: Option<&str>,
) -> anyhow::Result<()> {
anyhow::bail!("session management is not supported by this memory backend")
}
/// Mark a session as ended (idempotent — no-op if already ended).
async fn end_session(&self, _session_id: &str) -> anyhow::Result<()> {
anyhow::bail!("session management is not supported by this memory backend")
}
/// Increment message count and update last_activity for an active session.
async fn update_session_activity(
&self,
_session_id: &str,
_token_hash: Option<&str>,
) -> anyhow::Result<()> {
Ok(())
}
/// List sessions with optional status filter, pagination, sort, and order.
async fn list_sessions(
&self,
_status: Option<SessionStatus>,
_limit: u32,
_offset: u32,
_sort: &str,
_order: &str,
) -> anyhow::Result<(Vec<SessionEntry>, u64)> {
Ok((vec![], 0))
}
/// Get a single session by ID.
async fn get_session(&self, _session_id: &str) -> anyhow::Result<Option<SessionEntry>> {
Ok(None)
}
/// List sessions scoped to a specific token hash, with pagination.
async fn list_sessions_for_token(
&self,
_token_hash: &str,
_limit: u32,
_offset: u32,
) -> anyhow::Result<(Vec<SessionEntry>, u64)> {
Ok((vec![], 0))
}
/// Return aggregated memory and session statistics.
async fn memory_stats(&self) -> anyhow::Result<MemoryStats> {
Ok(MemoryStats::default())
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/agent-runtime/crates/corvus-traits/src/memory.rs` around lines 169 -
222, The default implementations for session-related trait methods
(upsert_session, end_session, update_session_activity, list_sessions,
get_session, list_sessions_for_token, memory_stats) currently return
success/empty results which hides unsupported backends; change these defaults to
return a clear error (e.g., Err(anyhow::anyhow!("session management not
supported by this backend")) ) so callers can detect lack of support, or
alternatively extract these methods into a separate extension trait (e.g.,
SessionStore) and remove default no-op implementations from the main trait;
update the trait definition to either return the explicit Err for each of the
listed methods or move them to the new extension trait so unsupported
implementations fail fast.

Comment thread clients/agent-runtime/crates/corvus-traits/src/testing.rs Outdated
Comment on lines +50 to +98
#[async_trait]
impl corvus_traits::memory::Memory for DummyMemory {
fn name(&self) -> &str {
"dummy"
}

async fn store(
&self,
_key: &str,
_content: &str,
_category: MemoryCategory,
_session_id: Option<&str>,
) -> anyhow::Result<()> {
Ok(())
}

async fn recall(
&self,
_query: &str,
_limit: usize,
_session_id: Option<&str>,
) -> anyhow::Result<Vec<corvus_traits::memory::MemoryEntry>> {
Ok(Vec::new())
}

async fn get(&self, _key: &str) -> anyhow::Result<Option<corvus_traits::memory::MemoryEntry>> {
Ok(None)
}

async fn list(
&self,
_category: Option<&MemoryCategory>,
_session_id: Option<&str>,
) -> anyhow::Result<Vec<corvus_traits::memory::MemoryEntry>> {
Ok(Vec::new())
}

async fn forget(&self, _key: &str) -> anyhow::Result<bool> {
Ok(false)
}

async fn count(&self) -> anyhow::Result<usize> {
Ok(0)
}

async fn health_check(&self) -> bool {
true
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

DummyMemory no longer satisfies the extracted trait.

corvus_traits::memory::Memory still requires memory_stats(&self) -> anyhow::Result<MemoryStats> in clients/agent-runtime/crates/corvus-traits/src/memory.rs:119-221. Without that method, this test target will not compile, so the API-compat suite cannot run.

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

In `@clients/agent-runtime/tests/traits_api_compat.rs` around lines 50 - 98,
DummyMemory implementation of corvus_traits::memory::Memory is missing the
required memory_stats method; implement async fn memory_stats(&self) ->
anyhow::Result<MemoryStats> on DummyMemory (matching the signature declared in
corvus_traits::memory::Memory) and return an appropriate dummy MemoryStats value
(or Ok with default/constructed MemoryStats) so the trait is satisfied;
reference the trait name corvus_traits::memory::Memory, the struct DummyMemory
and the missing method memory_stats and the type MemoryStats when adding the
method.

* refactor(agent-runtime): extract tool traits into corvus-traits

* fix(agent-runtime): address corvus-traits review feedback

* test(agent-runtime): extend tool traits compatibility coverage
@cloudflare-workers-and-pages
Copy link
Copy Markdown

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

Deploying corvus with  Cloudflare Pages  Cloudflare Pages

Latest commit: 20c0527
Status: ✅  Deploy successful!
Preview URL: https://593974f1.corvus-42x.pages.dev
Branch Preview URL: https://feature-capability-architect.corvus-42x.pages.dev

View logs

yacosta738 and others added 12 commits April 11, 2026 09:24
* chore(deps): bump @astrojs/starlight in / (#501)

Bumps [@astrojs/starlight](https://github.com/withastro/starlight/tree/HEAD/packages/starlight) in `/` from 0.38.2 to 0.38.3.


Updates `@astrojs/starlight` from 0.38.2 to 0.38.3
- [Release notes](https://github.com/withastro/starlight/releases)
- [Changelog](https://github.com/withastro/starlight/blob/main/packages/starlight/CHANGELOG.md)
- [Commits](https://github.com/withastro/starlight/commits/@astrojs/starlight@0.38.3/packages/starlight)

Updates `@astrojs/starlight` from 0.38.2 to 0.38.3
- [Release notes](https://github.com/withastro/starlight/releases)
- [Changelog](https://github.com/withastro/starlight/blob/main/packages/starlight/CHANGELOG.md)
- [Commits](https://github.com/withastro/starlight/commits/@astrojs/starlight@0.38.3/packages/starlight)

---
updated-dependencies:
- dependency-name: "@astrojs/starlight"
  dependency-version: 0.38.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm_and_yarn
- dependency-name: "@astrojs/starlight"
  dependency-version: 0.38.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* refactor: simplify PR size labeler workflow configuration

* feat: add capability family crates with registry APIs

Phase 2A: Extract capability family crates with feature-gated registries

This PR adds the following capability crates:
- corvus-providers: LLM provider registry with create_provider() and available_providers()
- corvus-channels: Messaging channel registry with create_channel() and available_channels()
- corvus-tools: Agent tool registry with create_tool() and available_tools()
- corvus-memory: Memory backend registry with create_memory() and available_memory_backends()
- corvus-security: Security/sandbox registry with create_sandbox() and available_sandboxes()

Each crate:
- Depends on corvus-traits for trait definitions
- Re-exports trait types for convenience
- Provides registry functions for capability discovery
- Uses corvus-traits as the foundation for capability abstraction

The main corvus crate now depends on these new crates, establishing the
foundation for future feature-gated capability registries.

Tests: 76 provider tests, 8 registry tests all pass
Clippy: passes with no warnings

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…schema (#511)

Implements Phase 3A (Agent Manifest) and Phase 3B (AgentComposer):

- Creates  with:
  - AgentManifest TOML schema (serializable Rust structs)
  - Validation rules per PRD (R1-R7):
    - R1: At least one provider
    - R2: At least one channel
    - R3: Default provider must be enabled
    - R4: Enabled capabilities must be known
    - R5: Memory backend must be valid
    - R6: Security sandbox must be valid
    - R7: Tool restrictions must be subset
  - ValidationError enum for structured errors
  - CapabilityReport for introspection
  - Known capability registries (providers, channels, tools, backends)

- Implements AgentComposer that:
  - Parses manifests from TOML string or file
  - Validates against PRD requirements
  - Provides required_capabilities() introspection
  - Provides validate_with_warnings() for non-blocking issues

- Adds crate to workspace and wires into main corvus crate

Note: Registry resolution delegating to bootstrap (not implemented in composer)
Implement corvus agent build/run/new subcommands backed by corvus-composer.

- Add composer.rs module with handle_composer_command dispatcher
- Wire AgentCompositionCommands enum into the Agent CLI subcommand
- handle_build_command: validates manifest, checks capabilities, scaffolds output dir
- handle_run_command: validates + checks platform constraints, stubs boot-time run
- handle_new_command: generates TOML manifest from chat-bot/support-bot/code-assistant templates
- Add 15 unit tests covering templates, new-command validation, build/run happy/error paths,
  and sandbox platform availability
- Legacy 'corvus agent' interactive loop preserved via optional subcommand

Part of issue #481 (Phase 4: CLI composition flows).
…for Phase 5B (#514)

- add six agent template manifests under agents/templates/:
  minimal, chat-bot, support-agent, code-assistant, research-agent, ops-agent
- all templates pass AgentComposer validation (R1-R7 rules)
- add docs/composing-agents.md: manifest reference, CLI usage, security notes,
  capability constraints, platform limitations, migration guide, troubleshooting
- add nine template compliance tests in corvus-composer:
  one per template (parse + validate), unique-name check,
  ops-agent sandbox assertion, minimal no-tools assertion

Closes DALLAY-263
@sonarqubecloud
Copy link
Copy Markdown

@yacosta738 yacosta738 marked this pull request as ready for review April 11, 2026 17:27
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 17

🤖 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/agents/templates/chat-bot.toml`:
- Line 22: The template uses a time-limited model identifier
"claude-haiku-4-5-20251001"; update the model declaration in the chat-bot
template to use the stable alias "claude-haiku-4-5" instead so the template
resolves to the latest supported version (locate the model = line in the
agents/templates/chat-bot.toml and replace the versioned ID with the alias).

In `@clients/agent-runtime/agents/templates/code-assistant.toml`:
- Around line 35-43: The template currently hardcodes sandbox = "none" which
makes agents with tools ["shell","file_write","git_operations"] fully
unsandboxed; change the default sandbox value in
clients/agent-runtime/agents/templates/code-assistant.toml from "none" to a
secure default (e.g., "landlock" or "restricted"/"auto-detect") and require an
explicit user override to opt out (do not silently fall back to none); update
the sandbox key and add a clear comment that unsupported platforms must
explicitly set sandbox="none" if they accept the risk, and ensure any
generator/loader that emits this template honors the explicit override flag for
sandboxing.

In `@clients/agent-runtime/agents/templates/ops-agent.toml`:
- Around line 31-33: The template enables the "webhook" channel in the channels
array in ops-agent.toml (channels = ["slack", "webhook", "stdio"]) for a
high-privilege agent without any webhook auth/allowlist settings; remove
"webhook" from the channels list (or replace it with a safe default) for this
high-privilege template OR explicitly add strict webhook authentication and
allowlist configuration entries (e.g., webhook_auth, webhook_allowlist, and any
required validation hooks) and wire them into the agent startup logic so that
the "webhook" channel cannot be used without auth; update the template where
channels/default are defined to reflect the safe choice.

In `@clients/agent-runtime/Cargo.toml`:
- Around line 87-93: Remove the unused workspace dependencies from the root
Cargo.toml: corvus-providers, corvus-channels, corvus-tools, corvus-memory, and
corvus-security are not directly used by the root crate and should be deleted
from clients/agent-runtime/Cargo.toml; instead add each of those as a dependency
in their respective sub-crate Cargo.toml (providers/, channels/, tools/,
memory/, security/) using the same path spec (e.g., corvus-providers = { path =
"crates/corvus-providers" }) so the sub-crates declare and own their transitive
dependencies, leave corvus-traits and corvus-composer in the root where they are
actually imported, then run cargo metadata / cargo check to verify no missing
dependencies.

In `@clients/agent-runtime/crates/corvus-composer/src/lib.rs`:
- Around line 297-313: The constructor unnecessarily clones manifest; in
from_manifest avoid manifest.clone() by first constructing the CapabilityReport
from manifest (use manifest.providers/providers, manifest.channels/channels,
manifest.tools/tools, manifest.memory, manifest.observer, manifest.security) and
then move manifest into Self so you set manifest: manifest (moved) and reports:
the previously built CapabilityReport; update names in this function
(from_manifest, CapabilityReport, composer) accordingly so no clone is required
and composer.validate() remains unchanged.
- Around line 386-394: The current validation in manifest.security ->
security.sandbox lets an empty string slip through because of the
`!sandbox.is_empty()` guard; update the check so an empty sandbox is treated as
invalid: instead of skipping validation for empty strings, explicitly reject
sandbox == "" (return ValidationError::InvalidSandboxBackend with the sandbox
clone) or restructure the condition to only accept sandbox values that are
either "none" or contained in KNOWN_SANDBOX_BACKENDS; adjust the logic around
security.sandbox and KNOWN_SANDBOX_BACKENDS and ensure the same
ValidationError::InvalidSandboxBackend path is used for empty strings.

In `@clients/agent-runtime/crates/corvus-memory/Cargo.toml`:
- Line 12: Remove the unused dependency "anyhow" from the corvus-memory crate by
deleting the anyhow = "1.0" entry from the crate's Cargo.toml; this crate only
re-exports corvus-traits and defines MemoryInfo (no error handling), so ensure
no other source files (e.g., lib.rs or mod files) reference anyhow before
committing the Cargo.toml change and running cargo check to update Cargo.lock if
necessary.

In `@clients/agent-runtime/crates/corvus-providers/Cargo.toml`:
- Around line 10-12: Remove the unused anyhow dependency entry from the crate's
Cargo.toml (delete the line `anyhow = "1.0"`), then run cargo check/cargo build
to ensure there are no remaining references and update Cargo.lock (cargo update)
if necessary; the change affects the corvus-providers crate's Cargo.toml and
targets removal of the `anyhow` dependency only.

In `@clients/agent-runtime/crates/corvus-traits/Cargo.toml`:
- Line 14: The StreamError enum in providers.rs currently exposes reqwest::Error
which couples corvus-traits to the reqwest HTTP client; change StreamError to
use a transport-neutral variant (e.g., Transport(Box<dyn std::error::Error +
Send + Sync>) or Transport(String/any opaque wrapper) instead of
reqwest::Error), update any match arms and conversions that construct
StreamError::Reqwest to produce the new Transport variant, and remove reqwest
from corvus-traits' Cargo.toml so the trait crate no longer depends on reqwest;
keep conversions from HTTP clients in their own crates to map reqwest::Error
into the new Transport variant.

In `@clients/agent-runtime/crates/corvus-traits/src/multimedia.rs`:
- Around line 186-191: sanitize_history_text currently only removes CR/LF which
permits bracket injection into the synthetic “[Prior ...]” envelope; update
sanitize_history_text to also remove or neutralize bracket characters (at
minimum '[' and ']'), other delimiter characters like '{','}','<','>', and all
control characters (chars where is_control() is true), collapse runs of
whitespace into a single space, and then enforce the 200‑char limit so the
output cannot break the history envelope used by history renderers and the
reshape model context; modify the implementation inside sanitize_history_text
accordingly so callers continue to receive a cleaned, safe string.

In `@clients/agent-runtime/crates/corvus-traits/src/providers.rs`:
- Around line 379-398: The default chat_with_history currently drops prior turns
by only passing the last user message to chat_with_system; instead, preserve
multi-turn context by concatenating the full non-system message sequence (using
ChatMessage.role and .content to build a single conversation string with clear
role markers or separators) and pass that combined string as the user input to
chat_with_system; update the async fn chat_with_history implementation to build
that combined conversation from messages.iter() (including assistant and earlier
user turns) and then call self.chat_with_system(system, combined_conversation,
model, temperature).
- Around line 315-331: The tool name/description are injected raw into the
system prompt (via build_tool_instructions_text →
build_tool_augmented_messages), allowing Markdown/newline injection;
sanitize/escape tool.name and tool.description before formatting the instruction
string (i.e., in build_tool_instructions_text) by normalizing or removing line
breaks and escaping Markdown-special characters (e.g., *, _, `, #, >, [ ], etc.)
or replacing newlines with single spaces so the resulting string cannot close or
create new Markdown blocks, then pass the escaped string into
build_tool_augmented_messages (which can continue using ChatMessage::system).

In `@clients/agent-runtime/crates/corvus-traits/src/testing.rs`:
- Around line 82-88: The macro's test (complies_with_execute_contract) currently
calls instance.execute(serde_json::json!({})) which will cause valid tools
needing required params to fail; update the macro so it either (A) uses the
$factory to also produce minimal valid args and call
instance.execute(minimal_args).await and assert Ok, or (B) relax the assertion
to accept a well-formed validation error by matching result:
assert!(result.is_ok() || is_validation_error(&result), "execute must return Ok
or validation error: {:?}", result), referencing the execute method and $factory
to locate the code; alternatively add a short doc comment to the macro
explaining that factories should supply minimal valid args if their tool
requires them.

In `@clients/agent-runtime/docs/composing-agents.md`:
- Around line 259-269: The fenced code block showing the "Expected output" in
composing-agents.md currently has no language identifier and triggers MD040;
update that block by adding a language tag such as "text" or "plaintext" (e.g.,
```text) before the manifest example so the CLI-style output is recognized by
markdownlint and the example remains unchanged; locate the block containing the
lines "Manifest valid." and "Capability report:" to apply the change.

In `@clients/agent-runtime/src/channels/media.rs`:
- Around line 195-204: The current cleanup_staged_image function uses a racy
exists() pre-check; instead call std::fs::remove_file(&staged.temp_path) once
and only log a warning when the error kind is not ErrorKind::NotFound. Update
cleanup_staged_image (operating on StagedImage / staged.temp_path) to attempt
removal unconditionally and suppress/remove the warning for errors where
e.kind() == std::io::ErrorKind::NotFound, preserving the existing warning for
other error kinds.

In `@clients/agent-runtime/src/composer.rs`:
- Around line 195-198: The fallback construction for output_path uses
output.or_else(|| Some(PathBuf::from("agents"))).unwrap() which is verbose;
change it to use output.unwrap_or_else(|| PathBuf::from("agents")) and then call
.join(format!("{}.toml", name)) so the variable building output_path (in
composer.rs where output_path is defined) uses unwrap_or_else on the output
Option to produce the default PathBuf.
- Around line 180-189: The current validation on the agent name only blocks '/'
and '\' but still allows path-traversal like '..'; update the validation in the
code paths that handle the agent name (e.g., the variable name and callers such
as handle_new_command) to reject any path traversal or multi-component names:
either explicitly disallow the substring ".." and leading/trailing '.' or,
better, use std::path::Path::new(name).components() and ensure it yields exactly
one Component::Normal (no ParentDir, RootDir, Prefix, or multiple components).
Return a clear error (e.g., "Agent name cannot contain path separators or
traversal components") when this check fails and keep the existing empty-name
check.
🪄 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: 14bdb787-fab8-4c4e-8554-47954242aadc

📥 Commits

Reviewing files that changed from the base of the PR and between cef3193 and 20c0527.

⛔ Files ignored due to path filters (2)
  • clients/agent-runtime/Cargo.lock is excluded by !**/*.lock
  • modules/cerebro/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (42)
  • clients/agent-runtime/Cargo.toml
  • clients/agent-runtime/agents/templates/chat-bot.toml
  • clients/agent-runtime/agents/templates/code-assistant.toml
  • clients/agent-runtime/agents/templates/minimal.toml
  • clients/agent-runtime/agents/templates/ops-agent.toml
  • clients/agent-runtime/agents/templates/research-agent.toml
  • clients/agent-runtime/agents/templates/support-agent.toml
  • clients/agent-runtime/crates/corvus-channels/Cargo.toml
  • clients/agent-runtime/crates/corvus-channels/src/lib.rs
  • clients/agent-runtime/crates/corvus-composer/Cargo.toml
  • clients/agent-runtime/crates/corvus-composer/src/lib.rs
  • clients/agent-runtime/crates/corvus-memory/Cargo.toml
  • clients/agent-runtime/crates/corvus-memory/src/lib.rs
  • clients/agent-runtime/crates/corvus-providers/Cargo.toml
  • clients/agent-runtime/crates/corvus-providers/src/lib.rs
  • clients/agent-runtime/crates/corvus-security/Cargo.toml
  • clients/agent-runtime/crates/corvus-security/src/lib.rs
  • clients/agent-runtime/crates/corvus-tools/Cargo.toml
  • clients/agent-runtime/crates/corvus-tools/src/lib.rs
  • clients/agent-runtime/crates/corvus-traits/Cargo.toml
  • clients/agent-runtime/crates/corvus-traits/src/channels.rs
  • clients/agent-runtime/crates/corvus-traits/src/lib.rs
  • clients/agent-runtime/crates/corvus-traits/src/multimedia.rs
  • clients/agent-runtime/crates/corvus-traits/src/providers.rs
  • clients/agent-runtime/crates/corvus-traits/src/testing.rs
  • clients/agent-runtime/crates/corvus-traits/src/tools.rs
  • clients/agent-runtime/docs/composing-agents.md
  • clients/agent-runtime/src/channels/audio_media.rs
  • clients/agent-runtime/src/channels/discord.rs
  • clients/agent-runtime/src/channels/media.rs
  • clients/agent-runtime/src/channels/mod.rs
  • clients/agent-runtime/src/channels/slack.rs
  • clients/agent-runtime/src/composer.rs
  • clients/agent-runtime/src/lib.rs
  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/providers/mod.rs
  • clients/agent-runtime/src/providers/reliable.rs
  • clients/agent-runtime/src/providers/router.rs
  • clients/agent-runtime/src/providers/traits.rs
  • clients/agent-runtime/src/tools/traits.rs
  • clients/agent-runtime/tests/traits_api_compat.rs
  • dev/cli.sh
📜 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: sonar
  • GitHub Check: pr-checks
  • GitHub Check: Cloudflare Pages
🧰 Additional context used
📓 Path-based instructions (12)
clients/agent-runtime/**/Cargo.toml

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

clients/agent-runtime/**/Cargo.toml: Preserve release-size profile assumptions in Cargo.toml and avoid adding heavy dependencies unless clearly justified
Do not add heavy dependencies for minor convenience; justify new crate additions

Files:

  • clients/agent-runtime/crates/corvus-providers/Cargo.toml
  • clients/agent-runtime/crates/corvus-tools/Cargo.toml
  • clients/agent-runtime/crates/corvus-channels/Cargo.toml
  • clients/agent-runtime/crates/corvus-composer/Cargo.toml
  • clients/agent-runtime/crates/corvus-security/Cargo.toml
  • clients/agent-runtime/crates/corvus-memory/Cargo.toml
  • clients/agent-runtime/Cargo.toml
  • clients/agent-runtime/crates/corvus-traits/Cargo.toml
**/*

⚙️ 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/agent-runtime/crates/corvus-providers/Cargo.toml
  • clients/agent-runtime/src/channels/discord.rs
  • clients/agent-runtime/crates/corvus-tools/Cargo.toml
  • clients/agent-runtime/src/channels/slack.rs
  • clients/agent-runtime/crates/corvus-traits/src/lib.rs
  • clients/agent-runtime/crates/corvus-channels/Cargo.toml
  • clients/agent-runtime/src/lib.rs
  • clients/agent-runtime/crates/corvus-composer/Cargo.toml
  • clients/agent-runtime/crates/corvus-security/Cargo.toml
  • clients/agent-runtime/crates/corvus-memory/Cargo.toml
  • clients/agent-runtime/crates/corvus-tools/src/lib.rs
  • clients/agent-runtime/src/providers/mod.rs
  • clients/agent-runtime/agents/templates/minimal.toml
  • clients/agent-runtime/crates/corvus-security/src/lib.rs
  • clients/agent-runtime/Cargo.toml
  • clients/agent-runtime/crates/corvus-channels/src/lib.rs
  • clients/agent-runtime/src/providers/reliable.rs
  • clients/agent-runtime/agents/templates/chat-bot.toml
  • clients/agent-runtime/src/providers/router.rs
  • clients/agent-runtime/crates/corvus-memory/src/lib.rs
  • clients/agent-runtime/docs/composing-agents.md
  • clients/agent-runtime/crates/corvus-providers/src/lib.rs
  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/agents/templates/research-agent.toml
  • clients/agent-runtime/agents/templates/ops-agent.toml
  • clients/agent-runtime/agents/templates/code-assistant.toml
  • clients/agent-runtime/agents/templates/support-agent.toml
  • clients/agent-runtime/src/channels/audio_media.rs
  • clients/agent-runtime/src/channels/mod.rs
  • clients/agent-runtime/crates/corvus-traits/Cargo.toml
  • clients/agent-runtime/tests/traits_api_compat.rs
  • clients/agent-runtime/src/tools/traits.rs
  • clients/agent-runtime/src/channels/media.rs
  • clients/agent-runtime/crates/corvus-traits/src/multimedia.rs
  • clients/agent-runtime/src/providers/traits.rs
  • clients/agent-runtime/src/composer.rs
  • clients/agent-runtime/crates/corvus-traits/src/testing.rs
  • clients/agent-runtime/crates/corvus-traits/src/tools.rs
  • clients/agent-runtime/crates/corvus-traits/src/channels.rs
  • clients/agent-runtime/crates/corvus-composer/src/lib.rs
  • clients/agent-runtime/crates/corvus-traits/src/providers.rs
clients/agent-runtime/src/channels/**/*.rs

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

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

Files:

  • clients/agent-runtime/src/channels/discord.rs
  • clients/agent-runtime/src/channels/slack.rs
  • clients/agent-runtime/src/channels/audio_media.rs
  • clients/agent-runtime/src/channels/mod.rs
  • clients/agent-runtime/src/channels/media.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/channels/discord.rs
  • clients/agent-runtime/src/channels/slack.rs
  • clients/agent-runtime/src/lib.rs
  • clients/agent-runtime/src/providers/mod.rs
  • clients/agent-runtime/src/providers/reliable.rs
  • clients/agent-runtime/src/providers/router.rs
  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/channels/audio_media.rs
  • clients/agent-runtime/src/channels/mod.rs
  • clients/agent-runtime/src/tools/traits.rs
  • clients/agent-runtime/src/channels/media.rs
  • clients/agent-runtime/src/providers/traits.rs
  • clients/agent-runtime/src/composer.rs
clients/agent-runtime/**/*.rs

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

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

Files:

  • clients/agent-runtime/src/channels/discord.rs
  • clients/agent-runtime/src/channels/slack.rs
  • clients/agent-runtime/crates/corvus-traits/src/lib.rs
  • clients/agent-runtime/src/lib.rs
  • clients/agent-runtime/crates/corvus-tools/src/lib.rs
  • clients/agent-runtime/src/providers/mod.rs
  • clients/agent-runtime/crates/corvus-security/src/lib.rs
  • clients/agent-runtime/crates/corvus-channels/src/lib.rs
  • clients/agent-runtime/src/providers/reliable.rs
  • clients/agent-runtime/src/providers/router.rs
  • clients/agent-runtime/crates/corvus-memory/src/lib.rs
  • clients/agent-runtime/crates/corvus-providers/src/lib.rs
  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/channels/audio_media.rs
  • clients/agent-runtime/src/channels/mod.rs
  • clients/agent-runtime/tests/traits_api_compat.rs
  • clients/agent-runtime/src/tools/traits.rs
  • clients/agent-runtime/src/channels/media.rs
  • clients/agent-runtime/crates/corvus-traits/src/multimedia.rs
  • clients/agent-runtime/src/providers/traits.rs
  • clients/agent-runtime/src/composer.rs
  • clients/agent-runtime/crates/corvus-traits/src/testing.rs
  • clients/agent-runtime/crates/corvus-traits/src/tools.rs
  • clients/agent-runtime/crates/corvus-traits/src/channels.rs
  • clients/agent-runtime/crates/corvus-composer/src/lib.rs
  • clients/agent-runtime/crates/corvus-traits/src/providers.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/channels/discord.rs
  • clients/agent-runtime/src/channels/slack.rs
  • clients/agent-runtime/crates/corvus-traits/src/lib.rs
  • clients/agent-runtime/src/lib.rs
  • clients/agent-runtime/crates/corvus-tools/src/lib.rs
  • clients/agent-runtime/src/providers/mod.rs
  • clients/agent-runtime/crates/corvus-security/src/lib.rs
  • clients/agent-runtime/crates/corvus-channels/src/lib.rs
  • clients/agent-runtime/src/providers/reliable.rs
  • clients/agent-runtime/src/providers/router.rs
  • clients/agent-runtime/crates/corvus-memory/src/lib.rs
  • clients/agent-runtime/crates/corvus-providers/src/lib.rs
  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/channels/audio_media.rs
  • clients/agent-runtime/src/channels/mod.rs
  • clients/agent-runtime/tests/traits_api_compat.rs
  • clients/agent-runtime/src/tools/traits.rs
  • clients/agent-runtime/src/channels/media.rs
  • clients/agent-runtime/crates/corvus-traits/src/multimedia.rs
  • clients/agent-runtime/src/providers/traits.rs
  • clients/agent-runtime/src/composer.rs
  • clients/agent-runtime/crates/corvus-traits/src/testing.rs
  • clients/agent-runtime/crates/corvus-traits/src/tools.rs
  • clients/agent-runtime/crates/corvus-traits/src/channels.rs
  • clients/agent-runtime/crates/corvus-composer/src/lib.rs
  • clients/agent-runtime/crates/corvus-traits/src/providers.rs
clients/agent-runtime/src/providers/**/*.rs

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

Implement Provider trait in src/providers/ and register in src/providers/mod.rs factory when adding a new provider

Files:

  • clients/agent-runtime/src/providers/mod.rs
  • clients/agent-runtime/src/providers/reliable.rs
  • clients/agent-runtime/src/providers/router.rs
  • clients/agent-runtime/src/providers/traits.rs
**/*.{md,mdx}

⚙️ CodeRabbit configuration file

**/*.{md,mdx}: Verify technical accuracy and that docs stay aligned with code changes.
For user-facing docs, check EN/ES parity or explicitly note pending translation gaps.

Files:

  • clients/agent-runtime/docs/composing-agents.md
clients/agent-runtime/src/main.rs

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

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

Files:

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

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

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

Files:

  • clients/agent-runtime/src/tools/traits.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/tools/traits.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/tools/traits.rs
🧠 Learnings (15)
📓 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/channels/**/*.rs : Implement `Channel` trait in `src/channels/` with consistent `send`, `listen`, and `health_check` semantics and cover auth/allowlist/health behavior with tests
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
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
📚 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/crates/corvus-providers/Cargo.toml
  • clients/agent-runtime/crates/corvus-tools/Cargo.toml
  • clients/agent-runtime/crates/corvus-traits/src/lib.rs
  • clients/agent-runtime/crates/corvus-channels/Cargo.toml
  • clients/agent-runtime/src/lib.rs
  • clients/agent-runtime/crates/corvus-composer/Cargo.toml
  • clients/agent-runtime/crates/corvus-security/Cargo.toml
  • clients/agent-runtime/crates/corvus-memory/Cargo.toml
  • clients/agent-runtime/crates/corvus-tools/src/lib.rs
  • clients/agent-runtime/src/providers/mod.rs
  • clients/agent-runtime/agents/templates/minimal.toml
  • clients/agent-runtime/crates/corvus-security/src/lib.rs
  • clients/agent-runtime/Cargo.toml
  • clients/agent-runtime/crates/corvus-providers/src/lib.rs
  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/crates/corvus-traits/Cargo.toml
  • clients/agent-runtime/tests/traits_api_compat.rs
  • clients/agent-runtime/src/tools/traits.rs
  • clients/agent-runtime/src/channels/media.rs
  • clients/agent-runtime/src/providers/traits.rs
  • clients/agent-runtime/src/composer.rs
  • clients/agent-runtime/crates/corvus-traits/src/testing.rs
  • clients/agent-runtime/crates/corvus-traits/src/tools.rs
  • clients/agent-runtime/crates/corvus-composer/src/lib.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/crates/corvus-providers/Cargo.toml
  • clients/agent-runtime/crates/corvus-tools/Cargo.toml
  • clients/agent-runtime/crates/corvus-channels/Cargo.toml
  • clients/agent-runtime/src/lib.rs
  • clients/agent-runtime/crates/corvus-composer/Cargo.toml
  • clients/agent-runtime/crates/corvus-security/Cargo.toml
  • clients/agent-runtime/crates/corvus-memory/Cargo.toml
  • clients/agent-runtime/Cargo.toml
  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/crates/corvus-traits/Cargo.toml
  • clients/agent-runtime/tests/traits_api_compat.rs
  • clients/agent-runtime/src/tools/traits.rs
  • clients/agent-runtime/src/channels/media.rs
  • clients/agent-runtime/src/composer.rs
  • clients/agent-runtime/crates/corvus-traits/src/tools.rs
  • clients/agent-runtime/crates/corvus-composer/src/lib.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/crates/corvus-providers/Cargo.toml
  • clients/agent-runtime/crates/corvus-traits/src/lib.rs
  • clients/agent-runtime/src/lib.rs
  • clients/agent-runtime/crates/corvus-tools/src/lib.rs
  • clients/agent-runtime/src/providers/mod.rs
  • clients/agent-runtime/src/providers/reliable.rs
  • clients/agent-runtime/src/providers/router.rs
  • clients/agent-runtime/crates/corvus-providers/src/lib.rs
  • clients/agent-runtime/src/channels/mod.rs
  • clients/agent-runtime/tests/traits_api_compat.rs
  • clients/agent-runtime/src/tools/traits.rs
  • clients/agent-runtime/src/providers/traits.rs
  • clients/agent-runtime/src/composer.rs
  • clients/agent-runtime/crates/corvus-traits/src/testing.rs
  • clients/agent-runtime/crates/corvus-traits/src/tools.rs
  • clients/agent-runtime/crates/corvus-composer/src/lib.rs
  • clients/agent-runtime/crates/corvus-traits/src/providers.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/crates/corvus-providers/Cargo.toml
  • clients/agent-runtime/src/channels/discord.rs
  • clients/agent-runtime/crates/corvus-tools/Cargo.toml
  • clients/agent-runtime/src/channels/slack.rs
  • clients/agent-runtime/crates/corvus-channels/Cargo.toml
  • clients/agent-runtime/src/lib.rs
  • clients/agent-runtime/crates/corvus-composer/Cargo.toml
  • clients/agent-runtime/crates/corvus-security/Cargo.toml
  • clients/agent-runtime/crates/corvus-memory/Cargo.toml
  • clients/agent-runtime/Cargo.toml
  • clients/agent-runtime/docs/composing-agents.md
  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/channels/mod.rs
  • clients/agent-runtime/crates/corvus-traits/Cargo.toml
  • clients/agent-runtime/tests/traits_api_compat.rs
  • clients/agent-runtime/src/tools/traits.rs
  • clients/agent-runtime/src/channels/media.rs
  • clients/agent-runtime/src/composer.rs
  • clients/agent-runtime/crates/corvus-traits/src/testing.rs
  • clients/agent-runtime/crates/corvus-traits/src/tools.rs
  • clients/agent-runtime/crates/corvus-composer/src/lib.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/channels/discord.rs
  • clients/agent-runtime/src/channels/slack.rs
  • clients/agent-runtime/src/lib.rs
  • clients/agent-runtime/src/providers/mod.rs
  • clients/agent-runtime/Cargo.toml
  • clients/agent-runtime/docs/composing-agents.md
  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/channels/mod.rs
  • clients/agent-runtime/crates/corvus-traits/Cargo.toml
  • clients/agent-runtime/tests/traits_api_compat.rs
  • clients/agent-runtime/src/tools/traits.rs
  • clients/agent-runtime/src/channels/media.rs
  • clients/agent-runtime/src/providers/traits.rs
  • clients/agent-runtime/src/composer.rs
  • clients/agent-runtime/crates/corvus-traits/src/testing.rs
  • clients/agent-runtime/crates/corvus-traits/src/tools.rs
  • clients/agent-runtime/crates/corvus-composer/src/lib.rs
  • clients/agent-runtime/crates/corvus-traits/src/providers.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/crates/corvus-tools/Cargo.toml
  • clients/agent-runtime/crates/corvus-tools/src/lib.rs
  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/crates/corvus-traits/Cargo.toml
  • clients/agent-runtime/tests/traits_api_compat.rs
  • clients/agent-runtime/src/tools/traits.rs
  • clients/agent-runtime/src/providers/traits.rs
  • clients/agent-runtime/src/composer.rs
  • clients/agent-runtime/crates/corvus-traits/src/testing.rs
  • clients/agent-runtime/crates/corvus-traits/src/tools.rs
  • clients/agent-runtime/crates/corvus-composer/src/lib.rs
  • clients/agent-runtime/crates/corvus-traits/src/providers.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/channels/slack.rs
  • clients/agent-runtime/crates/corvus-traits/src/lib.rs
  • clients/agent-runtime/crates/corvus-channels/Cargo.toml
  • clients/agent-runtime/src/providers/mod.rs
  • clients/agent-runtime/crates/corvus-channels/src/lib.rs
  • clients/agent-runtime/src/channels/mod.rs
  • clients/agent-runtime/crates/corvus-traits/Cargo.toml
  • clients/agent-runtime/tests/traits_api_compat.rs
  • clients/agent-runtime/src/channels/media.rs
  • clients/agent-runtime/src/providers/traits.rs
  • clients/agent-runtime/crates/corvus-traits/src/testing.rs
  • clients/agent-runtime/crates/corvus-traits/src/channels.rs
  • clients/agent-runtime/crates/corvus-traits/src/providers.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/crates/corvus-traits/src/lib.rs
  • clients/agent-runtime/crates/corvus-security/Cargo.toml
  • clients/agent-runtime/crates/corvus-security/src/lib.rs
  • clients/agent-runtime/Cargo.toml
  • clients/agent-runtime/crates/corvus-traits/Cargo.toml
  • clients/agent-runtime/tests/traits_api_compat.rs
  • clients/agent-runtime/src/tools/traits.rs
  • clients/agent-runtime/crates/corvus-traits/src/tools.rs
  • clients/agent-runtime/crates/corvus-composer/src/lib.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/crates/corvus-traits/src/lib.rs
  • clients/agent-runtime/crates/corvus-security/Cargo.toml
  • clients/agent-runtime/crates/corvus-security/src/lib.rs
  • clients/agent-runtime/Cargo.toml
  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/tests/traits_api_compat.rs
  • clients/agent-runtime/src/tools/traits.rs
  • clients/agent-runtime/crates/corvus-composer/src/lib.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/lib.rs
  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/channels/mod.rs
  • clients/agent-runtime/crates/corvus-traits/Cargo.toml
  • clients/agent-runtime/tests/traits_api_compat.rs
  • clients/agent-runtime/src/tools/traits.rs
📚 Learning: 2026-02-17T07:28:38.934Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-17T07:28:38.934Z
Learning: Applies to .agents/AGENTS.md : Document agent configurations and capabilities in AGENTS.md

Applied to files:

  • clients/agent-runtime/agents/templates/minimal.toml
  • clients/agent-runtime/docs/composing-agents.md
  • clients/agent-runtime/agents/templates/research-agent.toml
  • clients/agent-runtime/agents/templates/ops-agent.toml
  • clients/agent-runtime/agents/templates/code-assistant.toml
  • clients/agent-runtime/agents/templates/support-agent.toml
📚 Learning: 2026-02-17T07:28:38.934Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-17T07:28:38.934Z
Learning: Applies to .agents/AGENTS.md : Maintain comprehensive agent metadata including name, description, purpose, and capabilities

Applied to files:

  • clients/agent-runtime/docs/composing-agents.md
  • clients/agent-runtime/agents/templates/research-agent.toml
  • clients/agent-runtime/agents/templates/ops-agent.toml
📚 Learning: 2026-02-17T07:28:38.934Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-17T07:28:38.934Z
Learning: Applies to .agents/AGENTS.md : Include version information and compatibility details for agents

Applied to files:

  • clients/agent-runtime/docs/composing-agents.md
📚 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/main.rs
  • clients/agent-runtime/crates/corvus-traits/Cargo.toml
  • clients/agent-runtime/src/composer.rs
🪛 markdownlint-cli2 (0.22.0)
clients/agent-runtime/docs/composing-agents.md

[warning] 261-261: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 292-292: Spaces inside code span elements

(MD038, no-space-in-code)

🔇 Additional comments (37)
clients/agent-runtime/src/channels/media.rs (1)

3-5: No action required. The cited call sites in clients/agent-runtime/src/gateway/mod.rs and clients/agent-runtime/src/channels/cli.rs operate on StagedAudio objects (from audio_media), not StagedImage. StagedAudio retains its own cleanup() inherent method and is separate from the StagedImage refactoring to use cleanup_staged_image(). The migration is complete within its scope.

			> Likely an incorrect or invalid review comment.
clients/agent-runtime/src/channels/slack.rs (1)

913-913: Good refactor to centralized staged-image cleanup.

This keeps test behavior intact while matching the new cleanup contract used across channels.

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

1053-1053: Cleanup helper migration is correct.

The updated call preserves the staged-file lifecycle expectation and aligns with the shared media cleanup path.

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

81-87: Composer module/export wiring looks good.

This cleanly exposes composition APIs from the runtime crate boundary.

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

16-17: Re-export expansion is appropriate.

Exposing streaming/capability types at this boundary improves API completeness without altering provider factory behavior.

clients/agent-runtime/crates/corvus-traits/src/lib.rs (1)

1-7: Module exports are well-structured for the extracted trait crate.

The public surface is coherent and aligns with the contract split.

clients/agent-runtime/crates/corvus-security/Cargo.toml (1)

1-15: Manifest looks clean and minimal.

The dependency set is lightweight and appropriate for a security registry crate.

clients/agent-runtime/crates/corvus-tools/src/lib.rs (1)

5-12: Tools registry surface is solid.

The re-export set and lightweight ToolInfo type are appropriate for this crate boundary.

clients/agent-runtime/crates/corvus-composer/Cargo.toml (1)

17-18: No action required.

The toml = "1.1" version constraint is valid and resolves correctly on crates.io to versions like 1.1.0 and 1.1.2. Dependency resolution will succeed.

			> Likely an incorrect or invalid review comment.
clients/agent-runtime/src/providers/router.rs (1)

239-240: Good test refactor for shared mock handles.

The MockProviderHandle(Arc<MockProvider>) delegation keeps test behavior intact while making trait-object construction explicit and consistent across router tests.

Also applies to: 310-311, 334-346, 635-636, 655-656

clients/agent-runtime/crates/corvus-security/src/lib.rs (1)

5-13: Registry surface looks clean and minimal.

Re-export plus SecurityInfo metadata is straightforward and consistent with the extraction pattern.

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

579-580: Nice consistency update for reliable-provider test mocks.

Using ModelAwareMockHandle keeps trait-object wiring explicit and still shares the same underlying mock state for assertions.

Also applies to: 855-856, 891-894, 1150-1162

clients/agent-runtime/crates/corvus-channels/src/lib.rs (1)

5-12: Looks good for a registry shim.

The re-export set and ChannelInfo metadata are clean and aligned with the crate’s purpose.

clients/agent-runtime/crates/corvus-memory/src/lib.rs (1)

5-14: Memory registry entrypoint is clean and consistent.

Type re-exports plus MemoryInfo metadata keep this crate focused and easy to consume.

clients/agent-runtime/tests/traits_api_compat.rs (3)

70-120: DummyMemory missing memory_stats method.

The corvus_traits::memory::Memory trait requires memory_stats(&self) -> anyhow::Result<MemoryStats>. Without it, this test won't compile.


172-343: LGTM — Solid TypeId equality coverage.

The exhaustive TypeId assertions across all trait objects and supporting types provide strong compile-time and runtime guarantees that the re-export shims maintain API identity.


345-380: LGTM — Runtime casting verification is valuable.

Testing that trait objects can be cast across legacy → traits → corvus_traits boundaries confirms dynamic dispatch works correctly after the refactor.

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

283-318: LGTM — CLI extension follows existing patterns.

The AgentCompositionCommands enum cleanly mirrors the ComposerCommands structure. The --manifest flag requiring a path for Build/Run variants enforces explicit manifest usage, and --template/--name for New provides a consistent scaffolding UX.


873-888: LGTM — Early dispatch keeps startup lean.

Routing to handle_agent_composition_command before the legacy agent loop avoids heavy initialization (config overrides, cost tracking, peripherals) when using composition subcommands.


1340-1365: LGTM — Clean mapping layer.

The 1:1 mapping from AgentCompositionCommands to ComposerCommands keeps the CLI layer thin and delegates logic to the composer module.

clients/agent-runtime/agents/templates/minimal.toml (1)

1-40: LGTM — Clean minimal template.

Good documentation header, structurally valid per the ToolsSection schema, and no inline secrets.

clients/agent-runtime/crates/corvus-providers/src/lib.rs (1)

1-19: LGTM — Minimal registry surface.

Clean re-export of corvus_traits::providers types with a lightweight ProviderInfo metadata struct. No unnecessary dependencies.

clients/agent-runtime/agents/templates/support-agent.toml (1)

1-65: LGTM — Well-structured support agent template.

Tool restrictions exactly match enabled tools (R7 compliant), sandbox is a known backend, and the memory path uses env-var reference. Good inline documentation.

clients/agent-runtime/agents/templates/research-agent.toml (1)

1-69: LGTM — Valid research agent template.

All tools (http_request, browser, browser_open, screenshot, web_search_tool, memory_store, memory_recall) are present in CODE_TOOL_ALLOWLIST. Tool restrictions are properly aligned.

clients/agent-runtime/docs/composing-agents.md (1)

299-314: LGTM — Security guidance is appropriate.

Good emphasis on no inline secrets, tool_restrictions as first line of defense, and explicit warnings about shell/file_write being high-privilege. The bubblewrap sandbox recommendation for ops-agent is sound.

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

1-6: LGTM — Clean compatibility shim.

Re-exports preserve the full Tool trait API including spec() and descriptor_hint() methods. The TypeId equality tests in traits_api_compat.rs confirm runtime compatibility.

clients/agent-runtime/crates/corvus-traits/src/channels.rs (3)

108-138: SendMessage remains text-only — multimodal send is still blocked.

Per the past review, SendMessage only carries content: String. Channels implementing this trait cannot send images/audio through the shared API. This locks in an incomplete contract.

Consider adding a parts: Vec<ContentPart> field to SendMessage for parity with ChannelMessage.


47-75: LGTM!

The text_projection() method now correctly falls back to self.content when parts yield no text (e.g., uncaptioned images/audio). This resolves the prior regression concern.


140-196: LGTM!

Channel trait provides sensible defaults: health always passes, typing/draft ops are no-ops. Implementations override as needed. The draft update workflow (send_draftupdate_draftfinalize_draft) is a clean progressive-disclosure pattern.

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

358-369: LGTM!

Platform-conditional sandbox availability is correctly gated via #[cfg] attributes, with appropriate test coverage for non-Linux platforms.

clients/agent-runtime/crates/corvus-traits/src/testing.rs (1)

14-55: LGTM!

Provider compliance macro correctly validates capabilities, chat contract, streaming support, and tool conversion. The $crate::providers::ToolsPayload path resolution is sound.

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

1-7: LGTM!

Clean compatibility shim re-exporting all provider contracts from corvus_traits. Maintains backward compatibility for existing consumers.

clients/agent-runtime/crates/corvus-traits/src/tools.rs (2)

57-90: LGTM!

The Tool trait enforces schema validation at registration time via spec(). The panic is acceptable here since it's a developer-facing contract violation caught at init, not a runtime user input path.


4-13: LGTM!

ToolResult serialization correctly omits structured when None, reducing payload size. Test coverage at lines 226-251 validates this behavior.

clients/agent-runtime/crates/corvus-composer/src/lib.rs (1)

494-906: LGTM!

Comprehensive test coverage: manifest parsing, validation rules, capability report accuracy, template compliance, and differential assertions. The template uniqueness check at line 736 is a nice guard against accidental collisions.

clients/agent-runtime/crates/corvus-traits/src/providers.rs (2)

480-502: LGTM!

Streaming stubs have reasonable defaults: stream_chat_with_system returns empty (silent no-op), while stream_chat_with_history returns an error chunk explaining the provider doesn't support streaming. Providers override as needed.


538-726: LGTM!

Solid test coverage: message constructors, response helpers, capability checks, tool instruction generation, image rejection, and prompt-guided tool injection flow.

[providers]
providers = ["anthropic"]
default = "anthropic"
model = "claude-haiku-4-5-20251001"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

What Anthropic API model IDs are currently supported, and is "claude-haiku-4-5-20251001" valid?

💡 Result:

The Anthropic API supports multiple Claude models, including the latest ones like claude-opus-4-6, claude-sonnet-4-6, claude-haiku-4-5-20251001, and previous versions such as claude-sonnet-4-5-20250929, claude-opus-4-5-20251101, claude-opus-4-1-20250805, claude-sonnet-4-20250514, claude-opus-4-20250514. Older models like claude-3-haiku-20240307 are deprecated. Model aliases (e.g., claude-haiku-4-5) resolve to specific versioned IDs. "claude-haiku-4-5-20251001" is valid and is the Claude API ID for Claude Haiku 4.5, confirmed as active with retirement not sooner than October 15, 2026. To get the complete current list, use the /v1/models endpoint.

Citations:


Use a stable model alias instead of a versioned ID.

The model claude-haiku-4-5-20251001 is currently valid, but versioned IDs expire (this one retires October 15, 2026). To keep the template working long-term, use a stable alias like claude-haiku-4-5 which automatically resolves to the latest supported version.

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

In `@clients/agent-runtime/agents/templates/chat-bot.toml` at line 22, The
template uses a time-limited model identifier "claude-haiku-4-5-20251001";
update the model declaration in the chat-bot template to use the stable alias
"claude-haiku-4-5" instead so the template resolves to the latest supported
version (locate the model = line in the agents/templates/chat-bot.toml and
replace the versioned ID with the alias).

Comment on lines +35 to +43
[tools]
tools = [
"file_read", # Read source files
"file_write", # Write / patch source files
"shell", # Run build / test commands
"code_search", # Semantic and keyword search across the repo
"git_operations",# Commit, diff, branch management
]
mode = "allow"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Do not ship this template unsandboxed by default.

Line 58 hardcodes sandbox = "none" even though Line 55 says Landlock on Linux. With shell, file_write, and git_operations enabled, the generated agent is a fully unsandboxed executor out of the box.

Suggested direction
 [security]
-sandbox = "none"
+sandbox = "landlock"

If unsupported platforms need an escape hatch, make that an explicit user override instead of the default.

As per coding guidelines: "Security first, performance second."

Also applies to: 57-65

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

In `@clients/agent-runtime/agents/templates/code-assistant.toml` around lines 35 -
43, The template currently hardcodes sandbox = "none" which makes agents with
tools ["shell","file_write","git_operations"] fully unsandboxed; change the
default sandbox value in
clients/agent-runtime/agents/templates/code-assistant.toml from "none" to a
secure default (e.g., "landlock" or "restricted"/"auto-detect") and require an
explicit user override to opt out (do not silently fall back to none); update
the sandbox key and add a clear comment that unsupported platforms must
explicitly set sandbox="none" if they accept the risk, and ensure any
generator/loader that emits this template honors the explicit override flag for
sandboxing.

Comment on lines +31 to +33
[channels]
channels = ["slack", "webhook", "stdio"]
default = "slack"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Do not enable webhook on the high-privilege template without auth config.

This manifest exposes remote ingress while also allowing shell, file_write, http_request, delegate, and hardware tools, but there is no webhook auth/allowlist configuration anywhere in the template. If the runtime's defaults are permissive, this becomes remote code execution by configuration.

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

Also applies to: 38-61

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

In `@clients/agent-runtime/agents/templates/ops-agent.toml` around lines 31 - 33,
The template enables the "webhook" channel in the channels array in
ops-agent.toml (channels = ["slack", "webhook", "stdio"]) for a high-privilege
agent without any webhook auth/allowlist settings; remove "webhook" from the
channels list (or replace it with a safe default) for this high-privilege
template OR explicitly add strict webhook authentication and allowlist
configuration entries (e.g., webhook_auth, webhook_allowlist, and any required
validation hooks) and wire them into the agent startup logic so that the
"webhook" channel cannot be used without auth; update the template where
channels/default are defined to reflect the safe choice.

Comment on lines +87 to +93
corvus-traits = { path = "crates/corvus-traits" }
corvus-providers = { path = "crates/corvus-providers" }
corvus-channels = { path = "crates/corvus-channels" }
corvus-tools = { path = "crates/corvus-tools" }
corvus-memory = { path = "crates/corvus-memory" }
corvus-security = { path = "crates/corvus-security" }
corvus-composer = { path = "crates/corvus-composer" }
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Verify direct symbol references from the root crate sources/tests/benches.
rg -n --type rust -C2 '\bcorvus_(traits|providers|channels|tools|memory|security|composer)\b' \
  clients/agent-runtime/src \
  clients/agent-runtime/tests \
  clients/agent-runtime/benches

Repository: dallay/corvus

Length of output: 24715


Move unnecessary dependencies from root crate to sub-crates.

Search results confirm only corvus-traits and corvus-composer are directly used by the root corvus crate. The other five dependencies (corvus-providers, corvus-channels, corvus-tools, corvus-memory, corvus-security) have no direct imports in src/, tests/, or benches/ and should be dependencies of the individual sub-crates (providers/, channels/, tools/, memory/, security/) instead. This preserves release-size assumptions and follows the dependency-weight guideline for clients/agent-runtime/**/Cargo.toml.

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

In `@clients/agent-runtime/Cargo.toml` around lines 87 - 93, Remove the unused
workspace dependencies from the root Cargo.toml: corvus-providers,
corvus-channels, corvus-tools, corvus-memory, and corvus-security are not
directly used by the root crate and should be deleted from
clients/agent-runtime/Cargo.toml; instead add each of those as a dependency in
their respective sub-crate Cargo.toml (providers/, channels/, tools/, memory/,
security/) using the same path spec (e.g., corvus-providers = { path =
"crates/corvus-providers" }) so the sub-crates declare and own their transitive
dependencies, leave corvus-traits and corvus-composer in the root where they are
actually imported, then run cargo metadata / cargo check to verify no missing
dependencies.

Comment on lines +297 to +313
pub fn from_manifest(manifest: AgentManifest) -> Result<Self> {
let composer = Self {
manifest: manifest.clone(),
reports: CapabilityReport {
providers: manifest.providers.providers.clone(),
channels: manifest.channels.channels.clone(),
tools: manifest.tools.tools.clone(),
memory_backend: manifest.memory.as_ref().map(|m| m.backend.clone()),
observer: manifest.observer.as_ref().map(|o| o.name.clone()),
sandbox: manifest.security.as_ref().and_then(|s| s.sandbox.clone()),
},
};

// Validate and return
composer.validate()?;
Ok(composer)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Unnecessary clone of manifest.

manifest.clone() at line 299 followed by field accesses on manifest - the clone could be avoided by building CapabilityReport first, then moving manifest into the struct.

Proposed fix
     pub fn from_manifest(manifest: AgentManifest) -> Result<Self> {
+        let reports = CapabilityReport {
+            providers: manifest.providers.providers.clone(),
+            channels: manifest.channels.channels.clone(),
+            tools: manifest.tools.tools.clone(),
+            memory_backend: manifest.memory.as_ref().map(|m| m.backend.clone()),
+            observer: manifest.observer.as_ref().map(|o| o.name.clone()),
+            sandbox: manifest.security.as_ref().and_then(|s| s.sandbox.clone()),
+        };
+
         let composer = Self {
-            manifest: manifest.clone(),
-            reports: CapabilityReport {
-                providers: manifest.providers.providers.clone(),
-                channels: manifest.channels.channels.clone(),
-                tools: manifest.tools.tools.clone(),
-                memory_backend: manifest.memory.as_ref().map(|m| m.backend.clone()),
-                observer: manifest.observer.as_ref().map(|o| o.name.clone()),
-                sandbox: manifest.security.as_ref().and_then(|s| s.sandbox.clone()),
-            },
+            manifest,
+            reports,
         };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
pub fn from_manifest(manifest: AgentManifest) -> Result<Self> {
let composer = Self {
manifest: manifest.clone(),
reports: CapabilityReport {
providers: manifest.providers.providers.clone(),
channels: manifest.channels.channels.clone(),
tools: manifest.tools.tools.clone(),
memory_backend: manifest.memory.as_ref().map(|m| m.backend.clone()),
observer: manifest.observer.as_ref().map(|o| o.name.clone()),
sandbox: manifest.security.as_ref().and_then(|s| s.sandbox.clone()),
},
};
// Validate and return
composer.validate()?;
Ok(composer)
}
pub fn from_manifest(manifest: AgentManifest) -> Result<Self> {
let reports = CapabilityReport {
providers: manifest.providers.providers.clone(),
channels: manifest.channels.channels.clone(),
tools: manifest.tools.tools.clone(),
memory_backend: manifest.memory.as_ref().map(|m| m.backend.clone()),
observer: manifest.observer.as_ref().map(|o| o.name.clone()),
sandbox: manifest.security.as_ref().and_then(|s| s.sandbox.clone()),
};
let composer = Self {
manifest,
reports,
};
// Validate and return
composer.validate()?;
Ok(composer)
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/agent-runtime/crates/corvus-composer/src/lib.rs` around lines 297 -
313, The constructor unnecessarily clones manifest; in from_manifest avoid
manifest.clone() by first constructing the CapabilityReport from manifest (use
manifest.providers/providers, manifest.channels/channels, manifest.tools/tools,
manifest.memory, manifest.observer, manifest.security) and then move manifest
into Self so you set manifest: manifest (moved) and reports: the previously
built CapabilityReport; update names in this function (from_manifest,
CapabilityReport, composer) accordingly so no clone is required and
composer.validate() remains unchanged.

Comment on lines +82 to +88
#[tokio::test]
async fn complies_with_execute_contract() {
let instance = $factory;
let result = instance.execute(serde_json::json!({})).await;
assert!(result.is_ok(), "execute must return Ok: {:?}", result);
}
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

execute({}) assertion may reject valid strict-schema tools.

The compliance macro asserts execute(json!({})) returns Ok, but tools with required parameters will correctly fail validation. Consider documenting that compliance tests require tools to handle empty-args gracefully or provide a factory that also supplies minimal valid args.

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

In `@clients/agent-runtime/crates/corvus-traits/src/testing.rs` around lines 82 -
88, The macro's test (complies_with_execute_contract) currently calls
instance.execute(serde_json::json!({})) which will cause valid tools needing
required params to fail; update the macro so it either (A) uses the $factory to
also produce minimal valid args and call instance.execute(minimal_args).await
and assert Ok, or (B) relax the assertion to accept a well-formed validation
error by matching result: assert!(result.is_ok() ||
is_validation_error(&result), "execute must return Ok or validation error:
{:?}", result), referencing the execute method and $factory to locate the code;
alternatively add a short doc comment to the macro explaining that factories
should supply minimal valid args if their tool requires them.

Comment on lines +259 to +269
Expected output:

```
Manifest valid.
Capability report:
providers : ["anthropic"]
channels : ["slack"]
tools : []
memory : sqlite
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Add language identifier to fenced code block.

The example output block at line 261 triggers a markdownlint warning (MD040). Consider using text or plaintext as the language identifier for CLI output.

📝 Suggested fix
 Expected output:

-```
+```text
 Manifest valid.
 Capability report:
   providers : ["anthropic"]
   channels  : ["slack"]
   tools     : []
   memory    : sqlite
</details>

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 markdownlint-cli2 (0.22.0)</summary>

[warning] 261-261: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

</details>

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @clients/agent-runtime/docs/composing-agents.md around lines 259 - 269, The
fenced code block showing the "Expected output" in composing-agents.md currently
has no language identifier and triggers MD040; update that block by adding a
language tag such as "text" or "plaintext" (e.g., ```text) before the manifest
example so the CLI-style output is recognized by markdownlint and the example
remains unchanged; locate the block containing the lines "Manifest valid." and
"Capability report:" to apply the change.


</details>

<!-- fingerprinting:phantom:medusa:ocelot:347de71b-c3af-4497-a044-ee7b096a0595 -->

<!-- This is an auto-generated comment by CodeRabbit -->

Comment on lines +195 to 204
pub fn cleanup_staged_image(staged: &StagedImage) {
if staged.temp_path.exists() {
if let Err(e) = std::fs::remove_file(&staged.temp_path) {
tracing::warn!(
"Failed to remove staged image {}: {e}",
staged.temp_path.display()
);
}
s.push(']');
s
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Ignore NotFound directly instead of checking exists().

The pre-check is racy: another path can delete the file after exists() and turn a harmless duplicate cleanup into a warning. Call remove_file once and suppress ErrorKind::NotFound, like the staged-image reaper already does.

Proposed fix
 pub fn cleanup_staged_image(staged: &StagedImage) {
-    if staged.temp_path.exists() {
-        if let Err(e) = std::fs::remove_file(&staged.temp_path) {
-            tracing::warn!(
-                "Failed to remove staged image {}: {e}",
-                staged.temp_path.display()
-            );
-        }
+    match std::fs::remove_file(&staged.temp_path) {
+        Ok(()) => {}
+        Err(e) if e.kind() == std::io::ErrorKind::NotFound => {}
+        Err(e) => {
+            tracing::warn!(
+                "Failed to remove staged image {}: {e}",
+                staged.temp_path.display()
+            );
+        }
     }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
pub fn cleanup_staged_image(staged: &StagedImage) {
if staged.temp_path.exists() {
if let Err(e) = std::fs::remove_file(&staged.temp_path) {
tracing::warn!(
"Failed to remove staged image {}: {e}",
staged.temp_path.display()
);
}
s.push(']');
s
}
}
pub fn cleanup_staged_image(staged: &StagedImage) {
match std::fs::remove_file(&staged.temp_path) {
Ok(()) => {}
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {}
Err(e) => {
tracing::warn!(
"Failed to remove staged image {}: {e}",
staged.temp_path.display()
);
}
}
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/agent-runtime/src/channels/media.rs` around lines 195 - 204, The
current cleanup_staged_image function uses a racy exists() pre-check; instead
call std::fs::remove_file(&staged.temp_path) once and only log a warning when
the error kind is not ErrorKind::NotFound. Update cleanup_staged_image
(operating on StagedImage / staged.temp_path) to attempt removal unconditionally
and suppress/remove the warning for errors where e.kind() ==
std::io::ErrorKind::NotFound, preserving the existing warning for other error
kinds.

Comment on lines +180 to +189
if name.is_empty() {
bail!("Agent name cannot be empty");
}

if name.contains('/') || name.contains('\\') {
bail!(
"Agent name '{}' contains invalid characters. Use only alphanumeric, underscore, and hyphen.",
name
);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Incomplete path-traversal validation in agent name.

The check blocks / and \ but allows .., so handle_new_command("chat-bot", "..", None) writes to agents/../.toml — escaping the intended directory.

Proposed fix
     if name.is_empty() {
         bail!("Agent name cannot be empty");
     }

-    if name.contains('/') || name.contains('\\') {
+    if name.contains('/') || name.contains('\\') || name.contains("..") {
         bail!(
-            "Agent name '{}' contains invalid characters. Use only alphanumeric, underscore, and hyphen.",
+            "Agent name '{}' contains invalid characters or sequences. Use only alphanumeric, underscore, and hyphen.",
             name
         );
     }
+
+    // Stricter: enforce alphanumeric, underscore, hyphen only
+    if !name.chars().all(|c| c.is_ascii_alphanumeric() || c == '_' || c == '-') {
+        bail!(
+            "Agent name '{}' contains invalid characters. Use only alphanumeric, underscore, and hyphen.",
+            name
+        );
+    }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/agent-runtime/src/composer.rs` around lines 180 - 189, The current
validation on the agent name only blocks '/' and '\' but still allows
path-traversal like '..'; update the validation in the code paths that handle
the agent name (e.g., the variable name and callers such as handle_new_command)
to reject any path traversal or multi-component names: either explicitly
disallow the substring ".." and leading/trailing '.' or, better, use
std::path::Path::new(name).components() and ensure it yields exactly one
Component::Normal (no ParentDir, RootDir, Prefix, or multiple components).
Return a clear error (e.g., "Agent name cannot contain path separators or
traversal components") when this check fails and keep the existing empty-name
check.

Comment on lines +195 to +198
let output_path = output
.or_else(|| Some(PathBuf::from("agents")))
.unwrap()
.join(format!("{}.toml", name));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Simplify fallback path construction.

or_else(|| Some(...)).unwrap() is roundabout; unwrap_or_else is cleaner.

Proposed fix
-    let output_path = output
-        .or_else(|| Some(PathBuf::from("agents")))
-        .unwrap()
-        .join(format!("{}.toml", name));
+    let output_path = output
+        .unwrap_or_else(|| PathBuf::from("agents"))
+        .join(format!("{}.toml", name));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let output_path = output
.or_else(|| Some(PathBuf::from("agents")))
.unwrap()
.join(format!("{}.toml", name));
let output_path = output
.unwrap_or_else(|| PathBuf::from("agents"))
.join(format!("{}.toml", name));
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/agent-runtime/src/composer.rs` around lines 195 - 198, The fallback
construction for output_path uses output.or_else(||
Some(PathBuf::from("agents"))).unwrap() which is verbose; change it to use
output.unwrap_or_else(|| PathBuf::from("agents")) and then call
.join(format!("{}.toml", name)) so the variable building output_path (in
composer.rs where output_path is defined) uses unwrap_or_else on the output
Option to produce the default PathBuf.

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