/** * System-wide severity attestation primitive (T9071 / ADR-054 draft). * * Severity attestation fires for ANY task that carries a `--severity` flag, * not only `cleo bug` entries. This module extracts the attestation logic * that previously lived only in `packages/cleo/src/cli/commands/bug.ts` into * a shared core helper so any command — bug, task-add, sprint-add, etc. — * can produce a signed audit line without duplicating logic. * * ## Audit log * * Signed attestation lines are appended to * `.cleo/audit/severity-attestation.jsonl` (one JSON object per line). The * Task mutations persist signed assertions atomically in the task audit instead. * Standalone JSONL assertions do not prove a task mutation committed. The * previous path `.cleo/audit/bug-severity.jsonl` was bug-command-specific; * callers that still write to the old path will see a one-time deprecation * notice emitted to stderr — migration to the new path is separate cleanup. * * ## Owner-pubkey allowlist * * If `.cleo/config.json` declares an `ownerPubkeys` array, only identities * whose Ed25519 public key (hex) appears in that list may assert a severity. * Signers outside the allowlist receive a permission error naming `E_OWNER_ONLY`. * When the allowlist is absent or empty, any identity may sign (opt-in policy). * * @task T9071 * @adr ADR-054 (draft) */ import type { SeverityAttestation, SignedSeverityAttestation } from '@cleocode/contracts'; export type { SeverityAttestation }; /** * Audit log path for severity attestations. * * Changed from the earlier `bug-severity.jsonl` (which was scoped to * `cleo bug`) to the generic `severity-attestation.jsonl` so any command * that carries `--severity` contributes to the same audit trail. * * @internal */ export declare const SEVERITY_ATTESTATION_AUDIT_FILE = "severity-attestation.jsonl"; /** * Legacy audit log path (bug.ts era). Callers that still write here will * see a deprecation notice. Do NOT write new entries to this path. * * @internal */ export declare const LEGACY_BUG_SEVERITY_AUDIT_FILE = "bug-severity.jsonl"; /** * Read the project's opt-in severity signer allowlist. * * @param cwd - Explicit project root, otherwise the current project. * @returns Authorized keys; absent config or an absent/empty field returns an empty list. * @throws CleoError when configured authority cannot be read or validated. * @remarks An unreadable or malformed authority is not permission for every signer. * @example * ```ts * const owners = await loadOwnerPubkeys(projectRoot); * ``` */ export declare function loadOwnerPubkeys(cwd?: string): Promise; /** * Produce a stable JSON serialisation of the attestation (sorted keys) so * the bytes passed to the signer match what a verifier re-serialises. * * @param record - The full attestation record including `signerPub`. * @returns Deterministic JSON string with keys sorted alphabetically. * @internal */ export declare function canonicalAttestationJson(record: SeverityAttestation): string; /** * Options for {@link appendSignedSeverityAttestation}. */ export interface AppendSeverityAttestationOptions { /** * Optional working directory override. Determines which `.cleo/` directory * receives the audit line and which `config.json` is checked for the * `ownerPubkeys` allowlist. * * Defaults to `process.cwd()`. */ cwd?: string; } /** * Append a signed severity attestation to * `.cleo/audit/severity-attestation.jsonl`. * * Throws a permission error naming `E_OWNER_ONLY` when the signer's pubkey * is not in the configured `ownerPubkeys` allowlist (allowlist enforcement is * only active when the list is non-empty). * * @param record - Attestation fields (excluding `signerPub` which is derived * from the local CLEO identity). * @param options - Optional overrides (e.g. `cwd`). * * @throws CleoError with permission exit code when the allowlist rejects the signer. * * @example * ```ts * await appendSignedSeverityAttestation( * { * timestamp: new Date().toISOString(), * title: 'Fix crash on login', * severity: 'P1', * epic: 'T100', * }, * ); * ``` */ export declare function appendSignedSeverityAttestation(record: Omit, options?: AppendSeverityAttestationOptions): Promise; /** * Authorize and sign a severity assertion without appending a filesystem log. * * Task mutations persist this result in their task transaction, binding the * signature to the assigned task ID. The established owner allowlist is opt-in: * absent or empty lists permit the local identity; nonempty lists restrict it. * * @param record - Assertion to bind to the project identity. * @param options - Explicit project used for both identity and owner policy. * @returns Signed assertion ready for atomic audit persistence. * @remarks Preparation creates no committed task evidence; persist in the task transaction. * Restricted authority never provisions an unknown signer. With opt-in unrestricted * authority, first-use key provisioning is independent persistent project setup; * a later task rollback does not delete or roll back that signing identity. * @example * ```ts * const assertion = await prepareSignedSeverityAttestation({ * timestamp: new Date().toISOString(), taskId: 'T001', * title: 'Restore service', severity: 'P1', * }, { cwd: projectRoot }); * ``` * @throws CleoError with permission exit code when the signer is not allowed. */ export declare function prepareSignedSeverityAttestation(record: Omit, options?: AppendSeverityAttestationOptions): Promise; //# sourceMappingURL=severity-attestation.d.ts.map