The monolithic handle-dirty-state step handled three distinct concerns. Split into focused steps for clarity and maintainability: 1. handle-uncommitted: Handle staged/unstaged changes - Commit if ready (WIP) - Stash if experimental/incomplete 2. handle-untracked: Handle untracked files - Decision matrix by file type - Actions: gitignore, commit, or delete - Warns against auto-delete 3. handle-stashes: Review and clean stash entries - Age-based decision matrix - Drop stale entries (>1 week old) - Caution about index shifting Updated cleanup-worktrees to depend on handle-stashes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
554 lines
13 KiB
TOML
554 lines
13 KiB
TOML
description = """
|
|
Workspace synchronization molecule for batch prep.
|
|
|
|
This molecule prepares an agent's workspace for a new batch of work. It syncs git
|
|
and beads state, cleans up cruft, verifies the baseline is healthy, and reports
|
|
readiness. Designed to be broadcast to all agents when preparing for coordinated
|
|
work.
|
|
|
|
## When to Use
|
|
|
|
- Before major batch assignments
|
|
- After extended idle periods
|
|
- When repo baseline has diverged significantly
|
|
- Proactive cleanup between work sessions
|
|
|
|
## Conflict Resolution Philosophy
|
|
|
|
**Preserve and re-land, not discard.**
|
|
|
|
When git pull/rebase hits conflicts, the agent should:
|
|
1. Assess if the conflicting work is still valuable
|
|
2. If valuable: re-envision against new baseline, file a bead for re-implementation
|
|
3. If obsolete (e.g., touches deleted system): discard with a note
|
|
4. If unclear: escalate to human/mayor
|
|
|
|
Polecats can file a bead and delegate. Refinery must resolve inline.
|
|
|
|
## Variables
|
|
|
|
| Variable | Source | Description |
|
|
|----------|--------|-------------|
|
|
| role | auto-detected | Agent role (crew/polecat/refinery/witness) |
|
|
| build_command | config or default | Build command (default: `go build ./...`) |
|
|
| test_command | config or default | Test command (default: `go test ./...`) |
|
|
|
|
## Failure Modes
|
|
|
|
| Situation | Action |
|
|
|-----------|--------|
|
|
| Rebase conflict | Preserve work via bead, complete sync on clean state |
|
|
| Uncommitted work | Stash or commit, then sync |
|
|
| Untracked files | Warn, let agent decide (keep/delete/gitignore) |
|
|
| bd doctor errors | Report findings, agent triages |
|
|
| Test failures | File bead if not already tracked, don't block sync |
|
|
| Build failure | Must be resolved before marking sync complete |"""
|
|
formula = "mol-sync-workspace"
|
|
version = 1
|
|
|
|
[[steps]]
|
|
id = "assess-state"
|
|
title = "Assess current workspace state"
|
|
description = """
|
|
Capture current state before any changes.
|
|
|
|
**0. Prime context (critical for fresh sessions):**
|
|
```bash
|
|
gt prime # Load gt/mol context
|
|
bd prime # Load beads context
|
|
```
|
|
These ensure the agent has full system context, especially after session
|
|
start, compaction, or context clear.
|
|
|
|
**1. Check git status:**
|
|
```bash
|
|
git status --porcelain
|
|
git stash list
|
|
git branch --show-current
|
|
```
|
|
|
|
**2. Check beads state:**
|
|
```bash
|
|
bd sync --status
|
|
```
|
|
|
|
**3. Document starting state:**
|
|
- Branch name
|
|
- Uncommitted changes (staged/unstaged)
|
|
- Untracked files (list them)
|
|
- Stash entries
|
|
- Beads sync status
|
|
|
|
This information guides decisions in subsequent steps.
|
|
|
|
**Exit criteria:** Context primed, starting state documented."""
|
|
|
|
[[steps]]
|
|
id = "handle-uncommitted"
|
|
title = "Handle uncommitted changes"
|
|
needs = ["assess-state"]
|
|
description = """
|
|
Handle staged and unstaged changes before syncing.
|
|
|
|
**Check for uncommitted changes:**
|
|
```bash
|
|
git status --porcelain | grep -v '^??' # Exclude untracked
|
|
```
|
|
|
|
**If no uncommitted changes:** Skip to next step.
|
|
|
|
**If uncommitted changes exist:**
|
|
|
|
**Option A - Commit if ready:**
|
|
Changes are complete enough to commit (even as WIP):
|
|
```bash
|
|
git add -A && git commit -m "WIP: <description>"
|
|
```
|
|
|
|
Use this when:
|
|
- Changes are coherent (one logical unit)
|
|
- You want to preserve them through sync
|
|
- They're ready for potential rebase
|
|
|
|
**Option B - Stash if not ready:**
|
|
Changes are experimental or incomplete:
|
|
```bash
|
|
git stash push -m "pre-sync stash $(date +%Y%m%d-%H%M%S)"
|
|
```
|
|
|
|
Use this when:
|
|
- Changes are scattered/incomplete
|
|
- You're unsure if you want to keep them
|
|
- You need to temporarily set them aside
|
|
|
|
**Exit criteria:** No staged or unstaged changes (git status clean except untracked)."""
|
|
|
|
[[steps]]
|
|
id = "handle-untracked"
|
|
title = "Handle untracked files"
|
|
needs = ["handle-uncommitted"]
|
|
description = """
|
|
Review and handle untracked files before syncing.
|
|
|
|
**List untracked files:**
|
|
```bash
|
|
git status --porcelain | grep '^??'
|
|
```
|
|
|
|
**If no untracked files:** Skip to next step.
|
|
|
|
**For each untracked file, decide:**
|
|
|
|
| File Type | Action |
|
|
|-----------|--------|
|
|
| Build artifacts (.exe, .o, *.test) | Add to .gitignore |
|
|
| IDE/editor files (.idea/, .vscode/) | Add to .gitignore |
|
|
| Log files (*.log) | Delete or gitignore |
|
|
| WIP code files | Commit or delete |
|
|
| Config with secrets | Add to .gitignore, WARN |
|
|
| Unknown | Ask before deleting |
|
|
|
|
**Actions:**
|
|
|
|
- **Keep (gitignore):**
|
|
```bash
|
|
echo "<pattern>" >> .gitignore
|
|
```
|
|
|
|
- **Keep (commit):**
|
|
```bash
|
|
git add <file>
|
|
git commit -m "add: <file description>"
|
|
```
|
|
|
|
- **Delete:**
|
|
```bash
|
|
rm <file>
|
|
```
|
|
|
|
**WARN the agent**: Untracked files may contain valuable WIP.
|
|
Never auto-delete without review. When in doubt, gitignore.
|
|
|
|
**Exit criteria:** All untracked files handled (committed, gitignored, or deleted)."""
|
|
|
|
[[steps]]
|
|
id = "handle-stashes"
|
|
title = "Review and clean stash entries"
|
|
needs = ["handle-untracked"]
|
|
description = """
|
|
Review stash entries and clean up old ones.
|
|
|
|
**List stashes:**
|
|
```bash
|
|
git stash list
|
|
```
|
|
|
|
**If no stashes:** Skip to next step.
|
|
|
|
**For each stash entry:**
|
|
|
|
1. **Check age:**
|
|
```bash
|
|
git log -1 --format="%ar" stash@{N} # "2 weeks ago"
|
|
```
|
|
|
|
2. **Preview contents:**
|
|
```bash
|
|
git stash show stash@{N} # Files changed
|
|
git stash show -p stash@{N} # Full diff
|
|
```
|
|
|
|
**Decision matrix:**
|
|
|
|
| Age | Contents | Action |
|
|
|-----|----------|--------|
|
|
| < 1 week | Valuable WIP | Keep or apply |
|
|
| < 1 week | Obsolete | Drop |
|
|
| > 1 week | Any | Likely stale, consider dropping |
|
|
| > 1 month | Any | Almost certainly stale, drop |
|
|
|
|
**Actions:**
|
|
|
|
- **Keep:** Leave in stash list (no action)
|
|
- **Apply:** `git stash apply stash@{N}` then handle as uncommitted
|
|
- **Drop:** `git stash drop stash@{N}`
|
|
|
|
**Caution:** Stash indices shift when you drop! Drop from highest index first:
|
|
```bash
|
|
git stash drop stash@{2} # Drop this first
|
|
git stash drop stash@{1} # Then this
|
|
git stash drop stash@{0} # Then this
|
|
```
|
|
|
|
**Exit criteria:** Stash reviewed, old/stale entries dropped."""
|
|
|
|
[[steps]]
|
|
id = "sync-git"
|
|
title = "Sync with git remote"
|
|
needs = ["cleanup-worktrees"]
|
|
description = """
|
|
Fetch and rebase onto current main.
|
|
|
|
**1. Fetch latest:**
|
|
```bash
|
|
git fetch origin
|
|
```
|
|
|
|
**2. Check divergence:**
|
|
```bash
|
|
git log --oneline HEAD..origin/main | head -5 # What's new on main
|
|
git log --oneline origin/main..HEAD | head -5 # What we have locally
|
|
```
|
|
|
|
**3. Rebase onto main:**
|
|
```bash
|
|
git pull --rebase origin main
|
|
```
|
|
|
|
**If rebase succeeds:** Continue to next step.
|
|
|
|
**If rebase conflicts:**
|
|
|
|
The Preservation Protocol:
|
|
1. **Assess the conflicting work:**
|
|
- Is it still valuable against new baseline?
|
|
- Is the conflicting area still relevant (not deleted/refactored)?
|
|
|
|
2. **If work is valuable:**
|
|
```bash
|
|
git rebase --abort
|
|
# Create a bead capturing the work
|
|
bd create --title "Re-land: <description>" --type task --priority 2
|
|
# Note the changes needed in the bead description
|
|
# Reset to clean state
|
|
git reset --hard origin/main
|
|
```
|
|
|
|
3. **If work is obsolete:**
|
|
```bash
|
|
git rebase --abort
|
|
git reset --hard origin/main
|
|
# Note why it was discarded
|
|
```
|
|
|
|
4. **If unclear:**
|
|
- Escalate to human/mayor
|
|
- Document the conflict
|
|
- Proceed with sync on clean baseline
|
|
|
|
**Refinery-specific conflict resolution:**
|
|
|
|
Unlike polecats who can file a bead and delegate, the Refinery MUST resolve
|
|
conflicts inline. The Refinery processes the merge queue - if it can't resolve
|
|
a conflict, the queue backs up and polecats' completed work never lands.
|
|
|
|
**Refinery conflict protocol:**
|
|
|
|
1. **Analyze the conflict:**
|
|
```bash
|
|
git status # See conflicted files
|
|
git diff # Examine conflict markers
|
|
```
|
|
|
|
2. **Trivial conflicts (resolve immediately):**
|
|
- Import ordering changes
|
|
- Whitespace or formatting
|
|
- Non-overlapping additions in same file
|
|
- Version bumps or changelog entries
|
|
|
|
Resolution:
|
|
```bash
|
|
# Edit conflicted files to resolve
|
|
git add <resolved-files>
|
|
git rebase --continue
|
|
```
|
|
|
|
3. **Semantic conflicts (assess carefully):**
|
|
- Both sides modified same function
|
|
- Deleted code that the other side modified
|
|
- Structural changes (renamed files, moved code)
|
|
|
|
If you can understand both intents and merge correctly:
|
|
```bash
|
|
# Carefully merge the changes, preserving both intents
|
|
git add <resolved-files>
|
|
git rebase --continue
|
|
```
|
|
|
|
4. **Complex conflicts (abort and notify polecat):**
|
|
- Conflicting business logic changes
|
|
- Unclear which version is correct
|
|
- Risk of subtle bugs from incorrect merge
|
|
|
|
```bash
|
|
git rebase --abort
|
|
gt mail send {{ rig }}/polecats/<worker> -s "Rebase needed" \
|
|
-m "Your branch conflicts with main in <files>. Please rebase and resubmit via gt done."
|
|
# Skip this branch, continue with queue
|
|
```
|
|
|
|
**The Refinery judgment call:** When in doubt, abort and notify rather than
|
|
risk merging incorrectly. A resubmitted branch is better than a broken main.
|
|
|
|
**Exit criteria:** Local branch matches or is cleanly ahead of origin/main."""
|
|
|
|
[[steps]]
|
|
id = "sync-beads"
|
|
title = "Sync beads state"
|
|
needs = ["sync-git"]
|
|
description = """
|
|
Sync the beads database with remote.
|
|
|
|
```bash
|
|
bd sync
|
|
```
|
|
|
|
**If conflicts:**
|
|
Beads uses JSONL append-only format, so true conflicts are rare.
|
|
If they occur:
|
|
```bash
|
|
bd sync --status # Diagnose
|
|
```
|
|
|
|
Likely causes:
|
|
- Two agents edited same bead simultaneously
|
|
- Corrupted beads-sync branch
|
|
|
|
Resolution:
|
|
```bash
|
|
# Try pulling fresh
|
|
git fetch origin beads-sync
|
|
bd sync
|
|
```
|
|
|
|
If still failing, escalate to mayor.
|
|
|
|
**Exit criteria:** Beads synced successfully."""
|
|
|
|
[[steps]]
|
|
id = "run-doctor"
|
|
title = "Run beads health check"
|
|
needs = ["sync-beads"]
|
|
description = """
|
|
Check for beads system issues.
|
|
|
|
```bash
|
|
bd doctor
|
|
```
|
|
|
|
**Triage findings:**
|
|
|
|
| Finding | Action |
|
|
|---------|--------|
|
|
| Orphaned issues (committed but not closed) | Review and close if complete |
|
|
| Missing dependencies | Fix with `bd dep add` |
|
|
| Circular dependencies | Resolve or escalate |
|
|
| Stale in_progress | Check if still active, update status |
|
|
| Route misconfigurations | Fix routes.jsonl |
|
|
|
|
**For each issue found:**
|
|
- Quick fix (<5 min): Fix now
|
|
- Medium fix: File a bead
|
|
- Unclear: Note for human review
|
|
|
|
**Exit criteria:** Doctor findings triaged (not necessarily all fixed)."""
|
|
|
|
[[steps]]
|
|
id = "verify-build"
|
|
title = "Verify project builds"
|
|
needs = ["run-doctor"]
|
|
description = """
|
|
Ensure the codebase compiles.
|
|
|
|
```bash
|
|
{{ build_command }}
|
|
# Default: go build ./...
|
|
# Configure via build_command variable for non-Go projects
|
|
```
|
|
|
|
**If build succeeds:** Continue to next step.
|
|
|
|
**If build fails:**
|
|
|
|
This is a blocking issue. Options:
|
|
|
|
1. **Quick fix (<15 min):** Fix it now
|
|
```bash
|
|
# Fix the issue
|
|
git add <files>
|
|
git commit -m "fix: build failure from sync"
|
|
git push
|
|
```
|
|
|
|
2. **Non-trivial fix:** File and escalate
|
|
```bash
|
|
bd create --title "Build broken on main" --type bug --priority 0
|
|
gt mail send --human -s "ALERT: Main doesn't build" -m "Details..."
|
|
```
|
|
Cannot mark sync complete with broken build.
|
|
|
|
**Exit criteria:** Project builds successfully."""
|
|
|
|
[[steps]]
|
|
id = "run-tests"
|
|
title = "Run test suite"
|
|
needs = ["verify-build"]
|
|
description = """
|
|
Verify tests pass on current baseline.
|
|
|
|
```bash
|
|
{{ test_command }}
|
|
# Default: go test ./...
|
|
# Configure via test_command variable for non-Go projects
|
|
```
|
|
|
|
**If tests pass:** Continue to next step.
|
|
|
|
**If tests fail:**
|
|
|
|
Unlike build failures, test failures don't block sync completion.
|
|
However, they must be tracked.
|
|
|
|
1. **Check if already tracked:**
|
|
```bash
|
|
bd list --type=bug --status=open | grep -i test
|
|
```
|
|
|
|
2. **If not tracked, file a bead:**
|
|
```bash
|
|
bd create --title "Test failure: <test name>" --type bug --priority 1
|
|
```
|
|
|
|
3. **Report in summary:**
|
|
Note which tests are failing so batch assignment accounts for it.
|
|
|
|
**Exit criteria:** Test results documented, failures tracked in beads."""
|
|
|
|
[[steps]]
|
|
id = "cleanup-worktrees"
|
|
title = "Clean up stale worktrees"
|
|
needs = ["handle-stashes"]
|
|
description = """
|
|
Remove orphaned worktrees from cross-rig work.
|
|
|
|
**1. List worktrees:**
|
|
```bash
|
|
git worktree list
|
|
```
|
|
|
|
**2. Identify stale worktrees:**
|
|
- Worktrees for branches that no longer exist on remote
|
|
- Worktrees older than 1 week without recent commits
|
|
- Worktrees for completed/merged work
|
|
|
|
**3. Remove stale worktrees:**
|
|
```bash
|
|
git worktree remove <path>
|
|
# Or force if needed:
|
|
git worktree remove --force <path>
|
|
```
|
|
|
|
**4. Prune worktree metadata:**
|
|
```bash
|
|
git worktree prune
|
|
```
|
|
|
|
**CAUTION:** Don't remove worktrees for active cross-rig work.
|
|
Check with `gt worktree list` if available.
|
|
|
|
**Exit criteria:** Stale worktrees removed."""
|
|
|
|
[[steps]]
|
|
id = "generate-report"
|
|
title = "Generate sync report"
|
|
needs = ["run-tests"]
|
|
description = """
|
|
Summarize sync results for broadcast response.
|
|
|
|
**Report format:**
|
|
```
|
|
SYNC COMPLETE: <agent-name>
|
|
|
|
Git:
|
|
- Branch: <branch>
|
|
- Commits behind main: 0
|
|
- Commits ahead: <n>
|
|
- Conflicts resolved: <y/n, details if yes>
|
|
|
|
Beads:
|
|
- Sync status: OK
|
|
- Doctor findings: <count> (fixed: <n>, filed: <n>, deferred: <n>)
|
|
|
|
Build: PASS
|
|
Tests: PASS | FAIL (<count> failures, tracked in <bead-ids>)
|
|
|
|
Worktrees cleaned: <count>
|
|
|
|
Ready for work: YES | NO (<reason>)
|
|
```
|
|
|
|
**Exit criteria:** Report generated."""
|
|
|
|
[[steps]]
|
|
id = "signal-ready"
|
|
title = "Signal readiness"
|
|
needs = ["generate-report"]
|
|
description = """
|
|
Report sync completion to coordinator (if broadcast) or to self (if autonomous).
|
|
|
|
**If responding to broadcast:**
|
|
```bash
|
|
gt mail send <coordinator> -s "SYNC_COMPLETE $(hostname)" -m "<report>"
|
|
```
|
|
|
|
**If autonomous sync:**
|
|
- Log the report
|
|
- Update any relevant agent status
|
|
|
|
**If sync failed (couldn't build):**
|
|
```bash
|
|
gt mail send --human -s "SYNC_FAILED $(hostname)" -m "<report with failure details>"
|
|
```
|
|
|
|
**Exit criteria:** Readiness signaled, molecule complete."""
|