aa74294a7d
gates / gates (push) Successful in 8s
175 -> 99 effective lines. New .claude/rules/{proxmox,localapi,backup,storage}.md alongside the
existing health-checks.md. The release section points at the felhom-build-deploy skill rather than
restating a table that drifts from the script; the layout section's per-package annotations moved
into the rule file for their area instead of being deleted.
Kept in the core because it is the only part re-injected after /compact: the root-CLI fence and its
three exceptions, the destructive-op gate, prove-ownership (audit A1), the gate entry point, the F9
live-validation fence, and the checklist.
health-checks.md overlaps localapi.md and storage.md on three globs -- deliberate, both load,
stated in each file. Go build/vet/test green and unchanged.
50 lines
2.2 KiB
Markdown
50 lines
2.2 KiB
Markdown
---
|
|
paths: ["internal/storage/**", "internal/escrow/**"]
|
|
---
|
|
|
|
# Storage and escrow — format safety and zero-knowledge recovery
|
|
|
|
`internal/storage/` is the storage observer, durable IDs, role/claim classifiers, `SudoHostOps` and
|
|
the watchdog. `internal/escrow/` is the PBS-key escrow with its zero-knowledge recovery code.
|
|
|
|
> **Overlap note:** `health-checks.md` also matches `internal/storage/**`. Deliberate — both rules
|
|
> apply there and both load.
|
|
|
|
## Never format the device you inspected
|
|
|
|
**AGENT-001 is a TOCTOU:** acting on the caller's `req.Device` (or any remembered `/dev` path) after
|
|
inspection lets `/dev` re-enumeration retarget the node to a **different physical disk**. Format the
|
|
**re-resolved** device — `Server.reresolveWipe` / `reresolveBlank`.
|
|
|
|
**Never exec raw `mkfs.*`** (including `Binaries.MkfsExt4`/`MkfsXfs`): sudoers no longer allowlists
|
|
raw mkfs, and going direct bypasses the claim filter and the wrapper's re-checks. Use
|
|
`SudoHostOps.Format`, which routes through `felhom-mkfs-guarded`.
|
|
|
|
## The two durable-ID schemes refuse each other
|
|
|
|
They are not interchangeable, and each returns a `binding_mismatch` for the other's scheme:
|
|
|
|
| Purpose | Scheme | Resolver |
|
|
|---|---|---|
|
|
| wipe confirmation | `byid:` / `byuuid:` | `ResolveDurableDevice`, `DiskInfo.WipeDurableID` |
|
|
| enrolled-storage remount | `uuid:` | `ResolveStorageDevice` |
|
|
|
|
Using `DiskInfo.DurableID` (a `uuid:`) as a wipe-confirmation id is F20-BUG2.
|
|
|
|
## Drive data is never taken by force
|
|
|
|
Plain `umount` only — **never `-l`, never `-f`**, and never any format operation under
|
|
`/mnt/felhom-drives`.
|
|
|
|
## Escrow is zero-knowledge, and a fetch failure is not a wrong code
|
|
|
|
The server holds no client key; a no-key restore fails with `missing key`. **A fetch failure must
|
|
never be reported as a wrong recovery code** — that told a customer their correct code was bad, in
|
|
hundredths of a second, when checking a code actually takes about one. Distinguish "we could not
|
|
reach the store" from "the code did not match", always.
|
|
|
|
<!--
|
|
The escrow recovery-code "flake" was a REAL defect, not a flake. "Known flake, re-run" needs evidence
|
|
before it is said out loud — that phrase cost this project a real finding once.
|
|
-->
|