# Issue #172: Herald Status Updates ## Objective Implement status reporting via the bridge module to chat channels and PR comments. The Herald service will broadcast job status updates to appropriate channels based on workspace configuration. ## Approach 1. Review existing code: - JobEventsService (#169) for event types - IChatProvider interface and Discord provider (#170) 2. Create Herald module following TDD: - RED: Write tests for status broadcasting - GREEN: Implement Herald service - REFACTOR: Clean up and optimize 3. Implement channel selection logic (job type β†’ channel mapping) 4. Add PR comment support via GitHub/Gitea API 5. Format messages using PDA-friendly language ## Progress - [x] Create scratchpad - [x] Review JobEventsService and event types - [x] Review IChatProvider interface and Discord provider - [x] Write tests for Herald service (RED) - [x] Create Herald module structure - [x] Implement Herald service (GREEN) - [x] Add channel selection logic - [ ] Add PR comment support (deferred - GitHub API integration needed) - [x] Refactor and optimize (REFACTOR) - [x] Run quality gates (typecheck, lint, test, build) - [x] Commit changes ## Key Findings ### Event Types Available - Job lifecycle: `job.created`, `job.queued`, `job.started`, `job.completed`, `job.failed`, `job.cancelled` - Step lifecycle: `step.started`, `step.progress`, `step.output`, `step.completed`, `step.failed` - AI events: `ai.tool_called`, `ai.tokens_used`, `ai.artifact_created` - Gate events: `gate.started`, `gate.passed`, `gate.failed` ### IChatProvider Interface - `sendMessage(channelId, content)` - Send message to channel - `createThread(options)` - Create thread for updates - `sendThreadMessage(options)` - Send message to thread - `isConnected()` - Check connection status ### Workspace Settings - Workspace has `settings` JSON field for configuration - Can store channel mappings: `{ herald: { channelMappings: { "code-task": "channel-id" } } }` ### Herald Responsibilities 1. Subscribe to job events from JobEventsService 2. Format status messages using PDA-friendly language 3. Route to appropriate channels based on workspace config 4. Support Discord (via bridge) and PR comments (via GitHub/Gitea API) 5. Follow 10-second scannability rule ## Testing - Unit tests for status broadcasting - Tests for channel selection logic - Tests for message formatting (PDA-friendly) - Tests for PR comment integration - Minimum 85% coverage required ## Notes - Use PDA-friendly language (no "OVERDUE", "URGENT", etc.) - Follow 10-second scannability rule - Support multiple providers (Discord, GitHub PR comments) - Subscribe to job events via JobEventsService - Route to appropriate channels based on workspace config ## Implementation Details ### Architecture - Herald module created with HeraldService - Subscribes to job events (job lifecycle, step lifecycle, gate events) - Formats messages with PDA-friendly language and visual indicators - Routes to Discord threads via DiscordService ### Message Formatting - Job created: 🟒 Job created for #42 - Job started: πŸ”΅ Job started for #42 - Job completed: βœ… Job completed for #42 (120s) - Job failed: ⚠️ Job encountered an issue for #42 - Job cancelled: ⏸️ Job paused for #42 - Step completed: βœ… Step completed: Run tests - Gate passed: βœ… Gate passed: build - Gate failed: ⚠️ Gate needs attention: test ### Channel Selection - Workspace settings store channel mappings: `{ herald: { channelMappings: { "code-task": "channel-id" } } }` - Falls back to default channel if job type not mapped - Returns null if no channel configured ### Metadata Handling - Job metadata (including threadId) stored in first event payload (job.created) - Herald retrieves metadata from JobEvent table to determine where to send updates - This allows thread-based updates for each job ## Deferred Features - PR comment support via GitHub/Gitea API (requires additional API client implementation) - This can be added in a future iteration when needed ## Dependencies - #169 (JobEventsService) - βœ… COMPLETED - #170 (IChatProvider) - βœ… COMPLETED