feat: Add mol-ready-work protomolecule (cherry-pick from polecat/immortan)
Adds autonomous backlog processing patrol molecule for crew workers.
The molecule scans PRs, GitHub issues, and beads; selects work using
an ROI heuristic; executes items; and loops until context is low.
Key features:
- Vapor phase (wisp) - ephemeral patrol cycles
- Scans 4 backlogs: PRs > untriaged > beads > triaged
- ROI-based selection with context awareness
- Per-type execution handlers (PR review, triage, implementation)
- Clean handoff protocol with digest squashing
Original commit: 20e2a13 by immortan
Issue: gt-tnca.1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
1430
.beads/issues.jsonl
1430
.beads/issues.jsonl
File diff suppressed because it is too large
Load Diff
@@ -23,6 +23,7 @@ func BuiltinMolecules() []BuiltinMolecule {
|
||||
WitnessPatrolMolecule(),
|
||||
CrewSessionMolecule(),
|
||||
PolecatSessionMolecule(),
|
||||
ReadyWorkMolecule(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1391,6 +1392,193 @@ Needs: execute`,
|
||||
}
|
||||
}
|
||||
|
||||
// ReadyWorkMolecule returns the ready-work molecule definition.
|
||||
// This is an autonomous backlog processing patrol for crew workers.
|
||||
// It's a vapor-phase molecule (wisp) that scans backlogs, selects work,
|
||||
// and processes items until context is low.
|
||||
func ReadyWorkMolecule() BuiltinMolecule {
|
||||
return BuiltinMolecule{
|
||||
ID: "mol-ready-work",
|
||||
Title: "Ready Work",
|
||||
Description: `Autonomous backlog processing patrol for crew workers.
|
||||
|
||||
**Phase**: vapor (wisp) - ephemeral patrol cycles
|
||||
**Squash**: after each work item or context threshold
|
||||
|
||||
This molecule enables crew workers to autonomously process backlog items
|
||||
using an ROI heuristic. It scans multiple backlogs, selects the highest-value
|
||||
achievable item, executes it, and loops until context is low.
|
||||
|
||||
## Variables
|
||||
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| backlog_priority | (see scan order) | Override backlog scan order |
|
||||
| context_threshold | 20 | Percentage at which to handoff |
|
||||
| max_items | unlimited | Maximum items to process per session |
|
||||
|
||||
## Step: orient
|
||||
Load context and check for interrupts.
|
||||
|
||||
` + "```" + `bash
|
||||
gt prime # Load Gas Town context
|
||||
bd sync --from-main # Fresh beads state
|
||||
` + "```" + `
|
||||
|
||||
Check for:
|
||||
- Mail with overseer instructions: ` + "`gt mail inbox`" + `
|
||||
- Predecessor handoff: Look for 🤝 HANDOFF messages
|
||||
- Current context state
|
||||
|
||||
If overseer mail directs specific work, attach that instead of autonomous scan.
|
||||
If handoff exists, resume from handoff state.
|
||||
|
||||
## Step: scan-backlogs
|
||||
Survey all backlogs in priority order.
|
||||
|
||||
Scan order (highest to lowest priority):
|
||||
1. ` + "`gh pr list --state open`" + ` - PRs need review/merge
|
||||
2. ` + "`gh issue list --state open --label untriaged`" + ` - Untriaged issues
|
||||
3. ` + "`bd ready`" + ` - Beads issues ready to work
|
||||
4. ` + "`gh issue list --state open --label triaged`" + ` - Triaged GitHub issues
|
||||
|
||||
For each backlog, capture:
|
||||
- Total count of items
|
||||
- Top 3-5 candidates with brief descriptions
|
||||
- Estimated size category (small/medium/large)
|
||||
|
||||
` + "```" + `bash
|
||||
# Example scan
|
||||
echo "=== PRs ===" && gh pr list --state open --limit 10
|
||||
echo "=== Untriaged ===" && gh issue list --state open --label untriaged --limit 10
|
||||
echo "=== Beads Ready ===" && bd ready
|
||||
echo "=== Triaged ===" && gh issue list --state open --label triaged --limit 10
|
||||
` + "```" + `
|
||||
|
||||
If all backlogs empty: exit patrol (nothing to do).
|
||||
Needs: orient
|
||||
|
||||
## Step: select-work
|
||||
Apply ROI heuristic to select best work item.
|
||||
|
||||
**ROI Formula**: Impact / Effort, constrained by remaining context
|
||||
|
||||
Evaluation criteria:
|
||||
1. **Estimate size** - Tokens needed (small=1k, medium=5k, large=20k+)
|
||||
2. **Check context capacity** - Can this item fit in remaining context?
|
||||
3. **Weight by impact**:
|
||||
- PRs: High (blocking others) → weight 3x
|
||||
- Untriaged: Medium (needs triage) → weight 2x
|
||||
- Beads ready: Medium (concrete work) → weight 2x
|
||||
- Triaged GH: Lower (already processed) → weight 1x
|
||||
4. **Adjust by priority** - P0/P1 issues get 2x multiplier
|
||||
|
||||
Selection algorithm:
|
||||
1. Filter to items that fit in remaining context
|
||||
2. Score each: (impact_weight × priority_multiplier) / estimated_effort
|
||||
3. Select highest scoring item
|
||||
4. If tie: prefer PRs > untriaged > beads > triaged
|
||||
|
||||
If no achievable items (all too large): goto handoff step.
|
||||
Record selection rationale for audit.
|
||||
Needs: scan-backlogs
|
||||
|
||||
## Step: execute-work
|
||||
Work the selected item based on its type.
|
||||
|
||||
**For PRs (gh pr)**:
|
||||
- Review the changes
|
||||
- If good: approve and merge
|
||||
- If issues: request changes with specific feedback
|
||||
- Close or comment as appropriate
|
||||
|
||||
**For untriaged issues (gh issue, no label)**:
|
||||
- Read and understand the issue
|
||||
- Add appropriate labels (bug, feature, enhancement, etc.)
|
||||
- Set priority if determinable
|
||||
- Convert to beads if actionable: ` + "`bd create --title=\"...\" --type=...`" + `
|
||||
- Close if duplicate/invalid/wontfix
|
||||
|
||||
**For beads ready (bd)**:
|
||||
- Claim: ` + "`bd update <id> --status=in_progress`" + `
|
||||
- Implement the fix/feature
|
||||
- Test changes
|
||||
- Commit and push
|
||||
- Close: ` + "`bd close <id>`" + `
|
||||
|
||||
**For triaged GitHub issues**:
|
||||
- Implement the fix/feature
|
||||
- Create PR or push directly
|
||||
- Link to issue: ` + "`Fixes #<num>`" + `
|
||||
- Close issue when merged
|
||||
|
||||
Commit regularly. Push changes. Update issue state.
|
||||
Needs: select-work
|
||||
|
||||
## Step: check-context
|
||||
Assess context state after completing work item.
|
||||
|
||||
` + "```" + `bash
|
||||
# Estimate context usage (if tool available)
|
||||
gt context --usage
|
||||
` + "```" + `
|
||||
|
||||
Decision matrix:
|
||||
| Context Used | Action |
|
||||
|--------------|--------|
|
||||
| < 60% | Loop to scan-backlogs (continue working) |
|
||||
| 60-80% | One more small item, then handoff |
|
||||
| > 80% | Goto handoff immediately |
|
||||
|
||||
Also check:
|
||||
- Items processed this session vs max_items limit
|
||||
- Time elapsed (soft limit for long sessions)
|
||||
- Any new high-priority mail that should interrupt
|
||||
|
||||
If continuing: return to scan-backlogs step.
|
||||
Needs: execute-work
|
||||
|
||||
## Step: handoff
|
||||
Prepare for session transition.
|
||||
|
||||
1. **Summarize work completed**:
|
||||
- Items processed (count and types)
|
||||
- PRs reviewed/merged
|
||||
- Issues triaged
|
||||
- Beads closed
|
||||
- Any issues filed
|
||||
|
||||
2. **Note in-progress items**:
|
||||
- If interrupted mid-work, record state
|
||||
- File continuation issue if needed
|
||||
|
||||
3. **Send handoff mail**:
|
||||
` + "```" + `bash
|
||||
gt mail send <self-addr> -s "🤝 HANDOFF: Ready-work patrol" -m "
|
||||
## Completed This Session
|
||||
- <item counts and summaries>
|
||||
|
||||
## Backlog State
|
||||
- PRs remaining: <count>
|
||||
- Untriaged: <count>
|
||||
- Beads ready: <count>
|
||||
- Triaged: <count>
|
||||
|
||||
## Notes
|
||||
<any context for successor>
|
||||
"
|
||||
` + "```" + `
|
||||
|
||||
4. **Squash wisp to digest**:
|
||||
` + "```" + `bash
|
||||
bd mol squash <wisp-id> --summary="Processed N items: X PRs, Y issues, Z beads"
|
||||
` + "```" + `
|
||||
|
||||
5. **Exit for fresh session** - Successor picks up from handoff.
|
||||
Needs: check-context`,
|
||||
}
|
||||
}
|
||||
|
||||
// SeedBuiltinMolecules creates all built-in molecules in the beads database.
|
||||
// It skips molecules that already exist (by title match).
|
||||
// Returns the number of molecules created.
|
||||
|
||||
@@ -5,8 +5,8 @@ import "testing"
|
||||
func TestBuiltinMolecules(t *testing.T) {
|
||||
molecules := BuiltinMolecules()
|
||||
|
||||
if len(molecules) != 12 {
|
||||
t.Errorf("expected 12 built-in molecules, got %d", len(molecules))
|
||||
if len(molecules) != 13 {
|
||||
t.Errorf("expected 13 built-in molecules, got %d", len(molecules))
|
||||
}
|
||||
|
||||
// Verify each molecule can be parsed and validated
|
||||
|
||||
Reference in New Issue
Block a user