/** * Remediation-loop attestation (audit item 7 completion) — pure binder that ties a prior * BLOCK decision (with its remediation transaction) to a later ALLOW execution chain * (GuardExecutionProof + optional cas-attestation.v1). * * Does NOT modify cas-attestation.ts, execution-proof.ts, or envelope types. * Does NOT claim that the patch fixed required_changes, that recheck_scope was honored * server-side, that no other changes rode along, or that the new decision was caused by * the remediation — see limits (always set). * * Linkage mechanism (measured, app remediation-transaction.js): * resubmission.reference_fingerprint + fingerprint_profile + modified_is_not_permission * + next_preflight_required + recheck_scope. No decision_id prev-link on re-preflight. * * Future stronger form (NOT built here): server-echoed remediation_of on the re-authorize * path would bind decision_id→decision_id; this record only links measured fingerprints. * * DecisionResultEnvelope (SDK typed) does NOT declare remediation_transaction / * required_changes / resubmission — those ride on BLOCK envelopes at runtime when the app * attaches them. Access is via a narrow validated reader (measured field names only). */ import type { DecisionResultEnvelope } from './types.js'; import type { GuardExecutionProof } from './execution-proof.js'; import type { CasAttestation } from './cas-attestation.js'; /** Machine-readable schema id — mirrors cas-attestation.v1 / guard-execution-proof.v1 style. */ export declare const REMEDIATION_LOOP_ATTESTATION_SPEC: "remediation-loop-attestation.v1"; /** * Explicit non-claims. Always set (same discipline as CasAttestation.limits). * Readers that treat missing fields as "ok" are wrong. */ export type RemediationLoopAttestationLimits = { /** Does not claim the host patch addressed required_changes (semantic, unverifiable here). */ does_not_claim_patch_addressed_required_changes: true; /** Does not claim recheck_scope was honored server-side on the re-preflight. */ does_not_claim_recheck_scope_honored: true; /** Does not claim no unrelated changes rode along in the new change set. */ does_not_claim_no_other_changes: true; /** Does not claim the new ALLOW was caused by the remediation (correlation ≠ causation). */ does_not_claim_allow_caused_by_remediation: true; /** * Unchanged input is not permission (mirrors resubmission.modified_is_not_permission / * unchanged_input → deterministic_block). Attestation refuses when fingerprints match. */ does_not_claim_unchanged_input_is_permission: true; /** Same host-bypass residual — package cannot force the host to re-preflight or CAS-commit. */ does_not_claim_host_cannot_bypass: true; }; /** Measured remediation_transaction shape (app remediation-transaction.js, fixed key order). */ export type RemediationTransactionView = { required_changes: unknown[]; resubmission: { reference_fingerprint: string; fingerprint_profile?: string; modified_is_not_permission?: boolean; unchanged_input?: string; modified_input?: string; }; next_preflight_required?: boolean; recheck_scope?: unknown; }; /** * Frozen remediation-loop-attestation.v1 record. * References are lifted from measured identifiers only; derived flags are only what is * honestly computable from the typed inputs. */ export type RemediationLoopAttestation = { attestation_spec: typeof REMEDIATION_LOOP_ATTESTATION_SPEC; references: { block: { decision_id: string; reference_fingerprint: string; required_changes_count: number; recheck_scope: unknown | null; fingerprint_profile: string | null; next_preflight_required: boolean | null; }; allow: { decision_id: string | null; change_fp: string; }; cas: { status: string; authorized_and_committed: boolean; } | null; }; derived: { /** reference_fingerprint !== allow.change_fp (required for closure). */ input_changed: true; /** * True only when cas-attestation is supplied AND cas.derived.authorized_and_committed. * Absent cas → false (recheck+authorize linkage only, not CAS commit). */ loop_committed: boolean; }; limits: RemediationLoopAttestationLimits; }; /** * Read remediation_transaction from a BLOCK envelope object. * Typed DecisionResultEnvelope does not declare this field (measured absent from * decision-result.v1.d.ts); app attaches it at runtime on BLOCK. Measured names only * (remediation-transaction.js). */ export declare function readRemediationTransaction(envelope: unknown): RemediationTransactionView | null; /** * Validate prior envelope is a BLOCK with a usable remediation transaction. * Returns measured identifiers or null if shape invalid. */ export declare function readPriorBlockRemediation(envelope: unknown): { decision_id: string; reference_fingerprint: string; required_changes_count: number; recheck_scope: unknown | null; fingerprint_profile: string | null; next_preflight_required: boolean | null; } | null; export declare function isCasAttestation(x: unknown): x is CasAttestation; /** * Bind prior BLOCK envelope + ALLOW proof (+ optional cas-attestation) into * remediation-loop-attestation.v1. * * Validation-first: TypeError on invalid shapes / not-BLOCK / missing remediation tx / * missing allow change_fp / unchanged fingerprint (modified_is_not_permission). */ export declare function buildRemediationLoopAttestation(priorBlockEnvelope: DecisionResultEnvelope | Record, allowProof: GuardExecutionProof, casAttestation?: CasAttestation | null): RemediationLoopAttestation; //# sourceMappingURL=remediation-loop-attestation.d.ts.map