PackGuard's alpha rollback workflow is guarded and transaction-based.
Rollback is owned by packages/core and exposed through the CLI. The desktop prototype is not intentionally changed by this phase.
Rollback uses transaction journals and backups under the selected target root:
<targetRoot>/.packguard/transactions/<transactionId>.json
<targetRoot>/.packguard/backups/<transactionId>/<relative-path>Rollback does not use manifest sources, network fetches, downloads, or the verified cache.
await listTransactions({ targetRoot });
await planRollback({ targetRoot, transactionId });
await rollbackTransaction({
targetRoot,
transactionId,
options: {
force: false
}
});listTransactions reads JSON journals under .packguard/transactions and returns:
- transaction id
- status
- pack id/name/version
- start time
- completion time when present
- journal path
- whether backup records are referenced
Malformed journals are rejected instead of silently ignored.
Read-only rollback journal inspection is available:
await listRollbacks({ targetRoot });
await getRollback({ targetRoot, rollbackId });Rollback journals are read from:
<targetRoot>/.packguard/rollbacksRollback ids reject traversal and path separators. The CLI exposes:
packguard rollbacks list --target <folder>
packguard rollbacks show --target <folder> --rollback <id>Doctor reports malformed rollback journals, failed rollback journals, suspicious rollback journal ids, and rollback journals that reference missing rollback safety backup files.
Rollback inspection includes:
await listBackups({ targetRoot });The CLI exposes:
packguard backups list --target <folder>Backup listing inspects transaction backups under .packguard/backups and rollback safety backups under .packguard/rollback-backups. It reports directory metadata only and does not restore, prune, or delete backups.
planRollback reads and validates the transaction journal, then classifies completed apply operations in reverse order.
Planned rollback operation classes:
restore_backup: restore a replaced file from.packguard/backups/<transactionId>/...remove_created_file: remove a file that the transaction explicitly createdskip: operation does not need rollback or cannot be rolled back in the alphaconflict: rollback should not mutate by default
Conflicts include changed target content, missing backup records, missing backup files, or missing applied hash records for created files.
Wrong-hash replacements can be restored when the journal records:
- a completed
replaceoperation - a matching backup record
- a backup file still present under the target root
Before overwriting the current target file, rollback creates a safety backup:
<targetRoot>/.packguard/rollback-backups/<rollbackId>/<relative-path>The restore path and backup path are re-resolved through the target jail before mutation.
Rollback may remove files created by install operations only when:
- the journal records the completed operation
- the target path is re-resolved through the target jail
- the journal records the applied SHA-512
- the current file still matches that applied SHA-512
If the file changed after apply, rollback reports a conflict and does not remove it unless force: true is provided.
copy_rename_available operations do not record an applied hash in the journal, so rollback treats those created files conservatively as conflicts unless forced.
Rollback writes an audit journal:
<targetRoot>/.packguard/rollbacks/<rollbackId>.jsonThe journal records:
- rollback id
- transaction id
- start time
- completion time when completed
- status:
started,completed, orfailed - planned rollback operations
- completed rollback operations
- rollback safety backups
- structured error information when failed
Rollback is marked completed only after verification succeeds:
- restored files must match the backup SHA-512 captured during rollback planning
- removed created files must be absent
If verification fails, rollback marks the rollback journal failed where possible and preserves transaction journals, original backups, and rollback safety backups.
- Rollback is transaction-id based; backup-id rollback is not implemented yet.
- Rollback does not auto-run after failed apply.
- Rollback does not prune journals or backups.
- Extra files are not moved or deleted.
- Symlink hardening uses the existing mutation-time containment checks where feasible and remains an area for future hardening.