From 60556534da2ebbb2f1298e22f22148bded9fa27e Mon Sep 17 00:00:00 2001 From: Steve Yegge Date: Thu, 25 Dec 2025 21:59:43 -0800 Subject: [PATCH] Add TOML versions of formulas (gt-xmyha) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Converted all .formula.json files to .formula.toml using bd formula convert. TOML provides better ergonomics: - Multi-line strings without \n escaping - Human-readable diffs - Comments allowed Original JSON files retained for backwards compatibility. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../formulas/mol-deacon-patrol.formula.toml | 241 ++++++++++++++++++ .beads/formulas/mol-gastown-boot.formula.toml | 169 ++++++++++++ .beads/formulas/mol-polecat-arm.formula.toml | 145 +++++++++++ .../formulas/mol-polecat-lease.formula.toml | 70 +++++ .beads/formulas/mol-polecat-work.formula.toml | 62 +++++ .../formulas/mol-refinery-patrol.formula.toml | 166 ++++++++++++ .../formulas/mol-witness-patrol.formula.toml | 212 +++++++++++++++ .beads/formulas/rule-of-five.formula.toml | 33 +++ .beads/formulas/security-audit.formula.toml | 38 +++ .beads/formulas/shiny-enterprise.formula.toml | 11 + .beads/formulas/shiny-secure.formula.toml | 8 + .beads/formulas/shiny.formula.toml | 40 +++ .beads/formulas/towers-of-hanoi.formula.toml | 80 ++++++ 13 files changed, 1275 insertions(+) create mode 100644 .beads/formulas/mol-deacon-patrol.formula.toml create mode 100644 .beads/formulas/mol-gastown-boot.formula.toml create mode 100644 .beads/formulas/mol-polecat-arm.formula.toml create mode 100644 .beads/formulas/mol-polecat-lease.formula.toml create mode 100644 .beads/formulas/mol-polecat-work.formula.toml create mode 100644 .beads/formulas/mol-refinery-patrol.formula.toml create mode 100644 .beads/formulas/mol-witness-patrol.formula.toml create mode 100644 .beads/formulas/rule-of-five.formula.toml create mode 100644 .beads/formulas/security-audit.formula.toml create mode 100644 .beads/formulas/shiny-enterprise.formula.toml create mode 100644 .beads/formulas/shiny-secure.formula.toml create mode 100644 .beads/formulas/shiny.formula.toml create mode 100644 .beads/formulas/towers-of-hanoi.formula.toml diff --git a/.beads/formulas/mol-deacon-patrol.formula.toml b/.beads/formulas/mol-deacon-patrol.formula.toml new file mode 100644 index 00000000..3711e634 --- /dev/null +++ b/.beads/formulas/mol-deacon-patrol.formula.toml @@ -0,0 +1,241 @@ +description = """ +Mayor's daemon patrol loop. + +The Deacon is the Mayor's background process that runs continuously, handling callbacks, monitoring rig health, and performing cleanup. Each patrol cycle runs these steps in sequence, then loops or exits.""" +formula = "mol-deacon-patrol" +version = 1 + +[[steps]] +description = """ +Handle callbacks from agents. + +Check the Mayor's inbox for messages from: +- Witnesses reporting polecat status +- Refineries reporting merge results +- Polecats requesting help or escalation +- External triggers (webhooks, timers) + +```bash +gt mail inbox +# For each message: +gt mail read +# Handle based on message type +``` + +Callbacks may spawn new polecats, update issue state, or trigger other actions.""" +id = "inbox-check" +title = "Handle callbacks from agents" + +[[steps]] +description = """ +Nudge newly spawned polecats that are ready for input. + +When polecats are spawned, their Claude session takes 10-20 seconds to initialize. The spawn command returns immediately without waiting. This step finds spawned polecats that are now ready and sends them a trigger to start working. + +**ZFC-Compliant Observation** (AI observes AI): + +```bash +# View pending spawns with captured terminal output +gt deacon pending +``` + +For each pending session, analyze the captured output: +- Look for Claude's prompt indicator \"> \" at the start of a line +- If prompt is visible, Claude is ready for input +- Make the judgment call yourself - you're the AI observer + +For each ready polecat: +```bash +# 1. Trigger the polecat +gt nudge \"Begin.\" + +# 2. Clear from pending list +gt deacon pending +``` + +This triggers the UserPromptSubmit hook, which injects mail so the polecat sees its assignment. + +**Bootstrap mode** (daemon-only, no AI available): +The daemon uses `gt deacon trigger-pending` with regex detection. This ZFC violation is acceptable during cold startup when no AI agent is running yet.""" +id = "trigger-pending-spawns" +needs = ["inbox-check"] +title = "Nudge newly spawned polecats" + +[[steps]] +description = """ +Check Witness and Refinery health for each rig. + +**ZFC Principle**: You (Claude) make the judgment call about what is \"stuck\" or \"unresponsive\" - there are no hardcoded thresholds in Go. Read the signals, consider context, and decide. + +For each rig, run: +```bash +gt witness status +gt refinery status +``` + +**Signals to assess:** + +| Component | Healthy Signals | Concerning Signals | +|-----------|-----------------|-------------------| +| Witness | State: running, recent activity | State: not running, no heartbeat | +| Refinery | State: running, queue processing | Queue stuck, merge failures | + +**Tracking unresponsive cycles:** + +Maintain in your patrol state (persisted across cycles): +``` +health_state: + : + witness: + unresponsive_cycles: 0 + last_seen_healthy: + refinery: + unresponsive_cycles: 0 + last_seen_healthy: +``` + +**Decision matrix** (you decide the thresholds based on context): + +| Cycles Unresponsive | Suggested Action | +|---------------------|------------------| +| 1-2 | Note it, check again next cycle | +| 3-4 | Attempt restart: gt witness restart | +| 5+ | Escalate to Mayor with context | + +**Restart commands:** +```bash +gt witness restart +gt refinery restart +``` + +**Escalation:** +```bash +gt mail send mayor/ -s \"Health: unresponsive\" \\ + -m \"Component has been unresponsive for N cycles. Restart attempts failed. + Last healthy: + Error signals:
\" +``` + +Reset unresponsive_cycles to 0 when component responds normally.""" +id = "health-scan" +needs = ["trigger-pending-spawns"] +title = "Check Witness and Refinery health" + +[[steps]] +description = """ +Execute registered plugins. + +Scan ~/gt/plugins/ for plugin directories. Each plugin has a plugin.md with YAML frontmatter defining its gate (when to run) and instructions (what to do). + +See docs/deacon-plugins.md for full documentation. + +Gate types: +- cooldown: Time since last run (e.g., 24h) +- cron: Schedule-based (e.g., \"0 9 * * *\") +- condition: Metric threshold (e.g., wisp count > 50) +- event: Trigger-based (e.g., startup, heartbeat) + +For each plugin: +1. Read plugin.md frontmatter to check gate +2. Compare against state.json (last run, etc.) +3. If gate is open, execute the plugin + +Plugins marked parallel: true can run concurrently using Task tool subagents. Sequential plugins run one at a time in directory order. + +Skip this step if ~/gt/plugins/ does not exist or is empty.""" +id = "plugin-run" +needs = ["health-scan"] +title = "Execute registered plugins" + +[[steps]] +description = """ +Find abandoned work. + +Scan for orphaned state: +- Issues marked in_progress with no active polecat +- Polecats that stopped responding mid-work +- Merge queue entries with no polecat owner +- Wisp sessions that outlived their spawner + +```bash +bd list --status=in_progress +gt polecats --all --orphan +``` + +For each orphan: +- Check if polecat session still exists +- If not, mark issue for reassignment or retry +- File incident beads if data loss occurred""" +id = "orphan-check" +needs = ["health-scan"] +title = "Find abandoned work" + +[[steps]] +description = """ +Clean dead sessions and orphaned state. + +Run `gt doctor --fix` to handle all cleanup: + +```bash +# Preview what needs cleaning +gt doctor -v + +# Fix everything +gt doctor --fix +``` + +This handles: +- **orphan-sessions**: Kill orphaned tmux sessions (gt-* not matching valid patterns) +- **orphan-processes**: Kill orphaned Claude processes (no tmux parent) +- **wisp-gc**: Garbage collect abandoned wisps (>1h old) + +All cleanup is handled by doctor checks - no need to run separate commands.""" +id = "session-gc" +needs = ["orphan-check"] +title = "Clean dead sessions" + +[[steps]] +description = """ +Check own context limit. + +The Deacon runs in a Claude session with finite context. Check if approaching the limit: + +```bash +gt context --usage +``` + +If context is high (>80%), prepare for handoff: +- Summarize current state +- Note any pending work +- Write handoff to molecule state + +This enables the Deacon to burn and respawn cleanly.""" +id = "context-check" +needs = ["session-gc"] +title = "Check own context limit" + +[[steps]] +description = """ +Burn and let daemon respawn, or exit if context high. + +Decision point at end of patrol cycle: + +If context is LOW: +- Sleep briefly (avoid tight loop) +- Return to inbox-check step + +If context is HIGH: +- Write state to persistent storage +- Exit cleanly +- Let the daemon orchestrator respawn a fresh Deacon + +The daemon ensures Deacon is always running: +```bash +# Daemon respawns on exit +gt daemon status +``` + +This enables infinite patrol duration via context-aware respawning.""" +id = "loop-or-exit" +needs = ["context-check"] +title = "Burn and respawn or loop" diff --git a/.beads/formulas/mol-gastown-boot.formula.toml b/.beads/formulas/mol-gastown-boot.formula.toml new file mode 100644 index 00000000..beaae718 --- /dev/null +++ b/.beads/formulas/mol-gastown-boot.formula.toml @@ -0,0 +1,169 @@ +description = """ +Mayor bootstraps Gas Town via a verification-gated lifecycle molecule. + +## Purpose +When Mayor executes \"boot up gas town\", this proto provides the workflow. +Each step has action + verification - steps stay open until outcome is confirmed. + +## Key Principles +1. **Verification-gated steps** - Not \"command ran\" but \"outcome confirmed\" +2. **gt peek for verification** - Capture session output to detect stalls +3. **gt nudge for recovery** - Reliable message delivery to unstick agents +4. **Parallel where possible** - Witnesses and refineries can start in parallel +5. **Ephemeral execution** - Boot is a wisp, squashed to digest after completion + +## Execution +```bash +bd wisp mol-gastown-boot # Create wisp +```""" +formula = "mol-gastown-boot" +version = 1 + +[[steps]] +description = """ +Verify the Gas Town daemon is running. + +## Action +```bash +gt daemon status || gt daemon start +``` + +## Verify +1. Daemon PID file exists: `~/.gt/daemon.pid` +2. Process is alive: `kill -0 $(cat ~/.gt/daemon.pid)` +3. Daemon responds: `gt daemon status` returns success + +## OnFail +Cannot start daemon. Log error and continue - some commands work without daemon.""" +id = "ensure-daemon" +title = "Ensure daemon" + +[[steps]] +description = """ +Start the Deacon and verify patrol mode is active. + +## Action +```bash +gt deacon start +``` + +## Verify +1. Session exists: `tmux has-session -t gt-deacon 2>/dev/null` +2. Not stalled: `gt peek deacon/` does NOT show \"> Try\" prompt +3. Heartbeat fresh: `deacon/heartbeat.json` modified < 2 min ago + +## OnStall +```bash +gt nudge deacon/ \"Start patrol.\" +sleep 30 +# Re-verify +```""" +id = "ensure-deacon" +needs = ["ensure-daemon"] +title = "Ensure deacon" + +[[steps]] +description = """ +Parallel container: Start all rig witnesses. + +Children execute in parallel. Container completes when all children complete.""" +id = "ensure-witnesses" +needs = ["ensure-deacon"] +title = "Ensure witnesses" +type = "parallel" + +[[steps.children]] +description = """ +Start the gastown rig Witness. + +## Action +```bash +gt witness start gastown +``` + +## Verify +1. Session exists: `tmux has-session -t gastown-witness 2>/dev/null` +2. Not stalled: `gt peek gastown/witness` does NOT show \"> Try\" prompt +3. Heartbeat fresh: Last patrol cycle < 5 min ago""" +id = "ensure-gastown-witness" +title = "Ensure gastown witness" + +[[steps.children]] +description = """ +Start the beads rig Witness. + +## Action +```bash +gt witness start beads +``` + +## Verify +1. Session exists: `tmux has-session -t beads-witness 2>/dev/null` +2. Not stalled: `gt peek beads/witness` does NOT show \"> Try\" prompt +3. Heartbeat fresh: Last patrol cycle < 5 min ago""" +id = "ensure-beads-witness" +title = "Ensure beads witness" + +[[steps]] +description = """ +Parallel container: Start all rig refineries. + +Children execute in parallel. Container completes when all children complete.""" +id = "ensure-refineries" +needs = ["ensure-deacon"] +title = "Ensure refineries" +type = "parallel" + +[[steps.children]] +description = """ +Start the gastown rig Refinery. + +## Action +```bash +gt refinery start gastown +``` + +## Verify +1. Session exists: `tmux has-session -t gastown-refinery 2>/dev/null` +2. Not stalled: `gt peek gastown/refinery` does NOT show \"> Try\" prompt +3. Queue processing: Refinery can receive merge requests""" +id = "ensure-gastown-refinery" +title = "Ensure gastown refinery" + +[[steps.children]] +description = """ +Start the beads rig Refinery. + +## Action +```bash +gt refinery start beads +``` + +## Verify +1. Session exists: `tmux has-session -t beads-refinery 2>/dev/null` +2. Not stalled: `gt peek beads/refinery` does NOT show \"> Try\" prompt +3. Queue processing: Refinery can receive merge requests""" +id = "ensure-beads-refinery" +title = "Ensure beads refinery" + +[[steps]] +description = """ +Final verification that Gas Town is healthy. + +## Action +```bash +gt status +``` + +## Verify +1. Daemon running: Shows daemon status OK +2. Deacon active: Shows deacon in patrol mode +3. All witnesses: Each rig witness shows active +4. All refineries: Each rig refinery shows active + +## OnFail +Log degraded state but consider boot complete. Some agents may need manual recovery. +Run `gt doctor` for detailed diagnostics.""" +id = "verify-town-health" +needs = ["ensure-witnesses", "ensure-refineries"] +title = "Verify town health" diff --git a/.beads/formulas/mol-polecat-arm.formula.toml b/.beads/formulas/mol-polecat-arm.formula.toml new file mode 100644 index 00000000..1220a964 --- /dev/null +++ b/.beads/formulas/mol-polecat-arm.formula.toml @@ -0,0 +1,145 @@ +description = """ +Single polecat inspection and action cycle. + +This molecule is bonded dynamically by mol-witness-patrol's survey-workers step. Each polecat being monitored gets one arm that runs in parallel with other arms. + +## Variables + +| Variable | Required | Description | +|----------|----------|-------------| +| polecat_name | Yes | Name of the polecat to inspect | +| rig | Yes | Rig containing the polecat | +| nudge_text | No | Text to send when nudging (default: \"How's progress?...\") |""" +formula = "mol-polecat-arm" +version = 1 + +[[steps]] +description = """ +Capture recent tmux output for {{polecat_name}}. + +```bash +tmux capture-pane -t gt-{{rig}}-{{polecat_name}} -p | tail -50 +``` + +Record: +- Last activity timestamp (when was last tool call?) +- Visible errors or stack traces +- Completion indicators (\"Done\", \"Finished\", etc.)""" +id = "capture" +title = "Capture polecat state" + +[[steps]] +description = """ +Categorize polecat state based on captured output. + +States: +- **working**: Recent tool calls, active processing +- **idle**: At prompt, no recent activity +- **error**: Showing errors or stack traces +- **requesting_shutdown**: Sent LIFECYCLE/Shutdown mail +- **done**: Showing completion indicators + +Calculate: minutes since last activity.""" +id = "assess" +needs = ["capture"] +title = "Assess work status" + +[[steps]] +description = """ +Read nudge history for {{polecat_name}} from patrol state. + +``` +nudge_count = state.nudges[{{polecat_name}}].count +last_nudge_time = state.nudges[{{polecat_name}}].timestamp +``` + +This data was loaded by the parent patrol's load-state step and passed to the arm via the bonding context.""" +id = "load-history" +needs = ["assess"] +title = "Load intervention history" + +[[steps]] +description = """ +Apply the nudge matrix to determine action for {{polecat_name}}. + +| State | Idle Time | Nudge Count | Action | +|-------|-----------|-------------|--------| +| working | any | any | none | +| idle | <10min | any | none | +| idle | 10-15min | 0 | nudge-1 (gentle) | +| idle | 15-20min | 1 | nudge-2 (direct) | +| idle | 20+min | 2 | nudge-3 (final) | +| idle | any | 3 | escalate | +| error | any | any | assess-severity | +| requesting_shutdown | any | any | pre-kill-verify | +| done | any | any | pre-kill-verify | + +Nudge text: +1. \"How's progress? Need any help?\" +2. \"Please wrap up soon. What's blocking you?\" +3. \"Final check. Will escalate in 5 min if no response.\" + +Record decision and rationale.""" +id = "decide" +needs = ["load-history"] +title = "Decide intervention action" + +[[steps]] +description = """ +Take the decided action for {{polecat_name}}. + +**nudge-N**: +```bash +tmux send-keys -t gt-{{rig}}-{{polecat_name}} \"{{nudge_text}}\" Enter +``` + +**pre-kill-verify**: +```bash +cd polecats/{{polecat_name}} +git status # Must be clean +git log origin/main..HEAD # Check for unpushed +bd show # Verify closed/deferred + +# Verify productive work (for 'done' closures) +git log --oneline --grep='' | head -1 +``` + +**Commit verification** (ZFC principle - agent makes the call): +- If issue closed as 'done' but no commits reference it → flag for review +- Legitimate exceptions: already fixed elsewhere, duplicate, deferred +- Agent must provide justification if closing without commits + +If clean: kill session, remove worktree, delete branch +If dirty: record failure, retry next cycle + +**escalate**: +```bash +gt mail send mayor/ -s \"Escalation: {{polecat_name}} stuck\" -m \"...\" +``` + +**none**: No action needed. + +Record: action taken, result, updated nudge count. + +## Output + +The arm completes with: +- action_taken: none | nudge-1 | nudge-2 | nudge-3 | killed | escalated +- result: success | failed | pending +- updated_state: New nudge count and timestamp for {{polecat_name}} + +This data feeds back to the parent patrol's aggregate step.""" +id = "execute" +needs = ["decide"] +title = "Execute intervention" + +[vars] +[vars.nudge_text] +default = "How's progress? Need any help?" +description = "Text to send when nudging the polecat" +[vars.polecat_name] +description = "Name of the polecat to inspect" +required = true +[vars.rig] +description = "Rig containing the polecat" +required = true diff --git a/.beads/formulas/mol-polecat-lease.formula.toml b/.beads/formulas/mol-polecat-lease.formula.toml new file mode 100644 index 00000000..cdb3cf81 --- /dev/null +++ b/.beads/formulas/mol-polecat-lease.formula.toml @@ -0,0 +1,70 @@ +description = """ +Semaphore tracking a single polecat's lifecycle. + +Used by Witness to track polecat lifecycle during patrol. The Witness bonds this proto for each active polecat, creating a lease that tracks the polecat from spawn through work to cleanup. + +## Variables + +| Variable | Required | Description | +|----------|----------|-------------| +| polecat | Yes | Name of the polecat | +| issue | Yes | The issue assigned to the polecat |""" +formula = "mol-polecat-lease" +version = 1 + +[[steps]] +description = """ +Spawned. Verify it starts working. + +Check if the polecat is alive and working: +```bash +gt peek {{polecat}} +``` + +If idle for too long, nudge: +```bash +gt nudge {{polecat}} \"Please start working on your assigned issue.\" +``` + +Timeout: 60s before escalation to Mayor.""" +id = "boot" +title = "Boot" + +[[steps]] +description = """ +Actively working. Monitor for stuck. + +The polecat is processing its assigned issue ({{issue}}). +Monitor via peek. Watch for: +- Progress on commits +- Status updates in beads +- SHUTDOWN mail when done + +Wait for SHUTDOWN signal from the polecat.""" +id = "working" +needs = ["boot"] +title = "Working" + +[[steps]] +description = """ +Exit received. Ready for cleanup. + +The polecat has completed its work and sent SHUTDOWN. +Perform cleanup: +```bash +gt session kill {{polecat}} +gt worktree prune {{polecat}} +``` + +Update beads state and close the lease.""" +id = "done" +needs = ["working"] +title = "Done" + +[vars] +[vars.issue] +description = "The issue assigned to the polecat" +required = true +[vars.polecat] +description = "Name of the polecat" +required = true diff --git a/.beads/formulas/mol-polecat-work.formula.toml b/.beads/formulas/mol-polecat-work.formula.toml new file mode 100644 index 00000000..64db025c --- /dev/null +++ b/.beads/formulas/mol-polecat-work.formula.toml @@ -0,0 +1,62 @@ +description = """ +Full polecat lifecycle from assignment to decommission. + +This proto enables nondeterministic idempotence for polecat work. A polecat that crashes after any step can restart, read its molecule state, and continue from the last completed step. No work is lost. + +## Variables + +| Variable | Required | Description | +|----------|----------|-------------| +| issue | Yes | The source issue ID being worked on |""" +formula = "mol-polecat-work" +version = 1 + +[[steps]] +description = """ +Run gt prime and bd prime. Verify issue assignment. +Check inbox for any relevant messages. + +Read the assigned issue ({{issue}}) and understand the requirements. +Identify any blockers or missing information.""" +id = "load-context" +title = "Load context" + +[[steps]] +description = """ +Implement the solution for {{issue}}. Follow codebase conventions. +File discovered work as new issues with bd create. + +Make regular commits with clear messages. +Keep changes focused on the assigned issue.""" +id = "implement" +needs = ["load-context"] +title = "Implement" + +[[steps]] +description = """ +Review your own changes. Look for: +- Bugs and edge cases +- Style issues +- Missing error handling +- Security concerns + +Fix any issues found before proceeding.""" +id = "self-review" +needs = ["implement"] +title = "Self-review" + +[[steps]] +description = """ +Send shutdown request to Witness. +Wait for termination. + +The polecat is now ready to be cleaned up. +Do not exit directly - wait for Witness to kill the session.""" +id = "request-shutdown" +needs = ["self-review"] +title = "Request shutdown" + +[vars] +[vars.issue] +description = "The source issue ID being worked on" +required = true diff --git a/.beads/formulas/mol-refinery-patrol.formula.toml b/.beads/formulas/mol-refinery-patrol.formula.toml new file mode 100644 index 00000000..1b1a9b39 --- /dev/null +++ b/.beads/formulas/mol-refinery-patrol.formula.toml @@ -0,0 +1,166 @@ +description = """ +Merge queue processor patrol loop. + +The Refinery is the Engineer in the engine room. You process polecat branches, merging them to main one at a time with sequential rebasing. + +**The Scotty Test**: Before proceeding past any failure, ask yourself: \"Would Scotty walk past a warp core leak because it existed before his shift?\"""" +formula = "mol-refinery-patrol" +version = 1 + +[[steps]] +description = """ +Check mail for MR submissions, escalations, messages. + +```bash +gt mail inbox +# Process any urgent items +``` + +Handle shutdown requests, escalations, and status queries.""" +id = "inbox-check" +title = "Check refinery mail" + +[[steps]] +description = """ +Fetch remote and identify polecat branches waiting. + +```bash +git fetch origin +git branch -r | grep polecat +gt refinery queue +``` + +If queue empty, skip to context-check step. Track branch list for this cycle.""" +id = "queue-scan" +needs = ["inbox-check"] +title = "Scan merge queue" + +[[steps]] +description = """ +Pick next branch. Rebase on current main. + +```bash +git checkout -b temp origin/ +git rebase origin/main +``` + +If rebase conflicts and unresolvable: +- git rebase --abort +- Notify polecat to fix and resubmit +- Skip to loop-check for next branch""" +id = "process-branch" +needs = ["queue-scan"] +title = "Process next branch" + +[[steps]] +description = """ +Run the test suite. + +```bash +go test ./... +``` + +Track results: pass count, fail count, specific failures.""" +id = "run-tests" +needs = ["process-branch"] +title = "Run test suite" + +[[steps]] +description = """ +**VERIFICATION GATE**: This step enforces the Beads Promise. + +If tests PASSED: This step auto-completes. Proceed to merge. + +If tests FAILED: +1. Diagnose: Is this a branch regression or pre-existing on main? +2. If branch caused it: + - Abort merge + - Notify polecat: \"Tests failing. Please fix and resubmit.\" + - Skip to loop-check +3. If pre-existing on main: + - Option A: Fix it yourself (you're the Engineer!) + - Option B: File a bead: bd create --type=bug --priority=1 --title=\"...\" + +**GATE REQUIREMENT**: You CANNOT proceed to merge-push without: +- Tests passing, OR +- Fix committed, OR +- Bead filed for the failure + +This is non-negotiable. Never disavow. Never \"note and proceed.\"""" +id = "handle-failures" +needs = ["run-tests"] +title = "Handle test failures" + +[[steps]] +description = """ +Merge to main and push immediately. + +```bash +git checkout main +git merge --ff-only temp +git push origin main +git branch -d temp +git branch -D # Local delete (branches never go to origin) +``` + +Main has moved. Any remaining branches need rebasing on new baseline.""" +id = "merge-push" +needs = ["handle-failures"] +title = "Merge and push to main" + +[[steps]] +description = """ +More branches to process? + +If yes: Return to process-branch with next branch. +If no: Continue to generate-summary. + +Track: branches processed, branches skipped (with reasons).""" +id = "loop-check" +needs = ["merge-push"] +title = "Check for more work" + +[[steps]] +description = """ +Summarize this patrol cycle. + +Include: +- Branches processed (count, names) +- Test results (pass/fail) +- Issues filed (if any) +- Branches skipped (with reasons) +- Any escalations sent + +This becomes the digest when the patrol is squashed.""" +id = "generate-summary" +needs = ["loop-check"] +title = "Generate handoff summary" + +[[steps]] +description = """ +Check own context usage. + +If context is HIGH (>80%): +- Write handoff summary +- Prepare for burn/respawn + +If context is LOW: +- Can continue processing""" +id = "context-check" +needs = ["generate-summary"] +title = "Check own context limit" + +[[steps]] +description = """ +End of patrol cycle decision. + +If queue non-empty AND context LOW: +- Burn this wisp, start fresh patrol +- Return to inbox-check + +If queue empty OR context HIGH: +- Burn wisp with summary digest +- Exit (daemon will respawn if needed)""" +id = "burn-or-loop" +needs = ["context-check"] +title = "Burn and respawn or loop" diff --git a/.beads/formulas/mol-witness-patrol.formula.toml b/.beads/formulas/mol-witness-patrol.formula.toml new file mode 100644 index 00000000..02119577 --- /dev/null +++ b/.beads/formulas/mol-witness-patrol.formula.toml @@ -0,0 +1,212 @@ +description = """ +Per-rig worker monitor patrol loop using the Christmas Ornament pattern. + +The Witness is the Pit Boss for your rig. You watch polecats, nudge them toward completion, verify clean git state before kills, and escalate stuck workers. + +**You do NOT do implementation work.** Your job is oversight, not coding. + +This molecule uses dynamic bonding to spawn mol-polecat-arm for each worker, enabling parallel inspection with a fanout gate for aggregation. + +## The Christmas Ornament Shape + +``` + ★ mol-witness-patrol (trunk) + /|\\ + ┌────────┘ │ └────────┐ + PREFLIGHT DISCOVERY CLEANUP + │ │ │ + inbox-check survey aggregate (WaitsFor: all-children) + check-refnry │ save-state + load-state │ generate-summary + ↓ context-check + ┌───────┼───────┐ burn-or-loop + ● ● ● mol-polecat-arm (dynamic) + ace nux toast +```""" +formula = "mol-witness-patrol" +version = 1 + +[[steps]] +description = """ +Process witness mail: lifecycle requests, help requests. + +```bash +gt mail inbox +``` + +Handle by message type: +- **LIFECYCLE/Shutdown**: Queue for pre-kill verification +- **Blocked/Help**: Assess if resolvable or escalate +- **HANDOFF**: Load predecessor state +- **Work complete**: Verify issue closed, proceed to pre-kill + +Record any pending actions for later steps. Mark messages as processed when complete.""" +id = "inbox-check" +title = "Process witness mail" + +[[steps]] +description = """ +Ensure the refinery is alive and processing merge requests. + +**Redundant system**: This check runs in both gt spawn and Witness patrol to ensure the merge queue processor stays operational. + +```bash +# Check if refinery session is running +gt session status /refinery + +# Check for merge requests in queue +bd list --type=merge-request --status=open +``` + +If merge requests are waiting AND refinery is not running: +```bash +gt session start /refinery +gt mail send /refinery -s \"PATROL: Wake up\" -m \"Merge requests in queue. Please process.\" +``` + +If refinery is running but queue is non-empty for >30 min, send nudge. This ensures polecats don't wait forever for their branches to merge.""" +id = "check-refinery" +needs = ["inbox-check"] +title = "Ensure refinery is alive" + +[[steps]] +description = """ +Read handoff bead and get nudge counts. + +Load persistent state from the witness handoff bead: +- Active workers and their status from last cycle +- Nudge counts per worker per issue +- Last nudge timestamps +- Pending escalations + +```bash +bd show +``` + +If no handoff exists (fresh start), initialize empty state. This state persists across wisp burns and session cycles.""" +id = "load-state" +needs = ["check-refinery"] +title = "Load persisted patrol state" + +[[steps]] +description = """ +List polecats and bond mol-polecat-arm for each one. + +```bash +# Get list of polecats +gt polecat list +``` + +For each polecat discovered, dynamically bond an inspection arm: + +```bash +# Bond mol-polecat-arm for each polecat +for polecat in $(gt polecat list --names); do + bd mol bond mol-polecat-arm $PATROL_WISP_ID \\ + --ref arm-$polecat \\ + --var polecat_name=$polecat \\ + --var rig= +done +``` + +This creates child wisps like: +- patrol-x7k.arm-ace (5 steps) +- patrol-x7k.arm-nux (5 steps) +- patrol-x7k.arm-toast (5 steps) + +Each arm runs in PARALLEL. The aggregate step will wait for all to complete. + +If no polecats are found, this step completes immediately with no children.""" +id = "survey-workers" +needs = ["load-state"] +title = "Survey all polecats (fanout)" + +[[steps]] +description = """ +Collect outcomes from all polecat inspection arms. + +This is a **fanout gate** - it cannot proceed until ALL dynamically-bonded polecat arms have completed their inspection cycles. + +Once all arms complete, collect their outcomes: +- Actions taken per polecat (nudge, kill, escalate, none) +- Updated nudge counts +- Any errors or issues discovered + +Build the consolidated state for save-state.""" +id = "aggregate" +needs = ["survey-workers"] +title = "Aggregate arm results" +waits_for = "all-children" + +[[steps]] +description = """ +Update handoff bead with new states. + +Persist state to the witness handoff bead: +- Updated worker statuses from all arms +- Current nudge counts per worker +- Nudge timestamps +- Actions taken this cycle +- Pending items for next cycle + +```bash +bd update --description=\"\" +``` + +This state survives wisp burns and session cycles.""" +id = "save-state" +needs = ["aggregate"] +title = "Persist patrol state" + +[[steps]] +description = """ +Summarize this patrol cycle for digest. + +Include: +- Workers inspected (count, names) +- Nudges sent (count, to whom) +- Sessions killed (count, names) +- Escalations (count, issues) +- Issues found (brief descriptions) +- Actions pending for next cycle + +This becomes the digest when the patrol wisp is squashed.""" +id = "generate-summary" +needs = ["save-state"] +title = "Generate handoff summary" + +[[steps]] +description = """ +Check own context usage. + +If context is HIGH (>80%): +- Ensure state is saved to handoff bead +- Prepare for burn/respawn + +If context is LOW: +- Can continue patrolling""" +id = "context-check" +needs = ["generate-summary"] +title = "Check own context limit" + +[[steps]] +description = """ +End of patrol cycle decision. + +If context is LOW: +- Burn this wisp (no audit trail needed for patrol cycles) +- Sleep briefly to avoid tight loop (30-60 seconds) +- Return to inbox-check step + +If context is HIGH: +- Burn wisp with summary digest +- Exit cleanly (daemon will respawn fresh Witness) + +```bash +bd mol burn # Destroy ephemeral wisp +``` + +The daemon ensures Witness is always running.""" +id = "burn-or-loop" +needs = ["context-check"] +title = "Burn and respawn or loop" diff --git a/.beads/formulas/rule-of-five.formula.toml b/.beads/formulas/rule-of-five.formula.toml new file mode 100644 index 00000000..373d68b9 --- /dev/null +++ b/.beads/formulas/rule-of-five.formula.toml @@ -0,0 +1,33 @@ +description = "Jeffrey Emanuel's discovery: LLM agents produce best work through 4-5 iterative refinements. Breadth-first exploration, then editorial passes." +formula = "rule-of-five" +type = "expansion" +version = 1 + +[[template]] +description = "Initial attempt at: {target.description}. Don't aim for perfection. Get the shape right. Breadth over depth." +id = "{target}.draft" +title = "Draft: {target.title}" + +[[template]] +description = "First refinement pass. Focus: CORRECTNESS. Fix errors, bugs, mistakes. Is the logic sound?" +id = "{target}.refine-1" +needs = ["{target}.draft"] +title = "Refine 1: Correctness" + +[[template]] +description = "Second refinement pass. Focus: CLARITY. Can someone else understand this? Simplify. Remove jargon." +id = "{target}.refine-2" +needs = ["{target}.refine-1"] +title = "Refine 2: Clarity" + +[[template]] +description = "Third refinement pass. Focus: EDGE CASES. What could go wrong? What's missing? Handle the unusual." +id = "{target}.refine-3" +needs = ["{target}.refine-2"] +title = "Refine 3: Edge Cases" + +[[template]] +description = "Final polish. Focus: EXCELLENCE. This is the last pass. Make it shine. Is this something you'd be proud to ship?" +id = "{target}.refine-4" +needs = ["{target}.refine-3"] +title = "Refine 4: Excellence" diff --git a/.beads/formulas/security-audit.formula.toml b/.beads/formulas/security-audit.formula.toml new file mode 100644 index 00000000..67f9c0c9 --- /dev/null +++ b/.beads/formulas/security-audit.formula.toml @@ -0,0 +1,38 @@ +description = "Cross-cutting security concern. Applies security scanning before and after implementation steps." +formula = "security-audit" +type = "aspect" +version = 1 + +[[advice]] +target = "implement" +[advice.around] + +[[advice.around.after]] +description = "Post-implementation security scan. Scan new code for vulnerabilities (SAST). Check for hardcoded secrets. Review for OWASP Top 10 issues." +id = "{step.id}-security-postscan" +title = "Security postscan for {step.id}" + +[[advice.around.before]] +description = "Pre-implementation security check. Review for secrets/credentials in scope. Check dependencies for known vulnerabilities." +id = "{step.id}-security-prescan" +title = "Security prescan for {step.id}" + +[[advice]] +target = "submit" +[advice.around] + +[[advice.around.after]] +description = "Post-submission security verification. Confirm no new vulnerabilities introduced." +id = "{step.id}-security-postscan" +title = "Security postscan for {step.id}" + +[[advice.around.before]] +description = "Pre-submission security check. Final vulnerability scan before merge." +id = "{step.id}-security-prescan" +title = "Security prescan for {step.id}" + +[[pointcuts]] +glob = "implement" + +[[pointcuts]] +glob = "submit" diff --git a/.beads/formulas/shiny-enterprise.formula.toml b/.beads/formulas/shiny-enterprise.formula.toml new file mode 100644 index 00000000..cd398148 --- /dev/null +++ b/.beads/formulas/shiny-enterprise.formula.toml @@ -0,0 +1,11 @@ +description = "Enterprise-grade engineering workflow. Shiny + Rule of Five expansion on implement step." +extends = ["shiny"] +formula = "shiny-enterprise" +type = "workflow" +version = 1 + +[compose] + +[[compose.expand]] +target = "implement" +with = "rule-of-five" diff --git a/.beads/formulas/shiny-secure.formula.toml b/.beads/formulas/shiny-secure.formula.toml new file mode 100644 index 00000000..6ac0b8dc --- /dev/null +++ b/.beads/formulas/shiny-secure.formula.toml @@ -0,0 +1,8 @@ +description = "Shiny workflow with security audit aspect applied." +extends = ["shiny"] +formula = "shiny-secure" +type = "workflow" +version = 1 + +[compose] +aspects = ["security-audit"] diff --git a/.beads/formulas/shiny.formula.toml b/.beads/formulas/shiny.formula.toml new file mode 100644 index 00000000..fdef65ef --- /dev/null +++ b/.beads/formulas/shiny.formula.toml @@ -0,0 +1,40 @@ +description = "Engineer in a Box - the canonical right way. Design before you code. Review before you ship. Test before you submit." +formula = "shiny" +type = "workflow" +version = 1 + +[[steps]] +description = "Think carefully about architecture before writing code. Consider: How does this fit into the existing system? What are the edge cases? What could go wrong? Is there a simpler approach?" +id = "design" +title = "Design {{feature}}" + +[[steps]] +description = "Write the code for {{feature}}. Follow the design. Keep it simple. Don't gold-plate." +id = "implement" +needs = ["design"] +title = "Implement {{feature}}" + +[[steps]] +description = "Review the implementation. Check for: Does it match the design? Are there obvious bugs? Is it readable and maintainable? Are there security concerns?" +id = "review" +needs = ["implement"] +title = "Review implementation" + +[[steps]] +description = "Write and run tests. Unit tests for new code, integration tests if needed, run the full test suite, fix any regressions." +id = "test" +needs = ["review"] +title = "Test {{feature}}" + +[[steps]] +description = "Submit for merge. Final check: git status, git diff. Commit with clear message. Push and create PR." +id = "submit" +needs = ["test"] +title = "Submit for merge" + +[vars] +[vars.assignee] +description = "Who is assigned to this work" +[vars.feature] +description = "The feature being implemented" +required = true diff --git a/.beads/formulas/towers-of-hanoi.formula.toml b/.beads/formulas/towers-of-hanoi.formula.toml new file mode 100644 index 00000000..5ac74263 --- /dev/null +++ b/.beads/formulas/towers-of-hanoi.formula.toml @@ -0,0 +1,80 @@ +description = "Solve Towers of Hanoi for {disks} disks. Generates 2^{disks} - 1 steps, each a trivial move operation. Demonstrates mechanical structure generation for arbitrarily long workflows." +formula = "towers-of-hanoi" +version = 1 + +[example_3_disk] + +[[example_3_disk.steps]] +description = "Move disk 1 from A to C" +id = "move-1" + +[[example_3_disk.steps]] +description = "Move disk 2 from A to B" +id = "move-2" +needs = ["move-1"] + +[[example_3_disk.steps]] +description = "Move disk 1 from C to B" +id = "move-3" +needs = ["move-2"] + +[[example_3_disk.steps]] +description = "Move disk 3 from A to C" +id = "move-4" +needs = ["move-3"] + +[[example_3_disk.steps]] +description = "Move disk 1 from B to A" +id = "move-5" +needs = ["move-4"] + +[[example_3_disk.steps]] +description = "Move disk 2 from B to C" +id = "move-6" +needs = ["move-5"] + +[[example_3_disk.steps]] +description = "Move disk 1 from A to C" +id = "move-7" +needs = ["move-6"] + +[generate] +[generate.for-each] +range = "1..2^{disks}" +var = "move_num" +[generate.step] +description = "Move {computed_disk} from {computed_source} to {computed_target}. This is move {move_num} of {total_moves}. Simply execute the move - no decision needed." +id = "move-{move_num}" +needs = ["move-{move_num - 1}"] +[generate.step.compute] +disk = "lowest_set_bit({move_num})" +source = "peg_for_disk({disk}, {move_num}, 'source')" +target = "peg_for_disk({disk}, {move_num}, 'target')" + +[[steps]] +description = "Verify initial state: {disks} disks stacked on peg {source_peg}. All disks in order (largest on bottom)." +id = "setup" + +[[steps]] +description = "Execute all {total_moves} moves to transfer tower from {source_peg} to {target_peg}." +id = "solve" +needs = ["setup"] + +[[steps]] +description = "Verify final state: all {disks} disks now on peg {target_peg}. Tower intact, all moves were legal." +id = "verify" +needs = ["solve"] + +[vars] +[vars.auxiliary_peg] +default = "B" +description = "Helper peg" +[vars.disks] +description = "Number of disks to solve" +required = true +[vars.source_peg] +default = "A" +description = "Starting peg" +[vars.target_peg] +default = "C" +description = "Target peg"