Skip to content

v0.13.1

Choose a tag to compare

@kvnwolf kvnwolf released this 17 Aug 02:54
· 9 commits to main since this release

🧹 The trim sweep can actually finish now

/dobby:trim-context had a humiliating secret: point it at a real repository and it would never finish. A field run against a 948-file codebase reached 1.2% coverage and could not write a single line of its ledger. Not slowly β€” never. Three rules in the sweep contract guaranteed it, and this release replaces all three with what actually worked when the same repository was swept by hand: βˆ’263,238 bytes across 165 files, gate green, zero executable lines touched.

πŸ“Š Judgment, not inventory

The old contract demanded one inventory row per eligible unit. On that repo, that meant 24,113 rows β€” the entire budget spent writing a table before a single judgment call happened.

Now the inventory is one row per file, ranked by comment-byte weight, and per-unit decisions happen inside the lot that touches the file. The Tree-sitter extractor stays exactly where it was (it was never the bottleneck β€” it ran once, cheaply, in seconds), but it is now the targeting input that ranks files into lots rather than the source of an exhaustive census.

βœ… Approve once, then walk away

The old contract wanted every batch approved before any worker wrote a byte. At repository scale that gate can never clear β€” you'd be clicking approvals until the heat death of the universe.

Now you approve scope and aggressiveness once, up front: which tracks run, how aggressive, what's off-limits. Lots then run unattended. The sweep comes back to you only when the policy needs to change, or something blocks. Go make coffee.

πŸ’Ύ Progress that survives

The worst of the three: a single parse-error voided the entire sweep. 43 unparseable .sql migrations permanently vetoed coverage genuinely earned on ~900 other files, and every rerun started from zero.

Coverage is now incremental and checkpointed per lot. A file that couldn't be resolved simply carries no sub-key β€” which already meant "not covered", so there's no schema change β€” and the savings report names it with its reason. An interruption, a blocked lot, an unparseable migration: each costs only itself. Everything already verified stays verified.

The honesty invariant is untouched, and it's the whole point: the ledger never claims coverage it doesn't have. What changed is that missing coverage no longer erases real coverage.

πŸ”’ Nothing gets certified without being validated

Four rounds of adversarial review chased one invariant through this design, and each round found it hiding a level deeper. All four were real:

  • Comment lots could skip semantic review whenever the mechanical diff came back clean β€” but deleting a biome-ignore, a licence header or a security warning changes no executable line either. The exemption is gone: every lot gets the cheap mechanical proof and an independent semantic review.
  • The checkpoint writer mutated the canonical ledger before validation. Now it stages to .dobby/sweeps.json.pending, the reviewer validates that staging file alone, and only the coordinator promotes it.
  • /dobby:anti-slop shares that same ledger file β€” so it got the same staged-then-promoted ordering. Nothing else about it changed.
  • Nothing bound a checkpoint to the lot that just passed, so a stale staging file could be promoted as someone else's coverage. The reviewer now verifies the increment's paths match the lot's file set exactly.

🎯 The recipe that worked, encoded

Lots of 6-8 files by weight (a 47-file lot exhausted one implementor at 13 files, 430K tokens, 257 tool calls). One track per brief β€” comment-trim or prose densification, never both, after a mixed brief produced a proud βˆ’186 bytes. Levers carried forward between lots, worth a steady ~βˆ’12% once discovered. And every brief now states its expected yield (~5% on comments, 12-14% on prose) with "leaving a file untouched is a correct outcome" said out loud, because an agent measured on bytes removed will find bytes to remove.

⚠️ One thing to know

rulesVersion moves from human-text-v1 to human-text-v2 β€” the preservation rules genuinely changed. If you somehow have an existing sweep ledger, its entries no longer certify, and the next run re-sweeps from scratch. In practice nobody does: writing a ledger is precisely what the old contract could never manage. πŸ™ƒ

πŸ“¦ Upgrading

bun update @kvnwolf/dobby

The CLI itself has no changes this release β€” everything above lives in the plugin, which autoUpdate carries to you from the marketplace. Bump the devDependency to keep the two surfaces in step.

Worth saying plainly: this is methodology, validated by 1,676 tests and four review rounds, but nobody has yet run the new sweep against a large repository end to end. That's the real test. If you point it at something big, the interesting question is whether it now reaches ledger finality β€” and the savings report will tell you exactly what it couldn't cover.