fix: Remove YAML usage, standardize on JSON/TOML

- 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 <noreply@anthropic.com>
This commit is contained in:
gastown/crew/gus
2026-01-01 11:18:09 -08:00
committed by Steve Yegge
parent cc3622117e
commit f75eeb4da8
12 changed files with 20 additions and 286 deletions

View File

@@ -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.

View File

@@ -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"]

View File

@@ -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

View File

@@ -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}"

View File

@@ -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]

View File

@@ -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 <mol-id>
2. Find the next ready (unblocked) step
3. Close it: bd close <step-id>
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 <mol-id>`, 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]

View File

@@ -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:**

View File

@@ -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 {

View File

@@ -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"
)

View File

@@ -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)
}
}

View File

@@ -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

View File

@@ -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: