/** * deny-remedy.v1 — the machine-readable next step attached to a refusal. * * CANONICAL SCHEMA: capability-demo/docs/deny-remedy.v1.json * sha256 3f51c5afd1708a9185075a4f19f6386ea7d63ad39b0104e31f0e4e887b6e167f * * This builder is the TypeScript transliteration of the copy carried by the * JavaScript deny surfaces — same three classes, same refusal to invent a * fourth, same schema. It is a copy rather than a shared package on purpose: * these repos are installed independently and a shared * dependency would make one of them unable to refuse a request because another * failed to resolve. * * WHERE IT SITS IN THE FLOW. The remedy is attached AFTER a verdict is reached, * never inside verification. Nothing here reads a key, checks a signature, or * can change allow into deny. A surface that emits a remedy has already refused. * * WHAT IT REFUSES TO EMIT. Three error classes exist and no more. A refusal * whose reason does not map to one of them gets NO remedy — an unmapped reason * is a refusal we cannot yet describe as a next step, and inventing a fourth * class, or defaulting to the nearest one, would send a caller to a step that * does not address why they were refused. */ /** The closed set from the schema. */ export declare const DENY_ERROR: Readonly<{ GRANT_REQUIRED: "CODERIFTS_GRANT_REQUIRED"; GRANT_INVALID: "CODERIFTS_GRANT_INVALID"; GRANT_MISMATCH: "CODERIFTS_GRANT_MISMATCH"; }>; /** Carried verbatim from the schema so it cannot be softened in rendering. */ export declare const DOES_NOT_PROMISE = "a grant does not guarantee execution (CAS may still fail)"; export declare const ARGS_SHAPE: Readonly<{ artifacts: "Array<{ id, type, before, after }> — the change set being authorized"; context: "{ operation, environment?, repository?, branch?, pull_request? } — operation is required for authorize"; }>; /** The three classes, as a type. */ export type DenyError = (typeof DENY_ERROR)[keyof typeof DENY_ERROR]; /** The emitted object — exactly the shape the schema describes. */ export interface DenyRemedy { error: DenyError; target: string | null; fingerprint: string | null; action_required: { tool: 'preflight_change_set'; mode: 'authorize'; args_shape: Record; }; does_not_promise: string; observed?: Record; } /** * Build the remedy object, or return null when this refusal has no remedy. * * @param {string} o.error one of DENY_ERROR; anything else returns null * @param {string} [o.target] the surface's own addressing for what was refused * @param {string} [o.fingerprint] the change-set fingerprint the deny was evaluated * against, when the surface has one * @param {object} [o.observed] free-form, for an operator reading a log * @returns {object|null} */ export declare function buildDenyRemedy({ error, target, fingerprint, observed }: { error: DenyError | null; target?: string | null; fingerprint?: string | null; observed?: Record | null; }): DenyRemedy | null; /** * Map a surface's own refusal reason to an error class. * * The mapping is explicit and closed. An unlisted reason returns null, which * means no remedy — see the note at the top of this file. */ export declare function denyErrorForReason(reason: unknown): DenyError | null; //# sourceMappingURL=deny-remedy.d.ts.map