Determinism and Honest Failure
The same tree produces the same bytes; a broken boundary produces an error, not a partial story.
- Name every source of ordering that must be stabilized.
- Separate a valid empty result from a filesystem fault.
- Explain why partial output would be dishonest.
Core model
A useful inventory is comparable over time. That requires sorted traversal, stable aggregation, explicit timestamps from filesystem metadata, and no clock or random value in the result. When metadata or directory reads fail, the operation and path are named and the command exits unsuccessfully.
Mental model: Think of a calibrated scale: the same sealed crate must yield the same reading. If the scale loses power, it displays an error instead of yesterday's weight.
The implementation sorts injected `readDir` results before recursion and sorts final relative paths again. It returns `Result<T, Error>` for missing roots, non-directories, `lstat` faults, and `readDir` faults. Two JSON runs over an unchanged tree can therefore be byte-identical.
Boundary table
| Question | Observed boundary | Owner | Verdict |
|---|---|---|---|
| Injected directory order | Sort before walking | Stable paths | DETERMINISTIC |
| Unchanged mtimes | Use filesystem value | Stable range | DETERMINISTIC |
| Read fault | Return Result.err | No partial inventory | FAIL CLOSED |
Primary local source
packages/sessions/src/claude-inventory.test.tsconst first = await inventoryClaudeProject(root, shuffledFsA); const second = await inventoryClaudeProject(root, shuffledFsB); expect(JSON.stringify(first)).toBe(JSON.stringify(second));
Synthetic lab
Choose an observed state and inspect the honest result.
Retrieval and feedback
A nested `readDir` fails after three entries were collected. What may be returned?
Retrieval cards
Check your model
Which time range may U1 claim?
Evidence ledger
Authority: docs/fable-session-mining/LOOP-LOG.md. Tests never upgrade a missing live receipt.