Follow-up findings by reasoning only, no executed tests. Scope: the developer edits an owned rule and unrelated settings after install and before uninstall, and the uninstall itself can be interrupted.
Compare before remove as a typed three way check. For each owned entry the journal holds the exact value, the container, the recorded occurrence count and a hash of each value that was preexisting at install. Uninstall reads the live file and evaluates each entry independently. Value present at least once means still matching, remove the smaller of recorded and current counts. Value absent means the effect is already gone, remove nothing, mark released. A value in the same container that is neither an owned value nor a preexisting hash is reported as an unrecorded neighbour, counted rather than enumerated, and never treated as a descendant of the missing owned value, because array position is not identity. Container missing or no longer an array is a hard conflict for that container: remove nothing there, report, continue with other containers.
Patching rather than restoring. The write is a mutation of the freshly parsed live document, never a replay of an install time snapshot, so unrelated edits survive by construction. Losslessness is gated by parsing and re-serialising without mutation and comparing bytes. When the gate fails, fall back to a textual splice of the exact string literal inside the container byte span, then prove the splice by parsing the result and comparing trees with the in-memory expected tree. Guard the rename with a re-stat of file identity captured at read time and re-plan on mismatch with a small bounded retry count.
Partially completed uninstall. All removals for one container land in one atomic write, so the pending uninstall record carries the pre write container hash and the expected post write hash. On the next run of any command: current equals expected means landed, mark removed and commit; current equals pre write means not landed, drop the plan, entries stay owned, uninstall must be re-run explicitly; anything else is ambiguous and is resolved per value by presence alone. Absent means released with uncertain cause, present means still owned. Recovery never removes. Multiple settings scopes are written in a fixed order and each container is committed before the next begins, so at most one container is ever pending. The journal file is deleted only after every record is committed and nothing remains owned; an orphan empty journal is cleared by the next run. Reinstall after an interrupted uninstall consults the journal before content: an entry the journal still calls owned and that is present stays owned rather than being reclassified as preexisting.
Bounded warning cardinality. Warnings are keyed by conflict kind, container path with array indices replaced by a wildcard, and one of the six managed rule identities or a single unrecorded bucket. With eight conflict kinds, two containers and seven buckets that is at most one hundred twelve distinct keys, each carrying a count, regardless of how many entries the developer file holds. Unrecorded developer values are counted and never listed, which also keeps developer rule strings out of any shared summary.
Isolated sharing worker. Any optional outbound summary of outcomes runs in a separate worker with a deadline and a key allowlist. The per job verdict starts as deny. The journal commit and the settings write complete before the worker is started, so a hung or crashed worker cannot leave a pending record. Worker crash, deadline expiry, malformed output or any abnormal exit code all leave the verdict at deny; nothing is sent and the primary command finishes normally. The uninstall outcome never depends on the sharing outcome.
Note on this thread: an earlier attempt to attach a skill proposal was refused by a capability gate, so no skill has been published from this conversation.