Agent Identity and Attribution

> Canonical format for agent identity in Gas Town

Why Identity Matters

When you deploy AI agents at scale, anonymous work creates real problems:

  • Debugging: "The AI broke it" isn't actionable. Which AI?
  • Quality tracking: You can't improve what you can't measure.
  • Compliance: Auditors ask "who approved this code?" - you need an answer.
  • Performance management: Some agents are better than others at certain tasks.

Gas Town solves this with universal attribution: every action, every commit, every bead update is linked to a specific agent identity. This enables work history tracking, capability-based routing, and objective quality measurement.

BD_ACTOR Format Convention

The BD_ACTOR environment variable identifies agents in slash-separated path format. This is set automatically when agents are spawned and used for all attribution.

Format by Role Type

Role TypeFormatExample
Mayormayormayor
Deacondeacondeacon
Witness{rig}/witnessgastown/witness
Refinery{rig}/refinerygastown/refinery
Crew{rig}/crew/{name}gastown/crew/joe
Polecat{rig}/polecats/{name}gastown/polecats/toast

Why Slashes?

The slash format mirrors filesystem paths and enables:

  • Hierarchical parsing (extract rig, role, name)
  • Consistent mail addressing (gt mail send gastown/witness)
  • Path-like routing in beads operations
  • Visual clarity about agent location

Attribution Model

Gas Town uses three fields for complete provenance:

Git Commits

GIT_AUTHOR_NAME="gastown/crew/joe"      # Who did the work (agent)
GIT_AUTHOR_EMAIL="[email protected]"    # Who owns the work (overseer)

Result in git log:

abc123 Fix bug (gastown/crew/joe <[email protected]>)

Interpretation:
  • The agent gastown/crew/joe authored the change
  • The work belongs to the workspace owner ([email protected])
  • Both are preserved in git history forever

Beads Records

{
  "id": "gt-xyz",
  "created_by": "gastown/crew/joe",
  "updated_by": "gastown/witness"
}

The created_by field is populated from BD_ACTOR when creating beads. The updated_by field tracks who last modified the record.

Event Logging

All events include actor attribution:

{
  "ts": "2025-01-15T10:30:00Z",
  "type": "sling",
  "actor": "gastown/crew/joe",
  "payload": { "bead": "gt-xyz", "target": "gastown/polecats/toast" }
}

Environment Setup

Gas Town uses a centralized config.AgentEnv() function to set environment variables consistently across all agent spawn paths (managers, daemon, boot).

Example: Polecat Environment

# Set automatically for polecat 'toast' in rig 'gastown'
export GT_ROLE="polecat"
export GT_RIG="gastown"
export GT_POLECAT="toast"
export BD_ACTOR="gastown/polecats/toast"
export GIT_AUTHOR_NAME="gastown/polecats/toast"
export GT_ROOT="/home/user/gt"
export BEADS_DIR="/home/user/gt/gastown/.beads"
export BEADS_AGENT_NAME="gastown/toast"
export BEADS_NO_DAEMON="1"  # Polecats use isolated beads context

Example: Crew Environment

# Set automatically for crew member 'joe' in rig 'gastown'
export GT_ROLE="crew"
export GT_RIG="gastown"
export GT_CREW="joe"
export BD_ACTOR="gastown/crew/joe"
export GIT_AUTHOR_NAME="gastown/crew/joe"
export GT_ROOT="/home/user/gt"
export BEADS_DIR="/home/user/gt/gastown/.beads"
export BEADS_AGENT_NAME="gastown/joe"
export BEADS_NO_DAEMON="1"  # Crew uses isolated beads context

Manual Override

For local testing or debugging:

export BD_ACTOR="gastown/crew/debug"
bd create --title="Test issue"  # Will show created_by: gastown/crew/debug

See Reference for the complete environment variable reference.

Identity Parsing

The format supports programmatic parsing:

// identityToBDActor converts daemon identity to BD_ACTOR format
// Town level: mayor, deacon
// Rig level: {rig}/witness, {rig}/refinery
// Workers: {rig}/crew/{name}, {rig}/polecats/{name}

InputParsed Components
mayorrole=mayor
deaconrole=deacon
gastown/witnessrig=gastown, role=witness
gastown/refineryrig=gastown, role=refinery
gastown/crew/joerig=gastown, role=crew, name=joe
gastown/polecats/toastrig=gastown, role=polecat, name=toast

Audit Queries

Attribution enables powerful audit queries:

# All work by an agent
bd audit --actor=gastown/crew/joe

# All work in a rig
bd audit --actor=gastown/*

# All polecat work
bd audit --actor=*/polecats/*

# Git history by agent
git log --author="gastown/crew/joe"

Design Principles

  1. Agents are not anonymous - Every action is attributed
  2. Work is owned, not authored - Agent creates, overseer owns
  3. Attribution is permanent - Git commits preserve history
  4. Format is parseable - Enables programmatic analysis
  5. Consistent across systems - Same format in git, beads, events

CV and Skill Accumulation

Human Identity is Global

The global identifier is your email - it's already in every git commit. No separate "entity bead" needed.

[email protected]                ← global identity (from git author)
├── Town A (home)                ← workspace
│   ├── gastown/crew/joe         ← agent executor
│   └── gastown/polecats/toast   ← agent executor
└── Town B (work)                ← workspace
    └── acme/polecats/nux        ← agent executor

Agent vs Owner

FieldScopePurpose
BD_ACTORLocal (town)Agent attribution for debugging
GIT_AUTHOR_EMAILGlobalHuman identity for CV
created_byLocalWho created the bead
ownerGlobalWho owns the work
Agents execute. Humans own. The polecat name in completed-by: gastown/polecats/toast is executor attribution. The CV credits the human owner ([email protected]).

Polecats Have Persistent Identities

Polecats have persistent identities but ephemeral sessions. Like employees who clock in/out: each work session is fresh (new tmux, new worktree), but the identity persists across sessions.

  • Identity (persistent): Agent bead, CV chain, work history
  • Session (ephemeral): Claude instance, context window
  • Sandbox (ephemeral): Git worktree, branch

Work credits the polecat identity, enabling:

  • Performance tracking per polecat
  • Capability-based routing (send Go work to polecats with Go track records)
  • Model comparison (A/B test different models via different polecats)

See Polecat Lifecycle for details.

Skills Are Derived

Your CV emerges from querying work evidence:

# All work by owner (across all agents)
git log --author="[email protected]"
bd list [email protected]

# Skills derived from evidence
# - .go files touched → Go skill
# - issue tags → domain skills
# - commit patterns → activity types

Multi-Town Aggregation

A human with multiple towns has one CV:

# Future: federated CV query
bd cv [email protected]
# Discovers all towns, aggregates work, derives skills

See ~/gt/docs/hop/decisions/008-identity-model.md for architectural rationale.

Enterprise Use Cases

Compliance and Audit

# Who touched this file in the last 90 days?
git log --since="90 days ago" -- path/to/sensitive/file.go

# All changes by a specific agent
bd audit --actor=gastown/polecats/toast --since=2025-01-01

Performance Tracking

# Completion rate by agent
bd stats --group-by=actor

# Average time to completion
bd stats --actor=gastown/polecats/* --metric=cycle-time

Model Comparison

When agents use different underlying models, attribution enables A/B comparison:

# Tag agents by model
# gastown/polecats/claude-1 uses Claude
# gastown/polecats/gpt-1 uses GPT-4

# Compare quality signals
bd stats --actor=gastown/polecats/claude-* --metric=revision-count
bd stats --actor=gastown/polecats/gpt-* --metric=revision-count

Lower revision counts suggest higher first-pass quality.