Files
stack/docs/scratchpads/89-command-message-type.md
Jason Woltje 9501aa3867 feat(#89): implement COMMAND message type for federation
Implements federated command messages following TDD principles and
mirroring the QueryService pattern for consistency.

## Implementation

### Schema Changes
- Added commandType and payload fields to FederationMessage model
- Supports COMMAND message type (already defined in enum)
- Applied schema changes with prisma db push

### Type Definitions
- CommandMessage: Request structure with commandType and payload
- CommandResponse: Response structure with correlation
- CommandMessageDetails: Full message details for API responses

### CommandService
- sendCommand(): Send command to remote instance with signature
- handleIncomingCommand(): Process incoming commands with verification
- processCommandResponse(): Handle command responses
- getCommandMessages(): List commands for workspace
- getCommandMessage(): Get single command details
- Full signature verification and timestamp validation
- Error handling and status tracking

### CommandController
- POST /api/v1/federation/command - Send command (authenticated)
- POST /api/v1/federation/incoming/command - Handle incoming (public)
- GET /api/v1/federation/commands - List commands (authenticated)
- GET /api/v1/federation/commands/:id - Get command (authenticated)

## Testing
- CommandService: 15 tests, 90.21% coverage
- CommandController: 8 tests, 100% coverage
- All 23 tests passing
- Exceeds 85% coverage requirement
- Total 47 tests passing (includes command tests)

## Security
- RSA signature verification for all incoming commands
- Timestamp validation to prevent replay attacks
- Connection status validation
- Authorization checks on command types

## Quality Checks
- TypeScript compilation: PASSED
- All tests: 47 PASSED
- Code coverage: >85% (90.21% for CommandService, 100% for CommandController)
- Linting: PASSED

Fixes #89

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-03 13:30:16 -06:00

4.7 KiB

Issue #89: [FED-006] COMMAND Message Type

Objective

Implement COMMAND message type for federation to enable remote instances to execute commands on connected instances. This builds on the existing FederationMessage model and follows the patterns established by FED-005 (QUERY Message Type).

Approach

Design Decisions

  1. Reuse FederationMessage Model: The Prisma schema already supports COMMAND type in the FederationMessageType enum
  2. Follow Query Pattern: Mirror the structure and flow of QueryService/QueryController for consistency
  3. Command Authorization: Add authorization checks to ensure only permitted commands can be executed
  4. Command Types: Support various command types (e.g., spawn_agent, update_config, etc.)

Architecture

CommandService
├── sendCommand() - Send command to remote instance
├── handleIncomingCommand() - Process incoming command
├── processCommandResponse() - Handle command response
├── getCommandMessages() - List commands for workspace
└── getCommandMessage() - Get single command details

CommandController
├── POST /api/v1/federation/command - Send command
├── POST /api/v1/federation/incoming/command - Handle incoming command
├── GET /api/v1/federation/commands - List commands
└── GET /api/v1/federation/commands/:id - Get command details

Command Message Structure

interface CommandMessage {
  messageId: string; // Unique identifier
  instanceId: string; // Sending instance
  commandType: string; // Command type (spawn_agent, etc.)
  payload: Record<string, unknown>; // Command-specific data
  timestamp: number; // Unix milliseconds
  signature: string; // RSA signature
}

interface CommandResponse {
  messageId: string; // Response identifier
  correlationId: string; // Original command messageId
  instanceId: string; // Responding instance
  success: boolean; // Command execution result
  data?: unknown; // Result data
  error?: string; // Error message
  timestamp: number; // Unix milliseconds
  signature: string; // RSA signature
}

Progress

Phase 1: Types and DTOs (TDD)

  • Create command message types in message.types.ts
  • Create command DTOs (SendCommandDto, IncomingCommandDto)
  • Updated Prisma schema to add commandType and payload fields

Phase 2: Command Service (TDD)

  • Write tests for CommandService.sendCommand()
  • Implement sendCommand()
  • Write tests for CommandService.handleIncomingCommand()
  • Implement handleIncomingCommand()
  • Write tests for CommandService.processCommandResponse()
  • Implement processCommandResponse()
  • Write tests for query methods (getCommandMessages, getCommandMessage)
  • Implement query methods

Phase 3: Command Controller (TDD)

  • Write tests for CommandController endpoints
  • Implement CommandController
  • Add controller to FederationModule

Phase 4: Integration

  • All unit tests passing (23 tests)
  • Signature verification implemented
  • Authorization checks implemented
  • Error handling tested

Test Results

  • CommandService: 90.21% coverage (15 tests, all passing)
  • CommandController: 100% coverage (8 tests, all passing)
  • Total: 23 tests, all passing

Remaining Tasks

  • Run Prisma migration to create commandType and payload columns
  • Generate Prisma client with new schema
  • Manual integration testing with live instances

Testing Strategy

Unit Tests

  • DTO validation
  • CommandService methods (mocked dependencies)
  • CommandController endpoints (mocked service)

Integration Tests

  • Full command send/receive cycle
  • Signature verification
  • Error scenarios
  • Authorization checks

Coverage Target

  • Minimum 85% code coverage
  • All error paths tested
  • All validation rules tested

Security Considerations

  1. Signature Verification: All incoming commands must be signed
  2. Authorization: Check if sending instance has permission for command type
  3. Timestamp Validation: Reject commands with old timestamps
  4. Rate Limiting: Consider adding rate limits (future enhancement)
  5. Command Whitelist: Only allow specific command types

Notes

Reusable Patterns from QueryService

  • Signature verification flow
  • Connection validation
  • Message storage in FederationMessage table
  • Response correlation via correlationId
  • Status tracking (PENDING, DELIVERED, FAILED)

Key Differences from QUERY

  • Commands modify state (queries are read-only)
  • Commands require stricter authorization
  • Command types need to be registered/whitelisted
  • Command execution is async (may take longer than queries)

Future Enhancements

  • Command queueing for offline instances
  • Command retry logic
  • Command expiration
  • Command priority levels