# Security Policy

## Supported versions

Only the latest published version is supported. The extension requires OMP 18.3.2 or later (which runs it under Bun), or Pi with Node.js 20 or newer. It is type-checked against OMP 18.3.2's type definitions, and its test suite runs on Node.js 20, 22 and 24 and Bun 1.3.14 against a stand-in host, not a running OMP or Pi.

## Reporting a vulnerability

Please do not report security vulnerabilities in a public issue. Use the repository's GitHub security advisory/private reporting feature: <https://github.com/Baylar55/omp-undo-redo/security/advisories/new>.

Include a concise description, affected version, reproduction steps, impact, and any proposed mitigation. Remove tokens, credentials, private session data, and unrelated personal information before sending a report. If the private channel is unavailable, open a minimal issue asking for a private contact without including vulnerability details.

Maintainers will acknowledge reports when practical, investigate, and coordinate disclosure after a fix or mitigation is available. Please allow reasonable time for triage before public disclosure.

## Scope

The extension navigates OMP's in-memory session tree and restores worktree file contents between recorded checkpoints. It does not promise to roll back shell commands, network requests, editor state, or other external effects. Reports about those limitations are not security vulnerabilities, but may be filed as normal issues when they describe a reproducible defect.

## Snapshot storage

Checkpoints hold verbatim file content. In Git workspaces they capture tracked and untracked non-ignored files (bound by the repository's `.gitignore`, so an unignored `.env.local` is included) and live outside the repository, in a snapshot store under `<storeRoot>/repos/<sha256(commonDir)>.git` that borrows the objects the repository's `HEAD` reaches (`GIT_ALTERNATE_OBJECT_DIRECTORIES`) and holds everything else: no snapshot ref or snapshot-only Git object is ever written to the repository's refs or object database, so `git push --mirror`, `git clone --mirror`, `git bundle create --all` and `git log --all` cannot export or show them. Git LFS is the exception: snapshotting runs the repository's clean filters as `git add` does, so the content of every LFS-tracked file a snapshot captures is written to the repository's LFS storage (`.git/lfs/objects` unless `lfs.storage` moves it) and stays there until `git lfs prune` removes it. Snapshots that versions before this layout wrote into the repository (`refs/omp-undo-redo/`, `.git/omp-undo-redo/`) are moved into the store and deleted from the repository on the next session start in it; until then an all-refs push still exports them. In non-Git workspaces (Private-Git mode) they live under `<storeRoot>/repos/<sha256(cwd)>.git` and, because such a workspace rarely has a `.gitignore`, they capture every file outside the built-in ignore list — including `.env`, private keys, and credential files — in plaintext for the retention window (`OMP_UNDO_REDO_RETENTION_DAYS`, default 2 days). Both kinds of store follow the same expiry: it is enforced when OMP next starts a session, in any workspace, after the window lapses; the background `git gc` that follows deletes the objects. Expiry does not reach Git LFS content: in Private-Git mode LFS-tracked files land in the store's `lfs/` directory (unless `lfs.storage` moves it), which neither expiry nor `git gc` touches. Content kept there stays until the store itself is evicted, which, apart from stores left by earlier versions, happens only after its workspace is gone; content `lfs.storage` moved outside the store is never deleted by the extension. Stores evicted because their workspace or repository vanished stay as `.evicted-<timestamp>` trash for a further 7 days.

The store root and its `repos/` directory are therefore created owner-only (`0700`, POSIX; Windows uses the inherited ACL) and each store sets `core.sharedRepository=0600`. Private repositories created by an earlier version kept the process umask's modes: on a shared host, close every OMP and Pi process, then remove `<storeRoot>/repos` once so it is recreated hardened. This deletes all undo file history.

Each undo or redo that attempts a file restore (including its check-only probe) also writes its restore diff, in plaintext, to `checkpoint.patch` in a fresh directory under the OS temp directory (`omp-undo-redo-patch-*`; `0700` on POSIX, the per-user `%TEMP%` ACL on Windows); the directory may also hold scratch index files and copies of the snapshot's `.gitignore` files. The diff holds the changed lines of every restored file and the whole content of files it adds or deletes. The directory is deleted when the operation ends, on a best-effort basis. If the process exits mid-operation or the deletion fails, it is left behind until an OMP or Pi start finds it older than 24 hours and deletes it, so it can stay longer than 24 hours when neither is started again.
