Implements status broadcasting via bridge module to chat channels. The Herald service subscribes to job events and broadcasts status updates to Discord threads using PDA-friendly language. Features: - Herald module with HeraldService for status broadcasting - Subscribe to job lifecycle, step lifecycle, and gate events - Format messages with PDA-friendly language (no "FAILED", "URGENT", etc.) - Visual indicators for quick scanning (🟢, 🔵, ✅, ⚠️, ⏸️) - Channel selection logic via workspace settings - Route to Discord threads based on job metadata - Comprehensive unit tests (14 tests passing, 85%+ coverage) Message format examples: - 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 - Gate passed: ✅ Gate passed: build - Gate failed: ⚠️ Gate needs attention: test Quality gates: ✅ typecheck, lint, test, build PR comment support deferred - requires GitHub/Gitea API client implementation. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
120 lines
4.1 KiB
Markdown
120 lines
4.1 KiB
Markdown
# 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
|