You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Reverted from v3.4.21 before shipping. The v3.4.21 cold recovery review found the ledger could silently delete live scheduled jobs; the approach needs a different foundation, not patches.
Why the bookkeeping approach failed
The ledger recorded which labels a vault installed, and removed any that disappeared from the config. Two problems are structural, not bugs:
Labels are global; the ledger is per-vault.label_for_entry takes no vault input — it is a pure function of command basename + args (or skill name). Two vaults with the same entry produce the same label and the same artifact path. Vault A's routine register therefore deleted vault B's live job, printing "no longer in onebrain.yml" — true of A, false of B. Nothing in vault B ever mentioned it.
The guard test was vacuous.sweep_never_touches_an_artifact_this_vault_did_not_install planted a label the ledger never contained, and the sweep only iterates the ledger — so it could not fail regardless of the bug.
Also found, and worth carrying into any redesign:
deleting the whole schedule: block early-returns before the sweep, so the most common form of "entry deleted" left every job installed
--remove --dry-run deletes for real (remove is handled before dry_run is consulted, and the flags have no conflicts_with)
run_embedded hardcodes quiet = true, so onebrain plugin update could delete artifacts and print nothing
the ledger was unvalidated: any line reaching it was passed to backend::remove, so one line written into a vault file could delete any com.onebrain.* job on the machine
Decide ownership, then delete. Before removing anything, confirm the installed artifact actually belongs to this vault — its program args / working directory already carry the vault path. That subsumes the ledger's job and fixes the cross-vault case, because it stops trusting a name and starts checking the artifact.
Store any state that remains outside the vault (alongside the scheduler logs, per #315), keyed per machine.
The bug this was meant to fix is still open
Editing a schedule entry's args leaves the old artifact installed and firing, unreachable by --remove. Verified present in shipped v3.4.20 by building the tag and reproducing it, so this is long-standing, not a regression. v3.4.21 ships the label-collision fix (#345) without the sweep.
Reverted from v3.4.21 before shipping. The v3.4.21 cold recovery review found the ledger could silently delete live scheduled jobs; the approach needs a different foundation, not patches.
Why the bookkeeping approach failed
The ledger recorded which labels a vault installed, and removed any that disappeared from the config. Two problems are structural, not bugs:
label_for_entrytakes no vault input — it is a pure function of command basename + args (or skill name). Two vaults with the same entry produce the same label and the same artifact path. Vault A's routineregistertherefore deleted vault B's live job, printing "no longer in onebrain.yml" — true of A, false of B. Nothing in vault B ever mentioned it.sweep_never_touches_an_artifact_this_vault_did_not_installplanted a label the ledger never contained, and the sweep only iterates the ledger — so it could not fail regardless of the bug.Also found, and worth carrying into any redesign:
schedule:block early-returns before the sweep, so the most common form of "entry deleted" left every job installed--remove --dry-rundeletes for real (removeis handled beforedry_runis consulted, and the flags have noconflicts_with)run_embeddedhardcodesquiet = true, soonebrain plugin updatecould delete artifacts and print nothingbackend::remove, so one line written into a vault file could delete anycom.onebrain.*job on the machineDirection
Decide ownership, then delete. Before removing anything, confirm the installed artifact actually belongs to this vault — its program args / working directory already carry the vault path. That subsumes the ledger's job and fixes the cross-vault case, because it stops trusting a name and starts checking the artifact.
Store any state that remains outside the vault (alongside the scheduler logs, per #315), keyed per machine.
The bug this was meant to fix is still open
Editing a schedule entry's args leaves the old artifact installed and firing, unreachable by
--remove. Verified present in shipped v3.4.20 by building the tag and reproducing it, so this is long-standing, not a regression. v3.4.21 ships the label-collision fix (#345) without the sweep.