PersistedApprovalGrants
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/approvals/grants.ts:955
The persisted (always) grant store, backed by a JSON file whose path is injected (the runner
resolves it via fileUtils → .gsloth/.gsloth-settings/shell-allowlist.json for approvals and
…/shell-denylist.json for refusals) so tests can point it at a temp dir.
One class, two files. Which list a store’s entries belong to is the caller’s question, not this class’s: it holds ApprovalGrant records and writes them back. The only thing either side configures is PersistedApprovalGrantsOptions.legacyPrefixMigration, which the deny store turns off.
The v1 migration, and the direction it goes
Section titled “The v1 migration, and the direction it goes”The shipped v1 file held prefixes: string[] — classified command PREFIXES, so a stored
npm test also auto-approved npm test --watch. Each prefix migrates to an exact entry for
the same string, with one notice naming the file.
That narrows what the file grants, on purpose: a v1 prefix was broader than what the human was actually shown when they answered the prompt, so narrowing it costs at worst a re-prompt and never an execution — the direction every ambiguity in this design resolves. The migrated file is rewritten as v2 immediately, so the notice is a one-time event rather than a per-session one; a write that fails (read-only checkout) is not fatal — the grants are in force for this session and the notice simply appears again next time.
Constructors
Section titled “Constructors”Constructor
Section titled “Constructor”new PersistedApprovalGrants(
filePath,options?):PersistedApprovalGrants
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/approvals/grants.ts:988
Parameters
Section titled “Parameters”filePath
Section titled “filePath”string
options?
Section titled “options?”PersistedApprovalGrantsOptions
Returns
Section titled “Returns”PersistedApprovalGrants
Methods
Section titled “Methods”add(
grant):boolean
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/approvals/grants.ts:1238
Add a grant and persist the whole store. A duplicate entry rewrites nothing.
Returns whether the grant is now recorded in the file ([[EXT-144]]), which is not the same
question as whether it is in force — it is in force either way, held here and in the runner’s
session store. false says only that a restart will not find it.
Parameters
Section titled “Parameters”Returns
Section titled “Returns”boolean
canPersist()
Section titled “canPersist()”canPersist():
boolean
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/approvals/grants.ts:1227
[[EXT-144]] — may this store write its file at all? False when the load failed, in which case every write is refused.
Public because the caller has to know before it builds the record it is about to hand over: a grant is stamped with the scope it actually got, the runner’s in-memory stores can hold the very object they are passed, and a scope corrected after the fact would be corrected inside somebody else’s store. Asking first is what lets an answer that cannot be written down be recorded as the session-only thing it is.
It answers about the FILE being readable, never about a write succeeding. A store whose path cannot be written — a read-only checkout — still answers true here, because nothing was lost by reading it and the next write may well land.
Returns
Section titled “Returns”boolean
entries()
Section titled “entries()”entries():
ApprovalEntry[]
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/approvals/grants.ts:1204
Just the entries, for handing to the matcher as one of its rule lists.
Returns
Section titled “Returns”find()
Section titled “find()”find(
entry):ApprovalGrant|undefined
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/approvals/grants.ts:1263
The grant held under this entry’s identity, or undefined.
Parameters
Section titled “Parameters”Returns
Section titled “Returns”ApprovalGrant | undefined
list()
Section titled “list()”list():
ApprovalGrant[]
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/approvals/grants.ts:1199
Every grant.
Returns
Section titled “Returns”remove()
Section titled “remove()”remove(
entry):boolean
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/approvals/grants.ts:1290
Drop the grant held under this entry’s identity and rewrite the file.
Returns whether the deletion reached the FILE ([[EXT-149]]) — the mirror of what add
answers, and not the same question as whether the entry is still in force here. The in-memory
removal happens either way and is what lifts the entry for this session; false says only that
a restart will find it again. It used to return true after a write that threw, which is how
the /approvals lift came to report a deletion that had not happened.
false is also the answer when there was no such grant. The two are distinguishable with
find beforehand, and the caller that reports to a user has already established the entry
was there — it is offering to lift something it just listed.
The write is what makes §4.7.4’s invalidation a one-time event: a removal held only in memory would be undone by the next session reloading the same stale snapshot, so the user would be told their grant had been withdrawn once per session, forever.
The [[EXT-144]] refusal cannot strand a removal half-done, and by construction rather than by a check here: a store that could not read its file is empty — the load recovered nothing, and add takes back what it could not write — so there is never a grant to remove, and this returns before reaching the write. If that invariant is ever broken, restore it rather than teaching this method to unwind.
Parameters
Section titled “Parameters”Returns
Section titled “Returns”boolean
size()
Section titled “size()”size():
number
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/approvals/grants.ts:1209
How many grants are persisted.
Returns
Section titled “Returns”number