/** * Public `vault.custody.*` API surface (FR-6). * * The custody namespace is the vault-instance face of the FR-6 sovereign-custody * model — it mirrors `vault.user.*` exactly: a thin delegation shell with NO * business logic. The Vault constructs one `CustodyApi` per session, injecting * closures that bind the vault name / keyring into the genuinely-core * implementations (`Noydb.grantCustodian` / `Noydb.revokeCustodian` and the * `liberateVault` ceremony). Each method just forwards to its injected callback. * * Three operations: * - `grantCustodian(opts)` — owner-only: mint a `custodian` who operates the * vault fully but can never grant / rotate / sever / extract. * - `revokeCustodian(opts)` — owner-only: remove a custodian. * - `liberate(opts)` — custodian-only: audited claim of ownership over a * sealed-owner (Deed) vault (mints a DISTINCT new owner; ledger-audited). * * Provisioning a Deed (`createDeedOwner`) is deliberately NOT on this class: it * is a store-level operation that mints the vault's first owner, so there is no * vault instance (and thus no custody namespace) yet — it stays the exported * `team/deed.ts` function. * * @see docs/superpowers/specs/2026-06-17-fr6-deed-custodian-liberate-design.md * @module */ import type { GrantOptions, RevokeOptions, FactorProofBundle } from '../../kernel/types.js'; import type { LiberateOptions, LiberateResult } from './liberate.js'; /** Options for `vault.custody.grantCustodian` — a grant with the role fixed to `custodian`. */ export type GrantCustodianOptions = Omit; export { withCustody } from './active.js'; export { NO_CUSTODY, type CustodyStrategy, type CustodyHost } from './strategy.js'; export { CustodyNotEnabledError } from '../../kernel/errors.js'; /** * Implementation behind `vault.custody`. Constructed once per Vault. Holds the * injected, vault-bound implementations in closure; every method delegates with * no added logic (the owner-only / custodian-only / gate checks all live in the * injected implementations — `Noydb.grantCustodian` etc. and `liberateVault`). */ export declare class CustodyApi { /** Bound `Noydb.grantCustodian(this.name, ...)` — owner-only, gated. */ private readonly _grantCustodian; /** Bound `Noydb.revokeCustodian(this.name, ...)` — owner-only, gated. */ private readonly _revokeCustodian; /** Bound `liberateVault(this, ...)` — custodian-only audited ownership claim. */ private readonly _liberate; constructor( /** Bound `Noydb.grantCustodian(this.name, ...)` — owner-only, gated. */ _grantCustodian: (options: GrantCustodianOptions, factors?: FactorProofBundle) => Promise, /** Bound `Noydb.revokeCustodian(this.name, ...)` — owner-only, gated. */ _revokeCustodian: (options: RevokeOptions, factors?: FactorProofBundle) => Promise, /** Bound `liberateVault(this, ...)` — custodian-only audited ownership claim. */ _liberate: (opts: LiberateOptions) => Promise); /** * Owner-only: grant the FR-6 `custodian` role. The custodian operates every * collection (rw + access) but is provably unable to grant / revoke / rotate / * extract-and-sever. Defended in depth (gate + owner-only role check) inside * the injected `Noydb.grantCustodian`. */ grantCustodian(options: GrantCustodianOptions, factors?: FactorProofBundle): Promise; /** Owner-only: revoke a custodian. */ revokeCustodian(options: RevokeOptions, factors?: FactorProofBundle): Promise; /** * Custodian-only: the audited claim of ownership over a sealed-owner (Deed) * vault. Mints a DISTINCT new owner re-wrapping the incumbent DEKs under a * fresh KEK (the latent owner is never impersonated), ledger-audited. See * {@link liberateVault}. */ liberate(opts: LiberateOptions): Promise; }