@aigrc/core 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -2,6 +2,12 @@ var __defProp = Object.defineProperty;
2
2
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
3
  var __getOwnPropNames = Object.getOwnPropertyNames;
4
4
  var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
6
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
7
+ }) : x)(function(x) {
8
+ if (typeof require !== "undefined") return require.apply(this, arguments);
9
+ throw Error('Dynamic require of "' + x + '" is not supported');
10
+ });
5
11
  var __esm = (fn, res) => function __init() {
6
12
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
7
13
  };
@@ -1072,6 +1078,311 @@ var ConstraintsSchema = z.object({
1072
1078
  logToolInvocations: z.boolean().default(true)
1073
1079
  }).optional()
1074
1080
  });
1081
+ var RiskLevelSchema = z.enum(["minimal", "limited", "high", "unacceptable"]);
1082
+ var GoldenThreadSchema = z.object({
1083
+ /** Ticket ID from approval system (e.g., "FIN-1234") */
1084
+ ticket_id: z.string().min(1),
1085
+ /** Email of approver (e.g., "ciso@corp.com") */
1086
+ approved_by: z.string().email(),
1087
+ /** ISO 8601 timestamp of approval (e.g., "2025-01-15T10:30:00Z") */
1088
+ approved_at: z.string().datetime(),
1089
+ /** SHA-256 hash of canonical string: sha256:{64 hex chars} */
1090
+ hash: z.string().regex(/^sha256:[a-f0-9]{64}$/).optional(),
1091
+ /** Optional cryptographic signature: {ALGORITHM}:{BASE64_SIGNATURE} */
1092
+ signature: z.string().regex(/^(RSA-SHA256|ECDSA-P256):[A-Za-z0-9+/=]+$/).optional()
1093
+ });
1094
+ var LineageSchema = z.object({
1095
+ /** Parent agent's instance_id, null for root agents */
1096
+ parent_instance_id: z.string().uuid().nullable(),
1097
+ /** Depth in spawn tree: 0 for root, 1 for first child, etc. */
1098
+ generation_depth: z.number().int().min(0),
1099
+ /** Chain of ancestor instance_ids from root to parent */
1100
+ ancestor_chain: z.array(z.string().uuid()),
1101
+ /** When this agent was spawned */
1102
+ spawned_at: z.string().datetime(),
1103
+ /** Root agent's instance_id for tracing entire tree */
1104
+ root_instance_id: z.string().uuid()
1105
+ });
1106
+ var CapabilitiesManifestSchema = z.object({
1107
+ /** List of allowed tool/action identifiers (supports wildcards: *, prefix_*) */
1108
+ allowed_tools: z.array(z.string()).default([]),
1109
+ /** List of explicitly denied tools (takes precedence over allowed) */
1110
+ denied_tools: z.array(z.string()).default([]),
1111
+ /** Allowed domain patterns (regex) for external resources */
1112
+ allowed_domains: z.array(z.string()).default([]),
1113
+ /** Denied domain patterns (takes precedence over allowed) */
1114
+ denied_domains: z.array(z.string()).default([]),
1115
+ /** Maximum cost per session in USD */
1116
+ max_cost_per_session: z.number().positive().nullable().optional(),
1117
+ /** Maximum cost per day in USD */
1118
+ max_cost_per_day: z.number().positive().nullable().optional(),
1119
+ /** Maximum tokens per single API call */
1120
+ max_tokens_per_call: z.number().int().positive().nullable().optional(),
1121
+ /** Whether this agent can spawn child agents */
1122
+ may_spawn_children: z.boolean().default(false),
1123
+ /** Maximum depth of child agent spawning (0 = cannot spawn) */
1124
+ max_child_depth: z.number().int().min(0).default(0),
1125
+ /** Capability decay mode for children: decay, explicit, inherit */
1126
+ capability_mode: z.enum(["decay", "explicit", "inherit"]).default("decay"),
1127
+ /** Custom extension fields */
1128
+ custom: z.record(z.unknown()).optional()
1129
+ });
1130
+ var OperatingModeSchema = z.enum(["NORMAL", "SANDBOX", "RESTRICTED"]);
1131
+ var RuntimeIdentitySchema = z.object({
1132
+ /** Unique UUIDv4 for this runtime instance */
1133
+ instance_id: z.string().uuid(),
1134
+ /** Asset ID from the Asset Card (e.g., "aigrc-2024-a1b2c3d4") */
1135
+ asset_id: z.string().regex(/^aigrc-\d{4}-[a-f0-9]{8}$/),
1136
+ /** Human-readable name from Asset Card */
1137
+ asset_name: z.string().min(1).max(100),
1138
+ /** Semantic version from Asset Card */
1139
+ asset_version: z.string().regex(/^\d+\.\d+\.\d+/),
1140
+ /** SHA-256 hash of Golden Thread data */
1141
+ golden_thread_hash: z.string().regex(/^sha256:[a-f0-9]{64}$/),
1142
+ /** Full Golden Thread authorization data */
1143
+ golden_thread: GoldenThreadSchema,
1144
+ /** Risk level from classification */
1145
+ risk_level: RiskLevelSchema,
1146
+ /** Agent lineage for spawned agents */
1147
+ lineage: LineageSchema,
1148
+ /** Capabilities manifest defining permissions */
1149
+ capabilities_manifest: CapabilitiesManifestSchema,
1150
+ /** When this identity was created */
1151
+ created_at: z.string().datetime(),
1152
+ /** Whether Golden Thread hash has been verified */
1153
+ verified: z.boolean().default(false),
1154
+ /** Current operating mode */
1155
+ mode: OperatingModeSchema.default("NORMAL")
1156
+ });
1157
+ var KillSwitchCommandTypeSchema = z.enum(["TERMINATE", "PAUSE", "RESUME"]);
1158
+ var KillSwitchCommandSchema = z.object({
1159
+ /** Unique command ID for idempotency and replay prevention */
1160
+ command_id: z.string().uuid(),
1161
+ /** Type of command */
1162
+ type: KillSwitchCommandTypeSchema,
1163
+ /** Target instance_id (optional, for specific instance) */
1164
+ instance_id: z.string().uuid().optional(),
1165
+ /** Target asset_id (optional, for all instances of an asset) */
1166
+ asset_id: z.string().regex(/^aigrc-\d{4}-[a-f0-9]{8}$/).optional(),
1167
+ /** Target organization (optional, for org-wide kill) */
1168
+ organization: z.string().optional(),
1169
+ /** Cryptographic signature for verification */
1170
+ signature: z.string(),
1171
+ /** ISO 8601 timestamp for replay prevention */
1172
+ timestamp: z.string().datetime(),
1173
+ /** Human-readable reason for audit trail */
1174
+ reason: z.string().max(500),
1175
+ /** Issuer of the command (email or system ID) */
1176
+ issued_by: z.string()
1177
+ });
1178
+ var GovernanceTokenIdentityClaimsSchema = z.object({
1179
+ instance_id: z.string().uuid(),
1180
+ asset_id: z.string(),
1181
+ asset_name: z.string(),
1182
+ asset_version: z.string()
1183
+ });
1184
+ var GovernanceTokenGovernanceClaimsSchema = z.object({
1185
+ risk_level: RiskLevelSchema,
1186
+ golden_thread: z.object({
1187
+ hash: z.string().regex(/^sha256:[a-f0-9]{64}$/),
1188
+ verified: z.boolean(),
1189
+ ticket_id: z.string()
1190
+ }),
1191
+ mode: OperatingModeSchema
1192
+ });
1193
+ var GovernanceTokenControlClaimsSchema = z.object({
1194
+ kill_switch: z.object({
1195
+ enabled: z.boolean(),
1196
+ channel: z.enum(["sse", "polling", "file"])
1197
+ }),
1198
+ paused: z.boolean(),
1199
+ termination_pending: z.boolean()
1200
+ });
1201
+ var GovernanceTokenCapabilityClaimsSchema = z.object({
1202
+ hash: z.string(),
1203
+ tools: z.array(z.string()),
1204
+ max_budget_usd: z.number().nullable(),
1205
+ can_spawn: z.boolean(),
1206
+ max_child_depth: z.number().int().min(0)
1207
+ });
1208
+ var GovernanceTokenLineageClaimsSchema = z.object({
1209
+ generation_depth: z.number().int().min(0),
1210
+ parent_instance_id: z.string().uuid().nullable(),
1211
+ root_instance_id: z.string().uuid()
1212
+ });
1213
+ var GovernanceTokenPayloadSchema = z.object({
1214
+ // Standard JWT claims
1215
+ /** Issuer: "aigos-runtime" */
1216
+ iss: z.literal("aigos-runtime"),
1217
+ /** Subject: instance_id of the agent */
1218
+ sub: z.string().uuid(),
1219
+ /** Audience: "aigos-agents" or specific agent */
1220
+ aud: z.union([z.string(), z.array(z.string())]),
1221
+ /** Expiration timestamp (Unix epoch) */
1222
+ exp: z.number().int().positive(),
1223
+ /** Issued at timestamp (Unix epoch) */
1224
+ iat: z.number().int().positive(),
1225
+ /** Not before timestamp (Unix epoch) */
1226
+ nbf: z.number().int().positive(),
1227
+ /** Unique JWT ID */
1228
+ jti: z.string().uuid(),
1229
+ // AIGOS-specific claims
1230
+ aigos: z.object({
1231
+ identity: GovernanceTokenIdentityClaimsSchema,
1232
+ governance: GovernanceTokenGovernanceClaimsSchema,
1233
+ control: GovernanceTokenControlClaimsSchema,
1234
+ capabilities: GovernanceTokenCapabilityClaimsSchema,
1235
+ lineage: GovernanceTokenLineageClaimsSchema
1236
+ })
1237
+ });
1238
+ var AssetCardRuntimeSchema = z.object({
1239
+ /** Path to policy file for this asset */
1240
+ policy_path: z.string().optional(),
1241
+ /** Behavior when Golden Thread verification fails */
1242
+ verification_failure_mode: z.enum(["SANDBOX", "FAIL"]).default("SANDBOX"),
1243
+ /** Whether telemetry is enabled for this asset */
1244
+ telemetry_enabled: z.boolean().default(true),
1245
+ /** Kill switch configuration */
1246
+ kill_switch: z.object({
1247
+ enabled: z.boolean().default(true),
1248
+ channel: z.enum(["sse", "polling", "file"]).default("sse"),
1249
+ endpoint: z.string().url().optional()
1250
+ }).optional()
1251
+ });
1252
+ var PolicyRuleEffectSchema = z.enum(["allow", "deny", "audit"]);
1253
+ var PolicyRuleSchema = z.object({
1254
+ /** Unique identifier for this rule */
1255
+ id: z.string().min(1),
1256
+ /** Human-readable description */
1257
+ description: z.string().optional(),
1258
+ /** Effect when rule matches: allow, deny, or audit */
1259
+ effect: PolicyRuleEffectSchema,
1260
+ /** Actions/tools this rule applies to (supports wildcards) */
1261
+ actions: z.array(z.string()).default(["*"]),
1262
+ /** Resources/domains this rule applies to (supports patterns) */
1263
+ resources: z.array(z.string()).default(["*"]),
1264
+ /** Conditions that must be true for rule to apply */
1265
+ conditions: z.object({
1266
+ /** Required risk levels for this rule to apply */
1267
+ risk_levels: z.array(RiskLevelSchema).optional(),
1268
+ /** Required operating modes */
1269
+ modes: z.array(OperatingModeSchema).optional(),
1270
+ /** Time-based conditions (ISO 8601 time ranges) */
1271
+ time_ranges: z.array(z.object({
1272
+ start: z.string(),
1273
+ end: z.string()
1274
+ })).optional(),
1275
+ /** Custom condition expressions */
1276
+ custom: z.record(z.unknown()).optional()
1277
+ }).optional(),
1278
+ /** Priority for rule ordering (higher = evaluated first) */
1279
+ priority: z.number().int().default(0)
1280
+ });
1281
+ var PolicyCapabilitiesSchema = z.object({
1282
+ /** Default effect when no rule matches */
1283
+ default_effect: PolicyRuleEffectSchema.default("deny"),
1284
+ /** Allowed tools (supports wildcards: *, prefix_*) */
1285
+ allowed_tools: z.array(z.string()).default([]),
1286
+ /** Denied tools (takes precedence) */
1287
+ denied_tools: z.array(z.string()).default([]),
1288
+ /** Allowed domain patterns */
1289
+ allowed_domains: z.array(z.string()).default([]),
1290
+ /** Denied domain patterns */
1291
+ denied_domains: z.array(z.string()).default([]),
1292
+ /** Maximum budget per session in USD */
1293
+ max_budget_per_session: z.number().positive().nullable().optional(),
1294
+ /** Maximum budget per day in USD */
1295
+ max_budget_per_day: z.number().positive().nullable().optional(),
1296
+ /** Whether agent can spawn children */
1297
+ may_spawn: z.boolean().default(false),
1298
+ /** Maximum spawn depth */
1299
+ max_spawn_depth: z.number().int().min(0).default(0)
1300
+ });
1301
+ var PolicyFileSchema = z.object({
1302
+ /** Schema version for forward compatibility */
1303
+ version: z.literal("1.0"),
1304
+ /** Unique policy identifier */
1305
+ id: z.string().min(1),
1306
+ /** Human-readable name */
1307
+ name: z.string().min(1).max(100),
1308
+ /** Description of this policy */
1309
+ description: z.string().max(500).optional(),
1310
+ /** Parent policy to inherit from */
1311
+ extends: z.string().optional(),
1312
+ /** Target asset IDs or patterns this policy applies to */
1313
+ applies_to: z.array(z.string()).default(["*"]),
1314
+ /** Default capabilities when no rules match */
1315
+ capabilities: PolicyCapabilitiesSchema.optional(),
1316
+ /** Ordered list of policy rules */
1317
+ rules: z.array(PolicyRuleSchema).default([]),
1318
+ /** Metadata */
1319
+ metadata: z.object({
1320
+ created_at: z.string().datetime().optional(),
1321
+ updated_at: z.string().datetime().optional(),
1322
+ created_by: z.string().optional(),
1323
+ tags: z.array(z.string()).optional()
1324
+ }).optional()
1325
+ });
1326
+ var AigrcRuntimeConfigSchema = z.object({
1327
+ /** Default policy file path */
1328
+ default_policy: z.string().optional(),
1329
+ /** Policy search paths */
1330
+ policy_paths: z.array(z.string()).default([".aigrc/policies"]),
1331
+ /** Asset card search paths */
1332
+ asset_paths: z.array(z.string()).default([".aigrc/assets"]),
1333
+ /** Default verification failure mode */
1334
+ verification_failure_mode: z.enum(["SANDBOX", "FAIL"]).default("SANDBOX"),
1335
+ /** Telemetry configuration */
1336
+ telemetry: z.object({
1337
+ enabled: z.boolean().default(true),
1338
+ endpoint: z.string().url().optional(),
1339
+ sample_rate: z.number().min(0).max(1).default(1)
1340
+ }).optional(),
1341
+ /** Kill switch configuration */
1342
+ kill_switch: z.object({
1343
+ enabled: z.boolean().default(true),
1344
+ channel: z.enum(["sse", "polling", "file"]).default("sse"),
1345
+ endpoint: z.string().url().optional(),
1346
+ poll_interval_ms: z.number().int().positive().default(5e3)
1347
+ }).optional()
1348
+ });
1349
+ var AigrcIntegrationsConfigSchema = z.object({
1350
+ /** JIRA integration */
1351
+ jira: z.object({
1352
+ enabled: z.boolean().default(false),
1353
+ url: z.string().url().optional(),
1354
+ project_key: z.string().optional()
1355
+ }).optional(),
1356
+ /** Azure DevOps integration */
1357
+ azure_devops: z.object({
1358
+ enabled: z.boolean().default(false),
1359
+ organization: z.string().optional(),
1360
+ project: z.string().optional()
1361
+ }).optional(),
1362
+ /** GitHub integration */
1363
+ github: z.object({
1364
+ enabled: z.boolean().default(false),
1365
+ owner: z.string().optional(),
1366
+ repo: z.string().optional()
1367
+ }).optional()
1368
+ });
1369
+ var AigrcConfigSchema = z.object({
1370
+ /** Schema version */
1371
+ version: z.literal("1.0"),
1372
+ /** Project name */
1373
+ name: z.string().min(1).max(100).optional(),
1374
+ /** Project description */
1375
+ description: z.string().max(500).optional(),
1376
+ /** Runtime governance configuration */
1377
+ runtime: AigrcRuntimeConfigSchema.optional(),
1378
+ /** External integrations */
1379
+ integrations: AigrcIntegrationsConfigSchema.optional(),
1380
+ /** Environment-specific overrides */
1381
+ environments: z.record(z.object({
1382
+ runtime: AigrcRuntimeConfigSchema.partial().optional(),
1383
+ integrations: AigrcIntegrationsConfigSchema.partial().optional()
1384
+ })).optional()
1385
+ });
1075
1386
  var AssetCardSchema = z.object({
1076
1387
  $schema: z.string().optional(),
1077
1388
  id: z.string().regex(/^aigrc-\d{4}-[a-f0-9]{8}$/),
@@ -1088,7 +1399,11 @@ var AssetCardSchema = z.object({
1088
1399
  classification: ClassificationSchema,
1089
1400
  intent: IntentSchema,
1090
1401
  governance: GovernanceSchema,
1091
- constraints: ConstraintsSchema.optional()
1402
+ constraints: ConstraintsSchema.optional(),
1403
+ /** Golden Thread authorization data (SPEC-PRT-001) */
1404
+ golden_thread: GoldenThreadSchema.optional(),
1405
+ /** Runtime governance configuration (SPEC-RT) */
1406
+ runtime: AssetCardRuntimeSchema.optional()
1092
1407
  });
1093
1408
 
1094
1409
  // src/classification.ts
@@ -1159,6 +1474,73 @@ function validateRiskFactors(factors) {
1159
1474
  return true;
1160
1475
  }
1161
1476
 
1477
+ // src/risk-utils.ts
1478
+ var RISK_ORDINALS = {
1479
+ minimal: 0,
1480
+ limited: 1,
1481
+ high: 2,
1482
+ unacceptable: 3
1483
+ };
1484
+ var EU_AI_ACT_MAP = {
1485
+ minimal: "minimal_risk",
1486
+ limited: "limited_risk",
1487
+ high: "high_risk",
1488
+ unacceptable: "prohibited"
1489
+ };
1490
+ function compareRiskLevels(a, b) {
1491
+ const ordA = RISK_ORDINALS[a];
1492
+ const ordB = RISK_ORDINALS[b];
1493
+ if (ordA < ordB) return -1;
1494
+ if (ordA > ordB) return 1;
1495
+ return 0;
1496
+ }
1497
+ function isRiskLevelAtLeast(level, threshold) {
1498
+ return RISK_ORDINALS[level] >= RISK_ORDINALS[threshold];
1499
+ }
1500
+ function isRiskLevelAtMost(level, threshold) {
1501
+ return RISK_ORDINALS[level] <= RISK_ORDINALS[threshold];
1502
+ }
1503
+ function getRiskLevelOrdinal(level) {
1504
+ return RISK_ORDINALS[level];
1505
+ }
1506
+ function getMaxRiskLevel(levels) {
1507
+ if (levels.length === 0) {
1508
+ return "minimal";
1509
+ }
1510
+ return levels.reduce(
1511
+ (max, current) => RISK_ORDINALS[current] > RISK_ORDINALS[max] ? current : max
1512
+ );
1513
+ }
1514
+ function getMinRiskLevel(levels) {
1515
+ if (levels.length === 0) {
1516
+ return "minimal";
1517
+ }
1518
+ return levels.reduce(
1519
+ (min, current) => RISK_ORDINALS[current] < RISK_ORDINALS[min] ? current : min
1520
+ );
1521
+ }
1522
+ function mapToEuAiActCategory(level) {
1523
+ return EU_AI_ACT_MAP[level];
1524
+ }
1525
+ function getRiskLevelsAtLeast(threshold) {
1526
+ const thresholdOrd = RISK_ORDINALS[threshold];
1527
+ return Object.entries(RISK_ORDINALS).filter(([, ord]) => ord >= thresholdOrd).map(([level]) => level);
1528
+ }
1529
+ function getRiskLevelsAtMost(threshold) {
1530
+ const thresholdOrd = RISK_ORDINALS[threshold];
1531
+ return Object.entries(RISK_ORDINALS).filter(([, ord]) => ord <= thresholdOrd).map(([level]) => level);
1532
+ }
1533
+ function parseRiskLevel(value) {
1534
+ const normalized = value.toLowerCase();
1535
+ if (normalized in RISK_ORDINALS) {
1536
+ return normalized;
1537
+ }
1538
+ return void 0;
1539
+ }
1540
+ function isValidRiskLevel(value) {
1541
+ return typeof value === "string" && value in RISK_ORDINALS;
1542
+ }
1543
+
1162
1544
  // src/asset-card.ts
1163
1545
  import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
1164
1546
  import { dirname } from "path";
@@ -1308,6 +1690,115 @@ function validateAssetCard(card) {
1308
1690
  }
1309
1691
 
1310
1692
  // src/golden-thread.ts
1693
+ function computeCanonicalString(components) {
1694
+ const normalizedTimestamp = normalizeTimestamp(components.approved_at);
1695
+ const pairs = [
1696
+ `approved_at=${normalizedTimestamp}`,
1697
+ `approved_by=${components.approved_by}`,
1698
+ `ticket_id=${components.ticket_id}`
1699
+ ];
1700
+ return pairs.join("|");
1701
+ }
1702
+ function normalizeTimestamp(timestamp) {
1703
+ const date = new Date(timestamp);
1704
+ if (isNaN(date.getTime())) {
1705
+ throw new Error(`Invalid timestamp: ${timestamp}`);
1706
+ }
1707
+ return date.toISOString().replace(/\.\d{3}Z$/, "Z");
1708
+ }
1709
+ async function computeGoldenThreadHash(components) {
1710
+ const canonicalString = computeCanonicalString(components);
1711
+ const encoder = new TextEncoder();
1712
+ const data = encoder.encode(canonicalString);
1713
+ const hashBuffer = await crypto.subtle.digest("SHA-256", data);
1714
+ const hashArray = Array.from(new Uint8Array(hashBuffer));
1715
+ const hashHex = hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
1716
+ return {
1717
+ canonical_string: canonicalString,
1718
+ hash: `sha256:${hashHex}`
1719
+ };
1720
+ }
1721
+ function computeGoldenThreadHashSync(components) {
1722
+ const canonicalString = computeCanonicalString(components);
1723
+ const crypto2 = __require("crypto");
1724
+ const hash = crypto2.createHash("sha256").update(canonicalString).digest("hex");
1725
+ return {
1726
+ canonical_string: canonicalString,
1727
+ hash: `sha256:${hash}`
1728
+ };
1729
+ }
1730
+ async function verifyGoldenThreadHash(components, expectedHash) {
1731
+ const { hash: computedHash } = await computeGoldenThreadHash(components);
1732
+ const verified = constantTimeEqual(computedHash, expectedHash);
1733
+ return {
1734
+ verified,
1735
+ computed: computedHash,
1736
+ expected: expectedHash,
1737
+ mismatch_reason: verified ? void 0 : "Hash mismatch"
1738
+ };
1739
+ }
1740
+ function verifyGoldenThreadHashSync(components, expectedHash) {
1741
+ const { hash: computedHash } = computeGoldenThreadHashSync(components);
1742
+ const verified = constantTimeEqual(computedHash, expectedHash);
1743
+ return {
1744
+ verified,
1745
+ computed: computedHash,
1746
+ expected: expectedHash,
1747
+ mismatch_reason: verified ? void 0 : "Hash mismatch"
1748
+ };
1749
+ }
1750
+ function constantTimeEqual(a, b) {
1751
+ if (a.length !== b.length) {
1752
+ return false;
1753
+ }
1754
+ let result = 0;
1755
+ for (let i = 0; i < a.length; i++) {
1756
+ result |= a.charCodeAt(i) ^ b.charCodeAt(i);
1757
+ }
1758
+ return result === 0;
1759
+ }
1760
+ function extractGoldenThreadComponents(asset) {
1761
+ if (asset.golden_thread) {
1762
+ return {
1763
+ ticket_id: asset.golden_thread.ticket_id,
1764
+ approved_by: asset.golden_thread.approved_by,
1765
+ approved_at: asset.golden_thread.approved_at
1766
+ };
1767
+ }
1768
+ if (!asset.intent.ticketId) {
1769
+ return null;
1770
+ }
1771
+ const approvals = asset.governance.approvals;
1772
+ if (approvals.length === 0) {
1773
+ return null;
1774
+ }
1775
+ const latestApproval = approvals.reduce(
1776
+ (latest, current) => new Date(current.date) > new Date(latest.date) ? current : latest
1777
+ );
1778
+ return {
1779
+ ticket_id: asset.intent.ticketId,
1780
+ approved_by: latestApproval.email || latestApproval.name,
1781
+ approved_at: latestApproval.date
1782
+ };
1783
+ }
1784
+ async function createGoldenThread(components) {
1785
+ const { hash } = await computeGoldenThreadHash(components);
1786
+ return {
1787
+ ticket_id: components.ticket_id,
1788
+ approved_by: components.approved_by,
1789
+ approved_at: components.approved_at,
1790
+ hash
1791
+ };
1792
+ }
1793
+ function createGoldenThreadSync(components) {
1794
+ const { hash } = computeGoldenThreadHashSync(components);
1795
+ return {
1796
+ ticket_id: components.ticket_id,
1797
+ approved_by: components.approved_by,
1798
+ approved_at: components.approved_at,
1799
+ hash
1800
+ };
1801
+ }
1311
1802
  function linkAssetToTicket(asset, ticket) {
1312
1803
  const warnings = [];
1313
1804
  const intent = {
@@ -1356,6 +1847,144 @@ function validateGoldenThread(asset) {
1356
1847
  issues
1357
1848
  };
1358
1849
  }
1850
+ function parseSignature(signature) {
1851
+ const match = signature.match(/^(RSA-SHA256|ECDSA-P256):([A-Za-z0-9+/=]+)$/);
1852
+ if (!match) {
1853
+ return null;
1854
+ }
1855
+ const algorithm = match[1];
1856
+ const base64Data = match[2];
1857
+ try {
1858
+ const binaryString = atob(base64Data);
1859
+ const bytes = new Uint8Array(binaryString.length);
1860
+ for (let i = 0; i < binaryString.length; i++) {
1861
+ bytes[i] = binaryString.charCodeAt(i);
1862
+ }
1863
+ return { algorithm, data: bytes };
1864
+ } catch {
1865
+ return null;
1866
+ }
1867
+ }
1868
+ async function verifyGoldenThreadSignature(components, signature, publicKey) {
1869
+ const parsed = parseSignature(signature);
1870
+ if (!parsed) {
1871
+ return {
1872
+ verified: false,
1873
+ algorithm: null,
1874
+ error: "Invalid signature format. Expected {ALGORITHM}:{BASE64_SIGNATURE}"
1875
+ };
1876
+ }
1877
+ if (parsed.algorithm !== publicKey.algorithm) {
1878
+ return {
1879
+ verified: false,
1880
+ algorithm: parsed.algorithm,
1881
+ error: `Algorithm mismatch: signature uses ${parsed.algorithm}, key is ${publicKey.algorithm}`
1882
+ };
1883
+ }
1884
+ const canonicalString = computeCanonicalString(components);
1885
+ const encoder = new TextEncoder();
1886
+ const data = encoder.encode(canonicalString);
1887
+ try {
1888
+ const cryptoKey = await importPublicKey(publicKey);
1889
+ const algorithmParams = getVerifyAlgorithm(parsed.algorithm);
1890
+ const verified = await crypto.subtle.verify(
1891
+ algorithmParams,
1892
+ cryptoKey,
1893
+ parsed.data,
1894
+ data
1895
+ );
1896
+ return {
1897
+ verified,
1898
+ algorithm: parsed.algorithm,
1899
+ signedData: canonicalString,
1900
+ error: verified ? void 0 : "Signature verification failed"
1901
+ };
1902
+ } catch (error) {
1903
+ return {
1904
+ verified: false,
1905
+ algorithm: parsed.algorithm,
1906
+ error: `Verification error: ${error instanceof Error ? error.message : String(error)}`
1907
+ };
1908
+ }
1909
+ }
1910
+ function verifyGoldenThreadSignatureSync(components, signature, publicKeyPem) {
1911
+ const parsed = parseSignature(signature);
1912
+ if (!parsed) {
1913
+ return {
1914
+ verified: false,
1915
+ algorithm: null,
1916
+ error: "Invalid signature format"
1917
+ };
1918
+ }
1919
+ const canonicalString = computeCanonicalString(components);
1920
+ try {
1921
+ const crypto2 = __require("crypto");
1922
+ const verifier = crypto2.createVerify(
1923
+ parsed.algorithm === "RSA-SHA256" ? "RSA-SHA256" : "SHA256"
1924
+ );
1925
+ verifier.update(canonicalString);
1926
+ verifier.end();
1927
+ const verified = verifier.verify(publicKeyPem, Buffer.from(parsed.data));
1928
+ return {
1929
+ verified,
1930
+ algorithm: parsed.algorithm,
1931
+ signedData: canonicalString,
1932
+ error: verified ? void 0 : "Signature verification failed"
1933
+ };
1934
+ } catch (error) {
1935
+ return {
1936
+ verified: false,
1937
+ algorithm: parsed.algorithm,
1938
+ error: `Verification error: ${error instanceof Error ? error.message : String(error)}`
1939
+ };
1940
+ }
1941
+ }
1942
+ async function signGoldenThread(components, privateKey, algorithm) {
1943
+ const canonicalString = computeCanonicalString(components);
1944
+ const encoder = new TextEncoder();
1945
+ const data = encoder.encode(canonicalString);
1946
+ const signatureBuffer = await crypto.subtle.sign(
1947
+ getSignAlgorithm(algorithm),
1948
+ privateKey,
1949
+ data
1950
+ );
1951
+ const signatureArray = new Uint8Array(signatureBuffer);
1952
+ const base64 = btoa(String.fromCharCode(...signatureArray));
1953
+ return `${algorithm}:${base64}`;
1954
+ }
1955
+ async function importPublicKey(publicKey) {
1956
+ const pemHeader = "-----BEGIN PUBLIC KEY-----";
1957
+ const pemFooter = "-----END PUBLIC KEY-----";
1958
+ let keyData;
1959
+ if (publicKey.key.includes(pemHeader)) {
1960
+ const pemContents = publicKey.key.replace(pemHeader, "").replace(pemFooter, "").replace(/\s/g, "");
1961
+ const binaryString = atob(pemContents);
1962
+ const bytes = new Uint8Array(binaryString.length);
1963
+ for (let i = 0; i < binaryString.length; i++) {
1964
+ bytes[i] = binaryString.charCodeAt(i);
1965
+ }
1966
+ keyData = bytes.buffer;
1967
+ } else {
1968
+ const binaryString = atob(publicKey.key);
1969
+ const bytes = new Uint8Array(binaryString.length);
1970
+ for (let i = 0; i < binaryString.length; i++) {
1971
+ bytes[i] = binaryString.charCodeAt(i);
1972
+ }
1973
+ keyData = bytes.buffer;
1974
+ }
1975
+ const algorithm = publicKey.algorithm === "RSA-SHA256" ? { name: "RSASSA-PKCS1-v1_5", hash: "SHA-256" } : { name: "ECDSA", namedCurve: "P-256" };
1976
+ return crypto.subtle.importKey("spki", keyData, algorithm, true, ["verify"]);
1977
+ }
1978
+ function getVerifyAlgorithm(algorithm) {
1979
+ if (algorithm === "RSA-SHA256") {
1980
+ return { name: "RSASSA-PKCS1-v1_5" };
1981
+ } else {
1982
+ return { name: "ECDSA", hash: "SHA-256" };
1983
+ }
1984
+ }
1985
+ function getSignAlgorithm(algorithm) {
1986
+ return getVerifyAlgorithm(algorithm);
1987
+ }
1359
1988
 
1360
1989
  // src/detection/types.ts
1361
1990
  import { z as z2 } from "zod";
@@ -2194,6 +2823,1385 @@ init_javascript();
2194
2823
  init_model_files();
2195
2824
  init_risk_indicators();
2196
2825
 
2826
+ // src/config.ts
2827
+ import * as fs from "fs";
2828
+ import * as path from "path";
2829
+ import * as yaml from "yaml";
2830
+ var CONFIG_FILE_NAMES = [
2831
+ ".aigrc.yaml",
2832
+ ".aigrc.yml",
2833
+ "aigrc.yaml",
2834
+ "aigrc.yml"
2835
+ ];
2836
+ var CONFIG_ENV_VAR = "AIGRC_CONFIG_PATH";
2837
+ function discoverConfig(options = {}) {
2838
+ const { startDir = process.cwd(), maxDepth = 10 } = options;
2839
+ if (options.configPath) {
2840
+ const result = loadConfigFromPath(options.configPath);
2841
+ if (result) {
2842
+ return { ...result, fromEnv: false };
2843
+ }
2844
+ }
2845
+ const envPath = process.env[CONFIG_ENV_VAR];
2846
+ if (envPath) {
2847
+ const result = loadConfigFromPath(envPath);
2848
+ if (result) {
2849
+ return { ...result, fromEnv: true };
2850
+ }
2851
+ }
2852
+ let currentDir = path.resolve(startDir);
2853
+ let depth = 0;
2854
+ while (depth < maxDepth) {
2855
+ for (const fileName of CONFIG_FILE_NAMES) {
2856
+ const filePath = path.join(currentDir, fileName);
2857
+ if (fs.existsSync(filePath)) {
2858
+ const config = loadConfigFile(filePath);
2859
+ if (config) {
2860
+ return {
2861
+ config,
2862
+ configPath: filePath,
2863
+ configDir: currentDir,
2864
+ fromEnv: false
2865
+ };
2866
+ }
2867
+ }
2868
+ }
2869
+ const parentDir = path.dirname(currentDir);
2870
+ if (parentDir === currentDir) {
2871
+ break;
2872
+ }
2873
+ currentDir = parentDir;
2874
+ depth++;
2875
+ }
2876
+ return null;
2877
+ }
2878
+ function loadConfigFromPath(configPath) {
2879
+ const resolvedPath = path.resolve(configPath);
2880
+ if (!fs.existsSync(resolvedPath)) {
2881
+ return null;
2882
+ }
2883
+ const config = loadConfigFile(resolvedPath);
2884
+ if (!config) {
2885
+ return null;
2886
+ }
2887
+ return {
2888
+ config,
2889
+ configPath: resolvedPath,
2890
+ configDir: path.dirname(resolvedPath)
2891
+ };
2892
+ }
2893
+ function loadConfigFile(filePath) {
2894
+ try {
2895
+ const content = fs.readFileSync(filePath, "utf-8");
2896
+ const parsed = yaml.parse(content);
2897
+ return AigrcConfigSchema.parse(parsed);
2898
+ } catch {
2899
+ return null;
2900
+ }
2901
+ }
2902
+ function discoverConfigSync(options = {}) {
2903
+ return discoverConfig(options);
2904
+ }
2905
+ function discoverPolicies(options = {}) {
2906
+ const {
2907
+ config,
2908
+ baseDir = process.cwd(),
2909
+ additionalPaths = []
2910
+ } = options;
2911
+ const policies = /* @__PURE__ */ new Map();
2912
+ const loadedPaths = [];
2913
+ const errors = [];
2914
+ const searchPaths = [
2915
+ ...config?.runtime?.policy_paths ?? [".aigrc/policies"],
2916
+ ...additionalPaths
2917
+ ];
2918
+ for (const searchPath of searchPaths) {
2919
+ const absolutePath = path.isAbsolute(searchPath) ? searchPath : path.join(baseDir, searchPath);
2920
+ if (!fs.existsSync(absolutePath)) {
2921
+ continue;
2922
+ }
2923
+ const stat = fs.statSync(absolutePath);
2924
+ if (stat.isDirectory()) {
2925
+ const files = fs.readdirSync(absolutePath);
2926
+ for (const file of files) {
2927
+ if (file.endsWith(".yaml") || file.endsWith(".yml")) {
2928
+ const filePath = path.join(absolutePath, file);
2929
+ const result = loadPolicyFile(filePath);
2930
+ if (result.policy) {
2931
+ policies.set(result.policy.id, result.policy);
2932
+ loadedPaths.push(filePath);
2933
+ } else if (result.error) {
2934
+ errors.push({ path: filePath, error: result.error });
2935
+ }
2936
+ }
2937
+ }
2938
+ } else if (stat.isFile()) {
2939
+ const result = loadPolicyFile(absolutePath);
2940
+ if (result.policy) {
2941
+ policies.set(result.policy.id, result.policy);
2942
+ loadedPaths.push(absolutePath);
2943
+ } else if (result.error) {
2944
+ errors.push({ path: absolutePath, error: result.error });
2945
+ }
2946
+ }
2947
+ }
2948
+ return { policies, loadedPaths, errors };
2949
+ }
2950
+ function loadPolicyFile(filePath) {
2951
+ try {
2952
+ const content = fs.readFileSync(filePath, "utf-8");
2953
+ const parsed = yaml.parse(content);
2954
+ const policy = PolicyFileSchema.parse(parsed);
2955
+ return { policy, error: null };
2956
+ } catch (err) {
2957
+ const message = err instanceof Error ? err.message : String(err);
2958
+ return { policy: null, error: message };
2959
+ }
2960
+ }
2961
+ function loadPolicy(policyId, options = {}) {
2962
+ const { policies } = discoverPolicies(options);
2963
+ return policies.get(policyId) ?? null;
2964
+ }
2965
+ function discoverAssets(options = {}) {
2966
+ const {
2967
+ config,
2968
+ baseDir = process.cwd(),
2969
+ additionalPaths = []
2970
+ } = options;
2971
+ const assets = /* @__PURE__ */ new Map();
2972
+ const loadedPaths = [];
2973
+ const errors = [];
2974
+ const searchPaths = [
2975
+ ...config?.runtime?.asset_paths ?? [".aigrc/assets"],
2976
+ ...additionalPaths
2977
+ ];
2978
+ for (const searchPath of searchPaths) {
2979
+ const absolutePath = path.isAbsolute(searchPath) ? searchPath : path.join(baseDir, searchPath);
2980
+ if (!fs.existsSync(absolutePath)) {
2981
+ continue;
2982
+ }
2983
+ const stat = fs.statSync(absolutePath);
2984
+ if (stat.isDirectory()) {
2985
+ const files = fs.readdirSync(absolutePath);
2986
+ for (const file of files) {
2987
+ if (file.endsWith(".yaml") || file.endsWith(".yml")) {
2988
+ const filePath = path.join(absolutePath, file);
2989
+ const result = loadAssetFile(filePath);
2990
+ if (result.asset) {
2991
+ assets.set(result.asset.id, result.asset);
2992
+ loadedPaths.push(filePath);
2993
+ } else if (result.error) {
2994
+ errors.push({ path: filePath, error: result.error });
2995
+ }
2996
+ }
2997
+ }
2998
+ } else if (stat.isFile()) {
2999
+ const result = loadAssetFile(absolutePath);
3000
+ if (result.asset) {
3001
+ assets.set(result.asset.id, result.asset);
3002
+ loadedPaths.push(absolutePath);
3003
+ } else if (result.error) {
3004
+ errors.push({ path: absolutePath, error: result.error });
3005
+ }
3006
+ }
3007
+ }
3008
+ return { assets, loadedPaths, errors };
3009
+ }
3010
+ function loadAssetFile(filePath) {
3011
+ try {
3012
+ const content = fs.readFileSync(filePath, "utf-8");
3013
+ const parsed = yaml.parse(content);
3014
+ const asset = AssetCardSchema.parse(parsed);
3015
+ return { asset, error: null };
3016
+ } catch (err) {
3017
+ const message = err instanceof Error ? err.message : String(err);
3018
+ return { asset: null, error: message };
3019
+ }
3020
+ }
3021
+ function loadAsset(assetId, options = {}) {
3022
+ const { assets } = discoverAssets(options);
3023
+ return assets.get(assetId) ?? null;
3024
+ }
3025
+ function loadAssetFromPath(filePath) {
3026
+ const result = loadAssetFile(filePath);
3027
+ return result.asset;
3028
+ }
3029
+ function getEnvironmentConfig(config, environment) {
3030
+ const envOverrides = config.environments?.[environment];
3031
+ if (!envOverrides) {
3032
+ return config;
3033
+ }
3034
+ const result = { ...config };
3035
+ if (config.runtime || envOverrides.runtime) {
3036
+ result.runtime = {
3037
+ ...config.runtime,
3038
+ ...filterUndefined(envOverrides.runtime ?? {})
3039
+ };
3040
+ }
3041
+ if (config.integrations || envOverrides.integrations) {
3042
+ result.integrations = {
3043
+ ...config.integrations,
3044
+ ...filterUndefined(envOverrides.integrations ?? {})
3045
+ };
3046
+ }
3047
+ return result;
3048
+ }
3049
+ function filterUndefined(obj) {
3050
+ const result = {};
3051
+ for (const key of Object.keys(obj)) {
3052
+ if (obj[key] !== void 0) {
3053
+ result[key] = obj[key];
3054
+ }
3055
+ }
3056
+ return result;
3057
+ }
3058
+ function getCurrentEnvironment() {
3059
+ return process.env.AIGRC_ENV ?? process.env.NODE_ENV ?? "development";
3060
+ }
3061
+ function createDefaultConfig() {
3062
+ return AigrcConfigSchema.parse({
3063
+ version: "1.0",
3064
+ runtime: {},
3065
+ integrations: {}
3066
+ });
3067
+ }
3068
+
3069
+ // src/policy.ts
3070
+ var MAX_INHERITANCE_DEPTH = 10;
3071
+ var PolicyResolutionError = class extends Error {
3072
+ constructor(message, policyId, cause) {
3073
+ super(message);
3074
+ this.policyId = policyId;
3075
+ this.cause = cause;
3076
+ this.name = "PolicyResolutionError";
3077
+ }
3078
+ };
3079
+ function createPolicyRepository(policies) {
3080
+ return {
3081
+ get: (id) => policies.get(id),
3082
+ has: (id) => policies.has(id)
3083
+ };
3084
+ }
3085
+ function resolvePolicy(policyId, repository) {
3086
+ const chain = [];
3087
+ const seenIds = /* @__PURE__ */ new Set();
3088
+ let currentId = policyId;
3089
+ while (currentId) {
3090
+ if (seenIds.has(currentId)) {
3091
+ throw new PolicyResolutionError(
3092
+ `Circular inheritance detected: ${currentId}`,
3093
+ policyId
3094
+ );
3095
+ }
3096
+ if (chain.length >= MAX_INHERITANCE_DEPTH) {
3097
+ throw new PolicyResolutionError(
3098
+ `Maximum inheritance depth (${MAX_INHERITANCE_DEPTH}) exceeded`,
3099
+ policyId
3100
+ );
3101
+ }
3102
+ const policy = repository.get(currentId);
3103
+ if (!policy) {
3104
+ throw new PolicyResolutionError(
3105
+ `Policy not found: ${currentId}`,
3106
+ policyId
3107
+ );
3108
+ }
3109
+ seenIds.add(currentId);
3110
+ chain.push(policy);
3111
+ currentId = policy.extends;
3112
+ }
3113
+ chain.reverse();
3114
+ const mergedPolicy = chain.reduce(
3115
+ (accumulated, current) => mergePolicies(accumulated, current),
3116
+ createEmptyPolicy(chain[0]?.id ?? policyId)
3117
+ );
3118
+ mergedPolicy.id = policyId;
3119
+ return {
3120
+ policy: mergedPolicy,
3121
+ inheritanceChain: chain.map((p) => p.id),
3122
+ depth: chain.length
3123
+ };
3124
+ }
3125
+ function createEmptyPolicy(id) {
3126
+ return {
3127
+ version: "1.0",
3128
+ id,
3129
+ name: "",
3130
+ applies_to: [],
3131
+ rules: []
3132
+ };
3133
+ }
3134
+ function mergePolicies(parent, child) {
3135
+ return {
3136
+ version: child.version,
3137
+ id: child.id,
3138
+ name: child.name || parent.name,
3139
+ description: child.description ?? parent.description,
3140
+ extends: child.extends,
3141
+ // Keep child's extends for reference
3142
+ applies_to: child.applies_to.length > 0 && child.applies_to[0] !== "*" ? child.applies_to : parent.applies_to,
3143
+ capabilities: mergeCapabilities(parent.capabilities, child.capabilities),
3144
+ rules: mergeRules(parent.rules, child.rules),
3145
+ metadata: {
3146
+ ...parent.metadata,
3147
+ ...child.metadata,
3148
+ // Merge tags
3149
+ tags: mergeArrays(parent.metadata?.tags, child.metadata?.tags)
3150
+ }
3151
+ };
3152
+ }
3153
+ function mergeCapabilities(parent, child) {
3154
+ if (!parent && !child) {
3155
+ return void 0;
3156
+ }
3157
+ if (!parent) {
3158
+ return child;
3159
+ }
3160
+ if (!child) {
3161
+ return parent;
3162
+ }
3163
+ return {
3164
+ default_effect: child.default_effect ?? parent.default_effect,
3165
+ allowed_tools: mergeArrays(parent.allowed_tools, child.allowed_tools),
3166
+ denied_tools: mergeArrays(parent.denied_tools, child.denied_tools),
3167
+ allowed_domains: mergeArrays(parent.allowed_domains, child.allowed_domains),
3168
+ denied_domains: mergeArrays(parent.denied_domains, child.denied_domains),
3169
+ max_budget_per_session: child.max_budget_per_session ?? parent.max_budget_per_session,
3170
+ max_budget_per_day: child.max_budget_per_day ?? parent.max_budget_per_day,
3171
+ may_spawn: child.may_spawn ?? parent.may_spawn,
3172
+ max_spawn_depth: child.max_spawn_depth ?? parent.max_spawn_depth
3173
+ };
3174
+ }
3175
+ function mergeRules(parentRules, childRules) {
3176
+ const allRules = [...parentRules, ...childRules];
3177
+ return allRules.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
3178
+ }
3179
+ function mergeArrays(parent, child) {
3180
+ const combined = [...parent ?? [], ...child ?? []];
3181
+ return [...new Set(combined)];
3182
+ }
3183
+ function evaluatePolicy(policy, action, resource, context) {
3184
+ for (const rule of policy.rules) {
3185
+ if (ruleMatches(rule, action, resource, context)) {
3186
+ return {
3187
+ allowed: rule.effect === "allow",
3188
+ effect: rule.effect,
3189
+ matchedRule: rule,
3190
+ matched: true,
3191
+ reason: `Rule "${rule.id}" matched: ${rule.description ?? rule.effect}`
3192
+ };
3193
+ }
3194
+ }
3195
+ const defaultEffect = policy.capabilities?.default_effect ?? "deny";
3196
+ return {
3197
+ allowed: defaultEffect === "allow",
3198
+ effect: defaultEffect,
3199
+ matchedRule: void 0,
3200
+ matched: false,
3201
+ reason: `No rule matched, using default effect: ${defaultEffect}`
3202
+ };
3203
+ }
3204
+ function ruleMatches(rule, action, resource, context) {
3205
+ if (!matchesPattern(action, rule.actions)) {
3206
+ return false;
3207
+ }
3208
+ if (!matchesPattern(resource, rule.resources)) {
3209
+ return false;
3210
+ }
3211
+ if (rule.conditions) {
3212
+ if (!evaluateConditions(rule.conditions, context)) {
3213
+ return false;
3214
+ }
3215
+ }
3216
+ return true;
3217
+ }
3218
+ function matchesPattern(value, patterns) {
3219
+ for (const pattern of patterns) {
3220
+ if (pattern === "*") {
3221
+ return true;
3222
+ }
3223
+ if (pattern.endsWith("*")) {
3224
+ const prefix = pattern.slice(0, -1);
3225
+ if (value.startsWith(prefix)) {
3226
+ return true;
3227
+ }
3228
+ } else if (pattern.startsWith("*")) {
3229
+ const suffix = pattern.slice(1);
3230
+ if (value.endsWith(suffix)) {
3231
+ return true;
3232
+ }
3233
+ } else if (pattern === value) {
3234
+ return true;
3235
+ }
3236
+ }
3237
+ return false;
3238
+ }
3239
+ function evaluateConditions(conditions, context) {
3240
+ if (conditions.risk_levels && conditions.risk_levels.length > 0) {
3241
+ if (!conditions.risk_levels.includes(context.riskLevel)) {
3242
+ return false;
3243
+ }
3244
+ }
3245
+ if (conditions.modes && conditions.modes.length > 0) {
3246
+ if (!conditions.modes.includes(context.mode)) {
3247
+ return false;
3248
+ }
3249
+ }
3250
+ if (conditions.time_ranges && conditions.time_ranges.length > 0 && context.timestamp) {
3251
+ const currentTime = new Date(context.timestamp);
3252
+ const timeStr = currentTime.toTimeString().slice(0, 5);
3253
+ const inRange = conditions.time_ranges.some((range) => {
3254
+ return timeStr >= range.start && timeStr <= range.end;
3255
+ });
3256
+ if (!inRange) {
3257
+ return false;
3258
+ }
3259
+ }
3260
+ return true;
3261
+ }
3262
+ function isToolAllowed(tool, capabilities) {
3263
+ if (!capabilities) {
3264
+ return false;
3265
+ }
3266
+ if (capabilities.denied_tools.length > 0 && matchesPattern(tool, capabilities.denied_tools)) {
3267
+ return false;
3268
+ }
3269
+ if (capabilities.allowed_tools.length > 0 && matchesPattern(tool, capabilities.allowed_tools)) {
3270
+ return true;
3271
+ }
3272
+ return capabilities.default_effect === "allow";
3273
+ }
3274
+ function isDomainAllowed(domain, capabilities) {
3275
+ if (!capabilities) {
3276
+ return false;
3277
+ }
3278
+ if (capabilities.denied_domains.length > 0 && matchesDomainPattern(domain, capabilities.denied_domains)) {
3279
+ return false;
3280
+ }
3281
+ if (capabilities.allowed_domains.length > 0 && matchesDomainPattern(domain, capabilities.allowed_domains)) {
3282
+ return true;
3283
+ }
3284
+ return capabilities.default_effect === "allow";
3285
+ }
3286
+ function matchesDomainPattern(domain, patterns) {
3287
+ for (const pattern of patterns) {
3288
+ if (pattern === "*") {
3289
+ return true;
3290
+ }
3291
+ if (pattern.startsWith("*.")) {
3292
+ const suffix = pattern.slice(1);
3293
+ if (domain === pattern.slice(2) || domain.endsWith(suffix)) {
3294
+ return true;
3295
+ }
3296
+ } else if (pattern === domain) {
3297
+ return true;
3298
+ }
3299
+ }
3300
+ return false;
3301
+ }
3302
+ function selectPolicy(criteria, repository, defaultPolicyId) {
3303
+ const candidatePolicies = [];
3304
+ const scoredPolicies = [];
3305
+ const policies = getAllPoliciesFromRepository(repository);
3306
+ for (const [policyId, policy] of policies) {
3307
+ candidatePolicies.push(policyId);
3308
+ const appliesToResult = checkAppliesTo(policy.applies_to, criteria.assetId);
3309
+ if (!appliesToResult.applies) {
3310
+ continue;
3311
+ }
3312
+ const score = scorePolicy(policy, criteria, appliesToResult.isExplicit);
3313
+ const reason = determineSelectionReason(appliesToResult, score);
3314
+ scoredPolicies.push({ policyId, policy, score, reason });
3315
+ }
3316
+ scoredPolicies.sort((a, b) => b.score.total - a.score.total);
3317
+ if (scoredPolicies.length > 0) {
3318
+ const best = scoredPolicies[0];
3319
+ return {
3320
+ policy: best.policy,
3321
+ policyId: best.policyId,
3322
+ selectionReason: best.reason,
3323
+ candidatePolicies,
3324
+ score: best.score
3325
+ };
3326
+ }
3327
+ if (defaultPolicyId && repository.has(defaultPolicyId)) {
3328
+ const defaultPolicy = repository.get(defaultPolicyId);
3329
+ if (defaultPolicy) {
3330
+ return {
3331
+ policy: defaultPolicy,
3332
+ policyId: defaultPolicyId,
3333
+ selectionReason: "default_policy",
3334
+ candidatePolicies
3335
+ };
3336
+ }
3337
+ }
3338
+ return {
3339
+ policy: null,
3340
+ policyId: null,
3341
+ selectionReason: "no_policy_found",
3342
+ candidatePolicies
3343
+ };
3344
+ }
3345
+ function getAllPoliciesFromRepository(repository) {
3346
+ if (repository instanceof Map) {
3347
+ return repository;
3348
+ }
3349
+ const result = /* @__PURE__ */ new Map();
3350
+ const anyRepo = repository;
3351
+ if (anyRepo.policies instanceof Map) {
3352
+ return anyRepo.policies;
3353
+ }
3354
+ return result;
3355
+ }
3356
+ function checkAppliesTo(appliesTo, assetId) {
3357
+ for (const pattern of appliesTo) {
3358
+ if (pattern === "*") {
3359
+ return { applies: true, isExplicit: false };
3360
+ }
3361
+ if (pattern === assetId) {
3362
+ return { applies: true, isExplicit: true };
3363
+ }
3364
+ if (pattern.endsWith("*") && assetId.startsWith(pattern.slice(0, -1))) {
3365
+ return { applies: true, isExplicit: false };
3366
+ }
3367
+ }
3368
+ return { applies: false, isExplicit: false };
3369
+ }
3370
+ function scorePolicy(policy, criteria, isExplicitMatch) {
3371
+ let total = 0;
3372
+ let explicitMatch = 0;
3373
+ let riskLevelMatch = 0;
3374
+ let tagMatches = 0;
3375
+ if (isExplicitMatch) {
3376
+ explicitMatch = 100;
3377
+ total += 100;
3378
+ }
3379
+ const hasRiskLevelRule = policy.rules.some(
3380
+ (rule) => rule.conditions?.risk_levels?.includes(criteria.riskLevel)
3381
+ );
3382
+ if (hasRiskLevelRule) {
3383
+ riskLevelMatch = 50;
3384
+ total += 50;
3385
+ }
3386
+ const policyTags = policy.metadata?.tags ?? [];
3387
+ const criteriaTags = criteria.tags ?? [];
3388
+ for (const tag of criteriaTags) {
3389
+ if (policyTags.includes(tag)) {
3390
+ tagMatches++;
3391
+ total += 10;
3392
+ }
3393
+ }
3394
+ const maxPriority = Math.max(...policy.rules.map((r) => r.priority ?? 0), 0);
3395
+ total += maxPriority;
3396
+ return {
3397
+ total,
3398
+ explicitMatch,
3399
+ riskLevelMatch,
3400
+ tagMatches,
3401
+ priority: maxPriority
3402
+ };
3403
+ }
3404
+ function determineSelectionReason(appliesToResult, score) {
3405
+ if (appliesToResult.isExplicit) {
3406
+ return "explicit_match";
3407
+ }
3408
+ if (score.riskLevelMatch > 0) {
3409
+ return "risk_level_match";
3410
+ }
3411
+ if (score.tagMatches > 0) {
3412
+ return "tag_match";
3413
+ }
3414
+ return "wildcard_match";
3415
+ }
3416
+ function createPolicySelector(repository, defaultPolicyId, cacheSize = 100) {
3417
+ const cache = /* @__PURE__ */ new Map();
3418
+ let hits = 0;
3419
+ let misses = 0;
3420
+ function getCacheKey(criteria) {
3421
+ return `${criteria.assetId}|${criteria.riskLevel}|${criteria.mode}|${(criteria.tags ?? []).sort().join(",")}|${criteria.environment ?? ""}`;
3422
+ }
3423
+ function select(criteria) {
3424
+ const key = getCacheKey(criteria);
3425
+ if (cache.has(key)) {
3426
+ hits++;
3427
+ return cache.get(key);
3428
+ }
3429
+ misses++;
3430
+ const result = selectPolicy(criteria, repository, defaultPolicyId);
3431
+ if (cache.size >= cacheSize) {
3432
+ const firstKey = cache.keys().next().value;
3433
+ if (firstKey) {
3434
+ cache.delete(firstKey);
3435
+ }
3436
+ }
3437
+ cache.set(key, result);
3438
+ return result;
3439
+ }
3440
+ return {
3441
+ select,
3442
+ clearCache: () => cache.clear(),
3443
+ getCacheStats: () => ({ hits, misses, size: cache.size })
3444
+ };
3445
+ }
3446
+
3447
+ // src/air/index.ts
3448
+ import { z as z3 } from "zod";
3449
+ var AIRVendorSchema = z3.object({
3450
+ /** Vendor identifier (e.g., "openai", "anthropic", "google") */
3451
+ id: z3.string().min(1),
3452
+ /** Human-readable vendor name */
3453
+ name: z3.string().optional(),
3454
+ /** Status of this vendor */
3455
+ status: z3.enum(["approved", "pending", "blocked"]).default("pending"),
3456
+ /** Optional approval ticket ID (Golden Thread) */
3457
+ approval_ticket: z3.string().optional(),
3458
+ /** When approval was granted */
3459
+ approved_at: z3.string().datetime().optional(),
3460
+ /** Who approved this vendor */
3461
+ approved_by: z3.string().email().optional(),
3462
+ /** Expiration date for approval */
3463
+ expires_at: z3.string().datetime().optional(),
3464
+ /** Vendor-specific notes */
3465
+ notes: z3.string().optional()
3466
+ });
3467
+ var AIRModelSchema = z3.object({
3468
+ /** Model identifier (e.g., "gpt-4", "claude-3-opus") */
3469
+ id: z3.string().min(1),
3470
+ /** Vendor that provides this model */
3471
+ vendor_id: z3.string().min(1),
3472
+ /** Human-readable model name */
3473
+ name: z3.string().optional(),
3474
+ /** Model version pattern (supports wildcards like "gpt-4*") */
3475
+ version_pattern: z3.string().optional(),
3476
+ /** Status of this model */
3477
+ status: z3.enum(["approved", "pending", "blocked"]).default("pending"),
3478
+ /** Maximum allowed parameters (for on-premise deployment considerations) */
3479
+ max_parameters: z3.number().positive().optional(),
3480
+ /** Risk level assigned to this model */
3481
+ risk_level: z3.enum(["minimal", "limited", "high", "unacceptable"]).optional(),
3482
+ /** Optional approval ticket ID */
3483
+ approval_ticket: z3.string().optional(),
3484
+ /** When approval was granted */
3485
+ approved_at: z3.string().datetime().optional(),
3486
+ /** Expiration date for approval */
3487
+ expires_at: z3.string().datetime().optional(),
3488
+ /** Model-specific notes */
3489
+ notes: z3.string().optional()
3490
+ });
3491
+ var AIRRegionSchema = z3.object({
3492
+ /** Region code (e.g., "us-east-1", "eu-west-1", "EU", "US") */
3493
+ code: z3.string().min(1),
3494
+ /** Human-readable region name */
3495
+ name: z3.string().optional(),
3496
+ /** Status of this region */
3497
+ status: z3.enum(["allowed", "restricted", "blocked"]).default("allowed"),
3498
+ /** Jurisdictions this region falls under (e.g., ["GDPR", "EU-AI-ACT"]) */
3499
+ jurisdictions: z3.array(z3.string()).default([]),
3500
+ /** Data residency requirements */
3501
+ data_residency: z3.enum(["required", "preferred", "none"]).default("none"),
3502
+ /** Notes about this region */
3503
+ notes: z3.string().optional()
3504
+ });
3505
+ var AIRRegistryConstraintsSchema = z3.object({
3506
+ /** List of approved vendors */
3507
+ allowed_vendors: z3.array(AIRVendorSchema).default([]),
3508
+ /** List of blocked vendors */
3509
+ blocked_vendors: z3.array(z3.string()).default([]),
3510
+ /** List of approved regions */
3511
+ allowed_regions: z3.array(AIRRegionSchema).default([]),
3512
+ /** List of blocked regions */
3513
+ blocked_regions: z3.array(z3.string()).default([]),
3514
+ /** List of approved models */
3515
+ allowed_models: z3.array(AIRModelSchema).default([]),
3516
+ /** List of blocked models (patterns supported) */
3517
+ blocked_models: z3.array(z3.string()).default([]),
3518
+ /** Maximum model parameters allowed */
3519
+ max_model_parameters: z3.number().positive().optional(),
3520
+ /** Require vendor approval before use */
3521
+ require_vendor_approval: z3.boolean().default(true),
3522
+ /** Require model approval before use */
3523
+ require_model_approval: z3.boolean().default(true),
3524
+ /** Default behavior for unknown vendors: "block" or "request_approval" */
3525
+ unknown_vendor_behavior: z3.enum(["block", "request_approval"]).default("request_approval"),
3526
+ /** Default behavior for unknown models */
3527
+ unknown_model_behavior: z3.enum(["block", "request_approval"]).default("request_approval")
3528
+ });
3529
+ var AIRPIIFilterConfigSchema = z3.object({
3530
+ /** Whether PII filtering is enabled */
3531
+ enabled: z3.boolean().default(false),
3532
+ /** PII types to filter (e.g., ["email", "phone", "ssn", "credit_card"]) */
3533
+ filter_types: z3.array(z3.string()).default([]),
3534
+ /** Action when PII is detected: "redact", "block", "warn", "audit" */
3535
+ action: z3.enum(["redact", "block", "warn", "audit"]).default("warn"),
3536
+ /** Custom patterns to detect (regex) */
3537
+ custom_patterns: z3.array(z3.object({
3538
+ name: z3.string(),
3539
+ pattern: z3.string(),
3540
+ action: z3.enum(["redact", "block", "warn", "audit"]).optional()
3541
+ })).default([])
3542
+ });
3543
+ var AIRToxicityFilterConfigSchema = z3.object({
3544
+ /** Whether toxicity filtering is enabled */
3545
+ enabled: z3.boolean().default(false),
3546
+ /** Toxicity threshold (0-1) */
3547
+ threshold: z3.number().min(0).max(1).default(0.7),
3548
+ /** Categories to filter (e.g., ["hate", "violence", "sexual"]) */
3549
+ categories: z3.array(z3.string()).default([]),
3550
+ /** Action when toxicity is detected */
3551
+ action: z3.enum(["block", "warn", "audit"]).default("warn")
3552
+ });
3553
+ var AIRRuntimeConstraintsSchema = z3.object({
3554
+ /** PII filtering configuration */
3555
+ pii_filter: AIRPIIFilterConfigSchema.optional(),
3556
+ /** Toxicity filtering configuration */
3557
+ toxicity_filter: AIRToxicityFilterConfigSchema.optional(),
3558
+ /** Data retention period in days (0 = no retention) */
3559
+ data_retention_days: z3.number().int().min(0).default(90),
3560
+ /** Whether to enable output watermarking */
3561
+ watermark_enabled: z3.boolean().default(false),
3562
+ /** Logging level: "none", "errors", "all" */
3563
+ logging_level: z3.enum(["none", "errors", "all"]).default("all"),
3564
+ /** Maximum tokens per request */
3565
+ max_tokens_per_request: z3.number().int().positive().optional(),
3566
+ /** Maximum requests per minute */
3567
+ max_requests_per_minute: z3.number().int().positive().optional(),
3568
+ /** Maximum cost per request in USD */
3569
+ max_cost_per_request_usd: z3.number().positive().optional(),
3570
+ /** Maximum cost per day in USD */
3571
+ max_cost_per_day_usd: z3.number().positive().optional(),
3572
+ /** Session timeout in seconds */
3573
+ session_timeout_seconds: z3.number().int().positive().optional(),
3574
+ /** Require human approval for specific actions */
3575
+ human_approval_required: z3.array(z3.string()).default([]),
3576
+ /** Kill switch configuration */
3577
+ kill_switch: z3.object({
3578
+ enabled: z3.boolean().default(true),
3579
+ channel: z3.enum(["sse", "polling", "file"]).default("sse"),
3580
+ poll_interval_ms: z3.number().int().positive().default(5e3)
3581
+ }).optional(),
3582
+ /** Grounding check configuration (prevent hallucination) */
3583
+ grounding_check: z3.object({
3584
+ enabled: z3.boolean().default(false),
3585
+ confidence_threshold: z3.number().min(0).max(1).default(0.8),
3586
+ action: z3.enum(["block", "warn", "audit"]).default("warn")
3587
+ }).optional()
3588
+ });
3589
+ var AIRBuildConstraintsSchema = z3.object({
3590
+ /** Require Golden Thread linkage (business justification) */
3591
+ require_golden_thread: z3.boolean().default(true),
3592
+ /** Require asset card for all AI assets */
3593
+ require_asset_card: z3.boolean().default(true),
3594
+ /** Require risk classification */
3595
+ require_risk_classification: z3.boolean().default(true),
3596
+ /** Require model card documentation */
3597
+ require_model_card: z3.boolean().default(false),
3598
+ /** Require security review for high-risk assets */
3599
+ require_security_review: z3.boolean().default(false),
3600
+ /** Minimum risk levels that require security review */
3601
+ security_review_risk_levels: z3.array(z3.enum(["high", "unacceptable"])).default(["high", "unacceptable"]),
3602
+ /** Require governance.lock file */
3603
+ require_governance_lock: z3.boolean().default(true),
3604
+ /** governance.lock must be signed */
3605
+ require_lock_signature: z3.boolean().default(false),
3606
+ /** Block merge on validation failure */
3607
+ block_on_failure: z3.boolean().default(true),
3608
+ /** Generate SARIF report for GitHub Security tab */
3609
+ generate_sarif: z3.boolean().default(true),
3610
+ /** Required approvals before deployment */
3611
+ required_approvals: z3.array(z3.object({
3612
+ role: z3.string(),
3613
+ count: z3.number().int().positive().default(1)
3614
+ })).default([]),
3615
+ /** Allowed deployment environments */
3616
+ allowed_environments: z3.array(z3.string()).default(["development", "staging", "production"]),
3617
+ /** Environment-specific constraints */
3618
+ environment_constraints: z3.record(z3.object({
3619
+ require_approval: z3.boolean().default(false),
3620
+ approvers: z3.array(z3.string()).default([]),
3621
+ require_testing: z3.boolean().default(false),
3622
+ test_coverage_threshold: z3.number().min(0).max(100).optional()
3623
+ })).optional()
3624
+ });
3625
+ var AIRPolicySourceSchema = z3.object({
3626
+ /** Unique identifier for this source */
3627
+ id: z3.string().min(1),
3628
+ /** Type of source: "pdf", "url", "confluence", "jira", "manual" */
3629
+ type: z3.enum(["pdf", "url", "confluence", "jira", "manual"]),
3630
+ /** URI to the source document */
3631
+ uri: z3.string(),
3632
+ /** SHA-256 hash of the source content */
3633
+ content_hash: z3.string().regex(/^sha256:[a-f0-9]{64}$/),
3634
+ /** When the source was last fetched */
3635
+ fetched_at: z3.string().datetime(),
3636
+ /** Title of the policy document */
3637
+ title: z3.string().optional(),
3638
+ /** Version of the policy document */
3639
+ version: z3.string().optional(),
3640
+ /** Confidence score of extraction (0-1) */
3641
+ extraction_confidence: z3.number().min(0).max(1).optional()
3642
+ });
3643
+ var AIRMetadataSchema = z3.object({
3644
+ /** When this AIR was generated */
3645
+ generated_at: z3.string().datetime(),
3646
+ /** Tool/system that generated this AIR */
3647
+ generated_by: z3.string().default("aigrc-policy-compiler"),
3648
+ /** Version of the policy compiler */
3649
+ compiler_version: z3.string(),
3650
+ /** Organization this AIR belongs to */
3651
+ organization: z3.string().optional(),
3652
+ /** Environment this AIR is for (e.g., "production", "staging") */
3653
+ environment: z3.string().optional(),
3654
+ /** Human-readable description */
3655
+ description: z3.string().optional(),
3656
+ /** Tags for categorization */
3657
+ tags: z3.array(z3.string()).default([]),
3658
+ /** Custom metadata fields */
3659
+ custom: z3.record(z3.unknown()).optional()
3660
+ });
3661
+ var AIRSchema = z3.object({
3662
+ /** Schema version for forward compatibility */
3663
+ version: z3.literal("1.0"),
3664
+ /** Unique identifier for this AIR */
3665
+ id: z3.string().uuid(),
3666
+ /** Human-readable name */
3667
+ name: z3.string().min(1).max(200),
3668
+ /** SHA-256 hash of this AIR (computed after serialization) */
3669
+ hash: z3.string().regex(/^sha256:[a-f0-9]{64}$/).optional(),
3670
+ /** Policy sources that contributed to this AIR */
3671
+ policy_sources: z3.array(AIRPolicySourceSchema).default([]),
3672
+ /** Registry constraints (vendor/model/region governance) */
3673
+ registry: AIRRegistryConstraintsSchema.default({}),
3674
+ /** Runtime constraints (execution-time governance) */
3675
+ runtime: AIRRuntimeConstraintsSchema.default({}),
3676
+ /** Build constraints (CI/CD governance) */
3677
+ build: AIRBuildConstraintsSchema.default({}),
3678
+ /** Metadata about this AIR */
3679
+ metadata: AIRMetadataSchema,
3680
+ /** When this AIR expires (forces re-compilation) */
3681
+ expires_at: z3.string().datetime().optional(),
3682
+ /** Digital signatures for verification */
3683
+ signatures: z3.array(z3.object({
3684
+ /** Signer identity (email or system ID) */
3685
+ signer: z3.string(),
3686
+ /** Algorithm used (RS256, ES256) */
3687
+ algorithm: z3.enum(["RS256", "ES256"]),
3688
+ /** Base64-encoded signature */
3689
+ signature: z3.string(),
3690
+ /** When the signature was created */
3691
+ signed_at: z3.string().datetime(),
3692
+ /** Key ID for verification */
3693
+ key_id: z3.string().optional()
3694
+ })).default([])
3695
+ });
3696
+ function createEmptyAIR(name, compilerVersion = "1.0.0") {
3697
+ return {
3698
+ version: "1.0",
3699
+ id: crypto.randomUUID(),
3700
+ name,
3701
+ policy_sources: [],
3702
+ registry: {
3703
+ allowed_vendors: [],
3704
+ blocked_vendors: [],
3705
+ allowed_regions: [],
3706
+ blocked_regions: [],
3707
+ allowed_models: [],
3708
+ blocked_models: [],
3709
+ require_vendor_approval: true,
3710
+ require_model_approval: true,
3711
+ unknown_vendor_behavior: "request_approval",
3712
+ unknown_model_behavior: "request_approval"
3713
+ },
3714
+ runtime: {
3715
+ data_retention_days: 90,
3716
+ watermark_enabled: false,
3717
+ logging_level: "all",
3718
+ human_approval_required: []
3719
+ },
3720
+ build: {
3721
+ require_golden_thread: true,
3722
+ require_asset_card: true,
3723
+ require_risk_classification: true,
3724
+ require_model_card: false,
3725
+ require_security_review: false,
3726
+ security_review_risk_levels: ["high", "unacceptable"],
3727
+ require_governance_lock: true,
3728
+ require_lock_signature: false,
3729
+ block_on_failure: true,
3730
+ generate_sarif: true,
3731
+ required_approvals: [],
3732
+ allowed_environments: ["development", "staging", "production"]
3733
+ },
3734
+ metadata: {
3735
+ generated_at: (/* @__PURE__ */ new Date()).toISOString(),
3736
+ generated_by: "aigrc-policy-compiler",
3737
+ compiler_version: compilerVersion,
3738
+ tags: []
3739
+ },
3740
+ signatures: []
3741
+ };
3742
+ }
3743
+ function validateAIR(air) {
3744
+ const result = AIRSchema.safeParse(air);
3745
+ if (result.success) {
3746
+ return { valid: true, errors: [] };
3747
+ }
3748
+ return {
3749
+ valid: false,
3750
+ errors: result.error.errors.map((e) => `${e.path.join(".")}: ${e.message}`)
3751
+ };
3752
+ }
3753
+ function isVendorAllowed(vendorId, registry2) {
3754
+ if (registry2.blocked_vendors.includes(vendorId)) {
3755
+ return { allowed: false, reason: "Vendor is blocked", requiresApproval: false };
3756
+ }
3757
+ const allowedVendor = registry2.allowed_vendors.find((v) => v.id === vendorId);
3758
+ if (allowedVendor) {
3759
+ if (allowedVendor.status === "approved") {
3760
+ if (allowedVendor.expires_at && new Date(allowedVendor.expires_at) < /* @__PURE__ */ new Date()) {
3761
+ return { allowed: false, reason: "Vendor approval has expired", requiresApproval: true };
3762
+ }
3763
+ return { allowed: true, reason: "Vendor is approved", requiresApproval: false };
3764
+ }
3765
+ if (allowedVendor.status === "pending") {
3766
+ return { allowed: false, reason: "Vendor approval is pending", requiresApproval: true };
3767
+ }
3768
+ return { allowed: false, reason: "Vendor is blocked", requiresApproval: false };
3769
+ }
3770
+ if (registry2.unknown_vendor_behavior === "block") {
3771
+ return { allowed: false, reason: "Unknown vendor (blocked by policy)", requiresApproval: false };
3772
+ }
3773
+ return { allowed: false, reason: "Unknown vendor (requires approval)", requiresApproval: true };
3774
+ }
3775
+ function isModelAllowed(modelId, vendorId, registry2) {
3776
+ for (const pattern of registry2.blocked_models) {
3777
+ if (matchesPattern2(modelId, pattern)) {
3778
+ return { allowed: false, reason: `Model matches blocked pattern: ${pattern}`, requiresApproval: false };
3779
+ }
3780
+ }
3781
+ const allowedModel = registry2.allowed_models.find(
3782
+ (m) => m.id === modelId && m.vendor_id === vendorId
3783
+ );
3784
+ if (allowedModel) {
3785
+ if (allowedModel.status === "approved") {
3786
+ if (allowedModel.expires_at && new Date(allowedModel.expires_at) < /* @__PURE__ */ new Date()) {
3787
+ return { allowed: false, reason: "Model approval has expired", requiresApproval: true };
3788
+ }
3789
+ return { allowed: true, reason: "Model is approved", requiresApproval: false };
3790
+ }
3791
+ if (allowedModel.status === "pending") {
3792
+ return { allowed: false, reason: "Model approval is pending", requiresApproval: true };
3793
+ }
3794
+ return { allowed: false, reason: "Model is blocked", requiresApproval: false };
3795
+ }
3796
+ const matchingModel = registry2.allowed_models.find(
3797
+ (m) => m.vendor_id === vendorId && m.version_pattern && matchesPattern2(modelId, m.version_pattern)
3798
+ );
3799
+ if (matchingModel && matchingModel.status === "approved") {
3800
+ return { allowed: true, reason: `Model matches approved pattern: ${matchingModel.version_pattern}`, requiresApproval: false };
3801
+ }
3802
+ if (registry2.unknown_model_behavior === "block") {
3803
+ return { allowed: false, reason: "Unknown model (blocked by policy)", requiresApproval: false };
3804
+ }
3805
+ return { allowed: false, reason: "Unknown model (requires approval)", requiresApproval: true };
3806
+ }
3807
+ function isRegionAllowed(regionCode, registry2) {
3808
+ if (registry2.blocked_regions.includes(regionCode)) {
3809
+ return { allowed: false, reason: "Region is blocked", dataResidency: "none" };
3810
+ }
3811
+ const allowedRegion = registry2.allowed_regions.find((r) => r.code === regionCode);
3812
+ if (allowedRegion) {
3813
+ if (allowedRegion.status === "blocked") {
3814
+ return { allowed: false, reason: "Region is blocked", dataResidency: "none" };
3815
+ }
3816
+ if (allowedRegion.status === "restricted") {
3817
+ return { allowed: true, reason: "Region is restricted (requires approval)", dataResidency: allowedRegion.data_residency };
3818
+ }
3819
+ return { allowed: true, reason: "Region is allowed", dataResidency: allowedRegion.data_residency };
3820
+ }
3821
+ if (registry2.allowed_regions.length === 0) {
3822
+ return { allowed: true, reason: "No region restrictions", dataResidency: "none" };
3823
+ }
3824
+ return { allowed: false, reason: "Region not in allowed list", dataResidency: "none" };
3825
+ }
3826
+ function matchesPattern2(value, pattern) {
3827
+ if (pattern === "*") {
3828
+ return true;
3829
+ }
3830
+ if (pattern.endsWith("*")) {
3831
+ return value.startsWith(pattern.slice(0, -1));
3832
+ }
3833
+ if (pattern.startsWith("*")) {
3834
+ return value.endsWith(pattern.slice(1));
3835
+ }
3836
+ return value === pattern;
3837
+ }
3838
+
3839
+ // src/governance-lock/index.ts
3840
+ import { z as z4 } from "zod";
3841
+ import * as yaml2 from "yaml";
3842
+ var GovernanceLockSignatureSchema = z4.object({
3843
+ /** Signer identity (email or system ID) */
3844
+ signer: z4.string().min(1),
3845
+ /** Role of the signer (e.g., "CISO", "PolicyOwner", "SecurityLead") */
3846
+ role: z4.string().optional(),
3847
+ /** Algorithm used: RS256 (RSA-SHA256) or ES256 (ECDSA-P256) */
3848
+ algorithm: z4.enum(["RS256", "ES256"]),
3849
+ /** Base64-encoded signature */
3850
+ signature: z4.string().min(1),
3851
+ /** When the signature was created */
3852
+ signed_at: z4.string().datetime(),
3853
+ /** Key ID for key rotation support */
3854
+ key_id: z4.string().optional(),
3855
+ /** Expiration of this signature (optional, separate from lock expiration) */
3856
+ expires_at: z4.string().datetime().optional(),
3857
+ /** Certificate chain for verification (optional) */
3858
+ certificate_chain: z4.array(z4.string()).optional()
3859
+ });
3860
+ var GovernanceLockPolicySourceSchema = z4.object({
3861
+ /** Unique identifier for this source */
3862
+ id: z4.string().min(1),
3863
+ /** Type of source */
3864
+ type: z4.enum(["pdf", "url", "confluence", "jira", "manual"]),
3865
+ /** URI to the source document */
3866
+ uri: z4.string(),
3867
+ /** SHA-256 hash of the source content at time of compilation */
3868
+ content_hash: z4.string().regex(/^sha256:[a-f0-9]{64}$/),
3869
+ /** When the source was fetched */
3870
+ fetched_at: z4.string().datetime(),
3871
+ /** Title of the policy document */
3872
+ title: z4.string().optional(),
3873
+ /** Version of the policy document */
3874
+ version: z4.string().optional()
3875
+ });
3876
+ var GovernanceLockRegistryConstraintsSchema = z4.object({
3877
+ /** List of approved vendor IDs */
3878
+ allowed_vendor_ids: z4.array(z4.string()).default([]),
3879
+ /** List of blocked vendor IDs */
3880
+ blocked_vendor_ids: z4.array(z4.string()).default([]),
3881
+ /** List of approved region codes */
3882
+ allowed_region_codes: z4.array(z4.string()).default([]),
3883
+ /** List of blocked region codes */
3884
+ blocked_region_codes: z4.array(z4.string()).default([]),
3885
+ /** List of approved model patterns */
3886
+ allowed_model_patterns: z4.array(z4.string()).default([]),
3887
+ /** List of blocked model patterns */
3888
+ blocked_model_patterns: z4.array(z4.string()).default([]),
3889
+ /** Maximum model parameters allowed */
3890
+ max_model_parameters: z4.number().positive().optional()
3891
+ });
3892
+ var GovernanceLockRuntimeConstraintsSchema = z4.object({
3893
+ /** Whether PII filtering is required */
3894
+ pii_filter_enabled: z4.boolean().default(false),
3895
+ /** PII filter action */
3896
+ pii_filter_action: z4.enum(["redact", "block", "warn", "audit"]).optional(),
3897
+ /** Whether toxicity filtering is required */
3898
+ toxicity_filter_enabled: z4.boolean().default(false),
3899
+ /** Toxicity threshold */
3900
+ toxicity_threshold: z4.number().min(0).max(1).optional(),
3901
+ /** Data retention period in days */
3902
+ data_retention_days: z4.number().int().min(0).default(90),
3903
+ /** Whether watermarking is required */
3904
+ watermark_enabled: z4.boolean().default(false),
3905
+ /** Logging level */
3906
+ logging_level: z4.enum(["none", "errors", "all"]).default("all"),
3907
+ /** Maximum tokens per request */
3908
+ max_tokens_per_request: z4.number().int().positive().optional(),
3909
+ /** Maximum cost per day in USD */
3910
+ max_cost_per_day_usd: z4.number().positive().optional(),
3911
+ /** Kill switch enabled */
3912
+ kill_switch_enabled: z4.boolean().default(true)
3913
+ });
3914
+ var GovernanceLockBuildConstraintsSchema = z4.object({
3915
+ /** Require Golden Thread linkage */
3916
+ require_golden_thread: z4.boolean().default(true),
3917
+ /** Require asset card */
3918
+ require_asset_card: z4.boolean().default(true),
3919
+ /** Require risk classification */
3920
+ require_risk_classification: z4.boolean().default(true),
3921
+ /** Require model card */
3922
+ require_model_card: z4.boolean().default(false),
3923
+ /** Require security review for high risk */
3924
+ require_security_review: z4.boolean().default(false),
3925
+ /** Block merge on validation failure */
3926
+ block_on_failure: z4.boolean().default(true),
3927
+ /** Generate SARIF report */
3928
+ generate_sarif: z4.boolean().default(true),
3929
+ /** Allowed environments */
3930
+ allowed_environments: z4.array(z4.string()).default(["development", "staging", "production"])
3931
+ });
3932
+ var GovernanceLockConstraintsSchema = z4.object({
3933
+ /** Registry constraints (vendor/model/region) */
3934
+ registry: GovernanceLockRegistryConstraintsSchema.default({}),
3935
+ /** Runtime constraints */
3936
+ runtime: GovernanceLockRuntimeConstraintsSchema.default({}),
3937
+ /** Build constraints */
3938
+ build: GovernanceLockBuildConstraintsSchema.default({})
3939
+ });
3940
+ var GovernanceLockSchema = z4.object({
3941
+ /** Schema version for forward compatibility */
3942
+ version: z4.literal("1.0"),
3943
+ /** When this lock file was generated */
3944
+ generated_at: z4.string().datetime(),
3945
+ /** SHA-256 hash of the compiled policy (AIR) */
3946
+ policy_hash: z4.string().regex(/^sha256:[a-f0-9]{64}$/),
3947
+ /** Name of this policy lock */
3948
+ name: z4.string().min(1).max(200).optional(),
3949
+ /** Description of this lock file */
3950
+ description: z4.string().max(500).optional(),
3951
+ /** Policy sources that contributed to this lock */
3952
+ policy_sources: z4.array(GovernanceLockPolicySourceSchema).default([]),
3953
+ /** Compiled constraints (subset of AIR) */
3954
+ constraints: GovernanceLockConstraintsSchema.default({}),
3955
+ /** Digital signatures from policy owners */
3956
+ signatures: z4.array(GovernanceLockSignatureSchema).default([]),
3957
+ /** When this lock file expires (forces re-compilation) */
3958
+ expires_at: z4.string().datetime(),
3959
+ /** Tool/system that generated this lock */
3960
+ generated_by: z4.string().default("aigrc-policy-compiler"),
3961
+ /** Version of the generator */
3962
+ generator_version: z4.string().default("1.0.0"),
3963
+ /** Organization this lock belongs to */
3964
+ organization: z4.string().optional(),
3965
+ /** Environment this lock is for */
3966
+ environment: z4.string().optional(),
3967
+ /** Reference to the full AIR document (optional) */
3968
+ air_reference: z4.object({
3969
+ /** AIR document ID */
3970
+ id: z4.string().uuid(),
3971
+ /** AIR document location (URI) */
3972
+ location: z4.string().optional(),
3973
+ /** AIR document hash */
3974
+ hash: z4.string().regex(/^sha256:[a-f0-9]{64}$/)
3975
+ }).optional(),
3976
+ /** Custom metadata fields */
3977
+ metadata: z4.record(z4.unknown()).optional()
3978
+ });
3979
+ async function computeHash(data) {
3980
+ const encoder = new TextEncoder();
3981
+ const dataBuffer = encoder.encode(data);
3982
+ const hashBuffer = await crypto.subtle.digest("SHA-256", dataBuffer);
3983
+ const hashArray = Array.from(new Uint8Array(hashBuffer));
3984
+ const hashHex = hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
3985
+ return `sha256:${hashHex}`;
3986
+ }
3987
+ async function createGovernanceLock(air, options = {}) {
3988
+ const now = /* @__PURE__ */ new Date();
3989
+ const expiresAt = new Date(now);
3990
+ expiresAt.setDate(expiresAt.getDate() + (options.expiresInDays ?? 30));
3991
+ const airForHashing = { ...air, signatures: [] };
3992
+ const policyHash = await computeHash(JSON.stringify(airForHashing));
3993
+ const constraints = {
3994
+ registry: {
3995
+ allowed_vendor_ids: air.registry.allowed_vendors.map((v) => v.id),
3996
+ blocked_vendor_ids: air.registry.blocked_vendors,
3997
+ allowed_region_codes: air.registry.allowed_regions.map((r) => r.code),
3998
+ blocked_region_codes: air.registry.blocked_regions,
3999
+ allowed_model_patterns: air.registry.allowed_models.map((m) => m.version_pattern ?? m.id),
4000
+ blocked_model_patterns: air.registry.blocked_models,
4001
+ max_model_parameters: air.registry.max_model_parameters
4002
+ },
4003
+ runtime: {
4004
+ pii_filter_enabled: air.runtime.pii_filter?.enabled ?? false,
4005
+ pii_filter_action: air.runtime.pii_filter?.action,
4006
+ toxicity_filter_enabled: air.runtime.toxicity_filter?.enabled ?? false,
4007
+ toxicity_threshold: air.runtime.toxicity_filter?.threshold,
4008
+ data_retention_days: air.runtime.data_retention_days,
4009
+ watermark_enabled: air.runtime.watermark_enabled,
4010
+ logging_level: air.runtime.logging_level,
4011
+ max_tokens_per_request: air.runtime.max_tokens_per_request,
4012
+ max_cost_per_day_usd: air.runtime.max_cost_per_day_usd,
4013
+ kill_switch_enabled: air.runtime.kill_switch?.enabled ?? true
4014
+ },
4015
+ build: {
4016
+ require_golden_thread: air.build.require_golden_thread,
4017
+ require_asset_card: air.build.require_asset_card,
4018
+ require_risk_classification: air.build.require_risk_classification,
4019
+ require_model_card: air.build.require_model_card,
4020
+ require_security_review: air.build.require_security_review,
4021
+ block_on_failure: air.build.block_on_failure,
4022
+ generate_sarif: air.build.generate_sarif,
4023
+ allowed_environments: air.build.allowed_environments
4024
+ }
4025
+ };
4026
+ const policySources = air.policy_sources.map((s) => ({
4027
+ id: s.id,
4028
+ type: s.type,
4029
+ uri: s.uri,
4030
+ content_hash: s.content_hash,
4031
+ fetched_at: s.fetched_at,
4032
+ title: s.title,
4033
+ version: s.version
4034
+ }));
4035
+ return {
4036
+ version: "1.0",
4037
+ generated_at: now.toISOString(),
4038
+ policy_hash: policyHash,
4039
+ name: options.name ?? air.name,
4040
+ description: options.description,
4041
+ policy_sources: policySources,
4042
+ constraints,
4043
+ signatures: [],
4044
+ expires_at: expiresAt.toISOString(),
4045
+ generated_by: air.metadata.generated_by,
4046
+ generator_version: air.metadata.compiler_version,
4047
+ organization: options.organization ?? air.metadata.organization,
4048
+ environment: options.environment ?? air.metadata.environment,
4049
+ air_reference: {
4050
+ id: air.id,
4051
+ hash: policyHash
4052
+ }
4053
+ };
4054
+ }
4055
+ function validateGovernanceLock(lock, options = {}) {
4056
+ const errors = [];
4057
+ const warnings = [];
4058
+ const parseResult = GovernanceLockSchema.safeParse(lock);
4059
+ if (!parseResult.success) {
4060
+ return {
4061
+ valid: false,
4062
+ errors: parseResult.error.errors.map((e) => `${e.path.join(".")}: ${e.message}`),
4063
+ warnings: [],
4064
+ expired: false,
4065
+ daysUntilExpiration: 0,
4066
+ signed: false,
4067
+ validSignatureCount: 0,
4068
+ policyHashValid: false
4069
+ };
4070
+ }
4071
+ const parsed = parseResult.data;
4072
+ const now = /* @__PURE__ */ new Date();
4073
+ const expiresAt = new Date(parsed.expires_at);
4074
+ const daysUntilExpiration = Math.ceil((expiresAt.getTime() - now.getTime()) / (1e3 * 60 * 60 * 24));
4075
+ const expired = expiresAt < now;
4076
+ if (options.checkExpiration !== false && expired) {
4077
+ errors.push(`Lock file expired on ${parsed.expires_at}`);
4078
+ }
4079
+ if (daysUntilExpiration > 0 && daysUntilExpiration <= 7) {
4080
+ warnings.push(`Lock file expires in ${daysUntilExpiration} days`);
4081
+ }
4082
+ const signed = parsed.signatures.length > 0;
4083
+ if (options.requireSignatures && !signed) {
4084
+ errors.push("Lock file requires at least one signature");
4085
+ }
4086
+ let validSignatureCount = 0;
4087
+ for (const sig of parsed.signatures) {
4088
+ if (sig.expires_at) {
4089
+ const sigExpiresAt = new Date(sig.expires_at);
4090
+ if (sigExpiresAt < now) {
4091
+ warnings.push(`Signature from ${sig.signer} has expired`);
4092
+ } else {
4093
+ validSignatureCount++;
4094
+ }
4095
+ } else {
4096
+ validSignatureCount++;
4097
+ }
4098
+ }
4099
+ let policyHashValid = true;
4100
+ if (options.expectedPolicyHash) {
4101
+ if (parsed.policy_hash !== options.expectedPolicyHash) {
4102
+ errors.push(`Policy hash mismatch: expected ${options.expectedPolicyHash}, got ${parsed.policy_hash}`);
4103
+ policyHashValid = false;
4104
+ }
4105
+ }
4106
+ return {
4107
+ valid: errors.length === 0,
4108
+ errors,
4109
+ warnings,
4110
+ expired,
4111
+ daysUntilExpiration,
4112
+ signed,
4113
+ validSignatureCount,
4114
+ policyHashValid
4115
+ };
4116
+ }
4117
+ function parseGovernanceLockYAML(content) {
4118
+ const parsed = yaml2.parse(content);
4119
+ return GovernanceLockSchema.parse(parsed);
4120
+ }
4121
+ function parseGovernanceLockJSON(content) {
4122
+ const parsed = JSON.parse(content);
4123
+ return GovernanceLockSchema.parse(parsed);
4124
+ }
4125
+ function serializeGovernanceLockYAML(lock) {
4126
+ return yaml2.stringify(lock, {
4127
+ indent: 2,
4128
+ lineWidth: 120
4129
+ });
4130
+ }
4131
+ function serializeGovernanceLockJSON(lock, pretty = true) {
4132
+ return pretty ? JSON.stringify(lock, null, 2) : JSON.stringify(lock);
4133
+ }
4134
+ function isGovernanceLockExpired(lock) {
4135
+ return new Date(lock.expires_at) < /* @__PURE__ */ new Date();
4136
+ }
4137
+ function getDaysUntilExpiration(lock) {
4138
+ const now = /* @__PURE__ */ new Date();
4139
+ const expiresAt = new Date(lock.expires_at);
4140
+ return Math.ceil((expiresAt.getTime() - now.getTime()) / (1e3 * 60 * 60 * 24));
4141
+ }
4142
+ function isVendorAllowedByLock(vendorId, lock) {
4143
+ const { registry: registry2 } = lock.constraints;
4144
+ if (registry2.blocked_vendor_ids.includes(vendorId)) {
4145
+ return false;
4146
+ }
4147
+ if (registry2.allowed_vendor_ids.length > 0) {
4148
+ return registry2.allowed_vendor_ids.includes(vendorId);
4149
+ }
4150
+ return true;
4151
+ }
4152
+ function isModelAllowedByLock(modelId, lock) {
4153
+ const { registry: registry2 } = lock.constraints;
4154
+ for (const pattern of registry2.blocked_model_patterns) {
4155
+ if (matchesPattern3(modelId, pattern)) {
4156
+ return false;
4157
+ }
4158
+ }
4159
+ if (registry2.allowed_model_patterns.length > 0) {
4160
+ return registry2.allowed_model_patterns.some(
4161
+ (pattern) => matchesPattern3(modelId, pattern)
4162
+ );
4163
+ }
4164
+ return true;
4165
+ }
4166
+ function isRegionAllowedByLock(regionCode, lock) {
4167
+ const { registry: registry2 } = lock.constraints;
4168
+ if (registry2.blocked_region_codes.includes(regionCode)) {
4169
+ return false;
4170
+ }
4171
+ if (registry2.allowed_region_codes.length > 0) {
4172
+ return registry2.allowed_region_codes.includes(regionCode);
4173
+ }
4174
+ return true;
4175
+ }
4176
+ function matchesPattern3(value, pattern) {
4177
+ if (pattern === "*") {
4178
+ return true;
4179
+ }
4180
+ if (pattern.endsWith("*")) {
4181
+ return value.startsWith(pattern.slice(0, -1));
4182
+ }
4183
+ if (pattern.startsWith("*")) {
4184
+ return value.endsWith(pattern.slice(1));
4185
+ }
4186
+ return value === pattern;
4187
+ }
4188
+ function createSigningPayload(lock) {
4189
+ const forSigning = {
4190
+ version: lock.version,
4191
+ generated_at: lock.generated_at,
4192
+ policy_hash: lock.policy_hash,
4193
+ expires_at: lock.expires_at,
4194
+ constraints: lock.constraints
4195
+ };
4196
+ return JSON.stringify(forSigning);
4197
+ }
4198
+ function addSignature(lock, signature) {
4199
+ return {
4200
+ ...lock,
4201
+ signatures: [...lock.signatures, signature]
4202
+ };
4203
+ }
4204
+
2197
4205
  // src/utils.ts
2198
4206
  function formatDate(date) {
2199
4207
  return date.toISOString();
@@ -2205,60 +4213,164 @@ function slugify(text) {
2205
4213
  return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "");
2206
4214
  }
2207
4215
  export {
4216
+ AIRBuildConstraintsSchema,
4217
+ AIRMetadataSchema,
4218
+ AIRModelSchema,
4219
+ AIRPIIFilterConfigSchema,
4220
+ AIRPolicySourceSchema,
4221
+ AIRRegionSchema,
4222
+ AIRRegistryConstraintsSchema,
4223
+ AIRRuntimeConstraintsSchema,
4224
+ AIRSchema,
4225
+ AIRToxicityFilterConfigSchema,
4226
+ AIRVendorSchema,
4227
+ AigrcConfigSchema,
4228
+ AigrcIntegrationsConfigSchema,
4229
+ AigrcRuntimeConfigSchema,
2208
4230
  ApprovalSchema,
4231
+ AssetCardRuntimeSchema,
2209
4232
  AssetCardSchema,
4233
+ CONFIG_ENV_VAR,
4234
+ CONFIG_FILE_NAMES,
4235
+ CapabilitiesManifestSchema,
2210
4236
  ClassificationSchema,
2211
4237
  ConfidenceLevelSchema,
2212
4238
  ConstraintsSchema,
2213
4239
  ControlStatusSchema,
2214
4240
  DetectionStrategySchema,
2215
4241
  FrameworkCategorySchema,
4242
+ GoldenThreadSchema,
4243
+ GovernanceLockBuildConstraintsSchema,
4244
+ GovernanceLockConstraintsSchema,
4245
+ GovernanceLockPolicySourceSchema,
4246
+ GovernanceLockRegistryConstraintsSchema,
4247
+ GovernanceLockRuntimeConstraintsSchema,
4248
+ GovernanceLockSchema,
4249
+ GovernanceLockSignatureSchema,
2216
4250
  GovernanceSchema,
4251
+ GovernanceTokenCapabilityClaimsSchema,
4252
+ GovernanceTokenControlClaimsSchema,
4253
+ GovernanceTokenGovernanceClaimsSchema,
4254
+ GovernanceTokenIdentityClaimsSchema,
4255
+ GovernanceTokenLineageClaimsSchema,
4256
+ GovernanceTokenPayloadSchema,
2217
4257
  IntentSchema,
2218
4258
  JurisdictionClassificationSchema,
4259
+ KillSwitchCommandSchema,
4260
+ KillSwitchCommandTypeSchema,
4261
+ LineageSchema,
4262
+ MAX_INHERITANCE_DEPTH,
2219
4263
  MODEL_EXTENSIONS,
4264
+ OperatingModeSchema,
2220
4265
  OwnerSchema,
4266
+ PolicyCapabilitiesSchema,
4267
+ PolicyFileSchema,
4268
+ PolicyResolutionError,
4269
+ PolicyRuleEffectSchema,
4270
+ PolicyRuleSchema,
2221
4271
  RiskFactorsSchema,
4272
+ RiskLevelSchema,
4273
+ RuntimeIdentitySchema,
2222
4274
  TechnicalSchema,
2223
4275
  TrustworthinessCharacteristicSchema,
2224
4276
  TrustworthinessSchema,
2225
4277
  addJurisdiction,
4278
+ addSignature,
2226
4279
  analyzeImports,
2227
4280
  applyImplicationChains,
2228
4281
  classifyRisk,
2229
4282
  clearRegistry,
4283
+ compareRiskLevels,
4284
+ computeCanonicalString,
4285
+ computeGoldenThreadHash,
4286
+ computeGoldenThreadHashSync,
4287
+ computeHash,
2230
4288
  createAssetCard,
4289
+ createDefaultConfig,
4290
+ createEmptyAIR,
4291
+ createGoldenThread,
4292
+ createGoldenThreadSync,
4293
+ createGovernanceLock,
2231
4294
  createImplication,
4295
+ createPolicyRepository,
4296
+ createPolicySelector,
4297
+ createSigningPayload,
2232
4298
  detectAnnotations,
4299
+ discoverAssets,
4300
+ discoverConfig,
4301
+ discoverConfigSync,
4302
+ discoverPolicies,
4303
+ evaluatePolicy,
4304
+ extractGoldenThreadComponents,
2233
4305
  formatDate,
2234
4306
  generateAssetId,
2235
4307
  getAllPatterns,
4308
+ getCurrentEnvironment,
4309
+ getDaysUntilExpiration,
4310
+ getEnvironmentConfig,
4311
+ getMaxRiskLevel,
4312
+ getMinRiskLevel,
2236
4313
  getPattern,
2237
4314
  getPatternsByCategory,
2238
4315
  getPatternsByLanguage,
4316
+ getRiskLevelOrdinal,
4317
+ getRiskLevelsAtLeast,
4318
+ getRiskLevelsAtMost,
2239
4319
  inferRiskFactors,
2240
4320
  initializePatterns,
4321
+ isDomainAllowed,
4322
+ isGovernanceLockExpired,
4323
+ isModelAllowed,
4324
+ isModelAllowedByLock,
2241
4325
  isModelFile,
4326
+ isRegionAllowed,
4327
+ isRegionAllowedByLock,
2242
4328
  isRegistryInitialized,
4329
+ isRiskLevelAtLeast,
4330
+ isRiskLevelAtMost,
4331
+ isToolAllowed,
4332
+ isValidRiskLevel,
4333
+ isVendorAllowed,
4334
+ isVendorAllowedByLock,
2243
4335
  javascriptPatterns,
2244
4336
  linkAssetToTicket,
4337
+ loadAsset,
2245
4338
  loadAssetCard,
4339
+ loadAssetFromPath,
4340
+ loadPolicy,
4341
+ mapToEuAiActCategory,
2246
4342
  matchPatterns,
4343
+ mergePolicies,
2247
4344
  modelFilePatterns,
2248
4345
  parseDate,
4346
+ parseGovernanceLockJSON,
4347
+ parseGovernanceLockYAML,
4348
+ parseRiskLevel,
4349
+ parseSignature,
2249
4350
  pythonPatterns,
2250
4351
  registerPattern,
2251
4352
  resetPatterns,
4353
+ resolvePolicy,
2252
4354
  riskIndicatorPatterns,
2253
4355
  saveAssetCard,
2254
4356
  scan,
2255
4357
  scanFileExtension,
2256
4358
  scanSync,
4359
+ selectPolicy,
4360
+ serializeGovernanceLockJSON,
4361
+ serializeGovernanceLockYAML,
4362
+ signGoldenThread,
2257
4363
  slugify,
2258
4364
  suggestAssetCard,
2259
4365
  updateJurisdictionCompliance,
4366
+ validateAIR,
2260
4367
  validateAssetCard,
2261
4368
  validateGoldenThread,
2262
- validateRiskFactors
4369
+ validateGovernanceLock,
4370
+ validateRiskFactors,
4371
+ verifyGoldenThreadHash,
4372
+ verifyGoldenThreadHashSync,
4373
+ verifyGoldenThreadSignature,
4374
+ verifyGoldenThreadSignatureSync
2263
4375
  };
2264
4376
  //# sourceMappingURL=index.mjs.map