From f75eeb4da8ebf7367107b160c53575a603696ce3 Mon Sep 17 00:00:00 2001 From: gastown/crew/gus Date: Thu, 1 Jan 2026 11:18:09 -0800 Subject: [PATCH] fix: Remove YAML usage, standardize on JSON/TOML MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Delete 5 legacy .formula.yaml files (have .toml replacements) - Remove unused FileConfigYAML constant - Add TODO for beads config.yaml → config.json migration (bd-10wg) - Update docs to use JSON examples instead of yaml code blocks - Change plugin frontmatter from YAML to TOML in docs - Add .toml to code file detection in branch_check.go 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../formulas/mol-deacon-patrol.formula.toml | 2 +- .beads/formulas/rule-of-five.formula.yaml | 35 ------ .beads/formulas/security-audit.formula.yaml | 31 ----- .beads/formulas/shiny-enterprise.formula.yaml | 45 -------- .beads/formulas/shiny.formula.yaml | 39 ------- .beads/formulas/towers-of-hanoi.formula.yaml | 109 ------------------ docs/why-these-features.md | 6 +- internal/cmd/gitinit.go | 2 +- internal/constants/constants.go | 3 - internal/doctor/branch_check.go | 3 +- internal/rig/manager.go | 4 +- internal/templates/roles/witness.md.tmpl | 27 ++--- 12 files changed, 20 insertions(+), 286 deletions(-) delete mode 100644 .beads/formulas/rule-of-five.formula.yaml delete mode 100644 .beads/formulas/security-audit.formula.yaml delete mode 100644 .beads/formulas/shiny-enterprise.formula.yaml delete mode 100644 .beads/formulas/shiny.formula.yaml delete mode 100644 .beads/formulas/towers-of-hanoi.formula.yaml diff --git a/.beads/formulas/mol-deacon-patrol.formula.toml b/.beads/formulas/mol-deacon-patrol.formula.toml index 3dfb1984..cdf746aa 100644 --- a/.beads/formulas/mol-deacon-patrol.formula.toml +++ b/.beads/formulas/mol-deacon-patrol.formula.toml @@ -323,7 +323,7 @@ needs = ["health-scan"] 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). +Scan ~/gt/plugins/ for plugin directories. Each plugin has a plugin.md with TOML frontmatter defining its gate (when to run) and instructions (what to do). See docs/deacon-plugins.md for full documentation. diff --git a/.beads/formulas/rule-of-five.formula.yaml b/.beads/formulas/rule-of-five.formula.yaml deleted file mode 100644 index 2c541659..00000000 --- a/.beads/formulas/rule-of-five.formula.yaml +++ /dev/null @@ -1,35 +0,0 @@ -formula: rule-of-five -type: expansion -description: > - Jeffrey Emanuel's discovery: LLM agents produce best work through 4-5 - iterative refinements. Breadth-first exploration, then editorial passes. -version: 1 -template: - - id: "{target}.draft" - description: > - Initial attempt at: {target.description}. Don't aim for perfection. - Get the shape right. Breadth over depth. - - - id: "{target}.refine-1" - description: > - First refinement pass. Focus: CORRECTNESS. Fix errors, bugs, mistakes. - Is the logic sound? - needs: ["{target}.draft"] - - - id: "{target}.refine-2" - description: > - Second refinement pass. Focus: CLARITY. Can someone else understand - this? Simplify. Remove jargon. - needs: ["{target}.refine-1"] - - - id: "{target}.refine-3" - description: > - Third refinement pass. Focus: EDGE CASES. What could go wrong? - What's missing? Handle the unusual. - needs: ["{target}.refine-2"] - - - id: "{target}.refine-4" - description: > - Final polish. Focus: EXCELLENCE. This is the last pass. Make it shine. - Is this something you'd be proud to ship? - needs: ["{target}.refine-3"] diff --git a/.beads/formulas/security-audit.formula.yaml b/.beads/formulas/security-audit.formula.yaml deleted file mode 100644 index ad3ca5a1..00000000 --- a/.beads/formulas/security-audit.formula.yaml +++ /dev/null @@ -1,31 +0,0 @@ -formula: security-audit -type: aspect -description: > - Cross-cutting security concern. Applies security scanning before and - after implementation steps. -version: 1 -pointcuts: - - glob: "*.implement" - - glob: "*.submit" -advice: - around: - before: - - id: security-prescan - description: > - Pre-implementation security check. Review for secrets/credentials - in scope. Check dependencies for known vulnerabilities. - args: - target: "{step.id}" - after: - - id: security-postscan - description: > - Post-implementation security scan. Scan new code for vulnerabilities - (SAST). Check for hardcoded secrets. Review for OWASP Top 10 issues. - args: - target: "{step.id}" - output: - approved: boolean - findings: list - - gate: - condition: "security-postscan.output.approved == true" - message: Security approval required before proceeding diff --git a/.beads/formulas/shiny-enterprise.formula.yaml b/.beads/formulas/shiny-enterprise.formula.yaml deleted file mode 100644 index c14f6199..00000000 --- a/.beads/formulas/shiny-enterprise.formula.yaml +++ /dev/null @@ -1,45 +0,0 @@ -formula: shiny-enterprise -extends: shiny -description: > - Enterprise-grade engineering workflow. Shiny + Rule of Five + Security + - Performance Testing + Review Loop. -version: 1 -compose: - - expand: - target: implement - with: rule-of-five - - - aspect: - pointcut: "implement.*" - with: security-audit - - - gate: - before: submit - condition: "security-postscan.approved == true" - message: Cannot submit without security approval - - - branch: - from: implement.refine-4 - steps: - - id: perf-test - description: Run performance benchmarks - - id: load-test - description: Run load/stress tests - - id: chaos-test - description: Run chaos engineering tests - join: review - - - loop: - step: review - until: "review.output.approved == true" - max: 3 - on-max: escalate - - - advice: - target: "*" - before: - id: log-start - description: "Log: Starting {step.id}" - after: - id: log-end - description: "Log: Completed {step.id}" diff --git a/.beads/formulas/shiny.formula.yaml b/.beads/formulas/shiny.formula.yaml deleted file mode 100644 index a5416e14..00000000 --- a/.beads/formulas/shiny.formula.yaml +++ /dev/null @@ -1,39 +0,0 @@ -formula: shiny -description: > - Engineer in a Box - the canonical right way. Design before you code. - Review before you ship. Test before you submit. -version: 1 -vars: - feature: "{{feature}}" - assignee: "{{assignee}}" -steps: - - id: design - 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: implement - description: > - Write the code for {{feature}}. Follow the design. Keep it simple. - Don't gold-plate. - needs: [design] - - - id: review - description: > - Review the implementation. Check for: Does it match the design? - Are there obvious bugs? Is it readable and maintainable? - Are there security concerns? - needs: [implement] - - - id: test - description: > - Write and run tests. Unit tests for new code, integration tests - if needed, run the full test suite, fix any regressions. - needs: [review] - - - id: submit - description: > - Submit for merge. Final check: git status, git diff. Commit with - clear message. Push and create PR. - needs: [test] diff --git a/.beads/formulas/towers-of-hanoi.formula.yaml b/.beads/formulas/towers-of-hanoi.formula.yaml deleted file mode 100644 index 6e284483..00000000 --- a/.beads/formulas/towers-of-hanoi.formula.yaml +++ /dev/null @@ -1,109 +0,0 @@ -# Towers of Hanoi Formula -# -# Demonstrates that molecule algebra solves the "million step workflow" problem. -# LLMs fail on long sequences because errors accumulate (99.9%^1000 ≈ 37% success). -# MAKER used voting to reduce error. We use mechanical structure instead. -# -# Key insight: The move sequence is deterministic. Only execution needs AI. -# And each step is trivial: "move disk X from peg Y to peg Z". -# -# For n disks: 2^n - 1 moves -# 20 disks = 1,048,575 moves (the "million step" problem) -# -# Currently hardcoded for 3 disks (7 moves) as proof of concept. -# For million-step version, need to implement range expansion in cook. - -formula: towers-of-hanoi -version: 2 -description: | - AGENT EXECUTION PROTOCOL - Towers of Hanoi - - PURPOSE: This is a durability proof, not computation. Steps are pre-computed. - Your job is to execute them mechanically, proving crash-recovery at scale. - - EXECUTION LOOP: - 1. Find current state: bd mol current - 2. Find the next ready (unblocked) step - 3. Close it: bd close - 4. Repeat until no ready steps remain - - ON RESUME (after crash/restart/handoff): - - Same as fresh start. The molecule IS the state. - - Query `bd mol current `, continue from there. - - No memory of previous session needed. - - DO: - - Close steps as fast as possible (they're trivial mechanical moves) - - Use `gt handoff` when context fills (proactive cycling) - - Trust the pre-computed solution - every move is already correct - - DO NOT: - - Try to solve Hanoi yourself - moves are already computed - - Mark steps in_progress - just close them directly - - Ask for permission - this is GUPP territory, just execute - - Stop for human input - run autonomously until complete - - MONITORING: - - Progress: Count closed children of the molecule - - For mega-molecules: Use convoy dashboard when available - - Completion: All steps closed = molecule complete - - This proves Gas Town can execute arbitrarily long workflows with - nondeterministic idempotence - different sessions, same outcome. - -vars: - source_peg: - default: "A" - description: "Starting peg" - target_peg: - default: "C" - description: "Target peg" - auxiliary_peg: - default: "B" - description: "Helper peg" - -# 3-disk solution: 7 moves (2^3 - 1) -steps: - - id: setup - title: "Verify initial state" - description: "All 3 disks stacked on peg A. Largest on bottom." - - - id: move-1 - title: "Move disk 1: A → C" - description: "Move the smallest disk from peg A to peg C." - needs: [setup] - - - id: move-2 - title: "Move disk 2: A → B" - description: "Move disk 2 from peg A to peg B." - needs: [move-1] - - - id: move-3 - title: "Move disk 1: C → B" - description: "Move disk 1 from peg C to peg B." - needs: [move-2] - - - id: move-4 - title: "Move disk 3: A → C" - description: "Move the largest disk from peg A to peg C." - needs: [move-3] - - - id: move-5 - title: "Move disk 1: B → A" - description: "Move disk 1 from peg B to peg A." - needs: [move-4] - - - id: move-6 - title: "Move disk 2: B → C" - description: "Move disk 2 from peg B to peg C." - needs: [move-5] - - - id: move-7 - title: "Move disk 1: A → C" - description: "Move disk 1 from peg A to peg C." - needs: [move-6] - - - id: verify - title: "Verify final state" - description: "All 3 disks now on peg C. Tower intact, all moves were legal." - needs: [move-7] diff --git a/docs/why-these-features.md b/docs/why-these-features.md index d3564e05..17a1c73d 100644 --- a/docs/why-these-features.md +++ b/docs/why-these-features.md @@ -135,10 +135,10 @@ in different repos. Traditional tools don't track this. **The solution:** Explicit cross-project dependencies: -```yaml +``` depends_on: - - beads://github/acme/backend/be-456 # Backend API - - beads://github/acme/shared/sh-789 # Shared types + beads://github/acme/backend/be-456 # Backend API + beads://github/acme/shared/sh-789 # Shared types ``` **Why it matters:** diff --git a/internal/cmd/gitinit.go b/internal/cmd/gitinit.go index 4ef74393..e271244d 100644 --- a/internal/cmd/gitinit.go +++ b/internal/cmd/gitinit.go @@ -109,7 +109,7 @@ const HQGitignore = `# Gas Town HQ .gitignore # Explicitly track (override above patterns) # ============================================================================= # Note: .beads/ has its own .gitignore that handles SQLite files -# and keeps issues.jsonl, metadata.json, config.yaml as source of truth +# and keeps issues.jsonl, metadata.json, config file as source of truth ` func runGitInit(cmd *cobra.Command, args []string) error { diff --git a/internal/constants/constants.go b/internal/constants/constants.go index e3be7af9..2d39311e 100644 --- a/internal/constants/constants.go +++ b/internal/constants/constants.go @@ -70,9 +70,6 @@ const ( // FileConfigJSON is the general config file. FileConfigJSON = "config.json" - // FileConfigYAML is the beads config file. - FileConfigYAML = "config.yaml" - // FileAccountsJSON is the accounts configuration file in mayor/. FileAccountsJSON = "accounts.json" ) diff --git a/internal/doctor/branch_check.go b/internal/doctor/branch_check.go index 71b86972..0c41084e 100644 --- a/internal/doctor/branch_check.go +++ b/internal/doctor/branch_check.go @@ -273,8 +273,9 @@ func (c *BeadsSyncOrphanCheck) Run(ctx *CheckContext) *CheckResult { } // Check if it's a code file if strings.HasSuffix(f, ".go") || strings.HasSuffix(f, ".md") || + strings.HasSuffix(f, ".toml") || strings.HasSuffix(f, ".json") || strings.HasSuffix(f, ".yaml") || strings.HasSuffix(f, ".yml") || - strings.HasSuffix(f, ".json") || strings.HasSuffix(f, ".tmpl") { + strings.HasSuffix(f, ".tmpl") { codeFiles = append(codeFiles, f) } } diff --git a/internal/rig/manager.go b/internal/rig/manager.go index e355af8a..28536219 100644 --- a/internal/rig/manager.go +++ b/internal/rig/manager.go @@ -408,6 +408,7 @@ func (m *Manager) initAgentStates(rigPath string) error { // initBeads initializes the beads database at rig level. // The project's .beads/config.yaml determines sync-branch settings. // Use `bd doctor --fix` in the project to configure sync-branch if needed. +// TODO(bd-yaml): beads config should migrate to JSON (see beads issue) func (m *Manager) initBeads(rigPath, prefix string) error { beadsDir := filepath.Join(rigPath, ".beads") if err := os.MkdirAll(beadsDir, 0755); err != nil { @@ -419,6 +420,7 @@ func (m *Manager) initBeads(rigPath, prefix string) error { cmd.Dir = rigPath if err := cmd.Run(); err != nil { // bd might not be installed or --no-agents not supported, create minimal structure + // Note: beads currently expects YAML format for config configPath := filepath.Join(beadsDir, "config.yaml") configContent := fmt.Sprintf("prefix: %s\n", prefix) if writeErr := os.WriteFile(configPath, []byte(configContent), 0644); writeErr != nil { @@ -747,7 +749,7 @@ This directory contains town-level plugins that run during Deacon patrol cycles. ## Plugin Structure Each plugin is a directory containing: -- plugin.md - Plugin definition with YAML frontmatter +- plugin.md - Plugin definition with TOML frontmatter ## Gate Types diff --git a/internal/templates/roles/witness.md.tmpl b/internal/templates/roles/witness.md.tmpl index 9d446e2e..5af1f973 100644 --- a/internal/templates/roles/witness.md.tmpl +++ b/internal/templates/roles/witness.md.tmpl @@ -274,23 +274,16 @@ This sends handoff mail, respawns fresh. Your next instance picks up from your h Your handoff state is tracked in a pinned bead: `witness Handoff` -```yaml -# Find with: bd list | grep "witness Handoff" -attached_molecule: mol-witness-patrol -attached_at: 2025-12-24T10:00:00Z - -# Nudge escalation tracking -nudges: - toast: - count: 2 - last: "2025-12-24T10:30:00Z" - ace: - count: 0 - last: null - -# Polecats queued for cleanup -pending_cleanup: - - nux # received POLECAT_DONE, awaiting verification +```json +{ + "attached_molecule": "mol-witness-patrol", + "attached_at": "2025-12-24T10:00:00Z", + "nudges": { + "toast": {"count": 2, "last": "2025-12-24T10:30:00Z"}, + "ace": {"count": 0, "last": null} + }, + "pending_cleanup": ["nux"] +} ``` On startup, check for attached work: