Move documentation files into a clearer structure: - concepts/: core ideas (convoy, identity, molecules, polecat-lifecycle, propulsion) - design/: architecture and protocols (architecture, escalation, federation, mail, etc.) - examples/: demos and tutorials (hanoi-demo) - overview.md: renamed from understanding-gas-town.md Remove outdated/superseded docs and update reference.md. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
301 lines
8.5 KiB
Markdown
301 lines
8.5 KiB
Markdown
# Property Layers: Multi-Level Configuration
|
|
|
|
> Implementation guide for Gas Town's configuration system.
|
|
> Created: 2025-01-06
|
|
|
|
## Overview
|
|
|
|
Gas Town uses a layered property system for configuration. Properties are
|
|
looked up through multiple layers, with earlier layers overriding later ones.
|
|
This enables both local control and global coordination.
|
|
|
|
## The Four Layers
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ 1. WISP LAYER (transient, town-local) │
|
|
│ Location: <rig>/.beads-wisp/config/ │
|
|
│ Synced: Never │
|
|
│ Use: Temporary local overrides │
|
|
└─────────────────────────────┬───────────────────────────────┘
|
|
│ if missing
|
|
▼
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ 2. RIG BEAD LAYER (persistent, synced globally) │
|
|
│ Location: <rig>/.beads/ (rig identity bead labels) │
|
|
│ Synced: Via git (all clones see it) │
|
|
│ Use: Project-wide operational state │
|
|
└─────────────────────────────┬───────────────────────────────┘
|
|
│ if missing
|
|
▼
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ 3. TOWN DEFAULTS │
|
|
│ Location: ~/gt/config.json or ~/gt/.beads/ │
|
|
│ Synced: N/A (per-town) │
|
|
│ Use: Town-wide policies │
|
|
└─────────────────────────────┬───────────────────────────────┘
|
|
│ if missing
|
|
▼
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ 4. SYSTEM DEFAULTS (compiled in) │
|
|
│ Use: Fallback when nothing else specified │
|
|
└─────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
## Lookup Behavior
|
|
|
|
### Override Semantics (Default)
|
|
|
|
For most properties, the first non-nil value wins:
|
|
|
|
```go
|
|
func GetConfig(key string) interface{} {
|
|
if val := wisp.Get(key); val != nil {
|
|
if val == Blocked { return nil }
|
|
return val
|
|
}
|
|
if val := rigBead.GetLabel(key); val != nil {
|
|
return val
|
|
}
|
|
if val := townDefaults.Get(key); val != nil {
|
|
return val
|
|
}
|
|
return systemDefaults[key]
|
|
}
|
|
```
|
|
|
|
### Stacking Semantics (Integers)
|
|
|
|
For integer properties, values from wisp and bead layers **add** to the base:
|
|
|
|
```go
|
|
func GetIntConfig(key string) int {
|
|
base := getBaseDefault(key) // Town or system default
|
|
beadAdj := rigBead.GetInt(key) // 0 if missing
|
|
wispAdj := wisp.GetInt(key) // 0 if missing
|
|
return base + beadAdj + wispAdj
|
|
}
|
|
```
|
|
|
|
This enables temporary adjustments without changing the base value.
|
|
|
|
### Blocking Inheritance
|
|
|
|
You can explicitly block a property from being inherited:
|
|
|
|
```bash
|
|
gt rig config set gastown auto_restart --block
|
|
```
|
|
|
|
This creates a "blocked" marker in the wisp layer. Even if the rig bead
|
|
or defaults say `auto_restart: true`, the lookup returns nil.
|
|
|
|
## Rig Identity Beads
|
|
|
|
Each rig has an identity bead for operational state:
|
|
|
|
```yaml
|
|
id: gt-rig-gastown
|
|
type: rig
|
|
name: gastown
|
|
repo: git@github.com:steveyegge/gastown.git
|
|
prefix: gt
|
|
|
|
labels:
|
|
- status:operational
|
|
- priority:normal
|
|
```
|
|
|
|
These beads sync via git, so all clones of the rig see the same state.
|
|
|
|
## Two-Level Rig Control
|
|
|
|
### Level 1: Park (Local, Ephemeral)
|
|
|
|
```bash
|
|
gt rig park gastown # Stop services, daemon won't restart
|
|
gt rig unpark gastown # Allow services to run
|
|
```
|
|
|
|
- Stored in wisp layer (`.beads-wisp/config/`)
|
|
- Only affects this town
|
|
- Disappears on cleanup
|
|
- Use: Local maintenance, debugging
|
|
|
|
### Level 2: Dock (Global, Persistent)
|
|
|
|
```bash
|
|
gt rig dock gastown # Set status:docked label on rig bead
|
|
gt rig undock gastown # Remove label
|
|
```
|
|
|
|
- Stored on rig identity bead
|
|
- Syncs to all clones via git
|
|
- Permanent until explicitly changed
|
|
- Use: Project-wide maintenance, coordinated downtime
|
|
|
|
### Daemon Behavior
|
|
|
|
The daemon checks both levels before auto-restarting:
|
|
|
|
```go
|
|
func shouldAutoRestart(rig *Rig) bool {
|
|
status := rig.GetConfig("status")
|
|
if status == "parked" || status == "docked" {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
```
|
|
|
|
## Configuration Keys
|
|
|
|
| Key | Type | Behavior | Description |
|
|
|-----|------|----------|-------------|
|
|
| `status` | string | Override | operational/parked/docked |
|
|
| `auto_restart` | bool | Override | Daemon auto-restart behavior |
|
|
| `max_polecats` | int | Override | Maximum concurrent polecats |
|
|
| `priority_adjustment` | int | **Stack** | Scheduling priority modifier |
|
|
| `maintenance_window` | string | Override | When maintenance allowed |
|
|
| `dnd` | bool | Override | Do not disturb mode |
|
|
|
|
## Commands
|
|
|
|
### View Configuration
|
|
|
|
```bash
|
|
gt rig config show gastown # Show effective config (all layers)
|
|
gt rig config show gastown --layer # Show which layer each value comes from
|
|
```
|
|
|
|
### Set Configuration
|
|
|
|
```bash
|
|
# Set in wisp layer (local, ephemeral)
|
|
gt rig config set gastown key value
|
|
|
|
# Set in bead layer (global, permanent)
|
|
gt rig config set gastown key value --global
|
|
|
|
# Block inheritance
|
|
gt rig config set gastown key --block
|
|
|
|
# Clear from wisp layer
|
|
gt rig config unset gastown key
|
|
```
|
|
|
|
### Rig Lifecycle
|
|
|
|
```bash
|
|
gt rig park gastown # Local: stop + prevent restart
|
|
gt rig unpark gastown # Local: allow restart
|
|
|
|
gt rig dock gastown # Global: mark as offline
|
|
gt rig undock gastown # Global: mark as operational
|
|
|
|
gt rig status gastown # Show current state
|
|
```
|
|
|
|
## Examples
|
|
|
|
### Temporary Priority Boost
|
|
|
|
```bash
|
|
# Base priority: 0 (from defaults)
|
|
# Give this rig temporary priority boost for urgent work
|
|
|
|
gt rig config set gastown priority_adjustment 10
|
|
|
|
# Effective priority: 0 + 10 = 10
|
|
# When done, clear it:
|
|
|
|
gt rig config unset gastown priority_adjustment
|
|
```
|
|
|
|
### Local Maintenance
|
|
|
|
```bash
|
|
# I'm upgrading the local clone, don't restart services
|
|
gt rig park gastown
|
|
|
|
# ... do maintenance ...
|
|
|
|
gt rig unpark gastown
|
|
```
|
|
|
|
### Project-Wide Maintenance
|
|
|
|
```bash
|
|
# Major refactor in progress, all clones should pause
|
|
gt rig dock gastown
|
|
|
|
# Syncs via git - other towns see the rig as docked
|
|
bd sync
|
|
|
|
# When done:
|
|
gt rig undock gastown
|
|
bd sync
|
|
```
|
|
|
|
### Block Auto-Restart Locally
|
|
|
|
```bash
|
|
# Rig bead says auto_restart: true
|
|
# But I'm debugging and don't want that here
|
|
|
|
gt rig config set gastown auto_restart --block
|
|
|
|
# Now auto_restart returns nil for this town only
|
|
```
|
|
|
|
## Implementation Notes
|
|
|
|
### Wisp Storage
|
|
|
|
Wisp config stored in `.beads-wisp/config/<rig>.json`:
|
|
|
|
```json
|
|
{
|
|
"rig": "gastown",
|
|
"values": {
|
|
"status": "parked",
|
|
"priority_adjustment": 10
|
|
},
|
|
"blocked": ["auto_restart"]
|
|
}
|
|
```
|
|
|
|
### Rig Bead Labels
|
|
|
|
Rig operational state stored as labels on the rig identity bead:
|
|
|
|
```bash
|
|
bd label add gt-rig-gastown status:docked
|
|
bd label remove gt-rig-gastown status:docked
|
|
```
|
|
|
|
### Daemon Integration
|
|
|
|
The daemon's lifecycle manager checks config before starting services:
|
|
|
|
```go
|
|
func (d *Daemon) maybeStartRigServices(rig string) {
|
|
r := d.getRig(rig)
|
|
|
|
status := r.GetConfig("status")
|
|
if status == "parked" || status == "docked" {
|
|
log.Info("Rig %s is offline, skipping auto-start", rig)
|
|
return
|
|
}
|
|
|
|
d.ensureWitness(rig)
|
|
d.ensureRefinery(rig)
|
|
}
|
|
```
|
|
|
|
## Related Documents
|
|
|
|
- `~/gt/docs/hop/PROPERTY-LAYERS.md` - Strategic architecture
|
|
- `wisp-architecture.md` - Wisp system design
|
|
- `agent-as-bead.md` - Agent identity beads (similar pattern)
|