Metadata-Version: 2.4
Name: navig-cabinet
Version: 0.2.0
Summary: NAVIG Cabinet — your documents in one plugin: an encrypted cabinet for important files (ID and passport scans, medical records, contracts, photos, recordings — any type, any size; local-OCR search, expiry reminders, portable backups) plus `navig paperwork`, which files business paperwork (invoices, quotes, contracts, tax) into a space. A first-party navig plugin (free, toggleable).
Author-email: NAVIG Development Team <opensource@navig.run>
License-Expression: Apache-2.0
Project-URL: Homepage, https://navig.run
Project-URL: Documentation, https://navig.run/docs
Keywords: navig,cli,plugin,documents,encryption,vault,ocr,backup,personal,paperwork,invoice,facture,accounting
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: End Users/Desktop
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business :: Financial :: Accounting
Classifier: Topic :: Security :: Cryptography
Classifier: Topic :: Utilities
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: navig>=3.25.0
Requires-Dist: navig-vault>=0.7.0
Requires-Dist: cryptography>=42.0
Requires-Dist: python-docx>=1.1
Provides-Extra: ocr
Requires-Dist: pytesseract>=0.3.10; extra == "ocr"
Requires-Dist: Pillow>=9; extra == "ocr"
Dynamic: license-file

# navig-cabinet

<!-- navig:plugin-card:start -->
<!-- Generated by scripts/gen_plugin_catalog.py — edit the plugin's pyproject.toml, not this block. -->

> Your documents in one plugin: an encrypted cabinet for important files (ID and passport scans, medical records, contracts, photos, recordings — any type, any size; local-OCR search, expiry reminders, portable backups) plus `navig paperwork`, which files business paperwork (invoices, quotes, contracts, tax) into a space.

**A navig extension** — installing it pulls in navig and adds the commands below · v0.2.0 · not on PyPI yet (install from source below)

**Install**

```bash
pip install "git+https://github.com/navig-run/plugins#subdirectory=navig-cabinet"
navig cabinet --help
```

It is not a separate program: it needs navig, and installing it installs navig for you.

<details><summary>Commands</summary>

| Command | What it does |
|---|---|
| `navig cabinet add` | Encrypt files into the cabinet (originals are kept unless --move). |
| `navig cabinet backup` | Write one encrypted backup file that restores on any computer, with its own passphrase. |
| `navig cabinet close` | Remove every decrypted copy left by `open` right now. |
| `navig cabinet dates` | Find expiry dates inside documents that have none — passports, ID cards, policies. |
| `navig cabinet edit` | Change an item's title, category, tags, expiry, issuer or notes. |
| `navig cabinet expiring` | Documents that have expired or expire soon — passports, ID cards, insurance. |
| `navig cabinet export` | Write decrypted copies with their original names (verified; never overwrites). |
| `navig cabinet import-paperwork` | Encrypt the ID and medical documents a `navig paperwork` scan set aside (originals stay put). |
| `navig cabinet list` | Everything in the cabinet. |
| `navig cabinet open` | Open an item in its usual app (a temporary decrypted copy). |
| `navig cabinet passphrase clear` | Go back to the machine key (no passphrase). |
| `navig cabinet passphrase set` | Lock the cabinet with a passphrase (asked for on every command). |
| `navig cabinet remind` | Send the expiry reminders that are due now (the daemon also does this daily). |
| `navig cabinet remove` | Move an item to the trash (or --purge it for good). |
| `navig cabinet restore` | Add everything from a backup that the cabinet does not already hold. |
| `navig cabinet search` | Find items by title, tag, or any word inside the document. |
| `navig cabinet show` | Details of one item. |
| `navig cabinet status` | What is in the cabinet, how it is locked, and what needs attention. |
| `navig cabinet undelete` | Bring an item back from the trash. |
| `navig cabinet verify` | Decrypt every item and check it against its stored checksum. |
| `navig paperwork apply` | Execute the plan: copy, verify by hash, then quarantine the source. |
| `navig paperwork echeances` | The deadline radar: what is overdue or due soon, from filed letters and recurrent renewals. |
| `navig paperwork handoff` | File the manifest's non-company documents where they belong. |
| `navig paperwork index` | Rebuild the document index and the invoice register from disk. |
| `navig paperwork reply` | Draft the reply to a filed letter (French, formal) into out/courriers/ — never sent. |
| `navig paperwork review` | Show what the plan intends, or just the rows that still need you. |
| `navig paperwork scan` | Extract, classify and deduplicate documents into a reviewable plan. |
| `navig paperwork undo` | Reverse an apply, restoring every source from the quarantine. |

</details>

<!-- navig:plugin-card:end -->

Your documents, in one plugin. Two commands, one install:

- **`navig cabinet`** is an encrypted cabinet for your important files: ID card and
  passport scans, medical records, insurance, contracts, diplomas, and also photos, voice
  notes and videos. Any file type, any size. You can search by the words inside a
  document, see what expires soon, and back everything up to one file that restores on
  any computer.
- **`navig paperwork`** files your *business* paperwork (invoices, quotes, contracts,
  tax notices) into a space, by reading each document. Those stay ordinary files on
  purpose, because your accountant and the deadline tracker read them. See
  [PAPERWORK.md](PAPERWORK.md).

The two meet where they should. When a paperwork scan finds an ID scan or a medical
record among the business papers, `navig paperwork handoff --yes` encrypts it into the
cabinet instead of filing it as a plain file anywhere.

```bash
navig cabinet add passport.pdf --expires 2031-05-01     # encrypt + read the text (local OCR)
navig cabinet add ~/Scans/medical/                      # a whole folder
navig cabinet search blood test 2025                    # finds words INSIDE the scans
navig cabinet expiring                                  # passports / cards due within 90 days
navig cabinet open 3fa9                                 # view it in its usual app
navig cabinet export --all --by-category -o ~/Desktop/papers
navig cabinet backup -o D:/backups/cabinet              # one encrypted, portable file
```

## Why not the vault?

`navig vault` keeps **secrets**: small values the agent reads constantly (`${VAULT:x}`).
The cabinet keeps **files**: big and irreplaceable, rarely read. They have different
needs:

- **Streaming.** A 4 GB video is encrypted in 4 MiB chunks and never held in memory.
- **Backups.** A secret can be re-issued; a scan of a lost passport cannot.
- **A lock you choose.** See below.

## How it is locked

| | Machine key (default) | Passphrase |
|---|---|---|
| Asks for anything | no | the passphrase, on every command |
| A copy of the files on another computer | useless | useless without the passphrase |
| Someone using *this* computer as you | can open it | cannot |
| Forgetting | nothing to forget | files are unrecoverable |

- Switch with `navig cabinet passphrase set` / `navig cabinet passphrase clear`. Only the key is re-wrapped, so switching is instant.
- For scripts, set `NAVIG_CABINET_PASSPHRASE`.
- The machine key binds to the OS machine id, not the hostname, so renaming the computer is fine.
- A reinstall changes the machine id. **Back up.**

## What is encrypted

**Everything that says anything is encrypted:** the file, its name, title, category, tags, expiry date, issuer, notes, and all the text read out of it. Encryption is AES-256-GCM, with a random key per item wrapped by the cabinet key.

On disk, without the key, you can see only:
- how many items there are,
- roughly how big each one is,
- when each was added.

Text is read **locally only** (Tesseract / local Whisper). Nothing is sent to a cloud OCR, and the text is never cached anywhere in plaintext.

- **Audio/video:** transcribed only with `--transcribe`.
- **OCR for scans:** needs `pip install navig-cabinet[ocr]` plus Tesseract (`scoop install tesseract`). Without it, scans are still stored; they are just searchable by title and tags only.

`navig cabinet open` writes a temporary decrypted copy for the viewer app. It is removed 15 minutes later, or at once with `navig cabinet close`. `export` writes plain copies on purpose, so delete them when you are done.

## In the desktop app

NAVIG OS has a **Cabinet** app (Apps → Security):
- search by the words inside your documents, filter by category;
- see what expires soon;
- **Add files** from a file picker;
- **Open** any item in its usual app.

A passphrase-locked cabinet shows an unlock field, and stays unlocked for 15 idle minutes.

The app talks to the daemon's `/api/deck/cabinet/*` routes, which answer **only this
computer**. A request that came through the tunnel, Lighthouse or the Telegram Mini App
gets a 403, so your document list is never reachable remotely. The routes return
metadata only; opening a file decrypts it on this machine, and no file content travels
over HTTP.

## Expiry reminders

A document gets an expiry date in one of three ways, and navig then reminds you by itself:
- **read from the document** when you add it: the machine-readable zone of a passport or
  ID card (check-digit verified, so an OCR misread is rejected), or a labelled "date
  d'expiration" / "date of expiry" / "valable jusqu'au". A bare date is never taken,
  since the birth date sits right next to the expiry. `navig cabinet show` marks such a
  date "(read from the document)". `navig cabinet dates [--apply]` does the same for
  documents already stored;
- `--expires 2031-05-01` on `add`;
- `navig cabinet edit <id> --expires …` (this also corrects a detected date).

The reminders: **90, 30 and 7 days before, and once when
it has expired**. Each warning is sent once per document; renewing it (a new date) starts
them over. They arrive through your normal notifications (deck bell + Telegram, per
Settings → Notifications), once a day after 09:00, while the navig daemon is running.

A reminder names the **category and the id, never the title**. It says "an identity
document expires in 28 days (`navig cabinet show 3fa9`)", because it may be read on a
phone lock screen.

The daemon never needs your passphrase for this. The cabinet keeps a small **reminder
index** next to itself: just id, category and date, locked to this computer. It is
rewritten whenever the cabinet changes. In a passphrase-locked cabinet, that index is the
one thing readable on this machine without the passphrase.

```bash
navig cabinet remind --dry-run                     # what would be sent today
navig cabinet remind                               # send what is due now
navig config set cabinet.reminders.hour 8          # the daily hour (default 9)
navig config set cabinet.reminders.enabled false   # off, and the index is deleted
```

## Backups and getting your files out

`navig cabinet backup -o <file>` asks for a **backup passphrase** and writes one `.ncab` file.
- It restores on any computer with `navig cabinet restore <file>`.
- Items already present are skipped, so restoring twice is harmless.

**The files never depend on navig.** A backup is an encrypted ordinary tar holding
`manifest.json` (all metadata) and `files/<id>/<original name>`.
[`navig_cabinet/recover_backup.py`](navig_cabinet/recover_backup.py) turns it back into
that tar with nothing but Python and `cryptography`:

```bash
pip install cryptography
python recover_backup.py cabinet.ncab recovered.tar   # or set NCAB_PASSPHRASE for scripts
tar -xf recovered.tar
```

Keep a copy of that script next to your backups.

### Formats

- **Item stream** (`objects/<id>.bin`, also the backup body):
  - Header: `NCABSTR1 ‖ u32 chunk_size`.
  - Then records: `u32 len ‖ nonce(12) ‖ AES-GCM(chunk)`.
  - AAD per chunk: `header ‖ context ‖ u64 index ‖ u8 is_last`. This rejects reordering, truncation, splicing and trailing data.
- **Backup**: `NCABBAK1 ‖ u32 len ‖ header JSON (scrypt n,r,p,salt)`, then an item stream.
  - Key: `scrypt(passphrase)`.
  - Context: `"navig-cabinet/backup/" ‖ sha256(header JSON)`.
- **Key file** (`key.json`): the 32-byte cabinet key, AES-GCM-wrapped by `scrypt(machine id | passphrase)`. The KDF parameters are recorded in the file.

## With `navig paperwork`

`navig paperwork scan` files **business** paperwork into a space as ordinary files. Your
accountant and the deadline tracker need to read those, so they are not encrypted.

The scan also sets aside what is not the business's, in a handoff manifest:

| Found | Goes to |
|---|---|
| ID scans, passports, birth certificates | **the cabinet**, encrypted (category `identity`) |
| prescriptions, test results, medical letters | **the cabinet**, encrypted (category `medical`) |
| benefits and housing letters (CAF, bail, EDF…) | the space that works with them, as files |
| live credentials (2FA codes, recovery keys) | nowhere: import them with `navig vault` |
| someone else's documents | nowhere: never moved |

```bash
navig paperwork handoff --space company-paperwork --dry-run   # rehearse
navig paperwork handoff --space company-paperwork --yes       # file + encrypt
navig paperwork handoff --space company-paperwork --to cabinet --yes   # only the encrypted half
```

Each file must still match the checksum the scan recorded; one that changed since is
reported, not stored. Documents going into the cabinet keep their originals in place —
check them with `navig cabinet list --tag paperwork`, then delete the plain copies
yourself. `navig cabinet import-paperwork <handoff.jsonl>` does the same import from any
manifest.

## All commands

`navig cabinet`: `add` · `list` · `search` · `show` · `open` · `close` · `export` · `edit` ·
`remove` · `undelete` · `expiring` · `dates` · `remind` · `backup` · `restore` · `import-paperwork` ·
`verify` · `status` · `passphrase set|clear`.

`navig paperwork`: `scan` · `review` · `apply` · `undo` · `handoff` · `echeances` · `reply` ·
`index` ([PAPERWORK.md](PAPERWORK.md)).

Lists and reports take `--json`.

Location: `~/.navig/cabinet/`, or `NAVIG_CABINET_DIR`.
