@vorionsys/contracts 0.1.0 → 0.1.2

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.
Files changed (219) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/LICENSE +190 -0
  3. package/README.md +435 -0
  4. package/dist/aci/index.d.ts +6 -62
  5. package/dist/aci/index.d.ts.map +1 -1
  6. package/dist/aci/index.js +22 -152
  7. package/dist/aci/index.js.map +1 -1
  8. package/dist/canonical/agent.d.ts +2 -2
  9. package/dist/canonical/agent.d.ts.map +1 -1
  10. package/dist/canonical/agent.js +146 -130
  11. package/dist/canonical/agent.js.map +1 -1
  12. package/dist/canonical/governance.d.ts +1 -1
  13. package/dist/canonical/governance.js +134 -120
  14. package/dist/canonical/governance.js.map +1 -1
  15. package/dist/canonical/index.d.ts +1 -0
  16. package/dist/canonical/index.d.ts.map +1 -1
  17. package/dist/canonical/index.js +26 -8
  18. package/dist/canonical/index.js.map +1 -1
  19. package/dist/canonical/intent.d.ts +8 -15
  20. package/dist/canonical/intent.d.ts.map +1 -1
  21. package/dist/canonical/intent.js +91 -82
  22. package/dist/canonical/intent.js.map +1 -1
  23. package/dist/canonical/middleware.d.ts +513 -0
  24. package/dist/canonical/middleware.d.ts.map +1 -0
  25. package/dist/canonical/middleware.js +218 -0
  26. package/dist/canonical/middleware.js.map +1 -0
  27. package/dist/canonical/risk-level.d.ts +1 -1
  28. package/dist/canonical/risk-level.js +66 -46
  29. package/dist/canonical/risk-level.js.map +1 -1
  30. package/dist/canonical/trust-band.d.ts +1 -1
  31. package/dist/canonical/trust-band.js +39 -28
  32. package/dist/canonical/trust-band.js.map +1 -1
  33. package/dist/canonical/trust-score.d.ts +1 -1
  34. package/dist/canonical/trust-score.js +46 -29
  35. package/dist/canonical/trust-score.js.map +1 -1
  36. package/dist/canonical/trust-signal.d.ts +13 -13
  37. package/dist/canonical/trust-signal.js +91 -78
  38. package/dist/canonical/trust-signal.js.map +1 -1
  39. package/dist/canonical/validation.js +148 -102
  40. package/dist/canonical/validation.js.map +1 -1
  41. package/dist/{aci → car}/attestation.d.ts +73 -73
  42. package/dist/{aci → car}/attestation.d.ts.map +1 -1
  43. package/dist/{aci → car}/attestation.js +69 -59
  44. package/dist/car/attestation.js.map +1 -0
  45. package/dist/car/car-string.d.ts +846 -0
  46. package/dist/car/car-string.d.ts.map +1 -0
  47. package/dist/car/car-string.js +734 -0
  48. package/dist/car/car-string.js.map +1 -0
  49. package/dist/{aci → car}/domains.d.ts +3 -3
  50. package/dist/{aci → car}/domains.d.ts.map +1 -1
  51. package/dist/{aci → car}/domains.js +57 -39
  52. package/dist/car/domains.js.map +1 -0
  53. package/dist/{aci → car}/effective-permission.d.ts +8 -8
  54. package/dist/{aci → car}/effective-permission.d.ts.map +1 -1
  55. package/dist/{aci → car}/effective-permission.js +59 -46
  56. package/dist/car/effective-permission.js.map +1 -0
  57. package/dist/{aci → car}/identity.d.ts +235 -129
  58. package/dist/car/identity.d.ts.map +1 -0
  59. package/dist/{aci → car}/identity.js +125 -105
  60. package/dist/car/identity.js.map +1 -0
  61. package/dist/car/index.d.ts +104 -0
  62. package/dist/car/index.d.ts.map +1 -0
  63. package/dist/car/index.js +401 -0
  64. package/dist/car/index.js.map +1 -0
  65. package/dist/car/jwt-claims.d.ts +1364 -0
  66. package/dist/car/jwt-claims.d.ts.map +1 -0
  67. package/dist/car/jwt-claims.js +388 -0
  68. package/dist/car/jwt-claims.js.map +1 -0
  69. package/dist/{aci → car}/levels.d.ts +5 -5
  70. package/dist/{aci → car}/levels.d.ts.map +1 -1
  71. package/dist/{aci → car}/levels.js +81 -62
  72. package/dist/car/levels.js.map +1 -0
  73. package/dist/{aci → car}/mapping.d.ts +5 -5
  74. package/dist/{aci → car}/mapping.d.ts.map +1 -1
  75. package/dist/{aci → car}/mapping.js +96 -76
  76. package/dist/car/mapping.js.map +1 -0
  77. package/dist/{aci → car}/skills.d.ts +4 -4
  78. package/dist/{aci → car}/skills.d.ts.map +1 -1
  79. package/dist/{aci → car}/skills.js +72 -50
  80. package/dist/car/skills.js.map +1 -0
  81. package/dist/{aci → car}/tiers.d.ts +3 -3
  82. package/dist/{aci → car}/tiers.d.ts.map +1 -1
  83. package/dist/{aci → car}/tiers.js +140 -113
  84. package/dist/car/tiers.js.map +1 -0
  85. package/dist/common/index.d.ts +1 -0
  86. package/dist/common/index.d.ts.map +1 -1
  87. package/dist/common/index.js +18 -1
  88. package/dist/common/index.js.map +1 -1
  89. package/dist/common/primitives.d.ts +9 -7
  90. package/dist/common/primitives.d.ts.map +1 -1
  91. package/dist/common/primitives.js +30 -25
  92. package/dist/common/primitives.js.map +1 -1
  93. package/dist/common/types.d.ts +328 -0
  94. package/dist/common/types.d.ts.map +1 -0
  95. package/dist/common/types.js +61 -0
  96. package/dist/common/types.js.map +1 -0
  97. package/dist/db/agents.d.ts +1914 -0
  98. package/dist/db/agents.d.ts.map +1 -0
  99. package/dist/db/agents.js +283 -0
  100. package/dist/db/agents.js.map +1 -0
  101. package/dist/db/api-keys.d.ts +506 -0
  102. package/dist/db/api-keys.d.ts.map +1 -0
  103. package/dist/db/api-keys.js +101 -0
  104. package/dist/db/api-keys.js.map +1 -0
  105. package/dist/db/escalations.d.ts +554 -0
  106. package/dist/db/escalations.d.ts.map +1 -0
  107. package/dist/db/escalations.js +100 -0
  108. package/dist/db/escalations.js.map +1 -0
  109. package/dist/db/index.d.ts +20 -0
  110. package/dist/db/index.d.ts.map +1 -0
  111. package/dist/db/index.js +47 -0
  112. package/dist/db/index.js.map +1 -0
  113. package/dist/db/intents.d.ts +535 -0
  114. package/dist/db/intents.d.ts.map +1 -0
  115. package/dist/db/intents.js +93 -0
  116. package/dist/db/intents.js.map +1 -0
  117. package/dist/db/merkle.d.ts +475 -0
  118. package/dist/db/merkle.d.ts.map +1 -0
  119. package/dist/db/merkle.js +103 -0
  120. package/dist/db/merkle.js.map +1 -0
  121. package/dist/db/operations.d.ts +256 -0
  122. package/dist/db/operations.d.ts.map +1 -0
  123. package/dist/db/operations.js +68 -0
  124. package/dist/db/operations.js.map +1 -0
  125. package/dist/db/policy-versions.d.ts +149 -0
  126. package/dist/db/policy-versions.d.ts.map +1 -0
  127. package/dist/db/policy-versions.js +44 -0
  128. package/dist/db/policy-versions.js.map +1 -0
  129. package/dist/db/proofs.d.ts +412 -0
  130. package/dist/db/proofs.d.ts.map +1 -0
  131. package/dist/db/proofs.js +66 -0
  132. package/dist/db/proofs.js.map +1 -0
  133. package/dist/db/rbac.d.ts +882 -0
  134. package/dist/db/rbac.d.ts.map +1 -0
  135. package/dist/db/rbac.js +189 -0
  136. package/dist/db/rbac.js.map +1 -0
  137. package/dist/db/service-accounts.d.ts +783 -0
  138. package/dist/db/service-accounts.d.ts.map +1 -0
  139. package/dist/db/service-accounts.js +179 -0
  140. package/dist/db/service-accounts.js.map +1 -0
  141. package/dist/db/trust.d.ts +603 -0
  142. package/dist/db/trust.d.ts.map +1 -0
  143. package/dist/db/trust.js +111 -0
  144. package/dist/db/trust.js.map +1 -0
  145. package/dist/db/webhooks.d.ts +382 -0
  146. package/dist/db/webhooks.d.ts.map +1 -0
  147. package/dist/db/webhooks.js +94 -0
  148. package/dist/db/webhooks.js.map +1 -0
  149. package/dist/flags.d.ts +214 -0
  150. package/dist/flags.d.ts.map +1 -0
  151. package/dist/flags.js +443 -0
  152. package/dist/flags.js.map +1 -0
  153. package/dist/index.d.ts +3 -1
  154. package/dist/index.d.ts.map +1 -1
  155. package/dist/index.js +47 -4
  156. package/dist/index.js.map +1 -1
  157. package/dist/v2/canary-probe.js +10 -7
  158. package/dist/v2/canary-probe.js.map +1 -1
  159. package/dist/v2/component.js +2 -1
  160. package/dist/v2/component.js.map +1 -1
  161. package/dist/v2/decision.js +5 -2
  162. package/dist/v2/decision.js.map +1 -1
  163. package/dist/v2/enums.js +28 -25
  164. package/dist/v2/enums.js.map +1 -1
  165. package/dist/v2/evidence.js +75 -72
  166. package/dist/v2/evidence.js.map +1 -1
  167. package/dist/v2/execution.js +2 -1
  168. package/dist/v2/execution.js.map +1 -1
  169. package/dist/v2/index.js +29 -13
  170. package/dist/v2/index.js.map +1 -1
  171. package/dist/v2/intent.js +2 -1
  172. package/dist/v2/intent.js.map +1 -1
  173. package/dist/v2/policy-bundle.js +5 -2
  174. package/dist/v2/policy-bundle.js.map +1 -1
  175. package/dist/v2/pre-action-gate.js +10 -7
  176. package/dist/v2/pre-action-gate.js.map +1 -1
  177. package/dist/v2/proof-event.d.ts +3 -1
  178. package/dist/v2/proof-event.d.ts.map +1 -1
  179. package/dist/v2/proof-event.js +2 -1
  180. package/dist/v2/proof-event.js.map +1 -1
  181. package/dist/v2/retention.js +104 -101
  182. package/dist/v2/retention.js.map +1 -1
  183. package/dist/v2/trust-delta.js +5 -2
  184. package/dist/v2/trust-delta.js.map +1 -1
  185. package/dist/v2/trust-profile.js +12 -9
  186. package/dist/v2/trust-profile.js.map +1 -1
  187. package/dist/validators/decision.d.ts +2 -2
  188. package/dist/validators/decision.js +49 -46
  189. package/dist/validators/decision.js.map +1 -1
  190. package/dist/validators/enums.js +14 -11
  191. package/dist/validators/enums.js.map +1 -1
  192. package/dist/validators/index.js +30 -9
  193. package/dist/validators/index.js.map +1 -1
  194. package/dist/validators/intent.js +40 -37
  195. package/dist/validators/intent.js.map +1 -1
  196. package/dist/validators/proof-event.d.ts +3 -0
  197. package/dist/validators/proof-event.d.ts.map +1 -1
  198. package/dist/validators/proof-event.js +103 -99
  199. package/dist/validators/proof-event.js.map +1 -1
  200. package/dist/validators/trust-profile.js +40 -37
  201. package/dist/validators/trust-profile.js.map +1 -1
  202. package/package.json +81 -15
  203. package/dist/aci/aci-string.d.ts +0 -539
  204. package/dist/aci/aci-string.d.ts.map +0 -1
  205. package/dist/aci/aci-string.js +0 -563
  206. package/dist/aci/aci-string.js.map +0 -1
  207. package/dist/aci/attestation.js.map +0 -1
  208. package/dist/aci/domains.js.map +0 -1
  209. package/dist/aci/effective-permission.js.map +0 -1
  210. package/dist/aci/identity.d.ts.map +0 -1
  211. package/dist/aci/identity.js.map +0 -1
  212. package/dist/aci/jwt-claims.d.ts +0 -756
  213. package/dist/aci/jwt-claims.d.ts.map +0 -1
  214. package/dist/aci/jwt-claims.js +0 -335
  215. package/dist/aci/jwt-claims.js.map +0 -1
  216. package/dist/aci/levels.js.map +0 -1
  217. package/dist/aci/mapping.js.map +0 -1
  218. package/dist/aci/skills.js.map +0 -1
  219. package/dist/aci/tiers.js.map +0 -1
@@ -0,0 +1,734 @@
1
+ "use strict";
2
+ /**
3
+ * @fileoverview CAR String Parser and Generator
4
+ *
5
+ * Provides parsing, generation, and validation for Categorical Agent
6
+ * Registry (CAR) strings. CAR strings follow the format:
7
+ *
8
+ * `{registry}.{organization}.{agentClass}:{domains}-L{level}@{version}[#extensions]`
9
+ *
10
+ * Example: `a3i.acme-corp.invoice-bot:ABF-L3@1.0.0`
11
+ *
12
+ * **CRITICAL DESIGN PRINCIPLE:**
13
+ * The CAR is an IMMUTABLE identifier (like a certificate or passport number).
14
+ * Trust is NOT encoded in the CAR - it is computed at RUNTIME based on:
15
+ * - Attestations (stored separately)
16
+ * - Behavioral signals
17
+ * - Deployment context policies
18
+ *
19
+ * The optional extensions (section 5+) are mutable and can be defined by
20
+ * industry or community standards.
21
+ *
22
+ * @module @vorionsys/contracts/car/car-string
23
+ */
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ exports.aciValidationResultSchema = exports.carValidationResultSchema = exports.aciValidationWarningSchema = exports.carValidationWarningSchema = exports.aciValidationErrorSchema = exports.carValidationErrorSchema = exports.generateACIOptionsSchema = exports.generateCAROptionsSchema = exports.aciSchema = exports.carSchema = exports.aciStringSchema = exports.carStringSchema = exports.ACIParseError = exports.CARParseError = exports.parsedACISchema = exports.parsedCARSchema = exports.ACI_LEGACY_REGEX = exports.ACI_PARTIAL_REGEX = exports.ACI_REGEX = exports.CAR_LEGACY_REGEX = exports.CAR_PARTIAL_REGEX = exports.CAR_REGEX = void 0;
26
+ exports.getCARIdentity = getCARIdentity;
27
+ exports.getACIIdentity = getACIIdentity;
28
+ exports.parseCAR = parseCAR;
29
+ exports.parseACI = parseACI;
30
+ exports.parseLegacyCAR = parseLegacyCAR;
31
+ exports.parseLegacyACI = parseLegacyACI;
32
+ exports.tryParseCAR = tryParseCAR;
33
+ exports.tryParseACI = tryParseACI;
34
+ exports.safeParseCAR = safeParseCAR;
35
+ exports.safeParseACI = safeParseACI;
36
+ exports.generateCAR = generateCAR;
37
+ exports.generateACI = generateACI;
38
+ exports.generateCARString = generateCARString;
39
+ exports.generateACIString = generateACIString;
40
+ exports.validateCAR = validateCAR;
41
+ exports.validateACI = validateACI;
42
+ exports.isValidCAR = isValidCAR;
43
+ exports.isValidACI = isValidACI;
44
+ exports.isCARString = isCARString;
45
+ exports.isACIString = isACIString;
46
+ exports.updateCAR = updateCAR;
47
+ exports.updateACI = updateACI;
48
+ exports.addCARExtensions = addCARExtensions;
49
+ exports.addACIExtensions = addACIExtensions;
50
+ exports.removeCARExtensions = removeCARExtensions;
51
+ exports.removeACIExtensions = removeACIExtensions;
52
+ exports.incrementCARVersion = incrementCARVersion;
53
+ exports.incrementACIVersion = incrementACIVersion;
54
+ const zod_1 = require("zod");
55
+ const domains_js_1 = require("./domains.js");
56
+ const levels_js_1 = require("./levels.js");
57
+ // ============================================================================
58
+ // CAR Regex Pattern
59
+ // ============================================================================
60
+ /**
61
+ * Regular expression for parsing CAR strings.
62
+ *
63
+ * Format: `{registry}.{organization}.{agentClass}:{domains}-L{level}@{version}[#extensions]`
64
+ *
65
+ * Groups:
66
+ * 1. registry - Certifying registry (e.g., 'a3i')
67
+ * 2. organization - Operating organization (e.g., 'acme-corp')
68
+ * 3. agentClass - Agent classification (e.g., 'invoice-bot')
69
+ * 4. domains - Capability domain codes (e.g., 'ABF')
70
+ * 5. level - Autonomy level (0-5)
71
+ * 6. version - Semantic version (e.g., '1.0.0')
72
+ * 7. extensions - Optional comma-separated extensions (e.g., 'gov,audit')
73
+ *
74
+ * NOTE: Trust tier is NOT part of the CAR. Trust is computed at runtime
75
+ * from attestations, behavioral signals, and deployment context.
76
+ */
77
+ exports.CAR_REGEX = /^([a-z0-9]+)\.([a-z0-9-]+)\.([a-z0-9-]+):([A-Z]+)-L([0-5])@(\d+\.\d+\.\d+)(?:#([a-z0-9,_-]+))?$/;
78
+ /**
79
+ * Looser regex for partial CAR validation.
80
+ */
81
+ exports.CAR_PARTIAL_REGEX = /^([a-z0-9]+)\.([a-z0-9-]+)\.([a-z0-9-]+):([A-Z]+)-L([0-5])(@\d+\.\d+\.\d+)?(?:#([a-z0-9,_-]+))?$/;
82
+ /**
83
+ * Legacy regex for parsing old-format CAR strings that include trust tier.
84
+ * Used for migration/compatibility only.
85
+ * @deprecated Use CAR_REGEX instead - trust tier should not be in the identifier
86
+ */
87
+ exports.CAR_LEGACY_REGEX = /^([a-z0-9]+)\.([a-z0-9-]+)\.([a-z0-9-]+):([A-Z]+)-L([0-5])-T([0-5])@(\d+\.\d+\.\d+)$/;
88
+ // Legacy ACI aliases for backwards compatibility
89
+ /** @deprecated Use CAR_REGEX instead */
90
+ exports.ACI_REGEX = exports.CAR_REGEX;
91
+ /** @deprecated Use CAR_PARTIAL_REGEX instead */
92
+ exports.ACI_PARTIAL_REGEX = exports.CAR_PARTIAL_REGEX;
93
+ /** @deprecated Use CAR_LEGACY_REGEX instead */
94
+ exports.ACI_LEGACY_REGEX = exports.CAR_LEGACY_REGEX;
95
+ /**
96
+ * Extracts the identity portion from a parsed CAR.
97
+ */
98
+ function getCARIdentity(parsed) {
99
+ return `${parsed.registry}.${parsed.organization}.${parsed.agentClass}`;
100
+ }
101
+ /**
102
+ * @deprecated Use getCARIdentity instead
103
+ */
104
+ function getACIIdentity(parsed) {
105
+ return getCARIdentity(parsed);
106
+ }
107
+ /**
108
+ * Zod schema for ParsedCAR validation.
109
+ */
110
+ exports.parsedCARSchema = zod_1.z.object({
111
+ car: zod_1.z.string().min(1),
112
+ registry: zod_1.z.string().min(1).regex(/^[a-z0-9]+$/),
113
+ organization: zod_1.z.string().min(1).regex(/^[a-z0-9-]+$/),
114
+ agentClass: zod_1.z.string().min(1).regex(/^[a-z0-9-]+$/),
115
+ domains: zod_1.z.array(zod_1.z.enum(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'S'])).min(1),
116
+ domainsBitmask: zod_1.z.number().int().min(0),
117
+ level: zod_1.z.nativeEnum(levels_js_1.CapabilityLevel),
118
+ version: zod_1.z.string().regex(/^\d+\.\d+\.\d+$/),
119
+ extensions: zod_1.z.array(zod_1.z.string()).default([]),
120
+ });
121
+ /** @deprecated Use parsedCARSchema instead */
122
+ exports.parsedACISchema = exports.parsedCARSchema;
123
+ // ============================================================================
124
+ // CAR Parse Error
125
+ // ============================================================================
126
+ /**
127
+ * Error thrown when CAR parsing fails.
128
+ */
129
+ class CARParseError extends Error {
130
+ /** The invalid CAR string that caused the error */
131
+ car;
132
+ /** Error code for programmatic handling */
133
+ code;
134
+ constructor(message, car, code = 'INVALID_FORMAT') {
135
+ super(message);
136
+ this.name = 'CARParseError';
137
+ this.car = car;
138
+ this.code = code;
139
+ }
140
+ }
141
+ exports.CARParseError = CARParseError;
142
+ /**
143
+ * @deprecated Use CARParseError instead
144
+ */
145
+ class ACIParseError extends CARParseError {
146
+ /** @deprecated Use car instead */
147
+ aci;
148
+ constructor(message, aci, code = 'INVALID_FORMAT') {
149
+ super(message, aci, code);
150
+ this.name = 'ACIParseError';
151
+ this.aci = aci;
152
+ }
153
+ }
154
+ exports.ACIParseError = ACIParseError;
155
+ // ============================================================================
156
+ // Parsing Functions
157
+ // ============================================================================
158
+ /**
159
+ * Parses a CAR string into its components.
160
+ *
161
+ * @param car - The CAR string to parse
162
+ * @returns Parsed CAR components
163
+ * @throws CARParseError if the CAR string is invalid
164
+ *
165
+ * @example
166
+ * ```typescript
167
+ * const parsed = parseCAR('a3i.acme-corp.invoice-bot:ABF-L3@1.0.0');
168
+ * // {
169
+ * // car: 'a3i.acme-corp.invoice-bot:ABF-L3@1.0.0',
170
+ * // registry: 'a3i',
171
+ * // organization: 'acme-corp',
172
+ * // agentClass: 'invoice-bot',
173
+ * // domains: ['A', 'B', 'F'],
174
+ * // domainsBitmask: 0x023,
175
+ * // level: CapabilityLevel.L3_EXECUTE,
176
+ * // version: '1.0.0',
177
+ * // extensions: []
178
+ * // }
179
+ * ```
180
+ */
181
+ function parseCAR(car) {
182
+ // Check for legacy format with embedded trust tier
183
+ if (exports.CAR_LEGACY_REGEX.test(car)) {
184
+ throw new CARParseError(`Legacy CAR format detected with embedded trust tier. ` +
185
+ `Trust should not be part of the identifier - use parseLegacyCAR() for migration.`, car, 'LEGACY_FORMAT');
186
+ }
187
+ const match = car.match(exports.CAR_REGEX);
188
+ if (!match) {
189
+ throw new CARParseError(`Invalid CAR format: ${car}`, car, 'INVALID_FORMAT');
190
+ }
191
+ const [, registry, organization, agentClass, domainsStr, levelStr, version, extensionsStr] = match;
192
+ // Validate and parse domains
193
+ const domainChars = domainsStr.split('');
194
+ const invalidDomains = domainChars.filter((d) => !(0, domains_js_1.isDomainCode)(d));
195
+ if (invalidDomains.length > 0) {
196
+ throw new CARParseError(`Invalid domain codes: ${invalidDomains.join(', ')}`, car, 'INVALID_DOMAINS');
197
+ }
198
+ if (domainChars.length === 0) {
199
+ throw new CARParseError('CAR must have at least one domain', car, 'NO_DOMAINS');
200
+ }
201
+ const domains = domainChars;
202
+ const domainsBitmask = (0, domains_js_1.encodeDomains)(domains);
203
+ // Parse level (no tier - trust is computed at runtime)
204
+ const level = parseInt(levelStr, 10);
205
+ // Parse optional extensions
206
+ const extensions = extensionsStr ? extensionsStr.split(',').filter((e) => e.length > 0) : [];
207
+ return {
208
+ car,
209
+ registry: registry,
210
+ organization: organization,
211
+ agentClass: agentClass,
212
+ domains,
213
+ domainsBitmask,
214
+ level,
215
+ version: version,
216
+ extensions,
217
+ };
218
+ }
219
+ /**
220
+ * @deprecated Use parseCAR instead
221
+ */
222
+ function parseACI(aci) {
223
+ const parsed = parseCAR(aci);
224
+ return { ...parsed, aci: parsed.car };
225
+ }
226
+ /**
227
+ * Parses a legacy CAR string that includes trust tier.
228
+ * Returns the parsed CAR (without tier) plus the extracted tier value.
229
+ *
230
+ * @deprecated Use parseCAR() - trust should not be in the identifier
231
+ * @param car - Legacy CAR string with embedded tier
232
+ * @returns Parsed CAR plus extracted tier
233
+ */
234
+ function parseLegacyCAR(car) {
235
+ const match = car.match(exports.CAR_LEGACY_REGEX);
236
+ if (!match) {
237
+ throw new CARParseError(`Invalid legacy CAR format: ${car}`, car, 'INVALID_FORMAT');
238
+ }
239
+ const [, registry, organization, agentClass, domainsStr, levelStr, tierStr, version] = match;
240
+ // Validate and parse domains
241
+ const domainChars = domainsStr.split('');
242
+ const invalidDomains = domainChars.filter((d) => !(0, domains_js_1.isDomainCode)(d));
243
+ if (invalidDomains.length > 0) {
244
+ throw new CARParseError(`Invalid domain codes: ${invalidDomains.join(', ')}`, car, 'INVALID_DOMAINS');
245
+ }
246
+ const domains = domainChars;
247
+ const domainsBitmask = (0, domains_js_1.encodeDomains)(domains);
248
+ const level = parseInt(levelStr, 10);
249
+ const legacyTier = parseInt(tierStr, 10);
250
+ // Generate the new CAR format (without tier)
251
+ const newCar = `${registry}.${organization}.${agentClass}:${(0, domains_js_1.formatDomainString)(domains)}-L${level}@${version}`;
252
+ return {
253
+ parsed: {
254
+ car: newCar,
255
+ registry: registry,
256
+ organization: organization,
257
+ agentClass: agentClass,
258
+ domains,
259
+ domainsBitmask,
260
+ level,
261
+ version: version,
262
+ extensions: [],
263
+ },
264
+ legacyTier,
265
+ };
266
+ }
267
+ /**
268
+ * @deprecated Use parseLegacyCAR instead
269
+ */
270
+ function parseLegacyACI(aci) {
271
+ const result = parseLegacyCAR(aci);
272
+ return {
273
+ parsed: { ...result.parsed, aci: result.parsed.car },
274
+ legacyTier: result.legacyTier,
275
+ };
276
+ }
277
+ /**
278
+ * Safely parses a CAR string, returning null on failure.
279
+ *
280
+ * @param car - The CAR string to parse
281
+ * @returns Parsed CAR or null if invalid
282
+ */
283
+ function tryParseCAR(car) {
284
+ try {
285
+ return parseCAR(car);
286
+ }
287
+ catch {
288
+ return null;
289
+ }
290
+ }
291
+ /**
292
+ * @deprecated Use tryParseCAR instead
293
+ */
294
+ function tryParseACI(aci) {
295
+ try {
296
+ return parseACI(aci);
297
+ }
298
+ catch {
299
+ return null;
300
+ }
301
+ }
302
+ /**
303
+ * Safely parses a CAR string, returning a result object.
304
+ *
305
+ * @param car - The CAR string to parse
306
+ * @returns Result object with success flag and parsed CAR or error
307
+ */
308
+ function safeParseCAR(car) {
309
+ try {
310
+ return { success: true, data: parseCAR(car) };
311
+ }
312
+ catch (error) {
313
+ if (error instanceof CARParseError) {
314
+ return { success: false, error };
315
+ }
316
+ return {
317
+ success: false,
318
+ error: new CARParseError(String(error), car, 'INVALID_FORMAT'),
319
+ };
320
+ }
321
+ }
322
+ /**
323
+ * @deprecated Use safeParseCAR instead
324
+ */
325
+ function safeParseACI(aci) {
326
+ try {
327
+ return { success: true, data: parseACI(aci) };
328
+ }
329
+ catch (error) {
330
+ if (error instanceof CARParseError) {
331
+ return { success: false, error };
332
+ }
333
+ return {
334
+ success: false,
335
+ error: new CARParseError(String(error), aci, 'INVALID_FORMAT'),
336
+ };
337
+ }
338
+ }
339
+ /**
340
+ * Generates a CAR string from components.
341
+ *
342
+ * @param options - CAR components
343
+ * @returns Generated CAR string
344
+ *
345
+ * @example
346
+ * ```typescript
347
+ * const car = generateCAR({
348
+ * registry: 'a3i',
349
+ * organization: 'acme-corp',
350
+ * agentClass: 'invoice-bot',
351
+ * domains: ['A', 'B', 'F'],
352
+ * level: CapabilityLevel.L3_EXECUTE,
353
+ * version: '1.0.0',
354
+ * });
355
+ * // 'a3i.acme-corp.invoice-bot:ABF-L3@1.0.0'
356
+ *
357
+ * // With extensions:
358
+ * const carWithExt = generateCAR({
359
+ * registry: 'a3i',
360
+ * organization: 'acme-corp',
361
+ * agentClass: 'invoice-bot',
362
+ * domains: ['A', 'B', 'F'],
363
+ * level: CapabilityLevel.L3_EXECUTE,
364
+ * version: '1.0.0',
365
+ * extensions: ['gov', 'audit'],
366
+ * });
367
+ * // 'a3i.acme-corp.invoice-bot:ABF-L3@1.0.0#gov,audit'
368
+ * ```
369
+ */
370
+ function generateCAR(options) {
371
+ const { registry, organization, agentClass, domains, level, version, extensions = [] } = options;
372
+ // Validate components
373
+ if (!/^[a-z0-9]+$/.test(registry)) {
374
+ throw new Error(`Invalid registry: ${registry}. Must be lowercase alphanumeric.`);
375
+ }
376
+ if (!/^[a-z0-9-]+$/.test(organization)) {
377
+ throw new Error(`Invalid organization: ${organization}. Must be lowercase alphanumeric with hyphens.`);
378
+ }
379
+ if (!/^[a-z0-9-]+$/.test(agentClass)) {
380
+ throw new Error(`Invalid agent class: ${agentClass}. Must be lowercase alphanumeric with hyphens.`);
381
+ }
382
+ if (domains.length === 0) {
383
+ throw new Error('At least one domain is required.');
384
+ }
385
+ const invalidDomains = domains.filter((d) => !(0, domains_js_1.isDomainCode)(d));
386
+ if (invalidDomains.length > 0) {
387
+ throw new Error(`Invalid domain codes: ${invalidDomains.join(', ')}`);
388
+ }
389
+ if (!(0, levels_js_1.isCapabilityLevel)(level)) {
390
+ throw new Error(`Invalid level: ${level}. Must be 0-5.`);
391
+ }
392
+ if (!/^\d+\.\d+\.\d+$/.test(version)) {
393
+ throw new Error(`Invalid version: ${version}. Must be semantic version (e.g., 1.0.0).`);
394
+ }
395
+ // Validate extensions if provided
396
+ if (extensions.length > 0) {
397
+ const invalidExtensions = extensions.filter((e) => !/^[a-z0-9_-]+$/.test(e));
398
+ if (invalidExtensions.length > 0) {
399
+ throw new Error(`Invalid extensions: ${invalidExtensions.join(', ')}. Must be lowercase alphanumeric with hyphens/underscores.`);
400
+ }
401
+ }
402
+ // Format domains (sorted, deduplicated)
403
+ const domainsStr = (0, domains_js_1.formatDomainString)(domains);
404
+ // Build CAR string
405
+ let car = `${registry}.${organization}.${agentClass}:${domainsStr}-L${level}@${version}`;
406
+ // Append extensions if present
407
+ if (extensions.length > 0) {
408
+ car += `#${extensions.join(',')}`;
409
+ }
410
+ return car;
411
+ }
412
+ /**
413
+ * @deprecated Use generateCAR instead
414
+ */
415
+ function generateACI(options) {
416
+ return generateCAR(options);
417
+ }
418
+ /**
419
+ * Generates a CAR string from individual parameters.
420
+ *
421
+ * @param registry - Certifying registry
422
+ * @param organization - Operating organization
423
+ * @param agentClass - Agent classification
424
+ * @param domains - Capability domains
425
+ * @param level - Autonomy level
426
+ * @param version - Semantic version
427
+ * @param extensions - Optional extensions
428
+ * @returns Generated CAR string
429
+ */
430
+ function generateCARString(registry, organization, agentClass, domains, level, version, extensions) {
431
+ return generateCAR({
432
+ registry,
433
+ organization,
434
+ agentClass,
435
+ domains,
436
+ level,
437
+ version,
438
+ extensions,
439
+ });
440
+ }
441
+ /**
442
+ * @deprecated Use generateCARString instead
443
+ */
444
+ function generateACIString(registry, organization, agentClass, domains, level, version, extensions) {
445
+ return generateCARString(registry, organization, agentClass, domains, level, version, extensions);
446
+ }
447
+ /**
448
+ * Validates a CAR string.
449
+ *
450
+ * @param car - The CAR string to validate
451
+ * @returns Validation result
452
+ *
453
+ * @example
454
+ * ```typescript
455
+ * const result = validateCAR('a3i.acme-corp.bot:A-L5@1.0.0');
456
+ * // {
457
+ * // valid: true,
458
+ * // errors: [],
459
+ * // warnings: [],
460
+ * // parsed: { ... }
461
+ * // }
462
+ * ```
463
+ */
464
+ function validateCAR(car) {
465
+ const errors = [];
466
+ const warnings = [];
467
+ // Check for legacy format with embedded trust tier
468
+ if (exports.CAR_LEGACY_REGEX.test(car)) {
469
+ warnings.push({
470
+ code: 'LEGACY_FORMAT',
471
+ message: 'CAR contains embedded trust tier which is deprecated. ' +
472
+ 'Trust should be computed at runtime, not encoded in the identifier.',
473
+ });
474
+ }
475
+ try {
476
+ const parsed = parseCAR(car);
477
+ // Validate capability level constraints
478
+ // Note: Trust checks are now done at RUNTIME, not in the CAR itself
479
+ // L7 agents operate at maximum autonomy - should be rare
480
+ if (parsed.level === levels_js_1.CapabilityLevel.L7_AUTONOMOUS) {
481
+ warnings.push({
482
+ code: 'L7_AUTONOMOUS_LEVEL',
483
+ message: 'L7 (Autonomous) level grants maximum autonomy. ' +
484
+ 'Ensure runtime trust policies are configured appropriately.',
485
+ });
486
+ }
487
+ // Security domain agents require careful runtime trust
488
+ if (parsed.domains.includes('S')) {
489
+ warnings.push({
490
+ code: 'SECURITY_DOMAIN',
491
+ message: 'Security domain agent. Runtime attestations and behavioral scoring ' +
492
+ 'should be configured to enforce appropriate trust levels.',
493
+ });
494
+ }
495
+ // Finance domain agents require careful runtime trust
496
+ if (parsed.domains.includes('F')) {
497
+ warnings.push({
498
+ code: 'FINANCE_DOMAIN',
499
+ message: 'Finance domain agent. Runtime attestations and behavioral scoring ' +
500
+ 'should be configured to enforce appropriate trust levels.',
501
+ });
502
+ }
503
+ return {
504
+ valid: true,
505
+ errors,
506
+ warnings,
507
+ parsed,
508
+ };
509
+ }
510
+ catch (e) {
511
+ if (e instanceof CARParseError) {
512
+ // If it's a legacy format error, try parsing with legacy parser
513
+ if (e.code === 'LEGACY_FORMAT') {
514
+ try {
515
+ const { parsed } = parseLegacyCAR(car);
516
+ warnings.push({
517
+ code: 'LEGACY_FORMAT_MIGRATED',
518
+ message: 'Legacy CAR migrated to new format. Trust tier has been removed from identifier.',
519
+ });
520
+ return {
521
+ valid: true,
522
+ errors,
523
+ warnings,
524
+ parsed,
525
+ };
526
+ }
527
+ catch {
528
+ errors.push({ code: e.code, message: e.message });
529
+ }
530
+ }
531
+ else {
532
+ errors.push({ code: e.code, message: e.message });
533
+ }
534
+ }
535
+ else {
536
+ errors.push({ code: 'UNKNOWN_ERROR', message: String(e) });
537
+ }
538
+ return { valid: false, errors, warnings };
539
+ }
540
+ }
541
+ /**
542
+ * @deprecated Use validateCAR instead
543
+ */
544
+ function validateACI(aci) {
545
+ return validateCAR(aci);
546
+ }
547
+ /**
548
+ * Checks if a string is a valid CAR format.
549
+ *
550
+ * @param car - String to check
551
+ * @returns True if the string is a valid CAR
552
+ */
553
+ function isValidCAR(car) {
554
+ return exports.CAR_REGEX.test(car) && validateCAR(car).valid;
555
+ }
556
+ /**
557
+ * @deprecated Use isValidCAR instead
558
+ */
559
+ function isValidACI(aci) {
560
+ return isValidCAR(aci);
561
+ }
562
+ /**
563
+ * Type guard to check if a value is a valid CAR string.
564
+ *
565
+ * @param value - Value to check
566
+ * @returns True if value is a valid CAR string
567
+ */
568
+ function isCARString(value) {
569
+ return typeof value === 'string' && isValidCAR(value);
570
+ }
571
+ /**
572
+ * @deprecated Use isCARString instead
573
+ */
574
+ function isACIString(value) {
575
+ return isCARString(value);
576
+ }
577
+ // ============================================================================
578
+ // CAR Manipulation
579
+ // ============================================================================
580
+ /**
581
+ * Updates specific fields in a CAR and returns a new CAR string.
582
+ *
583
+ * @param car - Original CAR string
584
+ * @param updates - Fields to update
585
+ * @returns New CAR string with updates applied
586
+ */
587
+ function updateCAR(car, updates) {
588
+ const parsed = parseCAR(car);
589
+ return generateCAR({
590
+ registry: parsed.registry,
591
+ organization: parsed.organization,
592
+ agentClass: parsed.agentClass,
593
+ domains: updates.domains ?? parsed.domains,
594
+ level: updates.level ?? parsed.level,
595
+ version: updates.version ?? parsed.version,
596
+ extensions: updates.extensions ?? parsed.extensions,
597
+ });
598
+ }
599
+ /**
600
+ * @deprecated Use updateCAR instead
601
+ */
602
+ function updateACI(aci, updates) {
603
+ return updateCAR(aci, updates);
604
+ }
605
+ /**
606
+ * Adds extensions to a CAR string.
607
+ *
608
+ * @param car - Original CAR string
609
+ * @param newExtensions - Extensions to add
610
+ * @returns New CAR string with extensions added
611
+ */
612
+ function addCARExtensions(car, newExtensions) {
613
+ const parsed = parseCAR(car);
614
+ const allExtensions = [...new Set([...parsed.extensions, ...newExtensions])];
615
+ return updateCAR(car, { extensions: allExtensions });
616
+ }
617
+ /**
618
+ * @deprecated Use addCARExtensions instead
619
+ */
620
+ function addACIExtensions(aci, newExtensions) {
621
+ return addCARExtensions(aci, newExtensions);
622
+ }
623
+ /**
624
+ * Removes extensions from a CAR string.
625
+ *
626
+ * @param car - Original CAR string
627
+ * @param extensionsToRemove - Extensions to remove
628
+ * @returns New CAR string with extensions removed
629
+ */
630
+ function removeCARExtensions(car, extensionsToRemove) {
631
+ const parsed = parseCAR(car);
632
+ const remaining = parsed.extensions.filter((e) => !extensionsToRemove.includes(e));
633
+ return updateCAR(car, { extensions: remaining });
634
+ }
635
+ /**
636
+ * @deprecated Use removeCARExtensions instead
637
+ */
638
+ function removeACIExtensions(aci, extensionsToRemove) {
639
+ return removeCARExtensions(aci, extensionsToRemove);
640
+ }
641
+ /**
642
+ * Increments the version in a CAR string.
643
+ *
644
+ * @param car - Original CAR string
645
+ * @param type - Version component to increment ('major' | 'minor' | 'patch')
646
+ * @returns New CAR string with incremented version
647
+ */
648
+ function incrementCARVersion(car, type = 'patch') {
649
+ const parsed = parseCAR(car);
650
+ const [major, minor, patch] = parsed.version.split('.').map(Number);
651
+ let newVersion;
652
+ switch (type) {
653
+ case 'major':
654
+ newVersion = `${major + 1}.0.0`;
655
+ break;
656
+ case 'minor':
657
+ newVersion = `${major}.${minor + 1}.0`;
658
+ break;
659
+ case 'patch':
660
+ default:
661
+ newVersion = `${major}.${minor}.${patch + 1}`;
662
+ break;
663
+ }
664
+ return updateCAR(car, { version: newVersion });
665
+ }
666
+ /**
667
+ * @deprecated Use incrementCARVersion instead
668
+ */
669
+ function incrementACIVersion(aci, type = 'patch') {
670
+ return incrementCARVersion(aci, type);
671
+ }
672
+ // ============================================================================
673
+ // Zod Schemas
674
+ // ============================================================================
675
+ /**
676
+ * Zod schema for CAR string validation.
677
+ */
678
+ exports.carStringSchema = zod_1.z.string().refine((val) => exports.CAR_REGEX.test(val), {
679
+ message: 'Invalid CAR format. Expected: registry.org.class:DOMAINS-Ln@x.y.z[#extensions]',
680
+ });
681
+ /** @deprecated Use carStringSchema instead */
682
+ exports.aciStringSchema = exports.carStringSchema;
683
+ /**
684
+ * Zod schema for CAR string with parsing transform.
685
+ */
686
+ exports.carSchema = exports.carStringSchema.transform((car) => parseCAR(car));
687
+ /** @deprecated Use carSchema instead */
688
+ exports.aciSchema = exports.carStringSchema.transform((aci) => parseACI(aci));
689
+ /**
690
+ * Zod schema for GenerateCAROptions.
691
+ */
692
+ exports.generateCAROptionsSchema = zod_1.z.object({
693
+ registry: zod_1.z.string().min(1).regex(/^[a-z0-9]+$/),
694
+ organization: zod_1.z.string().min(1).regex(/^[a-z0-9-]+$/),
695
+ agentClass: zod_1.z.string().min(1).regex(/^[a-z0-9-]+$/),
696
+ domains: zod_1.z.array(zod_1.z.enum(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'S'])).min(1),
697
+ level: zod_1.z.nativeEnum(levels_js_1.CapabilityLevel),
698
+ version: zod_1.z.string().regex(/^\d+\.\d+\.\d+$/),
699
+ extensions: zod_1.z.array(zod_1.z.string().regex(/^[a-z0-9_-]+$/)).optional(),
700
+ });
701
+ /** @deprecated Use generateCAROptionsSchema instead */
702
+ exports.generateACIOptionsSchema = exports.generateCAROptionsSchema;
703
+ /**
704
+ * Zod schema for CARValidationError.
705
+ */
706
+ exports.carValidationErrorSchema = zod_1.z.object({
707
+ code: zod_1.z.string(),
708
+ message: zod_1.z.string(),
709
+ path: zod_1.z.string().optional(),
710
+ });
711
+ /** @deprecated Use carValidationErrorSchema instead */
712
+ exports.aciValidationErrorSchema = exports.carValidationErrorSchema;
713
+ /**
714
+ * Zod schema for CARValidationWarning.
715
+ */
716
+ exports.carValidationWarningSchema = zod_1.z.object({
717
+ code: zod_1.z.string(),
718
+ message: zod_1.z.string(),
719
+ path: zod_1.z.string().optional(),
720
+ });
721
+ /** @deprecated Use carValidationWarningSchema instead */
722
+ exports.aciValidationWarningSchema = exports.carValidationWarningSchema;
723
+ /**
724
+ * Zod schema for CARValidationResult.
725
+ */
726
+ exports.carValidationResultSchema = zod_1.z.object({
727
+ valid: zod_1.z.boolean(),
728
+ errors: zod_1.z.array(exports.carValidationErrorSchema),
729
+ warnings: zod_1.z.array(exports.carValidationWarningSchema),
730
+ parsed: exports.parsedCARSchema.optional(),
731
+ });
732
+ /** @deprecated Use carValidationResultSchema instead */
733
+ exports.aciValidationResultSchema = exports.carValidationResultSchema;
734
+ //# sourceMappingURL=car-string.js.map