Add TOML versions of formulas (gt-xmyha)
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 <noreply@anthropic.com>
This commit is contained in:
241
.beads/formulas/mol-deacon-patrol.formula.toml
Normal file
241
.beads/formulas/mol-deacon-patrol.formula.toml
Normal file
@@ -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 <id>
|
||||||
|
# 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 <session> \"Begin.\"
|
||||||
|
|
||||||
|
# 2. Clear from pending list
|
||||||
|
gt deacon pending <session>
|
||||||
|
```
|
||||||
|
|
||||||
|
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 <rig>
|
||||||
|
gt refinery status <rig>
|
||||||
|
```
|
||||||
|
|
||||||
|
**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:
|
||||||
|
<rig>:
|
||||||
|
witness:
|
||||||
|
unresponsive_cycles: 0
|
||||||
|
last_seen_healthy: <timestamp>
|
||||||
|
refinery:
|
||||||
|
unresponsive_cycles: 0
|
||||||
|
last_seen_healthy: <timestamp>
|
||||||
|
```
|
||||||
|
|
||||||
|
**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 <rig> |
|
||||||
|
| 5+ | Escalate to Mayor with context |
|
||||||
|
|
||||||
|
**Restart commands:**
|
||||||
|
```bash
|
||||||
|
gt witness restart <rig>
|
||||||
|
gt refinery restart <rig>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Escalation:**
|
||||||
|
```bash
|
||||||
|
gt mail send mayor/ -s \"Health: <rig> <component> unresponsive\" \\
|
||||||
|
-m \"Component has been unresponsive for N cycles. Restart attempts failed.
|
||||||
|
Last healthy: <timestamp>
|
||||||
|
Error signals: <details>\"
|
||||||
|
```
|
||||||
|
|
||||||
|
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"
|
||||||
169
.beads/formulas/mol-gastown-boot.formula.toml
Normal file
169
.beads/formulas/mol-gastown-boot.formula.toml
Normal file
@@ -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"
|
||||||
145
.beads/formulas/mol-polecat-arm.formula.toml
Normal file
145
.beads/formulas/mol-polecat-arm.formula.toml
Normal file
@@ -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 <assigned-issue> # Verify closed/deferred
|
||||||
|
|
||||||
|
# Verify productive work (for 'done' closures)
|
||||||
|
git log --oneline --grep='<issue-id>' | 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
|
||||||
70
.beads/formulas/mol-polecat-lease.formula.toml
Normal file
70
.beads/formulas/mol-polecat-lease.formula.toml
Normal file
@@ -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
|
||||||
62
.beads/formulas/mol-polecat-work.formula.toml
Normal file
62
.beads/formulas/mol-polecat-work.formula.toml
Normal file
@@ -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
|
||||||
166
.beads/formulas/mol-refinery-patrol.formula.toml
Normal file
166
.beads/formulas/mol-refinery-patrol.formula.toml
Normal file
@@ -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 <rig>
|
||||||
|
```
|
||||||
|
|
||||||
|
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/<polecat-branch>
|
||||||
|
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 <polecat-branch> # 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"
|
||||||
212
.beads/formulas/mol-witness-patrol.formula.toml
Normal file
212
.beads/formulas/mol-witness-patrol.formula.toml
Normal file
@@ -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 <rig>/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 <rig>/refinery
|
||||||
|
gt mail send <rig>/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 <handoff-bead-id>
|
||||||
|
```
|
||||||
|
|
||||||
|
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 <rig>
|
||||||
|
```
|
||||||
|
|
||||||
|
For each polecat discovered, dynamically bond an inspection arm:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Bond mol-polecat-arm for each polecat
|
||||||
|
for polecat in $(gt polecat list <rig> --names); do
|
||||||
|
bd mol bond mol-polecat-arm $PATROL_WISP_ID \\
|
||||||
|
--ref arm-$polecat \\
|
||||||
|
--var polecat_name=$polecat \\
|
||||||
|
--var rig=<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 <handoff-bead-id> --description=\"<serialized state>\"
|
||||||
|
```
|
||||||
|
|
||||||
|
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"
|
||||||
33
.beads/formulas/rule-of-five.formula.toml
Normal file
33
.beads/formulas/rule-of-five.formula.toml
Normal file
@@ -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"
|
||||||
38
.beads/formulas/security-audit.formula.toml
Normal file
38
.beads/formulas/security-audit.formula.toml
Normal file
@@ -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"
|
||||||
11
.beads/formulas/shiny-enterprise.formula.toml
Normal file
11
.beads/formulas/shiny-enterprise.formula.toml
Normal file
@@ -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"
|
||||||
8
.beads/formulas/shiny-secure.formula.toml
Normal file
8
.beads/formulas/shiny-secure.formula.toml
Normal file
@@ -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"]
|
||||||
40
.beads/formulas/shiny.formula.toml
Normal file
40
.beads/formulas/shiny.formula.toml
Normal file
@@ -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
|
||||||
80
.beads/formulas/towers-of-hanoi.formula.toml
Normal file
80
.beads/formulas/towers-of-hanoi.formula.toml
Normal file
@@ -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"
|
||||||
Reference in New Issue
Block a user