Town-level agents (mayor/, deacon/) need trailing slash to match
addressToIdentity() normalization.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When running bd update commands for hq-* beads from a polecat worktree,
the redirect mechanism only exposes gt-* beads. This fix sets BEADS_DIR
to the town-level .beads directory so hq-* beads are accessible.
Also adds NewWithBeadsDir() constructor to beads package for explicit
cross-database access when needed.
When slinging to an existing polecat, the bd update command was running
from town root which doesn't support prefix-based routing for writes.
Fix: Capture the target agent's working directory from resolveTargetAgent
and use it as hookWorkDir. This ensures bd update runs from the polecat's
worktree where the .beads/redirect file enables routing to the correct
database.
Also fixed the self-sling case to capture and use selfWorkDir.
When slinging work to a polecat, run bd commands from the polecat's
worktree directory instead of town root. This enables redirect-based
routing to work correctly since the polecat's .beads/redirect file
points to the canonical database location.
Adds hookWorkDir variable to track the polecat's clone path and passes
it to updateAgentHookBead for proper beads access.
When slinging work to a rig (auto-spawning a polecat), the hook_bead
is now set atomically during agent bead creation rather than in a
separate updateAgentHookBead call after spawn.
This fixes cross-beads routing issues when town beads (hq-*) are slung
to rig polecats (gt-* agent beads). By setting hook_bead at creation
time within the polecat manager context, the correct beads routing is
used.
Changes:
- Add AddOptions struct with HookBead field to polecat.Manager
- Add AddWithOptions() and RecreateWithOptions() functions
- Pass HookBead through SlingSpawnOptions in cmd/polecat_spawn.go
- Pass beadID as HookBead in cmd/sling.go for rig target spawns
Note: updateAgentHookBead() is kept for non-spawn targets (existing
agents) and formula-on-bead mode (updates hook to wisp root after
creation).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When gt sling is used without an existing convoy context, automatically
create a convoy for dashboard visibility. This ensures all work appears
in 'gt convoy list', even "swarm of one" assignments.
Changes:
- Add --no-convoy flag to skip auto-convoy creation
- Check if issue is already tracked by a convoy before creating new one
- Create convoy with title "Work: <issue-title>" and add tracks relation
- Display tracking info in sling output
- Update command help with auto-convoy documentation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When slinging with . as target, resolve it to the current agent identity
instead of using literal dot. This matches git convention where dot means
current directory/context.
Fix applied to both runSling and runSlingFormula code paths.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When slinging work from town beads (hq-*) to a polecat whose agent bead
is in rig beads (gt-*), the hook_bead update was silently failing because
bd couldn't find the cross-beads reference.
Changes:
- sling.go: Use town root for routing instead of cwd, enabling cross-beads
resolution via routes.jsonl. Log warnings on failure instead of silent ignore.
- done.go: Use townRoot (already available) instead of cwd for beads client.
Log warnings on failure for both state and cleanup status updates.
Root cause: The beads client was created from current working directory,
which may not have access to routes.jsonl for cross-prefix resolution.
Town root always has routes.jsonl for proper prefix → rig directory mapping.
(gt-ohqxq)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The runSlingFormula function was calling bd wisp which does not exist.
The correct command is bd mol wisp for creating ephemeral molecules.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Set Spawned=true when DispatchToDog creates a new dog, allowing
callers to distinguish between reusing an existing dog vs spawning.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Agent bead ID validation was hardcoded to only accept "gt-" prefix, which
caused errors when spawning beads polecats (which use "bd-" prefix):
Error: invalid agent ID: agent ID must start with 'gt-' (got "bd-beads-polecat-pearl")
Changed ParseAgentBeadID to accept any 2-3 character prefix (gt-, bd-, hq-)
instead of hardcoding "gt-". Updated tests to cover other prefixes.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Role templates (crew, polecat, mayor, deacon, witness, refinery)
- prime.go startup protocol messages
- Documentation (propulsion, reference, molecules, wisp architecture)
- Session hints and sling prompts
- Formula template instructions
- CLAUDE.md
The hook is the user-facing concept, molecules are implementation details.
Agents should use `gt hook` to check what work is assigned to them.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Agent beads must use gt- prefix (required by beads validation).
Only issue beads use rig-specific prefixes (ga-, bd-, etc.).
Fixed in:
- crew_add.go: Use CrewBeadID() not CrewBeadIDWithPrefix()
- prime.go: Use non-prefix variants for all agent types
- sling.go: Use non-prefix variants for all agent types
This fixes 'invalid agent ID' error when creating crew in rigs
with non-gt prefix (e.g., gastown with ga- prefix).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Using "greenplace" (The Green Place from Mad Max: Fury Road) as the
canonical example project/rig name in documentation and help text.
This provides a clearer distinction from the actual gastown repo name.
Changes:
- docs/*.md: Updated all example paths and commands
- internal/cmd/*.go: Updated help text examples
- internal/templates/: Updated example references
- Tests: Updated to use greenplace in example session names
Note: Import paths (github.com/steveyegge/gastown) and actual code
paths referencing the gastown repo structure are unchanged.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Extends gt sling to dispatch work to dogs (Deacon helper workers):
- gt sling <work> deacon/dogs - Auto-dispatch to idle dog from pool
- gt sling <work> deacon/dogs/alpha - Dispatch to specific dog
- Pool management: --create flag to spawn dogs if pool is empty
- Dog state tracking (marks dog as working on dispatch)
New functions:
- IsDogTarget: Detect dog target patterns
- DispatchToDog: Find/spawn dog and prepare for work
- generateDogName: Create unique names for new dogs
Dogs are reusable workers for infrastructure tasks.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When spawning polecats in non-gastown rigs like beads, the agent bead ID
was incorrectly using the hardcoded "gt-" prefix instead of the rig's
configured prefix (e.g., "bd-" for beads).
Changes:
- Add GetPrefixForRig() in routes.go to look up prefix from routes.jsonl
- Update agentIDToBeadID() in sling.go to use rig's prefix via the new
*WithPrefix functions instead of hardcoded "gt"
- Add unit tests for the new functionality
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 1 of activity feed improvements: gt commands now log events to
~/gt/.events.jsonl. This is the raw audit log that the feed daemon
(phase 2) will curate into the user-facing feed.
Instrumented commands:
- gt sling: logs sling events with bead and target
- gt hook: logs hook events with bead
- gt handoff: logs handoff events with subject
- gt done: logs done events with bead and branch
- gt mail send: logs mail events with to and subject
Event format follows the specification:
```json
{"ts":"2025-12-30T07:36:28Z","source":"gt","type":"mail",
"actor":"gastown/crew/joe","payload":{...},"visibility":"feed"}
```
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When using `gt sling <formula> --on <bead>`, the command now properly
instantiates the formula as a molecule and bonds it to the target bead:
1. Cook the formula (ensures proto exists)
2. Create wisp with feature variable from bead title
3. Bond wisp to original bead (creates compound)
4. Hook the compound root (not bare bead) to target agent
This enables the "shiny" workflow (design→implement→review→test→submit)
to be applied to existing bugs/features, ensuring polecats complete all
phases including the code review step.
Example:
gt sling shiny --on gt-abc gastown
# Creates shiny molecule, bonds to gt-abc, slings compound to polecat
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When slinging to an existing polecat with --naked flag, the code was still
attempting to look up the tmux pane, which fails for terminated polecats.
Now resolveTargetAgent accepts a skipPane parameter that bypasses the tmux
pane and working directory lookup when true.
This allows work to be slung to terminated polecats that will be restarted
manually later.
Also updated unsling to skip pane lookup since it only needs the agent ID.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements canonical naming convention for agent bead IDs:
- Town-level: gt-mayor, gt-deacon (unchanged)
- Rig-level: gt-<rig>-witness, gt-<rig>-refinery (was gt-witness-<rig>)
- Named: gt-<rig>-crew-<name>, gt-<rig>-polecat-<name> (was gt-crew-<rig>-<name>)
Changes:
- Added AgentBeadID helper functions to internal/beads/beads.go
- Updated all ID generation call sites to use helpers
- Fixed session parsing in theme.go, statusline.go, agents.go
- Updated doctor check and fix to use canonical format
- Updated tests for new format
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Create AgentIdentity type to parse and construct session names, replacing
duplicated logic in sling.go and handoff.go.
- Add internal/session/identity.go with AgentIdentity type
- ParseSessionName handles: mayor, deacon, witness, refinery, crew, polecat
- SessionName() reconstructs valid tmux session name
- Address() returns mail-style address (e.g., "gastown/crew/max")
- GTRole() returns GT_ROLE env var format
- Update sling.go:sessionToAgentID to use ParseSessionName
- Update handoff.go:sessionToGTRole to use ParseSessionName
- Add comprehensive unit tests with round-trip verification
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changes:
1. prime.go: Create agent beads on first prime for all roles including crew
2. done.go: Update agent state to done/stuck/idle when work completes
3. sling.go: Populate hook_bead when work is assigned to agents
4. mol-witness-patrol.formula.toml: Document dead and spawning states
Closes: gt-hymm0, gt-0lop3, gt-59k2x, gt-c4j4j
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When slinging or hooking work to mayor/deacon, the pin now lands in Town
beads (~/.beads/) instead of rig beads. This ensures gt mol status finds
the pinned work when run from ~/gt.
The issue was that town-level roles operate from the town root, so their
hooks should be discoverable from there.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When slinging a bead that has the template label (a proto), and --var
flags are provided, automatically call bd --no-daemon pour to
instantiate the proto with variable substitution before slinging.
This enables the seamless workflow:
gt sling mol-release beads --var version=0.38.0
Instead of the manual two-step:
bd --no-daemon pour mol-release --var version=0.38.0 --json
gt sling <resulting-mol-id> beads
Also adds a warning when slinging a proto without --var, since
{{variables}} will not be substituted.
Generated with Claude Code
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Delete all .formula.json files (TOML versions exist)
- Update sling.go comment to say TOML only
Note: Doc updates were prepared but those docs were deleted
upstream in the recent refactoring.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add guard that checks if bead is already pinned before slinging.
Shows current assignee and requires --force to override.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Complete unification of work assignment commands:
- Add spawn flags to sling: --naked, --create, --molecule, --force, --account
- SpawnPolecatForSling now accepts SlingSpawnOptions struct
- Deprecate gt spawn with warning pointing to gt sling
- Update no-tmux-mode.md to use sling examples
gt sling now handles:
- Existing agents (mayor, crew, witness, refinery)
- Auto-spawning polecats when target is a rig
- Formula instantiation and wisp creation
- No-tmux mode for manual agent operation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Enable Gas Town to operate without tmux by using beads for args transport:
- Add `attached_args` field to beads AttachmentFields
- gt sling: Store args in bead description, graceful fallback if no tmux
- gt prime: Display attached args prominently on startup
- gt mol status: Include attached_args in status output
- gt spawn --naked: Assign work via mail only, skip tmux session
Agents discover args via gt prime / bd show when starting manually.
Docs added explaining what works vs degraded behavior in no-tmux mode.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace hook file mechanism with discovery-based pinned beads:
- gt hook: now runs bd update <bead> --status=pinned
- gt sling: same, plus nudge to target
- gt handoff: same when bead ID provided
- gt prime: checks pinned beads instead of hook files
- gt mol status: no longer checks hook files
Key changes:
- outputAttachmentStatus: extended to all roles (was Crew/Polecat only)
- checkSlungWork: now queries pinned beads instead of reading hook files
- wisp/io.go functions: marked deprecated with migration notes
This follows Gas Town discovery over explicit state principle.
Hook files are kept for backward compatibility but no longer written.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When `gt sling <bead> <rig>` is used with a rig name as target, sling now
automatically spawns a fresh polecat and slings work to it. This provides
a simpler alternative to `gt spawn --issue <bead> <rig>` for quick dispatch.
Changes:
- Add IsRigName() helper to detect bare rig names
- Add SpawnPolecatForSling() for lightweight polecat creation
- Update sling to detect rig targets and auto-spawn
- Update help text for both sling and spawn to document behavior
Design: spawn and sling remain distinct commands with different purposes:
- sling: Light spawn with hook + nudge (quick dispatch)
- spawn: Full workflow with mol-polecat-work, mail, witness notification
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Args field to SlungWork struct in wisp/types.go
- Add --args/-a flag to gt sling command
- Display args in gt prime autonomous mode
- Display args in gt mol status output
The --args string is stored in the hook and shown to the LLM executor,
which interprets the instructions naturally without schema maintenance.
Example: gt sling beads-release --args "patch release"
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When first arg is a formula (not a bead), sling now:
1. Cooks the formula (bd cook)
2. Creates a wisp instance (bd wisp)
3. Attaches the wisp to the target hook
4. Nudges the target to start
New flags:
- --var key=value: Pass variables to formula (repeatable)
Examples:
gt sling mol-town-shutdown mayor/
gt sling towers-of-hanoi --var disks=3
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Organize 43 commands into 7 logical groups using cobra's built-in
AddGroup/GroupID feature:
- Work Management: spawn, sling, hook, handoff, done, mol, mq, etc.
- Agent Management: mayor, witness, refinery, deacon, polecat, etc.
- Communication: mail, nudge, broadcast, peek
- Services: daemon, start, stop, up, down, shutdown
- Workspace: rig, crew, init, install, git-init, namepool
- Configuration: account, theme, hooks, issue, completion
- Diagnostics: status, doctor, prime, version, help
Also renamed molecule to mol as the primary command name
(molecule is now an alias).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When --on is specified, the first argument is a formula name:
gt sling shiny --on gt-abc123
This applies the formula to existing work, creating wisp scaffolding
that shapes execution of the target bead.
Changes:
- Add Formula field to SlungWork wisp type
- Add --on flag to gt sling command
- Verify both bead and formula exist before slinging
- Update dry-run output to show formula info
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- gt prime: New AUTONOMOUS WORK MODE prompt with clear DO/DON'T instructions
- gt prime: Skip normal startup directive when in autonomous mode
- gt prime: Search multiple beads locations for Mayor's beads
- gt sling: Use GetRole() for role detection instead of cwd
- gt sling: Store hooks in role's home directory, not git root
This ensures hooks work correctly regardless of where commands are run from.
Mayor's hooks always go to ~/gt/.beads/ even when running from a rig dir.
- Add gt hook <bead>: durability primitive, attaches work to hook
- Update gt handoff: accept optional bead arg (detects bead vs role)
- Deprecate gt sling: shows warning, points to new commands
- Update doctor fix hint to reference new commands
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Code review fixes:
1. CRITICAL: Move polecat check to start of runSling
- Previously wrote wisp THEN failed, leaving orphan
- Now fails fast before any file operations
2. CRITICAL: Sanitize slashes in agent IDs for filenames
- Agent IDs like 'gastown/crew/joe' were creating subdirs
- Now converts '/' to '--' for safe filenames
- Added sanitizeAgentID/unsanitizeAgentID helpers
3. MODERATE: Use git root instead of WorkDir in prime.go
- Hooks are written to clone root, not cwd
- Added getGitRoot() helper for consistency
4. MODERATE: Fix silent error swallowing
- Now logs non-ErrNoHook errors when reading hooks
- Warns if bead doesn't exist before burning hook
- Preserves hook if bead is missing for debugging
Phase 1 of tracer bullet: Slinging Handoff
- Add internal/wisp package for ephemeral work attachment
- Add gt sling command to attach work and restart
- Update gt prime to check/burn slung work on hook
- Add .beads-wisp/ to gitignore