260 lines
6.2 KiB
TOML
260 lines
6.2 KiB
TOML
description = """
|
|
Feed stranded convoys by dispatching ready work to available polecats.
|
|
|
|
Dogs execute this formula when the Deacon detects a stranded convoy. A convoy
|
|
is stranded when it has ready issues (open, unblocked, no assignee) but no
|
|
workers are processing them.
|
|
|
|
## Dog Contract
|
|
|
|
This is infrastructure work. You:
|
|
1. Receive convoy ID via variable
|
|
2. Load convoy and find ready issues
|
|
3. Check idle polecat capacity across rigs
|
|
4. Dispatch min(ready_issues, idle_polecats) using gt sling
|
|
5. Report actions taken
|
|
6. Return to kennel
|
|
|
|
## Variables
|
|
|
|
| Variable | Source | Description |
|
|
|----------|--------|-------------|
|
|
| convoy | --var | The stranded convoy ID to feed |
|
|
|
|
## Single Pass Design
|
|
|
|
Dog doesn't babysit or wait for completion. The workflow is:
|
|
1. Find ready issues in convoy
|
|
2. Dispatch each to an available polecat
|
|
3. Exit immediately
|
|
|
|
If convoy is still stranded next Deacon patrol cycle, another dog will be
|
|
dispatched. This keeps the system stateless and batch-oriented.
|
|
|
|
## Failure Modes
|
|
|
|
| Situation | Action |
|
|
|-----------|--------|
|
|
| Convoy not found | Exit with error, notify Deacon |
|
|
| No ready issues | Exit success (false positive, convoy is fine) |
|
|
| No idle polecats | Exit success, note in report (will retry next cycle) |
|
|
| Sling fails | Continue with remaining issues, note failures |"""
|
|
formula = "mol-convoy-feed"
|
|
version = 1
|
|
|
|
[squash]
|
|
trigger = "on_complete"
|
|
template_type = "work"
|
|
include_metrics = true
|
|
|
|
[[steps]]
|
|
id = "load-convoy"
|
|
title = "Load convoy and identify ready issues"
|
|
description = """
|
|
Load the convoy and find issues ready for dispatch.
|
|
|
|
**1. Check assignment:**
|
|
```bash
|
|
gt hook # Shows convoy in hook_bead or vars
|
|
```
|
|
|
|
**2. Load convoy details:**
|
|
```bash
|
|
gt convoy status {{convoy}} --json
|
|
```
|
|
|
|
**3. Identify ready issues:**
|
|
|
|
For each tracked issue in the convoy:
|
|
```bash
|
|
bd show <issue-id> --json
|
|
```
|
|
|
|
An issue is "ready" if ALL of these are true:
|
|
- status = "open" (NOT in_progress, closed, or hooked)
|
|
- not in blocked list (check: bd blocked --json)
|
|
- assignee is empty OR assignee session is dead
|
|
|
|
Check blocked status:
|
|
```bash
|
|
bd blocked --json
|
|
# If issue ID appears here, it's blocked (skip it)
|
|
```
|
|
|
|
Check assignee session if set:
|
|
```bash
|
|
# If assignee like "gastown/polecats/nux"
|
|
tmux has-session -t gt-gastown-polecat-nux 2>/dev/null && echo "alive" || echo "dead"
|
|
```
|
|
|
|
**4. Build ready list:**
|
|
Collect all ready issues with their metadata:
|
|
- Issue ID
|
|
- Title
|
|
- Priority
|
|
- Rig (extracted from prefix)
|
|
|
|
Sort by priority (P0 first) for dispatch order.
|
|
|
|
**Exit criteria:** Ready issues identified and prioritized."""
|
|
|
|
[[steps]]
|
|
id = "check-capacity"
|
|
title = "Check polecat capacity across rigs"
|
|
needs = ["load-convoy"]
|
|
description = """
|
|
Determine how many polecats are available for dispatch.
|
|
|
|
**1. For each rig that has ready issues:**
|
|
```bash
|
|
gt polecats <rig>
|
|
# Shows polecat status: idle, working, etc.
|
|
```
|
|
|
|
**2. Count available capacity:**
|
|
Available polecats are those that:
|
|
- Exist in the rig's polecat pool
|
|
- Currently idle (no hooked work)
|
|
- Session is running
|
|
|
|
**3. Calculate dispatch count:**
|
|
```
|
|
dispatch_count = min(ready_issues, available_polecats)
|
|
```
|
|
|
|
If dispatch_count = 0:
|
|
- Log: "No capacity available, will retry next cycle"
|
|
- Proceed to report step (no dispatches to make)
|
|
|
|
**4. Match issues to rigs:**
|
|
For each ready issue, determine target rig from issue prefix:
|
|
- gt-* issues → gastown rig
|
|
- bd-* issues → beads rig
|
|
- etc.
|
|
|
|
**Exit criteria:** Dispatch plan created with issue→rig mappings."""
|
|
|
|
[[steps]]
|
|
id = "dispatch-work"
|
|
title = "Dispatch ready issues to polecats"
|
|
needs = ["check-capacity"]
|
|
description = """
|
|
Sling each ready issue to an available polecat.
|
|
|
|
**For each issue in dispatch plan:**
|
|
|
|
```bash
|
|
# Dispatch issue to the appropriate rig
|
|
# This spawns a fresh polecat or assigns to idle one
|
|
gt sling <issue-id> <rig>
|
|
|
|
# Example:
|
|
gt sling gt-abc123 gastown
|
|
gt sling bd-xyz789 beads
|
|
```
|
|
|
|
**Track results:**
|
|
For each dispatch:
|
|
- Success: Note issue ID, target rig, polecat assigned
|
|
- Failure: Note issue ID, error message
|
|
|
|
**Important notes:**
|
|
- `gt sling` handles polecat selection automatically
|
|
- It will spawn a new polecat if none available
|
|
- The polecat gets the issue hooked and starts immediately
|
|
- Don't wait for polecat to complete - fire and forget
|
|
|
|
**If sling fails:**
|
|
- Continue with remaining issues
|
|
- Note the failure for the report
|
|
- Don't escalate individual failures (will retry next cycle)
|
|
|
|
**Exit criteria:** All dispatchable issues have been slung."""
|
|
|
|
[[steps]]
|
|
id = "report-results"
|
|
title = "Generate and send feeding report"
|
|
needs = ["dispatch-work"]
|
|
description = """
|
|
Create summary report of convoy feeding actions.
|
|
|
|
**1. Generate report:**
|
|
```markdown
|
|
## Convoy Feed Report: {{convoy}}
|
|
|
|
**Ready issues found**: {{ready_count}}
|
|
**Polecats available**: {{available_count}}
|
|
**Issues dispatched**: {{dispatch_count}}
|
|
|
|
### Dispatched Work
|
|
{{#each dispatched}}
|
|
- {{issue_id}}: {{title}} → {{rig}}/{{polecat}}
|
|
{{/each}}
|
|
|
|
### Skipped (no capacity)
|
|
{{#if skipped}}
|
|
{{#each skipped}}
|
|
- {{issue_id}}: {{title}} (will retry next cycle)
|
|
{{/each}}
|
|
{{else}}
|
|
(none)
|
|
{{/if}}
|
|
|
|
### Errors
|
|
{{#if errors}}
|
|
{{#each errors}}
|
|
- {{issue_id}}: {{error}}
|
|
{{/each}}
|
|
{{else}}
|
|
(none)
|
|
{{/if}}
|
|
```
|
|
|
|
**2. Send to Deacon:**
|
|
```bash
|
|
gt mail send deacon/ -s "Convoy fed: {{convoy}}" -m "$(cat <<EOF
|
|
Convoy {{convoy}} feeding complete.
|
|
|
|
Dispatched: {{dispatch_count}}/{{ready_count}} issues
|
|
{{#if errors}}Errors: {{error_count}}{{/if}}
|
|
|
|
{{report_summary}}
|
|
EOF
|
|
)"
|
|
```
|
|
|
|
**3. Update convoy (optional):**
|
|
If convoy has a notify field, could add a note about feeding activity.
|
|
Not required - the dispatch tracking handles visibility.
|
|
|
|
**Exit criteria:** Report generated and sent."""
|
|
|
|
[[steps]]
|
|
id = "return-to-kennel"
|
|
title = "Signal completion and return to kennel"
|
|
needs = ["report-results"]
|
|
description = """
|
|
Signal work complete and return to available pool.
|
|
|
|
**1. Signal completion to Deacon:**
|
|
```bash
|
|
gt mail send deacon/ -s "DOG_DONE $(hostname)" -m "Task: convoy-feed
|
|
Convoy: {{convoy}}
|
|
Ready: {{ready_count}}
|
|
Dispatched: {{dispatch_count}}
|
|
Status: COMPLETE
|
|
|
|
Ready for next assignment."
|
|
```
|
|
|
|
**2. Return to kennel:**
|
|
Dog returns to available state in the pool. Deacon will assign next work
|
|
or retire the dog if pool is oversized.
|
|
|
|
**Exit criteria:** Deacon notified, dog ready for next work or retirement."""
|
|
|
|
[vars]
|
|
[vars.convoy]
|
|
description = "The convoy ID to feed"
|
|
required = true
|