Skip to content

feat(rook): complete operator surfaces, security baseline, and audit trail#630

Merged
yacosta738 merged 18 commits into
mainfrom
develop
Apr 22, 2026
Merged

feat(rook): complete operator surfaces, security baseline, and audit trail#630
yacosta738 merged 18 commits into
mainfrom
develop

Conversation

@yacosta738
Copy link
Copy Markdown
Contributor

@yacosta738 yacosta738 commented Apr 21, 2026

Related Issues

closes #592
closes #593
closes #594
closes #595
closes #596
closes #597
closes #598
closes #599


Summary

This PR completes the first M2 Corvus Rook operator surfaces and lands the first meaningful M3 hardening and observability slices.

It keeps the Rook experience separate from the legacy Corvus dashboard and includes:

  • dedicated embedded clients/web/apps/rook-dashboard served by clients/rook
  • operator shell and navigation for overview, providers/accounts, pools, routes, read-only health, usage, and settings
  • provider/account administration flows for list, detail, create, edit, enable/disable, and delete
  • backend account update refinement so omitted api_key preserves the stored secret on metadata-only edits
  • pool, route, and read-only health dashboard flows built only on verified contracts
  • usage placeholder and settings management flows built only on verified contracts, while logs and backups remain explicitly deferred
  • first usable embedded Rook TUI slice for read-only status, providers, pools, health, and routes via rook tui and rook serve --tui
  • focused read-only route inspection within the TUI routes view, bounded strictly to verified route contracts
  • final TUI boundary for setup, mutations, and advanced troubleshooting: the terminal now bridges operators to the web dashboard instead of promising terminal form workflows
  • M3 security hardening for loopback-first defaults, explicit non-loopback overrides, inbound-vs-outbound auth separation, and secret-safe operator-visible surfaces
  • a persisted append-only admin audit trail with a bounded recent-events read surface for successful account, pool, pool-membership, route, and settings mutations
  • archived OpenSpec artifacts and synced source-of-truth specs for dashboard, rook-tui, and gateway behavior

With #597, the Rook TUI is intentionally finalized as a fast read-only observability surface, while the web dashboard remains the primary operator surface for setup and mutations. With #598 and #599, the gateway security and admin observability baselines are strengthened without inventing unsupported pairing integration, fake usage analytics, or durable health history.


Tested Information

I verified the shipped slices with targeted dashboard and Rook runtime validation recorded in archived verification reports, plus a full repository build check.

Dashboard validation

  • pnpm --dir "clients/web" --filter @corvus/rook-dashboard check
  • pnpm --dir "clients/web" --filter @corvus/rook-dashboard test -- --run src/features/accounts/AccountsPage.spec.ts
  • pnpm --dir "clients/web" --filter @corvus/rook-dashboard test -- src/features/pools/usePools.spec.ts src/features/pools/PoolsPage.spec.ts src/features/routes/useRoutes.spec.ts src/features/routes/RoutesPage.spec.ts
  • pnpm --filter @corvus/rook-dashboard run test
  • pnpm --filter @corvus/rook-dashboard run test:e2e
  • pnpm --filter @corvus/rook-dashboard run build
  • pnpm --dir "clients/web" --filter @corvus/dashboard check

Observed evidence from archived verification:

Rook TUI validation

  • cargo fmt --manifest-path "clients/rook/Cargo.toml" --check
  • cargo test --manifest-path "clients/rook/Cargo.toml"
  • cargo test --manifest-path "clients/rook/Cargo.toml" tui::
  • cargo test --manifest-path "clients/rook/Cargo.toml" tui_command_launches_real_runner_with_effective_db_path
  • cargo test --manifest-path "clients/rook/Cargo.toml" enable_tui_runs_embedded_tui_with_shared_shutdown
  • cargo clippy --manifest-path "clients/rook/Cargo.toml" --all-targets -- -D warnings

Observed evidence from archived verification (#595, #596, #597):

  • full cargo test PASS from prior TUI slice verification (src/lib.rs: 262 passed, src/main.rs: 3 passed, doc tests: 1 passed)
  • targeted TUI tests PASS (12 passed, covering routes visibility, load states, query bounds, dashboard bridging, and shell rendering)
  • launch path tests PASS for standalone and embedded TUI entrypoints
  • cargo fmt --check PASS
  • cargo clippy ... -D warnings PASS

Gateway hardening and audit validation

  • cargo test --manifest-path "clients/rook/Cargo.toml" serve_cli_defaults_to_loopback_first_bind_posture
  • cargo test --manifest-path "clients/rook/Cargo.toml" server_config_defaults_to_loopback_first_bind_target
  • cargo test --manifest-path "clients/rook/Cargo.toml" explicit_non_loopback_override_remains_honored
  • cargo test --manifest-path "clients/rook/Cargo.toml" proxy_chat_completion_never_reuses_inbound_bearer_token_as_provider_auth
  • cargo test --manifest-path "clients/rook/Cargo.toml" inbound_auth_operator_state_reports_enabled_and_configured_without_exposing_token
  • cargo test --manifest-path "clients/rook/Cargo.toml" account_view_redacts_api_key_and_sets_has_api_key
  • cargo test --manifest-path "clients/rook/Cargo.toml" middleware_completion_log_fields_remain_structured_and_secret_free
  • cargo test --manifest-path "clients/rook/Cargo.toml" open_in_memory_applies_admin_audit_events_migration
  • cargo test --manifest-path "clients/rook/Cargo.toml" open_in_memory_records_admin_audit_events_migration_version
  • cargo test --manifest-path "clients/rook/Cargo.toml" append_and_list_admin_audit_events_newest_first
  • cargo test --manifest-path "clients/rook/Cargo.toml" sqlite_audit_service_appends_and_lists_recent_events
  • cargo test --manifest-path "clients/rook/Cargo.toml" registry_audit_append_and_list_round_trip
  • cargo test --manifest-path "clients/rook/Cargo.toml" handle_create_account_appends_audit_event_on_success
  • cargo clippy --manifest-path "clients/rook/Cargo.toml" --all-targets -- -D warnings

Observed evidence from archived verification (#598, #599):

  • bind posture defaults and explicit override behavior PASS
  • inbound/outbound auth boundary regression PASS
  • operator-visible auth/config redaction PASS
  • account secret redaction PASS
  • structured logging secret-safety PASS
  • admin audit migration, DB helpers, registry wiring, and handler emission PASS
  • bounded audit read surface PASS
  • usage remained placeholder-only and health remained runtime-only
  • cargo clippy ... -D warnings PASS

Full repository check

  • make build

Observed evidence:

  • the full repository build passed after fixing the legacy dashboard import-ordering failure
  • final make build exit code: 0

Documentation Impact

  • Docs updated in:
    • openspec/specs/dashboard/spec.md
    • openspec/specs/rook-tui/spec.md
    • openspec/specs/gateway/spec.md
    • openspec/changes/archive/2026-04-22-rook-592-dashboard-overview-providers-accounts/
    • openspec/changes/archive/2026-04-22-rook-593-dashboard-pools-routes-health-ops/
    • openspec/changes/archive/2026-04-22-rook-594-dashboard-usage-settings/
    • openspec/changes/archive/2026-04-23-rook-595-tui-status-providers-pools-health/
    • openspec/changes/archive/2026-04-23-rook-596-tui-route-inspection-recent-logs/
    • openspec/changes/archive/2026-04-23-rook-597-tui-setup-troubleshooting/
    • openspec/changes/archive/2026-04-23-rook-598-security-defaults-and-secret-protection/
    • openspec/changes/archive/2026-04-23-rook-599-observability-usage-health-audit/
  • I verified the documentation matches the current behavior.

Breaking Changes

None.


Checklist

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

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 21, 2026

Warning

Rate limit exceeded

@yacosta738 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 42 minutes and 51 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 42 minutes and 51 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 9f82b88e-06da-4b1f-beaa-4bf8bc7d2651

📥 Commits

Reviewing files that changed from the base of the PR and between eb2bc35 and 28df7ff.

⛔ Files ignored due to path filters (3)
  • .opencode/package-lock.json is excluded by !**/package-lock.json
  • clients/rook/Cargo.lock is excluded by !**/*.lock
  • clients/web/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (146)
  • .github/rulesets/README.md
  • .github/rulesets/develop-protection.json
  • .github/rulesets/minor-protection.json
  • clients/agent-runtime/src/agent/coordinator.rs
  • clients/agent-runtime/src/agent/mailbox.rs
  • clients/agent-runtime/src/bridge/mod.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/lib.rs
  • clients/agent-runtime/src/memory/dream.rs
  • clients/agent-runtime/src/memory/mod.rs
  • clients/agent-runtime/src/tools/delegate.rs
  • clients/agent-runtime/src/tools/delegate_cancel.rs
  • clients/agent-runtime/src/tools/delegate_inspect.rs
  • clients/agent-runtime/src/tools/delegate_launch.rs
  • clients/rook/Cargo.toml
  • clients/rook/assets/assets/index-BGLvRAEp.css
  • clients/rook/assets/assets/index-BOcxyaY5.js
  • clients/rook/assets/assets/index-Bzqbvx-K.js
  • clients/rook/assets/assets/index-Cjl9wA4y.js
  • clients/rook/assets/assets/index-Dq_oV3yI.js
  • clients/rook/assets/assets/index.js
  • clients/rook/assets/index.html
  • clients/rook/migrations/0004_chat_completions_idempotency.sql
  • clients/rook/src/admin/handlers.rs
  • clients/rook/src/admin/mod.rs
  • clients/rook/src/admin/types.rs
  • clients/rook/src/auth/bearer.rs
  • clients/rook/src/auth/middleware.rs
  • clients/rook/src/auth/mod.rs
  • clients/rook/src/auth/types.rs
  • clients/rook/src/config/mod.rs
  • clients/rook/src/dashboard/mod.rs
  • clients/rook/src/db/account.rs
  • clients/rook/src/db/idempotency.rs
  • clients/rook/src/db/mod.rs
  • clients/rook/src/db/pool.rs
  • clients/rook/src/db/route.rs
  • clients/rook/src/db/settings.rs
  • clients/rook/src/domain/mod.rs
  • clients/rook/src/gateway/handlers.rs
  • clients/rook/src/gateway/mod.rs
  • clients/rook/src/gateway/streaming.rs
  • clients/rook/src/gateway/types.rs
  • clients/rook/src/gateway/upstream.rs
  • clients/rook/src/gateway/vendor.rs
  • clients/rook/src/idempotency/canonical.rs
  • clients/rook/src/idempotency/middleware.rs
  • clients/rook/src/idempotency/mod.rs
  • clients/rook/src/idempotency/types.rs
  • clients/rook/src/lib.rs
  • clients/rook/src/main.rs
  • clients/rook/src/registry/mod.rs
  • clients/rook/src/routing/mod.rs
  • clients/rook/src/server/mod.rs
  • clients/rook/src/services/account.rs
  • clients/rook/src/services/health.rs
  • clients/rook/src/services/idempotency.rs
  • clients/rook/src/services/mod.rs
  • clients/rook/src/services/pool.rs
  • clients/rook/src/services/route.rs
  • clients/rook/src/services/settings.rs
  • clients/rook/src/transport/context.rs
  • clients/rook/src/transport/forwarded.rs
  • clients/rook/src/transport/middleware.rs
  • clients/rook/src/transport/mod.rs
  • clients/rook/src/transport/rate_limit.rs
  • clients/rook/src/transport/request_id.rs
  • clients/web/apps/rook-dashboard/README.md
  • clients/web/apps/rook-dashboard/e2e/rook-dashboard.spec.ts
  • clients/web/apps/rook-dashboard/index.html
  • clients/web/apps/rook-dashboard/package.json
  • clients/web/apps/rook-dashboard/playwright.config.ts
  • clients/web/apps/rook-dashboard/src/App.vue
  • clients/web/apps/rook-dashboard/src/features/accounts/AccountsPage.spec.ts
  • clients/web/apps/rook-dashboard/src/features/accounts/AccountsPage.vue
  • clients/web/apps/rook-dashboard/src/features/accounts/useAccounts.spec.ts
  • clients/web/apps/rook-dashboard/src/features/accounts/useAccounts.ts
  • clients/web/apps/rook-dashboard/src/features/overview/OverviewPage.spec.ts
  • clients/web/apps/rook-dashboard/src/features/overview/OverviewPage.vue
  • clients/web/apps/rook-dashboard/src/features/overview/useOverview.spec.ts
  • clients/web/apps/rook-dashboard/src/features/overview/useOverview.ts
  • clients/web/apps/rook-dashboard/src/lib/api/client.ts
  • clients/web/apps/rook-dashboard/src/lib/api/types.ts
  • clients/web/apps/rook-dashboard/src/lib/navigation/routes.spec.ts
  • clients/web/apps/rook-dashboard/src/lib/navigation/routes.ts
  • clients/web/apps/rook-dashboard/src/lib/session/useRookSession.ts
  • clients/web/apps/rook-dashboard/src/main.ts
  • clients/web/apps/rook-dashboard/src/style.css
  • clients/web/apps/rook-dashboard/src/vite-env.d.ts
  • clients/web/apps/rook-dashboard/tsconfig.app.json
  • clients/web/apps/rook-dashboard/tsconfig.json
  • clients/web/apps/rook-dashboard/tsconfig.node.json
  • clients/web/apps/rook-dashboard/vite.config.ts
  • clients/web/package.json
  • openspec/changes/archive/2026-04-21-rook-589-gateway-api/state.yaml
  • openspec/changes/archive/2026-04-21-rook-590-admin-api/design.md
  • openspec/changes/archive/2026-04-21-rook-590-admin-api/proposal.md
  • openspec/changes/archive/2026-04-21-rook-590-admin-api/spec.md
  • openspec/changes/archive/2026-04-21-rook-590-admin-api/state.yaml
  • openspec/changes/archive/2026-04-21-rook-590-admin-api/tasks.md
  • openspec/changes/archive/2026-04-21-rook-590-admin-api/verify-report.md
  • openspec/changes/archive/2026-04-22-2026-04-22-track-4-orchestration-parity-seam/design.md
  • openspec/changes/archive/2026-04-22-2026-04-22-track-4-orchestration-parity-seam/proposal.md
  • openspec/changes/archive/2026-04-22-2026-04-22-track-4-orchestration-parity-seam/specs/multi-agent-orchestration/spec.md
  • openspec/changes/archive/2026-04-22-2026-04-22-track-4-orchestration-parity-seam/state.yaml
  • openspec/changes/archive/2026-04-22-2026-04-22-track-4-orchestration-parity-seam/tasks.md
  • openspec/changes/archive/2026-04-22-2026-04-22-track-4-orchestration-parity-seam/verify-report.md
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-idempotency/design.md
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-idempotency/proposal.md
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-idempotency/specs/gateway/spec.md
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-idempotency/state.yaml
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-idempotency/tasks.md
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-idempotency/verify-report.md
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-streaming-transport/design.md
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-streaming-transport/proposal.md
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-streaming-transport/specs/gateway/spec.md
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-streaming-transport/state.yaml
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-streaming-transport/tasks.md
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-streaming-transport/verify-report.md
  • openspec/changes/archive/2026-04-22-rook-591-global-surface-rate-limits/design.md
  • openspec/changes/archive/2026-04-22-rook-591-global-surface-rate-limits/proposal.md
  • openspec/changes/archive/2026-04-22-rook-591-global-surface-rate-limits/specs/gateway/spec.md
  • openspec/changes/archive/2026-04-22-rook-591-global-surface-rate-limits/state.yaml
  • openspec/changes/archive/2026-04-22-rook-591-global-surface-rate-limits/tasks.md
  • openspec/changes/archive/2026-04-22-rook-591-global-surface-rate-limits/verify-report.md
  • openspec/changes/archive/2026-04-22-rook-591-inbound-auth-boundary/design.md
  • openspec/changes/archive/2026-04-22-rook-591-inbound-auth-boundary/proposal.md
  • openspec/changes/archive/2026-04-22-rook-591-inbound-auth-boundary/specs/gateway/spec.md
  • openspec/changes/archive/2026-04-22-rook-591-inbound-auth-boundary/state.yaml
  • openspec/changes/archive/2026-04-22-rook-591-inbound-auth-boundary/tasks.md
  • openspec/changes/archive/2026-04-22-rook-591-inbound-auth-boundary/verify-report.md
  • openspec/changes/archive/2026-04-22-rook-591-transport-middleware-baseline/design.md
  • openspec/changes/archive/2026-04-22-rook-591-transport-middleware-baseline/proposal.md
  • openspec/changes/archive/2026-04-22-rook-591-transport-middleware-baseline/specs/gateway/spec.md
  • openspec/changes/archive/2026-04-22-rook-591-transport-middleware-baseline/state.yaml
  • openspec/changes/archive/2026-04-22-rook-591-transport-middleware-baseline/tasks.md
  • openspec/changes/archive/2026-04-22-rook-591-transport-middleware-baseline/verify-report.md
  • openspec/changes/archive/2026-04-22-rook-592-dashboard-overview-providers-accounts/design.md
  • openspec/changes/archive/2026-04-22-rook-592-dashboard-overview-providers-accounts/proposal.md
  • openspec/changes/archive/2026-04-22-rook-592-dashboard-overview-providers-accounts/specs/dashboard/spec.md
  • openspec/changes/archive/2026-04-22-rook-592-dashboard-overview-providers-accounts/state.yaml
  • openspec/changes/archive/2026-04-22-rook-592-dashboard-overview-providers-accounts/tasks.md
  • openspec/changes/archive/2026-04-22-rook-592-dashboard-overview-providers-accounts/verify-report.md
  • openspec/specs/dashboard/spec.md
  • openspec/specs/gateway/spec.md
  • openspec/specs/multi-agent-orchestration/spec.md
📝 Walkthrough

Walkthrough

This PR implements comprehensive additions to the Rook gateway API with streaming support, idempotency, admin management, and transport infrastructure, while expanding agent-runtime with richer orchestration lifecycle tracking and memory consolidation. It includes a new Vue dashboard, GitHub branch protection rulesets, and extensive backend services across auth, database, and HTTP middleware layers.

Changes

Cohort / File(s) Summary
GitHub Rulesets Documentation & Config
.github/rulesets/README.md, .github/rulesets/develop-protection.json, .github/rulesets/minor-protection.json
Added comprehensive documentation for branch protections; introduced develop-protection ruleset with approval/CI/merge-queue rules; narrowed minor-protection scope to exclude develop branch
Agent Runtime Coordinator Lifecycle & Events
clients/agent-runtime/src/agent/coordinator.rs
Refactored child state machine with new lifecycle stages (Queued, Starting, WaitingOnParent, Cancelling, Completed); added execution spec/approval request/decision types; introduced persistent event log with CoordinatorEvent; implemented launch validation with fail-closed contract rejection for unsupported transports/isolations
Agent Runtime Mailbox & Bridge
clients/agent-runtime/src/agent/mailbox.rs, clients/agent-runtime/src/bridge/mod.rs, clients/agent-runtime/src/lib.rs
Added payload categorization for approval messages; introduced bridge protocol with SSE/WebSocket envelopes and remote availability semantics
Agent Runtime Memory Consolidation
clients/agent-runtime/src/memory/dream.rs, clients/agent-runtime/src/memory/mod.rs, clients/agent-runtime/src/gateway/mod.rs
Implemented "dream" consolidation workflow for memory deduplication/pruning with triggering logic and filesystem locking; wired session completion recording into gateway cleanup
Agent Runtime Delegate Tools
clients/agent-runtime/src/tools/delegate*.rs
Updated launch/inspect/cancel tool tests and implementations to handle execution metadata, cancellation visibility events, and approval workflows
Rook Admin API
clients/rook/src/admin/{handlers.rs,mod.rs,types.rs}
Complete admin CRUD endpoints for accounts/pools/routes/settings; health aggregation; structured error responses with redaction of api_key
Rook Auth & Transport
clients/rook/src/auth/{bearer.rs,middleware.rs,types.rs,mod.rs}, clients/rook/src/transport/{context.rs,forwarded.rs,middleware.rs,rate_limit.rs,request_id.rs,mod.rs}
Bearer token extraction; inbound auth middleware; request-ID resolution and response header injection; trusted-proxy forwarded-header parsing; per-surface rate limiting with window tracking; sanitized transport context injection
Rook Idempotency
clients/rook/src/idempotency/{canonical.rs,middleware.rs,mod.rs,types.rs}, clients/rook/src/db/idempotency.rs
JSON canonicalization and hashing; principal-scoped idempotency key validation; SQLite persistence and state transitions; route-local middleware with replay/conflict/in-progress detection
Rook Gateway Streaming
clients/rook/src/gateway/{streaming.rs,handlers.rs,types.rs,upstream.rs,mod.rs}
OpenAI-style SSE frame parsing/normalization with duplicate sentinel detection; split buffered/streaming chat-completion paths; upstream streaming adapter; new response helpers for auth/rate-limit/idempotency errors
Rook Services & Database
clients/rook/src/services/{account.rs,health.rs,idempotency.rs,pool.rs,route.rs,settings.rs,mod.rs}, clients/rook/src/db/{account.rs,pool.rs,route.rs,settings.rs,mod.rs}
Referential integrity checks for account deletion; transactional pool upsert; idempotency service abstraction with SQLite backing; fallback pool validation; database migration for idempotency table
Rook Configuration & Server
clients/rook/src/config/mod.rs, clients/rook/src/main.rs, clients/rook/src/server/mod.rs, clients/rook/Cargo.toml
Config structs for inbound auth, rate limits, idempotency, transport, request-ID; CLI argument parsing for feature flags; server router composition with layered auth/rate-limit/transport/idempotency middleware; added reqwest stream feature and cryptography dependencies
Rook Dashboard (Vue App)
clients/web/apps/rook-dashboard/{src/**,index.html,package.json,*.config.ts}
Complete operator dashboard with Overview and Accounts pages; session/API client management; account CRUD flows with enabled/disabled handling; vendor grouping; health summaries; unit + E2E test coverage
Rook Dashboard Frontend Assets
clients/rook/assets/{index.html,assets/*.js,assets/*.css}, clients/rook/src/dashboard/mod.rs
Compiled dashboard bundles, CSS styling, fallback/bootstrap HTML; wired into embedded asset serving
OpenSpec Archive Documentation
openspec/changes/archive/**/*.md, .github/rulesets/, migration files
Design specs, proposals, task lists, and verification reports for admin API, orchestration parity, idempotency, and streaming features; state transitions to archive

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Gateway as Rook Gateway<br/>(Middleware Stack)
    participant Upstream as Upstream Provider<br/>(OpenAI/Anthropic)
    
    Note over Client,Upstream: Chat Completions with Idempotency
    
    Client->>Gateway: POST /v1/chat/completions<br/>{"stream": false,<br/>"idempotency-key": "..."}
    
    Gateway->>Gateway: 1. Extract bearer token<br/>2. Validate idempotency key<br/>3. Canonicalize JSON body<br/>4. Hash canonical bytes
    
    Gateway->>Gateway: Check idempotency store<br/>for (principal, key, method, path)
    
    alt Replay Completed
        Gateway->>Gateway: Load stored response
        Gateway-->>Client: 200 OK<br/>+ Idempotency-Replayed: true
    else In Progress
        Gateway-->>Client: 409 Conflict<br/>idempotency_request_in_progress
    else Key Reused Mismatch
        Gateway-->>Client: 409 Conflict<br/>idempotency_key_reused
    else New Request
        Gateway->>Gateway: Reserve idempotency slot<br/>status = InProgress
        Gateway->>Upstream: POST /v1/chat/completions<br/>(buffered)
        Upstream-->>Gateway: 200 + JSON response
        Gateway->>Gateway: Store response + status<br/>= Completed
        Gateway-->>Client: 200 OK<br/>+ Idempotency-Replayed: false
    end
Loading
sequenceDiagram
    participant Client
    participant Gateway as Rook Gateway<br/>(Middleware Stack)
    participant Upstream as Upstream Provider
    
    Note over Client,Upstream: Streaming Chat Completions (stream=true)
    
    Client->>Gateway: POST /v1/chat/completions<br/>{"stream": true}
    
    Gateway->>Gateway: 1. Auth validation<br/>2. Rate limit check<br/>3. Route to streaming handler
    
    Gateway->>Upstream: POST /v1/chat/completions<br/>(stream request)
    
    Upstream-->>Gateway: 200 OK<br/>(streaming response)
    
    Gateway->>Gateway: Open byte stream<br/>from upstream
    
    Gateway->>Gateway: Parse SSE frames<br/>("data: {...}\n\n")
    
    loop For each upstream chunk
        Gateway->>Gateway: Validate frame format<br/>Reject duplicate [DONE]
        Gateway->>Client: SSE Event<br/>(event:, id:, data:)
    end
    
    Upstream-->>Gateway: [DONE]
    
    Gateway-->>Client: Final SSE Event<br/>([DONE])
    
    Gateway->>Gateway: Update account health<br/>(async)
Loading
sequenceDiagram
    participant Parent as Parent Runtime<br/>(Coordinator)
    participant Mailbox
    participant Child as Child Process
    
    Note over Parent,Child: Child Launch with Execution Contract
    
    Parent->>Parent: validate child execution spec<br/>(transport, isolation, broker)
    
    alt Unsupported Contract
        Parent-->>Parent: CoordinatorError<br/>LaunchContractRejected
    else Contract Valid
        Parent->>Parent: Normalize execution metadata<br/>(requested vs enforced)
        
        Parent->>Parent: Emit CoordinatorEvent<br/>(ChildStateChanged → Queued)
        
        Parent->>Mailbox: Enqueue launch message<br/>(with execution spec)
        
        Mailbox-->>Child: Deliver launch
        
        Child->>Child: Process launch
        
        Parent->>Parent: Emit CoordinatorEvent<br/>(ChildStateChanged → Starting)
        
        Parent->>Parent: Persist event to log
        
        Note over Parent: Inspect returns child state + events
    end
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Rationale: This PR introduces substantial, interconnected changes across multiple technical domains (Rust backend services, web frontend, database persistence, authentication, transport middleware, streaming protocols, and state machine logic). Key factors:

  • Complexity density: Idempotency middleware with multi-state transactions, coordinator lifecycle state machine with event ordering guarantees, streaming SSE frame parsing with duplicate detection, and rate-limit windowing all require careful logic verification
  • Scope heterogeneity: Changes span auth (bearer token extraction, middleware), transport (request-ID, trusted proxies, rate limiting), database (migrations, referential integrity), HTTP handlers (admin CRUD, streaming, error mapping), and a complete Vue.js dashboard application
  • Security implications: Bearer token handling, idempotency key scoping, API key redaction in responses, and fail-closed contract validation for unsupported transports require security-focused review
  • Behavioral correctness: Event ordering/idempotency guarantees, streaming frame termination, cancellation visibility, and state immutability in coordinator require careful verification against the specification

Possibly related PRs

Suggested labels

area:rust, area:docs, risk:high, risk:security, area:web

Suggested reviewers

  • yuniel-acosta
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch develop

@github-actions github-actions Bot added the size/s Denotes a small change size label Apr 21, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 21, 2026

✅ Contributor Report

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

Metric Description Value Threshold Status
PR Merge Rate PRs merged vs closed 92% >= 30%
Repo Quality Repos with ≥100 stars 0 >= 0
Positive Reactions Positive reactions received 11 >= 1
Negative Reactions Negative reactions received 0 <= 5
Account Age GitHub account age 3100 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 603 >= 0
Merger Diversity Unique maintainers who merged PRs 2 >= 0
Repo History Merge Rate Merge rate in this repo 93% >= 0%
Repo History Min PRs Previous PRs in this repo 272 >= 0
Profile Completeness Profile richness (bio, followers) 90 >= 0
Suspicious Patterns Spam-like activity detection 1 N/A

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

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

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

Deploying corvus with  Cloudflare Pages  Cloudflare Pages

Latest commit: 28df7ff
Status:⚡️  Build in progress...

View logs

@github-actions github-actions Bot added size/xl Denotes an extra large change size and removed size/s Denotes a small change size labels Apr 21, 2026
@yacosta738 yacosta738 changed the title feat: rook gateway feat(rook): add embedded operator dashboard flows Apr 22, 2026
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: 68

Caution

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

⚠️ Outside diff range comments (7)
clients/agent-runtime/src/tools/delegate.rs (1)

274-283: ⚠️ Potential issue | 🟠 Major

Reject unsupported execution fields instead of silently dropping them.

Session-mode delegate builds execution: None, while execute() ignores any extra request fields. A caller that passes remote_bridge, transport, isolation, or escalation metadata can be silently run locally, which violates the fail-closed contract.

🛡️ Proposed fix
     async fn execute(&self, args: serde_json::Value) -> anyhow::Result<ToolResult> {
-        let agent_name = args
-            .get("agent")
+        let Some(args_obj) = args.as_object() else {
+            return Ok(ToolResult {
+                success: false,
+                output: String::new(),
+                error: Some("delegate arguments must be an object".into()),
+                structured: None,
+            });
+        };
+
+        if let Some(unsupported) = args_obj
+            .keys()
+            .find(|key| !matches!(key.as_str(), "agent" | "prompt" | "context"))
+        {
+            return Ok(ToolResult {
+                success: false,
+                output: String::new(),
+                error: Some(format!(
+                    "Unsupported delegate parameter '{unsupported}'; remote transport, isolation, and escalation fields are not accepted by delegate"
+                )),
+                structured: None,
+            });
+        }
+
+        let agent_name = args_obj
+            .get("agent")
             .and_then(|v| v.as_str())
             .map(str::trim)
             .ok_or_else(|| anyhow::anyhow!("Missing 'agent' parameter"))?;
 
         if agent_name.is_empty() {
@@
-        let prompt = args
-            .get("prompt")
+        let prompt = args_obj
+            .get("prompt")
             .and_then(|v| v.as_str())
             .map(str::trim)
             .ok_or_else(|| anyhow::anyhow!("Missing 'prompt' parameter"))?;
@@
-        let context = args
-            .get("context")
+        let context = args_obj
+            .get("context")
             .and_then(|v| v.as_str())
             .map(str::trim)
             .unwrap_or("");

As per coding guidelines, 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.

Also applies to: 348-438

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

In `@clients/agent-runtime/src/tools/delegate.rs` around lines 274 - 283, The
delegate session builder currently constructs
CoordinatorLaunchRequest/ChildLaunchRequest with execution: None and silently
drops execution-related fields (remote_bridge, transport, isolation,
escalation), so update the delegate handling in
clients/agent-runtime/src/tools/delegate.rs to validate incoming request
parameters against the Tool trait schema and fail-fast: if any
execution-specific fields are present in the incoming request, return a
structured ToolResult error (not a panic) indicating unsupported execution
metadata for session-mode delegates; specifically add checks around the code
that constructs CoordinatorLaunchRequest and ChildLaunchRequest to inspect
execution/remote_bridge/transport/isolation/escalation and reject with a clear
ToolResult error, and ensure execute() is updated to propagate/validate these
errors rather than ignoring extra fields.
clients/agent-runtime/src/agent/coordinator.rs (2)

1034-1081: ⚠️ Potential issue | 🟠 Major

Lifecycle gap: Cancelling can be overwritten by a late child message.

ChildStarted, ChildProgress, RequestApproval, and ResolveApproval only reject on is_terminal(), but Cancelling is non-terminal. A message that races with apply_cancellation_visibility (or a slow in-process runner) will flip the record back to Running / WaitingOnParent, silently erasing the "cancellation in progress" state that the spec guarantees callers can observe, and re-emitting a ChildStateChanged event that contradicts prior cancellation visibility.

Guard these transitions against Cancelling too (either ignore or fold into the cancelling summary without state regression):

🛡️ Proposed fix
             CoordinatorMessage::ChildStarted { session_id } => {
-                if record.state.is_terminal() {
+                if record.state.is_terminal() || record.state == ChildState::Cancelling {
                     return Err(CoordinatorError::AlreadyTerminalState);
                 }
                 record.state = ChildState::Running;
                 record.approval = ApprovalStatus::None;
                 record.session_id = session_id.clone();
             }
             CoordinatorMessage::ChildProgress { summary } => {
-                if record.state.is_terminal() {
+                if record.state.is_terminal() || record.state == ChildState::Cancelling {
                     return Err(CoordinatorError::AlreadyTerminalState);
                 }
-                record.state = ChildState::Running;
-                record.summary = Some(summary.clone());
+                record.summary = Some(summary.clone());
             }
             CoordinatorMessage::RequestApproval { request } => {
-                if record.state.is_terminal() {
+                if record.state.is_terminal() || record.state == ChildState::Cancelling {
                     return Err(CoordinatorError::AlreadyTerminalState);
                 }
                 record.state = ChildState::WaitingOnParent;

As per coding guidelines: "Do not silently weaken security policy or access constraints; keep default behavior secure-by-default with deny-by-default where applicable" — cancellation visibility counts as a policy constraint the parent relies on.

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

In `@clients/agent-runtime/src/agent/coordinator.rs` around lines 1034 - 1081, The
handlers for CoordinatorMessage::ChildStarted, ::ChildProgress,
::RequestApproval, and ::ResolveApproval currently only reject terminal states
but will overwrite a non-terminal ChildState::Cancelling; update each handler in
the apply_message/apply_envelope path so that before mutating record.state or
emitting events (e.g., via self.log_event(CoordinatorEvent::...)) you check for
record.state == ChildState::Cancelling and either ignore the incoming message or
merge it into the cancelling state (e.g., update summary/approval without
changing state or emitting a ChildStateChanged), ensuring
apply_cancellation_visibility cannot be reverted by late child messages; keep
the check colocated with the existing is_terminal() guard so all four message
arms (ChildStarted, ChildProgress, RequestApproval, ResolveApproval) behave
consistently.

1838-1926: 🧹 Nitpick | 🔵 Trivial

admit_child runs three times per child on the launch path.

validate_launch_request (via a throwaway Coordinator), then snapshot_seed.admit_child, then coordinator.run_with_cancellationadmit_child again inside the spawned task. The snapshot_seed coordinator is immediately dropped after producing the initial snapshot, so it contributes nothing beyond duplicating validation. Consider collapsing to one: validate once, build the initial snapshot from the validator (or from the real coordinator after a pre-admit that the spawned task then skips).

Not a correctness bug — admit_child is deterministic for valid inputs — but it's extra allocation and a third place any future admission invariant needs to stay in sync.

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

In `@clients/agent-runtime/src/agent/coordinator.rs` around lines 1838 - 1926, The
validator flow currently admits children three times; change
validate_launch_request to build and return a pre-admitted Coordinator (or
accept a Coordinator to admit into) instead of creating a throwaway inside the
function, then in launch reuse that returned Coordinator as both the
snapshot_seed and the coordinator passed into tokio::spawn (so
snapshot_from_coordinator uses it and run_with_cancellation is started on the
same pre-admitted Coordinator), ensuring only one admit_child sequence; update
references: validate_launch_request, snapshot_from_coordinator, launch,
Coordinator::admit_child, and run_with_cancellation to use the shared
pre-admitted Coordinator.
clients/rook/src/db/settings.rs (1)

62-68: ⚠️ Potential issue | 🟠 Major

Use checked conversions for persisted numeric settings.

The row_to_settings() function retrieves signed i64 values from SQLite and casts them to unsigned types (u16, u32, u64) with unchecked as operators at lines 63, 66–67. Corrupted or manually edited database rows containing out-of-range values (negative numbers, values exceeding type limits) will silently wrap or truncate into valid-looking configuration. Replace these with try_from() checks:

     Ok(RookSettings {
-        gateway_port: gateway_port as u16,
+        gateway_port: u16::try_from(gateway_port)
+            .map_err(|_| RookError::Registry(format!("gateway_port out of range: {gateway_port}")))?,
         default_routing_policy: RoutingPolicy {
             strategy,
-            max_retries: max_retries as u32,
-            cooldown_seconds: cooldown_seconds as u64,
+            max_retries: u32::try_from(max_retries)
+                .map_err(|_| RookError::Registry(format!("max_retries out of range: {max_retries}")))?,
+            cooldown_seconds: u64::try_from(cooldown_seconds).map_err(|_| {
+                RookError::Registry(format!("cooldown_seconds out of range: {cooldown_seconds}"))
+            })?,
         },

This pattern is already used elsewhere in db/ (e.g., idempotency.rs:38, account.rs:84–86) and aligns with the existing error handling convention in this function.

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

In `@clients/rook/src/db/settings.rs` around lines 62 - 68, Replace the unchecked
casts in row_to_settings() that convert the retrieved i64 values into unsigned
types—specifically gateway_port, max_retries, and cooldown_seconds used to
populate RookSettings and its default_routing_policy (RoutingPolicy)—with
checked conversions (e.g., u16::try_from / u32::try_from / u64::try_from) and
map any conversion failures to the function's existing error return (consistent
with other db modules like idempotency.rs/account.rs). Ensure each failed
try_from returns a clear DB error (include the field name and offending value)
so out-of-range or negative persisted values are rejected instead of silently
wrapping.
clients/rook/src/db/route.rs (1)

174-225: ⚠️ Potential issue | 🟡 Minor

Doc comment now lies; also TOCTOU between the three queries.

Two issues in the rewritten delete_route:

  1. The doc comment still claims the function only returns true/false, but it now also returns Err(RookError::Registry(...)) when the route is referenced. Update the contract so callers know to expect the 409-style conflict branch.
  2. The guarded DELETE ... AND NOT EXISTS (...), the existence SELECT, and the referencing SELECT run as three independent statements on a pooled connection. If a concurrent caller removes the referencing route between steps 1 and 3, you fall through to the final Ok(false) on line 224 even though the route still exists and could have been deleted. It's a narrow race, but the admin API will then lie to the operator ("not found") for a row that's still in the DB.

Consider wrapping the three statements in a single transaction (or re-attempting the guarded delete once when the reference check comes back empty) and refreshing the doc.

📝 Proposed doc tweak
-    /// Delete a [`ModelRoute`] by ID.
-    ///
-    /// Returns `true` if a row was deleted, `false` if not found.
+    /// Delete a [`ModelRoute`] by ID.
+    ///
+    /// Returns `Ok(true)` if the row was deleted, `Ok(false)` if it did not exist,
+    /// or `Err(RookError::Registry(_))` if another route still references it as
+    /// `fallback_route_id`.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@clients/rook/src/db/route.rs` around lines 174 - 225, The doc comment for
delete_route is stale and the function has a TOCTOU race across three separate
queries; update the doc to state it can return Ok(true) if deleted, Ok(false) if
not found, or Err(RookError::Registry(...)) for a conflict when referenced, and
fix the race by executing the guarded DELETE, existence check, and reference
check inside a single database transaction (use a transaction obtained from the
pool and run query/execute on that transaction) so the checks and delete are
atomic; alternatively you may re-attempt the guarded DELETE once after the
reference check returns empty, but prefer the transaction approach and ensure
you commit/rollback the transaction and preserve the same error messages from
delete_route.
clients/rook/src/services/account.rs (1)

143-147: ⚠️ Potential issue | 🔴 Critical

update as delete+insert without atomicity is a data loss footgun.

The schema uses ON DELETE CASCADE for pool_members.account_id, so deleting a provider account cascades to remove every pool membership that references it. The current implementation executes delete_account + insert_account as two separate, non-atomic statements—a crash or error between them leaves the account gone entirely.

Concretely: updating an account's display_name/weight/etc. silently deletes all pool memberships that reference it on successful completion. A network hiccup or transient database error mid-operation loses the account entirely.

SqlitePoolService::update demonstrates the correct pattern: wrap the delete+insert in sqlx::Transaction and commit atomically (see db/pool.rs lines 147–226). Apply the same approach here, or implement a real UPDATE provider_accounts SET ... statement in the db layer (preserving created_at, updating updated_at). Also note SqliteRouteService::update has the identical issue.

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

In `@clients/rook/src/services/account.rs` around lines 143 - 147, The current
async fn update in account.rs performs self.db.delete_account(...).await
followed by self.db.insert_account(...).await without atomicity, which can
cascade-delete pool_members on failure; wrap the delete+insert inside a
sqlx::Transaction (begin, perform delete and insert via the transaction, then
commit) following the pattern used by SqlitePoolService::update so the operation
is atomic, or alternatively implement a proper UPDATE statement in the db layer
that preserves created_at and updates updated_at; also apply the same
transactional fix to SqliteRouteService::update which has the identical
delete+insert issue.
clients/rook/src/db/pool.rs (1)

147-229: ⚠️ Potential issue | 🟠 Major

The DELETE+INSERT pattern will fail if any model_route references this pool.

When deleting and re-inserting a row in provider_pools, the model_routes table's foreign key constraint (target_pool_id) REFERENCES provider_pools(id) ON DELETE RESTRICT prevents deletion. If any route targets this pool, the DELETE fails and the transaction rolls back. The pool_members table avoids this via its ON DELETE CASCADE, but the code still repopulates them unnecessarily.

Replace with UPDATE provider_pools SET name=?, strategy=?, fallback_pool_id=?, updated_at=? WHERE id=?, then diff members (DELETE missing ones, INSERT new ones). This keeps the row ID stable, avoids FK triggers, and prevents the created_at mutation problem.

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

In `@clients/rook/src/db/pool.rs` around lines 147 - 229, In replace_pool, the
current DELETE+INSERT of provider_pools breaks foreign keys (model_routes ON
DELETE RESTRICT) and mutates created_at; instead update the existing row:
perform an UPDATE provider_pools SET name=?, strategy=?, fallback_pool_id=?,
updated_at=? WHERE id=? (use strategy_to_db_str(&pool.strategy) and now for
updated_at) rather than deleting and reinserting, preserving created_at and the
same id; then diff pool.members against existing pool_members (select existing
account_id for pool_id) and issue DELETEs for removed members and INSERT OR
IGNORE for new members (binding pool_id strings), keeping the fallback existence
check and transaction/commit logic unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: c7565c78-d181-4e22-bb70-7c23370b5495

📥 Commits

Reviewing files that changed from the base of the PR and between 81aec86 and b1bfa68.

⛔ Files ignored due to path filters (3)
  • .opencode/package-lock.json is excluded by !**/package-lock.json
  • clients/rook/Cargo.lock is excluded by !**/*.lock
  • clients/web/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (146)
  • .github/rulesets/README.md
  • .github/rulesets/develop-protection.json
  • .github/rulesets/minor-protection.json
  • clients/agent-runtime/src/agent/coordinator.rs
  • clients/agent-runtime/src/agent/mailbox.rs
  • clients/agent-runtime/src/bridge/mod.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/lib.rs
  • clients/agent-runtime/src/memory/dream.rs
  • clients/agent-runtime/src/memory/mod.rs
  • clients/agent-runtime/src/tools/delegate.rs
  • clients/agent-runtime/src/tools/delegate_cancel.rs
  • clients/agent-runtime/src/tools/delegate_inspect.rs
  • clients/agent-runtime/src/tools/delegate_launch.rs
  • clients/rook/Cargo.toml
  • clients/rook/assets/assets/index-BGLvRAEp.css
  • clients/rook/assets/assets/index-BOcxyaY5.js
  • clients/rook/assets/assets/index-Bzqbvx-K.js
  • clients/rook/assets/assets/index-Cjl9wA4y.js
  • clients/rook/assets/assets/index-Dq_oV3yI.js
  • clients/rook/assets/assets/index.js
  • clients/rook/assets/index.html
  • clients/rook/migrations/0004_chat_completions_idempotency.sql
  • clients/rook/src/admin/handlers.rs
  • clients/rook/src/admin/mod.rs
  • clients/rook/src/admin/types.rs
  • clients/rook/src/auth/bearer.rs
  • clients/rook/src/auth/middleware.rs
  • clients/rook/src/auth/mod.rs
  • clients/rook/src/auth/types.rs
  • clients/rook/src/config/mod.rs
  • clients/rook/src/dashboard/mod.rs
  • clients/rook/src/db/account.rs
  • clients/rook/src/db/idempotency.rs
  • clients/rook/src/db/mod.rs
  • clients/rook/src/db/pool.rs
  • clients/rook/src/db/route.rs
  • clients/rook/src/db/settings.rs
  • clients/rook/src/domain/mod.rs
  • clients/rook/src/gateway/handlers.rs
  • clients/rook/src/gateway/mod.rs
  • clients/rook/src/gateway/streaming.rs
  • clients/rook/src/gateway/types.rs
  • clients/rook/src/gateway/upstream.rs
  • clients/rook/src/gateway/vendor.rs
  • clients/rook/src/idempotency/canonical.rs
  • clients/rook/src/idempotency/middleware.rs
  • clients/rook/src/idempotency/mod.rs
  • clients/rook/src/idempotency/types.rs
  • clients/rook/src/lib.rs
  • clients/rook/src/main.rs
  • clients/rook/src/registry/mod.rs
  • clients/rook/src/routing/mod.rs
  • clients/rook/src/server/mod.rs
  • clients/rook/src/services/account.rs
  • clients/rook/src/services/health.rs
  • clients/rook/src/services/idempotency.rs
  • clients/rook/src/services/mod.rs
  • clients/rook/src/services/pool.rs
  • clients/rook/src/services/route.rs
  • clients/rook/src/services/settings.rs
  • clients/rook/src/transport/context.rs
  • clients/rook/src/transport/forwarded.rs
  • clients/rook/src/transport/middleware.rs
  • clients/rook/src/transport/mod.rs
  • clients/rook/src/transport/rate_limit.rs
  • clients/rook/src/transport/request_id.rs
  • clients/web/apps/rook-dashboard/README.md
  • clients/web/apps/rook-dashboard/e2e/rook-dashboard.spec.ts
  • clients/web/apps/rook-dashboard/index.html
  • clients/web/apps/rook-dashboard/package.json
  • clients/web/apps/rook-dashboard/playwright.config.ts
  • clients/web/apps/rook-dashboard/src/App.vue
  • clients/web/apps/rook-dashboard/src/features/accounts/AccountsPage.spec.ts
  • clients/web/apps/rook-dashboard/src/features/accounts/AccountsPage.vue
  • clients/web/apps/rook-dashboard/src/features/accounts/useAccounts.spec.ts
  • clients/web/apps/rook-dashboard/src/features/accounts/useAccounts.ts
  • clients/web/apps/rook-dashboard/src/features/overview/OverviewPage.spec.ts
  • clients/web/apps/rook-dashboard/src/features/overview/OverviewPage.vue
  • clients/web/apps/rook-dashboard/src/features/overview/useOverview.spec.ts
  • clients/web/apps/rook-dashboard/src/features/overview/useOverview.ts
  • clients/web/apps/rook-dashboard/src/lib/api/client.ts
  • clients/web/apps/rook-dashboard/src/lib/api/types.ts
  • clients/web/apps/rook-dashboard/src/lib/navigation/routes.spec.ts
  • clients/web/apps/rook-dashboard/src/lib/navigation/routes.ts
  • clients/web/apps/rook-dashboard/src/lib/session/useRookSession.ts
  • clients/web/apps/rook-dashboard/src/main.ts
  • clients/web/apps/rook-dashboard/src/style.css
  • clients/web/apps/rook-dashboard/src/vite-env.d.ts
  • clients/web/apps/rook-dashboard/tsconfig.app.json
  • clients/web/apps/rook-dashboard/tsconfig.json
  • clients/web/apps/rook-dashboard/tsconfig.node.json
  • clients/web/apps/rook-dashboard/vite.config.ts
  • clients/web/package.json
  • openspec/changes/archive/2026-04-21-rook-589-gateway-api/state.yaml
  • openspec/changes/archive/2026-04-21-rook-590-admin-api/design.md
  • openspec/changes/archive/2026-04-21-rook-590-admin-api/proposal.md
  • openspec/changes/archive/2026-04-21-rook-590-admin-api/spec.md
  • openspec/changes/archive/2026-04-21-rook-590-admin-api/state.yaml
  • openspec/changes/archive/2026-04-21-rook-590-admin-api/tasks.md
  • openspec/changes/archive/2026-04-21-rook-590-admin-api/verify-report.md
  • openspec/changes/archive/2026-04-22-2026-04-22-track-4-orchestration-parity-seam/design.md
  • openspec/changes/archive/2026-04-22-2026-04-22-track-4-orchestration-parity-seam/proposal.md
  • openspec/changes/archive/2026-04-22-2026-04-22-track-4-orchestration-parity-seam/specs/multi-agent-orchestration/spec.md
  • openspec/changes/archive/2026-04-22-2026-04-22-track-4-orchestration-parity-seam/state.yaml
  • openspec/changes/archive/2026-04-22-2026-04-22-track-4-orchestration-parity-seam/tasks.md
  • openspec/changes/archive/2026-04-22-2026-04-22-track-4-orchestration-parity-seam/verify-report.md
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-idempotency/design.md
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-idempotency/proposal.md
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-idempotency/specs/gateway/spec.md
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-idempotency/state.yaml
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-idempotency/tasks.md
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-idempotency/verify-report.md
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-streaming-transport/design.md
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-streaming-transport/proposal.md
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-streaming-transport/specs/gateway/spec.md
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-streaming-transport/state.yaml
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-streaming-transport/tasks.md
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-streaming-transport/verify-report.md
  • openspec/changes/archive/2026-04-22-rook-591-global-surface-rate-limits/design.md
  • openspec/changes/archive/2026-04-22-rook-591-global-surface-rate-limits/proposal.md
  • openspec/changes/archive/2026-04-22-rook-591-global-surface-rate-limits/specs/gateway/spec.md
  • openspec/changes/archive/2026-04-22-rook-591-global-surface-rate-limits/state.yaml
  • openspec/changes/archive/2026-04-22-rook-591-global-surface-rate-limits/tasks.md
  • openspec/changes/archive/2026-04-22-rook-591-global-surface-rate-limits/verify-report.md
  • openspec/changes/archive/2026-04-22-rook-591-inbound-auth-boundary/design.md
  • openspec/changes/archive/2026-04-22-rook-591-inbound-auth-boundary/proposal.md
  • openspec/changes/archive/2026-04-22-rook-591-inbound-auth-boundary/specs/gateway/spec.md
  • openspec/changes/archive/2026-04-22-rook-591-inbound-auth-boundary/state.yaml
  • openspec/changes/archive/2026-04-22-rook-591-inbound-auth-boundary/tasks.md
  • openspec/changes/archive/2026-04-22-rook-591-inbound-auth-boundary/verify-report.md
  • openspec/changes/archive/2026-04-22-rook-591-transport-middleware-baseline/design.md
  • openspec/changes/archive/2026-04-22-rook-591-transport-middleware-baseline/proposal.md
  • openspec/changes/archive/2026-04-22-rook-591-transport-middleware-baseline/specs/gateway/spec.md
  • openspec/changes/archive/2026-04-22-rook-591-transport-middleware-baseline/state.yaml
  • openspec/changes/archive/2026-04-22-rook-591-transport-middleware-baseline/tasks.md
  • openspec/changes/archive/2026-04-22-rook-591-transport-middleware-baseline/verify-report.md
  • openspec/changes/archive/2026-04-22-rook-592-dashboard-overview-providers-accounts/design.md
  • openspec/changes/archive/2026-04-22-rook-592-dashboard-overview-providers-accounts/proposal.md
  • openspec/changes/archive/2026-04-22-rook-592-dashboard-overview-providers-accounts/specs/dashboard/spec.md
  • openspec/changes/archive/2026-04-22-rook-592-dashboard-overview-providers-accounts/state.yaml
  • openspec/changes/archive/2026-04-22-rook-592-dashboard-overview-providers-accounts/tasks.md
  • openspec/changes/archive/2026-04-22-rook-592-dashboard-overview-providers-accounts/verify-report.md
  • openspec/specs/dashboard/spec.md
  • openspec/specs/gateway/spec.md
  • openspec/specs/multi-agent-orchestration/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). (3)
  • GitHub Check: Cloudflare Pages
  • GitHub Check: sonar
  • GitHub Check: pr-checks
🧰 Additional context used
📓 Path-based instructions (9)
**/*

⚙️ CodeRabbit configuration file

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

Files:

  • clients/web/apps/rook-dashboard/src/vite-env.d.ts
  • clients/rook/src/auth/mod.rs
  • openspec/changes/archive/2026-04-22-2026-04-22-track-4-orchestration-parity-seam/state.yaml
  • clients/agent-runtime/src/lib.rs
  • clients/rook/assets/assets/index-BGLvRAEp.css
  • openspec/changes/archive/2026-04-22-2026-04-22-track-4-orchestration-parity-seam/tasks.md
  • clients/rook/src/services/mod.rs
  • clients/web/apps/rook-dashboard/tsconfig.json
  • clients/web/apps/rook-dashboard/src/lib/navigation/routes.spec.ts
  • clients/web/apps/rook-dashboard/src/main.ts
  • clients/web/apps/rook-dashboard/tsconfig.node.json
  • clients/web/apps/rook-dashboard/index.html
  • clients/rook/src/lib.rs
  • clients/rook/assets/assets/index.js
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-idempotency/state.yaml
  • clients/rook/assets/index.html
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-idempotency/tasks.md
  • clients/agent-runtime/src/agent/mailbox.rs
  • openspec/changes/archive/2026-04-21-rook-589-gateway-api/state.yaml
  • clients/web/apps/rook-dashboard/README.md
  • clients/web/apps/rook-dashboard/src/lib/session/useRookSession.ts
  • clients/rook/src/dashboard/mod.rs
  • clients/agent-runtime/src/tools/delegate_cancel.rs
  • clients/web/apps/rook-dashboard/src/features/accounts/useAccounts.spec.ts
  • clients/agent-runtime/src/tools/delegate.rs
  • clients/agent-runtime/src/tools/delegate_inspect.rs
  • clients/web/apps/rook-dashboard/src/features/overview/useOverview.spec.ts
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-streaming-transport/proposal.md
  • clients/web/apps/rook-dashboard/playwright.config.ts
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-streaming-transport/design.md
  • openspec/changes/archive/2026-04-22-2026-04-22-track-4-orchestration-parity-seam/proposal.md
  • clients/rook/src/transport/mod.rs
  • clients/rook/src/services/health.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-idempotency/design.md
  • openspec/changes/archive/2026-04-21-rook-590-admin-api/proposal.md
  • clients/web/apps/rook-dashboard/tsconfig.app.json
  • clients/rook/assets/assets/index-Bzqbvx-K.js
  • clients/rook/src/auth/types.rs
  • openspec/changes/archive/2026-04-21-rook-590-admin-api/verify-report.md
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-idempotency/proposal.md
  • clients/web/apps/rook-dashboard/src/App.vue
  • clients/rook/assets/assets/index-BOcxyaY5.js
  • clients/rook/src/idempotency/mod.rs
  • clients/rook/src/auth/bearer.rs
  • openspec/changes/archive/2026-04-22-2026-04-22-track-4-orchestration-parity-seam/verify-report.md
  • clients/web/apps/rook-dashboard/vite.config.ts
  • clients/rook/src/db/settings.rs
  • openspec/changes/archive/2026-04-21-rook-590-admin-api/state.yaml
  • clients/web/apps/rook-dashboard/src/features/accounts/AccountsPage.vue
  • clients/web/apps/rook-dashboard/src/features/overview/OverviewPage.vue
  • clients/rook/src/gateway/vendor.rs
  • clients/agent-runtime/src/memory/mod.rs
  • clients/rook/src/transport/middleware.rs
  • openspec/changes/archive/2026-04-22-2026-04-22-track-4-orchestration-parity-seam/design.md
  • clients/web/apps/rook-dashboard/src/lib/api/client.ts
  • clients/web/apps/rook-dashboard/package.json
  • clients/rook/src/domain/mod.rs
  • clients/web/apps/rook-dashboard/src/lib/api/types.ts
  • clients/agent-runtime/src/tools/delegate_launch.rs
  • clients/web/apps/rook-dashboard/e2e/rook-dashboard.spec.ts
  • clients/agent-runtime/src/bridge/mod.rs
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-idempotency/verify-report.md
  • clients/web/apps/rook-dashboard/src/lib/navigation/routes.ts
  • clients/rook/src/services/account.rs
  • clients/rook/src/admin/mod.rs
  • clients/rook/src/auth/middleware.rs
  • clients/web/apps/rook-dashboard/src/features/overview/OverviewPage.spec.ts
  • openspec/changes/archive/2026-04-21-rook-590-admin-api/spec.md
  • clients/rook/assets/assets/index-Cjl9wA4y.js
  • clients/rook/src/services/settings.rs
  • clients/rook/src/gateway/mod.rs
  • clients/rook/src/transport/request_id.rs
  • clients/rook/migrations/0004_chat_completions_idempotency.sql
  • openspec/changes/archive/2026-04-21-rook-590-admin-api/tasks.md
  • clients/rook/src/idempotency/canonical.rs
  • clients/rook/src/db/account.rs
  • clients/web/apps/rook-dashboard/src/features/accounts/AccountsPage.spec.ts
  • clients/rook/Cargo.toml
  • clients/rook/src/idempotency/types.rs
  • clients/web/package.json
  • clients/web/apps/rook-dashboard/src/features/accounts/useAccounts.ts
  • clients/rook/src/main.rs
  • clients/rook/src/registry/mod.rs
  • openspec/changes/archive/2026-04-21-rook-590-admin-api/design.md
  • clients/rook/src/transport/context.rs
  • clients/web/apps/rook-dashboard/src/features/overview/useOverview.ts
  • clients/rook/assets/assets/index-Dq_oV3yI.js
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-idempotency/specs/gateway/spec.md
  • clients/rook/src/db/idempotency.rs
  • clients/rook/src/services/route.rs
  • clients/rook/src/db/route.rs
  • clients/rook/src/idempotency/middleware.rs
  • clients/rook/src/transport/forwarded.rs
  • openspec/changes/archive/2026-04-22-2026-04-22-track-4-orchestration-parity-seam/specs/multi-agent-orchestration/spec.md
  • clients/rook/src/gateway/types.rs
  • clients/rook/src/gateway/streaming.rs
  • clients/rook/src/db/pool.rs
  • clients/rook/src/admin/types.rs
  • clients/rook/src/transport/rate_limit.rs
  • clients/rook/src/services/pool.rs
  • clients/rook/src/services/idempotency.rs
  • clients/rook/src/db/mod.rs
  • clients/rook/src/gateway/upstream.rs
  • clients/rook/src/gateway/handlers.rs
  • clients/agent-runtime/src/memory/dream.rs
  • clients/web/apps/rook-dashboard/src/style.css
  • clients/rook/src/routing/mod.rs
  • clients/rook/src/server/mod.rs
  • clients/rook/src/config/mod.rs
  • clients/rook/src/admin/handlers.rs
  • clients/agent-runtime/src/agent/coordinator.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/rook/src/auth/mod.rs
  • clients/agent-runtime/src/lib.rs
  • clients/rook/src/services/mod.rs
  • clients/rook/src/lib.rs
  • clients/agent-runtime/src/agent/mailbox.rs
  • clients/rook/src/dashboard/mod.rs
  • clients/agent-runtime/src/tools/delegate_cancel.rs
  • clients/agent-runtime/src/tools/delegate.rs
  • clients/agent-runtime/src/tools/delegate_inspect.rs
  • clients/rook/src/transport/mod.rs
  • clients/rook/src/services/health.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/rook/src/auth/types.rs
  • clients/rook/src/idempotency/mod.rs
  • clients/rook/src/auth/bearer.rs
  • clients/rook/src/db/settings.rs
  • clients/rook/src/gateway/vendor.rs
  • clients/agent-runtime/src/memory/mod.rs
  • clients/rook/src/transport/middleware.rs
  • clients/rook/src/domain/mod.rs
  • clients/agent-runtime/src/tools/delegate_launch.rs
  • clients/agent-runtime/src/bridge/mod.rs
  • clients/rook/src/services/account.rs
  • clients/rook/src/admin/mod.rs
  • clients/rook/src/auth/middleware.rs
  • clients/rook/src/services/settings.rs
  • clients/rook/src/gateway/mod.rs
  • clients/rook/src/transport/request_id.rs
  • clients/rook/src/idempotency/canonical.rs
  • clients/rook/src/db/account.rs
  • clients/rook/src/idempotency/types.rs
  • clients/rook/src/main.rs
  • clients/rook/src/registry/mod.rs
  • clients/rook/src/transport/context.rs
  • clients/rook/src/db/idempotency.rs
  • clients/rook/src/services/route.rs
  • clients/rook/src/db/route.rs
  • clients/rook/src/idempotency/middleware.rs
  • clients/rook/src/transport/forwarded.rs
  • clients/rook/src/gateway/types.rs
  • clients/rook/src/gateway/streaming.rs
  • clients/rook/src/db/pool.rs
  • clients/rook/src/admin/types.rs
  • clients/rook/src/transport/rate_limit.rs
  • clients/rook/src/services/pool.rs
  • clients/rook/src/services/idempotency.rs
  • clients/rook/src/db/mod.rs
  • clients/rook/src/gateway/upstream.rs
  • clients/rook/src/gateway/handlers.rs
  • clients/agent-runtime/src/memory/dream.rs
  • clients/rook/src/routing/mod.rs
  • clients/rook/src/server/mod.rs
  • clients/rook/src/config/mod.rs
  • clients/rook/src/admin/handlers.rs
  • clients/agent-runtime/src/agent/coordinator.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/lib.rs
  • clients/agent-runtime/src/agent/mailbox.rs
  • clients/agent-runtime/src/tools/delegate_cancel.rs
  • clients/agent-runtime/src/tools/delegate.rs
  • clients/agent-runtime/src/tools/delegate_inspect.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/memory/mod.rs
  • clients/agent-runtime/src/tools/delegate_launch.rs
  • clients/agent-runtime/src/bridge/mod.rs
  • clients/agent-runtime/src/memory/dream.rs
  • clients/agent-runtime/src/agent/coordinator.rs
clients/agent-runtime/**/*.rs

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

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

Files:

  • clients/agent-runtime/src/lib.rs
  • clients/agent-runtime/src/agent/mailbox.rs
  • clients/agent-runtime/src/tools/delegate_cancel.rs
  • clients/agent-runtime/src/tools/delegate.rs
  • clients/agent-runtime/src/tools/delegate_inspect.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/memory/mod.rs
  • clients/agent-runtime/src/tools/delegate_launch.rs
  • clients/agent-runtime/src/bridge/mod.rs
  • clients/agent-runtime/src/memory/dream.rs
  • clients/agent-runtime/src/agent/coordinator.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-04-22-2026-04-22-track-4-orchestration-parity-seam/tasks.md
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-idempotency/tasks.md
  • clients/web/apps/rook-dashboard/README.md
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-streaming-transport/proposal.md
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-streaming-transport/design.md
  • openspec/changes/archive/2026-04-22-2026-04-22-track-4-orchestration-parity-seam/proposal.md
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-idempotency/design.md
  • openspec/changes/archive/2026-04-21-rook-590-admin-api/proposal.md
  • openspec/changes/archive/2026-04-21-rook-590-admin-api/verify-report.md
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-idempotency/proposal.md
  • openspec/changes/archive/2026-04-22-2026-04-22-track-4-orchestration-parity-seam/verify-report.md
  • openspec/changes/archive/2026-04-22-2026-04-22-track-4-orchestration-parity-seam/design.md
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-idempotency/verify-report.md
  • openspec/changes/archive/2026-04-21-rook-590-admin-api/spec.md
  • openspec/changes/archive/2026-04-21-rook-590-admin-api/tasks.md
  • openspec/changes/archive/2026-04-21-rook-590-admin-api/design.md
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-idempotency/specs/gateway/spec.md
  • openspec/changes/archive/2026-04-22-2026-04-22-track-4-orchestration-parity-seam/specs/multi-agent-orchestration/spec.md
clients/agent-runtime/src/tools/**/*.rs

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

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

Files:

  • clients/agent-runtime/src/tools/delegate_cancel.rs
  • clients/agent-runtime/src/tools/delegate.rs
  • clients/agent-runtime/src/tools/delegate_inspect.rs
  • clients/agent-runtime/src/tools/delegate_launch.rs
clients/agent-runtime/src/{security,gateway,tools}/**/*.rs

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

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

Files:

  • clients/agent-runtime/src/tools/delegate_cancel.rs
  • clients/agent-runtime/src/tools/delegate.rs
  • clients/agent-runtime/src/tools/delegate_inspect.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/tools/delegate_launch.rs
clients/agent-runtime/src/{security,gateway,tools,config}/**/*.rs

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

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

Files:

  • clients/agent-runtime/src/tools/delegate_cancel.rs
  • clients/agent-runtime/src/tools/delegate.rs
  • clients/agent-runtime/src/tools/delegate_inspect.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/tools/delegate_launch.rs
**/*.vue

⚙️ CodeRabbit configuration file

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

Files:

  • clients/web/apps/rook-dashboard/src/App.vue
  • clients/web/apps/rook-dashboard/src/features/accounts/AccountsPage.vue
  • clients/web/apps/rook-dashboard/src/features/overview/OverviewPage.vue
🧠 Learnings (13)
📚 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/rook/src/auth/mod.rs
  • clients/agent-runtime/src/lib.rs
  • clients/rook/src/auth/middleware.rs
  • clients/rook/src/transport/context.rs
  • clients/rook/src/server/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/rook/src/auth/mod.rs
  • clients/agent-runtime/src/lib.rs
  • clients/rook/src/lib.rs
  • clients/rook/src/gateway/vendor.rs
  • clients/rook/src/auth/middleware.rs
  • clients/rook/src/main.rs
  • clients/rook/src/transport/context.rs
  • clients/rook/src/gateway/types.rs
  • clients/rook/src/routing/mod.rs
  • clients/rook/src/server/mod.rs
  • clients/rook/src/config/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/rook/src/auth/mod.rs
  • clients/agent-runtime/src/lib.rs
  • clients/rook/src/lib.rs
  • clients/rook/src/transport/mod.rs
  • clients/rook/src/domain/mod.rs
  • clients/agent-runtime/src/bridge/mod.rs
  • clients/rook/src/registry/mod.rs
  • clients/rook/src/routing/mod.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/**/Cargo.toml : Do not add heavy dependencies for minor convenience; justify new crate additions

Applied to files:

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

Applied to files:

  • clients/agent-runtime/src/lib.rs
  • clients/agent-runtime/src/tools/delegate_cancel.rs
  • clients/agent-runtime/src/tools/delegate.rs
  • clients/rook/src/services/health.rs
  • clients/agent-runtime/src/tools/delegate_launch.rs
  • clients/rook/src/main.rs
  • clients/rook/src/db/route.rs
  • clients/rook/src/gateway/types.rs
  • clients/rook/src/routing/mod.rs
  • clients/agent-runtime/src/agent/coordinator.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/**/*.rs : Run `cargo fmt --all -- --check`, `cargo clippy --all-targets -- -D warnings`, and `cargo test` for code validation, or document which checks were skipped and why

Applied to files:

  • clients/agent-runtime/src/lib.rs
  • openspec/changes/archive/2026-04-22-2026-04-22-track-4-orchestration-parity-seam/tasks.md
  • clients/rook/src/idempotency/mod.rs
  • clients/rook/src/gateway/vendor.rs
  • clients/rook/src/domain/mod.rs
  • clients/rook/src/main.rs
  • clients/agent-runtime/src/memory/dream.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:

  • openspec/changes/archive/2026-04-22-2026-04-22-track-4-orchestration-parity-seam/tasks.md
  • openspec/changes/archive/2026-04-22-rook-591-chat-completions-idempotency/tasks.md
  • clients/rook/src/transport/mod.rs
  • clients/agent-runtime/src/bridge/mod.rs
  • clients/rook/src/gateway/mod.rs
  • clients/rook/src/main.rs
  • clients/rook/src/gateway/upstream.rs
  • clients/rook/src/gateway/handlers.rs
  • clients/rook/src/routing/mod.rs
  • clients/rook/src/server/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-04-22-2026-04-22-track-4-orchestration-parity-seam/tasks.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/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/tools/delegate_cancel.rs
  • clients/agent-runtime/src/tools/delegate_launch.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/**/Cargo.toml : Preserve release-size profile assumptions in `Cargo.toml` and avoid adding heavy dependencies unless clearly justified

Applied to files:

  • clients/rook/Cargo.toml
📚 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/rook/src/main.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: Follow `.github/pull_request_template.md` and keep PR descriptions concrete with problem, change, non-goals, risk, and rollback information

Applied to files:

  • .github/rulesets/README.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:

  • clients/rook/src/routing/mod.rs
🪛 LanguageTool
openspec/changes/archive/2026-04-22-rook-591-chat-completions-idempotency/tasks.md

[grammar] ~23-~23: Ensure spelling is correct
Context: ...he chat-completions route. ## Phase 4: Config and Apply Readiness - [x] 4.1 Update `...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

openspec/changes/archive/2026-04-22-rook-591-chat-completions-streaming-transport/proposal.md

[style] ~21-~21: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...e SSE for streaming chat completions. - Define the minimum SSE event framing, media ty...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~36-~36: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...eaming behavior for GET /v1/models. - Any streaming behavior for routes outside `...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

openspec/changes/archive/2026-04-22-2026-04-22-track-4-orchestration-parity-seam/proposal.md

[grammar] ~26-~26: Ensure spelling is correct
Context: ...le tools so launch, inspect, and cancel form one explicit, parent-owned runtime co...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

openspec/changes/archive/2026-04-22-rook-591-chat-completions-idempotency/design.md

[style] ~59-~59: This adverb was used twice in the sentence. Consider removing one of them or replacing them with a synonym.
Context: ...raw incoming bytes as-is - Canonicalize only known OpenAI fields and ignore passthro...

(ADVERB_REPETITION_PREMIUM)

openspec/changes/archive/2026-04-21-rook-590-admin-api/proposal.md

[style] ~28-~28: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ..., get, update, and delete operations. - Expose pool membership endpoints for adding an...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~29-~29: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...emoving provider accounts from pools. - Expose route management endpoints for create, ...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~30-~30: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ..., get, update, and delete operations. - Expose health read endpoints for account-level...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~31-~31: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... records and aggregate summary views. - Expose settings read and update endpoints. - A...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

openspec/changes/archive/2026-04-22-rook-591-chat-completions-idempotency/proposal.md

[style] ~23-~23: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...etions create attempt for this slice. - Define replay behavior for equivalent repeated...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~39-~39: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...otency behavior for GET /v1/models. - Any idempotency behavior for routes outside...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

openspec/changes/archive/2026-04-22-2026-04-22-track-4-orchestration-parity-seam/design.md

[style] ~6-~6: Consider using “the surrounding contract”.
Context: ...ed orchestration authority and finishes the contract around it instead of introducing a second orchest...

(NOUN_AROUND_IT)


[style] ~226-~226: This wording could be more concise.
Context: ...ify | Keep shared service/runner wiring unchanged in shape, but ensure the same contract types are...

(ADJECTIVE_IN_ATTRIBUTE)

openspec/changes/archive/2026-04-21-rook-590-admin-api/spec.md

[style] ~32-~32: Consider removing “of” to be more concise
Context: ...ok. The composed server MUST preserve all of the following at the same time: - GET /ap...

(ALL_OF_THE)

openspec/changes/archive/2026-04-21-rook-590-admin-api/design.md

[style] ~245-~245: You have already used this phrasing in nearby sentences. Consider replacing it to add variety to your writing.
Context: ...| clients/rook/src/services/pool.rs | Maybe modify | Only if needed to tighten not-...

(REP_MAYBE)


[style] ~246-~246: You have already used this phrasing in nearby sentences. Consider replacing it to add variety to your writing.
Context: ... clients/rook/src/services/route.rs | Maybe modify | Only if needed to preserve sta...

(REP_MAYBE)


[style] ~246-~246: You have already used this phrasing in nearby sentences. Consider replacing it to add variety to your writing.
Context: ...ices/route.rs` | Maybe modify | Only if needed to preserve stable not-found/conflict mapp...

(REP_NEED_TO_VB)

openspec/changes/archive/2026-04-22-rook-591-chat-completions-idempotency/specs/gateway/spec.md

[style] ~81-~81: Consider removing “of” to be more concise
Context: ...system MUST determine equivalence using all of the following together: authenticated princ...

(ALL_OF_THE)

🪛 markdownlint-cli2 (0.22.0)
openspec/changes/archive/2026-04-22-2026-04-22-track-4-orchestration-parity-seam/proposal.md

[warning] 24-24: 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)

openspec/changes/archive/2026-04-22-2026-04-22-track-4-orchestration-parity-seam/verify-report.md

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

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

openspec/changes/archive/2026-04-22-rook-591-chat-completions-idempotency/verify-report.md

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

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


[warning] 53-53: Ordered list item prefix
Expected: 1; Actual: 13; Style: 1/1/1

(MD029, ol-prefix)

🪛 Stylelint (17.7.0)
clients/rook/assets/assets/index-BGLvRAEp.css

[error] 1-1: Expected quotes around "Segoe UI" (font-family-name-quotes)

(font-family-name-quotes)

clients/web/apps/rook-dashboard/src/style.css

[error] 1-1: Expected "url("@corvus/shared/base.css")" to be ""@corvus/shared/base.css"" (import-notation)

(import-notation)

Comment on lines +225 to +280
fn normalize_execution_metadata(
spec: Option<&ChildExecutionSpec>,
) -> Result<Option<ChildExecutionMetadataView>, LaunchContractRejection> {
let Some(spec) = spec else {
return Ok(None);
};

let requested = NormalizedExecutionRequest::from(spec);

if requested.transport == CoordinatorTransport::RemoteBridge {
return Err(LaunchContractRejection::UnsupportedTransport {
requested: CoordinatorTransport::RemoteBridge,
});
}

if let Some(repository_id) = &requested.repository_id {
return Err(LaunchContractRejection::UnsupportedIsolation {
field: "repository_id".to_string(),
requested: repository_id.clone(),
});
}

if let Some(worktree_id) = &requested.worktree_id {
return Err(LaunchContractRejection::UnsupportedIsolation {
field: "worktree_id".to_string(),
requested: worktree_id.clone(),
});
}

if let Some(sandbox_mode) = &requested.sandbox_mode {
let normalized = sandbox_mode.trim().to_ascii_lowercase();
if matches!(
normalized.as_str(),
"clone" | "cloned" | "isolated" | "workspace_clone"
) {
return Err(LaunchContractRejection::UnsupportedIsolation {
field: "sandbox_mode".to_string(),
requested: sandbox_mode.clone(),
});
}
}

if let Some(permission_broker) = &requested.permission_broker {
let normalized = permission_broker.trim().to_ascii_lowercase();
if normalized != "parent_owned_only" {
return Err(LaunchContractRejection::UnsupportedPermissionBroker {
reason: permission_broker.clone(),
});
}
}

Ok(Some(ChildExecutionMetadataView {
enforced: enforced_execution_guarantees(&requested),
requested,
}))
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

find . -type f -name "coordinator.rs" | grep -E "agent-runtime"

Repository: dallay/corvus

Length of output: 105


🏁 Script executed:

rg "fn normalize_execution_metadata" --type rs -A 70

Repository: dallay/corvus

Length of output: 83


🏁 Script executed:

rg "struct ChildExecutionSpec" --type rs -B 2 -A 15

Repository: dallay/corvus

Length of output: 83


🏁 Script executed:

rg "fn build_effective_config" --type rs -A 20

Repository: dallay/corvus

Length of output: 83


🏁 Script executed:

rg "delegate_launch" --type rs -B 3 -A 15 | head -100

Repository: dallay/corvus

Length of output: 83


🏁 Script executed:

cat -n clients/agent-runtime/src/agent/coordinator.rs | sed -n '225,285p'

Repository: dallay/corvus

Length of output: 2524


🏁 Script executed:

cat -n clients/agent-runtime/src/agent/coordinator.rs | sed -n '550,580p'

Repository: dallay/corvus

Length of output: 1537


🏁 Script executed:

rg "struct ChildExecutionSpec" --lang rust -B 2 -A 20

Repository: dallay/corvus

Length of output: 465


🏁 Script executed:

rg "fn build_effective_config" --lang rust -A 25

Repository: dallay/corvus

Length of output: 465


🏁 Script executed:

rg "delegate_launch" --lang rust -B 3 -A 20

Repository: dallay/corvus

Length of output: 465


🏁 Script executed:

rg "struct ChildExecutionSpec" -B 2 -A 20 clients/agent-runtime/src/

Repository: dallay/corvus

Length of output: 1864


🏁 Script executed:

rg "delegate_launch" -B 5 -A 25 clients/agent-runtime/src/

Repository: dallay/corvus

Length of output: 29824


🏁 Script executed:

rg "working_directory" clients/agent-runtime/src/ | head -30

Repository: dallay/corvus

Length of output: 1074


🏁 Script executed:

cat -n clients/agent-runtime/src/tools/delegate_launch.rs | head -150

Repository: dallay/corvus

Length of output: 7295


🏁 Script executed:

rg "ChildExecutionSpec" clients/agent-runtime/src/tools/delegate_launch.rs -B 3 -A 10

Repository: dallay/corvus

Length of output: 650


🏁 Script executed:

rg "working_directory" clients/agent-runtime/src/tools/delegate_launch.rs -B 3 -A 3

Repository: dallay/corvus

Length of output: 907


🏁 Script executed:

rg "workspace_dir" clients/agent-runtime/src/ -B 2 -A 2 | head -80

Repository: dallay/corvus

Length of output: 5609


🏁 Script executed:

cat -n clients/agent-runtime/src/agent/coordinator.rs | sed -n '170,220p'

Repository: dallay/corvus

Length of output: 2429


🏁 Script executed:

rg "workspace_dir" clients/agent-runtime/src/agent/coordinator.rs -B 3 -A 3

Repository: dallay/corvus

Length of output: 324


🏁 Script executed:

rg "NormalizedExecutionRequest" clients/agent-runtime/src/agent/coordinator.rs -B 5 -A 20 | head -100

Repository: dallay/corvus

Length of output: 3718


🏁 Script executed:

rg "canonicalize|absolute|normalize_path" clients/agent-runtime/src/agent/coordinator.rs -B 2 -A 2

Repository: dallay/corvus

Length of output: 39


🏁 Script executed:

rg "workspace_dir.*from|PathBuf::from" clients/agent-runtime/src/ -B 2 -A 2 | head -50

Repository: dallay/corvus

Length of output: 3929


Missing validation on working_directory allows arbitrary filesystem scope bypass.

normalize_execution_metadata rejects repository_id, worktree_id, and clone-ish sandbox_mode values, but allows any working_directory through without normalization or validation. The field is deserialized directly from untrusted delegate_launch input (src/tools/, a high-risk surface) and written straight into config.workspace_dir at line 565 via std::path::PathBuf::from() with no canonicalization or bounds checking. A child request carrying "working_directory": "/etc" or "../.." will silently reparent the delegated session's filesystem scope.

Either add canonicalization + allow-list validation in normalize_execution_metadata (consistent with how you handle other isolation fields), or reject working_directory entirely if it is intended as parent-orchestration-only and should never flow from LLM input.

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

In `@clients/agent-runtime/src/agent/coordinator.rs` around lines 225 - 280,
normalize_execution_metadata currently accepts an unvalidated working_directory
from ChildExecutionSpec which later becomes config.workspace_dir; either
canonicalize and validate it here or reject it outright: update
normalize_execution_metadata (working with ChildExecutionSpec,
ChildExecutionMetadataView, and enforced_execution_guarantees) to (a) if you
intend to allow a working_directory, canonicalize the path (resolve .. and
symlinks), enforce it is within an allow-list or sandbox root (reject absolute
paths like "/etc" and paths that escape the allowed workspace), and return an
UnsupportedIsolation/validation rejection on failure, or (b) simpler: refuse any
incoming working_directory by returning
LaunchContractRejection::UnsupportedIsolation for the "working_directory" field
so no untrusted path flows into config.workspace_dir. Ensure checks run before
building ChildExecutionMetadataView and reference the working_directory field on
the NormalizedExecutionRequest/ChildExecutionSpec.

Comment on lines +1876 to 1891
let events = coordinator
.event_log()
.map_err(OrchestrationServiceError::CoordinatorError)?
.iter()
.map(LifecycleEventView::from)
.collect();

Ok(OrchestrationSnapshot {
handle: handle.clone(),
parent_session_id: request.parent_session_id.clone(),
state,
children,
events,
outcome,
})
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

event_log() clones the full Vec<CoordinatorEvent> on every inspect.

For runs with many lifecycle transitions (or frequent polling of inspect), this is O(events) clone per snapshot plus an internal allocation for LifecycleEventView. Fine at current scale; worth a since_sequence filter or bounded ring buffer before this becomes a hot path on the dashboard.

As per coding guidelines: "Avoid unnecessary allocations, clones, and blocking operations to maintain performance and efficiency".

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

In `@clients/agent-runtime/src/agent/coordinator.rs` around lines 1876 - 1891, The
current code clones the entire Vec<CoordinatorEvent> via coordinator.event_log()
on every inspect; change the handling to avoid cloning and to filter events by
sequence before building views: call coordinator.event_log().map_err(...)? to
get a reference to the events, then use .iter().filter(|e| e.sequence >
request.since_sequence.unwrap_or(0)) (or an equivalent since_sequence field) and
map LifecycleEventView::from over the filtered iterator, collecting only the
needed subset (optionally cap the number returned). Update the mapping code
around LifecycleEventView::from and the events binding so it operates on
&CoordinatorEvent (no full Vec clone) and respects a since_sequence/bounded
limit to prevent O(n) cloning on every inspect.

Comment on lines +41 to +47
pub fn to_sse_frame(&self) -> anyhow::Result<String> {
Ok(format!(
"event: {}\nid: {}\ndata: {}\n\n",
self.kind,
self.sequence,
serde_json::to_string(self)?
))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Validate kind before writing it into the SSE frame.

self.kind is inserted into the event: header verbatim. A value containing \n/\r can inject additional SSE fields or split frames. Reject control characters or restrict event names to a safe allowlist before formatting.

🛡️ Proposed fix
 impl BridgeEnvelope {
+    fn validate_sse_event_name(name: &str) -> anyhow::Result<()> {
+        let valid = !name.is_empty()
+            && name
+                .bytes()
+                .all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b'_' | b'-' | b'.'));
+        anyhow::ensure!(valid, "invalid SSE event name");
+        Ok(())
+    }
+
     pub fn to_sse_frame(&self) -> anyhow::Result<String> {
+        Self::validate_sse_event_name(&self.kind)?;
+        let data = serde_json::to_string(self)?;
         Ok(format!(
             "event: {}\nid: {}\ndata: {}\n\n",
             self.kind,
             self.sequence,
-            serde_json::to_string(self)?
+            data
         ))
     }
 }

As per coding guidelines, **/*: Security first, performance second.

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

In `@clients/agent-runtime/src/bridge/mod.rs` around lines 41 - 47, The
to_sse_frame method currently interpolates self.kind directly into the "event:"
header allowing newline/control injection; update to_sse_frame to validate
self.kind before formatting by rejecting any characters like '\n' or '\r' or
other control chars (or enforce a safe allowlist such as /^[A-Za-z0-9_-]+$/) and
return an Err (anyhow::Error) when validation fails so only safe event names are
written into the SSE frame.

Comment on lines +1685 to +1710
async fn finalize_generated_session_if_needed(
state: &AppState,
session_id: &str,
session_source: webhook_dispatch::WebhookSessionSource,
) {
if !matches!(
session_source,
webhook_dispatch::WebhookSessionSource::Generated
) {
return;
}

if let Err(error) = state.mem.end_session(session_id).await {
tracing::debug!("generated session end best-effort failed: {error}");
return;
}

let workspace_dir = state.config.lock().workspace_dir.clone();
if let Err(error) = crate::memory::record_session_completion(&workspace_dir) {
tracing::debug!("dream session counter update failed: {error}");
return;
}
if let Err(error) = crate::memory::run_dream_if_triggered(&workspace_dir) {
tracing::debug!("dream consolidation after generated session skipped: {error}");
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Call sites for finalize_generated_session_if_needed:"
rg -n -C3 '\bfinalize_generated_session_if_needed\s*\('

echo
echo "Gateway session lifecycle touchpoints:"
rg -n -C5 '\b(end_session|record_session_completion|run_dream_if_triggered|update_session_activity_if_persisted)\b' clients/agent-runtime/src/gateway/mod.rs

Repository: dallay/corvus

Length of output: 4037


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Full-repo search for finalize_generated_session_if_needed ==="
rg 'finalize_generated_session_if_needed' --type rust

echo
echo "=== Check function visibility ==="
head -n 1690 clients/agent-runtime/src/gateway/mod.rs | tail -n 10

echo
echo "=== Verify if function would be flagged as dead code ==="
echo "Checking for 'async fn finalize_generated_session_if_needed' with no callers..."
rg -A 25 'async fn finalize_generated_session_if_needed' clients/agent-runtime/src/gateway/mod.rs | head -n 30

Repository: dallay/corvus

Length of output: 1516


Wire this cleanup helper into the webhook completion path or remove it.

finalize_generated_session_if_needed is completely unused—the entire repository contains zero call sites. None of the /webhook completion paths invoke it, so generated sessions never finalize and the completion/dream hooks never execute. This function also fails cargo clippy --all-targets -- -D warnings as dead code.

Either integrate this into the webhook lifecycle (likely before the response in the completion handlers at lines ~2120–2210) or remove the function entirely. If removed, ensure the session cleanup logic belongs elsewhere or confirm generated sessions can safely remain open.

🤖 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 1685 - 1710,
finalize_generated_session_if_needed is dead and never called; either invoke it
from the webhook completion flow or delete it. To wire it in: call
finalize_generated_session_if_needed(&state, &session_id, session_source).await
in each webhook completion handler (the handlers that finalize
responses/completions) before sending the HTTP response, ensuring you pass the
same session_id and webhook_dispatch::WebhookSessionSource used for that request
and await the future; handle errors only via internal logging (no panic). To
remove it: delete the finalize_generated_session_if_needed function and ensure
the session cleanup logic (end_session, record_session_completion,
run_dream_if_triggered) is moved into an existing completion path so generated
sessions are finalized and the clippy dead-code warning is resolved.

Comment on lines +142 to +143
for file in &recent_signal_files {
let content = fs::read_to_string(file)?;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's locate and examine the dream.rs file
find . -name "dream.rs" -type f

Repository: dallay/corvus

Length of output: 100


🏁 Script executed:

# Get the file size and line count
wc -l clients/agent-runtime/src/memory/dream.rs

Repository: dallay/corvus

Length of output: 102


🏁 Script executed:

# Examine the recent_memory_files function around lines 142-143 and 297-304
sed -n '130,160p' clients/agent-runtime/src/memory/dream.rs

Repository: dallay/corvus

Length of output: 1122


🏁 Script executed:

# Also check the 297-304 range
sed -n '290,315p' clients/agent-runtime/src/memory/dream.rs

Repository: dallay/corvus

Length of output: 801


🏁 Script executed:

# Search for all fs::read functions in the file to understand the full context
rg 'fs::read' clients/agent-runtime/src/memory/dream.rs -n -A 2 -B 2

Repository: dallay/corvus

Length of output: 1166


🏁 Script executed:

# Check if there are any symlink-related tests
rg 'symlink|hardlink' clients/agent-runtime/src/memory/dream.rs -n

Repository: dallay/corvus

Length of output: 39


🏁 Script executed:

# Examine the full recent_memory_files function and context
sed -n '296,315p' clients/agent-runtime/src/memory/dream.rs

Repository: dallay/corvus

Length of output: 704


🏁 Script executed:

# Check what get passed to fs::read_to_string - trace recent_signal_files origin
rg 'recent_signal_files' clients/agent-runtime/src/memory/dream.rs -n -B 3 -A 3

Repository: dallay/corvus

Length of output: 933


🏁 Script executed:

# Look for any platform-specific or symlink handling code
rg 'symlink|canonical|realpath' clients/agent-runtime/src/memory/ -n

Repository: dallay/corvus

Length of output: 279


🏁 Script executed:

# Check the entire test module to see if symlink handling is tested
sed -n '380,435p' clients/agent-runtime/src/memory/dream.rs

Repository: dallay/corvus

Length of output: 1948


🏁 Script executed:

# Let's verify fs::read_to_string actually follows symlinks in Rust
# by checking the Rust standard library behavior through web search is more reliable
echo "Checking Rust std fs behavior - fs::read_to_string follows symlinks per Rust docs"

Repository: dallay/corvus

Length of output: 138


Reject symlinked memory files before reading them.

recent_memory_files() enumerates .md files without filtering for regular files. Since fs::read_to_string() follows symlinks, a crafted memory/*.md symlink can read files outside memory/, which then get merged into MEMORY.md. This violates input boundary validation.

🛡️ Proposed hardening
fn recent_memory_files(memory_dir: &Path) -> Result<Vec<PathBuf>> {
    if !memory_dir.is_dir() {
        return Ok(Vec::new());
    }
-    let mut files: Vec<PathBuf> = fs::read_dir(memory_dir)?
-        .filter_map(|entry| entry.ok().map(|value| value.path()))
-        .filter(|path| path.extension().and_then(|value| value.to_str()) == Some("md"))
-        .collect();
+    let mut files = Vec::new();
+    for entry in fs::read_dir(memory_dir)? {
+        let entry = entry?;
+        if !entry.file_type()?.is_file() {
+            continue;
+        }
+        let path = entry.path();
+        if path.extension().and_then(|value| value.to_str()) == Some("md") {
+            files.push(path);
+        }
+    }
    files.sort();

Add a regression test creating a symlinked memory/*.md entry and verify it is skipped during consolidation.

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

In `@clients/agent-runtime/src/memory/dream.rs` around lines 142 - 143, The loop
that reads recent memory files (iterating recent_signal_files in
clients/agent-runtime/src/memory/dream.rs) currently calls
fs::read_to_string(file) without rejecting symlinks; fix by checking file
metadata before reading: use std::fs::symlink_metadata(file) and skip the entry
if metadata.file_type().is_symlink() (or otherwise ensure canonicalized path
stays inside the memory directory), then only call fs::read_to_string for
regular files (metadata.is_file()). Also add a regression test that creates a
symlinked memory/*.md and asserts that the symlink is skipped during
consolidation.

Comment on lines +138 to +170
### Requirement: Account responses MUST redact credentials

The system MUST accept `api_key` in create and update requests as a write-only field.

The system MUST NOT return raw `api_key` values in any admin response body.

Every account response MUST expose `has_api_key: boolean` instead of `api_key`.

This redaction rule MUST apply to list responses, get responses, create responses, update
responses, nested pool member views if any are ever returned, and any error payload metadata.

#### Scenario: account create response redacts api_key

- GIVEN a `CreateAccountRequest` with `api_key = "sk-secret"`
- WHEN the request succeeds
- THEN the response body MUST include `has_api_key: true`
- AND the response body MUST NOT include an `api_key` field
- AND the raw submitted credential MUST NOT be echoed back

#### Scenario: account update response redacts api_key

- GIVEN an existing account without a key
- WHEN a client submits `PUT /api/accounts/{account_id}` with a new `api_key`
- THEN the response body MUST include `has_api_key: true`
- AND the response body MUST NOT include an `api_key` field

#### Scenario: account list response remains redacted

- GIVEN one or more stored accounts with API keys
- WHEN a client requests `GET /api/accounts`
- THEN every item in the response MUST include `has_api_key`
- AND no item in the response MUST expose raw credential material

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Spec is silent on logging/telemetry redaction.

The redaction rule covers response bodies and error payload metadata, but not logs, traces, metrics labels, or request echo in validation errors. Recommend adding: api_key MUST NOT appear in server logs, tracing spans, metrics labels, or error details derived from the raw request body.

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

In `@openspec/changes/archive/2026-04-21-rook-590-admin-api/spec.md` around lines
138 - 170, Add a clear logging/telemetry redaction rule to the "Requirement:
Account responses MUST redact credentials" section: state that the `api_key`
field (and any raw credential material) MUST NOT be written to server logs,
tracing spans, metrics labels, or included in error `details` or any
request-echo in validation errors; ensure this requirement is explicitly applied
alongside the existing requirements for `CreateAccountRequest`, `PUT
/api/accounts/{account_id}`, `GET /api/accounts` and list/get/create/update
responses so implementers know to strip or redact `api_key` from logs, traces,
metrics, and error metadata as well as response bodies.

Comment on lines +537 to +554
### Requirement: Loopback-first and no-auth M1 safety posture

This change MUST preserve the current M1 safety posture.

The admin API defined here MUST NOT expand exposure beyond the existing loopback/local-admin
assumption.

Authentication and authorization are explicitly out of scope for this spec and belong to #591.

The admin API contract MUST therefore be specified without bearer-token, pairing, or role-based
authorization requirements.

#### Scenario: admin API remains unauthenticated in M1 contract

- GIVEN the M1 admin API defined by this spec
- WHEN a client interacts with `/api/*`
- THEN the contract MUST NOT require auth features from #591
- AND the spec MUST continue to describe this surface as local-admin only
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Make the loopback-only posture an enforced contract, not an assumption.

This section states the admin API "MUST NOT expand exposure beyond the existing loopback/local-admin assumption" and defers auth to #591, but nothing here requires the server to actually bind to loopback. An unauthenticated CRUD surface that can write api_key and delete accounts/pools/routes is dangerous if a misconfiguration (e.g. 0.0.0.0 bind, reverse proxy, container port publish) exposes it on a routable interface.

Consider adding a requirement such as:

  • Admin routes MUST only be served on a loopback listener in M1, OR
  • Binding to a non-loopback address MUST refuse to mount /api/* admin routes (or MUST log a prominent warning and require an explicit opt-in flag).

Otherwise the "local-admin only" guarantee is documentation, not behavior.

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

In `@openspec/changes/archive/2026-04-21-rook-590-admin-api/spec.md` around lines
537 - 554, Make the loopback-only posture an enforced contract: update the spec
text around the "Loopback-first and no-auth M1 safety posture" and the
"Scenario: admin API remains unauthenticated in M1 contract" to require that
admin routes under "/api/*" are only served on a loopback listener in M1, and
specify behavior if the server binds to a non-loopback address (e.g., the server
MUST refuse to mount "/api/*" admin routes or MUST require an explicit
documented opt-in flag such as an "--admin-bind" override and log a prominent
warning). Reference the M1 admin API and "/api/*" admin routes when adding this
requirement and describe the required runtime checks (bind address validation or
opt-in gating) and the expected failure/warning behavior.

Comment on lines +3 to +26
## Phase 1: Contract and Validation Foundation

- [x] 1.1 RED: Add coordinator/service tests in `clients/agent-runtime/src/agent/coordinator.rs` for normalized execution metadata, `remote_bridge` rejection, unsupported isolation rejection, and unsupported permission-broker rejection.
- [x] 1.2 GREEN: In `clients/agent-runtime/src/agent/coordinator.rs`, add normalized request/enforced-guarantee types, launch rejection types, and centralized fail-closed admission validation used by supervised orchestration.
- [x] 1.3 REFACTOR: Tighten `clients/agent-runtime/src/bridge/mod.rs` to metadata-only seam types consumed by the orchestration contract, without active runner wiring.

## Phase 2: Lifecycle Read Model and Mailbox Semantics

- [x] 2.1 RED: Extend coordinator/mailbox tests in `clients/agent-runtime/src/agent/coordinator.rs` and `clients/agent-runtime/src/agent/mailbox.rs` for `cancelling` state, immutable terminal states, deterministic event ordering, and redelivery dedupe.
- [x] 2.2 GREEN: Update `clients/agent-runtime/src/agent/coordinator.rs` to expose child execution metadata views, bounded lifecycle events, explicit `Cancelling` state, and terminal snapshot handling from coordinator-owned authority.
- [x] 2.3 GREEN: Update `clients/agent-runtime/src/agent/mailbox.rs` so mailbox-backed delivery remains internal lifecycle/control transport aligned with coordinator sequencing, dedupe, and no cross-run visibility.

## Phase 3: Tool Surface Parity Wiring

- [x] 3.1 RED: Add tool/service tests in `clients/agent-runtime/src/tools/delegate_launch.rs`, `delegate_inspect.rs`, and `delegate_cancel.rs` covering shared handle usage, requested vs enforced metadata visibility, idempotent cancel, and stale-handle fail-closed behavior.
- [x] 3.2 GREEN: Update `clients/agent-runtime/src/tools/delegate_launch.rs` to normalize launch metadata, reject unsupported transport/isolation/approval requests before admission, and return the initial orchestration snapshot.
- [x] 3.3 GREEN: Update `clients/agent-runtime/src/tools/delegate_inspect.rs` and `clients/agent-runtime/src/tools/delegate_cancel.rs` to read only supervised orchestration authority, expose lifecycle/event views, and preserve parent-owned cancel semantics.
- [x] 3.4 GREEN: Update `clients/agent-runtime/src/tools/delegate.rs` and `clients/agent-runtime/src/tools/mod.rs` to keep single-child compatibility while routing through the same supervised orchestration contract.

## Phase 4: Focused Compatibility and Boundary Coverage

- [x] 4.1 RED: Add integration tests around shared `SupervisedOrchestrationService` in `clients/agent-runtime/src/tools/` for mailbox-backed launch→inspect→cancel flow and single-child `delegate` compatibility.
- [x] 4.2 GREEN: Adjust `clients/agent-runtime/src/lib.rs` exports only as needed so the finalized orchestration and bridge seam types are consistently available to the runtime crate surface.
- [x] 4.3 VERIFY: Update/mark `openspec/changes/2026-04-22-track-4-orchestration-parity-seam/tasks.md` during apply as tasks land, keeping Track 6 transport, reconnect/resume, JWT auth, and full remote sessions explicitly out of scope.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add explicit risk/threat and rollback tasks before archiving as fully complete.

The checklist tracks RED/GREEN/VERIFY well, but it omits an explicit threat/risk note and rollback strategy task for these runtime/gateway changes. Please add a final checklist item capturing security/runtime failure modes and rollback steps.

Proposed doc patch
 ## Phase 4: Focused Compatibility and Boundary Coverage
@@
 - [x] 4.3 VERIFY: Update/mark `openspec/changes/2026-04-22-track-4-orchestration-parity-seam/tasks.md` during apply as tasks land, keeping Track 6 transport, reconnect/resume, JWT auth, and full remote sessions explicitly out of scope.
+
+## Phase 5: Risk and Rollback Readiness
+
+- [ ] 5.1 VERIFY: Document threat/risk notes for fail-closed admission, mailbox ordering/dedupe, and cancellation semantics regressions.
+- [ ] 5.2 VERIFY: Document rollback strategy (feature flags/revert points/data-contract safety) for coordinator, mailbox, and delegate tool surfaces.

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".

📝 Committable suggestion

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

Suggested change
## Phase 1: Contract and Validation Foundation
- [x] 1.1 RED: Add coordinator/service tests in `clients/agent-runtime/src/agent/coordinator.rs` for normalized execution metadata, `remote_bridge` rejection, unsupported isolation rejection, and unsupported permission-broker rejection.
- [x] 1.2 GREEN: In `clients/agent-runtime/src/agent/coordinator.rs`, add normalized request/enforced-guarantee types, launch rejection types, and centralized fail-closed admission validation used by supervised orchestration.
- [x] 1.3 REFACTOR: Tighten `clients/agent-runtime/src/bridge/mod.rs` to metadata-only seam types consumed by the orchestration contract, without active runner wiring.
## Phase 2: Lifecycle Read Model and Mailbox Semantics
- [x] 2.1 RED: Extend coordinator/mailbox tests in `clients/agent-runtime/src/agent/coordinator.rs` and `clients/agent-runtime/src/agent/mailbox.rs` for `cancelling` state, immutable terminal states, deterministic event ordering, and redelivery dedupe.
- [x] 2.2 GREEN: Update `clients/agent-runtime/src/agent/coordinator.rs` to expose child execution metadata views, bounded lifecycle events, explicit `Cancelling` state, and terminal snapshot handling from coordinator-owned authority.
- [x] 2.3 GREEN: Update `clients/agent-runtime/src/agent/mailbox.rs` so mailbox-backed delivery remains internal lifecycle/control transport aligned with coordinator sequencing, dedupe, and no cross-run visibility.
## Phase 3: Tool Surface Parity Wiring
- [x] 3.1 RED: Add tool/service tests in `clients/agent-runtime/src/tools/delegate_launch.rs`, `delegate_inspect.rs`, and `delegate_cancel.rs` covering shared handle usage, requested vs enforced metadata visibility, idempotent cancel, and stale-handle fail-closed behavior.
- [x] 3.2 GREEN: Update `clients/agent-runtime/src/tools/delegate_launch.rs` to normalize launch metadata, reject unsupported transport/isolation/approval requests before admission, and return the initial orchestration snapshot.
- [x] 3.3 GREEN: Update `clients/agent-runtime/src/tools/delegate_inspect.rs` and `clients/agent-runtime/src/tools/delegate_cancel.rs` to read only supervised orchestration authority, expose lifecycle/event views, and preserve parent-owned cancel semantics.
- [x] 3.4 GREEN: Update `clients/agent-runtime/src/tools/delegate.rs` and `clients/agent-runtime/src/tools/mod.rs` to keep single-child compatibility while routing through the same supervised orchestration contract.
## Phase 4: Focused Compatibility and Boundary Coverage
- [x] 4.1 RED: Add integration tests around shared `SupervisedOrchestrationService` in `clients/agent-runtime/src/tools/` for mailbox-backed launch→inspect→cancel flow and single-child `delegate` compatibility.
- [x] 4.2 GREEN: Adjust `clients/agent-runtime/src/lib.rs` exports only as needed so the finalized orchestration and bridge seam types are consistently available to the runtime crate surface.
- [x] 4.3 VERIFY: Update/mark `openspec/changes/2026-04-22-track-4-orchestration-parity-seam/tasks.md` during apply as tasks land, keeping Track 6 transport, reconnect/resume, JWT auth, and full remote sessions explicitly out of scope.
## Phase 1: Contract and Validation Foundation
- [x] 1.1 RED: Add coordinator/service tests in `clients/agent-runtime/src/agent/coordinator.rs` for normalized execution metadata, `remote_bridge` rejection, unsupported isolation rejection, and unsupported permission-broker rejection.
- [x] 1.2 GREEN: In `clients/agent-runtime/src/agent/coordinator.rs`, add normalized request/enforced-guarantee types, launch rejection types, and centralized fail-closed admission validation used by supervised orchestration.
- [x] 1.3 REFACTOR: Tighten `clients/agent-runtime/src/bridge/mod.rs` to metadata-only seam types consumed by the orchestration contract, without active runner wiring.
## Phase 2: Lifecycle Read Model and Mailbox Semantics
- [x] 2.1 RED: Extend coordinator/mailbox tests in `clients/agent-runtime/src/agent/coordinator.rs` and `clients/agent-runtime/src/agent/mailbox.rs` for `cancelling` state, immutable terminal states, deterministic event ordering, and redelivery dedupe.
- [x] 2.2 GREEN: Update `clients/agent-runtime/src/agent/coordinator.rs` to expose child execution metadata views, bounded lifecycle events, explicit `Cancelling` state, and terminal snapshot handling from coordinator-owned authority.
- [x] 2.3 GREEN: Update `clients/agent-runtime/src/agent/mailbox.rs` so mailbox-backed delivery remains internal lifecycle/control transport aligned with coordinator sequencing, dedupe, and no cross-run visibility.
## Phase 3: Tool Surface Parity Wiring
- [x] 3.1 RED: Add tool/service tests in `clients/agent-runtime/src/tools/delegate_launch.rs`, `delegate_inspect.rs`, and `delegate_cancel.rs` covering shared handle usage, requested vs enforced metadata visibility, idempotent cancel, and stale-handle fail-closed behavior.
- [x] 3.2 GREEN: Update `clients/agent-runtime/src/tools/delegate_launch.rs` to normalize launch metadata, reject unsupported transport/isolation/approval requests before admission, and return the initial orchestration snapshot.
- [x] 3.3 GREEN: Update `clients/agent-runtime/src/tools/delegate_inspect.rs` and `clients/agent-runtime/src/tools/delegate_cancel.rs` to read only supervised orchestration authority, expose lifecycle/event views, and preserve parent-owned cancel semantics.
- [x] 3.4 GREEN: Update `clients/agent-runtime/src/tools/delegate.rs` and `clients/agent-runtime/src/tools/mod.rs` to keep single-child compatibility while routing through the same supervised orchestration contract.
## Phase 4: Focused Compatibility and Boundary Coverage
- [x] 4.1 RED: Add integration tests around shared `SupervisedOrchestrationService` in `clients/agent-runtime/src/tools/` for mailbox-backed launch→inspect→cancel flow and single-child `delegate` compatibility.
- [x] 4.2 GREEN: Adjust `clients/agent-runtime/src/lib.rs` exports only as needed so the finalized orchestration and bridge seam types are consistently available to the runtime crate surface.
- [x] 4.3 VERIFY: Update/mark `openspec/changes/2026-04-22-track-4-orchestration-parity-seam/tasks.md` during apply as tasks land, keeping Track 6 transport, reconnect/resume, JWT auth, and full remote sessions explicitly out of scope.
## Phase 5: Risk and Rollback Readiness
- [ ] 5.1 VERIFY: Document threat/risk notes for fail-closed admission, mailbox ordering/dedupe, and cancellation semantics regressions.
- [ ] 5.2 VERIFY: Document rollback strategy (feature flags/revert points/data-contract safety) for coordinator, mailbox, and delegate tool surfaces.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@openspec/changes/archive/2026-04-22-2026-04-22-track-4-orchestration-parity-seam/tasks.md`
around lines 3 - 26, Add a final checklist item to the tasks doc
(openspec/changes/.../tasks.md) that explicitly captures threat/risk notes and
rollback strategy: insert under Phase 4 (after 4.3 VERIFY) a bullet describing
security/runtime/gateway failure modes to monitor (e.g., auth/token, transport
resume, unauthorized isolation/permission denial, mailbox redelivery), automated
and manual rollback steps (feature flags, config toggles, service-side rejects,
DB/schema rollback, and test harness replay), and a requirement to add
boundary/failure-mode tests; reference the doc's Track and supervised
orchestration artifacts (SupervisedOrchestrationService, coordinator/mailbox,
delegate_* tools) so reviewers know which components the risk/rollback item
covers.

Comment on lines +5 to +26
- [x] 1.1 RED: Add coordinator/service tests in `clients/agent-runtime/src/agent/coordinator.rs` for normalized execution metadata, `remote_bridge` rejection, unsupported isolation rejection, and unsupported permission-broker rejection.
- [x] 1.2 GREEN: In `clients/agent-runtime/src/agent/coordinator.rs`, add normalized request/enforced-guarantee types, launch rejection types, and centralized fail-closed admission validation used by supervised orchestration.
- [x] 1.3 REFACTOR: Tighten `clients/agent-runtime/src/bridge/mod.rs` to metadata-only seam types consumed by the orchestration contract, without active runner wiring.

## Phase 2: Lifecycle Read Model and Mailbox Semantics

- [x] 2.1 RED: Extend coordinator/mailbox tests in `clients/agent-runtime/src/agent/coordinator.rs` and `clients/agent-runtime/src/agent/mailbox.rs` for `cancelling` state, immutable terminal states, deterministic event ordering, and redelivery dedupe.
- [x] 2.2 GREEN: Update `clients/agent-runtime/src/agent/coordinator.rs` to expose child execution metadata views, bounded lifecycle events, explicit `Cancelling` state, and terminal snapshot handling from coordinator-owned authority.
- [x] 2.3 GREEN: Update `clients/agent-runtime/src/agent/mailbox.rs` so mailbox-backed delivery remains internal lifecycle/control transport aligned with coordinator sequencing, dedupe, and no cross-run visibility.

## Phase 3: Tool Surface Parity Wiring

- [x] 3.1 RED: Add tool/service tests in `clients/agent-runtime/src/tools/delegate_launch.rs`, `delegate_inspect.rs`, and `delegate_cancel.rs` covering shared handle usage, requested vs enforced metadata visibility, idempotent cancel, and stale-handle fail-closed behavior.
- [x] 3.2 GREEN: Update `clients/agent-runtime/src/tools/delegate_launch.rs` to normalize launch metadata, reject unsupported transport/isolation/approval requests before admission, and return the initial orchestration snapshot.
- [x] 3.3 GREEN: Update `clients/agent-runtime/src/tools/delegate_inspect.rs` and `clients/agent-runtime/src/tools/delegate_cancel.rs` to read only supervised orchestration authority, expose lifecycle/event views, and preserve parent-owned cancel semantics.
- [x] 3.4 GREEN: Update `clients/agent-runtime/src/tools/delegate.rs` and `clients/agent-runtime/src/tools/mod.rs` to keep single-child compatibility while routing through the same supervised orchestration contract.

## Phase 4: Focused Compatibility and Boundary Coverage

- [x] 4.1 RED: Add integration tests around shared `SupervisedOrchestrationService` in `clients/agent-runtime/src/tools/` for mailbox-backed launch→inspect→cancel flow and single-child `delegate` compatibility.
- [x] 4.2 GREEN: Adjust `clients/agent-runtime/src/lib.rs` exports only as needed so the finalized orchestration and bridge seam types are consistently available to the runtime crate surface.
- [x] 4.3 VERIFY: Update/mark `openspec/changes/2026-04-22-track-4-orchestration-parity-seam/tasks.md` during apply as tasks land, keeping Track 6 transport, reconnect/resume, JWT auth, and full remote sessions explicitly out of scope.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "1) Confirm referenced runtime files exist:"
fd -a 'coordinator.rs|mailbox.rs|delegate_launch.rs|delegate_inspect.rs|delegate_cancel.rs|delegate.rs|mod.rs|lib.rs'

echo
echo "2) Spot-check key behaviors claimed as complete:"
rg -n -C2 'remote_bridge|unsupported isolation|permission-broker|Cancelling|dedupe|idempotent cancel|stale-handle|SupervisedOrchestrationService' --type rust

echo
echo "3) Confirm integration tests under tools mention launch->inspect->cancel flow:"
rg -n -C2 'launch.*inspect.*cancel|inspect.*cancel|SupervisedOrchestrationService' --type rust clients/agent-runtime/src/tools

echo
echo "4) Validate task-file path references (archived vs non-archived):"
rg -n 'openspec/changes/.*/tasks.md' openspec/changes/archive/2026-04-22-2026-04-22-track-4-orchestration-parity-seam/tasks.md

Repository: dallay/corvus

Length of output: 50369


🏁 Script executed:

#!/bin/bash
# Check if the archived tasks.md explicitly documents Track 6 out-of-scope constraints
head -50 openspec/changes/archive/2026-04-22-2026-04-22-track-4-orchestration-parity-seam/tasks.md

Repository: dallay/corvus

Length of output: 3265


Task 4.3 references an outdated non-archived path; update the documented path reference or clarify intent.

All claimed implementations, tests, and integration flows verified as complete. However, task 4.3 is marked [x] VERIFY but it references openspec/changes/2026-04-22-track-4-orchestration-parity-seam/tasks.md, which doesn't match the actual archived file location at openspec/changes/archive/2026-04-22-2026-04-22-track-4-orchestration-parity-seam/tasks.md.

Track 6 scope exclusion (transport, reconnect/resume, JWT auth, full remote sessions) is explicitly documented. Update 4.3 to reference the correct archived path, or document why the reference should remain non-archived.

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

In
`@openspec/changes/archive/2026-04-22-2026-04-22-track-4-orchestration-parity-seam/tasks.md`
around lines 5 - 26, Task 4.3's documentation references an
incorrect/non-archived path; update the line for "4.3 VERIFY" in tasks.md so it
either points to the actual archived location or explicitly states why the
non-archived path is intentional (e.g., keep as a top-level spec pointer vs
archived copy). Locate the "4.3 VERIFY" entry under "Phase 4: Focused
Compatibility and Boundary Coverage" and replace the outdated path string with
the correct archived reference or add a short clarifying note indicating
retention of the non-archived reference and reasoning (mention Track 6
exclusions remain out of scope).

Comment on lines +191 to +192
| `openspec/changes/rook-591-chat-completions-streaming-transport/design.md` | Create | This technical design artifact. |
| `openspec/changes/rook-591-chat-completions-streaming-transport/state.yaml` | Modify | Mark design phase complete and advance to tasks. |
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Stale self-reference to the non-archived change directory.

The File Changes table still lists openspec/changes/rook-591-chat-completions-streaming-transport/design.md and .../state.yaml even though this file itself is now under openspec/changes/archive/2026-04-22-.... Either refresh the paths to the archived location or remove the rows — otherwise the "Create/Modify" entries are pointing at ghosts.

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

In
`@openspec/changes/archive/2026-04-22-rook-591-chat-completions-streaming-transport/design.md`
around lines 191 - 192, The File Changes table contains stale paths pointing to
openspec/changes/rook-591-chat-completions-streaming-transport/design.md and
openspec/changes/rook-591-chat-completions-streaming-transport/state.yaml while
the current document lives under
openspec/changes/archive/2026-04-22-rook-591-chat-completions-streaming-transport;
update the table rows to reference the archived paths
(openspec/changes/archive/2026-04-22-rook-591-chat-completions-streaming-transport/design.md
and .../state.yaml) or remove those rows entirely so the "Create/Modify" entries
no longer point to nonexistent locations.

Expose stable /api endpoints for accounts, pools, routes, health, settings, and usage status so the dashboard and automation can manage Rook through supported contracts instead of internal runtime state.
Wrap admin extractor failures in the documented error envelope, avoid leaking internal error details, make account and route deletes safer under references, validate pool fallbacks transactionally, and align Rook admin docs with the verified contract.
Sync the admin API delta spec into the gateway source of truth and archive the completed rook-590-admin-api change after PASS verification.
Add inbound auth, transport middleware, global surface rate limits, chat idempotency, and streaming support so Rook can protect and serve OpenAI-compatible chat traffic more reliably.
Finalize durable local orchestration, parent-owned lifecycle controls, and a fail-closed remote bridge seam so multi-agent delegation can be inspected and cancelled through a stable runtime contract.
Implements the dedicated Rook dashboard surface for overview and provider account administration.

- add embedded rook-dashboard Vue app and tests
- preserve stored api keys on metadata-only account edits
- wire built assets into clients/rook assets
- archive OpenSpec change for issue #592
- update dashboard spec with Rook operator flows
Remove unnecessary font-family quotes so the web pre-push checks pass for the new embedded Rook dashboard.
Align the new embedded Rook dashboard sources with Biome import, unused binding, and formatting rules so the web pre-push checks pass.
Resolve the remaining Biome/style formatting and template-binding warnings in the embedded Rook dashboard so pre-push validation can complete successfully.
Apply Biome formatting to the embedded Rook dashboard sources so the web pre-push checks pass cleanly.
@yacosta738 yacosta738 merged commit c51c8c1 into main Apr 22, 2026
12 of 14 checks passed
@yacosta738 yacosta738 deleted the develop branch April 22, 2026 20:13
@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

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

See analysis details on SonarQube Cloud

@yacosta738 yacosta738 changed the title feat(rook): add embedded operator dashboard flows feat(rook): add operator dashboard and first tui slice Apr 23, 2026
@yacosta738 yacosta738 changed the title feat(rook): add operator dashboard and first tui slice feat(rook): add operator dashboard and tui route inspection Apr 23, 2026
@yacosta738 yacosta738 changed the title feat(rook): add operator dashboard and tui route inspection feat(rook): complete operator dashboard and tui surfaces Apr 23, 2026
@yacosta738 yacosta738 changed the title feat(rook): complete operator dashboard and tui surfaces feat(rook): complete operator surfaces and security baseline Apr 24, 2026
@yacosta738 yacosta738 changed the title feat(rook): complete operator surfaces and security baseline feat(rook): complete operator surfaces, security baseline, and audit trail Apr 24, 2026
@coderabbitai coderabbitai Bot mentioned this pull request May 5, 2026
8 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment