|
| 1 | +# Convoy Lifecycle Design |
| 2 | + |
| 3 | +> Making convoys actively converge on completion. |
| 4 | +
|
| 5 | +## Problem Statement |
| 6 | + |
| 7 | +Convoys are passive trackers. They group work but don't drive it. The completion |
| 8 | +loop has a structural gap: |
| 9 | + |
| 10 | +``` |
| 11 | +Create → Assign → Execute → Issues close → ??? → Convoy closes |
| 12 | +``` |
| 13 | + |
| 14 | +The `???` is "Deacon patrol runs `gt convoy check`" - a poll-based single point of |
| 15 | +failure. When Deacon is down, convoys don't close. Work completes but the loop |
| 16 | +never lands. |
| 17 | + |
| 18 | +## Current State |
| 19 | + |
| 20 | +### What Works |
| 21 | +- Convoy creation and issue tracking |
| 22 | +- `gt convoy status` shows progress |
| 23 | +- `gt convoy stranded` finds unassigned work |
| 24 | +- `gt convoy check` auto-closes completed convoys |
| 25 | + |
| 26 | +### What Breaks |
| 27 | +1. **Poll-based completion**: Only Deacon runs `gt convoy check` |
| 28 | +2. **No event-driven trigger**: Issue close doesn't propagate to convoy |
| 29 | +3. **No manual close**: Can't force-close abandoned convoys |
| 30 | +4. **Single observer**: No redundant completion detection |
| 31 | +5. **Weak notification**: Convoy owner not always clear |
| 32 | + |
| 33 | +## Design: Active Convoy Convergence |
| 34 | + |
| 35 | +### Principle: Event-Driven, Redundantly Observed |
| 36 | + |
| 37 | +Convoy completion should be: |
| 38 | +1. **Event-driven**: Triggered by issue close, not polling |
| 39 | +2. **Redundantly observed**: Multiple agents can detect and close |
| 40 | +3. **Manually overridable**: Humans can force-close |
| 41 | + |
| 42 | +### Event-Driven Completion |
| 43 | + |
| 44 | +When an issue closes, check if it's tracked by a convoy: |
| 45 | + |
| 46 | +``` |
| 47 | +Issue closes |
| 48 | + ↓ |
| 49 | +Is issue tracked by convoy? ──(no)──► done |
| 50 | + │ |
| 51 | + (yes) |
| 52 | + ↓ |
| 53 | +Run gt convoy check <convoy-id> |
| 54 | + ↓ |
| 55 | +All tracked issues closed? ──(no)──► done |
| 56 | + │ |
| 57 | + (yes) |
| 58 | + ↓ |
| 59 | +Close convoy, send notifications |
| 60 | +``` |
| 61 | + |
| 62 | +**Implementation options:** |
| 63 | +1. Daemon hook on `bd update --status=closed` |
| 64 | +2. Refinery step after successful merge |
| 65 | +3. Witness step after verifying polecat completion |
| 66 | + |
| 67 | +Option 1 is most reliable - catches all closes regardless of source. |
| 68 | + |
| 69 | +### Redundant Observers |
| 70 | + |
| 71 | +Per PRIMING.md: "Redundant Monitoring Is Resilience." |
| 72 | + |
| 73 | +Three places should check convoy completion: |
| 74 | + |
| 75 | +| Observer | When | Scope | |
| 76 | +|----------|------|-------| |
| 77 | +| **Daemon** | On any issue close | All convoys | |
| 78 | +| **Witness** | After verifying polecat work | Rig's convoy work | |
| 79 | +| **Deacon** | Periodic patrol | All convoys (backup) | |
| 80 | + |
| 81 | +Any observer noticing completion triggers close. Idempotent - closing |
| 82 | +an already-closed convoy is a no-op. |
| 83 | + |
| 84 | +### Manual Close Command |
| 85 | + |
| 86 | +**Desire path**: `gt convoy close` is expected but missing. |
| 87 | + |
| 88 | +```bash |
| 89 | +# Close a completed convoy |
| 90 | +gt convoy close hq-cv-abc |
| 91 | + |
| 92 | +# Force-close an abandoned convoy |
| 93 | +gt convoy close hq-cv-xyz --reason="work done differently" |
| 94 | + |
| 95 | +# Close with explicit notification |
| 96 | +gt convoy close hq-cv-abc --notify mayor/ |
| 97 | +``` |
| 98 | + |
| 99 | +Use cases: |
| 100 | +- Abandoned convoys no longer relevant |
| 101 | +- Work completed outside tracked path |
| 102 | +- Force-closing stuck convoys |
| 103 | + |
| 104 | +### Convoy Owner/Requester |
| 105 | + |
| 106 | +Track who requested the convoy for targeted notifications: |
| 107 | + |
| 108 | +```bash |
| 109 | +gt convoy create "Feature X" gt-abc --owner mayor/ --notify overseer |
| 110 | +``` |
| 111 | + |
| 112 | +| Field | Purpose | |
| 113 | +|-------|---------| |
| 114 | +| `owner` | Who requested (gets completion notification) | |
| 115 | +| `notify` | Additional subscribers | |
| 116 | + |
| 117 | +If `owner` not specified, defaults to creator (from `created_by`). |
| 118 | + |
| 119 | +### Convoy States |
| 120 | + |
| 121 | +``` |
| 122 | +OPEN ──(all issues close)──► CLOSED |
| 123 | + │ │ |
| 124 | + │ ▼ |
| 125 | + │ (add issues) |
| 126 | + │ │ |
| 127 | + └─────────────────────────────┘ |
| 128 | + (auto-reopens) |
| 129 | +``` |
| 130 | + |
| 131 | +Adding issues to closed convoy reopens automatically. |
| 132 | + |
| 133 | +**New state for abandonment:** |
| 134 | + |
| 135 | +``` |
| 136 | +OPEN ──► CLOSED (completed) |
| 137 | + │ |
| 138 | + └────► ABANDONED (force-closed without completion) |
| 139 | +``` |
| 140 | + |
| 141 | +### Timeout/SLA (Future) |
| 142 | + |
| 143 | +Optional `due_at` field for convoy deadline: |
| 144 | + |
| 145 | +```bash |
| 146 | +gt convoy create "Sprint work" gt-abc --due="2026-01-15" |
| 147 | +``` |
| 148 | + |
| 149 | +Overdue convoys surface in `gt convoy stranded --overdue`. |
| 150 | + |
| 151 | +## Commands |
| 152 | + |
| 153 | +### New: `gt convoy close` |
| 154 | + |
| 155 | +```bash |
| 156 | +gt convoy close <convoy-id> [--reason=<reason>] [--notify=<agent>] |
| 157 | +``` |
| 158 | + |
| 159 | +- Closes convoy regardless of tracked issue status |
| 160 | +- Sets `close_reason` field |
| 161 | +- Sends notification to owner and subscribers |
| 162 | +- Idempotent - closing closed convoy is no-op |
| 163 | + |
| 164 | +### Enhanced: `gt convoy check` |
| 165 | + |
| 166 | +```bash |
| 167 | +# Check all convoys (current behavior) |
| 168 | +gt convoy check |
| 169 | + |
| 170 | +# Check specific convoy (new) |
| 171 | +gt convoy check <convoy-id> |
| 172 | + |
| 173 | +# Dry-run mode |
| 174 | +gt convoy check --dry-run |
| 175 | +``` |
| 176 | + |
| 177 | +### New: `gt convoy reopen` |
| 178 | + |
| 179 | +```bash |
| 180 | +gt convoy reopen <convoy-id> |
| 181 | +``` |
| 182 | + |
| 183 | +Explicit reopen for clarity (currently implicit via add). |
| 184 | + |
| 185 | +## Implementation Priority |
| 186 | + |
| 187 | +1. **P0: `gt convoy close`** - Desire path, escape hatch |
| 188 | +2. **P0: Event-driven check** - Daemon hook on issue close |
| 189 | +3. **P1: Redundant observers** - Witness/Refinery integration |
| 190 | +4. **P2: Owner field** - Targeted notifications |
| 191 | +5. **P3: Timeout/SLA** - Deadline tracking |
| 192 | + |
| 193 | +## Related |
| 194 | + |
| 195 | +- [convoy.md](../concepts/convoy.md) - Convoy concept and usage |
| 196 | +- [watchdog-chain.md](watchdog-chain.md) - Deacon patrol system |
| 197 | +- [mail-protocol.md](mail-protocol.md) - Notification delivery |
0 commit comments