yf-beads-hygiene
Safe, read-only-first audit and gated repair of a beads (`bd`) dependency graph: finds orphaned beads and dangling depen
Safe, read-only-first audit and gated repair of a beads (`bd`) dependency graph: finds orphaned beads and dangling dependency edges, and correctly classifies gate-typed edges so live gates are never mistaken for dangling. The canonical trigger for any "clean up beads" request.
At a glance
- Category:
beads - Invocation:
/yf-beads-hygiene(user-invocable) - Requires tools:
bd,uv,git - Depends on skills:
yf-beads-extra,yf-beads-init - Source:
SKILL.md·README.md
When it fires
/yf-beads-hygiene invoked; "clean up" / "cleanup" open or orphaned beads; "are there orphaned/dangling beads"; "audit the beads graph"; or a dependency-edge removal is being considered.
When to skip it
verifying/repairing beads CONFIG or DB health — a wedged/corrupted DB or uninitialized repo routes to `yf-beads-init` (this skill operates on the graph CONTENT of an already-healthy DB); routine `bd ready`/`bd show`/`bd close` (the `beads` skill); direct-CLI gotchas (`yf-beads-extra`); authoring beads-backed skills (`yf-beads-authoring`).
Prerequisites
| Tool | Version | Purpose |
|---|---|---|
bd |
>= 1.1.0 | the beads CLI being audited/repaired |
uv |
any | runs the beads_hygiene.py engine (PEP 723) |
git |
any | repo-root resolution |
Mirrors SKILL.md frontmatter depends-on-tool: [bd, uv, git]. Depends on yf-beads-extra
(direct-CLI gotchas) and yf-beads-init (DB-health routing).
Usage
/yf-beads-hygiene
Or invoke the engine directly:
uv run scripts/beads_hygiene.py audit # read-only four-class edge report
uv run scripts/beads_hygiene.py audit --json # machine-readable
uv run scripts/beads_hygiene.py reconcile # read-only: hoist candidates + obsolete upstream
uv run scripts/beads_hygiene.py reconcile --apply --record hoist.json # delegate hoists (prompts)
uv run scripts/beads_hygiene.py repair # dry run: list truly-dangling proposals
uv run scripts/beads_hygiene.py repair --apply --record removed.json # mutate (prompts)
uv run scripts/beads_hygiene.py restore --record removed.json --apply # round-trip undo
audit classifies every dependency edge into true-orphan / truly-dangling /
satisfied-gate / live-gate. Only truly-dangling is ever proposed for removal; live-gate
edges are always preserved.
reconcile works the other axis: it computes the active set (in_progress, OR claimed-open,
OR an open parent-chain ancestor of an active bead) and lists every other non-closed bead as a
hoist candidate, plus flags upstream issues as obsolete only on a mechanical delivered
signal (linked plan Status: complete or a merged PR) — otherwise flag-for-review, never
auto-closed. Per the carve, hygiene proposes and yf-beads-upstream executes: reconcile
--apply delegates each hoist to yf-beads-upstream (reversible bd close tombstone) and never
pushes or closes beads itself.
On a wedged/corrupted DB both audit and reconcile exit with status db_wedged and route you
to yf-beads-init (do not clean a broken store).
Tests
cd scripts && uv run --with pytest python3 -m pytest test_beads_hygiene.py -q
The classifier core is pure, so the tests reproduce the #29 11-live-gate false positive without a live DB.
Layout
skills/yf-beads-hygiene/
├── SKILL.md # trigger contract, audit/repair/restore procedure
├── SPEC.md # REQ-HYG-* requirements
├── README.md # this file
└── scripts/
├── beads_hygiene.py # PEP 723 engine: audit / reconcile / repair / restore
└── test_beads_hygiene.py # four-class + #29 regression + reconcile active-set tests