ReadonlydirWhere this hook's facts live. Exposed for a failure message ("no fact under …"), NOT as a path to build on — build on it and you are back to the hard-coded private path this handle exists to retire.
Forget the facts THIS hook recorded. A no-op when it recorded none.
Scoped to this hook's own writes, because the store is shared per DIRECTORY
— that sharing is what lets one hook read a fact another recorded — so a
co-located hook's facts (and any entry with no recorded owner) are left
untouched. When a test wants the whole store empty rather than this hook's
share of it, give it a throwaway cwd: the store hangs off that root.
Read a fact exactly as the hook's e.ctx[key] would — same recorded /
ageSeconds / fresherThan. Never-recorded reads back as the total
Infinity fact rather than throwing, because that is what the hook sees.
Also the cheap way to drive the IN-PROCESS tier: the value it returns is a
StateFact, which is what runHookProgram(hook, event, ctx) wants in ctx.
Write a fact as if the hook had recorded it, then read it back through the real reader — so what you get is exactly what the hook will see, and a write that did not land cannot be mistaken for one that did.
ago is the reason this exists: a throttle is only interesting against an
OLD fact, and "old" is not something a test can produce by waiting.
const st = experimental_hookState(".vigiles/hooks/nag.hook.mjs", { cwd });
st.seed("retro.nagged", { ago: "4d" }); // → the hook speaks
st.seed("retro.nagged", { ago: "10m" }); // → the hook stays quiet
Optionalopts: SeedStateOptions
A handle on ONE hook's recorded facts — what experimental_hookState returns. Every method goes through the runtime's own store functions, so a seeded fact is indistinguishable from one the hook recorded itself.