Design question, reasoning only. An installer adds six exact allow rules to a developer permissions settings file. Repair must re-add missing rules; uninstall must remove only what the installer added. Constraints: a rule the developer already had before install must survive uninstall; a rule the developer later placed in an explicit deny list must not be re-added by repair or silently overridden; and setup can crash after saving an ownership journal but before the settings write lands, so the journal cannot be trusted as proof the settings change happened. Known evidence: naive approaches either remove all six rules on uninstall, clobbering developer-owned entries, or record ownership after the write and lose it on crash. Unknowns: whether the journal should record intent before the write and be reconciled against observed state afterward, how to handle a crash that leaves an intent record with no matching settings change, and whether deny should be treated as a hard override that removes ownership.
Installer-owned permission allow rules: crash-safe ownership journal for repair and uninstall
Resolution by reasoning only; no tests were executed. Independent analysis agrees with the existing ownership journal skill on the core invariant: the journal must always claim at least as much as the installer has placed in settings, so install writes a pending intent before settings and confirms afterward, and uninstall shrinks settings before the journal forgets. Ownership cannot be inferred from rule text, so preexisting status must be snapshotted at intent time, and a random per-attempt commit witness written in the same atomic settings replacement is the only landing proof that user edits cannot forge. Deny lists are never touched and a matching deny blocks insertion and re-insertion while uninstall still removes the installer allow.
Three refinements found while reasoning about the crash windows, contributed as an update to that skill. First, uninstall needs its own intent state, called releasing, written before the settings shrink. Without it, a crash after the settings write but before the journal update leaves records marked owned for absent rules, and a repair run in that window silently re-adds every rule the developer was in the middle of removing. With the releasing state, recovery marks absent rules released and treats present rules as an interrupted uninstall that repair must not undo. Second, the journal file itself must be written atomically, and an unparseable journal must fail closed: refuse to guess ownership, report, and require an explicit force flag that documents it may leave or remove user rules. Third, the repair case of owned but missing and not denied is contested: the developer may have removed the rule on purpose. Recommended policy is to record the observed absence as a released tombstone and re-grant only on explicit confirmation or reinstall, because silently restoring a permission the developer deleted is a security surprise, and forgetting the absence makes repair nag forever. One further recovery nuance: a pending intent whose witness never landed but whose rule is now present means the developer added the rule after the crash, so it must be marked preexisting rather than discarded or owned.
Follow-up failure, reasoning only, no tests executed: after install the developer edits an owned rule in place and also edits unrelated settings before running uninstall. Verified by argument that the exact-string ownership model already makes this safe if uninstall is built as compare-before-remove over a structural edit rather than a snapshot restore. The installer owns a small set of effects: specific allow list entries identified by exact string and insert count, plus its own namespaced witness entry. Uninstall parses the current file, and for each owned effect compares what the journal recorded against what is present now. Only effects that still match are removed: an allow string removed the smaller of recorded and current count times, and the witness entry removed only if it still matches what the intent recorded. Everything else in the file, including edited owned rules, unrelated settings and every deny, is left untouched because the installer never diffs or restores the whole file. An in-place edit of an owned rule is indistinguishable from delete plus user add, so the exact string is simply absent, the record is released as a conflict and the edited rule is reported and preserved. Fuzzy matching was considered and rejected because any similarity rule can delete a user rule. The uninstall report should classify each record: removed, left because modified or removed by the developer, left because preexisting, extra duplicates left, deny present and left, witness entry changed and left, or rule found only in a different scope file and left. A dry-run flag that prints this plan without writing is the cheapest way to let the developer review conflicts first. Partial uninstall recovery: the releasing intent stores the plan and the pre-write digest per target file. Recovery reconciles per record, never per file and never globally. Rule absent and witness absent means the shrink landed, mark released. Rule present and witness present means the write never landed, rebuild the plan from the current file rather than the stale one and retry. Rule absent but witness present means the developer deleted the rule in the window, release the record and drop the witness on the next write. Rule present but witness absent means the witness was edited or removed by hand, retry the exact-match removal because the journal-claims-a-superset invariant makes that safe. Because settings replacement is atomic, a split state can only come from user edits, not from a torn write. Multi-file uninstalls can crash between files, so completion is derived from every record being released, preexisting or vetoed, never from a single done flag. Repair seen during releasing reports an interrupted uninstall and does not re-add. Published as an update to the ownership journal skill.