feat: Phase 7 multi-agent state tools with permission model #19

Merged
jesse merged 9 commits from phase-7/agent-state-tools into main 2026-04-11 06:16:25 +02:00
Owner

Summary

  • Multi-agent permission model: AgentRole (Primary/Contributor/Observer/Reader) with role-based tool access control, enforced at MCP dispatch layer via fail-open pattern
  • MCP agent tools: share_session, list_agents, get_server_health tool definitions with JSON schemas, registered in ToolRegistry with placeholder handlers
  • Server foundation types: AgentSession, AgentRegistry (with prune/eviction), SharedSession with owner-authorized grant/revoke, ServerHealth with optional metrics
  • Config refactor: Split monolithic config.rs into 7 focused modules; typed LogLevel/LogFormat enums; port collision validation scoped to TransportKind::All
  • Code review fixes: 24 issues (4 HIGH, 12 MEDIUM, 8 LOW) resolved — removed phantom tool names from permission model, eliminated fragile MCP→permission name translation layer, converted server errors to anyhow, added session authorization checks, added 28 new tests

Phase

Phase 7 — Multi-Agent Coordination

Commits

  • f59c7dd feat(mcp): share_session, list_agents, get_server_health tool definitions
  • 224fadf feat(server): AgentSession, SharedSession, ServerHealth foundation types
  • 6037104 feat(mcp): role-based tool dispatch permission enforcement
  • 6fcbc67 fix: update registration test for 16 tools, format fixes
  • c3374e1 docs: mark PR14 phases B, F, G as complete in todo
  • e035217 fix(core): config validation, typed log enums, test coverage
  • faa668e fix(core,mcp): use real MCP tool names in permission model, filter tools/list by role
  • ee5aeae fix(server): wire handler match arms, anyhow errors, session auth, health cleanup
  • bf9cc5f chore: update Cargo.lock for thiserror removal from cognix-server

Test Plan

  • cargo test --workspace — 964 tests pass (28 new, 0 regressions from 936 baseline)
  • cargo clippy --workspace --all-targets with full deny list — clean
  • cargo fmt --check — clean
  • Permission enforcement: restricted tools checked at dispatch, unrestricted tools accessible to all roles
  • Fail-open: permission denials return MCP success with [permission denied] text, not protocol errors
  • Session authorization: only owner/Primary agents can grant/revoke access
  • Handler match arms: all 3 new tools return [not yet wired] placeholder (not [error] unknown tool)
  • Config validation: port collision only checked for TransportKind::All; invalid env vars logged and ignored

Self-Review Checklist

  • No hardcoded secrets
  • No unwrap() in library code
  • No println!/dbg!
  • Fail-open degradation for new subsystems
  • Tests cover happy path and error cases
  • thiserror in lib crates only, anyhow in binary crates
  • Privacy: no thought content in errors or logs
  • Sensitive<T> used for content fields

🤖 Generated with Claude Code

## Summary - **Multi-agent permission model**: `AgentRole` (Primary/Contributor/Observer/Reader) with role-based tool access control, enforced at MCP dispatch layer via fail-open pattern - **MCP agent tools**: `share_session`, `list_agents`, `get_server_health` tool definitions with JSON schemas, registered in ToolRegistry with placeholder handlers - **Server foundation types**: `AgentSession`, `AgentRegistry` (with prune/eviction), `SharedSession` with owner-authorized grant/revoke, `ServerHealth` with optional metrics - **Config refactor**: Split monolithic `config.rs` into 7 focused modules; typed `LogLevel`/`LogFormat` enums; port collision validation scoped to `TransportKind::All` - **Code review fixes**: 24 issues (4 HIGH, 12 MEDIUM, 8 LOW) resolved — removed phantom tool names from permission model, eliminated fragile MCP→permission name translation layer, converted server errors to `anyhow`, added session authorization checks, added 28 new tests ## Phase Phase 7 — Multi-Agent Coordination ## Commits - `f59c7dd` feat(mcp): share_session, list_agents, get_server_health tool definitions - `224fadf` feat(server): AgentSession, SharedSession, ServerHealth foundation types - `6037104` feat(mcp): role-based tool dispatch permission enforcement - `6fcbc67` fix: update registration test for 16 tools, format fixes - `c3374e1` docs: mark PR14 phases B, F, G as complete in todo - `e035217` fix(core): config validation, typed log enums, test coverage - `faa668e` fix(core,mcp): use real MCP tool names in permission model, filter tools/list by role - `ee5aeae` fix(server): wire handler match arms, anyhow errors, session auth, health cleanup - `bf9cc5f` chore: update Cargo.lock for thiserror removal from cognix-server ## Test Plan - [x] `cargo test --workspace` — 964 tests pass (28 new, 0 regressions from 936 baseline) - [x] `cargo clippy --workspace --all-targets` with full deny list — clean - [x] `cargo fmt --check` — clean - [x] Permission enforcement: restricted tools checked at dispatch, unrestricted tools accessible to all roles - [x] Fail-open: permission denials return MCP success with `[permission denied]` text, not protocol errors - [x] Session authorization: only owner/Primary agents can grant/revoke access - [x] Handler match arms: all 3 new tools return `[not yet wired]` placeholder (not `[error] unknown tool`) - [x] Config validation: port collision only checked for `TransportKind::All`; invalid env vars logged and ignored ## Self-Review Checklist - [x] No hardcoded secrets - [x] No `unwrap()` in library code - [x] No `println!`/`dbg!` - [x] Fail-open degradation for new subsystems - [x] Tests cover happy path and error cases - [x] `thiserror` in lib crates only, `anyhow` in binary crates - [x] Privacy: no thought content in errors or logs - [x] `Sensitive<T>` used for content fields 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Port collision check only fires for TransportKind::All (not SSE/WS-only)
- Replace stringly-typed LoggingConfig level/format with LogLevel/LogFormat enums
- Split apply_env_overrides into per-section helpers (<50 lines each)
- Split tests.rs into submodules (defaults, serde, embedding, validation, env)
- Add tests for all Phase 7 server/agent env var overrides
- Add tests for invalid env var values retaining defaults
- Add logging env override support (COGNIX_LOGGING_LEVEL, COGNIX_LOGGING_FORMAT)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
chore: update Cargo.lock for thiserror removal from cognix-server
All checks were successful
CI / Detect Changes (pull_request) Successful in 6s
CI / Integration Tests (pull_request) Has been skipped
CI / Benchmarks (pull_request) Has been skipped
CI / Security Scan (pull_request) Successful in 15s
CI / Check file lengths (pull_request) Successful in 15s
CI / Format (pull_request) Successful in 16s
CI / Clippy (pull_request) Successful in 1m45s
CI / Test (pull_request) Successful in 2m29s
CI / Coverage (80% gate) (pull_request) Successful in 3m40s
CI / Audit (CVEs) (pull_request) Successful in 3m59s
CI / Deny (pull_request) Successful in 4m39s
CI / Build (release) (pull_request) Successful in 2m52s
CI / PR Size Check (pull_request) Successful in 5s
CI / Documentation (pull_request) Successful in 37s
CI / CI Report (pull_request) Successful in 5s
bf9cc5f745
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
jesse merged commit 732e5f2719 into main 2026-04-11 06:16:25 +02:00
jesse deleted branch phase-7/agent-state-tools 2026-04-11 06:16:25 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
jesse/cognix!19
No description provided.