terminology: spawn → pour/wisp for molecules (gt-9uy0)

Molecules use chemistry verbs, not spawn:
- pour = create persistent mol (liquid)
- wisp = create ephemeral wisp (vapor)
- spawn = polecats only (workers)

Changes:
- Delete chemistry-design-changes.md (migration doc)
- Remove migration tables from sling-design.md
- Update bond tables: Spawn → Pour/Wisp
- Rename spawnMoleculeFromProto → pourMoleculeFromProto
- Rename spawnMoleculeOnIssue → runMoleculeOnIssue
- Update templates: bd mol spawn → bd wisp
- Update prime.go: commands and messages
- Clean all docs and comments

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Steve Yegge
2025-12-24 14:02:09 -08:00
parent 0acad8af25
commit c10709dc3f
17 changed files with 95 additions and 531 deletions

View File

@@ -604,7 +604,7 @@ Some workflows need **dynamic structure** - steps that emerge at runtime based
on discovered work. Consider mol-witness-patrol: it monitors N polecats where
N varies. A static molecule can't express "for each polecat, do these steps."
The solution is **dynamic bonding** - spawning child molecules at runtime:
The solution is **dynamic bonding** - creating child molecules at runtime:
```bash
# In survey-workers step:

View File

@@ -1,375 +0,0 @@
# Chemistry Design Changes
> Implementation roadmap for the molecular chemistry UX described in
> `molecular-chemistry.md`
## Summary of Changes
The chemistry metaphor requires the following changes to Beads and Gas Town:
### Beads Changes
| Change | Priority | Issue |
|--------|----------|-------|
| Add `bd pour` command (alias for `bd mol spawn --pour`) | P0 | Create |
| Add `bd wisp` command (alias for `bd mol spawn`) | P0 | Create |
| Add `bd pin` command for agent attachment | P1 | Create |
| Add `bd hook` command for hook inspection | P2 | Create |
| Rename `--persistent` to `--pour` in `bd mol spawn` | P0 | Update |
| Add `--pour` flag to `bd mol bond` | P1 | Update |
| Implement digest ID reservation for wisps | P1 | Create |
### Gas Town Changes
| Change | Priority | Issue |
|--------|----------|-------|
| Update daemon: remove permanent attachment for patrol | P0 | gt-3x0z.9 |
| Update deacon.md.tmpl: use wisp-based patrol | P0 | gt-3x0z.9 |
| Update witness.md.tmpl: use wisp-based patrol | P1 | Create |
| Add `gt hook` command (thin wrapper around `bd hook`) | P2 | Create |
---
## Detailed Specifications
### 1. `bd pour` Command
**Purpose:** Instantiate a proto as a persistent mol (liquid phase).
**Syntax:**
```bash
bd pour <proto-id> [flags]
Flags:
--var strings Variable substitution (key=value)
--assignee Assign the root issue to this agent
--dry-run Preview what would be created
```
**Implementation:**
- Alias/wrapper for `bd mol spawn <proto-id> --pour`
- Default behavior: creates mol in permanent `.beads/` storage
- Returns the head bead ID of the created mol
**Example:**
```bash
bd pour mol-feature --var name=auth
# Output: Created mol bd-abc123 from mol-feature
```
---
### 2. `bd wisp` Command
**Purpose:** Instantiate a proto as a wisp (vapor phase).
**Syntax:**
```bash
bd wisp <proto-id> [flags]
Flags:
--var strings Variable substitution (key=value)
--dry-run Preview what would be created
```
**Implementation:**
- Alias/wrapper for `bd mol spawn <proto-id>` (wisp is default)
- Creates wisp in `.beads-wisp/` storage
- Reserves digest ID in permanent storage (placeholder)
**Example:**
```bash
bd wisp mol-patrol
# Output: Created wisp bd-xyz789 from mol-patrol
```
---
### 3. `bd pin` Command
**Purpose:** Attach a mol to an agent's hook (work assignment).
**Syntax:**
```bash
bd pin <mol-id> [flags]
Flags:
--for string Agent to pin work for (default: current agent)
```
**Implementation:**
1. Look up the mol by ID
2. Set `pinned: true` on the mol's head bead
3. Set `assignee` to the target agent
4. Update `status` to `in_progress` if not already
**Example:**
```bash
# Pin to myself
bd pin bd-abc123
# Pin to specific agent (Witness assigning work)
bd pin bd-abc123 --for polecat-ace
```
**Unpin:**
```bash
bd unpin [mol-id]
# Clears pinned flag, optionally releases assignee
```
---
### 4. `bd hook` Command
**Purpose:** Inspect what's on an agent's hook.
**Syntax:**
```bash
bd hook [flags]
Flags:
--agent string Agent to inspect (default: current agent)
--json Output in JSON format
```
**Implementation:**
- Query beads for issues where `pinned: true` AND `assignee: <agent>`
- Display the mol(s) attached to the hook
**Example:**
```bash
bd hook
# Output:
# Hook: polecat-ace
# Pinned: bd-abc123 (mol-feature) - in_progress
# Step: implement (2 of 5)
bd hook --agent deacon
# Output:
# Hook: deacon
# (empty - patrol uses wisps, no persistent attachment)
```
---
### 5. Rename `--persistent` to `--pour`
**Current:**
```bash
bd mol spawn mol-feature --persistent
```
**New:**
```bash
bd mol spawn mol-feature --pour
# or simply:
bd pour mol-feature
```
**Migration:**
- Keep `--persistent` as deprecated alias
- Log warning when `--persistent` is used
- Remove in next major version
---
### 6. Add `--pour` flag to `bd mol bond`
**Purpose:** Override phase when spawning protos during bond.
**Current behavior:**
- Phase follows target (mol → liquid, wisp → vapor)
- `--wisp` forces vapor
**New:**
- Add `--pour` to force liquid even when target is vapor
```bash
# Found important bug during patrol, make it a real issue
bd mol bond mol-critical-bug wisp-patrol-123 --pour
```
---
### 7. Digest ID Reservation
**Problem:** When a wisp is created and later squashed, the digest should
have the same ID so cross-phase references remain valid.
**Solution:** Reserve the ID on wisp creation.
**Implementation:**
1. **On wisp creation (`bd wisp`):**
- Generate the head bead ID
- Write a placeholder to permanent beads:
```json
{
"id": "bd-xyz789",
"title": "[Wisp Placeholder]",
"status": "open",
"labels": ["wisp-placeholder"],
"description": "Reserved for wisp digest"
}
```
- Create actual wisp in `.beads-wisp/` with same ID
2. **On squash (`bd mol squash`):**
- Replace placeholder with actual digest content
- Delete wisp from `.beads-wisp/`
3. **On burn (`bd mol burn`):**
- Delete placeholder from permanent beads
- Delete wisp from `.beads-wisp/`
**Edge cases:**
- Crash before squash: Placeholder remains (orphan cleanup needed)
- Multiple wisps: Each has unique ID, no collision
---
### 8. Daemon Patrol Changes (Gas Town)
**Current behavior (`checkDeaconAttachment`):**
- Checks if Deacon has pinned mol
- If not, spawns `mol-deacon-patrol` and attaches permanently
- This is wrong for wisp-based patrol
**New behavior:**
- Remove `checkDeaconAttachment` entirely
- Deacon manages its own wisp lifecycle
- Daemon just ensures Deacon session is running and pokes it
**Code change in `daemon.go`:**
```go
// Remove this function entirely:
// func (d *Daemon) checkDeaconAttachment() error { ... }
// Or replace with a simpler check:
func (d *Daemon) ensureDeaconReady() error {
// Just verify session is running, don't attach anything
// Deacon self-spawns wisps for patrol
return nil
}
```
---
### 9. Deacon Template Update
**Current (`deacon.md.tmpl`):**
```markdown
If no molecule (naked), **start a new patrol**:
```bash
bd mol run mol-deacon-patrol
```
```
**New:**
```markdown
## Patrol Cycle (Wisp-Based)
Each patrol cycle uses wisps:
```bash
# 1. Spawn wisp for this cycle
bd wisp mol-deacon-patrol
# 2. Execute steps
bd close <step-1>
bd close <step-2>
# ...
# 3. Squash with summary
bd mol squash <wisp-id> --summary="Patrol complete: <findings>"
# 4. Loop
# Repeat from step 1
```
**Why wisps?**
- Patrol cycles are operational, not auditable work
- Each cycle is independent
- Only the digest matters (and only if notable)
- Keeps permanent beads clean
```
---
## Implementation Order
### Phase 1: Core Commands (P0)
1. [ ] Add `bd pour` command
2. [ ] Add `bd wisp` command
3. [ ] Rename `--persistent` to `--pour` (with deprecated alias)
4. [ ] Update daemon to remove `checkDeaconAttachment`
5. [ ] Update `deacon.md.tmpl` for wisp-based patrol
### Phase 2: Agent Attachment (P1)
1. [ ] Add `bd pin` command
2. [ ] Add `bd unpin` command
3. [ ] Add `--pour` flag to `bd mol bond`
4. [ ] Implement digest ID reservation for wisps
5. [ ] Update `witness.md.tmpl` for wisp-based patrol
### Phase 3: Inspection (P2)
1. [ ] Add `bd hook` command
2. [ ] Add `gt hook` command (thin wrapper)
---
## Testing Plan
### Manual Tests
```bash
# Test pour
bd pour mol-quick-fix
bd show <id> # Verify in permanent beads
# Test wisp
bd wisp mol-patrol
ls .beads-wisp/ # Verify wisp created
bd show <id> # Should work from permanent (placeholder)
# Test squash
bd mol squash <wisp-id> --summary="Test"
ls .beads-wisp/ # Wisp should be gone
bd show <id> # Digest should exist
# Test pin
bd pour mol-feature
bd pin <id>
bd hook # Should show pinned mol
```
### Integration Tests
- Deacon patrol cycle with wisps
- Cross-phase bonding (mol + wisp)
- Digest ID stability after squash
---
## Migration Notes
### Existing Code
- `bd mol spawn` defaults to wisp (vapor) now
- Code using `bd mol spawn` for permanent mols needs `--pour`
- `bd mol run` continues to work (creates mol, not wisp)
### Deprecation Path
| Old | New | Deprecation |
|-----|-----|-------------|
| `--persistent` | `--pour` | Warn in 0.x, remove in 1.0 |
| `bd mol spawn` (for mols) | `bd pour` | Keep both, prefer new |
---
*This document tracks the implementation of chemistry UX changes.*

View File

@@ -344,9 +344,9 @@ behavior.
| bond | Proto | Mol | Wisp |
|------|-------|-----|------|
| **Proto** | Compound Proto | Spawn Mol, attach | Spawn Wisp, attach |
| **Mol** | Spawn Mol, attach | Link via edges | Link via edges |
| **Wisp** | Spawn Wisp, attach | Link via edges | Link via edges |
| **Proto** | Compound Proto | Pour, attach | Wisp, attach |
| **Mol** | Pour, attach | Link via edges | Link via edges |
| **Wisp** | Wisp, attach | Link via edges | Link via edges |
The table is symmetric: bonding A+B produces the same structure as B+A.
@@ -363,7 +363,7 @@ bd mol bond mol-review mol-deploy --as "Review and Deploy"
Creates a compound proto that includes both workflows. The result is a
reusable template (solid phase).
### Bond: Proto + Mol → Spawn + Attach
### Bond: Proto + Mol → Pour + Attach
A solid template melts into an existing liquid workflow.
@@ -374,7 +374,7 @@ bd mol bond mol-hotfix bd-feature-123
The proto is instantiated (as liquid by default) and attached to the
existing mol. The new issues become part of the flowing work.
### Bond: Proto + Wisp → Spawn + Attach (Vapor)
### Bond: Proto + Wisp → Wisp + Attach
A solid template sublimates into an existing vapor workflow.
@@ -382,7 +382,7 @@ A solid template sublimates into an existing vapor workflow.
bd mol bond mol-extra-check wisp-patrol-456
```
The proto instantiates as vapor (following the wisp's phase) and attaches.
The proto is created as a wisp (following the target's phase) and attaches.
### Bond: Mol + Mol → Compound Mol
@@ -416,8 +416,8 @@ bd mol bond mol-temp-check bd-feature --wisp
| Flag | Effect | Use Case |
|------|--------|----------|
| `--pour` | Force create as liquid | "This matters, persist it" |
| `--wisp` | Force create as vapor | "This is ephemeral, let it evaporate" |
| `--pour` | Force creation as liquid | "This matters, persist it" |
| `--wisp` | Force creation as vapor | "This is ephemeral, let it evaporate" |
### Cross-Phase Bonding
@@ -480,7 +480,7 @@ Wisps are single-cycle and don't survive session boundaries in the
traditional sense. Agents hold them in working memory for one cycle:
```bash
# Deacon creates patrol (no pin needed)
# Deacon creates patrol wisp (no pin needed)
bd wisp mol-deacon-patrol # Create vapor
# ... execute steps ...
bd mol squash <id> --summary="..." # Condense and dissipate
@@ -908,8 +908,8 @@ Install alternatives from the Mol Mall:
### For Beads
1. **New commands**: `bd pour`, `bd wisp`, `bd pin`
2. **Flag changes**: `--persistent``--pour` (or phase follows operand)
1. **Commands**: `bd pour`, `bd wisp`, `bd pin`
2. **Flags**: `--pour` forces liquid phase when bonding
3. **Wisp storage**: `.beads-wisp/` directory, gitignored
4. **Digest ID reservation**: Placeholder in permanent store on wisp creation

View File

@@ -200,7 +200,7 @@ Work in Gas Town exists in three phases:
**"Is this the work, or is this wrapping the work?"**
| Spawn as Mol when... | Spawn as Wisp when... |
| Pour when... | Wisp when... |
|---------------------|----------------------|
| This IS the work item | This SHAPES execution |
| Multiple agents coordinate | Single agent executes |
@@ -539,8 +539,8 @@ Still declarative, still mechanical.
| Operands | Result |
|----------|--------|
| proto + proto | compound proto (frozen) |
| proto + mol | spawn proto as mol, attach |
| proto + wisp | spawn proto as wisp, attach |
| proto + mol | pour proto, attach |
| proto + wisp | wisp proto, attach |
| mol + mol | link via edges |
| wisp + wisp | link via edges |
| mol + wisp | reference link (cross-phase) |
@@ -548,8 +548,8 @@ Still declarative, still mechanical.
| aspect + molecule | advised molecule |
Phase override flags:
- `--pour`: Force spawn as mol
- `--wisp`: Force spawn as wisp
- `--pour`: Force creation as mol
- `--wisp`: Force creation as wisp
## Complete Example: Shiny-Enterprise

View File

@@ -67,12 +67,12 @@ The **sling** operation puts work on an agent's hook. Here's the full lifecycle:
│ gt sling lifecycle │
├─────────────────────────────────────────────────────────┤
│ │
│ 1. SPAWN (if proto) 2. ASSIGN 3. PIN │
│ 1. POUR (if proto) 2. ASSIGN 3. PIN │
│ proto → molecule mol → agent → hook │
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Proto │ ────────► │Molecule │ ─────► │ Hook │ │
│ │(catalog)│ spawn │(instance)│ assign │(pinned) │ │
│ │(catalog)│ pour │(instance)│ assign │(pinned) │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ │ │
│ agent wakes │

View File

@@ -52,7 +52,7 @@ gt sling gt-epic-123 refinery/
| Thing | Prefix | Example | Notes |
|-------|--------|---------|-------|
| Molecule proto | none | `gt sling feature polecat/alpha` | Spawns from proto |
| Molecule proto | none | `gt sling feature polecat/alpha` | Pours from proto |
| Issue/Bead | `gt-*`, `bd-*` | `gt sling gt-xyz polecat/alpha` | Work item |
| Epic | `gt-*` (type=epic) | `gt sling gt-epic refinery/` | Batch of issues |
| Wisp | `--wisp` flag | `gt sling patrol deacon/ --wisp` | Wisp (no audit trail) |
@@ -64,12 +64,12 @@ gt sling gt-epic-123 refinery/
│ gt sling lifecycle │
├─────────────────────────────────────────────────────────┤
│ │
│ 1. SPAWN (if proto) 2. ASSIGN 3. PIN │
│ 1. POUR (if proto) 2. ASSIGN 3. PIN │
│ proto → molecule mol → agent → hook │
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Proto │ ────────► │Molecule │ ─────► │ Hook │ │
│ │(catalog)│ spawn │(instance)│ assign │(pinned) │ │
│ │(catalog)│ pour │(instance)│ assign │(pinned) │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ │ │
│ agent wakes │
@@ -131,7 +131,7 @@ Flags:
--force Re-sling even if hook already has work
Examples:
gt sling feature polecat/alpha # Spawn feature mol, sling to alpha
gt sling feature polecat/alpha # Pour feature mol, sling to alpha
gt sling gt-xyz polecat/beta -m bugfix # Sling issue with bugfix workflow
gt sling patrol deacon/ --wisp # Patrol wisp
gt sling gt-epic-batch refinery/ # Batch work to refinery
@@ -172,7 +172,7 @@ Output:
| Command | gt mol | bd mol | Notes |
|---------|--------|--------|-------|
| Create molecule | via `gt sling` | `bd mol spawn` | gt adds assignment |
| Create molecule | via `gt sling` | `bd pour` | gt adds assignment |
| List protos | `gt mol catalog` | `bd mol catalog` | Same data |
| Show molecule | `gt mol status` | `bd mol show` | gt adds agent context |
| Combine | - | `bd mol bond` | Data operation only |
@@ -182,26 +182,6 @@ Output:
**Design principle**: `bd mol` is pure data operations. `gt sling` and `gt mol`
add agent context (assignment, hooks, sessions).
## Migration Path
### Old Commands → New
| Old | New | Notes |
|-----|-----|-------|
| `gt molecule instantiate` | `gt sling` | With assignment |
| `gt molecule attach` | `gt sling --force` | Re-sling to hook |
| `gt molecule detach` | `gt mol burn` | Or auto on complete |
| `gt molecule progress` | `gt mol status` | Better name |
| `gt molecule list` | `gt mol catalog` | Protos only |
| `gt spawn --molecule` | `gt sling` | Unified |
### Template Updates Required
1. **deacon.md.tmpl** - Use `gt mol status`, remove decision logic
2. **polecat.md.tmpl** - Propulsion principle, check hook on wake
3. **witness.md.tmpl** - Sling wisps to agents it spawns
4. **refinery.md.tmpl** - Accept slung epics
## Open Design Questions
1. **Default molecule**: If you `gt sling gt-xyz polecat/alpha` without `-m`,

View File

@@ -162,9 +162,9 @@ source formulas). Bond adapts to its operands:
| bond | Proto | Mol | Wisp |
|------|-------|-----|------|
| **Proto** | Compound Proto | Spawn + attach | Spawn wisp + attach |
| **Mol** | Spawn + attach | Link | Link |
| **Wisp** | Spawn + attach | Link | Link |
| **Proto** | Compound Proto | Pour + attach | Wisp + attach |
| **Mol** | Pour + attach | Link | Link |
| **Wisp** | Wisp + attach | Link | Link |
This enables patterns like:
- Patrol wisp discovers issue → bonds new work mol
@@ -240,7 +240,7 @@ Patrol agents run ephemeral wisps for their cycles:
- Wisp starts at cycle begin
- Steps complete as work progresses
- Wisp squashes to digest at cycle end
- New wisp spawns for next cycle
- New wisp created for next cycle
This prevents accumulation: patrol work is vapor that condenses to minimal
digests, not liquid that pools forever.