Skip to content

feat(agent-runtime): complete gateway webhook dispatcher parity#283

Merged
yacosta738 merged 11 commits into
mainfrom
feature/257-complete-gateway-parity-with-the-canonical-agent-dispatcher
Mar 20, 2026
Merged

feat(agent-runtime): complete gateway webhook dispatcher parity#283
yacosta738 merged 11 commits into
mainfrom
feature/257-complete-gateway-parity-with-the-canonical-agent-dispatcher

Conversation

@yacosta738
Copy link
Copy Markdown
Contributor

This pull request introduces support for session-scoped memory in the agent runtime, allowing agent turns and memory operations to be associated with an explicit session context. This enables more granular control over memory recall and storage, particularly useful for scenarios like multi-session conversations or webhook-based interactions. The changes include new types for turn context and results, updates to memory loader and agent APIs, and enhancements to tests for session-aware behavior.

Session Context and Turn Result Structures:

  • Introduced new types: TurnContext, AgentTurnResult, AgentTurnOutcome, and AgentTurnEvent to track session context and detailed outcomes for each agent turn. These types enable passing and recording session information and turn events throughout the agent workflow.

Agent API and Internal Refactoring:

  • Updated agent methods (e.g., prepare_turn, step, turn_with_context) to accept a TurnContext, propagate session IDs, and return richer results (AgentTurnResult). This refactoring ensures that session information is consistently used during memory and provider interactions. [1] [2] [3] [4]
  • Made from_bootstrap_with_provider public (within the crate) to facilitate agent construction with custom providers.

Memory Loader and Memory Trait Changes:

  • Modified the MemoryLoader trait and its implementations to accept an optional session_id, ensuring memory recall can be scoped to a session. Updated memory loader logic to pass this session context to the underlying memory. [1] [2] [3]

Testing Enhancements:

  • Added new test memory implementations (SessionTrackingMemory, TrackingMemory) that track session IDs used in memory operations, and extended tests to verify that the correct session context is propagated during memory recall and storage. [1] [2] [3] [4]

Public API Surface:

  • Re-exported the new turn context and result types from the agent module, making them available to consumers of the crate.

These changes collectively enable session-aware agent behavior and lay the groundwork for advanced conversational and multi-session use cases.

Closes: #257

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 20, 2026

Note

Reviews paused

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

Use the following commands to manage reviews:

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

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Routes gateway /webhook through a dispatcher-backed Agent turn with a session-aware TurnContext, threads session_id into memory recall/store, surfaces structured AgentTurnResult/events, adds a feature-flagged dispatcher path and webhook dispatcher adapter, and updates tests/specs/docs to prove parity and env-test isolation.

Changes

Cohort / File(s) Summary
Agent core
clients/agent-runtime/src/agent/agent.rs, clients/agent-runtime/src/agent/mod.rs
Added public turn types (AgentTurnOutcome, AgentTurnEvent, TurnContext, AgentTurnResult), turn_with_context, threaded TurnContext through prepare/step/finalize, replaced older turn flow, exposed from_bootstrap_with_provider as pub(crate), and added approval detection from tool-result history.
Memory loader & tests
clients/agent-runtime/src/agent/memory_loader.rs, clients/agent-runtime/src/agent/tests.rs, clients/agent-runtime/tests/memory_backend_selection.rs
Extended MemoryLoader::load_context to accept session_id: Option<&str>; updated implementations to forward session_id (Cerebro guards session-scoped remote recall), added Tracking/SessionTrackingMemory test doubles and tests asserting session-aware recall/store behavior.
Bootstrap & gateway init
clients/agent-runtime/src/bootstrap/mod.rs
Added override-aware init helper and BootstrapContext::for_gateway to bootstrap gateway Agents reusing canonical Memory/Observer; factored init helpers for overrides.
Gateway feature flag & runtime
clients/agent-runtime/src/config/schema.rs, clients/agent-runtime/src/gateway/mod.rs
Added GatewayConfig.webhook_dispatcher_enabled with env override; added resolve_session_id (validates/generates session id and source), idempotency helpers, idempotency-store additions, and feature-flagged dispatcher routing with observability and duplicate-response handling.
Webhook dispatcher module
clients/agent-runtime/src/gateway/webhook_dispatch.rs
New module providing execute(...) dispatcher adapter, request/result types (WebhookTurnRequest, WebhookTurnResult), canonical outcome mapping (WebhookTerminalOutcome), approval mapping, optional SSE event-frame emission, and provider adaptation.
Test infra & env guard
clients/agent-runtime/src/test_support.rs, clients/agent-runtime/src/agent/tests.rs
Added test-only GatewayWebhookDispatcherEnvGuard with shared mutex to serialize env-var mutation; added tests for turn_with_context, session propagation, and approval-required scenarios.
Gateway tests & idempotency
clients/agent-runtime/tests/*, clients/agent-runtime/src/gateway/mod.rs tests
Updated/added gateway tests for session resolution, dispatcher routing, idempotency duplicate behavior, SSE rules, and auth ordering; removed legacy unified-loop SSE preview assertions in fallback path.
Specs & archives
openspec/specs/..., openspec/changes/archive/...
Updated agent-loop and mcp-runtime specs to require webhook dispatcher parity; added/archived proposal/design/tasks/verify artifacts for dispatcher parity, env-flake stabilization, MCP mapping, and session-isolation proofs.

Sequence Diagram

sequenceDiagram
    participant Client
    participant Gateway as Gateway Handler
    participant Dispatcher as Webhook Dispatcher
    participant Agent
    participant Memory
    participant Tools

    Client->>Gateway: POST /webhook (with/without X-Session-Id)
    Gateway->>Gateway: resolve_session_id() -> (session_id, source)
    Gateway->>Gateway: check cfg.gateway.webhook_dispatcher_enabled
    alt Dispatcher Enabled
        Gateway->>Dispatcher: execute(WebhookTurnRequest {session_id, include_sse})
        Dispatcher->>Agent: bootstrap Agent & call turn_with_context(TurnContext)
        Agent->>Memory: load_context(user_message, session_id)
        Memory-->>Agent: recalled_context
        Agent->>Tools: dispatch/execute tools
        Tools-->>Agent: tool_results
        Agent->>Agent: detect approval_required -> set AgentTurnResult.approval_required?
        Agent->>Memory: auto_save(assistant_response, session_id)
        Agent-->>Dispatcher: AgentTurnResult (final_text, events, outcome)
        Dispatcher->>Gateway: WebhookTurnResult (mapped outcome, response_text, event_frames)
        Gateway->>Client: HTTP response (status + JSON / events_sse)
    else Legacy Fallback
        Gateway->>Gateway: pre_execution::evaluate()
        Gateway->>Agent: Provider::simple_chat(...) (legacy path)
        Agent-->>Gateway: response text
        Gateway-->>Client: HTTP response (legacy mapping)
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • yuniel-acosta
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 34.78% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'feat(agent-runtime): complete gateway webhook dispatcher parity' follows Conventional Commit style with 'feat' prefix and descriptive scope/summary.
Description check ✅ Passed The PR description is comprehensive, covering session context structures, API refactoring, memory loader changes, testing enhancements, and public API updates with clear motivation and links to specific changes.
Linked Issues check ✅ Passed The PR implements the core requirements of issue #257 by introducing session-scoped memory support, refactoring agent APIs to accept TurnContext, and enabling dispatcher-backed gateway parity through webhook dispatch mechanisms.
Out of Scope Changes check ✅ Passed All changes are directly aligned with issue #257 objectives: session context support, agent API refactoring, memory loader updates, bootstrap context enhancements, gateway webhook dispatcher implementation, and comprehensive testing.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/257-complete-gateway-parity-with-the-canonical-agent-dispatcher
📝 Coding Plan
  • Generate coding plan for human review comments

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.

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Mar 20, 2026

Deploying corvus with  Cloudflare Pages  Cloudflare Pages

Latest commit: e094d61
Status: ✅  Deploy successful!
Preview URL: https://6ea5e457.corvus-42x.pages.dev
Branch Preview URL: https://feature-257-complete-gateway.corvus-42x.pages.dev

View logs

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 20, 2026

✅ Contributor Report

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

Metric Description Value Threshold Status
PR Merge Rate PRs merged vs closed 89% >= 30%
Repo Quality Repos with ≥100 stars 0 >= 0
Positive Reactions Positive reactions received 9 >= 1
Negative Reactions Negative reactions received 0 <= 5
Account Age GitHub account age 3065 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 423 >= 0
Merger Diversity Unique maintainers who merged PRs 2 >= 0
Repo History Merge Rate Merge rate in this repo 91% >= 0%
Repo History Min PRs Previous PRs in this repo 163 >= 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-03-20 to 2026-03-20

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: 18

Caution

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

⚠️ Outside diff range comments (2)
clients/agent-runtime/src/agent/memory_loader.rs (2)

331-377: ⚠️ Potential issue | 🟡 Minor

Add a Cerebro loader session-forwarding test to prevent regressions.

You added explicit session propagation coverage for DefaultMemoryLoader, but not for CerebroMemoryLoader. Add one focused test that passes Some(session_id) and asserts recall sees that value (using endpoint-missing or egress-blocked path to avoid network calls).

As per coding guidelines **/*: Security first, performance second... Look for ... missing tests ....

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

In `@clients/agent-runtime/src/agent/memory_loader.rs` around lines 331 - 377, Add
a new async test mirroring the DefaultMemoryLoader session test but for
CerebroMemoryLoader: instantiate a CerebroMemoryLoader (use the endpoint-missing
path by calling CerebroMemoryLoader::new(MemoryCerebroConfig::default(), 5, 0.4)
or the egress-blocked config), use a SessionTrackingMemory instance, call
loader.load_context(&memory, "hello", Some("webhook-session-1")).await.unwrap(),
and then assert that memory.recall_sessions.lock().unwrap().clone() equals
vec![Some("webhook-session-1".to_string())]; reference CerebroMemoryLoader,
MemoryCerebroConfig, load_context, and SessionTrackingMemory.recall_sessions to
locate the code.

118-123: ⚠️ Potential issue | 🟠 Major

Add session scoping to Cerebro recall payload or document the behavioral difference.

CerebroMemoryLoader accepts session_id and passes it to local memory recall, but omits it entirely from the remote Cerebro MCP payload. While Cerebro's mem_search schema doesn't currently support session_id, this creates a silent behavioral gap: DefaultMemoryLoader respects session boundaries, but CerebroMemoryLoader silently ignores them for remote recall, risking cross-session memory leakage in webhook flows.

Either:

  1. Extend Cerebro's mem_search input schema to accept session_id and propagate it via the payload
  2. Or add explicit documentation/test that CerebroMemoryLoader cannot enforce session isolation and document the security implications

Currently, only DefaultMemoryLoader has a regression test (default_loader_uses_explicit_session_scope), but CerebroMemoryLoader is untested with non-None session_id.

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

In `@clients/agent-runtime/src/agent/memory_loader.rs` around lines 118 - 123,
CerebroMemoryLoader builds a remote recall payload (the payload JSON near the
json!({...}) block) but omits session_id, creating a behavioral gap versus
DefaultMemoryLoader; either extend Cerebro's mem_search input schema to accept
session_id and include session_id in the payload constructed by
CerebroMemoryLoader, or explicitly document and test that CerebroMemoryLoader
does not enforce session isolation. Update the payload construction in
CerebroMemoryLoader to add "session_id": self.session_id (and propagate this
change to the mem_search schema/handler), and add a regression test analogous to
default_loader_uses_explicit_session_scope to validate non-None session_id
behavior if you choose the schema approach; if not, add documentation and a test
that asserts the lack of session scoping to make the security implications
explicit.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@clients/agent-runtime/src/agent/agent.rs`:
- Around line 784-797: The function approval_denial_from_history currently scans
the entire history and may return stale "approval_required" results; change it
to only consider the most recent turn by scanning history in reverse and
returning the first ToolResults entry that contains a JSON with code ==
"approval_required". Specifically, update approval_denial_from_history to
iterate history.iter().rev(), find the first ConversationMessage::ToolResults
group, then search that group's results for the parsed JSON with code
"approval_required" (instead of searching every ToolResults across the whole
history).
- Around line 816-831: The code is calling turn_with_context(...,
TurnContext::default()) so code-mode turns aren't given the session_id; change
the TurnContext passed into self.turn_with_context to include the code-session
id when session_id.is_some() so the turn context and the CodeSessionResult use
the same session identifier. Locate the call to turn_with_context in agent.rs
and replace TurnContext::default() with a TurnContext constructed/populated with
the session_id (derived from session_id.as_deref()) before calling
record_code_session_result, ensuring the same session_id is used for both the
turn (turn_with_context) and the subsequent
CodeSessionResult/record_code_session_result paths.

In `@clients/agent-runtime/src/config/schema.rs`:
- Around line 2807-2811: The code now ingests CORVUS_GATEWAY_WEBHOOK_DISPATCHER
at config load via env_override_bool but the runtime helper
webhook_dispatcher_enabled() still re-reads the env var and ORs it in, causing
post-startup env changes to override config; remove the runtime env read and
make webhook_dispatcher_enabled() return the loaded config value
(gateway.webhook_dispatcher_enabled) only so the config value loaded at startup
is the single source of truth; locate and remove the getenv/OR logic in
webhook_dispatcher_enabled() (gateway/mod.rs) and ensure all callers use the
configured field rather than env::var at runtime.

In `@clients/agent-runtime/src/gateway/mod.rs`:
- Around line 1387-1389: The webhook_duplicate_response function currently logs
the raw idempotency_key; change this to never log the raw key and instead log a
redacted fingerprint (e.g., compute a short stable hash/fingerprint of
idempotency_key and log only the first N chars). Update
webhook_duplicate_response to compute the fingerprint (using a hashing utility
or a new helper like redact_idempotency_key/fingerprint_idempotency_key) and
replace the tracing::info call so it includes only the fingerprint (not the raw
key) in the message; ensure no other places in this function write the raw
idempotency_key to logs or responses.

In `@clients/agent-runtime/src/gateway/webhook_dispatch.rs`:
- Around line 333-346: The current handler recreates a fresh Agent for every
webhook (using BootstrapContext::for_gateway and
Agent::from_bootstrap_with_provider with SharedProvider) so same-session calls
lose prior conversation messages; persist and replay session transcript into the
Provider before calling Agent::turn_with_context. Concretely: use a
session-scoped store keyed by request.session (or attach to TurnContext) to
retrieve prior ConversationMessage history, and either (a) construct a
session-backed Provider implementation that wraps SharedProvider and replays the
stored ConversationMessage list into Provider::chat before delegating, or (b)
reuse a single Agent instance per session (cached by session id) instead of
rebuilding via Agent::from_bootstrap_with_provider; ensure turn_with_context
receives the replayed messages via the Provider or TurnContext so continuity is
preserved.
- Around line 318-330: The code treats BlockingOutcome::ApprovalRequired as if
it were non-blocking and continues processing, which can downgrade an
approval-gated request; update the blocking match in the webhook_dispatch path
(where evaluate and classify_blocking are called) to immediately return a
Blocking result for ApprovalRequired rather than falling through — i.e., when
classify_blocking(&canonical) yields BlockingOutcome::ApprovalRequired, call
map_canonical_result(&request, model,
CanonicalWebhookResult::Blocking(BlockingOutcome::ApprovalRequired { .. })) (or
equivalent) and return, similar to how other blocking outcomes are handled, so
no further agent/model work is performed after an approval decision.

In `@clients/agent-runtime/src/test_support.rs`:
- Around line 32-65: The current guard (GatewayWebhookDispatcherEnvGuard)
acquires gateway_webhook_dispatcher_env_mutex but only when callers use
set()/set_blocking(); direct env manipulation still bypasses the mutex. Add and
export a lock-only helper (e.g., acquire_gateway_webhook_dispatcher_lock and
acquire_gateway_webhook_dispatcher_lock_blocking) that returns a
tokio::sync::MutexGuard<'static, ()> (or a thin RAII wrapper) by calling
gateway_webhook_dispatcher_env_mutex().lock().await / .blocking_lock(), and
update tests to use this helper for baseline setup/cleanup when they need to
manipulate GATEWAY_WEBHOOK_DISPATCHER_ENV_VAR directly so all env mutations are
serialized by the same mutex.

In `@openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/design.md`:
- Around line 216-222: Update the WebhookTerminalOutcome enum in the design doc
to match the implemented variant name: change the variant TimeoutAborted to
Timeout in the WebhookTerminalOutcome definition so it aligns with the
implementation used in gateway/webhook_dispatch.rs (see the variant at the
implementation site).

In
`@openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/exploration.md`:
- Around line 3-10: Rename or prepend this section to clearly label it as a
historical "Pre-change snapshot" and update the prose to state that the
described behavior (gateway routes using Provider::simple_chat(), /webhook being
the exception, and /whatsapp lacking dispatcher/MCP parity) reflects the
pre-migration state; also add one sentence noting that dispatcher-backed webhook
specs and implementations have since been merged and reference the existing
symbols pre_execution::evaluate(...), Provider::simple_chat(), and the /webhook
and /whatsapp call paths so readers can correlate the snapshot with current
files.

In
`@openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/verify-report.md`:
- Around line 142-147: Run the specific Rust test repeatedly to confirm the
`GatewayWebhookDispatcherEnvGuard::set_blocking("1")` usage in the
`config::schema::tests::env_override_gateway_webhook_dispatcher` test actually
stabilizes the intermittent failure: execute `cargo test --lib
config::schema::tests::env_override_gateway_webhook_dispatcher` several times
(e.g., 10+ runs) and verify no flakiness; if failures persist despite the guard,
collect failing traces and environment mutation points, then escalate for deeper
isolation fixes (investigate other tests mutating the same env, refactor to use
per-test guards or temp env APIs, or serialize via a test-level mutex). Ensure
the guard call is present in the test harness
(`GatewayWebhookDispatcherEnvGuard::set_blocking("1")`) and document the
verification results in the PR.

In
`@openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/design.md`:
- Around line 81-84: The fenced Rust code block using ```rust around the
gateway_webhook_dispatcher_env_guard declaration must use the repository's
configured fence style to satisfy MD046; replace the triple backtick fence with
the repository-preferred fence (e.g., use triple tildes ~~~rust if that is the
configured style) for the block containing gateway_webhook_dispatcher_env_guard
so the markdown linter stops flagging it.

In
`@openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/tasks.md`:
- Line 6: The checklist entry references the test_support path inconsistently
(one place uses the module file variant and another uses the flat file variant);
update the tasks.md checklist line that mentions the test_support file so it
matches the actual module path used in the repo (i.e., normalize the
test_support reference to the module-style path) and ensure the same normalized
reference is used for the CORVUS_GATEWAY_WEBHOOK_DISPATCHER seam mention so docs
and code stay aligned.

In `@openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/design.md`:
- Around line 35-37: Replace the inconsistent phrase "end to end" with the
hyphenated "end-to-end" in the design text; specifically update the bullet lines
that include "Prove everything only in
`clients/agent-runtime/src/gateway/webhook_dispatch.rs`" and "Broaden the change
into dispatcher or policy work so MCP can execute end to end", and also the
other occurrence later in the document (the standalone "end to end" usage) so
all instances use "end-to-end" consistently.

In
`@openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/design.md`:
- Around line 110-115: The assertions use
tracking.recall_sessions.lock().clone() and
tracking.store_sessions.lock().clone(), which is invalid because Mutex::lock()
returns a Result; change both to unwrap (or expect) before cloning, e.g. call
tracking.recall_sessions.lock().unwrap().clone() and
tracking.store_sessions.lock().unwrap().clone() (or use expect with a clear
message) so the MutexGuard is unwrapped prior to clone.

In
`@openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/exploration.md`:
- Around line 1-54: The markdown fails linting (MD041/MD022): change the first
line title "Exploration: webhook-generated-session-isolation" to an H1 (prefix
with "# "), and ensure all section headings (e.g., "### Current State", "###
Affected Areas", "### Approaches", "### Recommendation", "What this change
should include:", "What stays out of scope:", "Minimum spec delta likely
needed:", "### Risks", "### Ready for Proposal") are preceded and followed by a
single blank line so each heading is isolated; run a quick markdownlint check to
confirm MD041/MD022 are resolved.

In
`@openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/tasks.md`:
- Around line 6-7: Update the task wording to remove the contradictory "RED"
label and describe it as a passing/regression test: change the checklist item
referencing the `/webhook` dispatcher-backed test in
clients/agent-runtime/src/gateway/mod.rs to read something like "Add a new
dispatcher-backed regression test for `/webhook` that omits `X-Session-Id`,
enables auto-save, captures the JSON `session_id`, and asserts the generated
`webhook-...` id matches all recorded recall/store session ids without reusing
any prior explicit session." Ensure "RED" is not used and the wording clearly
states it is a new regression test (or equivalent) that now passes.

In
`@openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/verify-report.md`:
- Line 17: Update the stale tasks link in verify-report.md: replace the
reference to "openspec/changes/webhook-generated-session-isolation/tasks.md"
with the archived path
"openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/tasks.md"
so the Assessment line points to the archived tasks file; edit the string in
verify-report.md where the Assessment paragraph references the tasks file to
ensure the audit trail is accurate.

---

Outside diff comments:
In `@clients/agent-runtime/src/agent/memory_loader.rs`:
- Around line 331-377: Add a new async test mirroring the DefaultMemoryLoader
session test but for CerebroMemoryLoader: instantiate a CerebroMemoryLoader (use
the endpoint-missing path by calling
CerebroMemoryLoader::new(MemoryCerebroConfig::default(), 5, 0.4) or the
egress-blocked config), use a SessionTrackingMemory instance, call
loader.load_context(&memory, "hello", Some("webhook-session-1")).await.unwrap(),
and then assert that memory.recall_sessions.lock().unwrap().clone() equals
vec![Some("webhook-session-1".to_string())]; reference CerebroMemoryLoader,
MemoryCerebroConfig, load_context, and SessionTrackingMemory.recall_sessions to
locate the code.
- Around line 118-123: CerebroMemoryLoader builds a remote recall payload (the
payload JSON near the json!({...}) block) but omits session_id, creating a
behavioral gap versus DefaultMemoryLoader; either extend Cerebro's mem_search
input schema to accept session_id and include session_id in the payload
constructed by CerebroMemoryLoader, or explicitly document and test that
CerebroMemoryLoader does not enforce session isolation. Update the payload
construction in CerebroMemoryLoader to add "session_id": self.session_id (and
propagate this change to the mem_search schema/handler), and add a regression
test analogous to default_loader_uses_explicit_session_scope to validate
non-None session_id behavior if you choose the schema approach; if not, add
documentation and a test that asserts the lack of session scoping to make the
security implications explicit.
🪄 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: 8add987f-b54b-442d-812b-ed6fdea87cca

📥 Commits

Reviewing files that changed from the base of the PR and between 2cc8450 and 8489514.

📒 Files selected for processing (39)
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/agent/memory_loader.rs
  • clients/agent-runtime/src/agent/mod.rs
  • clients/agent-runtime/src/agent/tests.rs
  • clients/agent-runtime/src/bootstrap/mod.rs
  • clients/agent-runtime/src/config/schema.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/gateway/webhook_dispatch.rs
  • clients/agent-runtime/src/test_support.rs
  • clients/agent-runtime/tests/memory_backend_selection.rs
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/archive-report.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/design.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/exploration.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/proposal.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/specs/agent-loop/spec.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/specs/mcp-runtime/spec.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/tasks.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/verify-report.md
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/archive-report.md
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/design.md
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/exploration.md
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/proposal.md
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/tasks.md
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/verify-report.md
  • openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/archive-report.md
  • openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/design.md
  • openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/exploration.md
  • openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/proposal.md
  • openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/specs/mcp-runtime/spec.md
  • openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/tasks.md
  • openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/verify-report.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/archive-report.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/design.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/exploration.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/proposal.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/tasks.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/verify-report.md
  • openspec/specs/agent-loop/spec.md
  • openspec/specs/mcp-runtime/spec.md
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: pr-checks
  • GitHub Check: Analyze (python)
  • GitHub Check: pr-checks
  • GitHub Check: core-checks
  • GitHub Check: submit-gradle
  • GitHub Check: Cloudflare Pages
🧰 Additional context used
📓 Path-based instructions (7)
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/tests/memory_backend_selection.rs
  • clients/agent-runtime/src/agent/mod.rs
  • clients/agent-runtime/src/agent/memory_loader.rs
  • clients/agent-runtime/src/agent/tests.rs
  • clients/agent-runtime/src/test_support.rs
  • clients/agent-runtime/src/gateway/webhook_dispatch.rs
  • clients/agent-runtime/src/bootstrap/mod.rs
  • clients/agent-runtime/src/config/schema.rs
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/gateway/mod.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/tests/memory_backend_selection.rs
  • clients/agent-runtime/src/agent/mod.rs
  • clients/agent-runtime/src/agent/memory_loader.rs
  • clients/agent-runtime/src/agent/tests.rs
  • clients/agent-runtime/src/test_support.rs
  • clients/agent-runtime/src/gateway/webhook_dispatch.rs
  • clients/agent-runtime/src/bootstrap/mod.rs
  • clients/agent-runtime/src/config/schema.rs
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/gateway/mod.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/tests/memory_backend_selection.rs
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/proposal.md
  • clients/agent-runtime/src/agent/mod.rs
  • openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/proposal.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/proposal.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/tasks.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/design.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/archive-report.md
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/tasks.md
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/design.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/archive-report.md
  • openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/exploration.md
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/archive-report.md
  • openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/verify-report.md
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/exploration.md
  • openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/design.md
  • openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/archive-report.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/tasks.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/exploration.md
  • clients/agent-runtime/src/agent/memory_loader.rs
  • openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/specs/mcp-runtime/spec.md
  • openspec/specs/mcp-runtime/spec.md
  • openspec/specs/agent-loop/spec.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/proposal.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/design.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/specs/agent-loop/spec.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/verify-report.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/specs/mcp-runtime/spec.md
  • clients/agent-runtime/src/agent/tests.rs
  • clients/agent-runtime/src/test_support.rs
  • openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/tasks.md
  • clients/agent-runtime/src/gateway/webhook_dispatch.rs
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/verify-report.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/exploration.md
  • clients/agent-runtime/src/bootstrap/mod.rs
  • clients/agent-runtime/src/config/schema.rs
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/verify-report.md
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/gateway/mod.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:

  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/proposal.md
  • openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/proposal.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/proposal.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/tasks.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/design.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/archive-report.md
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/tasks.md
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/design.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/archive-report.md
  • openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/exploration.md
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/archive-report.md
  • openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/verify-report.md
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/exploration.md
  • openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/design.md
  • openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/archive-report.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/tasks.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/exploration.md
  • openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/specs/mcp-runtime/spec.md
  • openspec/specs/mcp-runtime/spec.md
  • openspec/specs/agent-loop/spec.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/proposal.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/design.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/specs/agent-loop/spec.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/verify-report.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/specs/mcp-runtime/spec.md
  • openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/tasks.md
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/verify-report.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/exploration.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/verify-report.md
clients/agent-runtime/src/**/*.rs

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

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

Files:

  • clients/agent-runtime/src/agent/mod.rs
  • clients/agent-runtime/src/agent/memory_loader.rs
  • clients/agent-runtime/src/agent/tests.rs
  • clients/agent-runtime/src/test_support.rs
  • clients/agent-runtime/src/gateway/webhook_dispatch.rs
  • clients/agent-runtime/src/bootstrap/mod.rs
  • clients/agent-runtime/src/config/schema.rs
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/gateway/mod.rs
clients/agent-runtime/src/{security,gateway,tools}/**/*.rs

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

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

Files:

  • clients/agent-runtime/src/gateway/webhook_dispatch.rs
  • clients/agent-runtime/src/gateway/mod.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/gateway/webhook_dispatch.rs
  • clients/agent-runtime/src/config/schema.rs
  • clients/agent-runtime/src/gateway/mod.rs
🧠 Learnings (12)
📓 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
📚 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/tests/memory_backend_selection.rs
  • clients/agent-runtime/src/agent/mod.rs
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/exploration.md
  • clients/agent-runtime/src/agent/tests.rs
  • clients/agent-runtime/src/test_support.rs
  • clients/agent-runtime/src/gateway/webhook_dispatch.rs
  • clients/agent-runtime/src/bootstrap/mod.rs
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/gateway/mod.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Include threat/risk notes and rollback strategy for security, runtime, and gateway changes; add or update tests for boundary checks and failure modes

Applied to files:

  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/proposal.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/tasks.md
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/tasks.md
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/design.md
  • openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/verify-report.md
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/exploration.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/tasks.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/exploration.md
  • openspec/specs/mcp-runtime/spec.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/proposal.md
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/verify-report.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/verify-report.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/**/*.rs : Run `cargo fmt --all -- --check`, `cargo clippy --all-targets -- -D warnings`, and `cargo test` for code validation, or document which checks were skipped and why

Applied to files:

  • clients/agent-runtime/src/agent/mod.rs
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/tasks.md
  • clients/agent-runtime/src/agent/tests.rs
  • clients/agent-runtime/src/test_support.rs
  • clients/agent-runtime/src/gateway/webhook_dispatch.rs
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/verify-report.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/**/Cargo.toml : Do not add heavy dependencies for minor convenience; justify new crate additions

Applied to files:

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

Applied to files:

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

Applied to files:

  • clients/agent-runtime/src/agent/mod.rs
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/design.md
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/exploration.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/tasks.md
  • openspec/specs/mcp-runtime/spec.md
  • clients/agent-runtime/src/test_support.rs
  • clients/agent-runtime/src/gateway/webhook_dispatch.rs
  • clients/agent-runtime/src/bootstrap/mod.rs
  • clients/agent-runtime/src/config/schema.rs
  • clients/agent-runtime/src/gateway/mod.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/providers/**/*.rs : Implement `Provider` trait in `src/providers/` and register in `src/providers/mod.rs` factory when adding a new provider

Applied to files:

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

Applied to files:

  • clients/agent-runtime/src/agent/mod.rs
  • clients/agent-runtime/src/agent/tests.rs
  • clients/agent-runtime/src/bootstrap/mod.rs
  • clients/agent-runtime/src/agent/agent.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/{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:

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

Applied to files:

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

Applied to files:

  • clients/agent-runtime/src/gateway/webhook_dispatch.rs
🪛 LanguageTool
openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/proposal.md

[style] ~45-~45: As an alternative to the over-used intensifier ‘very’, consider replacing this phrase.
Context: ...default plan is test-only, with at most a very small supporting test-harness adjustment in `...

(EN_WEAK_ADJECTIVE)


[style] ~61-~61: To elevate your writing, try using a synonym here.
Context: ...----------|------------| | The flake is hard to reproduce deterministically | Medium...

(HARD_TO)

openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/proposal.md

[grammar] ~1-~1: Use a hyphen to join words.
Context: # Proposal: Webhook Generated Session Isolation ## Intent ...

(QB_NEW_EN_HYPHEN)

openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/tasks.md

[grammar] ~1-~1: Use a hyphen to join words.
Context: # Tasks: Webhook Generated Session Isolation ## Phase 1:...

(QB_NEW_EN_HYPHEN)

openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/design.md

[grammar] ~1-~1: Use a hyphen to join words.
Context: # Design: Webhook Generated Session Isolation ## Technica...

(QB_NEW_EN_HYPHEN)

openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/archive-report.md

[style] ~51-~51: To elevate your writing, try using an alternative expression here.
Context: ... ## Next Recommended - If auditability matters for a later follow-up, isolate unrelate...

(MATTERS_RELEVANT)

openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/exploration.md

[style] ~40-~40: Using a “neither–nor” construction here can make your writing sound more fluent.
Context: ...therwise. The narrowest useful scope is not a broad config refactor and not a production behavior change; it is a small test-harness correction ...

(N_NOR)

openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/design.md

[grammar] ~37-~37: Use a hyphen to join words.
Context: ...er or policy work so MCP can execute end to end Rationale: `clients/agent-ru...

(QB_NEW_EN_HYPHEN)


[grammar] ~37-~37: Use a hyphen to join words.
Context: ...or policy work so MCP can execute end to end Rationale: `clients/agent-runti...

(QB_NEW_EN_HYPHEN)


[grammar] ~152-~152: Use a hyphen to join words.
Context: ...eachable MCP policy behavior remains end to end | Keep `webhook_dispatcher_blocks...

(QB_NEW_EN_HYPHEN)


[grammar] ~152-~152: Use a hyphen to join words.
Context: ...hable MCP policy behavior remains end to end | Keep `webhook_dispatcher_blocks_mc...

(QB_NEW_EN_HYPHEN)

openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/specs/mcp-runtime/spec.md

[grammar] ~28-~28: Use a hyphen to join words.
Context: ...ntime-reachable MCP denial is proven end to end - GIVEN a dispatcher-backed gate...

(QB_NEW_EN_HYPHEN)


[grammar] ~28-~28: Use a hyphen to join words.
Context: ...me-reachable MCP denial is proven end to end - GIVEN a dispatcher-backed gateway...

(QB_NEW_EN_HYPHEN)

openspec/specs/mcp-runtime/spec.md

[grammar] ~148-~148: Use a hyphen to join words.
Context: ...ntime-reachable MCP denial is proven end to end - GIVEN a dispatcher-backed gate...

(QB_NEW_EN_HYPHEN)


[grammar] ~148-~148: Use a hyphen to join words.
Context: ...me-reachable MCP denial is proven end to end - GIVEN a dispatcher-backed gateway...

(QB_NEW_EN_HYPHEN)

openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/design.md

[uncategorized] ~177-~177: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...- pairing enforcement - IP/header-aware rate limiting - idempotency policy - request parsing ...

(EN_COMPOUND_ADJECTIVE_INTERNAL)


[style] ~350-~350: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...ts. - No resumable approval protocol. - No broad channels/gateway shared-runtime r...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/exploration.md

[style] ~46-~46: As an alternative to the over-used intensifier ‘very’, consider replacing this phrase.
Context: ...ta spec for the follow-up, it should be a very small agent-loop delta that restates this a...

(EN_WEAK_ADJECTIVE)

🪛 markdownlint-cli2 (0.21.0)
openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/proposal.md

[warning] 14-14: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 24-24: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)

openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/design.md

[warning] 12-12: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 20-20: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)

openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/design.md

[warning] 81-81: Code block style
Expected: indented; Actual: fenced

(MD046, code-block-style)

openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/exploration.md

[warning] 13-13: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 25-25: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)

openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/exploration.md

[warning] 1-1: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)


[warning] 3-3: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 15-15: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 23-23: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 39-39: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 56-56: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 62-62: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)

openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/exploration.md

[warning] 1-1: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)


[warning] 3-3: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 12-12: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 21-21: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 32-32: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 41-41: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 47-47: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)

openspec/specs/agent-loop/spec.md

[warning] 18-18: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 26-26: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 33-33: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 47-47: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 62-62: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 70-70: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 85-85: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 92-92: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 106-106: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 113-113: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 127-127: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 134-134: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)

openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/proposal.md

[warning] 81-81: Code block style
Expected: indented; Actual: fenced

(MD046, code-block-style)

openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/exploration.md

[warning] 1-1: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)


[warning] 3-3: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 12-12: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 20-20: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 31-31: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 48-48: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 54-54: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)

🔇 Additional comments (27)
openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/proposal.md (1)

124-138: Risk and rollback coverage is clear and actionable.

The proposal’s risk table and rollback path are explicit and scoped correctly for gateway/runtime migration work.

Based on learnings: "Include threat/risk notes and rollback strategy for security, runtime, and gateway changes; add or update tests for boundary checks and failure modes".

clients/agent-runtime/tests/memory_backend_selection.rs (1)

75-118: Signature migration is correctly applied in tests.

Passing None explicitly at call sites keeps these tests aligned with the new session-aware MemoryLoader contract.

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

17-20: Public re-exports match the new turn-context API surface.

This keeps downstream imports consistent with the session-aware agent runtime changes.

openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/archive-report.md (1)

30-55: Archive warning carry-forward is documented well.

The warnings and next recommended actions are precise and maintain auditability of remaining proof gaps.

openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/proposal.md (1)

57-69: Good scope control and rollback discipline for the flake fix.

The proposal keeps runtime behavior stable unless a deterministic production defect is proven.

Based on learnings: "Include threat/risk notes and rollback strategy for security, runtime, and gateway changes; add or update tests for boundary checks and failure modes".

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

666-673: Secure default is correctly fail-closed.

webhook_dispatcher_enabled defaults to false, which keeps legacy behavior unless explicitly enabled.

As per coding guidelines "clients/agent-runtime/src/{security,gateway,tools,config}/**/*.rs: ... keep default behavior secure-by-default with deny-by-default where applicable".

Also applies to: 723-723

openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/proposal.md (1)

29-35: Approach is appropriately proof-first and tightly scoped.

This keeps the follow-up focused on validating session isolation without widening production change scope.

openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/archive-report.md (1)

12-49: Looks good — archive rationale and artifact trail are clear and internally consistent.

openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/archive-report.md (1)

12-61: LGTM — warning carry-forward and audit trail are well documented for this test-only slice.

openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/proposal.md (1)

13-97: Well-scoped proposal with clear proof-first boundaries and acceptance criteria.

openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/archive-report.md (1)

12-69: LGTM — archive summary, carry-forward warnings, and follow-up guidance are clear and consistent.

clients/agent-runtime/src/agent/tests.rs (2)

219-279: Good targeted test double for session propagation.

TrackingMemory at Line 219 cleanly captures recall/store session IDs and keeps the assertions deterministic for async tests.


808-861: Great coverage for both session-present and session-absent paths.

Lines 808-861 validate session threading end-to-end through recall/store and result metadata for both explicit and default TurnContext.

openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/tasks.md (1)

1-16: Scope control is clear and well constrained.

The phased tasks keep this follow-up proof-oriented and avoid accidental runtime-scope expansion.

openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/verify-report.md (1)

53-74: Verification evidence is well-structured and traceable.

The compliance and correctness sections clearly separate runtime-reachable proof from seam-only proof, which matches the scoped objective.

openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/verify-report.md (1)

38-65: Strong flake-validation evidence.

The repeated focused runs and per-file coverage details make the stabilization claim credible and auditable.

openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/exploration.md (1)

1-63: Well-structured investigation with appropriate scope boundaries.

The exploration correctly identifies the cross-module env-var race between ENV_OVERRIDE_TEST_LOCK in config tests and GATEWAY_ENV_MUTEX in gateway tests. The recommendation to use a shared test-only env guard (approach 2) is the right call—it addresses the structural root cause without touching production code.

openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/exploration.md (1)

1-63: Sound framing of proof-vs-reachability distinction.

The exploration correctly distinguishes runtime-reachable outcomes (MCP denial) from policy-blocked outcomes (MCP success/timeout/error). The recommendation to use seam-level proof for blocked outcomes while requiring E2E proof for reachable outcomes is the right architectural stance—it avoids false confidence from tests that can't exercise real execution paths.

openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/design.md (1)

1-361: Solid security-first design with appropriate rollout controls.

The design correctly:

  • Keeps transport/auth concerns at the gateway edge before dispatcher execution
  • Enforces "Gateway MUST NOT bypass approval checks" as an explicit constraint
  • Provides dedicated rollout flag with legacy fallback for safe migration
  • Preserves idempotency semantics for non-terminal outcomes

This aligns with the coding guidelines for secure-by-default behavior. Based on learnings: "Include threat/risk notes and rollback strategy for security, runtime, and gateway changes."

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

147-174: Clean delegation pattern with idiomatic option handling.

The refactoring correctly extracts override-aware initialization while preserving the original API through delegation. The unwrap_or_else for lazy observer creation and explicit if let for memory are readable and avoid unnecessary allocations.


188-194: Appropriate visibility for gateway-only bootstrap path.

pub(crate) correctly limits for_gateway to internal use, preventing external callers from bypassing the canonical bootstrap flow. This maintains the design constraint that gateway reuses canonical memory/observer instances.


572-588: Good feature-flag conditional test coverage.

The test correctly validates MCP tool registry behavior under both feature states using cfg!(feature = "mcp-runtime"). This ensures gateway bootstrap maintains parity with canonical MCP registration regardless of the feature flag.

openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/tasks.md (1)

1-38: Comprehensive task breakdown with clear phase boundaries.

The task plan correctly sequences: contract tests (RED) → implementation → HTTP mapping → MCP parity → verification. The explicit /whatsapp exclusion in task 4.4 maintains scope discipline, and Phase 5 verification ensures both targeted Rust tests and standard project verification are executed.

openspec/specs/mcp-runtime/spec.md (2)

93-130: Strong security boundary for MCP policy enforcement.

The expanded requirement correctly:

  • Extends approval gates to dispatcher-backed /webhook
  • Explicitly disallows any canonical entry point from bypassing MCP approval
  • Treats legacy fallback as "MCP parity inactive" rather than partially enforced

This prevents the security posture gap where gateway might accidentally weaken MCP policy. Based on learnings: "Do not silently weaken security policy or access constraints."


131-176: Well-defined proof semantics distinguish reachable vs blocked outcomes.

The three-scenario structure is precise:

  1. Denial (E2E required): Runtime-reachable, must prove through full dispatcher path
  2. Non-denial blocked (seam OK): Policy prevents execution, seam-level proof acceptable with clear labeling
  3. Future reachable (E2E required): When policy changes, seam-only evidence becomes insufficient

This prevents false confidence from tests labeled "MCP" that only exercise generic outcome mapping.

openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/specs/mcp-runtime/spec.md (1)

1-55: Clear delta documentation with change tracking.

The "Previously:" clause (Lines 22-26) provides good change history context, showing exactly what was added to the original capability parity requirement. The proof semantics mirror the main spec correctly.

openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/verify-report.md (1)

1-162: Thorough verification with honest gap disclosure.

The report correctly:

  • Documents 14/16 compliant scenarios with 2 partial (not hidden)
  • Provides actionable suggestions for each warning
  • Acknowledges the make test vs cargo test coverage gap
  • Maintains "PASS WITH WARNINGS" rather than overstating compliance

The partial scenarios (missing-session E2E and MCP non-denial mapping) are legitimate gaps tracked as follow-ups in the exploration docs.

Comment thread clients/agent-runtime/src/agent/agent.rs Outdated
Comment thread clients/agent-runtime/src/agent/agent.rs Outdated
Comment thread clients/agent-runtime/src/config/schema.rs
Comment thread clients/agent-runtime/src/gateway/mod.rs
Comment thread clients/agent-runtime/src/gateway/mod.rs Outdated
Comment thread openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/design.md Outdated
Comment thread openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/tasks.md Outdated
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: 7

Caution

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

⚠️ Outside diff range comments (2)
clients/agent-runtime/src/agent/memory_loader.rs (1)

117-125: ⚠️ Potential issue | 🔴 Critical

Do not merge global Cerebro recall into session-scoped turns.

When session_id is set, this still issues an unscoped remote mem_search and appends those results to the prompt. That breaks the new session-isolation contract and can leak memories across webhook sessions whenever Cerebro is enabled. Until the remote API can filter by session, this path needs to fail closed for session-bound turns.

Suggested fix
-        let adapter = cerebro::cerebro_tool_adapter(&self.config, normalize::CEREBRO_TOOL_RECALL)?;
-        // Cerebro's current mem_search contract does not accept a session filter, so remote recall
-        // remains global even when the local memory fallback is session-scoped.
+        // Fail closed for session-scoped turns until Cerebro supports server-side session filters.
+        if session_id.is_some() {
+            if !added {
+                return Ok(String::new());
+            }
+            context.push('\n');
+            return Ok(context);
+        }
+
+        let adapter =
+            cerebro::cerebro_tool_adapter(&self.config, normalize::CEREBRO_TOOL_RECALL)?;
As per coding guidelines `**/*`: Security first, performance second. Validate input boundaries, auth/authz implications, and secret management.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/agent-runtime/src/agent/memory_loader.rs` around lines 117 - 125, The
remote Cerebro recall path currently builds a global mem_search payload and
calls cerebro::cerebro_tool_adapter (normalize::CEREBRO_TOOL_RECALL) even when a
session_id is present, which can leak memories across sessions; modify the code
in the memory loading function so that if session_id (or the field representing
session scope on self) is Some/exists you do not construct or call the remote
mem_search (the payload and cerebro::cerebro_tool_adapter/ mem_search path) and
instead fail closed — return an Err (or skip adding remote results) with a clear
error indicating remote recall is disallowed for session-scoped turns; keep the
existing global behavior only when session_id is None.
clients/agent-runtime/src/gateway/mod.rs (1)

714-735: ⚠️ Potential issue | 🟠 Major

Reject malformed X-Session-Id instead of treating it as missing.

A present-but-invalid header currently falls through to the generated-session path. That silently forks the caller into a new session and hides client bugs. Only the truly missing-header case should mint webhook-<uuid>; malformed values should get a 400.

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

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

In `@clients/agent-runtime/src/gateway/mod.rs` around lines 714 - 735, Change
resolve_session_id so that a present but syntactically invalid X-Session-Id
causes an explicit client error instead of generating a new session: update the
function signature to return a Result<(String,
webhook_dispatch::WebhookSessionSource), E> (E can be the framework error type
or an HttpResponse) and when headers.get("X-Session-Id") exists but fails the
trim/len/char validation return Err(BadRequest) with a clear message; only when
the header is absent return Ok((format!("webhook-{}", Uuid::new_v4()),
webhook_dispatch::WebhookSessionSource::Generated)), and when the header is
valid return Ok((session_id, webhook_dispatch::WebhookSessionSource::Explicit)).
♻️ Duplicate comments (4)
openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/design.md (1)

79-84: ⚠️ Potential issue | 🟡 Minor

Use the repo’s configured code-block style here.

This fenced snippet still trips MD046, so doc lint will keep failing until it is converted to the configured indented style.

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

In
`@openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/design.md`
around lines 79 - 84, The markdown snippet uses a fenced code block which
violates the repo’s configured indented code-block style and triggers MD046;
change the fenced Rust example for the test-only seam to the repo’s indented
style and keep the same signature/name (gateway_webhook_dispatcher_env_guard),
ensuring the block is prefixed by the required indentation so the linter accepts
it and the snippet remains exactly the same content-wise except for formatting.
openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/exploration.md (1)

3-3: ⚠️ Potential issue | 🟡 Minor

Use H2 section headings under the H1.

The file still jumps from # to ###, so markdownlint's MD001 remains unresolved.

Also applies to: 34-34, 49-49, 68-68, 74-74, 82-82, 89-89, 96-96, 107-107

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

In
`@openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/exploration.md`
at line 3, Replace all third-level headings (e.g., the "### Current State"
heading and the other occurrences at the noted locations) with second-level
headings under the top-level title so H2 (##) follows the H1; update every "###
..." instance in this file (including the instances referenced at lines 34, 49,
68, 74, 82, 89, 96, 107) to "## ..." to satisfy markdownlint MD001.
clients/agent-runtime/src/gateway/mod.rs (1)

1613-1645: ⚠️ Potential issue | 🔴 Critical

Make dispatcher idempotency reservation atomic.

This path still does a contains() pre-check and a later record(). Two concurrent requests with the same key can both pass Line 1616, both execute side effects, and only then record the key. Reserve with record_if_new() before dispatch and remove() it again when persist_idempotency is false.

🔒 Minimal fix
-        if let Some(idempotency_key) = webhook_idempotency_key(&headers) {
-            if state.idempotency_store.contains(idempotency_key) {
-                return webhook_duplicate_response(idempotency_key);
-            }
-        }
+        let idempotency_key = webhook_idempotency_key(&headers);
+        if let Some(key) = idempotency_key {
+            if !state.idempotency_store.record_if_new(key) {
+                return webhook_duplicate_response(key);
+            }
+        }
@@
-        if persist_idempotency {
-            if let Some(idempotency_key) = webhook_idempotency_key(&headers) {
-                state.idempotency_store.record(idempotency_key);
-            }
-        }
+        if !persist_idempotency {
+            if let Some(key) = idempotency_key {
+                state.idempotency_store.remove(key);
+            }
+        }
As per coding guidelines `**/*`: "Security first, performance second. Validate input boundaries, auth/authz implications, and secret management. Look for behavioral regressions, missing tests, and contract breaks across modules."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/agent-runtime/src/gateway/mod.rs` around lines 1613 - 1645, Replace
the separate contains() pre-check and later record() with an atomic reservation
using record_if_new() before calling webhook_dispatch::execute: call
webhook_idempotency_key(&headers) once, if Some(key) then if
state.idempotency_store.record_if_new(key) returns false immediately return
webhook_duplicate_response(key); proceed to call webhook_dispatch::execute;
after computing (response, persist_idempotency) from
webhook_response_from_dispatch_result, if persist_idempotency is false and an
idempotency key was reserved earlier call state.idempotency_store.remove(key) to
release the reservation; remove the original contains()/record() pair so
reservations are atomic.
clients/agent-runtime/src/agent/agent.rs (1)

784-799: ⚠️ Potential issue | 🟠 Major

Scope approval_required detection to current turn only.

The function iterates the entire history in reverse. If a previous turn ended with approval_required but the current turn completed with only a text response (no tool calls), the stale denial will still be returned in AgentTurnResult.approval_required.

Track history_start at the beginning of turn_with_context and pass only the relevant slice:

Suggested fix
     pub async fn turn_with_context(
         &mut self,
         user_message: &str,
         turn_context: TurnContext,
     ) -> Result<AgentTurnResult> {
+        let history_start = self.history.len();
         let effective_model = self
             .prepare_turn_with_context(user_message, &turn_context)
             .await?;
         // ... later at line 858:
-                    approval_required: Self::approval_denial_from_history(&self.history),
+                    approval_required: Self::approval_denial_from_history(
+                        &self.history[history_start..],
+                    ),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/agent-runtime/src/agent/agent.rs` around lines 784 - 799, The code
currently scans the entire conversation history in approval_denial_from_history,
which can return stale "approval_required" results; change call sites (e.g.,
turn_with_context) to compute history_start at turn start and pass only the
current-turn slice (e.g., &history[history_start..]) into
approval_denial_from_history, and adjust the function signature to accept that
slice (or an explicit start index) so detection is scoped to the current turn
only; update any callers of approval_denial_from_history to pass the sliced
history and run tests to confirm AgentTurnResult.approval_required only reflects
the current turn.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@clients/agent-runtime/src/gateway/webhook_dispatch.rs`:
- Around line 189-203: The ApprovalRequired branch is setting a hardcoded
"approval_required" reason which loses the structured denial reason produced by
evaluate_tool_risk() / canonical_outcome_early_response(); update the pattern in
CanonicalWebhookResult::Blocking(BlockingOutcome::ApprovalRequired { tool }) to
capture the real denial reason (e.g. BlockingOutcome::ApprovalRequired { tool,
reason }) and use that reason string when constructing WebhookTurnResult (set
WebhookTerminalOutcome::ApprovalRequired.reason to the captured reason and pass
Some(&reason) to event_frames_for_blocking_result) so the dispatcher-backed
/webhook matches the legacy path.

In `@openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/design.md`:
- Around line 30-31: Update the archived API snippet so it reflects the landed
turn contract: replace usages of Agent::turn and bool-based outcome fields with
the new turn_with_context function and the AgentTurnOutcome and AgentTurnEvent
types, mapping previous boolean flags to the appropriate AgentTurnOutcome
variants and emitting AgentTurnEvent values where the old sketch referenced turn
primitives; if you prefer to keep the old sketch, mark it explicitly as
pre-implementation pseudocode and add a short note calling out the actual
shipped APIs (turn_with_context, AgentTurnOutcome, AgentTurnEvent,
unified_loop/unified_entrypoint) so readers are not misled—apply the same change
to the other sketch region mentioned.

In
`@openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/verify-report.md`:
- Around line 21-41: Update the verification report to explicitly state the
status of Rust formatting and lint checks for the changed
clients/agent-runtime/**/*.rs files: either run and record the results of `cargo
fmt --all -- --check`, `cargo clippy --all-targets -- -D warnings`, and `cargo
test` (include exit codes and any failing test names such as
config::schema::tests::env_override_gateway_webhook_dispatcher), or document
that each check was intentionally skipped with the reason; reference the
affected path pattern (clients/agent-runtime/**/*.rs) and include the exact
commands and outcomes (pass/fail and exit codes) in the report.

In
`@openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/design.md`:
- Around line 67-74: Update the File Changes table to point to the actual helper
file `clients/agent-runtime/src/test_support.rs` (instead of the speculative
`test_support/mod.rs`), and adjust the descriptions for
`clients/agent-runtime/src/config/schema.rs` and
`clients/agent-runtime/src/gateway/mod.rs` to explicitly mention that they now
use the shared dispatcher env test lock/helper in `test_support.rs` and that the
flaky test restores `CORVUS_GATEWAY_WEBHOOK_DISPATCHER` deterministically;
reference the symbol CORVUS_GATEWAY_WEBHOOK_DISPATCHER and the shared test
helper in `test_support.rs` to make the doc match the implementation.

In `@openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/design.md`:
- Around line 99-105: Update the file-change table entry so the path points to
the archived document location: change
`openspec/changes/mcp-webhook-response-mapping/design.md` to
`openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/design.md`
(the record for the created design doc referenced in the table), ensuring the
table row for that file and the Description/Action columns remain unchanged and
that any other occurrences of the non-archived path in this document are updated
to the archived path as well.

In
`@openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/exploration.md`:
- Around line 5-32: Replace all hard-coded line-number citations in the
exploration notes with symbol-and-file references (e.g., resolve_session_id in
clients/agent-runtime/src/gateway/mod.rs, WebhookSessionSource::Generated in
clients/agent-runtime/src/gateway/webhook_dispatch.rs, TurnContext::default()
and relevant tests in clients/agent-runtime/src/agent/tests.rs, and the gateway
`/webhook` handler locations in clients/agent-runtime/src/gateway/mod.rs) so the
text links to functions/structs/files rather than specific line numbers; update
each reference sentence to mention the symbol and file path only, remove the
numeric anchors, and verify the surrounding prose still accurately describes the
behavior (generated webhook-{uuid} session propagation and the missing-header
proof) after making the replacements.

In
`@openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/verify-report.md`:
- Line 57: Update the verification report anchors to use symbol-based references
instead of stale line numbers: replace the hardcoded line anchors for the
"Gateway Webhook Session Scoping" entry and the test
`webhook_dispatcher_generates_isolated_session_when_header_missing` and the
`TrackingMemory` symbol with current symbol-based links (e.g., reference the
test function name
`webhook_dispatcher_generates_isolated_session_when_header_missing`, the type
`TrackingMemory`, and the module `gateway`), and refresh the other affected
verification rows mentioned in the comment so all proof links point to the
current symbols in the repository rather than fixed line numbers.

---

Outside diff comments:
In `@clients/agent-runtime/src/agent/memory_loader.rs`:
- Around line 117-125: The remote Cerebro recall path currently builds a global
mem_search payload and calls cerebro::cerebro_tool_adapter
(normalize::CEREBRO_TOOL_RECALL) even when a session_id is present, which can
leak memories across sessions; modify the code in the memory loading function so
that if session_id (or the field representing session scope on self) is
Some/exists you do not construct or call the remote mem_search (the payload and
cerebro::cerebro_tool_adapter/ mem_search path) and instead fail closed — return
an Err (or skip adding remote results) with a clear error indicating remote
recall is disallowed for session-scoped turns; keep the existing global behavior
only when session_id is None.

In `@clients/agent-runtime/src/gateway/mod.rs`:
- Around line 714-735: Change resolve_session_id so that a present but
syntactically invalid X-Session-Id causes an explicit client error instead of
generating a new session: update the function signature to return a
Result<(String, webhook_dispatch::WebhookSessionSource), E> (E can be the
framework error type or an HttpResponse) and when headers.get("X-Session-Id")
exists but fails the trim/len/char validation return Err(BadRequest) with a
clear message; only when the header is absent return Ok((format!("webhook-{}",
Uuid::new_v4()), webhook_dispatch::WebhookSessionSource::Generated)), and when
the header is valid return Ok((session_id,
webhook_dispatch::WebhookSessionSource::Explicit)).

---

Duplicate comments:
In `@clients/agent-runtime/src/agent/agent.rs`:
- Around line 784-799: The code currently scans the entire conversation history
in approval_denial_from_history, which can return stale "approval_required"
results; change call sites (e.g., turn_with_context) to compute history_start at
turn start and pass only the current-turn slice (e.g.,
&history[history_start..]) into approval_denial_from_history, and adjust the
function signature to accept that slice (or an explicit start index) so
detection is scoped to the current turn only; update any callers of
approval_denial_from_history to pass the sliced history and run tests to confirm
AgentTurnResult.approval_required only reflects the current turn.

In `@clients/agent-runtime/src/gateway/mod.rs`:
- Around line 1613-1645: Replace the separate contains() pre-check and later
record() with an atomic reservation using record_if_new() before calling
webhook_dispatch::execute: call webhook_idempotency_key(&headers) once, if
Some(key) then if state.idempotency_store.record_if_new(key) returns false
immediately return webhook_duplicate_response(key); proceed to call
webhook_dispatch::execute; after computing (response, persist_idempotency) from
webhook_response_from_dispatch_result, if persist_idempotency is false and an
idempotency key was reserved earlier call state.idempotency_store.remove(key) to
release the reservation; remove the original contains()/record() pair so
reservations are atomic.

In
`@openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/design.md`:
- Around line 79-84: The markdown snippet uses a fenced code block which
violates the repo’s configured indented code-block style and triggers MD046;
change the fenced Rust example for the test-only seam to the repo’s indented
style and keep the same signature/name (gateway_webhook_dispatcher_env_guard),
ensuring the block is prefixed by the required indentation so the linter accepts
it and the snippet remains exactly the same content-wise except for formatting.

In
`@openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/exploration.md`:
- Line 3: Replace all third-level headings (e.g., the "### Current State"
heading and the other occurrences at the noted locations) with second-level
headings under the top-level title so H2 (##) follows the H1; update every "###
..." instance in this file (including the instances referenced at lines 34, 49,
68, 74, 82, 89, 96, 107) to "## ..." to satisfy markdownlint MD001.
🪄 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: 1fc9f002-0dab-4de5-8e67-14cb93c4af26

📥 Commits

Reviewing files that changed from the base of the PR and between 8489514 and 4a1e565.

📒 Files selected for processing (17)
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/agent/memory_loader.rs
  • clients/agent-runtime/src/config/schema.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/gateway/webhook_dispatch.rs
  • clients/agent-runtime/src/test_support.rs
  • clients/agent-runtime/tests/memory_backend_selection.rs
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/design.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/exploration.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/verify-report.md
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/design.md
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/tasks.md
  • openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/design.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/design.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/exploration.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/tasks.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/verify-report.md
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: pr-checks
  • GitHub Check: Cloudflare Pages
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{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:

  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/tasks.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/tasks.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/design.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/design.md
  • openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/design.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/exploration.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/verify-report.md
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/design.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/exploration.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/verify-report.md
**/*

⚙️ 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:

  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/tasks.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/tasks.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/design.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/design.md
  • clients/agent-runtime/tests/memory_backend_selection.rs
  • openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/design.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/exploration.md
  • clients/agent-runtime/src/config/schema.rs
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/verify-report.md
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/design.md
  • clients/agent-runtime/src/test_support.rs
  • clients/agent-runtime/src/agent/memory_loader.rs
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/exploration.md
  • clients/agent-runtime/src/gateway/webhook_dispatch.rs
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/verify-report.md
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/gateway/mod.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/tests/memory_backend_selection.rs
  • clients/agent-runtime/src/config/schema.rs
  • clients/agent-runtime/src/test_support.rs
  • clients/agent-runtime/src/agent/memory_loader.rs
  • clients/agent-runtime/src/gateway/webhook_dispatch.rs
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/gateway/mod.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/tests/memory_backend_selection.rs
  • clients/agent-runtime/src/config/schema.rs
  • clients/agent-runtime/src/test_support.rs
  • clients/agent-runtime/src/agent/memory_loader.rs
  • clients/agent-runtime/src/gateway/webhook_dispatch.rs
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/gateway/mod.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/config/schema.rs
  • clients/agent-runtime/src/test_support.rs
  • clients/agent-runtime/src/agent/memory_loader.rs
  • clients/agent-runtime/src/gateway/webhook_dispatch.rs
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/gateway/mod.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/config/schema.rs
  • clients/agent-runtime/src/gateway/webhook_dispatch.rs
  • clients/agent-runtime/src/gateway/mod.rs
clients/agent-runtime/src/{security,gateway,tools}/**/*.rs

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

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

Files:

  • clients/agent-runtime/src/gateway/webhook_dispatch.rs
  • clients/agent-runtime/src/gateway/mod.rs
🧠 Learnings (10)
📓 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
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Include threat/risk notes and rollback strategy for security, runtime, and gateway changes; add or update tests for boundary checks and failure modes

Applied to files:

  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/tasks.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/exploration.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/verify-report.md
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/design.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/**/*.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:

  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/tasks.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/verify-report.md
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/design.md
  • clients/agent-runtime/src/test_support.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:

  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/tasks.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/design.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/design.md
  • clients/agent-runtime/tests/memory_backend_selection.rs
  • clients/agent-runtime/src/config/schema.rs
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/verify-report.md
  • clients/agent-runtime/src/test_support.rs
  • clients/agent-runtime/src/gateway/webhook_dispatch.rs
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/gateway/mod.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/{security,gateway,tools,config}/**/*.rs : Do not silently weaken security policy or access constraints; keep default behavior secure-by-default with deny-by-default where applicable

Applied to files:

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

Applied to files:

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

Applied to files:

  • clients/agent-runtime/src/config/schema.rs
  • clients/agent-runtime/src/agent/agent.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/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/test_support.rs
  • clients/agent-runtime/src/gateway/mod.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/providers/**/*.rs : Implement `Provider` trait in `src/providers/` and register in `src/providers/mod.rs` factory when adding a new provider

Applied to files:

  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/gateway/mod.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/**/*.rs : Never log secrets, tokens, raw credentials, or sensitive payloads in any logging statements

Applied to files:

  • clients/agent-runtime/src/gateway/mod.rs
🪛 LanguageTool
openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/tasks.md

[grammar] ~1-~1: Use a hyphen to join words.
Context: # Tasks: Webhook Generated Session Isolation ## Phase 1:...

(QB_NEW_EN_HYPHEN)

openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/design.md

[grammar] ~1-~1: Use a hyphen to join words.
Context: # Design: Webhook Generated Session Isolation ## Technica...

(QB_NEW_EN_HYPHEN)

openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/design.md

[uncategorized] ~177-~177: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...- pairing enforcement - IP/header-aware rate limiting - idempotency policy - request parsing ...

(EN_COMPOUND_ADJECTIVE_INTERNAL)


[style] ~350-~350: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...ts. - No resumable approval protocol. - No broad channels/gateway shared-runtime r...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/exploration.md

[style] ~93-~93: As an alternative to the over-used intensifier ‘very’, consider replacing this phrase.
Context: ...ta spec for the follow-up, it should be a very small agent-loop delta that restates this a...

(EN_WEAK_ADJECTIVE)

🪛 markdownlint-cli2 (0.21.0)
openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/exploration.md

[warning] 26-26: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 35-35: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 46-46: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 55-55: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 61-61: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)

openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/verify-report.md

[warning] 81-81: Code block style
Expected: indented; Actual: fenced

(MD046, code-block-style)

openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/design.md

[warning] 81-81: Code block style
Expected: indented; Actual: fenced

(MD046, code-block-style)

openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/exploration.md

[warning] 3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3

(MD001, heading-increment)

🔇 Additional comments (11)
clients/agent-runtime/src/config/schema.rs (1)

666-673: Defaulting this rollout flag off is the right security posture.

webhook_dispatcher_enabled stays opt-in, and the Default impl matches the documented behavior, so /webhook remains on the legacy path unless operators explicitly enable dispatcher mode.

As per coding guidelines clients/agent-runtime/src/{security,gateway,tools,config}/**/*.rs: Do not silently weaken security policy or access constraints; keep default behavior secure-by-default with deny-by-default where applicable.

Also applies to: 723-724

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

31-88: Nice shared env-guard extraction.

This gives config and gateway tests one serialization point for CORVUS_GATEWAY_WEBHOOK_DISPATCHER and restores the prior value on drop.

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

1388-1405: Good redaction on duplicate-idempotency logging.

Fingerprinting the idempotency key here is a solid improvement over emitting the raw header value.

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

318-337: Nice fail-closed handling for classified blocks.

Returning immediately on pre-execution blocks keeps the dispatcher path deny-by-default before the agent ever runs.

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

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

30-73: LGTM!

Clean type definitions for the session-aware turn API. The TurnContext design with with_session constructor and Default impl provides ergonomic construction paths.


595-648: LGTM!

Session ID correctly threaded through memory operations. The fallback on load_context failure (log + empty string) is appropriate for resilience.


659-695: LGTM!

Session ID properly passed to assistant response storage. Truncation before storage is a sensible memory hygiene practice.


811-836: LGTM!

Session ID is now correctly propagated into TurnContext for code-mode turns, addressing the previous session/audit divergence concern.


838-868: LGTM!

Clean structured return API with proper event logging. Session ID correctly propagated to result for downstream correlation.


1393-1445: LGTM!

Clean refactor threading turn_context through the step pipeline. Mission policy enforcement and tool result handling remain intact.


382-386: LGTM!

pub(crate) visibility is appropriate for internal gateway/webhook dispatcher wiring without exposing to external consumers.

Comment thread clients/agent-runtime/src/gateway/webhook_dispatch.rs
Comment thread openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/design.md Outdated
@sentry
Copy link
Copy Markdown

sentry Bot commented Mar 20, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 14

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@clients/agent-runtime/src/agent/agent.rs`:
- Around line 41-54: TurnContext exposes a public origin field but nothing reads
it, making the API misleading; either remove origin from the TurnContext struct
or thread it into the policy gating logic. To fix, choose one: (A) delete the
origin field and its uses (and update constructors like
TurnContext::with_session and any TurnContext::default) so callers cannot pass
an unused origin, or (B) update the execution/policy check paths (the functions
that use the "mission" flag and the entry points like turn_with_context and any
execution gating code) to consult TurnContext.origin (e.g., add a parameter or
access TurnContext.origin inside the policy decision function) so origin
actually influences behavior; pick one approach and apply consistently across
TurnContext, with_session, turn_with_context, and the mission gating logic.
- Around line 843-861: The code captures history_start before the turn mutates
self.history, then later computes approval_required from
&self.history[history_start..], which is invalid if trim_history() ran and
shifted/compacted history; instead, compute and track approval state in
turn-local state while processing the turn (e.g., set a local approval_required
flag when detecting approval/denial events during prepare_turn_with_context /
step_with_context) and return that flag into the AgentTurnResult rather than
slicing self.history by history_start; update uses of history_start,
approval_denial_from_history, and the return path that constructs
AgentTurnResult (including where AgentTurnEvent::Completed is pushed) to use the
new local approval_required value.

In `@clients/agent-runtime/src/agent/memory_loader.rs`:
- Around line 117-120: The code currently panics with anyhow::bail! when
session_id.is_some(), which prevents session-scoped turns from falling back to
local recall; instead, change the branch in the function that checks session_id
(the block containing session_id.is_some() and the call path to mem_search /
Cerebro remote recall) to not bail—log or warn the condition and skip remote
Cerebro recall, returning the safe local-only result (e.g., Ok(None) or the
already-found local memory) so session-aware turns continue without error;
ensure mem_search remains unchanged and only the remote-recall path is skipped
when session_id is present.

In `@clients/agent-runtime/src/gateway/mod.rs`:
- Around line 1629-1667: The branch currently reserves and conditionally
releases idempotency only when dispatcher_enabled (see dispatcher_enabled,
reserved_idempotency_key, webhook_idempotency_key,
state.idempotency_store.record_if_new), causing retryability differences versus
the legacy /webhook/simple_chat path; move the idempotency reservation logic so
the key is reserved before choosing between webhook_dispatch::execute and the
legacy/simple_chat flow, and ensure both paths call the same release policy (use
webhook_response_from_dispatch_result-like persist_idempotency handling and call
state.idempotency_store.remove when persist_idempotency is false) so provider
failures yield identical 500 retry behavior; also add a legacy 500-retry test
that posts with an idempotency key and verifies the key is consumed/released
consistently across dispatcher_enabled true/false.

In `@clients/agent-runtime/src/gateway/webhook_dispatch.rs`:
- Around line 284-295: render_sse_frame currently injects session_id verbatim
into the SSE "id:" field which allows CR/LF injection; sanitize or canonicalize
the session_id before formatting by normalizing it to a single line (e.g., strip
or replace '\r' and '\n' and trim whitespace or take only the first line) and
ensure empty/invalid ids are handled consistently, and update/add a
unit/regression test that passes a session_id containing newlines to
render_sse_frame to assert the output contains a single-line id and no extra SSE
fields; modify the render_sse_frame function's session_id usage (and any callers
if needed) to use the sanitized value.
- Around line 367-378: The code currently falls back to
CanonicalWebhookResult::Agent(result) when approval_denial_from_value() fails to
extract fields, silently downgrading an approval-required event; change the
branch that tests result.approval_required to always map to
CanonicalWebhookResult::ApprovalRequired when approval_required is Some(_) (or
surface an Error), and if approval_denial_from_value() returns a tool with
missing reason, derive the reason using approval_reason_for_tool(tool) instead
of the literal "approval_required"; update map_canonical_result usage
accordingly (referencing AgentTurnResult.approval_required,
approval_denial_from_value, CanonicalWebhookResult::ApprovalRequired,
approval_reason_for_tool and map_canonical_result) and add a regression test
that submits a payload with code == "approval_required" but missing fields to
assert the result is ApprovalRequired (or Error) rather than Completed.
- Around line 298-319: The helper approval_denial_from_history currently scans
history oldest-first while the runtime parser in agent::agent.rs uses
history.iter().rev(); fix this by making approval_denial_from_history iterate
newest-first (e.g., use history.iter().rev() on the outer iterator) so the
search order matches the runtime parser, ensuring the same approval_required
tool result is returned; alternatively, call or reuse the agent-side parser used
at agent::agent.rs lines ~784-799 to keep logic identical.

In `@openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/design.md`:
- Around line 256-264: Update the `/webhook` response contract to account for
the adapter terminal outcomes: map WebhookTerminalOutcome::Fallback to `200 OK`
with the `response` shape plus `fallback: true`, and map
WebhookTerminalOutcome::Error to `500 Internal Server Error` with a structured
`error` payload (distinct from the transport-only 500 case described); keep
`403` for approval-required tool actions, `408` for canonical timeouts with
`aborted: true`, and ensure `session_id` is explicitly stated as echoed in all
terminal responses and that `events_sse` frames (when present) are derived from
the real canonical execution path.

In
`@openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/verify-report.md`:
- Line 17: Update the checklist link in verify-report.md to point to the
archived tasks file instead of the live path: replace references to
"openspec/changes/gateway-dispatcher-parity/tasks.md" with
"openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/tasks.md" so the
checklist stays correct in the archived report; edit the link in
verify-report.md (the file under
openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/) to use the
archived tasks.md path.

In
`@openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/design.md`:
- Around line 71-72: The planned gateway changes must also prevent unguarded
reads of CORVUS_GATEWAY_WEBHOOK_DISPATCHER in
clients/agent-runtime/src/gateway/mod.rs::temp_config(): update temp_config to
obtain the same shared test lock/helper from
clients/agent-runtime/src/test_support.rs (or otherwise remove the direct env
read) before reading CORVUS_GATEWAY_WEBHOOK_DISPATCHER so gateway tests cannot
observe another test's transient env value, and ensure temp_config restores or
derives the value deterministically under that lock.

In `@openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/design.md`:
- Around line 45-58: The decision text in design.md claims a single non-success
seam (Error) suffices, but webhook_response_from_dispatch_result(...) implements
both Timeout and Error paths with different transport contracts; update the
document to either require tests for both Timeout (408 + aborted) and Error (500
+ body) branches or explicitly narrow the decision to state that only the Error
branch is in-scope and justify why Timeout can remain unproven; reference
webhook_response_from_dispatch_result, the Timeout and Error branches, and
ensure the rationale aligns with the actual transport contracts described.

In
`@openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/exploration.md`:
- Around line 16-26: Update the archive note in exploration.md to reflect
current code: change the phrasing that calls missing-header session isolation a
remaining gap to state that the gateway test
webhook_dispatcher_generates_isolated_session_when_header_missing (in
clients/agent-runtime/src/gateway/mod.rs) now provides end-to-end proof, or
explicitly mark the paragraph as historical context; also update the sentence
ranges noted (lines ~64-75) to avoid contradicting the implementation and ensure
the doc references the test by name and file so readers can locate the proof.

In
`@openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/verify-report.md`:
- Around line 79-80: The documentation references two different test symbols for
the "missing-session" proof
(agent::tests::turn_with_context_keeps_missing_session_isolated vs
turn_with_context_omits_session_scope_when_context_missing) which causes an
audit mismatch; update the verify-report.md evidence bullet to use the exact
landed test symbol name (or, if both tests exist, add a one-line clarification
distinguishing their intent) so the doc matches the code; specifically ensure
the evidence bullet references either
turn_with_context_keeps_missing_session_isolated or
turn_with_context_omits_session_scope_when_context_missing (whichever is the
actual test in clients/agent-runtime/src/agent/tests.rs) and, if keeping both,
briefly state the difference relative to
turn_with_context_scopes_memory_recall_and_auto_save_to_session.
- Around line 21-47: The report omitted whether code style and lint checks were
run for the changed Rust surface (clients/agent-runtime/**/*.rs); run and record
the results of `cargo fmt --all -- --check` and `cargo clippy --all-targets --
-D warnings` against that directory (or explicitly document that you
intentionally skipped them and why), and update the verify-report.md to state
the exact commands executed and their pass/fail outputs for those files.
🪄 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: 4dc40840-e6a1-40f5-87a6-6b3cbebc6461

📥 Commits

Reviewing files that changed from the base of the PR and between 4a1e565 and 51cf118.

📒 Files selected for processing (12)
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/agent/memory_loader.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/gateway/webhook_dispatch.rs
  • clients/agent-runtime/src/test_support.rs
  • clients/agent-runtime/tests/memory_backend_selection.rs
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/design.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/verify-report.md
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/design.md
  • openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/design.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/exploration.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/verify-report.md
📜 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: pr-checks
  • GitHub Check: sonar
  • GitHub Check: pr-checks
  • GitHub Check: Cloudflare Pages
🧰 Additional context used
📓 Path-based instructions (7)
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/tests/memory_backend_selection.rs
  • clients/agent-runtime/src/test_support.rs
  • clients/agent-runtime/src/agent/memory_loader.rs
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/gateway/webhook_dispatch.rs
  • clients/agent-runtime/src/gateway/mod.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/tests/memory_backend_selection.rs
  • clients/agent-runtime/src/test_support.rs
  • clients/agent-runtime/src/agent/memory_loader.rs
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/gateway/webhook_dispatch.rs
  • clients/agent-runtime/src/gateway/mod.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/tests/memory_backend_selection.rs
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/design.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/verify-report.md
  • clients/agent-runtime/src/test_support.rs
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/exploration.md
  • clients/agent-runtime/src/agent/memory_loader.rs
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/design.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/verify-report.md
  • openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/design.md
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/gateway/webhook_dispatch.rs
  • clients/agent-runtime/src/gateway/mod.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:

  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/design.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/verify-report.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/exploration.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/design.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/verify-report.md
  • openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/design.md
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/test_support.rs
  • clients/agent-runtime/src/agent/memory_loader.rs
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/gateway/webhook_dispatch.rs
  • clients/agent-runtime/src/gateway/mod.rs
clients/agent-runtime/src/{security,gateway,tools}/**/*.rs

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

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

Files:

  • clients/agent-runtime/src/gateway/webhook_dispatch.rs
  • clients/agent-runtime/src/gateway/mod.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/gateway/webhook_dispatch.rs
  • clients/agent-runtime/src/gateway/mod.rs
🧠 Learnings (14)
📓 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/{security,gateway,tools,config}/**/*.rs : Do not silently weaken security policy or access constraints; keep default behavior secure-by-default with deny-by-default where applicable
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Include threat/risk notes and rollback strategy for security, runtime, and gateway changes; add or update tests for boundary checks and failure modes
📚 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/tests/memory_backend_selection.rs
  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/design.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/exploration.md
  • clients/agent-runtime/src/agent/memory_loader.rs
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/design.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/verify-report.md
  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/gateway/webhook_dispatch.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Include threat/risk notes and rollback strategy for security, runtime, and gateway changes; add or update tests for boundary checks and failure modes

Applied to files:

  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/design.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/verify-report.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/**/*.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:

  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/design.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/verify-report.md
  • clients/agent-runtime/src/test_support.rs
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/exploration.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/verify-report.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/{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:

  • openspec/changes/archive/2026-03-20-gateway-webhook-dispatcher-env-flake/design.md
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/verify-report.md
  • clients/agent-runtime/src/test_support.rs
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/exploration.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/verify-report.md
  • clients/agent-runtime/src/gateway/webhook_dispatch.rs
  • clients/agent-runtime/src/gateway/mod.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/{security,gateway,tools}/**/*.rs : Treat `src/security/`, `src/gateway/`, `src/tools/` as high-risk surfaces and never broaden filesystem/network execution scope without explicit policy checks

Applied to files:

  • clients/agent-runtime/src/test_support.rs
  • openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/exploration.md
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/verify-report.md
  • clients/agent-runtime/src/gateway/webhook_dispatch.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/test_support.rs
  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/verify-report.md
  • clients/agent-runtime/src/gateway/mod.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/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:

  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/verify-report.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/**/Cargo.toml : Do not add heavy dependencies for minor convenience; justify new crate additions

Applied to files:

  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/verify-report.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/**/Cargo.toml : Preserve release-size profile assumptions in `Cargo.toml` and avoid adding heavy dependencies unless clearly justified

Applied to files:

  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/verify-report.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/**/*.rs : Avoid unnecessary allocations, clones, and blocking operations to maintain performance and efficiency

Applied to files:

  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/verify-report.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/.github/**/*.{yml,yaml} : For workflow/template-only changes, ensure YAML/template syntax validity

Applied to files:

  • openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/verify-report.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/providers/**/*.rs : Implement `Provider` trait in `src/providers/` and register in `src/providers/mod.rs` factory when adding a new provider

Applied to files:

  • clients/agent-runtime/src/agent/agent.rs
  • clients/agent-runtime/src/gateway/mod.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/**/*.rs : Never log secrets, tokens, raw credentials, or sensitive payloads in any logging statements

Applied to files:

  • clients/agent-runtime/src/gateway/mod.rs
🪛 LanguageTool
openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/verify-report.md

[style] ~81-~81: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...ayer. - turn_context_for_request(...) in `clients/agent-runtime/src/gateway/webh...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

openspec/changes/archive/2026-03-20-webhook-generated-session-isolation/exploration.md

[style] ~87-~87: As an alternative to the over-used intensifier ‘very’, consider replacing this phrase.
Context: ...ta spec for the follow-up, it should be a very small agent-loop delta that restates this a...

(EN_WEAK_ADJECTIVE)

openspec/changes/archive/2026-03-20-gateway-dispatcher-parity/design.md

[uncategorized] ~178-~178: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...- pairing enforcement - IP/header-aware rate limiting - idempotency policy - request parsing ...

(EN_COMPOUND_ADJECTIVE_INTERNAL)


[style] ~355-~355: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...ts. - No resumable approval protocol. - No broad channels/gateway shared-runtime r...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

🔇 Additional comments (1)
clients/agent-runtime/src/gateway/webhook_dispatch.rs (1)

330-348: Early return on pre-execution blocks looks correct.

This now short-circuits approval/timeout/fallback outcomes before any agent/model work, which preserves the canonical gate in the webhook path.

Comment thread clients/agent-runtime/src/agent/agent.rs Outdated
Comment thread clients/agent-runtime/src/agent/agent.rs Outdated
Comment thread clients/agent-runtime/src/agent/memory_loader.rs
Comment thread clients/agent-runtime/src/gateway/mod.rs
Comment thread clients/agent-runtime/src/gateway/webhook_dispatch.rs Outdated
Comment thread openspec/changes/archive/2026-03-20-mcp-webhook-response-mapping/design.md Outdated
@yacosta738 yacosta738 merged commit b327cfa into main Mar 20, 2026
16 checks passed
@yacosta738 yacosta738 deleted the feature/257-complete-gateway-parity-with-the-canonical-agent-dispatcher branch March 20, 2026 14:56
@yacosta738 yacosta738 mentioned this pull request Mar 20, 2026
@sonarqubecloud
Copy link
Copy Markdown

@dallay-bot dallay-bot Bot mentioned this pull request Apr 14, 2026
@dallay-bot dallay-bot Bot mentioned this pull request May 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Complete gateway parity with the canonical agent dispatcher

1 participant