In the previous chapter, Molecules (Workflow Engines), we gave our agents checklists to follow. But as any project manager knows, handing out checklists is easy; tracking who has finished what, who is stuck, and who is currently working is the hard part.
Welcome to the Ledger of Gas Town.
Imagine you have 10 construction workers (Polecats) building a house. They are all working fast.
If they write these updates on sticky notes and put them on a wall, two workers might try to write on the same note at the same time, or a note might fall off.
In software, if agents store their status in simple text files (JSON/YAML), they will overwrite each other's changes. If we use a massive cloud database, setup becomes a nightmare for a local tool.
Gas Town solves this with a two-part system:
Dolt is the magic ingredient. Because it supports branching and merging (just like Git), every AI agent can create its own "database branch," do its work, and merge the results back without corrupting the main list.
Gas Town organizes memory into two distinct levels to keep things tidy.
You interact with the ledger using the bd (Beads) CLI tool.
To see all open issues in your current rig:
# List all open beads (tasks)
bd list --status=open
Output:
ID Title Status Assignee
GT-101 Fix login bug open -
GT-102 Refactor database open gastown/polecats/tinker
You can create a new bead easily. This is what molecules do automatically, but you can do it manually too.
bd create --title="Update documentation" --priority=1
Beads doesn't just track work; it tracks workers. Every agent (like a Polecat) has a corresponding Bead that stores its state.
# Check on a specific agent bead
bd show polecat-tinker-123
While bd is the friendly face, the engine powering it is a real SQL server running locally on your machine (usually port 3307).
When an agent needs to record data, it doesn't write to a file. It queries the server.
Let's look at how Gas Town manages this database server. The logic is in internal/doltserver/doltserver.go.
Gas Town spins up a dedicated Dolt process. It sets the data directory to ~/.gt/.dolt-data, ensuring all your projects live in one manageable place.
// internal/doltserver/doltserver.go
func Start(townRoot string) error {
config := DefaultConfig(townRoot)
// Command: dolt sql-server --port 3307 --data-dir ~/.gt/.dolt-data
args := []string{"sql-server",
"--port", strconv.Itoa(config.Port),
"--data-dir", config.DataDir,
}
cmd := exec.Command("dolt", args...)
return cmd.Start()
}
Explanation: We aren't relying on an external MySQL installation. Gas Town bundles its own server. It uses a specific port (3307) to avoid clashing if you already have MySQL running for your own work.
This is where Gas Town differs from standard project management tools. When a Polecat starts work, we create a database branch for it. This prevents "Optimistic Lock" errors where two agents try to update the same row.
// internal/doltserver/doltserver.go
func CreatePolecatBranch(townRoot, rigDB, branchName string) error {
// SQL: CALL DOLT_BRANCH('polecat-tinker-123')
query := fmt.Sprintf("CALL DOLT_BRANCH('%s')", branchName)
// Execute safe SQL command
return doltSQLWithRecovery(townRoot, rigDB, query)
}
Explanation: By calling DOLT_BRANCH, we create an isolated timeline of the database. The agent can spam updates to its heart's content. When it's done, we merge that branch back to main.
Since we have multiple databases (HQ vs. Rigs), the system needs to know where to look. We use beads.go to resolve the directory.
// internal/beads/beads.go
func (b *Beads) getResolvedBeadsDir() string {
// If explicitly set, use that
if b.beadsDir != "" {
return b.beadsDir
}
// Otherwise, calculate based on current directory
return ResolveBeadsDir(b.workDir)
}
Explanation: If you run bd list inside ~/gt/my-app/, the system automatically detects you are in a Rig and connects to the my-app database. If you are in ~/gt/, it connects to HQ.
Because it is standard SQL, you can pop the hood and run queries yourself if you want to perform complex analytics on your project's progress.
# Enter the SQL shell
gt dolt sql
Then run:
USE `my-app`;
SELECT * FROM issues WHERE status = 'open';
bd commands translate into SQL queries sent to a local server on port 3307.Now that we have a Ledger to track our work, we need a way to organize large groups of tasks and move work between Rigs.
Next Chapter: Convoys (Work Logistics)
Generated by Code IQ