refactor: remove unused bd pin/unpin/hook commands (bd-x0zl)
Analysis found these commands are dead code: - gt never calls `bd pin` - uses `bd update --status=pinned` instead - Beads.Pin() wrapper exists but is never called - bd hook functionality duplicated by gt mol status - Code comment says "pinned field is cosmetic for bd hook visibility" Removed: - cmd/bd/pin.go - cmd/bd/unpin.go - cmd/bd/hook.go 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -275,7 +275,7 @@ open ──▶ in_progress ──▶ closed
|
||||
|
||||
```
|
||||
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
||||
│ bd wisp create │───▶│ Wisp Issues │───▶│ bd mol squash │
|
||||
│ bd mol wisp │───▶│ Wisp Issues │───▶│ bd mol squash │
|
||||
│ (from template) │ │ (local-only) │ │ (→ digest) │
|
||||
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
||||
```
|
||||
|
||||
+22
-22
@@ -349,15 +349,15 @@ Beads uses a chemistry metaphor for template-based workflows. See [MOLECULES.md]
|
||||
|
||||
| Phase | State | Storage | Command |
|
||||
|-------|-------|---------|---------|
|
||||
| Solid | Proto | `.beads/` | `bd mol catalog` |
|
||||
| Liquid | Mol | `.beads/` | `bd pour` |
|
||||
| Vapor | Wisp | `.beads/` (Wisp=true, not exported) | `bd wisp create` |
|
||||
| Solid | Proto | `.beads/` | `bd formula list` |
|
||||
| Liquid | Mol | `.beads/` | `bd mol pour` |
|
||||
| Vapor | Wisp | `.beads/` (Ephemeral=true, not exported) | `bd mol wisp` |
|
||||
|
||||
### Proto/Template Commands
|
||||
|
||||
```bash
|
||||
# List available protos (templates)
|
||||
bd mol catalog --json
|
||||
# List available formulas (templates)
|
||||
bd formula list --json
|
||||
|
||||
# Show proto structure and variables
|
||||
bd mol show <proto-id> --json
|
||||
@@ -370,32 +370,32 @@ bd mol distill <epic-id> --json
|
||||
|
||||
```bash
|
||||
# Instantiate proto as persistent mol (solid → liquid)
|
||||
bd pour <proto-id> --var key=value --json
|
||||
bd mol pour <proto-id> --var key=value --json
|
||||
|
||||
# Preview what would be created
|
||||
bd pour <proto-id> --var key=value --dry-run
|
||||
bd mol pour <proto-id> --var key=value --dry-run
|
||||
|
||||
# Assign root issue
|
||||
bd pour <proto-id> --var key=value --assignee alice --json
|
||||
bd mol pour <proto-id> --var key=value --assignee alice --json
|
||||
|
||||
# Attach additional protos during pour
|
||||
bd pour <proto-id> --attach <other-proto> --json
|
||||
bd mol pour <proto-id> --attach <other-proto> --json
|
||||
```
|
||||
|
||||
### Wisp Commands
|
||||
|
||||
```bash
|
||||
# Instantiate proto as ephemeral wisp (solid → vapor)
|
||||
bd wisp create <proto-id> --var key=value --json
|
||||
bd mol wisp <proto-id> --var key=value --json
|
||||
|
||||
# List all wisps
|
||||
bd wisp list --json
|
||||
bd wisp list --all --json # Include closed
|
||||
bd mol wisp list --json
|
||||
bd mol wisp list --all --json # Include closed
|
||||
|
||||
# Garbage collect orphaned wisps
|
||||
bd wisp gc --json
|
||||
bd wisp gc --age 24h --json # Custom age threshold
|
||||
bd wisp gc --dry-run # Preview what would be cleaned
|
||||
bd mol wisp gc --json
|
||||
bd mol wisp gc --age 24h --json # Custom age threshold
|
||||
bd mol wisp gc --dry-run # Preview what would be cleaned
|
||||
```
|
||||
|
||||
### Bonding (Combining Work)
|
||||
@@ -424,29 +424,29 @@ bd mol bond <A> <B> --dry-run
|
||||
|
||||
```bash
|
||||
# Compress wisp to permanent digest
|
||||
bd mol squash <wisp-id> --json
|
||||
bd mol squash <ephemeral-id> --json
|
||||
|
||||
# With agent-provided summary
|
||||
bd mol squash <wisp-id> --summary "Work completed" --json
|
||||
bd mol squash <ephemeral-id> --summary "Work completed" --json
|
||||
|
||||
# Preview
|
||||
bd mol squash <wisp-id> --dry-run
|
||||
bd mol squash <ephemeral-id> --dry-run
|
||||
|
||||
# Keep wisp children after squash
|
||||
bd mol squash <wisp-id> --keep-children --json
|
||||
bd mol squash <ephemeral-id> --keep-children --json
|
||||
```
|
||||
|
||||
### Burn (Discard Wisp)
|
||||
|
||||
```bash
|
||||
# Delete wisp without digest (destructive)
|
||||
bd mol burn <wisp-id> --json
|
||||
bd mol burn <ephemeral-id> --json
|
||||
|
||||
# Preview
|
||||
bd mol burn <wisp-id> --dry-run
|
||||
bd mol burn <ephemeral-id> --dry-run
|
||||
|
||||
# Skip confirmation
|
||||
bd mol burn <wisp-id> --force --json
|
||||
bd mol burn <ephemeral-id> --force --json
|
||||
```
|
||||
|
||||
**Note:** Most mol commands require `--no-daemon` flag when daemon is running.
|
||||
|
||||
+1
-1
@@ -202,7 +202,7 @@ The 1-hour grace period ensures tombstones propagate even with minor clock drift
|
||||
|
||||
## Wisps: Intentional Tombstone Bypass
|
||||
|
||||
**Wisps** (ephemeral issues created by `bd wisp create`) are intentionally excluded from tombstone tracking.
|
||||
**Wisps** (ephemeral issues created by `bd mol wisp`) are intentionally excluded from tombstone tracking.
|
||||
|
||||
### Why Wisps Don't Need Tombstones
|
||||
|
||||
|
||||
+14
-45
@@ -128,8 +128,8 @@ For reusable workflows, beads uses a chemistry metaphor:
|
||||
### Phase Commands
|
||||
|
||||
```bash
|
||||
bd pour <proto> # Proto → Mol (persistent instance)
|
||||
bd wisp create <proto> # Proto → Wisp (ephemeral instance)
|
||||
bd mol pour <proto> # Proto → Mol (persistent instance)
|
||||
bd mol wisp <proto> # Proto → Wisp (ephemeral instance)
|
||||
bd mol squash <id> # Mol/Wisp → Digest (permanent record)
|
||||
bd mol burn <id> # Wisp → nothing (discard)
|
||||
```
|
||||
@@ -227,10 +227,10 @@ bd close <id> --reason "Done"
|
||||
Wisps accumulate if not squashed/burned:
|
||||
|
||||
```bash
|
||||
bd wisp list # Check for orphans
|
||||
bd mol squash <id> # Create digest
|
||||
bd mol burn <id> # Or discard
|
||||
bd wisp gc # Garbage collect old wisps
|
||||
bd mol wisp list # Check for orphans
|
||||
bd mol squash <id> # Create digest
|
||||
bd mol burn <id> # Or discard
|
||||
bd mol wisp gc # Garbage collect old wisps
|
||||
```
|
||||
|
||||
## Layer Cake Architecture
|
||||
@@ -238,49 +238,18 @@ bd wisp gc # Garbage collect old wisps
|
||||
For reference, here's how the layers stack:
|
||||
|
||||
```
|
||||
Formulas (.formula.json) ← SOURCE: shareable workflow definitions
|
||||
↓ cook (ephemeral)
|
||||
[Protos] ← TRANSIENT: compiled templates (auto-deleted)
|
||||
↓ pour/wisp
|
||||
Molecules (bond, squash, burn) ← EXECUTION: workflow operations
|
||||
Formulas (JSON compile-time macros) ← optional, for complex composition
|
||||
↓
|
||||
Protos (template issues) ← optional, for reusable patterns
|
||||
↓
|
||||
Molecules (bond, squash, burn) ← workflow operations
|
||||
↓
|
||||
Epics (parent-child, dependencies) ← DATA PLANE (the core)
|
||||
↓
|
||||
Issues (JSONL, git-backed) ← STORAGE
|
||||
```
|
||||
|
||||
**Protos are ephemeral**: When you `bd pour formula-name` or `bd wisp create formula-name`, the formula is cooked into a temporary proto, used to spawn the mol/wisp, then automatically deleted. Protos are an implementation detail, not something users manage directly.
|
||||
|
||||
**Most users only need the bottom two layers.** Formulas are for sharing reusable patterns.
|
||||
|
||||
## Distillation: Extracting Patterns
|
||||
|
||||
The lifecycle is circular - you can extract formulas from completed work:
|
||||
|
||||
```
|
||||
Formulas ──cook──→ Mols/Wisps ──distill──→ Formulas
|
||||
```
|
||||
|
||||
**Use cases for distillation:**
|
||||
- **Emergent patterns**: Manually structured an epic that worked well
|
||||
- **Modified execution**: Poured a formula but added custom steps
|
||||
- **Learning from success**: Extract what made a complex mol succeed
|
||||
|
||||
```bash
|
||||
bd distill <mol-id> -o my-workflow.formula.json # Extract formula from mol
|
||||
```
|
||||
|
||||
## Sharing: The Mol Mall
|
||||
|
||||
All workflow sharing happens via formulas:
|
||||
|
||||
```bash
|
||||
bd mol publish my-workflow.formula.json # Share to GitHub repo
|
||||
bd mol install github.com/org/mol-code-review # Install from GitHub
|
||||
bd pour mol-code-review --var repo=myproject # Use installed formula
|
||||
```
|
||||
|
||||
Formulas are clean source code: composable, versioned, parameterized. Mols contain execution-specific context and aren't shared directly.
|
||||
**Most users only need the bottom two layers.** Protos and formulas are for reusable patterns and complex composition.
|
||||
|
||||
## Commands Quick Reference
|
||||
|
||||
@@ -303,8 +272,8 @@ bd dep tree <id> # Show dependency tree
|
||||
### Molecules
|
||||
|
||||
```bash
|
||||
bd pour <proto> --var k=v # Template → persistent mol
|
||||
bd wisp create <proto> # Template → ephemeral wisp
|
||||
bd mol pour <proto> --var k=v # Template → persistent mol
|
||||
bd mol wisp <proto> # Template → ephemeral wisp
|
||||
bd mol bond A B # Connect work graphs
|
||||
bd mol squash <id> # Compress to digest
|
||||
bd mol burn <id> # Discard without record
|
||||
|
||||
@@ -434,6 +434,91 @@ bd create "Add profile UI components" -t task -p 2
|
||||
# Clean merge back to main when ready
|
||||
```
|
||||
|
||||
## Fully Separate Beads Repository
|
||||
|
||||
For users who want complete separation between code history and issue tracking, beads supports storing issues in a completely separate git repository.
|
||||
|
||||
### Why Use a Separate Repo?
|
||||
|
||||
- **Clean code history** - No beads commits polluting your project's git log
|
||||
- **Shared across worktrees** - All worktrees can use the same BEADS_DIR
|
||||
- **Platform agnostic** - Works even if your main project isn't git-based
|
||||
- **Monorepo friendly** - Single beads repo for multiple projects
|
||||
|
||||
### Setup
|
||||
|
||||
```bash
|
||||
# 1. Create a dedicated beads repository (one-time)
|
||||
mkdir ~/my-project-beads
|
||||
cd ~/my-project-beads
|
||||
git init
|
||||
bd init --prefix myproj
|
||||
|
||||
# 2. Add a remote for cross-machine sync (optional)
|
||||
git remote add origin git@github.com:you/my-project-beads.git
|
||||
git push -u origin main
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
Set `BEADS_DIR` to point at your separate beads repository:
|
||||
|
||||
```bash
|
||||
cd ~/my-project
|
||||
export BEADS_DIR=~/my-project-beads/.beads
|
||||
|
||||
# All bd commands now use the separate repo
|
||||
bd create "My task" -t task
|
||||
bd list
|
||||
bd sync # commits to ~/my-project-beads, pushes there
|
||||
```
|
||||
|
||||
### Making It Permanent
|
||||
|
||||
**Option 1: Shell profile**
|
||||
```bash
|
||||
# Add to ~/.bashrc or ~/.zshrc
|
||||
export BEADS_DIR=~/my-project-beads/.beads
|
||||
```
|
||||
|
||||
**Option 2: direnv (per-project)**
|
||||
```bash
|
||||
# In ~/my-project/.envrc
|
||||
export BEADS_DIR=~/my-project-beads/.beads
|
||||
```
|
||||
|
||||
**Option 3: Wrapper script**
|
||||
```bash
|
||||
# ~/bin/bd-myproj
|
||||
#!/bin/bash
|
||||
BEADS_DIR=~/my-project-beads/.beads exec bd "$@"
|
||||
```
|
||||
|
||||
### How It Works
|
||||
|
||||
When `BEADS_DIR` points to a different git repository than your current directory:
|
||||
|
||||
1. `bd sync` detects "External BEADS_DIR"
|
||||
2. Git operations (add, commit, push, pull) target the beads repo
|
||||
3. Your code repository is never touched
|
||||
|
||||
This was contributed by @dand-oss in [PR #533](https://github.com/steveyegge/beads/pull/533).
|
||||
|
||||
### Combining with Worktrees
|
||||
|
||||
This approach elegantly solves the worktree isolation problem:
|
||||
|
||||
```bash
|
||||
# All worktrees share the same external beads repo
|
||||
export BEADS_DIR=~/project-beads/.beads
|
||||
|
||||
cd ~/project/main && bd list # Same issues
|
||||
cd ~/project/feature-1 && bd list # Same issues
|
||||
cd ~/project/feature-2 && bd list # Same issues
|
||||
```
|
||||
|
||||
No daemon conflicts, no branch confusion - all worktrees see the same issues because they all use the same external repository.
|
||||
|
||||
## See Also
|
||||
|
||||
- [GIT_INTEGRATION.md](GIT_INTEGRATION.md) - General git integration guide
|
||||
|
||||
@@ -0,0 +1,204 @@
|
||||
# PR #752 Chaos Testing Review
|
||||
|
||||
**PR**: https://github.com/steveyegge/beads/pull/752
|
||||
**Author**: jordanhubbard
|
||||
**Bead**: bd-kx1j
|
||||
**Status**: Under Review
|
||||
|
||||
## Summary
|
||||
|
||||
Jordan proposes adding chaos testing and E2E test coverage to beads. The PR:
|
||||
- Adds 4849 lines, removes 511 lines
|
||||
- Introduces chaos testing framework (random corruption, disk space exhaustion, NFS-like failures)
|
||||
- Creates side databases for testing recovery scenarios
|
||||
- Adds E2E tests tracking documented user scenarios
|
||||
- Brings code coverage to ~48%
|
||||
|
||||
## Key Question from Jordan
|
||||
|
||||
> "Is this level of testing something you actually want with the current pace of progress?
|
||||
> It comes with an implied obligation to update and add to the tests as well as follow
|
||||
> the CICD feedback in github (very spammy if your tests don't pass!)"
|
||||
|
||||
## Files Changed (Major Categories)
|
||||
|
||||
### Chaos/Doctor Infrastructure
|
||||
- `cmd/bd/doctor_repair_chaos_test.go` (378 lines) - Core chaos testing
|
||||
- `cmd/bd/doctor/fix/database_integrity.go` (116 lines) - DB integrity fixes
|
||||
- `cmd/bd/doctor/fix/jsonl_integrity.go` (87 lines) - JSONL integrity fixes
|
||||
- `cmd/bd/doctor/fix/fs.go` (57 lines) - Filesystem fault injection
|
||||
- `cmd/bd/doctor/fix/sqlite_open.go` (52 lines) - SQLite open handling
|
||||
- `cmd/bd/doctor/jsonl_integrity.go` (123 lines) - JSONL checks
|
||||
- `cmd/bd/doctor/git.go` (168 additions) - Git hygiene checks
|
||||
|
||||
### Test Coverage Additions
|
||||
- `internal/storage/memory/memory_more_coverage_test.go` (921 lines) - Memory storage tests
|
||||
- `cmd/bd/cli_coverage_show_test.go` (426 lines) - CLI show command tests
|
||||
- `cmd/bd/daemon_autostart_unit_test.go` (331 lines) - Daemon autostart tests
|
||||
- `internal/rpc/client_gate_shutdown_test.go` (107 lines) - RPC client tests
|
||||
- Various other test files
|
||||
|
||||
### Bug Fixes Discovered During Testing
|
||||
- `internal/storage/sqlite/migrations/021_migrate_edge_fields.go` - Major migration fix
|
||||
- `internal/storage/sqlite/migrations/022_drop_edge_columns.go` - Column cleanup
|
||||
- `internal/storage/sqlite/migrations_template_pinned_regression_test.go` - Regression test
|
||||
|
||||
## Tradeoffs
|
||||
|
||||
### Costs
|
||||
1. **Maintenance burden**: Must keep coverage above 48% (or whatever threshold is set)
|
||||
2. **CI noise**: Failed tests = spam until fixed
|
||||
3. **Velocity tax**: Every change needs test updates
|
||||
4. **Complexity**: Chaos testing framework itself needs maintenance
|
||||
|
||||
### Benefits
|
||||
1. **Robustness validation**: Proves beads can recover from corruption
|
||||
2. **Bug discovery**: Already found migration bugs (021, 022)
|
||||
3. **Confidence**: If chaos tests pass, beads is more robust than feared
|
||||
4. **Documentation**: E2E tests document expected user scenarios
|
||||
5. **Regression prevention**: Future changes caught before release
|
||||
|
||||
## Initial Assessment
|
||||
|
||||
**Implementation Quality: HIGH**
|
||||
|
||||
The chaos testing code is well-structured. Key observations:
|
||||
|
||||
### What the Chaos Tests Actually Cover
|
||||
|
||||
From `doctor_repair_chaos_test.go`:
|
||||
|
||||
1. **Complete DB corruption** - Writes "not a database" garbage, verifies recovery from JSONL
|
||||
2. **Truncated DB without JSONL** - Tests graceful failure when no recovery source exists
|
||||
3. **Sidecar file backup** - Ensures -wal, -shm, -journal files are preserved during repair
|
||||
4. **Repair with running daemon** - Tests recovery while daemon holds locks
|
||||
5. **JSONL integrity** - Malformed lines, re-export from DB
|
||||
|
||||
Each test:
|
||||
- Uses isolated temp directories
|
||||
- Builds a fresh `bd` binary for testing
|
||||
- Uses "side databases" (separate from real data)
|
||||
- Has proper cleanup
|
||||
|
||||
### Bug Fixes Already Discovered
|
||||
|
||||
The PR includes fixes for bugs found during testing:
|
||||
- Migration 021/022: `pinned` and `is_template` columns were being clobbered
|
||||
- Regression test added to prevent recurrence
|
||||
|
||||
### Test Coverage Structure
|
||||
|
||||
Tests are organized by build tags:
|
||||
- `//go:build chaos` - Chaos/corruption tests (run separately)
|
||||
- `//go:build e2e` - End-to-end CLI tests
|
||||
- Regular unit tests - No build tag required
|
||||
|
||||
This means chaos tests only run when explicitly requested, not on every `go test`.
|
||||
|
||||
---
|
||||
|
||||
## Deep Analysis (Ultrathink)
|
||||
|
||||
### The Core Question
|
||||
|
||||
Is the testing worth the ongoing maintenance cost?
|
||||
|
||||
### Argument FOR Merging
|
||||
|
||||
1. **Beads is more robust than feared**. If Jordan got these tests passing, it means:
|
||||
- `bd doctor` actually recovers from corruption
|
||||
- JSONL/DB sync is working correctly
|
||||
- Migration edge cases are handled
|
||||
|
||||
This validates the core design: SQLite + JSONL + git backstop.
|
||||
|
||||
2. **Bugs already found**. The migration 021/022 bugs are exactly the kind of subtle
|
||||
issues that would cause data loss in production. Finding them now is worth something.
|
||||
|
||||
3. **Build tag isolation**. Chaos tests won't slow down regular development:
|
||||
```bash
|
||||
go test ./... # Normal tests only
|
||||
go test -tags=chaos ./... # Include chaos tests
|
||||
go test -tags=e2e ./... # Include E2E tests
|
||||
```
|
||||
|
||||
4. **48% coverage is a floor, not a target**. The PR doesn't enforce maintaining 48%.
|
||||
Jordan is asking: "Is this level worth it?" We can always add more later, or let
|
||||
coverage drift if priorities change.
|
||||
|
||||
5. **Documentation value**. E2E tests document expected user scenarios. When an AI agent
|
||||
asks "what should happen when X?", the tests provide executable answers.
|
||||
|
||||
### Argument AGAINST Merging
|
||||
|
||||
1. **Velocity tax is real**. Every behavior change needs test updates. This is especially
|
||||
painful during rapid iteration phases.
|
||||
|
||||
2. **CI noise**. Failed tests block merges. With multiple agents working, flaky tests
|
||||
become coordination bottlenecks.
|
||||
|
||||
3. **Framework maintenance**. The chaos testing framework itself (side databases, build
|
||||
tags, test helpers) becomes another thing to maintain.
|
||||
|
||||
4. **False confidence**. Tests passing doesn't mean beads is production-ready. It means
|
||||
tested scenarios work. Edge cases not covered still fail silently.
|
||||
|
||||
### The Real Question: What Phase Are We In?
|
||||
|
||||
**If beads is still in "rapid prototype" phase**: The testing overhead is premature.
|
||||
Focus on features, fix crashes as they happen, lean on git backstop.
|
||||
|
||||
**If beads is approaching "reliable tool" phase**: Testing is essential. Multi-agent
|
||||
workflows amplify bugs. Corruption during a 10-agent batch is expensive.
|
||||
|
||||
**Current reality**: Beads is being dogfooded seriously. Multiple agents, real work,
|
||||
real data loss when things break. We're closer to "reliable tool" than "prototype."
|
||||
|
||||
### ROI Calculation
|
||||
|
||||
**Cost of NOT testing**: When corruption happens:
|
||||
- Agent loses context (30-60 min recovery)
|
||||
- Human has to debug (variable, often 15-60 min)
|
||||
- Trust erosion (hard to quantify)
|
||||
|
||||
**Cost of testing**:
|
||||
- Review this PR (1-2 hours, one time)
|
||||
- Update tests when behavior changes (5-15 min per change)
|
||||
- Fix flaky tests when they appear (variable)
|
||||
|
||||
If corruption happens once a month, testing ROI is marginal.
|
||||
If corruption happens weekly (or with each new feature), testing pays for itself.
|
||||
|
||||
---
|
||||
|
||||
## Recommendation
|
||||
|
||||
**MERGE WITH MODIFICATIONS**
|
||||
|
||||
### Why Merge
|
||||
|
||||
1. The implementation quality is high
|
||||
2. Bugs already found justify the effort
|
||||
3. Build tag isolation minimizes velocity impact
|
||||
4. Beads is past the prototype phase
|
||||
|
||||
### Suggested Modifications
|
||||
|
||||
1. **No hard coverage threshold in CI**. Let coverage drift naturally. The value is in
|
||||
the chaos tests catching corruption, not in hitting a percentage.
|
||||
|
||||
2. **Chaos tests optional in CI**. Run chaos tests on release branches, not every PR.
|
||||
This reduces CI noise during active development.
|
||||
|
||||
3. **Clear ownership**. Jordan should document how to add new chaos scenarios. Future
|
||||
contributors need to know when to add vs skip tests.
|
||||
|
||||
### Decision Framework for User
|
||||
|
||||
If you answer YES to 2+ of these, merge:
|
||||
- [ ] Are you dogfooding beads for real work?
|
||||
- [ ] Has corruption caused you to lose time in the last month?
|
||||
- [ ] Do you expect multiple agents using beads concurrently?
|
||||
- [ ] Is beads approaching a "v1.0" milestone?
|
||||
|
||||
If you answer NO to all, defer the PR until beads stabilizes.
|
||||
Reference in New Issue
Block a user