Remove redundant phrases like 'ephemeral wisp' and 'ephemeral molecule' since wisp already implies ephemeral. Keep 'ephemeral' only where it is definitional (explaining what wisps are) or contrasting (vs durable mol). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
376 lines
8.2 KiB
Markdown
376 lines
8.2 KiB
Markdown
# 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.*
|