Design problem. A CLI installer inserts six exact tool allow rules into a developer settings file that also contains user-authored allow rules and explicit deny rules. Repair must restore missing installer rules without touching user rules, and uninstall must remove only the rules the installer added, leaving an allow the user had already written for the same string, and never adding or removing a deny. The settings write and a separate ownership journal write cannot be made atomic together, so setup can crash after the journal is saved but before settings are updated, or the reverse. Known evidence: per-rule ownership must be recorded at insertion time, since a rule string alone cannot show who added it. Unknowns: the best journal state model for the crash window, whether intent-before-write or write-before-record is safer, how to reconcile when the journal and settings disagree, and how to treat a deny the user added later for a string the installer also allows. Reasoning only; no tests executed.
Crash-safe ownership journal for installer-managed tool allow rules in shared developer settings
Resolution by reasoning; no tests executed. Core invariant: the ownership journal must always claim at least as much as the installer has placed in settings. Install therefore writes the journal first as a pending intent and confirms it after the settings write. Uninstall does the reverse: settings shrink first and the journal record is released last. Failure asymmetry justifies the order: a stale pending intent is harmless noise, while an installer-added allow with no journal record becomes an orphaned permission that uninstall can never safely remove. Per rule journal record states: pending, owned, preexisting, vetoed, released. At intent time the installer snapshots for each of the six strings whether an exact allow already existed, and whether an exact or matching deny existed. Preexisting allows are never removed. A matching deny vetoes insertion, and a deny is never added, removed or rewritten by the installer. Crash recovery runs at the start of every command: for each pending record, check a commit witness. Preferred witness is a random token written in the same atomic settings replacement inside an installer-namespaced metadata key; token present promotes pending to owned, token absent discards the intent. Where extra keys are not allowed, fall back to the pre-write file digest captured in the intent, treating a changed digest with the rule present as landed and an unchanged digest as not landed; any other combination is reported rather than guessed. Repair re-adds only owned rules that are missing and still not denied, and treats a missing preexisting rule as not its business. Uninstall removes one instance of each owned rule if present, then marks released, then deletes the journal when every record is released. Duplicates: remove the smaller of the recorded and current counts. Multiple settings scopes need journal keys by target, and a lock around the read-modify-write pair. Related community threads proposed the same commit witness idea; that agrees with this analysis but was not independently verified here.