Skip to content

feat(agent-runtime): add slash command registry core#545

Merged
yacosta738 merged 6 commits into
developfrom
feature/dallay-539-slash-command-registry-core
Apr 15, 2026
Merged

feat(agent-runtime): add slash command registry core#545
yacosta738 merged 6 commits into
developfrom
feature/dallay-539-slash-command-registry-core

Conversation

@yacosta738
Copy link
Copy Markdown
Contributor

Related Issues

Closes #539
Refs #527


Summary

This PR introduces the slash command registry core for clients/agent-runtime.

It replaces the previous hard-coded slash-session dispatch path with a validated central registry that owns command descriptors, canonical/alias lookup, and dispatch through the shared pre_execution::evaluate_ingress(...) seam.

It also keeps the existing session commands (/resume, /suspend, /tldr, /compact) working through thin registry-backed handlers, preserves backend/authz enforcement in SessionCommandService, and syncs the completed OpenSpec artifacts for the change.


Tested Information

Validated with the Rust runtime checks relevant to this change:

  • cargo fmt --manifest-path clients/agent-runtime/Cargo.toml --all -- --check
  • cargo clippy --manifest-path clients/agent-runtime/Cargo.toml --all-targets -- -D warnings
  • cargo test --manifest-path clients/agent-runtime/Cargo.toml

I also verified the gateway/webhook slash-command regression cases during the SDD verification loop.


Documentation Impact

  • Docs updated in:
    • openspec/specs/slash-command-registry/spec.md
    • openspec/specs/sessions/spec.md
    • openspec/changes/archive/2026-04-15-slash-command-registry-core/
  • No docs update required because:
    • User-facing product docs were not required for this internal runtime/refactoring slice.
  • 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).

…vice.rs issues

- gateway/mod.rs: replace MockMemory with SqliteMemory in slash-session tests
  - canonical_outcome_early_response_intercepts_slash_session_commands
  - legacy_webhook_preview_intercepts_slash_session_commands
  - web_chat_stream_returns_deterministic_slash_session_sse_without_provider_execution
  - update assertions to expect 422 + session_command_failed error

- session_commands/service.rs:
  - FakeMemory::get_session now looks up by session_id
  - build_resume_context adds truncation limits (2k per entry, 16k global)
  - visibility check uses get_session instead of paginated list

- openspec/specs/sessions/spec.md: add trailing newline
@cloudflare-workers-and-pages
Copy link
Copy Markdown

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

Deploying corvus with  Cloudflare Pages  Cloudflare Pages

Latest commit: 4329d45
Status: ✅  Deploy successful!
Preview URL: https://c386ad04.corvus-42x.pages.dev
Branch Preview URL: https://feature-dallay-539-slash-com.corvus-42x.pages.dev

View logs

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 15, 2026

Warning

Rate limit exceeded

@yacosta738 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 11 minutes and 16 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 11 minutes and 16 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: 4f5bed0b-7e7c-4fe7-9748-2b348376c3f1

📥 Commits

Reviewing files that changed from the base of the PR and between 2f61719 and 4329d45.

📒 Files selected for processing (6)
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/session_commands/parser.rs
  • clients/agent-runtime/src/session_commands/registry.rs
  • clients/agent-runtime/src/session_commands/service.rs
  • openspec/changes/archive/2026-04-15-slash-command-registry-core/proposal.md
  • openspec/changes/archive/2026-04-15-slash-command-registry-core/verify-report.md
📝 Walkthrough

Walkthrough

This PR implements the core slash command registry architecture for Corvus, replacing hard-coded command dispatching with a validated, metadata-driven registry system. It introduces descriptor-based command metadata, refactors the parser to lexical parsing, implements registry storage with name/alias lookup and duplicate validation, adds a trait-based handler dispatch model, and integrates this across CLI, gateway, webhook, and channel ingress points while preserving fallthrough behavior for unknown slash-like input.

Changes

Cohort / File(s) Summary
Registry Core Abstractions
clients/agent-runtime/src/session_commands/types.rs, registry.rs, parser.rs
Replaced fixed SessionSlashCommand enum with descriptor-based model: SlashCommandDescriptor, SlashCommandArgumentShape, SlashInvocation, SlashCommandHandler trait, and SlashCommandRegistration. Refactored parser from command-specific to lexical parsing returning RawSlashInvocation. Implemented validated SlashCommandRegistry with registration, canonical/alias indexing, duplicate detection, and async dispatch with argument validation.
Module Exports
clients/agent-runtime/src/session_commands/mod.rs
Broadened re-exports from dispatch function to default_registry and SlashCommandRegistry, and expanded types re-exports to include new descriptor, invocation, and error types. Added #[allow(unused_imports)] attributes.
Service Layer
clients/agent-runtime/src/session_commands/service.rs
Updated handle_resume to directly check session existence instead of visibility-based filtering. Added bounded truncation constants (MAX_ENTRY_CONTENT=2048, MAX_CONTEXT_LENGTH=16384) and context-building truncation. Fixed FakeMemory::get_session to filter by session ID.
Ingress Integration
clients/agent-runtime/src/pre_execution/mod.rs
Refactored evaluate_ingress to route all slash commands through default_registry().dispatch(...) with full prompt instead of conditional parsing, mapping errors to synthesized SessionCommandResult.
Gateway Layers
clients/agent-runtime/src/gateway/mod.rs
Moved/duplicated deterministic session command interception before and after session upsert in handle_webhook; switched tests from MockMemory to SqliteMemory with revised expected outcomes (422 UNPROCESSABLE_ENTITY instead of 200 OK); added legacy_webhook_resume_preserves_transport_identity_through_registry test.
CLI & Webhook Dispatch
clients/agent-runtime/src/main.rs, gateway/webhook_dispatch.rs, channels/mod.rs
Replaced SessionCommandParser::parse(message).is_none() with !default_registry().recognizes(message) in CLI. Updated pattern matching for LoopEvent::ApprovalRequired. Added tests for unknown slash-like input preservation in webhook dispatch and channel ingress.
Test Coverage Updates
Various test files
Rewrote parser tests for lexical behavior; added tests for registry validation, dispatch argument validation, alias routing, unknown slash fallthrough; updated streaming/early-response assertions to match SqliteMemory behavior.
Import Hygiene
clients/agent-runtime/src/memory/sqlite.rs
Merged use super::traits imports onto single line; added SessionFieldPatch import to test module.
Documentation & Specification
openspec/changes/archive/2026-04-15-slash-command-registry-core/*, openspec/specs/slash-command-registry/spec.md, openspec/specs/sessions/spec.md
Added comprehensive design documents (exploration, proposal, design, tasks, verification report) and published specification defining registry contract, descriptor metadata, deterministic lookup, validation rules, dispatch seam preservation, and transport parity requirements. Fixed trailing newline in sessions spec.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Justification: Substantial multi-file refactor touching critical ingress-path logic across four entry points (CLI, gateway HTTP/SSE, webhook, channels). Introduces trait-based dispatch, complex registry validation with duplicate detection, lexical parsing, and behavioral changes around error handling and session targeting. Heterogeneous changes across distinct modules require separate reasoning for each integration point. High density of logic changes and control-flow alterations warrant careful verification of fallthrough semantics and error propagation.

Possibly related PRs

Suggested labels

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

Suggested reviewers

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

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 55.17% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed Title follows Conventional Commit format (feat prefix) with scope and clear, concise summary within 72-character limit.
Description check ✅ Passed Description is comprehensive: includes related issues, clear summary of changes, tested information, documentation impact, breaking changes status, and all checklist items marked complete.
Linked Issues check ✅ Passed PR implements all core objectives of #539: command registry abstraction with descriptor metadata, name/alias lookup, central dispatch through pre_execution seam, and tests for registration/lookup/aliases/duplicates.
Out of Scope Changes check ✅ Passed All changes are directly scoped to #539: registry implementation, slash command handler trait, descriptor types, parsing refactor, service adjustments, and test additions. No unrelated command migrations or new command families introduced.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/dallay-539-slash-command-registry-core

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

❤️ Share

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

@yacosta738 yacosta738 linked an issue Apr 15, 2026 that may be closed by this pull request
5 tasks
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 15, 2026

✅ Contributor Report

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

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 8

Caution

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

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

2213-2246: ⚠️ Potential issue | 🟠 Major

Align streaming slash-command semantics with /webhook.

Because the unconditional upsert_session on Line 2180 still runs before this branch, a fresh /tldr over /web/chat/stream succeeds against an auto-created session while /webhook now returns 422 session_command_failed before any tracking. That makes transport choice observable in command behavior and looks like a contract regression for the same slash command. Consider short-circuiting recognized slash commands before session upsert here as well, or explicitly documenting the divergence.

🤖 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 2213 - 2246, The
branch handling crate::pre_execution::IngressDecision::SessionCommand is
executed after an unconditional call to state.mem.upsert_session, which causes
/web/chat/stream to auto-create sessions while /webhook returns
session_command_failed; to fix, detect and short-circuit recognized slash
commands before calling state.mem.upsert_session (or add a conditional skip of
upsert_session when ingress_decision matches SessionCommand) so that
SessionCommand handling (the block using update_session_activity, session_id,
and result) runs without an earlier upsert creating differing transport
behavior; update references to upsert_session, ingress_decision, and
SessionCommand accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@clients/agent-runtime/src/session_commands/mod.rs`:
- Around line 6-16: Remove the temporary #[allow(unused_imports)] attributes
from the re-exports once downstream consumers stabilize: delete the attributes
applied to SessionCommandParser, the registry exports (default_registry,
SlashCommandRegistry) and the bulk types export (CommandContext,
RawSlashInvocation, SessionCommandError, SessionCommandResult,
SlashCommandArgumentShape, SlashCommandDescriptor, SlashCommandHandler,
SlashCommandRegistration, SlashCommandRequirements, SlashInvocation,
SlashRegistryError); keep the explicit pub use service::SessionCommandService
line as-is and ensure the module still compiles after removing those attributes.

In `@clients/agent-runtime/src/session_commands/parser.rs`:
- Around line 24-34: split_primary_target currently returns the entire trimmed
input as the second value instead of the arguments after the primary target;
update split_primary_target so after computing target_end and primary_target it
returns the post-target substring trimmed of leading whitespace. Concretely, set
remaining_args = if target_end == 0 { trimmed.to_string() } else {
trimmed[target_end..].trim_start().to_string() } and return (primary_target,
remaining_args) in the split_primary_target function.

In `@clients/agent-runtime/src/session_commands/registry.rs`:
- Around line 274-289: The validator currently allows "/" because it only checks
index 0; update validate_name to require at least one character after the
leading slash and enforce that the second character is an ASCII lowercase letter
(i.e. require name.len() >= 2 or check that chars().nth(1) exists and
is_ascii_lowercase()), while keeping the existing per-character rules for
subsequent chars, and continue returning Err(SlashRegistryError::InvalidName {
name: name.to_string() }) when the check fails.
- Around line 44-79: Reject a registration whose canonical name conflicts with
any existing alias and detect duplicate aliases inside the same descriptor:
first, before the alias loop, check if
self.by_alias.contains_key(registration.descriptor.canonical_name) and return an
AliasCollidesWithCanonical error using alias =
registration.descriptor.canonical_name and canonical_name = the existing
canonical owner (lookup self.registrations[*index].descriptor.canonical_name) to
show who owns that alias; then in the for alias in
registration.descriptor.aliases loop, validate_name(alias) as now but also
maintain a local HashSet (e.g., seen_aliases) to detect duplicate aliases inside
the same descriptor and return DuplicateAlias (with existing_canonical_name =
registration.descriptor.canonical_name.to_string()) when an alias repeats; keep
the existing checks against self.by_alias and self.by_canonical_name but ensure
the error payloads use the looked-up existing canonical name from
self.registrations when available.

In `@clients/agent-runtime/src/session_commands/service.rs`:
- Around line 455-466: The current logic trims `context` from the start when
`context.chars().count() > MAX_CONTEXT_LENGTH`, which discards the header
("Session {session_id} summary: {summary}"); change it to trim from the end
instead so the header is preserved: when `context` is too long, take the first
MAX_CONTEXT_LENGTH chars of `context` (e.g., via
`context.chars().take(MAX_CONTEXT_LENGTH)`), then ensure you don't cut mid-entry
by finding the last occurrence of "\n- " within that prefix and trimming the
prefix to that boundary (so only complete, older transcript entries are
dropped); keep using the `context` variable and `MAX_CONTEXT_LENGTH` and remove
the existing skip-from-start logic and the `find("\n- ")` adjustment that
realigns after cutting from the front.
- Around line 207-219: The second storage lookup is redundant—reuse the
already-fetched session variable (from the earlier get_session call stored in
session) to determine target_exists instead of calling self.memory.get_session
again; replace the await/map_err chain with a simple is_some() check on session
(or session.as_ref().is_some() depending on ownership) and keep returning
SessionCommandError::InvalidResumeTarget with session_id:
target_session_id.to_string() when false, preserving the existing error mapping
logic elsewhere.

In `@openspec/changes/archive/2026-04-15-slash-command-registry-core/proposal.md`:
- Line 77: Change the phrase "prompt side" to the hyphenated compound adjective
"prompt side-effects" in the proposal document: locate the text fragment "prompt
side" (appearing on the line containing "webhook, and channel-backed flows
continue to intercept slash commands before normal prompt side") and replace it
with "prompt side-effects"; also scan the same file for other occurrences of
"prompt side" to ensure consistent hyphenation across the doc.

In
`@openspec/changes/archive/2026-04-15-slash-command-registry-core/verify-report.md`:
- Line 1: The first heading "Verification Report" uses "##" but must be a
top-level H1; replace the existing "## Verification Report" with "# Verification
Report" so the document begins with an H1 per markdownlint MD041 rules.

---

Outside diff comments:
In `@clients/agent-runtime/src/gateway/mod.rs`:
- Around line 2213-2246: The branch handling
crate::pre_execution::IngressDecision::SessionCommand is executed after an
unconditional call to state.mem.upsert_session, which causes /web/chat/stream to
auto-create sessions while /webhook returns session_command_failed; to fix,
detect and short-circuit recognized slash commands before calling
state.mem.upsert_session (or add a conditional skip of upsert_session when
ingress_decision matches SessionCommand) so that SessionCommand handling (the
block using update_session_activity, session_id, and result) runs without an
earlier upsert creating differing transport behavior; update references to
upsert_session, ingress_decision, and SessionCommand accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: def502fd-37c6-473b-b3ff-e39a974c8207

📥 Commits

Reviewing files that changed from the base of the PR and between 8a777b9 and 2f61719.

📒 Files selected for processing (20)
  • clients/agent-runtime/src/channels/mod.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/gateway/webhook_dispatch.rs
  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/memory/sqlite.rs
  • clients/agent-runtime/src/pre_execution/mod.rs
  • clients/agent-runtime/src/session_commands/mod.rs
  • clients/agent-runtime/src/session_commands/parser.rs
  • clients/agent-runtime/src/session_commands/registry.rs
  • clients/agent-runtime/src/session_commands/service.rs
  • clients/agent-runtime/src/session_commands/types.rs
  • openspec/changes/archive/2026-04-15-slash-command-registry-core/design.md
  • openspec/changes/archive/2026-04-15-slash-command-registry-core/exploration.md
  • openspec/changes/archive/2026-04-15-slash-command-registry-core/proposal.md
  • openspec/changes/archive/2026-04-15-slash-command-registry-core/specs/slash-command-registry/spec.md
  • openspec/changes/archive/2026-04-15-slash-command-registry-core/state.yaml
  • openspec/changes/archive/2026-04-15-slash-command-registry-core/tasks.md
  • openspec/changes/archive/2026-04-15-slash-command-registry-core/verify-report.md
  • openspec/specs/sessions/spec.md
  • openspec/specs/slash-command-registry/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). (1)
  • GitHub Check: Cloudflare Pages
🧰 Additional context used
📓 Path-based instructions (9)
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/memory/sqlite.rs
  • clients/agent-runtime/src/gateway/webhook_dispatch.rs
  • clients/agent-runtime/src/channels/mod.rs
  • clients/agent-runtime/src/pre_execution/mod.rs
  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/session_commands/service.rs
  • clients/agent-runtime/src/session_commands/parser.rs
  • clients/agent-runtime/src/session_commands/mod.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/session_commands/registry.rs
  • clients/agent-runtime/src/session_commands/types.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/memory/sqlite.rs
  • clients/agent-runtime/src/gateway/webhook_dispatch.rs
  • clients/agent-runtime/src/channels/mod.rs
  • clients/agent-runtime/src/pre_execution/mod.rs
  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/session_commands/service.rs
  • clients/agent-runtime/src/session_commands/parser.rs
  • clients/agent-runtime/src/session_commands/mod.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/session_commands/registry.rs
  • clients/agent-runtime/src/session_commands/types.rs
**/*.rs

⚙️ CodeRabbit configuration file

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

Files:

  • clients/agent-runtime/src/memory/sqlite.rs
  • clients/agent-runtime/src/gateway/webhook_dispatch.rs
  • clients/agent-runtime/src/channels/mod.rs
  • clients/agent-runtime/src/pre_execution/mod.rs
  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/session_commands/service.rs
  • clients/agent-runtime/src/session_commands/parser.rs
  • clients/agent-runtime/src/session_commands/mod.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/session_commands/registry.rs
  • clients/agent-runtime/src/session_commands/types.rs
**/*

⚙️ CodeRabbit configuration file

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

Files:

  • clients/agent-runtime/src/memory/sqlite.rs
  • clients/agent-runtime/src/gateway/webhook_dispatch.rs
  • openspec/specs/sessions/spec.md
  • openspec/changes/archive/2026-04-15-slash-command-registry-core/state.yaml
  • clients/agent-runtime/src/channels/mod.rs
  • clients/agent-runtime/src/pre_execution/mod.rs
  • clients/agent-runtime/src/main.rs
  • openspec/changes/archive/2026-04-15-slash-command-registry-core/exploration.md
  • openspec/changes/archive/2026-04-15-slash-command-registry-core/verify-report.md
  • openspec/changes/archive/2026-04-15-slash-command-registry-core/tasks.md
  • clients/agent-runtime/src/session_commands/service.rs
  • openspec/changes/archive/2026-04-15-slash-command-registry-core/design.md
  • clients/agent-runtime/src/session_commands/parser.rs
  • clients/agent-runtime/src/session_commands/mod.rs
  • openspec/changes/archive/2026-04-15-slash-command-registry-core/specs/slash-command-registry/spec.md
  • openspec/specs/slash-command-registry/spec.md
  • openspec/changes/archive/2026-04-15-slash-command-registry-core/proposal.md
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/session_commands/registry.rs
  • clients/agent-runtime/src/session_commands/types.rs
clients/agent-runtime/src/{security,gateway,tools}/**/*.rs

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

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

Files:

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

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

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

Files:

  • clients/agent-runtime/src/gateway/webhook_dispatch.rs
  • clients/agent-runtime/src/gateway/mod.rs
**/*.{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/specs/sessions/spec.md
  • openspec/changes/archive/2026-04-15-slash-command-registry-core/exploration.md
  • openspec/changes/archive/2026-04-15-slash-command-registry-core/verify-report.md
  • openspec/changes/archive/2026-04-15-slash-command-registry-core/tasks.md
  • openspec/changes/archive/2026-04-15-slash-command-registry-core/design.md
  • openspec/changes/archive/2026-04-15-slash-command-registry-core/specs/slash-command-registry/spec.md
  • openspec/specs/slash-command-registry/spec.md
  • openspec/changes/archive/2026-04-15-slash-command-registry-core/proposal.md
clients/agent-runtime/src/channels/**/*.rs

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

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

Files:

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

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

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

Files:

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

Applied to files:

  • clients/agent-runtime/src/memory/sqlite.rs
  • clients/agent-runtime/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: 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/memory/sqlite.rs
  • clients/agent-runtime/src/gateway/webhook_dispatch.rs
  • clients/agent-runtime/src/channels/mod.rs
  • clients/agent-runtime/src/pre_execution/mod.rs
  • clients/agent-runtime/src/main.rs
  • openspec/changes/archive/2026-04-15-slash-command-registry-core/exploration.md
  • openspec/changes/archive/2026-04-15-slash-command-registry-core/tasks.md
  • clients/agent-runtime/src/session_commands/service.rs
  • openspec/changes/archive/2026-04-15-slash-command-registry-core/design.md
  • clients/agent-runtime/src/session_commands/parser.rs
  • clients/agent-runtime/src/session_commands/mod.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/session_commands/registry.rs
  • clients/agent-runtime/src/session_commands/types.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/channels/**/*.rs : Implement `Channel` trait in `src/channels/` with consistent `send`, `listen`, and `health_check` semantics and cover auth/allowlist/health behavior with tests

Applied to files:

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

Applied to files:

  • clients/agent-runtime/src/channels/mod.rs
  • clients/agent-runtime/src/pre_execution/mod.rs
  • clients/agent-runtime/src/main.rs
  • openspec/changes/archive/2026-04-15-slash-command-registry-core/tasks.md
  • clients/agent-runtime/src/session_commands/service.rs
  • clients/agent-runtime/src/session_commands/parser.rs
  • clients/agent-runtime/src/session_commands/mod.rs
  • clients/agent-runtime/src/gateway/mod.rs
  • clients/agent-runtime/src/session_commands/registry.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/{security,gateway,tools,config}/**/*.rs : Do not silently weaken security policy or access constraints; keep default behavior secure-by-default with deny-by-default where applicable

Applied to files:

  • clients/agent-runtime/src/main.rs
  • clients/agent-runtime/src/gateway/mod.rs
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/**/*.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/main.rs
  • openspec/changes/archive/2026-04-15-slash-command-registry-core/verify-report.md
📚 Learning: 2026-02-17T12:31:17.076Z
Learnt from: CR
Repo: dallay/corvus PR: 0
File: clients/agent-runtime/AGENTS.md:0-0
Timestamp: 2026-02-17T12:31:17.076Z
Learning: Applies to clients/agent-runtime/src/tools/**/*.rs : Implement `Tool` trait in `src/tools/` with strict parameter schema, validate and sanitize all inputs, and return structured `ToolResult` without panics in runtime path

Applied to files:

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

Applied to files:

  • clients/agent-runtime/src/gateway/mod.rs
🪛 LanguageTool
openspec/changes/archive/2026-04-15-slash-command-registry-core/proposal.md

[grammar] ~77-~77: Use a hyphen to join words.
Context: ...cept slash commands before normal prompt side effects. Existing session commands ...

(QB_NEW_EN_HYPHEN)

🪛 markdownlint-cli2 (0.22.0)
openspec/changes/archive/2026-04-15-slash-command-registry-core/verify-report.md

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

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

🔇 Additional comments (18)
clients/agent-runtime/src/memory/sqlite.rs (2)

4-5: LGTM: Import formatting improvement.

Grouping related session state types on single lines improves readability. No semantic change.


1599-1599: LGTM: Test import addition is correct.

Explicitly importing SessionFieldPatch makes test dependencies clear and supports the session state patching tests added for the slash-command registry feature.

openspec/specs/sessions/spec.md (1)

595-595: No issues in this change segment.

Line 595 is a non-behavioral docs touch and remains consistent with the current session spec contract.

As per coding guidelines: "**/*.{md,mdx}: Verify technical accuracy and that docs stay aligned with code changes."

openspec/changes/archive/2026-04-15-slash-command-registry-core/state.yaml (1)

1-12: State metadata looks consistent.

Phase progression and archive handoff fields are internally coherent for the archived change record.

openspec/changes/archive/2026-04-15-slash-command-registry-core/specs/slash-command-registry/spec.md (1)

1-167: Spec contract is clear and aligned with implementation intent.

The requirements are internally consistent and preserve critical boundaries (registry dispatch vs handler auth/backend enforcement).

As per coding guidelines: "**/*.{md,mdx}: Verify technical accuracy and that docs stay aligned with code changes."

openspec/specs/slash-command-registry/spec.md (1)

1-167: Looks good—requirements are precise and testable.

The spec cleanly defines deterministic registry behavior while preserving existing slash-session semantics and fallthrough for unknown slash-like input.

As per coding guidelines: "**/*.{md,mdx}: Verify technical accuracy and that docs stay aligned with code changes."

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

1087-1116: Good regression test for slash-like fallthrough.

This test correctly protects the gateway path against over-eager slash interception by asserting normal provider execution for unknown slash-like input.

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

3263-3281: Good regression coverage for unknown slash-like fallthrough.

Line 3263 adds the right guardrail: unknown slash-like input returns None and sends no channel response.

clients/agent-runtime/src/pre_execution/mod.rs (2)

50-77: Registry-first ingress dispatch is correctly wired.

Line 50 through Line 77 correctly short-circuits recognized slash commands through the registry while preserving fallthrough for non-dispatched input.


259-292: Test coverage now pins critical slash-command error semantics.

Line 259 through Line 292 adds strong regression checks for unsupported-backend /tldr and invalid-argument /tldr usage.

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

1529-1531: Behavioral change correctly aligns with registry semantics.

The switch from SessionCommandParser::parse(message).is_none() to !default_registry().recognizes(message) is intentional: parse() returns Some(...) for any slash-prefixed input (e.g., /resume-later), while recognizes() only returns true for registered commands. This ensures unknown slash-like input falls through to the agent loop rather than being incorrectly intercepted.

The test at lines 3418–3428 validates this fallthrough behavior.


3411-3428: Test coverage validates registry fallthrough semantics.

The /tldr test correctly expects an error when memory backend is "none" (SQLite required). The new /resume-later test validates that unregistered slash-like input returns None (fallthrough) rather than being intercepted.


718-719: Pattern match updates are sound.

Using (..) and { tool, .. } to ignore additional fields in ApprovalRequired is idiomatic and forward-compatible with future struct extensions.

Also applies to: 782-782, 1422-1422

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

564-571: Test helper now correctly filters by session ID.

The FakeMemory::get_session change ensures the mock matches real behavior—only returning the session when the requested ID matches. This prevents false-positive test results.

openspec/changes/archive/2026-04-15-slash-command-registry-core/exploration.md (1)

1-27: Documentation accurately captures the registry architecture.

The exploration doc correctly describes the transition from hard-coded dispatch to registry-driven lookup, the pre_execution::evaluate_ingress seam, and identifies relevant risks (transport parity, /resume authorization semantics, backend capability rules).

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

6-22: Lexical parser implementation is sound.

The parser correctly extracts the slash command token and raw args without hardcoding specific commands. Edge cases (bare /, non-slash input, whitespace handling) are properly handled.

openspec/changes/archive/2026-04-15-slash-command-registry-core/tasks.md (1)

1-26: Task documentation is complete and accurate.

The implementation checklist correctly reflects the PR scope—registry core only, excluding help/introspection APIs and new command families. All four phases are marked complete with appropriate verification steps.

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

1977-2040: Good move short-circuiting recognized slash commands before legacy session tracking.

This keeps registry-backed session commands off the legacy upsert/autosave path while still preserving the shared ingress seam for non-slash prompts.

Comment on lines +6 to +16
#[allow(unused_imports)]
pub use parser::SessionCommandParser;
pub use registry::dispatch;
#[allow(unused_imports)]
pub use registry::{default_registry, SlashCommandRegistry};
pub use service::SessionCommandService;
pub use types::{CommandContext, SessionCommandResult};
#[allow(unused_imports)]
pub use types::{
CommandContext, RawSlashInvocation, SessionCommandError, SessionCommandResult,
SlashCommandArgumentShape, SlashCommandDescriptor, SlashCommandHandler,
SlashCommandRegistration, SlashCommandRequirements, SlashInvocation, SlashRegistryError,
};
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

Re-exports align with registry API; consider removing #[allow(unused_imports)] later.

The exported types match the new registry-driven architecture. The #[allow(unused_imports)] attributes are acceptable during transition, but consider removing them once downstream consumers stabilize.

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

In `@clients/agent-runtime/src/session_commands/mod.rs` around lines 6 - 16,
Remove the temporary #[allow(unused_imports)] attributes from the re-exports
once downstream consumers stabilize: delete the attributes applied to
SessionCommandParser, the registry exports (default_registry,
SlashCommandRegistry) and the bulk types export (CommandContext,
RawSlashInvocation, SessionCommandError, SessionCommandResult,
SlashCommandArgumentShape, SlashCommandDescriptor, SlashCommandHandler,
SlashCommandRegistration, SlashCommandRequirements, SlashInvocation,
SlashRegistryError); keep the explicit pub use service::SessionCommandService
line as-is and ensure the module still compiles after removing those attributes.

Comment thread clients/agent-runtime/src/session_commands/parser.rs
Comment thread clients/agent-runtime/src/session_commands/registry.rs
Comment thread clients/agent-runtime/src/session_commands/registry.rs
Comment thread clients/agent-runtime/src/session_commands/service.rs Outdated
Comment thread clients/agent-runtime/src/session_commands/service.rs
Comment thread openspec/changes/archive/2026-04-15-slash-command-registry-core/proposal.md Outdated
Comment thread openspec/changes/archive/2026-04-15-slash-command-registry-core/verify-report.md Outdated
- parser: fix split_primary_target to return args after target
- registry: strengthen validate_name to require len >= 2 and lowercase second char
- registry: detect canonical vs alias conflicts and duplicate aliases in same descriptor
- service: fix context truncation to trim from end preserving header
- service: remove redundant get_session call in handle_resume
- gateway: handle SessionCommand after session upsert for session-dependent commands
- docs: fix 'prompt side' -> 'prompt side-effects' in proposal
- docs: fix verify-report.md to use H1 instead of H2
@yacosta738 yacosta738 merged commit 72d1eff into develop Apr 15, 2026
7 checks passed
@yacosta738 yacosta738 deleted the feature/dallay-539-slash-command-registry-core branch April 15, 2026 14:59
This was referenced Apr 29, 2026
@dallay-bot dallay-bot Bot mentioned this pull request May 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Slash Command Registry Core

1 participant