/** * Grant resolution — the entire security surface of capability governance, as a pure function. * * The invariant (ADR-0008): a capability set may only ever SHRINK as it passes down a delegation * tree. Escalation is impossible by construction rather than by policy, because a parent can never * confer what it does not itself hold. * * effective = ( requested ∩ parentGrant ∩ ceiling ) \ (gated \ approved) * * Being pure — no I/O, no model, no network — this is exhaustively testable, which matters because it * is the only place an escalation could be introduced. */ /** `tool:read` · `ext:pi-web-access/web_search` · `skill:review` · `agent:researcher` */ export type Capability = string; /** * Capabilities that transitively confer everything else. Granting one is equivalent to granting the * whole catalog, so they can never be a *narrowing* grant. * * `ext:pi-fabric/fabric_exec` is here on measured evidence, not suspicion: a child granted * `tools: []` (nothing at all) plus `recursive: true` still reached `pi.write` and `pi.bash` and * spawned a grandchild that wrote to disk. See probe `pi-fabric-eval` (probes 2, 4, 7, 8). */ export declare const UNIVERSAL_CAPABILITIES: readonly Capability[]; /** * Capabilities that functionally contain others. * * `bash` can run `grep`, `find`, `ls`, `cat`, and `sed` — so a session holding it can already do * everything the file and search tools do, whatever the tool list says. Modelling this explicitly serves * two purposes: * * 1. It removes false escalation reports. pi's *default* surface is only `read`, `bash`, `edit`, `write` * (measured, not assumed), so an agent type declaring `tools: read, grep, find, ls` would otherwise * look like an escalation from any normal parent — despite being strictly weaker. * 2. It makes the uncomfortable truth visible rather than implied: **a grant containing `bash` is not a * narrow grant.** `subsumedBy` in the result says so, so a reviewer can see what the grant really means. */ export declare const SUBSUMPTION: Readonly>; /** Expand a grant to everything it functionally confers. */ export declare function expandSubsumed(grant: Capability[]): Capability[]; /** * "Any definition" — ADR-0023, and one of two wildcards this module understands. * * Declared here rather than beside `WILDCARD` because `pi-tools.ts` imports `Capability` from this module. * That import is `import type`, so it is erased and the runtime dependency runs one way only — which is * what makes importing `WILDCARD` back safe. * * Deliberately weaker than `tool:*`: it confers **no tool authority**, so `agent:*,tool:read` may spawn * every definition on disk and hand each of them nothing but `read`. It exists because the alternative was * `tool:*` — authority to grant every tool — which made the safe configuration the laborious one. */ export declare const AGENT_WILDCARD: Capability; /** * `workspace:*` covers any `workspace:` — ADR-0035, and the second namespace wildcard. * * Added as a deliberate edit, which is what the comment in `resolve()` below asks for: there is no * generalised `:*` rule, so a namespace does not acquire a wildcard by existing. Unlike `agent:*` this * one is **not inheritable** (`childEnv` strips it) — R-26's rule, because a root that handed * `workspace:*` down would make routing attenuation meaningless below the root, which is the exact defect * R-131 records. */ export declare const WORKSPACE_WILDCARD: Capability; export interface ResolveInput { /** What the delegating agent asked to give the child. */ requested: Capability[]; /** What the delegating agent itself holds. The root's grant is configured, never defaulted to all. */ parentGrant: Capability[]; /** Declarative maximum for the child's agent type (its frontmatter). Omit for no ceiling. */ ceiling?: Capability[]; /** Destructive capabilities that may never enter a grant without explicit human approval. */ gated?: Capability[]; /** Gated capabilities a human has approved for this specific spawn. */ approved?: Capability[]; /** * Honour functional subsumption when deciding what the parent covers (default true). * Set false for a strict name-equality check. */ subsumption?: boolean; } export interface ResolveResult { /** The capability set the child may hold. */ effective: Capability[]; /** Requested but NOT held by the parent — the escalation-attempt signal. Log every one. */ denied: Capability[]; /** Held by the parent but outside the child type's declared ceiling. */ clipped: Capability[]; /** Allowed by the tree but gated and unapproved. */ gatedBlocked: Capability[]; /** Universal capabilities that survived resolution — see `assertNarrowing`. */ universal: Capability[]; /** * Capabilities the parent covers only through subsumption, not by holding them directly — e.g. `grep` * covered because the parent holds `bash`. Non-empty means the grant is broader than its list suggests. */ subsumedBy: Capability[]; } /** * Resolve a child's grant. Total and side-effect free; every rejected capability is reported rather * than silently dropped, because a grant nobody can audit proves nothing. */ export declare function resolve(input: ResolveInput): ResolveResult; /** * Fail closed on a grant that cannot actually narrow anything. * * A universal capability in an "attenuated" grant is not a narrow grant with one extra item — it is * full authority wearing a narrow grant's clothing. Callers must opt in explicitly rather than * discover this at runtime. */ export declare function assertNarrowing(result: ResolveResult, allowUniversal?: boolean): void; /** * Project an effective grant onto pi's `--tools` allowlist. * * pi core is the enforcement point — verified: `--tools` and `--no-tools` both hard-block extension * tools, and an explicitly `-e`-loaded extension cannot re-add its tool past them * (probe `pi-fabric-eval` probes 9–11). That is why enforcement needs no in-descendant runtime. * * Returns `null` when the grant contains no callable tools, meaning the caller should pass * `--no-tools` rather than an empty `--tools` (an empty list is not a valid allowlist). */ export declare function toPiToolsAllowlist(effective: Capability[]): string[] | null; //# sourceMappingURL=resolve.d.ts.map