chore: add design docs and ready command
- Add convoy-lifecycle.md design doc - Add formula-resolution.md design doc - Add mol-mall-design.md design doc - Add ready.go command implementation - Move dog-pool-architecture.md to docs/design/ - Update .gitignore for beads sync files Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
197
docs/design/convoy-lifecycle.md
Normal file
197
docs/design/convoy-lifecycle.md
Normal file
@@ -0,0 +1,197 @@
|
||||
# Convoy Lifecycle Design
|
||||
|
||||
> Making convoys actively converge on completion.
|
||||
|
||||
## Problem Statement
|
||||
|
||||
Convoys are passive trackers. They group work but don't drive it. The completion
|
||||
loop has a structural gap:
|
||||
|
||||
```
|
||||
Create → Assign → Execute → Issues close → ??? → Convoy closes
|
||||
```
|
||||
|
||||
The `???` is "Deacon patrol runs `gt convoy check`" - a poll-based single point of
|
||||
failure. When Deacon is down, convoys don't close. Work completes but the loop
|
||||
never lands.
|
||||
|
||||
## Current State
|
||||
|
||||
### What Works
|
||||
- Convoy creation and issue tracking
|
||||
- `gt convoy status` shows progress
|
||||
- `gt convoy stranded` finds unassigned work
|
||||
- `gt convoy check` auto-closes completed convoys
|
||||
|
||||
### What Breaks
|
||||
1. **Poll-based completion**: Only Deacon runs `gt convoy check`
|
||||
2. **No event-driven trigger**: Issue close doesn't propagate to convoy
|
||||
3. **No manual close**: Can't force-close abandoned convoys
|
||||
4. **Single observer**: No redundant completion detection
|
||||
5. **Weak notification**: Convoy owner not always clear
|
||||
|
||||
## Design: Active Convoy Convergence
|
||||
|
||||
### Principle: Event-Driven, Redundantly Observed
|
||||
|
||||
Convoy completion should be:
|
||||
1. **Event-driven**: Triggered by issue close, not polling
|
||||
2. **Redundantly observed**: Multiple agents can detect and close
|
||||
3. **Manually overridable**: Humans can force-close
|
||||
|
||||
### Event-Driven Completion
|
||||
|
||||
When an issue closes, check if it's tracked by a convoy:
|
||||
|
||||
```
|
||||
Issue closes
|
||||
↓
|
||||
Is issue tracked by convoy? ──(no)──► done
|
||||
│
|
||||
(yes)
|
||||
↓
|
||||
Run gt convoy check <convoy-id>
|
||||
↓
|
||||
All tracked issues closed? ──(no)──► done
|
||||
│
|
||||
(yes)
|
||||
↓
|
||||
Close convoy, send notifications
|
||||
```
|
||||
|
||||
**Implementation options:**
|
||||
1. Daemon hook on `bd update --status=closed`
|
||||
2. Refinery step after successful merge
|
||||
3. Witness step after verifying polecat completion
|
||||
|
||||
Option 1 is most reliable - catches all closes regardless of source.
|
||||
|
||||
### Redundant Observers
|
||||
|
||||
Per PRIMING.md: "Redundant Monitoring Is Resilience."
|
||||
|
||||
Three places should check convoy completion:
|
||||
|
||||
| Observer | When | Scope |
|
||||
|----------|------|-------|
|
||||
| **Daemon** | On any issue close | All convoys |
|
||||
| **Witness** | After verifying polecat work | Rig's convoy work |
|
||||
| **Deacon** | Periodic patrol | All convoys (backup) |
|
||||
|
||||
Any observer noticing completion triggers close. Idempotent - closing
|
||||
an already-closed convoy is a no-op.
|
||||
|
||||
### Manual Close Command
|
||||
|
||||
**Desire path**: `gt convoy close` is expected but missing.
|
||||
|
||||
```bash
|
||||
# Close a completed convoy
|
||||
gt convoy close hq-cv-abc
|
||||
|
||||
# Force-close an abandoned convoy
|
||||
gt convoy close hq-cv-xyz --reason="work done differently"
|
||||
|
||||
# Close with explicit notification
|
||||
gt convoy close hq-cv-abc --notify mayor/
|
||||
```
|
||||
|
||||
Use cases:
|
||||
- Abandoned convoys no longer relevant
|
||||
- Work completed outside tracked path
|
||||
- Force-closing stuck convoys
|
||||
|
||||
### Convoy Owner/Requester
|
||||
|
||||
Track who requested the convoy for targeted notifications:
|
||||
|
||||
```bash
|
||||
gt convoy create "Feature X" gt-abc --owner mayor/ --notify overseer
|
||||
```
|
||||
|
||||
| Field | Purpose |
|
||||
|-------|---------|
|
||||
| `owner` | Who requested (gets completion notification) |
|
||||
| `notify` | Additional subscribers |
|
||||
|
||||
If `owner` not specified, defaults to creator (from `created_by`).
|
||||
|
||||
### Convoy States
|
||||
|
||||
```
|
||||
OPEN ──(all issues close)──► CLOSED
|
||||
│ │
|
||||
│ ▼
|
||||
│ (add issues)
|
||||
│ │
|
||||
└─────────────────────────────┘
|
||||
(auto-reopens)
|
||||
```
|
||||
|
||||
Adding issues to closed convoy reopens automatically.
|
||||
|
||||
**New state for abandonment:**
|
||||
|
||||
```
|
||||
OPEN ──► CLOSED (completed)
|
||||
│
|
||||
└────► ABANDONED (force-closed without completion)
|
||||
```
|
||||
|
||||
### Timeout/SLA (Future)
|
||||
|
||||
Optional `due_at` field for convoy deadline:
|
||||
|
||||
```bash
|
||||
gt convoy create "Sprint work" gt-abc --due="2026-01-15"
|
||||
```
|
||||
|
||||
Overdue convoys surface in `gt convoy stranded --overdue`.
|
||||
|
||||
## Commands
|
||||
|
||||
### New: `gt convoy close`
|
||||
|
||||
```bash
|
||||
gt convoy close <convoy-id> [--reason=<reason>] [--notify=<agent>]
|
||||
```
|
||||
|
||||
- Closes convoy regardless of tracked issue status
|
||||
- Sets `close_reason` field
|
||||
- Sends notification to owner and subscribers
|
||||
- Idempotent - closing closed convoy is no-op
|
||||
|
||||
### Enhanced: `gt convoy check`
|
||||
|
||||
```bash
|
||||
# Check all convoys (current behavior)
|
||||
gt convoy check
|
||||
|
||||
# Check specific convoy (new)
|
||||
gt convoy check <convoy-id>
|
||||
|
||||
# Dry-run mode
|
||||
gt convoy check --dry-run
|
||||
```
|
||||
|
||||
### New: `gt convoy reopen`
|
||||
|
||||
```bash
|
||||
gt convoy reopen <convoy-id>
|
||||
```
|
||||
|
||||
Explicit reopen for clarity (currently implicit via add).
|
||||
|
||||
## Implementation Priority
|
||||
|
||||
1. **P0: `gt convoy close`** - Desire path, escape hatch
|
||||
2. **P0: Event-driven check** - Daemon hook on issue close
|
||||
3. **P1: Redundant observers** - Witness/Refinery integration
|
||||
4. **P2: Owner field** - Targeted notifications
|
||||
5. **P3: Timeout/SLA** - Deadline tracking
|
||||
|
||||
## Related
|
||||
|
||||
- [convoy.md](../concepts/convoy.md) - Convoy concept and usage
|
||||
- [watchdog-chain.md](watchdog-chain.md) - Deacon patrol system
|
||||
- [mail-protocol.md](mail-protocol.md) - Notification delivery
|
||||
495
docs/design/dog-pool-architecture.md
Normal file
495
docs/design/dog-pool-architecture.md
Normal file
@@ -0,0 +1,495 @@
|
||||
# Dog Pool Architecture for Concurrent Shutdown Dances
|
||||
|
||||
> Design document for gt-fsld8
|
||||
|
||||
## Problem Statement
|
||||
|
||||
Boot needs to run multiple shutdown-dance molecules concurrently when multiple death
|
||||
warrants are issued. The current hook design only allows one molecule per agent.
|
||||
|
||||
Example scenario:
|
||||
- Warrant 1: Kill stuck polecat Toast (60s into interrogation)
|
||||
- Warrant 2: Kill stuck polecat Shadow (just started)
|
||||
- Warrant 3: Kill stuck witness (120s into interrogation)
|
||||
|
||||
All three need concurrent tracking, independent timeouts, and separate outcomes.
|
||||
|
||||
## Design Decision: Lightweight State Machines
|
||||
|
||||
After analyzing the options, the shutdown-dance does NOT need Claude sessions.
|
||||
The dance is a deterministic state machine:
|
||||
|
||||
```
|
||||
WARRANT -> INTERROGATE -> EVALUATE -> PARDON|EXECUTE
|
||||
```
|
||||
|
||||
Each step is mechanical:
|
||||
1. Send a tmux message (no LLM needed)
|
||||
2. Wait for timeout or response (timer)
|
||||
3. Check tmux output for ALIVE keyword (string match)
|
||||
4. Repeat or terminate
|
||||
|
||||
**Decision**: Dogs are lightweight Go routines, not Claude sessions.
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────────────────────────────────┐
|
||||
│ BOOT │
|
||||
│ (Claude session in tmux) │
|
||||
│ │
|
||||
│ ┌──────────────────────────────────────────────────────────────┐ │
|
||||
│ │ Dog Manager │ │
|
||||
│ │ │ │
|
||||
│ │ Pool: [Dog1, Dog2, Dog3, ...] (goroutines + state files) │ │
|
||||
│ │ │ │
|
||||
│ │ allocate() → Dog │ │
|
||||
│ │ release(Dog) │ │
|
||||
│ │ status() → []DogStatus │ │
|
||||
│ └──────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ Boot's job: │
|
||||
│ - Watch for warrants (file or event) │
|
||||
│ - Allocate dog from pool │
|
||||
│ - Monitor dog progress │
|
||||
│ - Handle dog completion/failure │
|
||||
│ - Report results │
|
||||
└────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Dog Structure
|
||||
|
||||
```go
|
||||
// Dog represents a shutdown-dance executor
|
||||
type Dog struct {
|
||||
ID string // Unique ID (e.g., "dog-1704567890123")
|
||||
Warrant *Warrant // The death warrant being processed
|
||||
State ShutdownDanceState
|
||||
Attempt int // Current interrogation attempt (1-3)
|
||||
StartedAt time.Time
|
||||
StateFile string // Persistent state: ~/gt/deacon/dogs/active/<id>.json
|
||||
}
|
||||
|
||||
type ShutdownDanceState string
|
||||
|
||||
const (
|
||||
StateIdle ShutdownDanceState = "idle"
|
||||
StateInterrogating ShutdownDanceState = "interrogating" // Sent message, waiting
|
||||
StateEvaluating ShutdownDanceState = "evaluating" // Checking response
|
||||
StatePardoned ShutdownDanceState = "pardoned" // Session responded
|
||||
StateExecuting ShutdownDanceState = "executing" // Killing session
|
||||
StateComplete ShutdownDanceState = "complete" // Done, ready for cleanup
|
||||
StateFailed ShutdownDanceState = "failed" // Dog crashed/errored
|
||||
)
|
||||
|
||||
type Warrant struct {
|
||||
ID string // Bead ID for the warrant
|
||||
Target string // Session to interrogate (e.g., "gt-gastown-Toast")
|
||||
Reason string // Why warrant was issued
|
||||
Requester string // Who filed the warrant
|
||||
FiledAt time.Time
|
||||
}
|
||||
```
|
||||
|
||||
## Pool Design
|
||||
|
||||
### Fixed Pool Size
|
||||
|
||||
**Decision**: Fixed pool of 5 dogs, configurable via environment.
|
||||
|
||||
Rationale:
|
||||
- Dynamic sizing adds complexity without clear benefit
|
||||
- 5 concurrent shutdown dances handles worst-case scenarios
|
||||
- If pool exhausted, warrants queue (better than infinite dog spawning)
|
||||
- Memory footprint is negligible (goroutines + small state files)
|
||||
|
||||
```go
|
||||
const (
|
||||
DefaultPoolSize = 5
|
||||
MaxPoolSize = 20
|
||||
)
|
||||
|
||||
type DogPool struct {
|
||||
mu sync.Mutex
|
||||
dogs []*Dog // All dogs in pool
|
||||
idle chan *Dog // Channel of available dogs
|
||||
active map[string]*Dog // ID -> Dog for active dogs
|
||||
stateDir string // ~/gt/deacon/dogs/active/
|
||||
}
|
||||
|
||||
func (p *DogPool) Allocate(warrant *Warrant) (*Dog, error) {
|
||||
select {
|
||||
case dog := <-p.idle:
|
||||
dog.Warrant = warrant
|
||||
dog.State = StateInterrogating
|
||||
dog.Attempt = 1
|
||||
dog.StartedAt = time.Now()
|
||||
p.active[dog.ID] = dog
|
||||
return dog, nil
|
||||
default:
|
||||
return nil, ErrPoolExhausted
|
||||
}
|
||||
}
|
||||
|
||||
func (p *DogPool) Release(dog *Dog) {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
delete(p.active, dog.ID)
|
||||
dog.Reset()
|
||||
p.idle <- dog
|
||||
}
|
||||
```
|
||||
|
||||
### Why Not Dynamic Pool?
|
||||
|
||||
Considered but rejected:
|
||||
- Adding dogs on demand increases complexity
|
||||
- No clear benefit - warrants rarely exceed 5 concurrent
|
||||
- If needed, raise DefaultPoolSize
|
||||
- Simpler to reason about fixed resources
|
||||
|
||||
## Communication: State Files + Events
|
||||
|
||||
### State Persistence
|
||||
|
||||
Each active dog writes state to `~/gt/deacon/dogs/active/<id>.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "dog-1704567890123",
|
||||
"warrant": {
|
||||
"id": "gt-abc123",
|
||||
"target": "gt-gastown-Toast",
|
||||
"reason": "no_response_health_check",
|
||||
"requester": "deacon",
|
||||
"filed_at": "2026-01-07T20:15:00Z"
|
||||
},
|
||||
"state": "interrogating",
|
||||
"attempt": 2,
|
||||
"started_at": "2026-01-07T20:15:00Z",
|
||||
"last_message_at": "2026-01-07T20:16:00Z",
|
||||
"next_timeout": "2026-01-07T20:18:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### Boot Monitoring
|
||||
|
||||
Boot monitors dogs via:
|
||||
1. **Polling**: `gt dog status --active` every tick
|
||||
2. **Completion files**: Dogs write `<id>.done` when complete
|
||||
|
||||
```go
|
||||
type DogResult struct {
|
||||
DogID string
|
||||
Warrant *Warrant
|
||||
Outcome DogOutcome // pardoned | executed | failed
|
||||
Duration time.Duration
|
||||
Details string
|
||||
}
|
||||
|
||||
type DogOutcome string
|
||||
|
||||
const (
|
||||
OutcomePardoned DogOutcome = "pardoned" // Session responded
|
||||
OutcomeExecuted DogOutcome = "executed" // Session killed
|
||||
OutcomeFailed DogOutcome = "failed" // Dog crashed
|
||||
)
|
||||
```
|
||||
|
||||
### Why Not Mail?
|
||||
|
||||
Considered but rejected for dog<->boot communication:
|
||||
- Mail is async, poll-based - adds latency
|
||||
- State files are simpler for local coordination
|
||||
- Dogs don't need complex inter-agent communication
|
||||
- Keep mail for external coordination (Witness, Mayor)
|
||||
|
||||
## Shutdown Dance State Machine
|
||||
|
||||
Each dog executes this state machine:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ │
|
||||
▼ │
|
||||
┌───────────────────────────┐ │
|
||||
│ INTERROGATING │ │
|
||||
│ │ │
|
||||
│ 1. Send health check │ │
|
||||
│ 2. Start timeout timer │ │
|
||||
└───────────┬───────────────┘ │
|
||||
│ │
|
||||
│ timeout or response │
|
||||
▼ │
|
||||
┌───────────────────────────┐ │
|
||||
│ EVALUATING │ │
|
||||
│ │ │
|
||||
│ Check tmux output for │ │
|
||||
│ ALIVE keyword │ │
|
||||
└───────────┬───────────────┘ │
|
||||
│ │
|
||||
┌───────┴───────┐ │
|
||||
│ │ │
|
||||
▼ ▼ │
|
||||
[ALIVE found] [No ALIVE] │
|
||||
│ │ │
|
||||
│ │ attempt < 3? │
|
||||
│ ├──────────────────────────────────→─┘
|
||||
│ │ yes: attempt++, longer timeout
|
||||
│ │
|
||||
│ │ no: attempt == 3
|
||||
▼ ▼
|
||||
┌─────────┐ ┌─────────────┐
|
||||
│ PARDONED│ │ EXECUTING │
|
||||
│ │ │ │
|
||||
│ Cancel │ │ Kill tmux │
|
||||
│ warrant │ │ session │
|
||||
└────┬────┘ └──────┬──────┘
|
||||
│ │
|
||||
└────────┬───────┘
|
||||
│
|
||||
▼
|
||||
┌────────────────┐
|
||||
│ COMPLETE │
|
||||
│ │
|
||||
│ Write result │
|
||||
│ Release dog │
|
||||
└────────────────┘
|
||||
```
|
||||
|
||||
### Timeout Gates
|
||||
|
||||
| Attempt | Timeout | Cumulative Wait |
|
||||
|---------|---------|-----------------|
|
||||
| 1 | 60s | 60s |
|
||||
| 2 | 120s | 180s (3 min) |
|
||||
| 3 | 240s | 420s (7 min) |
|
||||
|
||||
### Health Check Message
|
||||
|
||||
```
|
||||
[DOG] HEALTH CHECK: Session {target}, respond ALIVE within {timeout}s or face termination.
|
||||
Warrant reason: {reason}
|
||||
Filed by: {requester}
|
||||
Attempt: {attempt}/3
|
||||
```
|
||||
|
||||
### Response Detection
|
||||
|
||||
```go
|
||||
func (d *Dog) CheckForResponse() bool {
|
||||
tm := tmux.NewTmux()
|
||||
output, err := tm.CapturePane(d.Warrant.Target, 50) // Last 50 lines
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// Any output after our health check counts as alive
|
||||
// Specifically look for ALIVE keyword for explicit response
|
||||
return strings.Contains(output, "ALIVE")
|
||||
}
|
||||
```
|
||||
|
||||
## Dog Implementation
|
||||
|
||||
### Not Reusing Polecat Infrastructure
|
||||
|
||||
**Decision**: Dogs do NOT reuse polecat infrastructure.
|
||||
|
||||
Rationale:
|
||||
- Polecats are Claude sessions with molecules, hooks, sandboxes
|
||||
- Dogs are simple state machine executors
|
||||
- Polecats have 3-layer lifecycle (session/sandbox/slot)
|
||||
- Dogs have single-layer lifecycle (just state)
|
||||
- Different resource profiles, different management
|
||||
|
||||
What dogs DO share:
|
||||
- tmux utilities for message sending/capture
|
||||
- State file patterns
|
||||
- Name slot allocation pattern (pool of names, not instances)
|
||||
|
||||
### Dog Execution Loop
|
||||
|
||||
```go
|
||||
func (d *Dog) Run(ctx context.Context) DogResult {
|
||||
d.State = StateInterrogating
|
||||
d.saveState()
|
||||
|
||||
for d.Attempt <= 3 {
|
||||
// Send interrogation message
|
||||
if err := d.sendHealthCheck(); err != nil {
|
||||
return d.fail(err)
|
||||
}
|
||||
|
||||
// Wait for timeout or context cancellation
|
||||
timeout := d.timeoutForAttempt(d.Attempt)
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return d.fail(ctx.Err())
|
||||
case <-time.After(timeout):
|
||||
// Timeout reached
|
||||
}
|
||||
|
||||
// Evaluate response
|
||||
d.State = StateEvaluating
|
||||
d.saveState()
|
||||
|
||||
if d.CheckForResponse() {
|
||||
// Session is alive
|
||||
return d.pardon()
|
||||
}
|
||||
|
||||
// No response - try again or execute
|
||||
d.Attempt++
|
||||
if d.Attempt <= 3 {
|
||||
d.State = StateInterrogating
|
||||
d.saveState()
|
||||
}
|
||||
}
|
||||
|
||||
// All attempts exhausted - execute warrant
|
||||
return d.execute()
|
||||
}
|
||||
```
|
||||
|
||||
## Failure Handling
|
||||
|
||||
### Dog Crashes Mid-Dance
|
||||
|
||||
If a dog crashes (Boot process restarts, system crash):
|
||||
|
||||
1. State files persist in `~/gt/deacon/dogs/active/`
|
||||
2. On Boot restart, scan for orphaned state files
|
||||
3. Resume or restart based on state:
|
||||
|
||||
| State | Recovery Action |
|
||||
|------------------|------------------------------------|
|
||||
| interrogating | Restart from current attempt |
|
||||
| evaluating | Check response, continue |
|
||||
| executing | Verify kill, mark complete |
|
||||
| pardoned/complete| Already done, clean up |
|
||||
|
||||
```go
|
||||
func (p *DogPool) RecoverOrphans() error {
|
||||
files, _ := filepath.Glob(p.stateDir + "/*.json")
|
||||
for _, f := range files {
|
||||
state := loadDogState(f)
|
||||
if state.State != StateComplete && state.State != StatePardoned {
|
||||
dog := p.allocateForRecovery(state)
|
||||
go dog.Resume()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
```
|
||||
|
||||
### Handling Pool Exhaustion
|
||||
|
||||
If all dogs are busy when new warrant arrives:
|
||||
|
||||
```go
|
||||
func (b *Boot) HandleWarrant(warrant *Warrant) error {
|
||||
dog, err := b.pool.Allocate(warrant)
|
||||
if err == ErrPoolExhausted {
|
||||
// Queue the warrant for later processing
|
||||
b.warrantQueue.Push(warrant)
|
||||
b.log("Warrant %s queued (pool exhausted)", warrant.ID)
|
||||
return nil
|
||||
}
|
||||
|
||||
go func() {
|
||||
result := dog.Run(b.ctx)
|
||||
b.handleResult(result)
|
||||
b.pool.Release(dog)
|
||||
|
||||
// Check queue for pending warrants
|
||||
if next := b.warrantQueue.Pop(); next != nil {
|
||||
b.HandleWarrant(next)
|
||||
}
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
```
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
~/gt/deacon/dogs/
|
||||
├── boot/ # Boot's working directory
|
||||
│ ├── CLAUDE.md # Boot context
|
||||
│ └── .boot-status.json # Boot execution status
|
||||
├── active/ # Active dog state files
|
||||
│ ├── dog-123.json # Dog 1 state
|
||||
│ ├── dog-456.json # Dog 2 state
|
||||
│ └── ...
|
||||
├── completed/ # Completed dance records (for audit)
|
||||
│ ├── dog-789.json # Historical record
|
||||
│ └── ...
|
||||
└── warrants/ # Pending warrant queue
|
||||
├── warrant-abc.json
|
||||
└── ...
|
||||
```
|
||||
|
||||
## Command Interface
|
||||
|
||||
```bash
|
||||
# Pool status
|
||||
gt dog pool status
|
||||
# Output:
|
||||
# Dog Pool: 3/5 active
|
||||
# dog-123: interrogating Toast (attempt 2, 45s remaining)
|
||||
# dog-456: executing Shadow
|
||||
# dog-789: idle
|
||||
|
||||
# Manual dog operations (for debugging)
|
||||
gt dog pool allocate <warrant-id>
|
||||
gt dog pool release <dog-id>
|
||||
|
||||
# View active dances
|
||||
gt dog dances
|
||||
# Output:
|
||||
# Active Shutdown Dances:
|
||||
# dog-123 → Toast: Interrogating (2/3), timeout in 45s
|
||||
# dog-456 → Shadow: Executing warrant
|
||||
|
||||
# View warrant queue
|
||||
gt dog warrants
|
||||
# Output:
|
||||
# Pending Warrants: 2
|
||||
# 1. gt-abc: witness-gastown (stuck_no_progress)
|
||||
# 2. gt-def: polecat-Copper (crash_loop)
|
||||
```
|
||||
|
||||
## Integration with Existing Dogs
|
||||
|
||||
The existing `dog` package (`internal/dog/`) manages Deacon's multi-rig helper dogs.
|
||||
Those are different from shutdown-dance dogs:
|
||||
|
||||
| Aspect | Helper Dogs (existing) | Dance Dogs (new) |
|
||||
|-----------------|-----------------------------|-----------------------------|
|
||||
| Purpose | Cross-rig infrastructure | Shutdown dance execution |
|
||||
| Sessions | Claude sessions | Goroutines (no Claude) |
|
||||
| Worktrees | One per rig | None |
|
||||
| Lifecycle | Long-lived, reusable | Ephemeral per warrant |
|
||||
| State | idle/working | Dance state machine |
|
||||
|
||||
**Recommendation**: Use different package to avoid confusion:
|
||||
- `internal/dog/` - existing helper dogs
|
||||
- `internal/shutdown/` - shutdown dance pool
|
||||
|
||||
## Summary: Answers to Design Questions
|
||||
|
||||
| Question | Answer |
|
||||
|----------|--------|
|
||||
| How many Dogs in pool? | Fixed: 5 (configurable via GT_DOG_POOL_SIZE) |
|
||||
| How do Dogs communicate with Boot? | State files + completion markers |
|
||||
| Are Dogs tmux sessions? | No - goroutines with state machine |
|
||||
| Reuse polecat infrastructure? | No - too heavyweight, different model |
|
||||
| What if Dog dies mid-dance? | State file recovery on Boot restart |
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [x] Architecture document for Dog pool
|
||||
- [x] Clear allocation/deallocation protocol
|
||||
- [x] Failure handling for Dog crashes
|
||||
248
docs/formula-resolution.md
Normal file
248
docs/formula-resolution.md
Normal file
@@ -0,0 +1,248 @@
|
||||
# Formula Resolution Architecture
|
||||
|
||||
> Where formulas live, how they're found, and how they'll scale to Mol Mall
|
||||
|
||||
## The Problem
|
||||
|
||||
Formulas currently exist in multiple locations with no clear precedence:
|
||||
- `.beads/formulas/` (source of truth for a project)
|
||||
- `internal/formula/formulas/` (embedded copy for `go install`)
|
||||
- Crew directories have their own `.beads/formulas/` (diverging copies)
|
||||
|
||||
When an agent runs `bd cook mol-polecat-work`, which version do they get?
|
||||
|
||||
## Design Goals
|
||||
|
||||
1. **Predictable resolution** - Clear precedence rules
|
||||
2. **Local customization** - Override system defaults without forking
|
||||
3. **Project-specific formulas** - Committed workflows for collaborators
|
||||
4. **Mol Mall ready** - Architecture supports remote formula installation
|
||||
5. **Federation ready** - Formulas are shareable across towns via HOP (Highway Operations Protocol)
|
||||
|
||||
## Three-Tier Resolution
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ FORMULA RESOLUTION ORDER │
|
||||
│ (most specific wins) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
|
||||
TIER 1: PROJECT (rig-level)
|
||||
Location: <project>/.beads/formulas/
|
||||
Source: Committed to project repo
|
||||
Use case: Project-specific workflows (deploy, test, release)
|
||||
Example: ~/gt/gastown/.beads/formulas/mol-gastown-release.formula.toml
|
||||
|
||||
TIER 2: TOWN (user-level)
|
||||
Location: ~/gt/.beads/formulas/
|
||||
Source: Mol Mall installs, user customizations
|
||||
Use case: Cross-project workflows, personal preferences
|
||||
Example: ~/gt/.beads/formulas/mol-polecat-work.formula.toml (customized)
|
||||
|
||||
TIER 3: SYSTEM (embedded)
|
||||
Location: Compiled into gt binary
|
||||
Source: gastown/mayor/rig/.beads/formulas/ at build time
|
||||
Use case: Defaults, blessed patterns, fallback
|
||||
Example: mol-polecat-work.formula.toml (factory default)
|
||||
```
|
||||
|
||||
### Resolution Algorithm
|
||||
|
||||
```go
|
||||
func ResolveFormula(name string, cwd string) (Formula, Tier, error) {
|
||||
// Tier 1: Project-level (walk up from cwd to find .beads/formulas/)
|
||||
if projectDir := findProjectRoot(cwd); projectDir != "" {
|
||||
path := filepath.Join(projectDir, ".beads", "formulas", name+".formula.toml")
|
||||
if f, err := loadFormula(path); err == nil {
|
||||
return f, TierProject, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Tier 2: Town-level
|
||||
townDir := getTownRoot() // ~/gt or $GT_HOME
|
||||
path := filepath.Join(townDir, ".beads", "formulas", name+".formula.toml")
|
||||
if f, err := loadFormula(path); err == nil {
|
||||
return f, TierTown, nil
|
||||
}
|
||||
|
||||
// Tier 3: Embedded (system)
|
||||
if f, err := loadEmbeddedFormula(name); err == nil {
|
||||
return f, TierSystem, nil
|
||||
}
|
||||
|
||||
return nil, 0, ErrFormulaNotFound
|
||||
}
|
||||
```
|
||||
|
||||
### Why This Order
|
||||
|
||||
**Project wins** because:
|
||||
- Project maintainers know their workflows best
|
||||
- Collaborators get consistent behavior via git
|
||||
- CI/CD uses the same formulas as developers
|
||||
|
||||
**Town is middle** because:
|
||||
- User customizations override system defaults
|
||||
- Mol Mall installs don't require project changes
|
||||
- Cross-project consistency for the user
|
||||
|
||||
**System is fallback** because:
|
||||
- Always available (compiled in)
|
||||
- Factory reset target
|
||||
- The "blessed" versions
|
||||
|
||||
## Formula Identity
|
||||
|
||||
### Current Format
|
||||
|
||||
```toml
|
||||
formula = "mol-polecat-work"
|
||||
version = 4
|
||||
description = "..."
|
||||
```
|
||||
|
||||
### Extended Format (Mol Mall Ready)
|
||||
|
||||
```toml
|
||||
[formula]
|
||||
name = "mol-polecat-work"
|
||||
version = "4.0.0" # Semver
|
||||
author = "steve@gastown.io" # Author identity
|
||||
license = "MIT"
|
||||
repository = "https://github.com/steveyegge/gastown"
|
||||
|
||||
[formula.registry]
|
||||
uri = "hop://molmall.gastown.io/formulas/mol-polecat-work@4.0.0"
|
||||
checksum = "sha256:abc123..." # Integrity verification
|
||||
signed_by = "steve@gastown.io" # Optional signing
|
||||
|
||||
[formula.capabilities]
|
||||
# What capabilities does this formula exercise? Used for agent routing.
|
||||
primary = ["go", "testing", "code-review"]
|
||||
secondary = ["git", "ci-cd"]
|
||||
```
|
||||
|
||||
### Version Resolution
|
||||
|
||||
When multiple versions exist:
|
||||
|
||||
```bash
|
||||
bd cook mol-polecat-work # Resolves per tier order
|
||||
bd cook mol-polecat-work@4 # Specific major version
|
||||
bd cook mol-polecat-work@4.0.0 # Exact version
|
||||
bd cook mol-polecat-work@latest # Explicit latest
|
||||
```
|
||||
|
||||
## Crew Directory Problem
|
||||
|
||||
### Current State
|
||||
|
||||
Crew directories (`gastown/crew/max/`) are sparse checkouts of gastown. They have:
|
||||
- Their own `.beads/formulas/` (from the checkout)
|
||||
- These can diverge from `mayor/rig/.beads/formulas/`
|
||||
|
||||
### The Fix
|
||||
|
||||
Crew should NOT have their own formula copies. Options:
|
||||
|
||||
**Option A: Symlink/Redirect**
|
||||
```bash
|
||||
# crew/max/.beads/formulas -> ../../mayor/rig/.beads/formulas
|
||||
```
|
||||
All crew share the rig's formulas.
|
||||
|
||||
**Option B: Provision on Demand**
|
||||
Crew directories don't have `.beads/formulas/`. Resolution falls through to:
|
||||
1. Town-level (~/gt/.beads/formulas/)
|
||||
2. System (embedded)
|
||||
|
||||
**Option C: Sparse Checkout Exclusion**
|
||||
Exclude `.beads/formulas/` from crew sparse checkouts entirely.
|
||||
|
||||
**Recommendation: Option B** - Crew shouldn't need project-level formulas. They work on the project, they don't define its workflows.
|
||||
|
||||
## Commands
|
||||
|
||||
### Existing
|
||||
|
||||
```bash
|
||||
bd formula list # Available formulas (should show tier)
|
||||
bd formula show <name> # Formula details
|
||||
bd cook <formula> # Formula → Proto
|
||||
```
|
||||
|
||||
### Enhanced
|
||||
|
||||
```bash
|
||||
# List with tier information
|
||||
bd formula list
|
||||
mol-polecat-work v4 [project]
|
||||
mol-polecat-code-review v1 [town]
|
||||
mol-witness-patrol v2 [system]
|
||||
|
||||
# Show resolution path
|
||||
bd formula show mol-polecat-work --resolve
|
||||
Resolving: mol-polecat-work
|
||||
✓ Found at: ~/gt/gastown/.beads/formulas/mol-polecat-work.formula.toml
|
||||
Tier: project
|
||||
Version: 4
|
||||
|
||||
Resolution path checked:
|
||||
1. [project] ~/gt/gastown/.beads/formulas/ ← FOUND
|
||||
2. [town] ~/gt/.beads/formulas/
|
||||
3. [system] <embedded>
|
||||
|
||||
# Override tier for testing
|
||||
bd cook mol-polecat-work --tier=system # Force embedded version
|
||||
bd cook mol-polecat-work --tier=town # Force town version
|
||||
```
|
||||
|
||||
### Future (Mol Mall)
|
||||
|
||||
```bash
|
||||
# Install from Mol Mall
|
||||
gt formula install mol-code-review-strict
|
||||
gt formula install mol-code-review-strict@2.0.0
|
||||
gt formula install hop://acme.corp/formulas/mol-deploy
|
||||
|
||||
# Manage installed formulas
|
||||
gt formula list --installed # What's in town-level
|
||||
gt formula upgrade mol-polecat-work # Update to latest
|
||||
gt formula pin mol-polecat-work@4.0.0 # Lock version
|
||||
gt formula uninstall mol-code-review-strict
|
||||
```
|
||||
|
||||
## Migration Path
|
||||
|
||||
### Phase 1: Resolution Order (Now)
|
||||
|
||||
1. Implement three-tier resolution in `bd cook`
|
||||
2. Add `--resolve` flag to show resolution path
|
||||
3. Update `bd formula list` to show tiers
|
||||
4. Fix crew directories (Option B)
|
||||
|
||||
### Phase 2: Town-Level Formulas
|
||||
|
||||
1. Establish `~/gt/.beads/formulas/` as town formula location
|
||||
2. Add `gt formula` commands for managing town formulas
|
||||
3. Support manual installation (copy file, track in `.installed.json`)
|
||||
|
||||
### Phase 3: Mol Mall Integration
|
||||
|
||||
1. Define registry API (see mol-mall-design.md)
|
||||
2. Implement `gt formula install` from remote
|
||||
3. Add version pinning and upgrade flows
|
||||
4. Add integrity verification (checksums, optional signing)
|
||||
|
||||
### Phase 4: Federation (HOP)
|
||||
|
||||
1. Add capability tags to formula schema
|
||||
2. Track formula execution for agent accountability
|
||||
3. Enable federation (cross-town formula sharing via Highway Operations Protocol)
|
||||
4. Author attribution and validation records
|
||||
|
||||
## Related Documents
|
||||
|
||||
- [Mol Mall Design](mol-mall-design.md) - Registry architecture
|
||||
- [molecules.md](molecules.md) - Formula → Proto → Mol lifecycle
|
||||
- [understanding-gas-town.md](../../../docs/understanding-gas-town.md) - Gas Town architecture
|
||||
476
docs/mol-mall-design.md
Normal file
476
docs/mol-mall-design.md
Normal file
@@ -0,0 +1,476 @@
|
||||
# Mol Mall Design
|
||||
|
||||
> A marketplace for Gas Town formulas
|
||||
|
||||
## Vision
|
||||
|
||||
**Mol Mall** is a registry for sharing formulas across Gas Town installations. Think npm for molecules, or Terraform Registry for workflows.
|
||||
|
||||
```
|
||||
"Cook a formula, sling it to a polecat, the witness watches, refinery merges."
|
||||
|
||||
What if you could browse a mall of formulas, install one, and immediately
|
||||
have your polecats executing world-class workflows?
|
||||
```
|
||||
|
||||
### The Network Effect
|
||||
|
||||
A well-designed formula for "code review" or "security audit" or "deploy to K8s" can spread across thousands of Gas Town installations. Each adoption means:
|
||||
- More agents executing proven workflows
|
||||
- More structured, trackable work output
|
||||
- Better capability routing (agents with track records on a formula get similar work)
|
||||
|
||||
## Architecture
|
||||
|
||||
### Registry Types
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ MOL MALL REGISTRIES │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
|
||||
PUBLIC REGISTRY (molmall.gastown.io)
|
||||
├── Community formulas (MIT licensed)
|
||||
├── Official Gas Town formulas (blessed)
|
||||
├── Verified publisher formulas
|
||||
└── Open contribution model
|
||||
|
||||
PRIVATE REGISTRY (self-hosted)
|
||||
├── Organization-specific formulas
|
||||
├── Proprietary workflows
|
||||
├── Internal deployment patterns
|
||||
└── Enterprise compliance formulas
|
||||
|
||||
FEDERATED REGISTRY (HOP future)
|
||||
├── Cross-organization discovery
|
||||
├── Skill-based search
|
||||
└── Attribution chain tracking
|
||||
└── hop:// URI resolution
|
||||
```
|
||||
|
||||
### URI Scheme
|
||||
|
||||
```
|
||||
hop://molmall.gastown.io/formulas/mol-polecat-work@4.0.0
|
||||
└──────────────────┘ └──────────────┘ └───┘
|
||||
registry host formula name version
|
||||
|
||||
# Short forms
|
||||
mol-polecat-work # Default registry, latest version
|
||||
mol-polecat-work@4 # Major version
|
||||
mol-polecat-work@4.0.0 # Exact version
|
||||
@acme/mol-deploy # Scoped to publisher
|
||||
hop://acme.corp/formulas/mol-deploy # Full HOP URI
|
||||
```
|
||||
|
||||
### Registry API
|
||||
|
||||
```yaml
|
||||
# OpenAPI-style specification
|
||||
|
||||
GET /formulas
|
||||
# List all formulas
|
||||
Query:
|
||||
- q: string # Search query
|
||||
- capabilities: string[] # Filter by capability tags
|
||||
- author: string # Filter by author
|
||||
- limit: int
|
||||
- offset: int
|
||||
Response:
|
||||
formulas:
|
||||
- name: mol-polecat-work
|
||||
version: 4.0.0
|
||||
description: "Full polecat work lifecycle..."
|
||||
author: steve@gastown.io
|
||||
downloads: 12543
|
||||
capabilities: [go, testing, code-review]
|
||||
|
||||
GET /formulas/{name}
|
||||
# Get formula metadata
|
||||
Response:
|
||||
name: mol-polecat-work
|
||||
versions: [4.0.0, 3.2.1, 3.2.0, ...]
|
||||
latest: 4.0.0
|
||||
author: steve@gastown.io
|
||||
repository: https://github.com/steveyegge/gastown
|
||||
license: MIT
|
||||
capabilities:
|
||||
primary: [go, testing]
|
||||
secondary: [git, code-review]
|
||||
stats:
|
||||
downloads: 12543
|
||||
stars: 234
|
||||
used_by: 89 # towns using this formula
|
||||
|
||||
GET /formulas/{name}/{version}
|
||||
# Get specific version
|
||||
Response:
|
||||
name: mol-polecat-work
|
||||
version: 4.0.0
|
||||
checksum: sha256:abc123...
|
||||
signature: <optional PGP signature>
|
||||
content: <base64 or URL to .formula.toml>
|
||||
changelog: "Added self-cleaning model..."
|
||||
published_at: 2026-01-10T00:00:00Z
|
||||
|
||||
POST /formulas
|
||||
# Publish formula (authenticated)
|
||||
Body:
|
||||
name: mol-my-workflow
|
||||
version: 1.0.0
|
||||
content: <formula TOML>
|
||||
changelog: "Initial release"
|
||||
Auth: Bearer token (linked to HOP identity)
|
||||
|
||||
GET /formulas/{name}/{version}/download
|
||||
# Download formula content
|
||||
Response: raw .formula.toml content
|
||||
```
|
||||
|
||||
## Formula Package Format
|
||||
|
||||
### Simple Case: Single File
|
||||
|
||||
Most formulas are single `.formula.toml` files:
|
||||
|
||||
```bash
|
||||
gt formula install mol-polecat-code-review
|
||||
# Downloads mol-polecat-code-review.formula.toml to ~/gt/.beads/formulas/
|
||||
```
|
||||
|
||||
### Complex Case: Formula Bundle
|
||||
|
||||
Some formulas need supporting files (scripts, templates, configs):
|
||||
|
||||
```
|
||||
mol-deploy-k8s.formula.bundle/
|
||||
├── formula.toml # Main formula
|
||||
├── templates/
|
||||
│ ├── deployment.yaml.tmpl
|
||||
│ └── service.yaml.tmpl
|
||||
├── scripts/
|
||||
│ └── healthcheck.sh
|
||||
└── README.md
|
||||
```
|
||||
|
||||
Bundle format:
|
||||
```bash
|
||||
# Bundles are tarballs
|
||||
mol-deploy-k8s-1.0.0.bundle.tar.gz
|
||||
```
|
||||
|
||||
Installation:
|
||||
```bash
|
||||
gt formula install mol-deploy-k8s
|
||||
# Extracts to ~/gt/.beads/formulas/mol-deploy-k8s/
|
||||
# formula.toml is at mol-deploy-k8s/formula.toml
|
||||
```
|
||||
|
||||
## Installation Flow
|
||||
|
||||
### Basic Install
|
||||
|
||||
```bash
|
||||
$ gt formula install mol-polecat-code-review
|
||||
|
||||
Resolving mol-polecat-code-review...
|
||||
Registry: molmall.gastown.io
|
||||
Version: 1.2.0 (latest)
|
||||
Author: steve@gastown.io
|
||||
Skills: code-review, security
|
||||
|
||||
Downloading... ████████████████████ 100%
|
||||
Verifying checksum... ✓
|
||||
|
||||
Installed to: ~/gt/.beads/formulas/mol-polecat-code-review.formula.toml
|
||||
```
|
||||
|
||||
### Version Pinning
|
||||
|
||||
```bash
|
||||
$ gt formula install mol-polecat-work@4.0.0
|
||||
|
||||
Installing mol-polecat-work@4.0.0 (pinned)...
|
||||
✓ Installed
|
||||
|
||||
$ gt formula list --installed
|
||||
mol-polecat-work 4.0.0 [pinned]
|
||||
mol-polecat-code-review 1.2.0 [latest]
|
||||
```
|
||||
|
||||
### Upgrade Flow
|
||||
|
||||
```bash
|
||||
$ gt formula upgrade mol-polecat-code-review
|
||||
|
||||
Checking for updates...
|
||||
Current: 1.2.0
|
||||
Latest: 1.3.0
|
||||
|
||||
Changelog for 1.3.0:
|
||||
- Added security focus option
|
||||
- Improved test coverage step
|
||||
|
||||
Upgrade? [y/N] y
|
||||
|
||||
Downloading... ✓
|
||||
Installed: mol-polecat-code-review@1.3.0
|
||||
```
|
||||
|
||||
### Lock File
|
||||
|
||||
```json
|
||||
// ~/gt/.beads/formulas/.lock.json
|
||||
{
|
||||
"version": 1,
|
||||
"formulas": {
|
||||
"mol-polecat-work": {
|
||||
"version": "4.0.0",
|
||||
"pinned": true,
|
||||
"checksum": "sha256:abc123...",
|
||||
"installed_at": "2026-01-10T00:00:00Z",
|
||||
"source": "hop://molmall.gastown.io/formulas/mol-polecat-work@4.0.0"
|
||||
},
|
||||
"mol-polecat-code-review": {
|
||||
"version": "1.3.0",
|
||||
"pinned": false,
|
||||
"checksum": "sha256:def456...",
|
||||
"installed_at": "2026-01-10T12:00:00Z",
|
||||
"source": "hop://molmall.gastown.io/formulas/mol-polecat-code-review@1.3.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Publishing Flow
|
||||
|
||||
### First-Time Setup
|
||||
|
||||
```bash
|
||||
$ gt formula publish --init
|
||||
|
||||
Setting up Mol Mall publishing...
|
||||
|
||||
1. Create account at https://molmall.gastown.io/signup
|
||||
2. Generate API token at https://molmall.gastown.io/settings/tokens
|
||||
3. Run: gt formula login
|
||||
|
||||
$ gt formula login
|
||||
Token: ********
|
||||
Logged in as: steve@gastown.io
|
||||
```
|
||||
|
||||
### Publishing
|
||||
|
||||
```bash
|
||||
$ gt formula publish mol-polecat-work
|
||||
|
||||
Publishing mol-polecat-work...
|
||||
|
||||
Pre-flight checks:
|
||||
✓ formula.toml is valid
|
||||
✓ Version 4.0.0 not yet published
|
||||
✓ Required fields present (name, version, description)
|
||||
✓ Skills declared
|
||||
|
||||
Publish to molmall.gastown.io? [y/N] y
|
||||
|
||||
Uploading... ✓
|
||||
Published: hop://molmall.gastown.io/formulas/mol-polecat-work@4.0.0
|
||||
|
||||
View at: https://molmall.gastown.io/formulas/mol-polecat-work
|
||||
```
|
||||
|
||||
### Verification Levels
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ FORMULA TRUST LEVELS │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
|
||||
UNVERIFIED (default)
|
||||
Anyone can publish
|
||||
Basic validation only
|
||||
Displayed with ⚠️ warning
|
||||
|
||||
VERIFIED PUBLISHER
|
||||
Publisher identity confirmed
|
||||
Displayed with ✓ checkmark
|
||||
Higher search ranking
|
||||
|
||||
OFFICIAL
|
||||
Maintained by Gas Town team
|
||||
Displayed with 🏛️ badge
|
||||
Included in embedded defaults
|
||||
|
||||
AUDITED
|
||||
Security review completed
|
||||
Displayed with 🔒 badge
|
||||
Required for enterprise registries
|
||||
```
|
||||
|
||||
## Capability Tagging
|
||||
|
||||
### Formula Capability Declaration
|
||||
|
||||
```toml
|
||||
[formula.capabilities]
|
||||
# What capabilities does this formula exercise? Used for agent routing.
|
||||
primary = ["go", "testing", "code-review"]
|
||||
secondary = ["git", "ci-cd"]
|
||||
|
||||
# Capability weights (optional, for fine-grained routing)
|
||||
[formula.capabilities.weights]
|
||||
go = 0.3 # 30% of formula work is Go
|
||||
testing = 0.4 # 40% is testing
|
||||
code-review = 0.3 # 30% is code review
|
||||
```
|
||||
|
||||
### Capability-Based Search
|
||||
|
||||
```bash
|
||||
$ gt formula search --capabilities="security,go"
|
||||
|
||||
Formulas matching capabilities: security, go
|
||||
|
||||
mol-security-audit v2.1.0 ⭐ 4.8 📥 8,234
|
||||
Capabilities: security, go, code-review
|
||||
"Comprehensive security audit workflow"
|
||||
|
||||
mol-dependency-scan v1.0.0 ⭐ 4.2 📥 3,102
|
||||
Capabilities: security, go, supply-chain
|
||||
"Scan Go dependencies for vulnerabilities"
|
||||
```
|
||||
|
||||
### Agent Accountability
|
||||
|
||||
When a polecat completes a formula, the execution is tracked:
|
||||
|
||||
```
|
||||
Polecat: beads/amber
|
||||
Formula: mol-polecat-code-review@1.3.0
|
||||
Completed: 2026-01-10T15:30:00Z
|
||||
Capabilities exercised:
|
||||
- code-review (primary)
|
||||
- security (secondary)
|
||||
- go (secondary)
|
||||
```
|
||||
|
||||
This execution record enables:
|
||||
1. **Routing** - Agents with successful track records get similar work
|
||||
2. **Debugging** - Trace which agent did what, when
|
||||
3. **Quality metrics** - Track success rates by agent and formula
|
||||
|
||||
## Private Registries
|
||||
|
||||
### Enterprise Deployment
|
||||
|
||||
```yaml
|
||||
# ~/.gtconfig.yaml
|
||||
registries:
|
||||
- name: acme
|
||||
url: https://molmall.acme.corp
|
||||
auth: token
|
||||
priority: 1 # Check first
|
||||
|
||||
- name: public
|
||||
url: https://molmall.gastown.io
|
||||
auth: none
|
||||
priority: 2 # Fallback
|
||||
```
|
||||
|
||||
### Self-Hosted Registry
|
||||
|
||||
```bash
|
||||
# Docker deployment
|
||||
docker run -d \
|
||||
-p 8080:8080 \
|
||||
-v /data/formulas:/formulas \
|
||||
-e AUTH_PROVIDER=oidc \
|
||||
gastown/molmall-registry:latest
|
||||
|
||||
# Configuration
|
||||
MOLMALL_STORAGE=s3://bucket/formulas
|
||||
MOLMALL_AUTH=oidc
|
||||
MOLMALL_OIDC_ISSUER=https://auth.acme.corp
|
||||
```
|
||||
|
||||
## Federation
|
||||
|
||||
Federation enables formula sharing across organizations using the Highway Operations Protocol (HOP).
|
||||
|
||||
### Cross-Registry Discovery
|
||||
|
||||
```bash
|
||||
$ gt formula search "deploy kubernetes" --federated
|
||||
|
||||
Searching across federated registries...
|
||||
|
||||
molmall.gastown.io:
|
||||
mol-deploy-k8s v3.0.0 🏛️ Official
|
||||
|
||||
molmall.acme.corp:
|
||||
@acme/mol-deploy-k8s v2.1.0 ✓ Verified
|
||||
|
||||
molmall.bigco.io:
|
||||
@bigco/k8s-workflow v1.0.0 ⚠️ Unverified
|
||||
```
|
||||
|
||||
### HOP URI Resolution
|
||||
|
||||
The `hop://` URI scheme provides cross-registry entity references:
|
||||
|
||||
```bash
|
||||
# Full HOP URI
|
||||
gt formula install hop://molmall.acme.corp/formulas/@acme/mol-deploy@2.1.0
|
||||
|
||||
# Resolution via HOP (Highway Operations Protocol)
|
||||
1. Parse hop:// URI
|
||||
2. Resolve registry endpoint (DNS/HOP discovery)
|
||||
3. Authenticate (if required)
|
||||
4. Download formula
|
||||
5. Verify checksum/signature
|
||||
6. Install to town-level
|
||||
```
|
||||
|
||||
## Implementation Phases
|
||||
|
||||
### Phase 1: Local Commands (Now)
|
||||
|
||||
- `gt formula list` with tier display
|
||||
- `gt formula show --resolve`
|
||||
- Formula resolution order (project → town → system)
|
||||
|
||||
### Phase 2: Manual Sharing
|
||||
|
||||
- Formula export/import
|
||||
- `gt formula export mol-polecat-work > mol-polecat-work.formula.toml`
|
||||
- `gt formula import < mol-polecat-work.formula.toml`
|
||||
- Lock file format
|
||||
|
||||
### Phase 3: Public Registry
|
||||
|
||||
- molmall.gastown.io launch
|
||||
- `gt formula install` from registry
|
||||
- `gt formula publish` flow
|
||||
- Basic search and browse
|
||||
|
||||
### Phase 4: Enterprise Features
|
||||
|
||||
- Private registry support
|
||||
- Authentication integration
|
||||
- Verification levels
|
||||
- Audit logging
|
||||
|
||||
### Phase 5: Federation (HOP)
|
||||
|
||||
- Capability tags in schema
|
||||
- Federation protocol (Highway Operations Protocol)
|
||||
- Cross-registry search
|
||||
- Agent execution tracking for accountability
|
||||
|
||||
## Related Documents
|
||||
|
||||
- [Formula Resolution](formula-resolution.md) - Local resolution order
|
||||
- [molecules.md](molecules.md) - Formula lifecycle (cook, pour, squash)
|
||||
- [understanding-gas-town.md](../../../docs/understanding-gas-town.md) - Gas Town architecture
|
||||
Reference in New Issue
Block a user