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 --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 # 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 # 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 <