From 1e53cd78a615950ef37c3be2f01ab870631edcc5 Mon Sep 17 00:00:00 2001 From: gastown/crew/jack Date: Thu, 1 Jan 2026 11:01:55 -0800 Subject: [PATCH] fix: Security fixes and docs updates (gt-jsm2s, gt-d47q0, gt-orujk) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - convoy.go: Escape single quotes in SQL to prevent injection - engineer.go: Add comment clarifying test command trust model (config.json is trusted infra, not PR-controlled) - agents.go, prime.go, mayor.md.tmpl: Fix 'gt polecats' -> 'gt polecat list' 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- internal/cmd/agents.go | 2 +- internal/cmd/convoy.go | 4 +++- internal/cmd/prime.go | 2 +- internal/refinery/engineer.go | 2 ++ internal/templates/roles/mayor.md.tmpl | 2 +- 5 files changed, 8 insertions(+), 4 deletions(-) diff --git a/internal/cmd/agents.go b/internal/cmd/agents.go index f506d425..ea747f31 100644 --- a/internal/cmd/agents.go +++ b/internal/cmd/agents.go @@ -64,7 +64,7 @@ var agentsCmd = &cobra.Command{ Long: `Display a popup menu of core Gas Town agent sessions. Shows Mayor, Deacon, Witnesses, Refineries, and Crew workers. -Polecats are hidden (use 'gt polecats' to see them). +Polecats are hidden (use 'gt polecat list' to see them). The menu appears as a tmux popup for quick session switching.`, RunE: runAgents, diff --git a/internal/cmd/convoy.go b/internal/cmd/convoy.go index 1454f076..66842459 100644 --- a/internal/cmd/convoy.go +++ b/internal/cmd/convoy.go @@ -577,8 +577,10 @@ func getTrackedIssues(townBeads, convoyID string) []trackedIssueInfo { dbPath := filepath.Join(townBeads, "beads.db") // Query tracked dependencies from SQLite + // Escape single quotes to prevent SQL injection + safeConvoyID := strings.ReplaceAll(convoyID, "'", "''") queryCmd := exec.Command("sqlite3", "-json", dbPath, - fmt.Sprintf(`SELECT depends_on_id, type FROM dependencies WHERE issue_id = '%s' AND type = 'tracks'`, convoyID)) + fmt.Sprintf(`SELECT depends_on_id, type FROM dependencies WHERE issue_id = '%s' AND type = 'tracks'`, safeConvoyID)) var stdout bytes.Buffer queryCmd.Stdout = &stdout diff --git a/internal/cmd/prime.go b/internal/cmd/prime.go index 4a9f0d80..e80aa8be 100644 --- a/internal/cmd/prime.go +++ b/internal/cmd/prime.go @@ -332,7 +332,7 @@ func outputWitnessContext(ctx RoleContext) { fmt.Println() fmt.Println("## Key Commands") fmt.Println("- `gt witness status` - Show witness status") - fmt.Println("- `gt polecats` - List polecats in this rig") + fmt.Println("- `gt polecat list` - List polecats in this rig") fmt.Println() fmt.Println("## Hookable Mail") fmt.Println("Mail can be hooked for ad-hoc instructions: `gt hook attach `") diff --git a/internal/refinery/engineer.go b/internal/refinery/engineer.go index 49b991fb..fa918286 100644 --- a/internal/refinery/engineer.go +++ b/internal/refinery/engineer.go @@ -346,6 +346,8 @@ func (e *Engineer) runTests(ctx context.Context) ProcessResult { fmt.Fprintf(e.output, "[Engineer] Retrying tests (attempt %d/%d)...\n", attempt, maxRetries) } + // Note: TestCommand comes from rig's config.json (trusted infrastructure config), + // not from PR branches. Shell execution is intentional for flexibility (pipes, etc). cmd := exec.CommandContext(ctx, "sh", "-c", e.config.TestCommand) cmd.Dir = e.workDir var stdout, stderr bytes.Buffer diff --git a/internal/templates/roles/mayor.md.tmpl b/internal/templates/roles/mayor.md.tmpl index 11251a38..098f22b4 100644 --- a/internal/templates/roles/mayor.md.tmpl +++ b/internal/templates/roles/mayor.md.tmpl @@ -189,7 +189,7 @@ bd show hq-abc # Routes to town beads ### Status - `gt status` - Overall town status - `gt rigs` - List all rigs -- `gt polecats ` - List polecats in a rig +- `gt polecat list [rig]` - List polecats in a rig ### Work Management - `gt convoy list` - Dashboard of active work (primary view)