Installer ownership journal with file locking and content verification for safe uninstall
# Installer ownership journal with file locking and content verification for safe uninstall
## Problem
A CLI installer adds a fixed small set of exact entries to a settings file that a person also edits by hand. Repair and uninstall must touch only installer-added entries, never pre-existing or user-added entries, respecting explicit denies. Process can crash at any point. Concurrent user edits must not cause lost updates or incorrect removals.
## Failures prevented
**Race from missing lock**: User opens settings during install. Installer reads, computes changes, writes. User saves unrelated edit, overwriting installer changes. Recovery finds marker missing, enters undefined state.
**Non-atomic metadata write**: Installer writes settings successfully, crashes before writing completion marker. Recovery cannot distinguish write failed from write succeeded then marker deleted.
**Blind removal during uninstall**: User modifies installer-owned rule before uninstall. Uninstall removes by pattern without verifying content, destroying modification.
**Partial operation without progress**: Uninstall processes three of six rules, crashes. Resume has no record of completed rules. Reprocessing or skipping both incorrect.
**System metadata in fingerprint**: Settings system adds timestamps. Fingerprint at install never matches at uninstall for unchanged rules, preventing clean uninstall.
**Duplicate install**: Running installer twice creates duplicate ownership claims.
## Core invariants
1. Ownership decided once at install by observation, recorded, never re-derived
2. Deny overrides allow at every step, installer never touches denies
3. All operations hold advisory file lock during read-modify-write
4. Atomicity through single-write: compute changes, write once atomically
5. Content fingerprint verification: remove only if current matches recorded
6. Incremental progress: record each outcome before next step
## Journal structure
In installer state directory:
```
operation_id: unique identifier
timestamp: when operation ran
status: pending | confirmed | removing | removed
per_rule:
pattern: exact rule text
action: allow or deny
fingerprint: digest of immutable fields only
ownership: installer_added | pre_existing
observed_state: was_absent | was_present | deny_blocked
result: planned | completed | conflict | skipped
completion_marker:
value: large random identifier
storage: metadata_field or separate_file
file_state:
before_digest: full file before changes
after_digest: expected file after changes
```
Fingerprint only immutable fields (pattern, action), exclude system timestamps and IDs.
## Install with locking
1. Acquire advisory lock
2. Read settings, compute digest
3. Classify each target:
- Explicit deny present: ownership none, state deny_blocked
- Already present: ownership pre_existing, state was_present
- Absent: ownership installer_added, state was_absent
4. Generate random completion marker
5. Write journal status pending with rules and marker, sync
6. Prepare new settings with installer_added rules and completion marker in metadata
7. Atomic write via temp and rename, sync
8. Update journal status confirmed, sync
9. Release lock
Recovery for pending operations:
```
acquire lock
current_marker = read from settings
if matches journal marker:
mark confirmed (write succeeded)
else:
add missing installer_added rules
write marker
mark confirmed
release lock
```
## Uninstall with compare-before-remove
1. Acquire lock
2. Read settings, load journal
3. Create removal log status removing
4. For each installer_added rule:
- Locate in current settings
- If absent: log already_gone, continue
- Compute current fingerprint
- If matches journal: remove, log removed_match
- If differs: preserve, log user_modified with difference
- Write log entry, sync
5. Atomic write settings
6. Mark journal removed or partial if conflicts
7. Release lock
Recovery for removing operations:
```
acquire lock
completed = get from removal log
for each installer_added:
if in completed: skip
else: resume from locate step
release lock
```
## Conflict reporting
Report preserved rules: pattern, installed version, current version, reason preserved. Optional force mode overrides but logs forced actions.
## Duplicate prevention
Before journal creation, search existing journals for same rules. If found and confirmed, error already installed. If pending, resume that operation.
## Requirements
Do not: write settings then separately write marker (non-atomic); read without lock (race); remove without fingerprint check (destroys edits); use full file digest for detection (format changes break); include system metadata in fingerprint (false mismatches).
Required: lock before read-modify-write; prepare then write once; marker in atomic operation or readable separate file; fingerprint immutable fields only; record incremental progress.
## Applicability
For file-based configuration with concurrent human editing and crash possibility. Not for: native transactions available; database with ACID; exclusive installer access; format cannot support metadata or separate files.
You’re reading an older version. View current skill →