radroots_sdk_contract_lib.mjs (6930B)
1 import { createHash } from "node:crypto"; 2 import { lstatSync, readFileSync } from "node:fs"; 3 import { resolve } from "node:path"; 4 5 export const HISTORICAL_AUTHORITY_PATH = 6 "contracts/historical_authority.v1.json"; 7 8 export const HISTORICAL_ARTIFACTS = Object.freeze([ 9 Object.freeze({ 10 path: "contracts/api_baselines/radroots-0.1.0-alpha.txt", 11 role: "public_api_baseline", 12 sha256: "e0c21fc096715fba3b3273bb1a8a880d6e871161772c5a1019404064aa0becb1", 13 }), 14 Object.freeze({ 15 path: "contracts/api_baselines/radroots_sdk-0.1.0-alpha.txt", 16 role: "public_api_baseline", 17 sha256: "97dfccb393fcc7953a59f0b12f03485daf9b7c625e9a4529fd883fcf0306e618", 18 }), 19 Object.freeze({ 20 path: "contracts/architecture/deviations.toml", 21 role: "historical_deviation_ledger", 22 sha256: "888d581264cddf6fe0b4a09a2171535094ef9fb3c422f7866e4e0c802359ea1f", 23 }), 24 Object.freeze({ 25 path: "contracts/crates/release_v1/radroots_crates_release_v1.dot", 26 role: "historical_release_graph", 27 sha256: "d47de10be596a4d33fee102a4f0617f66700b49515a75a1f42d62c9710043059", 28 }), 29 Object.freeze({ 30 path: "contracts/crates/release_v1/radroots_crates_release_v1.sha256", 31 role: "captured_stale_checksum_manifest", 32 sha256: "5759ceaae30a9435346320c2791cfda9eb1559b779ea79fd2e94810e14efa281", 33 }), 34 Object.freeze({ 35 path: "contracts/crates/release_v1/radroots_crates_release_v1.toml", 36 role: "historical_release_catalog", 37 sha256: "1dc18437200dcd65b52090493306f452dade89b5116401d71be4ba4127239b19", 38 }), 39 Object.freeze({ 40 path: "contracts/crates/release_v1/radroots_crates_release_v1_inventory.csv", 41 role: "historical_release_inventory", 42 sha256: "5020875c2cda4b2c9568c8b3f0fad5cd96756c3c779a72481a9652e558f77891", 43 }), 44 ]); 45 46 const RETIRED_HUMAN_ARTIFACTS = Object.freeze([ 47 Object.freeze({ 48 former_path: 49 "docs/decisions/0001-public-api-leakage-migration-baseline.md", 50 parent_path: 51 "docs/oss/sdk/release-v1-history/decisions/0001-public-api-leakage-migration-baseline.md", 52 sha256: "c5f2367bc85c84ce5a3af0d066d3fc8dab6d4e9f1061bb6af35b15d9e4b6e2b1", 53 }), 54 Object.freeze({ 55 former_path: "docs/specs/radroots_crates_release_v1.md", 56 parent_path: 57 "docs/oss/sdk/release-v1-history/release-v1-specification.md", 58 sha256: "6f98eb958a29921919147c44ff6a80565df367adf362f7ac872ce2588a09a1e5", 59 }), 60 ]); 61 62 const CAPTURED_CHECKSUM_MANIFEST = 63 "5a11c6ad90cf03162ca2ce4d1692192d01fa57a31c03fd07d61f70093da5e703 radroots_crates_release_v1.md\n" + 64 "7db533f32c70306b29adea35f85686e67287ae33abd33d1013a61590449f1296 radroots_crates_release_v1.toml\n" + 65 "5020875c2cda4b2c9568c8b3f0fad5cd96756c3c779a72481a9652e558f77891 radroots_crates_release_v1_inventory.csv\n" + 66 "d47de10be596a4d33fee102a4f0617f66700b49515a75a1f42d62c9710043059 radroots_crates_release_v1.dot\n"; 67 68 function exactKeys(value, expected, context) { 69 if (!value || typeof value !== "object" || Array.isArray(value)) { 70 throw new Error(`${context} must be an object`); 71 } 72 const actual = Object.keys(value).sort(); 73 const wanted = [...expected].sort(); 74 if (JSON.stringify(actual) !== JSON.stringify(wanted)) { 75 throw new Error(`${context} has invalid keys`); 76 } 77 } 78 79 function regularFile(path, context) { 80 let metadata; 81 try { 82 metadata = lstatSync(path); 83 } catch (error) { 84 throw new Error(`${context} is missing: ${error.code ?? error.message}`); 85 } 86 if (!metadata.isFile() || metadata.isSymbolicLink()) { 87 throw new Error(`${context} must be a regular non-symlink file`); 88 } 89 } 90 91 function pathExists(path) { 92 try { 93 lstatSync(path); 94 return true; 95 } catch (error) { 96 if (error.code === "ENOENT") { 97 return false; 98 } 99 throw error; 100 } 101 } 102 103 function sha256(path) { 104 return createHash("sha256").update(readFileSync(path)).digest("hex"); 105 } 106 107 export function validateHistoricalAuthority(root) { 108 for (const forbidden of ["docs", ".github", ".act"]) { 109 if (pathExists(resolve(root, forbidden))) { 110 throw new Error(`forbidden capsule root exists: ${forbidden}`); 111 } 112 } 113 114 const manifestPath = resolve(root, HISTORICAL_AUTHORITY_PATH); 115 regularFile(manifestPath, HISTORICAL_AUTHORITY_PATH); 116 const manifest = JSON.parse(readFileSync(manifestPath, "utf8")); 117 exactKeys( 118 manifest, 119 [ 120 "schema_version", 121 "contract_id", 122 "status", 123 "source_revision", 124 "parent_human_owner", 125 "capsule_human_docs_forbidden", 126 "artifacts", 127 "retired_human_artifacts", 128 "captured_checksum_manifest", 129 ], 130 "historical authority", 131 ); 132 if ( 133 manifest.schema_version !== 1 || 134 manifest.contract_id !== "radroots.sdk.historical_authority.v1" || 135 manifest.status !== "historical" || 136 manifest.source_revision !== 137 "bcda74b3ebfff3f711670cc25b7910f27360fba7" || 138 manifest.parent_human_owner !== "docs/oss/sdk/release-v1-history" || 139 manifest.capsule_human_docs_forbidden !== true 140 ) { 141 throw new Error("historical authority identity is invalid"); 142 } 143 144 if ( 145 !Array.isArray(manifest.artifacts) || 146 manifest.artifacts.length !== HISTORICAL_ARTIFACTS.length 147 ) { 148 throw new Error("historical artifact inventory is not exact"); 149 } 150 for (let index = 0; index < HISTORICAL_ARTIFACTS.length; index += 1) { 151 const artifact = manifest.artifacts[index]; 152 const expected = HISTORICAL_ARTIFACTS[index]; 153 exactKeys(artifact, ["path", "role", "sha256"], `artifact ${index}`); 154 if ( 155 artifact.path !== expected.path || 156 artifact.role !== expected.role || 157 artifact.sha256 !== expected.sha256 158 ) { 159 throw new Error(`artifact ${index} identity is invalid`); 160 } 161 if (!/^[0-9a-f]{64}$/.test(artifact.sha256)) { 162 throw new Error(`artifact ${index} digest is invalid`); 163 } 164 const artifactPath = resolve(root, artifact.path); 165 regularFile(artifactPath, artifact.path); 166 if (sha256(artifactPath) !== artifact.sha256) { 167 throw new Error(`artifact digest mismatch: ${artifact.path}`); 168 } 169 } 170 171 if ( 172 JSON.stringify(manifest.retired_human_artifacts) !== 173 JSON.stringify(RETIRED_HUMAN_ARTIFACTS) 174 ) { 175 throw new Error("retired human artifact inventory is not exact"); 176 } 177 178 exactKeys( 179 manifest.captured_checksum_manifest, 180 ["path", "status", "current_digest_authority"], 181 "captured checksum manifest", 182 ); 183 if ( 184 manifest.captured_checksum_manifest.path !== 185 "contracts/crates/release_v1/radroots_crates_release_v1.sha256" || 186 manifest.captured_checksum_manifest.status !== 187 "historical_stale_capture" || 188 manifest.captured_checksum_manifest.current_digest_authority !== 189 HISTORICAL_AUTHORITY_PATH 190 ) { 191 throw new Error("captured checksum disposition is invalid"); 192 } 193 if ( 194 readFileSync( 195 resolve(root, manifest.captured_checksum_manifest.path), 196 "utf8", 197 ) !== CAPTURED_CHECKSUM_MANIFEST 198 ) { 199 throw new Error("captured stale checksum manifest changed"); 200 } 201 }