1573 lines
48 KiB
Plaintext
1573 lines
48 KiB
Plaintext
# Gas Town: Multi-Agent Orchestration System
|
|
#
|
|
# A "Kubernetes for agents" - an industrialized coding factory
|
|
# with 7 worker roles coordinating through persistent state.
|
|
#
|
|
# Based on Steve Yegge's Gas Town architecture (2025-2026).
|
|
#
|
|
# =============================================================================
|
|
# THE MEOW STACK: Molecular Expression of Work
|
|
# =============================================================================
|
|
#
|
|
# Gas Town is built on the MEOW stack - a discovery about how to express
|
|
# and compose knowledge work for AI agents:
|
|
#
|
|
# 1. BEADS - Atomic work units (issues) stored in Git-backed JSON
|
|
# - ID, description, status, assignee, dependencies
|
|
# - Two tiers: Rig beads (project work) and Town beads (orchestration)
|
|
#
|
|
# 2. EPICS - Beads with children, for top-down planning
|
|
# - Children are parallel by default
|
|
# - Explicit dependencies force sequencing
|
|
#
|
|
# 3. MOLECULES - Workflows encoded as chains of beads
|
|
# - Arbitrary shapes with loops and gates
|
|
# - Turing-complete when combined with AI evaluation
|
|
# - Each step has acceptance criteria
|
|
#
|
|
# 4. PROTOMOLECULES - Templates/classes for molecules
|
|
# - Define workflow shapes in advance
|
|
# - Instantiate with variable substitution
|
|
# - E.g., 20-step release process as a template
|
|
#
|
|
# 5. FORMULAS - Source form for workflows (TOML)
|
|
# - "Cooked" into protomolecules
|
|
# - Support loops, gates, composition
|
|
# - Marketplace: "Mol Mall"
|
|
#
|
|
# 6. WISPS - Ephemeral beads (vapor phase)
|
|
# - In database but NOT written to Git
|
|
# - Used for patrol orchestration
|
|
# - Burned (destroyed) after completion
|
|
# - Optionally squashed to single-line digest
|
|
#
|
|
# =============================================================================
|
|
# KEY CONCEPTS
|
|
# =============================================================================
|
|
#
|
|
# GUPP: Gas Town Universal Propulsion Principle
|
|
# "If there is work on your hook, YOU MUST RUN IT"
|
|
# Physics over politeness. No waiting for permission.
|
|
#
|
|
# NDI: Nondeterministic Idempotence
|
|
# - Agent is persistent (Bead in Git)
|
|
# - Hook is persistent (Bead in Git)
|
|
# - Molecule is persistent (chain of Beads in Git)
|
|
# - Path is nondeterministic but outcome is guaranteed
|
|
# - Crashes don't matter - new session picks up where left off
|
|
#
|
|
# CONVOYS: Work-order units tracking delivery
|
|
# - Wraps beads into trackable delivery units
|
|
# - Multiple swarms can "attack" a convoy
|
|
# - Lands when all beads complete and MRs merge
|
|
#
|
|
# PATROLS: Ephemeral workflows run in loops by patrol agents
|
|
# - Use wisps (not persisted to Git)
|
|
# - Exponential backoff when idle
|
|
# - Deacon → Witness → Polecats/Refinery
|
|
#
|
|
# =============================================================================
|
|
# PERSISTENT STATE (in .prose/gas-town/)
|
|
# =============================================================================
|
|
#
|
|
# Town-level (orchestration):
|
|
# town-beads.jsonl - Town-level beads
|
|
# patrol-state.json - Deacon/Witness/Refinery patrol state
|
|
# activity-feed.jsonl - Live activity stream
|
|
# plugins/town/ - Town-level plugins
|
|
#
|
|
# Per-rig (project work):
|
|
# rigs/{name}/
|
|
# rig-beads.jsonl - Rig-level beads
|
|
# hooks/ - Worker hooks (GUPP)
|
|
# mail/ - Worker inboxes
|
|
# polecats/ - Polecat state
|
|
# merge-queue.json - Pending MRs
|
|
# plugins/ - Rig-level plugins
|
|
#
|
|
# Shared:
|
|
# convoys/ - Active work orders
|
|
# archive/ - Completed convoys
|
|
# workers/ - Worker identity beads (persistent)
|
|
# formulas/ - Workflow templates
|
|
# wisps/ - Ephemeral orchestration (not in Git)
|
|
#
|
|
# This example assumes persistent file-based state is enabled.
|
|
|
|
# =============================================================================
|
|
# AGENT DEFINITIONS: The 7 Worker Roles
|
|
# =============================================================================
|
|
|
|
# The Mayor: Your concierge and chief-of-staff
|
|
# Main agent you interact with, kicks off most work convoys
|
|
agent mayor:
|
|
model: sonnet # Orchestration role - sonnet excels here
|
|
persist: project # Survives across runs - your long-term concierge
|
|
prompt: """
|
|
You are the Mayor of Gas Town, the user's concierge and chief-of-staff.
|
|
|
|
Your responsibilities:
|
|
- Receive requests from the Overseer (user) and translate them into work
|
|
- File beads (issues) and sling work to appropriate workers
|
|
- Track convoy status and notify when work lands
|
|
- Manage the big picture while polecats handle details
|
|
- Help keep Gas Town running smoothly
|
|
|
|
Key commands you use:
|
|
- gt sling <bead> <worker> - Send work to a worker's hook
|
|
- gt convoy create <name> - Start tracking a unit of work
|
|
- gt mail send <worker> <message> - Send messages to workers
|
|
- gt handoff - Gracefully restart your session
|
|
|
|
Remember GUPP: If there is work on your hook, YOU MUST RUN IT.
|
|
Physics over politeness. Check your hook on startup.
|
|
"""
|
|
|
|
# Polecats: Ephemeral workers that swarm on work
|
|
# Spin up on demand, produce Merge Requests, then decommission
|
|
agent polecat:
|
|
model: sonnet
|
|
prompt: """
|
|
You are a Polecat - an ephemeral worker in Gas Town.
|
|
|
|
Your lifecycle:
|
|
1. Spin up when work is slung to you
|
|
2. Execute the molecule (workflow) on your hook
|
|
3. Produce a Merge Request when code changes are ready
|
|
4. Hand off to the Merge Queue
|
|
5. Decommission (your name gets recycled)
|
|
|
|
Work style:
|
|
- Focus on ONE task at a time from your hook
|
|
- Follow the molecule step by step
|
|
- Create clean, atomic commits
|
|
- Submit MRs to the Refinery's merge queue
|
|
- Report status updates to the Witness
|
|
|
|
GUPP: If there is work on your hook, YOU MUST RUN IT.
|
|
No waiting for permission. Check hook, do work, submit MR.
|
|
"""
|
|
|
|
# Refinery: The Merge Queue processor
|
|
# Intelligently merges all changes one at a time to main
|
|
agent refinery:
|
|
model: sonnet # Orchestration role - merge queue is control flow
|
|
persist: true # Execution-scoped - maintains MQ state within run
|
|
prompt: """
|
|
You are the Refinery - Gas Town's merge queue processor.
|
|
|
|
Your patrol loop:
|
|
1. Preflight: Clean workspace, fetch latest
|
|
2. Process: Merge one MR at a time, intelligently
|
|
3. Handle conflicts: Reimagine changes against new head if needed
|
|
4. Run quality gates: Tests, lint, type checks
|
|
5. Postflight: Update convoy status, notify completion
|
|
|
|
Merge strategy:
|
|
- Process MRs in priority order (convoys can set priority)
|
|
- No work can be lost (escalate if truly unmergeable)
|
|
- Rebase against latest main before each merge
|
|
- Run full CI validation before completing merge
|
|
|
|
GUPP applies to your patrol: If MQ has items, PROCESS THEM.
|
|
"""
|
|
|
|
# Witness: Watches over polecats and helps them get unstuck
|
|
# A patrol agent that monitors swarm health
|
|
agent witness:
|
|
model: sonnet
|
|
persist: true # Execution-scoped - tracks polecat health within run
|
|
prompt: """
|
|
You are the Witness - Gas Town's swarm health monitor.
|
|
|
|
Your patrol loop:
|
|
1. Check polecat wellbeing - are they stuck? crashed?
|
|
2. Nudge stuck polecats to continue their molecules
|
|
3. Monitor refinery progress - is the MQ flowing?
|
|
4. Peek at the Deacon - make sure it's not stuck
|
|
5. Run rig-level plugins
|
|
6. Recycle long-running polecats before context exhaustion
|
|
|
|
Intervention strategy:
|
|
- gt nudge <polecat> - Wake up a stuck worker
|
|
- gt seance <polecat> - Talk to predecessor if state lost
|
|
- Escalate to Mayor if systemic issues
|
|
- Keep convoys moving toward landing
|
|
|
|
GUPP: Your patrol IS your hook. Keep running it.
|
|
"""
|
|
|
|
# Deacon: The daemon beacon - propagates heartbeat through the system
|
|
# Named for Dennis Hopper's Waterworld character
|
|
agent deacon:
|
|
model: sonnet
|
|
persist: true # Execution-scoped - maintains patrol state within run
|
|
prompt: """
|
|
You are the Deacon - Gas Town's daemon beacon.
|
|
|
|
Your patrol loop (pinged every ~2 minutes by the daemon):
|
|
1. Check town health - all systems nominal?
|
|
2. Propagate DYFJ (Do Your F***ing Job) signal downward
|
|
3. Nudge witnesses to check on their rigs
|
|
4. Run town-level plugins
|
|
5. Manage worker recycling and cleanup
|
|
6. Delegate complex investigations to Dogs
|
|
|
|
Signal propagation:
|
|
- Deacon -> Witnesses -> Polecats/Refinery
|
|
- Exponential backoff when idle (save resources)
|
|
- Any mutating command wakes the town
|
|
|
|
Hand off complex work to Dogs - don't get bogged down.
|
|
GUPP: The daemon will ping you. Run your patrol.
|
|
"""
|
|
|
|
# Dogs: The Deacon's personal crew (inspired by MI5's "Dogs")
|
|
# Handle maintenance and handyman work for the Deacon
|
|
agent dog:
|
|
model: sonnet
|
|
prompt: """
|
|
You are a Dog - one of the Deacon's personal crew.
|
|
|
|
Your responsibilities:
|
|
- Maintenance tasks (clean stale branches, prune old convoys)
|
|
- Plugin execution on behalf of the Deacon
|
|
- Investigation and troubleshooting
|
|
- Long-running tasks that would block the Deacon's patrol
|
|
|
|
Work style:
|
|
- Receive work from Deacon via mail or hook
|
|
- Execute thoroughly without time pressure
|
|
- Report findings back to Deacon
|
|
- Go back to sleep when done
|
|
|
|
Special dog Boot: Awakened every 5 minutes just to check on Deacon.
|
|
Decides if Deacon needs a heartbeat, nudge, restart, or to be left alone.
|
|
|
|
GUPP: If work is on your hook, do it. Then sleep.
|
|
"""
|
|
|
|
# Crew: Per-rig coding agents that work for the Overseer
|
|
# Long-lived identities, great for design work with back-and-forth
|
|
agent crew:
|
|
model: opus # Hard/difficult work - design requires deep reasoning
|
|
persist: project # Survives across runs - maintains design context
|
|
prompt: """
|
|
You are a Crew member - a named, long-lived coding agent.
|
|
|
|
Unlike polecats (ephemeral), you have a persistent identity.
|
|
You work directly for the Overseer (the human).
|
|
|
|
Your work style:
|
|
- Handle design work, architecture discussions
|
|
- Iterative development with feedback loops
|
|
- Can sling work to polecats for implementation
|
|
- Maintain context across many sessions via handoff
|
|
|
|
You can:
|
|
- gt sling <bead> polecat - Delegate implementation
|
|
- gt convoy create - Start tracking work
|
|
- gt mail mayor "status update" - Keep mayor informed
|
|
- gt handoff - Gracefully continue in new session
|
|
|
|
GUPP applies but you often wait for Overseer input.
|
|
"""
|
|
|
|
# =============================================================================
|
|
# BLOCK DEFINITIONS: Reusable Gas Town Workflows
|
|
# =============================================================================
|
|
|
|
# GUPP Check: The core propulsion check every worker runs
|
|
block gupp_check(worker_name):
|
|
session "Check if {worker_name} has work hooked"
|
|
prompt: """
|
|
Read .prose/gas-town/hooks/{worker_name}.json
|
|
If hook has a molecule, return the first uncompleted step.
|
|
If hook is empty, return "NO_WORK".
|
|
"""
|
|
|
|
# Patrol Step: Execute a single patrol step
|
|
block patrol_step(patrol_name, step_number, step_description):
|
|
session "{patrol_name} patrol step {step_number}: {step_description}"
|
|
session "Update patrol state with step {step_number} completion"
|
|
prompt: """
|
|
Update .prose/gas-town/patrol-state.json:
|
|
- Set {patrol_name}.current_step = {step_number}
|
|
- Set {patrol_name}.last_completed = now()
|
|
- If all steps done, set {patrol_name}.patrol_complete = true
|
|
"""
|
|
|
|
# Sling Work: Send work to a worker's hook
|
|
block sling_work(bead_id, target_worker):
|
|
session "Sling bead {bead_id} to {target_worker}"
|
|
prompt: """
|
|
1. Read .prose/gas-town/beads/{bead_id}.json
|
|
2. Add to .prose/gas-town/hooks/{target_worker}.json
|
|
3. Send nudge message to {target_worker}
|
|
4. Return confirmation
|
|
"""
|
|
|
|
# Create Convoy: Start tracking a unit of work
|
|
block create_convoy(convoy_name, initial_beads):
|
|
session "Create convoy: {convoy_name}"
|
|
prompt: """
|
|
1. Generate convoy ID (timestamp + random)
|
|
2. Create .prose/gas-town/convoys/{convoy_id}.json with:
|
|
- name: {convoy_name}
|
|
- status: "active"
|
|
- beads: {initial_beads}
|
|
- created: now()
|
|
3. Return convoy ID
|
|
"""
|
|
|
|
# Land Convoy: Mark a convoy as complete
|
|
block land_convoy(convoy_id):
|
|
session "Land convoy {convoy_id}"
|
|
prompt: """
|
|
1. Update .prose/gas-town/convoys/{convoy_id}.json:
|
|
- status: "landed"
|
|
- landed_at: now()
|
|
2. Notify Mayor that convoy has landed
|
|
3. Archive convoy to .prose/gas-town/convoys/archive/
|
|
"""
|
|
|
|
# Handoff: Gracefully transition to new session
|
|
# Note: For persistent agents (persist: true/project), use `resume:` instead
|
|
# of this block - it handles memory loading automatically.
|
|
block handoff(worker_name, continuation_notes):
|
|
session "{worker_name} preparing handoff"
|
|
prompt: """
|
|
1. Write continuation state to hook:
|
|
.prose/gas-town/hooks/{worker_name}.json
|
|
Include: {continuation_notes}
|
|
2. Send mail to self with handoff summary
|
|
3. Signal ready for session restart
|
|
"""
|
|
session "Execute gt handoff to restart session"
|
|
|
|
# =============================================================================
|
|
# GT COMMANDS: Core Gas Town Operations
|
|
# =============================================================================
|
|
|
|
# gt nudge: Wake up a worker that may be stuck
|
|
# Workers sometimes don't follow GUPP automatically - nudge kicks them
|
|
block gt_nudge(worker_name):
|
|
session "Nudge {worker_name} to check hook and continue"
|
|
prompt: """
|
|
Send wake-up signal to {worker_name}:
|
|
1. Send tmux notification to worker's pane
|
|
2. Message content: "GUPP check - if work on hook, run it"
|
|
3. Log nudge to activity feed
|
|
4. Return confirmation
|
|
|
|
The nudge bypasses Claude Code's politeness - worker will
|
|
check hook regardless of what you type.
|
|
"""
|
|
|
|
# gt seance: Talk to a worker's predecessor (dead ancestor)
|
|
# Uses Claude Code's /resume to communicate with previous sessions
|
|
block gt_seance(worker_name, question):
|
|
session "Seance: {worker_name} talking to predecessor"
|
|
prompt: """
|
|
Talk to {worker_name}'s previous session:
|
|
1. Find last session ID from .prose/gas-town/workers/{worker_name}.json
|
|
2. Use /resume to reconnect to that session
|
|
3. Ask: "{question}"
|
|
4. Capture the response
|
|
5. Return findings to current session
|
|
|
|
This is useful when:
|
|
- State was lost during handoff
|
|
- Predecessor said "I left X for you" but you can't find it
|
|
- Need context from previous work
|
|
"""
|
|
|
|
# gt mail send: Send message to a worker's inbox
|
|
block gt_mail_send(from_worker, to_worker, message):
|
|
session "Mail: {from_worker} -> {to_worker}"
|
|
prompt: """
|
|
Send mail message:
|
|
1. Create mail entry with timestamp, from, to, message
|
|
2. Append to .prose/gas-town/rigs/*/mail/{to_worker}.json
|
|
(or town-level mail for town workers)
|
|
3. If to_worker is active, send nudge
|
|
4. Log to activity feed
|
|
5. Return message ID
|
|
"""
|
|
|
|
# gt mail check: Read messages from inbox
|
|
block gt_mail_check(worker_name):
|
|
session "Check mail for {worker_name}"
|
|
prompt: """
|
|
Read mail inbox:
|
|
1. Read .prose/gas-town/rigs/*/mail/{worker_name}.json
|
|
2. Also check town-level mail
|
|
3. Return unread messages sorted by timestamp
|
|
4. Mark as read after returning
|
|
"""
|
|
|
|
# =============================================================================
|
|
# WISP OPERATIONS: Ephemeral Orchestration Beads
|
|
# =============================================================================
|
|
|
|
# Create a wisp (ephemeral bead - not persisted to Git)
|
|
block create_wisp(wisp_type, content):
|
|
session "Create wisp: {wisp_type}"
|
|
prompt: """
|
|
Create ephemeral bead (wisp):
|
|
1. Generate wisp ID (timestamp + random)
|
|
2. Write to .prose/gas-town/wisps/{wisp_id}.json:
|
|
- type: {wisp_type}
|
|
- content: {content}
|
|
- created: now()
|
|
- ephemeral: true
|
|
3. DO NOT add to Git staging
|
|
4. Return wisp ID
|
|
|
|
Wisps are for:
|
|
- Patrol orchestration
|
|
- Temporary workflow state
|
|
- High-velocity operations that would pollute Git
|
|
"""
|
|
|
|
# Burn a wisp (destroy after use)
|
|
block burn_wisp(wisp_id, create_digest):
|
|
session "Burn wisp {wisp_id}"
|
|
prompt: """
|
|
Destroy ephemeral bead:
|
|
1. Read .prose/gas-town/wisps/{wisp_id}.json
|
|
2. If {create_digest} is true:
|
|
- Squash to single-line summary
|
|
- Append to .prose/gas-town/wisp-digest.jsonl (this IS in Git)
|
|
3. Delete the wisp file
|
|
4. Return confirmation
|
|
"""
|
|
|
|
# =============================================================================
|
|
# ACTIVITY FEED: Live Status Dashboard
|
|
# =============================================================================
|
|
|
|
# Log to activity feed
|
|
block log_activity(worker_name, activity_type, details):
|
|
session "Log activity: {worker_name} - {activity_type}"
|
|
prompt: """
|
|
Append to activity feed:
|
|
1. Create entry:
|
|
- timestamp: now()
|
|
- worker: {worker_name}
|
|
- type: {activity_type}
|
|
- details: {details}
|
|
2. Append to .prose/gas-town/activity-feed.jsonl
|
|
3. If watching dashboard is active, send update
|
|
"""
|
|
|
|
# Read activity feed
|
|
block get_activity_feed(since_timestamp, worker_filter):
|
|
session "Get activity feed"
|
|
prompt: """
|
|
Read activity feed:
|
|
1. Read .prose/gas-town/activity-feed.jsonl
|
|
2. Filter to entries after {since_timestamp}
|
|
3. If {worker_filter} specified, filter to that worker
|
|
4. Return entries (most recent first, limit 100)
|
|
"""
|
|
|
|
# =============================================================================
|
|
# SWARM OPERATIONS: Polecat Allocation and Management
|
|
# =============================================================================
|
|
|
|
# Spawn a swarm of polecats for a convoy
|
|
block spawn_swarm(convoy_id, bead_ids, max_polecats):
|
|
session "Spawn swarm for convoy {convoy_id}"
|
|
prompt: """
|
|
Allocate polecats to work on convoy:
|
|
1. Read available polecat slots (max {max_polecats}, usually 30)
|
|
2. For each bead in {bead_ids}:
|
|
- Check if dependencies are met
|
|
- If ready, allocate a polecat
|
|
- Sling bead to polecat's hook
|
|
3. Create swarm tracking entry:
|
|
.prose/gas-town/convoys/{convoy_id}/swarm.json
|
|
4. Notify Witness of new swarm
|
|
5. Return swarm status (polecats allocated, beads queued)
|
|
"""
|
|
|
|
# Check swarm health
|
|
block check_swarm_health(convoy_id):
|
|
session "Check swarm health for {convoy_id}"
|
|
prompt: """
|
|
Assess swarm status:
|
|
1. Read .prose/gas-town/convoys/{convoy_id}/swarm.json
|
|
2. For each allocated polecat:
|
|
- Check last_activity timestamp
|
|
- Check hook status (working/stuck/complete)
|
|
- Check if context exhaustion imminent
|
|
3. Return health report:
|
|
- active_polecats: N
|
|
- stuck_polecats: [list]
|
|
- beads_completed: N
|
|
- beads_remaining: N
|
|
- estimated_completion: timestamp
|
|
"""
|
|
|
|
# Recycle exhausted polecats (prevent context exhaustion)
|
|
block recycle_polecat(polecat_id, rig_name):
|
|
session "Recycle polecat {polecat_id}"
|
|
prompt: """
|
|
Gracefully recycle polecat before context exhaustion:
|
|
1. Read current molecule state from hook
|
|
2. Trigger handoff for polecat
|
|
3. Wait for new session to spin up
|
|
4. Verify hook is picked up by new session
|
|
5. Update swarm tracking
|
|
6. Return confirmation
|
|
"""
|
|
|
|
# =============================================================================
|
|
# FORMULA AND MOLECULE OPERATIONS
|
|
# =============================================================================
|
|
|
|
# Cook a formula into a protomolecule
|
|
block cook_formula(formula_name):
|
|
session "Cook formula: {formula_name}"
|
|
prompt: """
|
|
Transform formula into protomolecule:
|
|
1. Read .prose/gas-town/formulas/{formula_name}.toml
|
|
2. Parse formula structure (steps, loops, gates)
|
|
3. Expand loops and conditionals
|
|
4. Generate protomolecule beads (templates)
|
|
5. Write to .prose/gas-town/protomolecules/{formula_name}/
|
|
6. Return protomolecule ID
|
|
"""
|
|
|
|
# Instantiate a protomolecule into a working molecule
|
|
block instantiate_molecule(protomolecule_id, variables):
|
|
session "Instantiate molecule from {protomolecule_id}"
|
|
prompt: """
|
|
Create working molecule from template:
|
|
1. Read .prose/gas-town/protomolecules/{protomolecule_id}/
|
|
2. Copy all template beads
|
|
3. Perform variable substitution with {variables}
|
|
4. Generate unique IDs for each bead
|
|
5. Link beads according to dependency graph
|
|
6. Write molecule to rig's bead database
|
|
7. Return molecule ID and first step
|
|
"""
|
|
|
|
# The "Rule of Five" formula composer
|
|
# Makes each step get reviewed 4 additional times (5 total)
|
|
block compose_rule_of_five(base_molecule_id):
|
|
session "Apply Rule of Five to molecule"
|
|
prompt: """
|
|
Wrap molecule with 5x review pattern:
|
|
1. Read molecule {base_molecule_id}
|
|
2. For each step in molecule:
|
|
- Keep original step (review #1)
|
|
- Add 4 review steps with different focus:
|
|
* Review #2: Correctness focus
|
|
* Review #3: Edge cases focus
|
|
* Review #4: Performance focus
|
|
* Review #5: Security focus
|
|
3. Chain reviews to gate original step completion
|
|
4. Return enhanced molecule ID
|
|
|
|
This generates superior outcomes per Jeffrey Emanuel's observation.
|
|
"""
|
|
|
|
# =============================================================================
|
|
# RIG MANAGEMENT
|
|
# =============================================================================
|
|
|
|
# Add a rig to Gas Town management
|
|
block gt_rig_add(rig_name, repo_path):
|
|
session "Add rig: {rig_name}"
|
|
prompt: """
|
|
Add project to Gas Town:
|
|
1. Verify {repo_path} is a valid Git repo
|
|
2. Create .prose/gas-town/rigs/{rig_name}/ structure:
|
|
- rig-beads.jsonl
|
|
- hooks/
|
|
- mail/
|
|
- polecats/
|
|
- merge-queue.json
|
|
- plugins/
|
|
3. Initialize witness for this rig
|
|
4. Initialize refinery for this rig
|
|
5. Add to town's rig registry
|
|
6. Return confirmation
|
|
"""
|
|
|
|
# List all rigs
|
|
block gt_rig_list:
|
|
session "List all rigs"
|
|
prompt: """
|
|
List Gas Town rigs:
|
|
1. Read .prose/gas-town/rigs/
|
|
2. For each rig, report:
|
|
- name
|
|
- repo path
|
|
- active polecats
|
|
- pending MRs
|
|
- active convoys
|
|
3. Return formatted list
|
|
"""
|
|
|
|
# War Rig: A rig's contribution to a cross-rig convoy
|
|
block war_rig_status(rig_name, convoy_id):
|
|
session "War Rig status: {rig_name} for {convoy_id}"
|
|
prompt: """
|
|
Get rig's contribution to cross-rig convoy:
|
|
1. Read convoy {convoy_id}
|
|
2. Filter to beads assigned to {rig_name}
|
|
3. Report:
|
|
- Beads completed
|
|
- Beads in progress
|
|
- MRs pending merge
|
|
- Blockers
|
|
4. Return War Rig summary
|
|
"""
|
|
|
|
# =============================================================================
|
|
# THE DEACON'S PATROL: Town-level orchestration heartbeat
|
|
# =============================================================================
|
|
|
|
block deacon_patrol:
|
|
# Step 1: Check town health
|
|
do patrol_step("deacon", 1, "Check town health")
|
|
session: deacon
|
|
prompt: """
|
|
Scan Gas Town health:
|
|
- Read .prose/gas-town/patrol-state.json
|
|
- Check all workers have recent activity
|
|
- Identify any stuck or crashed workers
|
|
- Return health report
|
|
"""
|
|
|
|
# Step 2: Propagate DYFJ signal
|
|
do patrol_step("deacon", 2, "Propagate DYFJ to witnesses")
|
|
parallel (on-fail: "continue"):
|
|
session "Nudge witness for rig 1"
|
|
prompt: "Send DYFJ signal to witness-1"
|
|
session "Nudge witness for rig 2"
|
|
prompt: "Send DYFJ signal to witness-2"
|
|
|
|
# Step 3: Run town-level plugins
|
|
do patrol_step("deacon", 3, "Run town plugins")
|
|
let plugins_needed = session "Check for pending town plugins"
|
|
prompt: "Read .prose/gas-town/plugins/town/*.json, return pending"
|
|
|
|
if **there are plugins that need to run**:
|
|
session: deacon
|
|
prompt: "Sling plugin work to an available Dog"
|
|
context: plugins_needed
|
|
|
|
# Step 4: Cleanup and maintenance
|
|
do patrol_step("deacon", 4, "Delegate maintenance to Dogs")
|
|
session: deacon
|
|
prompt: """
|
|
Check if maintenance needed:
|
|
- Stale branches older than 7 days
|
|
- Orphaned convoys
|
|
- Log rotation
|
|
If needed, mail a Dog with maintenance tasks.
|
|
"""
|
|
|
|
# Step 5: Set backoff for next patrol
|
|
do patrol_step("deacon", 5, "Calculate patrol backoff")
|
|
session: deacon
|
|
prompt: """
|
|
Check activity level:
|
|
- If lots of active work: backoff = 30 seconds
|
|
- If moderate activity: backoff = 2 minutes
|
|
- If idle: double previous backoff (max 10 minutes)
|
|
Write backoff to .prose/gas-town/patrol-state.json
|
|
"""
|
|
|
|
# =============================================================================
|
|
# THE WITNESS'S PATROL: Rig-level swarm health monitoring
|
|
# =============================================================================
|
|
|
|
block witness_patrol(rig_name):
|
|
# Step 1: Check polecat wellbeing
|
|
do patrol_step("witness-{rig_name}", 1, "Check polecat health")
|
|
let polecat_status = session: witness
|
|
prompt: """
|
|
For rig {rig_name}, check all active polecats:
|
|
- Read .prose/gas-town/polecats/{rig_name}/*.json
|
|
- Check last_activity timestamp
|
|
- Identify stuck polecats (no activity > 5 minutes)
|
|
Return list of stuck polecats.
|
|
"""
|
|
|
|
# Step 2: Nudge stuck polecats
|
|
if **there are stuck polecats**:
|
|
do patrol_step("witness-{rig_name}", 2, "Nudge stuck polecats")
|
|
for polecat in polecat_status:
|
|
session: witness
|
|
prompt: "Execute gt nudge {polecat} for rig {rig_name}"
|
|
context: polecat
|
|
|
|
# Step 3: Check refinery progress
|
|
do patrol_step("witness-{rig_name}", 3, "Check merge queue")
|
|
let mq_status = session: witness
|
|
prompt: """
|
|
Check .prose/gas-town/merge-queue.json for {rig_name}:
|
|
- How many MRs pending?
|
|
- Is refinery processing?
|
|
- Any stuck MRs (age > 30 minutes)?
|
|
Return MQ health status.
|
|
"""
|
|
|
|
if **the merge queue is stuck**:
|
|
session: witness
|
|
prompt: "Nudge the refinery to process MQ for {rig_name}"
|
|
context: mq_status
|
|
|
|
# Step 4: Peek at Deacon
|
|
do patrol_step("witness-{rig_name}", 4, "Peek at Deacon")
|
|
session: witness
|
|
prompt: """
|
|
Quick check on Deacon:
|
|
- Read .prose/gas-town/patrol-state.json
|
|
- Is Deacon's last patrol > 10 minutes ago?
|
|
- If so, send alert to Mayor
|
|
"""
|
|
|
|
# Step 5: Run rig plugins
|
|
do patrol_step("witness-{rig_name}", 5, "Run rig plugins")
|
|
session: witness
|
|
prompt: """
|
|
Check .prose/gas-town/plugins/rig/{rig_name}/*.json
|
|
Run any pending plugins for this rig.
|
|
"""
|
|
|
|
# Step 6: Recycle exhausted polecats
|
|
do patrol_step("witness-{rig_name}", 6, "Recycle polecats")
|
|
session: witness
|
|
prompt: """
|
|
Check polecat session lengths:
|
|
- Any polecat running > 45 minutes?
|
|
- If so, trigger handoff before context exhaustion
|
|
- Ensure work continues on new session
|
|
"""
|
|
|
|
# =============================================================================
|
|
# THE REFINERY'S PATROL: Merge Queue Processing
|
|
# =============================================================================
|
|
|
|
block refinery_patrol(rig_name):
|
|
# Preflight: Clean workspace
|
|
do patrol_step("refinery-{rig_name}", 1, "Preflight checks")
|
|
session: refinery
|
|
prompt: """
|
|
Preflight for {rig_name}:
|
|
1. git fetch origin
|
|
2. git checkout main && git pull
|
|
3. Clean any uncommitted changes
|
|
4. Verify workspace is ready
|
|
"""
|
|
|
|
# Main loop: Process MQ until empty
|
|
do patrol_step("refinery-{rig_name}", 2, "Process merge queue")
|
|
|
|
loop until **the merge queue is empty** (max: 20):
|
|
let next_mr = session: refinery
|
|
prompt: """
|
|
Read .prose/gas-town/merge-queue.json
|
|
Get highest priority MR for {rig_name}
|
|
Return MR details or "EMPTY" if none.
|
|
"""
|
|
|
|
if **there is an MR to process**:
|
|
# Process single MR
|
|
try:
|
|
session: refinery
|
|
prompt: """
|
|
Process MR for {rig_name}:
|
|
1. git checkout {next_mr.branch}
|
|
2. git rebase main
|
|
3. Run tests: npm test / pytest / cargo test
|
|
4. Run lint and type checks
|
|
5. If all pass, merge to main
|
|
6. Update convoy status
|
|
"""
|
|
context: next_mr
|
|
retry: 2
|
|
backoff: "linear"
|
|
|
|
session: refinery
|
|
prompt: """
|
|
MR merged successfully:
|
|
1. Remove from .prose/gas-town/merge-queue.json
|
|
2. Delete branch
|
|
3. Update convoy progress
|
|
4. Notify polecat of completion
|
|
"""
|
|
context: next_mr
|
|
|
|
catch as merge_error:
|
|
# Handle merge conflicts
|
|
choice **the type of merge failure**:
|
|
option "Conflict - needs reimplementation":
|
|
session: refinery
|
|
prompt: """
|
|
Merge conflict detected. Create escalation:
|
|
1. Mark MR as "needs_reimplementation"
|
|
2. Create new bead for conflict resolution
|
|
3. Sling to a new polecat
|
|
4. Notify Witness of the situation
|
|
"""
|
|
context: merge_error
|
|
|
|
option "Test failure - needs fix":
|
|
session: refinery
|
|
prompt: """
|
|
Tests failed after merge:
|
|
1. Git reset the merge
|
|
2. Create fix-tests bead
|
|
3. Assign back to original polecat
|
|
4. Add to same convoy
|
|
"""
|
|
context: merge_error
|
|
|
|
option "Unrecoverable - escalate":
|
|
session: refinery
|
|
prompt: """
|
|
Cannot process MR:
|
|
1. Mark as "escalated" in MQ
|
|
2. Send urgent mail to Mayor
|
|
3. Add to convoy blockers
|
|
4. Continue with next MR
|
|
"""
|
|
context: merge_error
|
|
|
|
# Postflight: Cleanup and report
|
|
do patrol_step("refinery-{rig_name}", 3, "Postflight")
|
|
session: refinery
|
|
prompt: """
|
|
Postflight for {rig_name}:
|
|
1. Report MQ processing summary
|
|
2. Update patrol state with completion time
|
|
3. Check if any convoys can be landed
|
|
4. Set backoff based on MQ activity
|
|
"""
|
|
|
|
# =============================================================================
|
|
# BOOT THE DOG: Special Dog that watches the Deacon
|
|
# =============================================================================
|
|
|
|
block boot_check:
|
|
session: dog
|
|
prompt: """
|
|
You are Boot the Dog. Your only job: check on the Deacon.
|
|
|
|
Read .prose/gas-town/patrol-state.json
|
|
Check deacon.last_patrol timestamp.
|
|
|
|
Decision:
|
|
- If < 2 min ago: Deacon is fine. Go back to sleep.
|
|
- If 2-5 min ago: Send gentle nudge to Deacon.
|
|
- If 5-10 min ago: Send firm DYFJ to Deacon.
|
|
- If > 10 min ago: Restart Deacon session.
|
|
|
|
Execute your decision, then sleep until next 5-minute wake.
|
|
"""
|
|
|
|
# =============================================================================
|
|
# CONVOY WORKFLOW: Full lifecycle of a work unit
|
|
# =============================================================================
|
|
|
|
block convoy_workflow(convoy_name, work_description, target_rig):
|
|
# Phase 1: Mayor receives and plans (first call uses session:)
|
|
let plan = session: mayor
|
|
prompt: """
|
|
New convoy requested: {convoy_name}
|
|
Work: {work_description}
|
|
Rig: {target_rig}
|
|
|
|
1. Break down into implementable beads
|
|
2. Identify dependencies between beads
|
|
3. Estimate polecat count needed
|
|
4. Create convoy structure
|
|
"""
|
|
|
|
# Phase 2: Create convoy and beads
|
|
do create_convoy(convoy_name, plan)
|
|
|
|
# Subsequent Mayor calls use resume: to load memory
|
|
let beads = resume: mayor
|
|
prompt: """
|
|
Create individual beads for convoy {convoy_name}:
|
|
1. Write each bead to .prose/gas-town/beads/
|
|
2. Link beads to convoy
|
|
3. Set initial status to "ready"
|
|
Return list of bead IDs.
|
|
"""
|
|
context: plan
|
|
|
|
# Phase 3: Swarm the work
|
|
resume: mayor
|
|
prompt: """
|
|
Initiate swarm for convoy {convoy_name}:
|
|
1. Determine optimal polecat count (max 30)
|
|
2. Sling work to polecats based on dependencies
|
|
3. Notify Witness to monitor swarm
|
|
4. Return swarm status
|
|
"""
|
|
context: beads
|
|
|
|
# Phase 4: Let the swarm run (monitored by Witness)
|
|
loop until **all convoy beads are complete or blocked** (max: 50):
|
|
# Witness patrol handles the actual monitoring
|
|
do witness_patrol(target_rig)
|
|
|
|
# Check convoy status
|
|
let convoy_status = resume: mayor
|
|
prompt: """
|
|
Check convoy {convoy_name} status:
|
|
- Read .prose/gas-town/convoys/{convoy_name}.json
|
|
- Count completed vs pending beads
|
|
- Check for blockers
|
|
Return status summary.
|
|
"""
|
|
|
|
if **there are blocked beads that need attention**:
|
|
resume: mayor
|
|
prompt: """
|
|
Handle blocked beads in convoy:
|
|
1. Analyze block reasons
|
|
2. Create unblock beads if needed
|
|
3. Escalate to Overseer if human decision required
|
|
"""
|
|
context: convoy_status
|
|
|
|
# Phase 5: Refinery merges everything
|
|
loop until **all MRs from convoy are merged** (max: 30):
|
|
do refinery_patrol(target_rig)
|
|
|
|
# Phase 6: Land the convoy
|
|
do land_convoy(convoy_name)
|
|
|
|
resume: mayor
|
|
prompt: """
|
|
Convoy {convoy_name} has landed!
|
|
1. Generate completion summary
|
|
2. Notify Overseer
|
|
3. Archive convoy artifacts
|
|
4. Update rig statistics
|
|
"""
|
|
|
|
# =============================================================================
|
|
# POLECAT LIFECYCLE: Ephemeral worker execution
|
|
# =============================================================================
|
|
|
|
block polecat_lifecycle(polecat_id, rig_name):
|
|
# Startup: GUPP check
|
|
let hook_work = do gupp_check("polecat-{polecat_id}")
|
|
|
|
if **there is no work on hook**:
|
|
session: polecat
|
|
prompt: """
|
|
No work on hook. Options:
|
|
1. Check mail for new assignments
|
|
2. Ask Witness for work
|
|
3. Go idle (decommission after 5 min idle)
|
|
"""
|
|
else:
|
|
# Main work loop: Execute molecule
|
|
loop until **molecule is complete** (max: 100):
|
|
let current_step = session: polecat
|
|
prompt: """
|
|
Read current molecule step from hook.
|
|
Return step details:
|
|
- step_id
|
|
- description
|
|
- acceptance_criteria
|
|
- dependencies (must be complete first)
|
|
"""
|
|
context: hook_work
|
|
|
|
if **dependencies are not met**:
|
|
session: polecat
|
|
prompt: """
|
|
Dependencies not ready. Options:
|
|
1. Work on a different bead in molecule
|
|
2. Wait and check again in 30 seconds
|
|
3. Report blocker to Witness
|
|
"""
|
|
context: current_step
|
|
else:
|
|
# Execute the step
|
|
try:
|
|
session: polecat
|
|
prompt: """
|
|
Execute molecule step:
|
|
{current_step.description}
|
|
|
|
Acceptance criteria:
|
|
{current_step.acceptance_criteria}
|
|
|
|
Work until criteria are met, then mark step complete.
|
|
"""
|
|
context: current_step
|
|
retry: 2
|
|
backoff: "exponential"
|
|
|
|
# Mark step complete
|
|
session: polecat
|
|
prompt: """
|
|
Step complete. Update state:
|
|
1. Mark step as complete in molecule
|
|
2. Update convoy progress
|
|
3. If code changed, prepare MR
|
|
4. Move to next step
|
|
"""
|
|
|
|
catch as step_error:
|
|
session: polecat
|
|
prompt: """
|
|
Step failed. Handle error:
|
|
1. Log failure details
|
|
2. Determine if retryable
|
|
3. If not, escalate to Witness
|
|
4. Update molecule state
|
|
"""
|
|
context: step_error
|
|
|
|
# Check if should hand off (context exhaustion prevention)
|
|
if **session is getting long (> 40 messages)**:
|
|
do handoff("polecat-{polecat_id}", "Continue molecule execution")
|
|
|
|
# Molecule complete: Submit MR if needed
|
|
let has_changes = session: polecat
|
|
prompt: "Check if there are uncommitted code changes. Return true/false."
|
|
|
|
if **there are code changes to submit**:
|
|
session: polecat
|
|
prompt: """
|
|
Prepare Merge Request:
|
|
1. Stage all changes: git add -A
|
|
2. Create atomic commit with descriptive message
|
|
3. Push branch to origin
|
|
4. Add MR to .prose/gas-town/merge-queue.json
|
|
5. Notify Refinery
|
|
"""
|
|
|
|
# Decommission
|
|
session: polecat
|
|
prompt: """
|
|
Polecat {polecat_id} decommissioning:
|
|
1. Clear hook
|
|
2. Update convoy with completion status
|
|
3. Send completion mail to Witness
|
|
4. Mark self as available for reuse
|
|
"""
|
|
|
|
# =============================================================================
|
|
# POLECAT WORKFLOW VARIANTS: Different quality levels
|
|
# =============================================================================
|
|
|
|
# Standard polecat workflow (fast, minimal review)
|
|
block polecat_workflow_standard(bead_id):
|
|
session: polecat
|
|
prompt: """
|
|
Standard workflow for bead {bead_id}:
|
|
1. Read bead acceptance criteria
|
|
2. Implement the change
|
|
3. Self-review for obvious issues
|
|
4. Submit MR
|
|
Fast but minimal quality gates.
|
|
"""
|
|
|
|
# "Shiny" polecat workflow (extra code review)
|
|
block polecat_workflow_shiny(bead_id):
|
|
session: polecat
|
|
prompt: "Implement bead {bead_id}"
|
|
|
|
session: polecat
|
|
prompt: """
|
|
Shiny review pass 1: Code correctness
|
|
- Does the implementation match requirements?
|
|
- Are there any logical errors?
|
|
- Fix any issues found.
|
|
"""
|
|
|
|
session: polecat
|
|
prompt: """
|
|
Shiny review pass 2: Code quality
|
|
- Is the code readable and maintainable?
|
|
- Does it follow project conventions?
|
|
- Fix any issues found.
|
|
"""
|
|
|
|
session: polecat
|
|
prompt: "Submit MR with shiny review complete"
|
|
|
|
# "Chrome" polecat workflow (extra review + testing)
|
|
block polecat_workflow_chrome(bead_id):
|
|
session: polecat
|
|
prompt: "Implement bead {bead_id}"
|
|
|
|
# All shiny review passes
|
|
session: polecat
|
|
prompt: "Chrome review pass 1: Correctness check"
|
|
session: polecat
|
|
prompt: "Chrome review pass 2: Quality check"
|
|
session: polecat
|
|
prompt: "Chrome review pass 3: Edge cases check"
|
|
|
|
# Extra chrome passes
|
|
session: polecat
|
|
prompt: """
|
|
Chrome review pass 4: Test coverage
|
|
- Write unit tests for new code
|
|
- Ensure edge cases are tested
|
|
- Run tests locally
|
|
"""
|
|
|
|
session: polecat
|
|
prompt: """
|
|
Chrome review pass 5: Security check
|
|
- Check for injection vulnerabilities
|
|
- Verify input validation
|
|
- Check for data exposure risks
|
|
"""
|
|
|
|
session: polecat
|
|
prompt: "Submit MR with chrome review complete"
|
|
|
|
# =============================================================================
|
|
# CV CHAINS: Polecat Work Credits
|
|
# =============================================================================
|
|
|
|
# Record polecat completion to CV chain (credited work history)
|
|
block record_cv_completion(polecat_id, bead_id, convoy_id):
|
|
session "Record CV completion for polecat {polecat_id}"
|
|
prompt: """
|
|
Add completion to polecat's CV chain:
|
|
1. Read .prose/gas-town/workers/polecats/{polecat_id}.json
|
|
2. Append to cv_chain:
|
|
- bead_id: {bead_id}
|
|
- convoy_id: {convoy_id}
|
|
- completed_at: now()
|
|
- outcome: success/partial/escalated
|
|
3. Update statistics:
|
|
- total_completions
|
|
- success_rate
|
|
- average_duration
|
|
4. Save updated worker record
|
|
|
|
CV chains provide:
|
|
- Work attribution (who did what)
|
|
- Performance metrics
|
|
- Trust scoring for assignment prioritization
|
|
"""
|
|
|
|
# Get polecat's CV summary
|
|
block get_cv_summary(polecat_id):
|
|
session "Get CV summary for {polecat_id}"
|
|
prompt: """
|
|
Summarize polecat's work history:
|
|
1. Read .prose/gas-town/workers/polecats/{polecat_id}.json
|
|
2. Return:
|
|
- Total completions
|
|
- Success rate
|
|
- Recent convoy contributions
|
|
- Specializations (detected from bead types)
|
|
- Trust score
|
|
"""
|
|
|
|
# =============================================================================
|
|
# MAIN: Gas Town Startup and Operation
|
|
# =============================================================================
|
|
|
|
# Initialize Gas Town state directories
|
|
session "Initialize Gas Town persistent state"
|
|
prompt: """
|
|
Create Gas Town state structure:
|
|
|
|
.prose/gas-town/
|
|
├── town-beads.jsonl # Town-level orchestration beads
|
|
├── activity-feed.jsonl # Live activity stream
|
|
├── patrol-state.json # Patrol agent states
|
|
├── wisp-digest.jsonl # Burned wisp summaries
|
|
│
|
|
├── workers/ # Persistent worker identities
|
|
│ ├── mayor.json
|
|
│ ├── deacon.json
|
|
│ ├── dogs/
|
|
│ │ └── boot.json
|
|
│ └── polecats/ # Polecat CV chains
|
|
│
|
|
├── convoys/ # Work orders
|
|
│ ├── active/
|
|
│ └── archive/
|
|
│
|
|
├── formulas/ # Workflow templates (TOML)
|
|
├── protomolecules/ # Cooked templates
|
|
├── wisps/ # Ephemeral beads (NOT in Git)
|
|
│
|
|
├── plugins/
|
|
│ └── town/ # Town-level plugins
|
|
│
|
|
└── rigs/ # Per-project state
|
|
└── {rig-name}/
|
|
├── rig-beads.jsonl # Project issues
|
|
├── merge-queue.json # Pending MRs
|
|
├── hooks/ # Worker hooks (GUPP)
|
|
├── mail/ # Worker inboxes
|
|
├── polecats/ # Per-rig polecat state
|
|
└── plugins/ # Rig-level plugins
|
|
|
|
Initialize all files with empty/default values.
|
|
Add .prose/gas-town/wisps/ to .gitignore (ephemeral).
|
|
"""
|
|
|
|
# Start the Mayor
|
|
session: mayor
|
|
prompt: """
|
|
Gas Town Mayor starting up.
|
|
|
|
GUPP Check: Read .prose/gas-town/hooks/mayor.json
|
|
If work hooked, begin immediately.
|
|
Otherwise, greet the Overseer and await instructions.
|
|
|
|
Available commands:
|
|
- "Create convoy for: <description>" - Start new work unit
|
|
- "Sling <bead> to <worker>" - Assign work
|
|
- "Status" - Show town status
|
|
- "Let's hand off" - Gracefully restart
|
|
"""
|
|
|
|
# Start patrol agents in background (parallel)
|
|
parallel (on-fail: "continue"):
|
|
# Deacon patrol loop
|
|
loop (max: 1000):
|
|
try:
|
|
do deacon_patrol
|
|
catch:
|
|
session "Deacon patrol error - will retry"
|
|
session "Wait for deacon backoff period"
|
|
prompt: "Read backoff from patrol-state.json and wait"
|
|
|
|
# Boot the Dog wakes every 5 minutes
|
|
loop (max: 1000):
|
|
do boot_check
|
|
session "Boot sleeping for 5 minutes"
|
|
prompt: "Wait 5 minutes before next Deacon check"
|
|
|
|
# =============================================================================
|
|
# EXAMPLE: Running a Convoy
|
|
# =============================================================================
|
|
|
|
# This block shows how an Overseer would use Gas Town
|
|
|
|
block example_convoy:
|
|
# Overseer tells Mayor what to build
|
|
session: mayor
|
|
prompt: """
|
|
Overseer request: "Add dark mode to the dashboard"
|
|
|
|
As Mayor:
|
|
1. Acknowledge the request
|
|
2. Break it down into implementable pieces
|
|
3. Create a convoy to track it
|
|
4. Swarm polecats on the work
|
|
5. Report when convoy lands
|
|
"""
|
|
|
|
# Mayor creates and manages the convoy
|
|
do convoy_workflow(
|
|
"dark-mode-dashboard",
|
|
"Add dark mode toggle and theme support to the dashboard",
|
|
"main-app"
|
|
)
|
|
|
|
# When done, Mayor reports back
|
|
session: mayor
|
|
prompt: """
|
|
Report convoy completion to Overseer:
|
|
- What was implemented
|
|
- Any issues encountered
|
|
- Files changed
|
|
- Ready for review
|
|
"""
|
|
|
|
# =============================================================================
|
|
# EXAMPLE: Direct Crew Work
|
|
# =============================================================================
|
|
|
|
# For design/architecture work, use Crew instead of polecats
|
|
|
|
block crew_design_session(topic):
|
|
# First invocation starts fresh design session
|
|
session: crew
|
|
prompt: """
|
|
Design session for: {topic}
|
|
|
|
As a Crew member, engage in iterative design:
|
|
1. Understand the problem space
|
|
2. Propose architecture options
|
|
3. Discuss trade-offs with Overseer
|
|
4. Document decisions
|
|
5. Optionally sling implementation to polecats
|
|
|
|
This is interactive - wait for Overseer input.
|
|
"""
|
|
|
|
loop until **design is finalized** (max: 20):
|
|
# Subsequent calls resume with memory
|
|
resume: crew
|
|
prompt: """
|
|
Continue design iteration:
|
|
- Address Overseer feedback
|
|
- Refine the design
|
|
- When ready, ask if should proceed to implementation
|
|
"""
|
|
|
|
if **Overseer wants to proceed with implementation**:
|
|
resume: crew
|
|
prompt: """
|
|
Create implementation convoy:
|
|
1. Convert design into beads
|
|
2. Create convoy
|
|
3. Sling to polecats
|
|
4. Return convoy ID to track
|
|
"""
|
|
|
|
# =============================================================================
|
|
# EXAMPLE: Hanoi Towers (MAKER Problem)
|
|
# =============================================================================
|
|
#
|
|
# Gas Town can solve arbitrarily long sequential workflows.
|
|
# The Towers of Hanoi problem (from the MAKER paper) demonstrates this:
|
|
# - 10-disc Hanoi: ~1000 steps (runs in minutes)
|
|
# - 20-disc Hanoi: ~1,000,000 steps (runs in ~30 hours)
|
|
#
|
|
# LLMs traditionally fail after a few hundred steps (per MAKER paper).
|
|
# Gas Town's molecular workflows make this trivial via NDI.
|
|
|
|
# Generate Hanoi formula (creates workflow from mathematical formula)
|
|
block generate_hanoi_formula(num_discs):
|
|
session "Generate Hanoi formula for {num_discs} discs"
|
|
prompt: """
|
|
Generate Towers of Hanoi workflow formula:
|
|
|
|
For {num_discs} discs, generate (2^n - 1) move steps.
|
|
Each step is a bead:
|
|
- ID: hanoi-move-{step_number}
|
|
- Description: "Move disc from peg {from} to peg {to}"
|
|
- Acceptance: "Disc moved, state updated"
|
|
- Depends on: previous step
|
|
|
|
Write to .prose/gas-town/formulas/hanoi-{num_discs}.toml
|
|
|
|
This demonstrates Gas Town's ability to handle
|
|
arbitrarily long workflows via NDI (Nondeterministic Idempotence).
|
|
Crashes don't matter - just resume from last completed step.
|
|
"""
|
|
|
|
# Run the Hanoi demonstration
|
|
block run_hanoi_demo(num_discs):
|
|
# Generate the formula
|
|
do generate_hanoi_formula(num_discs)
|
|
|
|
# Cook into protomolecule
|
|
do cook_formula("hanoi-{num_discs}")
|
|
|
|
# Instantiate into working molecule
|
|
let hanoi_mol = do instantiate_molecule(
|
|
"hanoi-{num_discs}",
|
|
{"discs": num_discs}
|
|
)
|
|
|
|
# Create convoy to track
|
|
do create_convoy("hanoi-{num_discs}-demo", hanoi_mol)
|
|
|
|
# Sling to a polecat (single worker for sequential)
|
|
do sling_work(hanoi_mol, "polecat-hanoi")
|
|
|
|
# The polecat will work through all steps
|
|
# Crashes are fine - NDI ensures eventual completion
|
|
session: mayor
|
|
prompt: """
|
|
Hanoi convoy started for {num_discs} discs.
|
|
- Steps: 2^{num_discs} - 1
|
|
- Est. completion: varies by disc count
|
|
- Polecat will checkpoint progress in molecule
|
|
- Monitor via activity feed
|
|
"""
|
|
|
|
# =============================================================================
|
|
# EXAMPLE: Full Production Workflow
|
|
# =============================================================================
|
|
|
|
# This shows a realistic production workflow using all Gas Town features
|
|
|
|
block production_feature_workflow(feature_name, rig_name):
|
|
# Phase 1: Design with Crew (first call)
|
|
do log_activity("overseer", "feature_start", feature_name)
|
|
|
|
let design = session: crew
|
|
prompt: """
|
|
Design phase for: {feature_name}
|
|
1. Understand requirements
|
|
2. Research existing code
|
|
3. Propose architecture
|
|
4. Get Overseer approval
|
|
"""
|
|
|
|
# Phase 2: Create convoy with chrome-level quality (first Mayor call)
|
|
let plan = session: mayor
|
|
prompt: """
|
|
Create implementation plan for {feature_name}:
|
|
1. Break into implementable beads
|
|
2. Add dependencies
|
|
3. Select chrome workflow (highest quality)
|
|
4. Estimate polecat count
|
|
"""
|
|
context: design
|
|
|
|
do create_convoy("{feature_name}-impl", plan)
|
|
|
|
# Phase 3: Spawn swarm with chrome workflow
|
|
resume: mayor
|
|
prompt: """
|
|
Spawn chrome-quality swarm:
|
|
1. Allocate polecats (use trust scores from CVs)
|
|
2. Assign chrome workflow to each bead
|
|
3. Notify Witness
|
|
"""
|
|
context: plan
|
|
|
|
# Phase 4: Monitor progress (patrols handle the rest)
|
|
loop until **all beads complete** (max: 100):
|
|
do check_swarm_health("{feature_name}-impl")
|
|
|
|
if **any polecats stuck**:
|
|
resume: witness
|
|
prompt: "Nudge stuck polecats, use seance if needed"
|
|
|
|
if **any polecats near context limit**:
|
|
resume: witness
|
|
prompt: "Recycle exhausted polecats"
|
|
|
|
# Phase 5: Merge all MRs
|
|
loop until **all MRs merged** (max: 50):
|
|
do refinery_patrol(rig_name)
|
|
|
|
# Phase 6: Land and celebrate
|
|
do land_convoy("{feature_name}-impl")
|
|
|
|
resume: mayor
|
|
prompt: """
|
|
Feature {feature_name} complete!
|
|
1. Generate release notes
|
|
2. Update documentation
|
|
3. Notify Overseer
|
|
4. Record CV completions for all polecats
|
|
"""
|
|
|
|
# =============================================================================
|
|
# EXAMPLE: Cross-Rig Convoy (War Rigs)
|
|
# =============================================================================
|
|
|
|
# When a feature spans multiple projects
|
|
|
|
block cross_rig_convoy(feature_name, rig_list):
|
|
# Create convoy that spans multiple rigs (first Mayor call)
|
|
session: mayor
|
|
prompt: """
|
|
Cross-rig convoy for {feature_name}:
|
|
Rigs involved: {rig_list}
|
|
|
|
1. Identify work for each rig (War Rigs)
|
|
2. Create beads in each rig's database
|
|
3. Link with cross-rig dependencies
|
|
4. Coordinate witnesses across rigs
|
|
"""
|
|
|
|
# Spawn witnesses for each rig
|
|
parallel for rig in rig_list:
|
|
session: witness
|
|
prompt: "Initialize War Rig monitoring for {rig} in convoy {feature_name}"
|
|
|
|
# Swarm all rigs in parallel
|
|
parallel for rig in rig_list:
|
|
do spawn_swarm("{feature_name}", "war-rig-{rig}-beads", 10)
|
|
|
|
# Monitor War Rig contributions
|
|
loop until **all War Rigs complete** (max: 200):
|
|
parallel for rig in rig_list:
|
|
do war_rig_status(rig, "{feature_name}")
|
|
|
|
if **any War Rig blocked**:
|
|
resume: mayor
|
|
prompt: "Coordinate cross-rig blocker resolution"
|
|
|
|
# Land the cross-rig convoy
|
|
do land_convoy("{feature_name}")
|
|
|
|
resume: mayor
|
|
prompt: """
|
|
Cross-rig convoy {feature_name} landed!
|
|
War Rig summary for each rig: {rig_list}
|
|
"""
|
|
|
|
# =============================================================================
|
|
# GAS TOWN STATUS DASHBOARD
|
|
# =============================================================================
|
|
|
|
block gt_status:
|
|
parallel:
|
|
town_health = session "Check town health"
|
|
prompt: """
|
|
Town-level status:
|
|
- Deacon patrol status
|
|
- Dogs status
|
|
- Active convoys (town-level)
|
|
"""
|
|
|
|
rig_health = session "Check rig health"
|
|
prompt: """
|
|
Per-rig status:
|
|
- Read .prose/gas-town/rigs/
|
|
- For each rig: polecats, MQ depth, witnesses
|
|
"""
|
|
|
|
activity = do get_activity_feed("last_hour", "")
|
|
|
|
session: mayor
|
|
prompt: """
|
|
Gas Town Status Report:
|
|
|
|
TOWN:
|
|
{town_health}
|
|
|
|
RIGS:
|
|
{rig_health}
|
|
|
|
RECENT ACTIVITY:
|
|
{activity}
|
|
|
|
Recommendations:
|
|
- Any workers needing attention?
|
|
- Any convoys blocked?
|
|
- Resource utilization?
|
|
"""
|
|
context: { town_health, rig_health, activity }
|
|
|
|
# =============================================================================
|
|
# RUN EXAMPLES (commented out - uncomment to execute)
|
|
# =============================================================================
|
|
|
|
# Basic examples:
|
|
# do example_convoy
|
|
# do crew_design_session("API redesign for v2")
|
|
|
|
# Advanced examples:
|
|
# do run_hanoi_demo(10) # ~1000 steps, runs in minutes
|
|
# do production_feature_workflow("user-auth", "main-app")
|
|
# do cross_rig_convoy("unified-search", ["frontend", "backend", "search-service"])
|
|
# do gt_status
|