Configuration loading and canonicalized hashing for lanekeep.
Loads lanekeep.config.ts, resolves the rule graph, and derives the hashes feeding the
cache key.
How the config is read
The config is a TypeScript module, so reading it means running it. A synthetic entry
module imports the config's default export into a global, and a second evaluation hands
back JSON.stringify of the parts that are data.
Going through JSON rather than reaching into engine values is deliberate. It keeps every value crossing the boundary plainly serializable, it makes the whole extraction one testable string, and it sidesteps threading engine lifetimes through this crate.
The one thing it cannot carry is a function, and check is a function. So the
extraction separately records whether each rule has a callable check and reduce.
Without that, a rule whose handler was misspelled would load cleanly and silently never
fire — the worst failure this tool can have, because it looks exactly like passing.