I0821 — Flattened YAML is cached under .ai/local/cache by content hash
Cache the output of mj_yaml_flatten under .ai/local/cache/flat/<sha256>, keyed by the file's content hash and the flattener's own version, so a second command on unchanged files does no parsing.
READY wave 1 · p0 · implementation profile · runs alone
Part of M004 — Performance is executable evidence, and the hot path does no canonical work twice.
Ready. Every dependency is done, so majordomus plan start I0821 will be accepted.
Objective
Cache the output of mj_yaml_flatten under .ai/local/cache/flat/<sha256>, keyed by the file's content hash and the flattener's own version, so a second command on unchanged files does no parsing.
Why
doctor flattens 181 files and knowledge nodes 146; across the hook, watch and context the same files are parsed again and again.
Current state
.ai/README.md already reserves local/cache/ for rebuildable caches; nothing uses it.
Desired state
A miss parses and writes atomically; a hit copies; a changed file cannot hit because its hash changed; the cache is bounded by an entry cap in the policy and trimmed oldest first.
Scope
- lib/common.sh
- share/allow/policy.txt
- share/skeleton/policy.yaml
- .ai/repo/policy.yaml
- docs/SCHEMAS.md
- test/cases/77_flatten_cache.sh
Out of scope
- A cross-process cache of command results
Dependencies
What waits on this
- I0840BLOCKED context and its subcommands under a second
- I0841BLOCKED Cache equivalence proved by property-shaped cases
Acceptance criteria
- Byte-identical output of every read-only command with a cold and a warm cache, proved by case 77
- A changed file is re-parsed, proved by mutation
- The cache never grows past the cap
- yaml_flatten count is unchanged; a new counter flatten_cache_hit reports hits
Validation
- bash test/run.sh 77_flatten_cache
- MJ_TIMING=1 bin/majordomus doctor
Evidence required
- flatten_cache
Evidence
None recorded. Every token above needs a command or an artifact behind it before this issue can be completed; narrative is refused.
Risk
Hashing a file costs a subprocess too; the cache pays only when a flatten is materially dearer than a hash, which the counters must show before this lands.
Timeline
- started
- —
- verified
- —
- completed
- —
Those three fields, the evidence above and the state of the dependencies are all the status is made of. There is no status field to disagree with them.
Canonical record: .ai/repo/project/issues/I0821.yaml. Read it back with majordomus plan show I0821.