PhoinixDR

Recovery health model (v0)

phoinix-health scores a RecoveryEvidence into a RecoveryHealth with two independent numbers (ADR-0006):

The model is deterministic: hard constraints cap the likelihood, weighted evidence moves it within the cap, and every adjustment produces a reason.

Likelihood (defaults in ScoringModel)

evidence effect
resident content in a valid record likelihood ≤ 97
every extent known, every cluster free likelihood ≤ 92
any required cluster allocated cap 79
≥ 10 % allocated cap 59
≥ 50 % allocated cap 34
100 % allocated cap 15
extent map incomplete cap 79 × (located share); 0 when nothing is located
content overlaps a region the device could not read cap 79 × (readable share, from the logical size; 0.5 when unknown), never below 5
allocation map unavailable cap 74
structure damaged / invalid cap 59 / 34
zeros contradict the format (ZeroContentAssessment::ContradictsFormat) cap 20
zeros suspicious for a recognised type (Suspicious) cap 59
empty file (logical size 0) likelihood ≤ 97, validation not applicable
encrypted / compressed cap 10 / 0
heuristic layout (skipped clusters) or inferred start cap 59, or 79 when the content validates completely
layout from an older journal copy that predates the last modification (ExtentEvidence::stale) cap 59, or 79 when the content validates completely
layout recovered from a journal copy (CandidateSource::Journal), not stale no cap; positive reason
carved file (CandidateSource::FileCarving), structure validated cap 85
carved file without a structural validator cap 74
carved file whose end could not be determined cap 59
valid structure +3
fragments −1 per extra extent, at most −5

Fragmentation alone never makes a file Poor when every extent is known and free.

Zero-filled content

Zero sampling (the head block plus up to 64 blocks of 4 KiB spread over the content; 8 for carved files) runs regardless of the examine content option, because clusters discarded by TRIM or wiped read as zeros while the metadata still describes the file perfectly; only the structural validators are optional.

Zeros are not evidence of loss by themselves. Sampled zero blocks are interpreted with the file's context:

All-zero content detected
        │
        ├── stream is sparse                 → Expected, no penalty
        ├── recognised structured type
        │       ├── validation fails         → ContradictsFormat (cap 20)
        │       ├── validation passes        → Plausible, no penalty
        │       └── no validator             → Suspicious (cap 59)
        ├── name implies a structured type   → ContradictsFormat (cap 20)
        └── unknown / raw type               → Ambiguous: likelihood untouched,
                                               confidence −25, explicit warning

An empty file (logical size 0) has no content to recover; it is Excellent when its metadata survives and validation is reported as not applicable.

Confidence

Starts at 100 and loses points for what PHOINIX could not see: damaged record (−30), unknown size (−10), incomplete extents (−25), no allocation map (−25, or proportional to unknown clusters), no structural validator (−15), no content sample (−5), ambiguous zero-filled content (−25), unknown medium (−3), SSD without TRIM knowledge (−10), contiguity assumed (−10) or heuristic layout (−30), start inferred (a further −20), stale journal layout (−10), carved file (−15 for the missing metadata plus −10 for the contiguity assumption).

Carved candidates

A carved file has no metadata record, so the metadata rules are replaced by a single reason ("Found by signature carving: …") and the size rule reads whether the structure determined the end. Allocation caps, validation caps and zero-content rules apply unchanged: a carved file over reused clusters is still Very poor, and a damaged structure is still capped at 59. See docs/carving/deep-scan.md.

Journal candidates

On ext3/ext4 the kernel clears a deleted inode's size and extent tree, so the layout usually comes from an older copy of the inode-table block in the jbd2 journal (docs/ext/reader.md). Such a layout is complete and trustworthy when it was the last state of the file before deletion: the candidate carries CandidateSource::Journal, a diagnostic naming the transaction and whether its checksum verified, and is scored like any other known layout. When the on-disk inode shows a modification the copy does not know about, the layout is marked stale and capped as above.

Wording

$Bitmap proves that a cluster is allocated to active data. It does not prove that every previous byte is gone. Reasons therefore say

42 % of the required clusters are currently allocated to active filesystem data

and never "overwritten". SSD sources produce a warning that TRIM may reduce recoverability, affecting confidence and explanation rather than likelihood, because PHOINIX has no evidence about NAND state.

Categories (provisional)

likelihood category
95–100 Excellent
80–94 Very good
60–79 Good
35–59 Poor
1–34 Very poor
0 Unrecoverable

All thresholds are development heuristics until calibrated against the controlled corpus in tests/fixtures/ntfs/undelete.manifest.json and larger successors.