readIfValid method
Reads the artifact at <dir>/usage.json and returns it when it is
parseable AND its chain fingerprint matches expectedRecords/
expectedHash (a fresh scan's numbers). Returns null for a missing
file, a parse failure, or a fingerprint mismatch — the caller then
REBUILDS from the chain instead of merging into garbage (E3).
Implementation
Future<UsageLedger?> readIfValid(
String dir, {
required int expectedRecords,
required String expectedHash,
}) async {
final path = '$dir/$artifactFileName';
final read = await env.readTextFile(path);
if (read.isErr) return null;
final Map<String, dynamic> decoded;
try {
final parsed = jsonDecode(read.valueOrNull!);
if (parsed is! Map) return null;
decoded = parsed.cast<String, dynamic>();
} on Object {
return null;
}
final ledger = UsageLedger.fromJson(decoded);
if (ledger.chainRecords != expectedRecords) return null;
if (ledger.chainHash != expectedHash) return null;
if (ledger.sessionId.isEmpty) return null;
return ledger;
}