import { z } from "zod"; import { AuthorizationSchema } from "./registration.js"; /** * The per-component materialization receipt (F5). * * This is the byte-ownership record for components AIH materialized directly * into a destination root, and it is deliberately NOT the machine registration * ledger: the ledger (`registration-ledger.json`) stays the machine index — * which components, which targets, which authorization — and never becomes the * byte-ownership home. Ownership evidence belongs next to the owned bytes, so * this document is destination-root-scoped: it disappears with a deleted root * instead of dangling in machine state. * * It follows the two shipped receipt precedents (the profile ownership record * and the hook registrar receipt): a `format` discriminator, a strict Zod * schema, and fail-closed reads. A malformed or unrecognized receipt refuses * every ownership claim and degrades removal to an advisory — never a guess, * and never a delete. */ /** Where the receipt lives, relative to the destination root that holds the owned bytes. */ export declare const ECC_MATERIALIZATION_RECEIPT_PATH = ".aih/ecc/materialization-v1.json"; export declare const ECC_MATERIALIZATION_RECEIPT_FORMAT = "aih-ecc-materialization-receipt"; /** Exact curated runtime authorization required for every governed Kiro destination byte. */ export declare const ECC_KIRO_RUNTIME_COMPONENT_ID = "runtime:ecc-kiro"; /** * The one byte bound. The ownership record is read back through the same * bounded reader as any other destination, so a record larger than a readable * file would be valid and unreadable at once — an install nothing could revoke. * Deriving the second name from the first makes the two impossible to disagree. */ export declare const MAX_MATERIALIZED_FILE_BYTES: number; export declare const MAX_MATERIALIZED_COMPONENTS = 4096; export declare const MAX_MATERIALIZED_FILES_PER_COMPONENT = 2048; export declare const MAX_MATERIALIZED_OWNED_KEYS = 64; export declare const MAX_MATERIALIZATION_RECEIPT_BYTES: number; /** * The ledger's own authorization schema, referenced rather than restated. A * restatement cannot notice a field ADDED upstream, which is the likeliest * direction of drift; sharing the object makes the two contracts the same * contract. */ export { AuthorizationSchema as eccMaterializationAuthorizationSchema }; /** * Whether one path segment names a directory no component may write into or * through. Reserved-ness is a property of ANY segment, not just the first: a * nested repository's `.git/hooks` executes exactly like the outer one's, and * `sub/.aih/` is AIH state wherever it sits. */ export declare function reservedSegmentKind(segment: string): "aih" | "git" | undefined; /** * Refuse a reserved segment anywhere in a path. Callers pass BOTH the requested * spelling (catching names that do not exist yet) and, once the filesystem has * resolved them, the real segments — because a requested string is not what the * OS opens. On NTFS with 8.3 generation, `GIT~1` opens `.git`; the string is * innocent and the resolved path is not. */ export declare function assertUnreservedSegments(segments: readonly string[], requested: string): void; /** * Normalize and validate a destination-relative path a component may own. * Traversal, absolute inputs, AIH's own state area, and Git's directory are * refused rather than repaired. This is the STRING gate; the filesystem * boundary repeats the reserved check on what each segment actually resolves to. */ export declare function assertOwnedRelativePath(value: string): string; /** * Neutralise and bound a value before it reaches an operator-facing message. A * component id or JSON key is third-party text: unbounded it produces a * 200,000-character error, and with terminal controls it can forge output * inside AIH's own refusal. */ export declare function displaySafe(value: string, max?: number): string; /** Validate a component id at the boundary, so no unbounded id reaches a message. */ export declare function assertMaterializedComponentId(value: string): string; /** Validate an owned JSON key at the boundary, for the same reason. */ export declare function assertOwnedJsonKey(value: string): string; /** * Whether a value nests deeper than this engine renders. Iterative on purpose: * `JSON.parse` accepts documents far deeper than `JSON.stringify` survives, so * the check that guards the renderer must not itself recurse. */ export declare function exceedsJsonDepth(value: unknown, max?: number): boolean; /** Validate a source-side component path (provenance), which never touches the destination. */ export declare function assertComponentSourcePath(value: string): string; /** * The identity two destinations collide on. Case folding and Unicode * normalization both resolve to one file on the platforms AIH targets, so * comparing raw strings would let two components claim the same bytes. */ export declare function destinationIdentity(path: string): string; declare const ProvenanceSchema: z.ZodObject<{ repository: z.ZodString; commit: z.ZodString; componentPath: z.ZodString; }, z.core.$strict>; declare const OwnedFileSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{ path: z.ZodString; operation: z.ZodLiteral<"copy-file">; contentSha256: z.ZodString; contentAuthorization: z.ZodOptional; issuer: z.ZodString; evidenceSha256: z.ZodString; effective: z.ZodOptional>; acceptance: z.ZodOptional; }, z.core.$strict>>; }, z.core.$strict>>; contentSourcePath: z.ZodOptional; }, z.core.$strict>, z.ZodObject<{ path: z.ZodString; operation: z.ZodLiteral<"merge-json">; contentSha256: z.ZodString; ownedKeys: z.ZodArray; createdByAih: z.ZodBoolean; contentAuthorization: z.ZodOptional; issuer: z.ZodString; evidenceSha256: z.ZodString; effective: z.ZodOptional>; acceptance: z.ZodOptional; }, z.core.$strict>>; }, z.core.$strict>>; contentSourcePath: z.ZodOptional; }, z.core.$strict>], "operation">; declare const ComponentSchema: z.ZodObject<{ id: z.ZodString; authorization: z.ZodObject<{ componentId: z.ZodString; source: z.ZodString; pinnedSha: z.ZodString; treeSha256: z.ZodString; tier: z.ZodEnum<{ org: "org"; vendor: "vendor"; }>; issuer: z.ZodString; evidenceSha256: z.ZodString; effective: z.ZodOptional>; acceptance: z.ZodOptional; }, z.core.$strict>>; }, z.core.$strict>; provenance: z.ZodObject<{ repository: z.ZodString; commit: z.ZodString; componentPath: z.ZodString; }, z.core.$strict>; files: z.ZodArray; contentSha256: z.ZodString; contentAuthorization: z.ZodOptional; issuer: z.ZodString; evidenceSha256: z.ZodString; effective: z.ZodOptional>; acceptance: z.ZodOptional; }, z.core.$strict>>; }, z.core.$strict>>; contentSourcePath: z.ZodOptional; }, z.core.$strict>, z.ZodObject<{ path: z.ZodString; operation: z.ZodLiteral<"merge-json">; contentSha256: z.ZodString; ownedKeys: z.ZodArray; createdByAih: z.ZodBoolean; contentAuthorization: z.ZodOptional; issuer: z.ZodString; evidenceSha256: z.ZodString; effective: z.ZodOptional>; acceptance: z.ZodOptional; }, z.core.$strict>>; }, z.core.$strict>>; contentSourcePath: z.ZodOptional; }, z.core.$strict>], "operation">>; }, z.core.$strict>; declare const ReceiptSchema: z.ZodObject<{ format: z.ZodLiteral<"aih-ecc-materialization-receipt">; schemaVersion: z.ZodLiteral<1>; components: z.ZodArray; issuer: z.ZodString; evidenceSha256: z.ZodString; effective: z.ZodOptional>; acceptance: z.ZodOptional; }, z.core.$strict>>; }, z.core.$strict>; provenance: z.ZodObject<{ repository: z.ZodString; commit: z.ZodString; componentPath: z.ZodString; }, z.core.$strict>; files: z.ZodArray; contentSha256: z.ZodString; contentAuthorization: z.ZodOptional; issuer: z.ZodString; evidenceSha256: z.ZodString; effective: z.ZodOptional>; acceptance: z.ZodOptional; }, z.core.$strict>>; }, z.core.$strict>>; contentSourcePath: z.ZodOptional; }, z.core.$strict>, z.ZodObject<{ path: z.ZodString; operation: z.ZodLiteral<"merge-json">; contentSha256: z.ZodString; ownedKeys: z.ZodArray; createdByAih: z.ZodBoolean; contentAuthorization: z.ZodOptional; issuer: z.ZodString; evidenceSha256: z.ZodString; effective: z.ZodOptional>; acceptance: z.ZodOptional; }, z.core.$strict>>; }, z.core.$strict>>; contentSourcePath: z.ZodOptional; }, z.core.$strict>], "operation">>; }, z.core.$strict>>; }, z.core.$strict>; export type EccMaterializationOperation = "copy-file" | "merge-json"; export type EccOwnedFile = z.infer; export type EccComponentProvenance = z.infer; export type EccMaterializedComponent = z.infer; export type EccMaterializationReceipt = z.infer; /** * Validate the policy/content evidence split before planning can read or write * destination bytes. Error text is intentionally value-free. */ export declare function assertEccMaterializationEvidenceBinding(binding: { id: string; authorization: unknown; provenance: unknown; path: string; operation: unknown; contentAuthorization?: unknown; contentSourcePath?: unknown; }): void; export type EccMaterializationReceiptRead = { state: "absent"; } | { state: "valid"; receipt: EccMaterializationReceipt; raw: string; sourceBytes: Buffer; sourceSha256: string; } | { state: "malformed"; detail: string; }; export declare function parseEccMaterializationReceipt(text: string): EccMaterializationReceipt; /** * Validate and render the receipt. Every failure is wrapped, so a raw schema * error never escapes to an operator, and the size bound the READ enforces is * enforced here too — a receipt too large to read back is an install nothing * could ever revoke. */ export declare function serializeEccMaterializationReceipt(receipt: EccMaterializationReceipt): string; export declare function eccMaterializationReceiptPath(root: string): string; /** * Fail-closed read. Anything that is not a readable, contained, regular file * holding a valid receipt reports `malformed` instead of throwing, so callers * can refuse ownership claims and degrade removal to an advisory without ever * guessing what AIH owns. */ export declare function readEccMaterializationReceipt(root: string): EccMaterializationReceiptRead; /** The digest a `copy-file` entry pins: the exact bytes written to the destination. */ export declare function ownedFileSha256(bytes: Buffer | string): string; /** * The digest a `merge-json` entry pins: the owned fragment in a canonical, * key-sorted form. Scoping the digest to the owned keys is what lets an * operator edit their own keys in the same document without the edit reading as * drift on AIH's. */ export declare function ownedFragmentSha256(fragment: Record): string;