@holoscript/core 6.0.3 → 7.0.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.
Files changed (244) hide show
  1. package/README.md +40 -40
  2. package/dist/codebase/index.d.ts +25 -0
  3. package/dist/compiler/index.d.ts +82 -0
  4. package/dist/constants.d.ts +4 -0
  5. package/dist/coordinators/index.d.ts +189 -0
  6. package/dist/entries/interop.d.ts +9 -0
  7. package/dist/entries/scripting.d.ts +7 -0
  8. package/dist/index.d.ts +520 -19
  9. package/dist/paper-0c-spike/index.d.ts +29 -0
  10. package/dist/reconstruction/index.d.ts +78 -0
  11. package/dist/self-improvement/index.d.ts +0 -48
  12. package/dist/storage/index.d.ts +24 -0
  13. package/dist/tools/index.d.ts +33 -0
  14. package/dist/traitDocs/traitDocs.d.ts +69 -0
  15. package/dist/traits/index.d.ts +61 -0
  16. package/package.json +102 -19
  17. package/dist/GLTFPipeline-3KLWWUQO.cjs +0 -34
  18. package/dist/GLTFPipeline-LYII2ZVQ.js +0 -13
  19. package/dist/HoloScriptPlusParser-BZR5DELQ.js +0 -692
  20. package/dist/HoloScriptPlusParser-SBMYDNXO.cjs +0 -697
  21. package/dist/USDZExporter-MHEHXZB4.cjs +0 -709
  22. package/dist/USDZExporter-YA55ZS35.js +0 -707
  23. package/dist/chunk-26TLYBFD.js +0 -309
  24. package/dist/chunk-27LWW5FU.cjs +0 -410
  25. package/dist/chunk-2UX5LRAP.cjs +0 -833
  26. package/dist/chunk-32TWR3HE.js +0 -70
  27. package/dist/chunk-3FXV5S25.cjs +0 -633
  28. package/dist/chunk-3FYZOR7S.cjs +0 -69
  29. package/dist/chunk-3KEU5QYY.cjs +0 -175
  30. package/dist/chunk-4FCZDTD5.js +0 -610
  31. package/dist/chunk-4KJ2R7VP.cjs +0 -507
  32. package/dist/chunk-4SMUJFHL.js +0 -1213
  33. package/dist/chunk-54FHG2MX.js +0 -655
  34. package/dist/chunk-56IF4NTA.js +0 -56
  35. package/dist/chunk-5GLCTO44.js +0 -161
  36. package/dist/chunk-5TOFIR6L.js +0 -407
  37. package/dist/chunk-65RFOWZI.js +0 -765
  38. package/dist/chunk-6OQBLABR.js +0 -5240
  39. package/dist/chunk-6WNCRE6F.js +0 -126
  40. package/dist/chunk-74YCHHTE.js +0 -1872
  41. package/dist/chunk-7H5UNJZD.cjs +0 -1973
  42. package/dist/chunk-7KPI4EKH.cjs +0 -701
  43. package/dist/chunk-7LCYLPW2.cjs +0 -663
  44. package/dist/chunk-7N3JIJMT.js +0 -1395
  45. package/dist/chunk-7X2IEJIE.cjs +0 -2526
  46. package/dist/chunk-A6GO3DPZ.cjs +0 -1002
  47. package/dist/chunk-AC4BSHFV.js +0 -765
  48. package/dist/chunk-AIUXRS74.cjs +0 -3681
  49. package/dist/chunk-ARNKA274.cjs +0 -130
  50. package/dist/chunk-AW7WAELW.js +0 -975
  51. package/dist/chunk-BKIGPPVM.js +0 -629
  52. package/dist/chunk-BO2OKHIY.js +0 -6055
  53. package/dist/chunk-BU5ZAFMC.js +0 -115
  54. package/dist/chunk-BY3B7ZYV.cjs +0 -457
  55. package/dist/chunk-C2QHVHZF.js +0 -4066
  56. package/dist/chunk-C7BNX4XJ.js +0 -1043
  57. package/dist/chunk-CLYEIWA5.cjs +0 -408
  58. package/dist/chunk-CMYAWUX3.js +0 -4455
  59. package/dist/chunk-CN4NOESF.cjs +0 -416
  60. package/dist/chunk-CNVM7J3M.js +0 -883
  61. package/dist/chunk-CO2VM2DK.js +0 -1965
  62. package/dist/chunk-CQDOF3G7.cjs +0 -1404
  63. package/dist/chunk-DH5G2JUA.cjs +0 -614
  64. package/dist/chunk-DIEDKX5B.cjs +0 -660
  65. package/dist/chunk-DN7UFU63.cjs +0 -172
  66. package/dist/chunk-DXVCEFZB.js +0 -2027
  67. package/dist/chunk-EGIZHYJP.cjs +0 -85
  68. package/dist/chunk-EJA7G2C4.cjs +0 -428
  69. package/dist/chunk-ELLQPFAF.js +0 -830
  70. package/dist/chunk-EMO7HAKJ.cjs +0 -1875
  71. package/dist/chunk-ENV7K6XA.js +0 -282
  72. package/dist/chunk-EPWRXL6S.js +0 -2522
  73. package/dist/chunk-EUFLX2PI.js +0 -56956
  74. package/dist/chunk-F5LVGHNT.js +0 -449
  75. package/dist/chunk-FEFHPUEM.cjs +0 -6122
  76. package/dist/chunk-FF3Q7ADR.js +0 -380
  77. package/dist/chunk-GC3YU46J.js +0 -762
  78. package/dist/chunk-H6WMMLQK.cjs +0 -4492
  79. package/dist/chunk-H7XMORZI.js +0 -2731
  80. package/dist/chunk-HAN4V3PF.cjs +0 -2037
  81. package/dist/chunk-HBZYCASG.js +0 -4208
  82. package/dist/chunk-HF4OFY25.cjs +0 -4097
  83. package/dist/chunk-HHS6FMOU.cjs +0 -3813
  84. package/dist/chunk-HJJLD366.js +0 -1169
  85. package/dist/chunk-HKCVM6OK.cjs +0 -2237
  86. package/dist/chunk-HUFNKFA6.js +0 -698
  87. package/dist/chunk-I3XGTIHM.cjs +0 -1505
  88. package/dist/chunk-I6XZ5DZF.cjs +0 -488
  89. package/dist/chunk-IHOUYQIA.js +0 -406
  90. package/dist/chunk-ILRBGFVD.cjs +0 -72
  91. package/dist/chunk-KDB6BUMB.js +0 -3666
  92. package/dist/chunk-KUJRR4FJ.js +0 -657
  93. package/dist/chunk-KYM4XRFG.js +0 -421
  94. package/dist/chunk-L3Z2HIWJ.cjs +0 -793
  95. package/dist/chunk-LBPEZQAF.js +0 -2232
  96. package/dist/chunk-LER4WXW5.cjs +0 -286
  97. package/dist/chunk-LK5IAVH6.cjs +0 -1173
  98. package/dist/chunk-M6FU6S22.js +0 -2911
  99. package/dist/chunk-MWEFR6YQ.js +0 -1857
  100. package/dist/chunk-N5FTS757.cjs +0 -415
  101. package/dist/chunk-NCUHGRTZ.js +0 -752
  102. package/dist/chunk-NKRKT6V2.js +0 -69
  103. package/dist/chunk-NLPSZT4C.js +0 -630
  104. package/dist/chunk-NRUB55IT.cjs +0 -771
  105. package/dist/chunk-NTMZSDXM.cjs +0 -633
  106. package/dist/chunk-ODGMVILH.js +0 -9662
  107. package/dist/chunk-PBA6NXCT.cjs +0 -1216
  108. package/dist/chunk-PHENW4MQ.js +0 -65
  109. package/dist/chunk-PJMOXFPR.cjs +0 -1861
  110. package/dist/chunk-PLMYCCA4.js +0 -504
  111. package/dist/chunk-PPULB4GG.cjs +0 -9728
  112. package/dist/chunk-PQLGZKMC.cjs +0 -755
  113. package/dist/chunk-Q56TT7IL.js +0 -483
  114. package/dist/chunk-QHVVVN47.cjs +0 -2033
  115. package/dist/chunk-QWKUKVRE.js +0 -2026
  116. package/dist/chunk-RE3OKSYF.cjs +0 -424
  117. package/dist/chunk-RT7LJRSF.cjs +0 -57378
  118. package/dist/chunk-SPDELRRV.cjs +0 -319
  119. package/dist/chunk-SUCBB66F.js +0 -229
  120. package/dist/chunk-TSWTWZ42.cjs +0 -4214
  121. package/dist/chunk-UITWA6DV.cjs +0 -2829
  122. package/dist/chunk-UQW6SLM5.js +0 -172
  123. package/dist/chunk-V2ILLPHK.cjs +0 -237
  124. package/dist/chunk-V42NTCFH.js +0 -3645
  125. package/dist/chunk-VJ3L7CHT.cjs +0 -169
  126. package/dist/chunk-VJVCD5T5.cjs +0 -769
  127. package/dist/chunk-VK5AXKO3.js +0 -746
  128. package/dist/chunk-VSXOIUCF.cjs +0 -473
  129. package/dist/chunk-VZNKJZTT.cjs +0 -749
  130. package/dist/chunk-W76ETJTI.js +0 -678
  131. package/dist/chunk-WFJIDI2N.cjs +0 -424
  132. package/dist/chunk-WN3YF33G.cjs +0 -118
  133. package/dist/chunk-WUXIRGZP.cjs +0 -2915
  134. package/dist/chunk-WYH4GVZ5.js +0 -1488
  135. package/dist/chunk-X4YVN7H3.cjs +0 -888
  136. package/dist/chunk-X67XRI2T.js +0 -410
  137. package/dist/chunk-XDXZM3ZP.cjs +0 -1046
  138. package/dist/chunk-XH7SE4HH.cjs +0 -72
  139. package/dist/chunk-XNMEH2BI.js +0 -126
  140. package/dist/chunk-XSF76QRU.js +0 -468
  141. package/dist/chunk-XSUZMPVQ.cjs +0 -682
  142. package/dist/chunk-XUILI4KB.cjs +0 -430
  143. package/dist/chunk-Y5MUAYTO.js +0 -167
  144. package/dist/chunk-Y7VK5TH3.cjs +0 -129
  145. package/dist/chunk-YCMQQQ5U.cjs +0 -5244
  146. package/dist/chunk-YYXH45E2.js +0 -426
  147. package/dist/chunk-ZGTGVSTZ.js +0 -422
  148. package/dist/chunk-ZL6VJ6SN.js +0 -421
  149. package/dist/cli/holoscript-runner.cjs +0 -2258
  150. package/dist/cli/holoscript-runner.js +0 -2233
  151. package/dist/codebase/index.cjs +0 -336
  152. package/dist/codebase/index.js +0 -331
  153. package/dist/compiler/agent-inference.cjs +0 -29
  154. package/dist/compiler/agent-inference.js +0 -6
  155. package/dist/compiler/android-xr.cjs +0 -20
  156. package/dist/compiler/android-xr.js +0 -10
  157. package/dist/compiler/android.cjs +0 -21
  158. package/dist/compiler/android.js +0 -11
  159. package/dist/compiler/ar.cjs +0 -21
  160. package/dist/compiler/ar.js +0 -9
  161. package/dist/compiler/babylon.cjs +0 -18
  162. package/dist/compiler/babylon.js +0 -12
  163. package/dist/compiler/coco.cjs +0 -27
  164. package/dist/compiler/coco.js +0 -4
  165. package/dist/compiler/domain-block-utils.cjs +0 -595
  166. package/dist/compiler/domain-block-utils.js +0 -9
  167. package/dist/compiler/dtdl.cjs +0 -25
  168. package/dist/compiler/dtdl.js +0 -9
  169. package/dist/compiler/gltf-pipeline.cjs +0 -39
  170. package/dist/compiler/gltf-pipeline.js +0 -4
  171. package/dist/compiler/godot.cjs +0 -16
  172. package/dist/compiler/godot.js +0 -10
  173. package/dist/compiler/incremental.cjs +0 -30
  174. package/dist/compiler/incremental.js +0 -5
  175. package/dist/compiler/index.cjs +0 -1522
  176. package/dist/compiler/index.js +0 -1321
  177. package/dist/compiler/ios.cjs +0 -21
  178. package/dist/compiler/ios.js +0 -11
  179. package/dist/compiler/multi-layer.cjs +0 -27
  180. package/dist/compiler/multi-layer.js +0 -12
  181. package/dist/compiler/nodetoy.cjs +0 -23
  182. package/dist/compiler/nodetoy.js +0 -4
  183. package/dist/compiler/openxr.cjs +0 -16
  184. package/dist/compiler/openxr.js +0 -10
  185. package/dist/compiler/playcanvas.cjs +0 -17
  186. package/dist/compiler/playcanvas.js +0 -11
  187. package/dist/compiler/r3f.cjs +0 -35
  188. package/dist/compiler/r3f.js +0 -13
  189. package/dist/compiler/remotion.cjs +0 -23
  190. package/dist/compiler/remotion.js +0 -4
  191. package/dist/compiler/reproducibility.cjs +0 -39
  192. package/dist/compiler/reproducibility.js +0 -4
  193. package/dist/compiler/sdf.cjs +0 -22
  194. package/dist/compiler/sdf.js +0 -10
  195. package/dist/compiler/semantic-scene.cjs +0 -31
  196. package/dist/compiler/semantic-scene.js +0 -4
  197. package/dist/compiler/state.cjs +0 -18
  198. package/dist/compiler/state.js +0 -8
  199. package/dist/compiler/trait-composition.cjs +0 -27
  200. package/dist/compiler/trait-composition.js +0 -6
  201. package/dist/compiler/unity.cjs +0 -16
  202. package/dist/compiler/unity.js +0 -10
  203. package/dist/compiler/unreal.cjs +0 -20
  204. package/dist/compiler/unreal.js +0 -10
  205. package/dist/compiler/urdf.cjs +0 -46
  206. package/dist/compiler/urdf.js +0 -10
  207. package/dist/compiler/usd-physics.cjs +0 -24
  208. package/dist/compiler/usd-physics.js +0 -7
  209. package/dist/compiler/visionos.cjs +0 -16
  210. package/dist/compiler/visionos.js +0 -10
  211. package/dist/compiler/vrchat.cjs +0 -20
  212. package/dist/compiler/vrchat.js +0 -10
  213. package/dist/compiler/vrr.cjs +0 -22
  214. package/dist/compiler/vrr.js +0 -10
  215. package/dist/compiler/wasm.cjs +0 -34
  216. package/dist/compiler/wasm.js +0 -10
  217. package/dist/compiler/webgpu.cjs +0 -16
  218. package/dist/compiler/webgpu.js +0 -10
  219. package/dist/debugger.cjs +0 -21
  220. package/dist/debugger.js +0 -8
  221. package/dist/entries/interop.cjs +0 -62
  222. package/dist/entries/interop.js +0 -5
  223. package/dist/entries/scripting.cjs +0 -67
  224. package/dist/entries/scripting.js +0 -10
  225. package/dist/index.cjs +0 -61703
  226. package/dist/index.js +0 -58652
  227. package/dist/math/vec3.cjs +0 -57
  228. package/dist/math/vec3.js +0 -4
  229. package/dist/parser.cjs +0 -26
  230. package/dist/parser.js +0 -9
  231. package/dist/playwright-7DTEQCBD.cjs +0 -98673
  232. package/dist/playwright-BIZXMLD2.js +0 -98660
  233. package/dist/post-quantum-JTTAAGO3.cjs +0 -6
  234. package/dist/post-quantum-RVPVDEPI.js +0 -4
  235. package/dist/runtime.cjs +0 -16
  236. package/dist/runtime.js +0 -7
  237. package/dist/storage/index.cjs +0 -37
  238. package/dist/storage/index.js +0 -4
  239. package/dist/traits/index.cjs +0 -14331
  240. package/dist/traits/index.js +0 -12126
  241. package/dist/type-checker.cjs +0 -18
  242. package/dist/type-checker.js +0 -5
  243. package/dist/wot/index.cjs +0 -29
  244. package/dist/wot/index.js +0 -4
@@ -1,3645 +0,0 @@
1
- import { __esm } from './chunk-32TWR3HE.js';
2
- import * as crypto3 from 'crypto';
3
- import { promisify } from 'util';
4
- import jwt from 'jsonwebtoken';
5
- import path from 'path';
6
-
7
- function calculateJwkThumbprint(publicKeyPem) {
8
- const keyObject = crypto3.createPublicKey(publicKeyPem);
9
- const jwk = keyObject.export({ format: "jwk" });
10
- const canonical = buildCanonicalJwk(jwk);
11
- const json = JSON.stringify(canonical);
12
- return crypto3.createHash("sha256").update(json).digest("base64url");
13
- }
14
- function buildCanonicalJwk(jwk) {
15
- const kty = jwk.kty;
16
- switch (kty) {
17
- case "RSA": {
18
- const e = jwk.e;
19
- const n = jwk.n;
20
- if (!e || !n) {
21
- throw new Error("RSA JWK missing required members: e, n");
22
- }
23
- return { e, kty: "RSA", n };
24
- }
25
- case "EC": {
26
- const crv = jwk.crv;
27
- const x = jwk.x;
28
- const y = jwk.y;
29
- if (!crv || !x || !y) {
30
- throw new Error("EC JWK missing required members: crv, x, y");
31
- }
32
- return { crv, kty: "EC", x, y };
33
- }
34
- case "OKP": {
35
- const crv = jwk.crv;
36
- const x = jwk.x;
37
- if (!crv || !x) {
38
- throw new Error("OKP JWK missing required members: crv, x");
39
- }
40
- return { crv, kty: "OKP", x };
41
- }
42
- default:
43
- throw new Error(`Unsupported JWK key type: ${kty ?? "(undefined)"}`);
44
- }
45
- }
46
- var init_JwkThumbprint = __esm({
47
- "src/compiler/identity/JwkThumbprint.ts"() {
48
- }
49
- });
50
- function calculateAgentChecksum(config) {
51
- const canonical = {
52
- role: config.role,
53
- name: config.name,
54
- version: config.version,
55
- prompt: config.prompt || "",
56
- tools: (config.tools || []).sort(),
57
- // Sort for determinism
58
- configuration: config.configuration || {},
59
- culturalProfile: config.culturalProfile || null
60
- };
61
- const serialized = JSON.stringify(canonical);
62
- const hash = crypto3.createHash("sha256").update(serialized).digest("hex");
63
- return {
64
- hash,
65
- algorithm: "sha256",
66
- calculatedAt: (/* @__PURE__ */ new Date()).toISOString(),
67
- label: `${config.role}:${config.name}:${config.version}`
68
- };
69
- }
70
- async function generateAgentKeyPair(agentRole, timestamp) {
71
- if (!generateKeyPairAsync) {
72
- throw new Error(
73
- "crypto.generateKeyPair is unavailable in this environment (browser). Key pair generation requires a Node.js runtime."
74
- );
75
- }
76
- const { publicKey, privateKey } = await generateKeyPairAsync("ed25519", {
77
- publicKeyEncoding: {
78
- type: "spki",
79
- format: "pem"
80
- },
81
- privateKeyEncoding: {
82
- type: "pkcs8",
83
- format: "pem"
84
- }
85
- });
86
- const ts = /* @__PURE__ */ new Date();
87
- const kid = `agent:${agentRole}#${ts.toISOString()}`;
88
- const thumbprint = calculateJwkThumbprint(publicKey);
89
- return {
90
- publicKey,
91
- privateKey,
92
- kid,
93
- thumbprint
94
- };
95
- }
96
- function isValidWorkflowTransition(currentStep, nextStep) {
97
- const validNextSteps = WORKFLOW_SEQUENCES[currentStep];
98
- return validNextSteps.includes(nextStep);
99
- }
100
- function getDefaultPermissions(role) {
101
- return [...ROLE_PERMISSIONS[role]];
102
- }
103
- var generateKeyPairAsync, AgentPermission, WorkflowStep, ROLE_PERMISSIONS, WORKFLOW_SEQUENCES;
104
- var init_AgentIdentity = __esm({
105
- "src/compiler/identity/AgentIdentity.ts"() {
106
- init_JwkThumbprint();
107
- generateKeyPairAsync = typeof crypto3.generateKeyPair === "function" ? promisify(crypto3.generateKeyPair) : null;
108
- AgentPermission = /* @__PURE__ */ ((AgentPermission4) => {
109
- AgentPermission4["READ_SOURCE"] = "read:source";
110
- AgentPermission4["READ_CONFIG"] = "read:config";
111
- AgentPermission4["READ_AST"] = "read:ast";
112
- AgentPermission4["READ_IR"] = "read:ir";
113
- AgentPermission4["READ_CODE"] = "read:code";
114
- AgentPermission4["WRITE_AST"] = "write:ast";
115
- AgentPermission4["WRITE_IR"] = "write:ir";
116
- AgentPermission4["WRITE_CODE"] = "write:code";
117
- AgentPermission4["WRITE_OUTPUT"] = "write:output";
118
- AgentPermission4["TRANSFORM_AST"] = "transform:ast";
119
- AgentPermission4["TRANSFORM_IR"] = "transform:ir";
120
- AgentPermission4["EXECUTE_OPTIMIZATION"] = "execute:optimization";
121
- AgentPermission4["EXECUTE_CODEGEN"] = "execute:codegen";
122
- AgentPermission4["EXECUTE_EXPORT"] = "execute:export";
123
- return AgentPermission4;
124
- })(AgentPermission || {});
125
- WorkflowStep = /* @__PURE__ */ ((WorkflowStep3) => {
126
- WorkflowStep3["PARSE_TOKENS"] = "parse_tokens";
127
- WorkflowStep3["BUILD_AST"] = "build_ast";
128
- WorkflowStep3["ANALYZE_AST"] = "analyze_ast";
129
- WorkflowStep3["APPLY_TRANSFORMS"] = "apply_transforms";
130
- WorkflowStep3["SELECT_INSTRUCTIONS"] = "select_instructions";
131
- WorkflowStep3["GENERATE_ASSEMBLY"] = "generate_assembly";
132
- WorkflowStep3["FORMAT_OUTPUT"] = "format_output";
133
- WorkflowStep3["SERIALIZE"] = "serialize";
134
- return WorkflowStep3;
135
- })(WorkflowStep || {});
136
- ROLE_PERMISSIONS = {
137
- ["syntax_analyzer" /* SYNTAX_ANALYZER */]: [
138
- "read:source" /* READ_SOURCE */,
139
- "read:config" /* READ_CONFIG */,
140
- "write:ast" /* WRITE_AST */
141
- ],
142
- ["ast_optimizer" /* AST_OPTIMIZER */]: [
143
- "read:ast" /* READ_AST */,
144
- "read:config" /* READ_CONFIG */,
145
- "write:ast" /* WRITE_AST */,
146
- "transform:ast" /* TRANSFORM_AST */,
147
- "execute:optimization" /* EXECUTE_OPTIMIZATION */
148
- ],
149
- ["code_generator" /* CODE_GENERATOR */]: [
150
- "read:ast" /* READ_AST */,
151
- "read:ir" /* READ_IR */,
152
- "read:config" /* READ_CONFIG */,
153
- "write:ir" /* WRITE_IR */,
154
- "write:code" /* WRITE_CODE */,
155
- "transform:ir" /* TRANSFORM_IR */,
156
- "execute:codegen" /* EXECUTE_CODEGEN */
157
- ],
158
- ["exporter" /* EXPORTER */]: [
159
- "read:code" /* READ_CODE */,
160
- "read:config" /* READ_CONFIG */,
161
- "write:output" /* WRITE_OUTPUT */,
162
- "execute:export" /* EXECUTE_EXPORT */
163
- ],
164
- ["orchestrator" /* ORCHESTRATOR */]: [
165
- // Orchestrator has all permissions
166
- ...Object.values(AgentPermission)
167
- ]
168
- };
169
- WORKFLOW_SEQUENCES = {
170
- ["parse_tokens" /* PARSE_TOKENS */]: ["build_ast" /* BUILD_AST */],
171
- ["build_ast" /* BUILD_AST */]: ["analyze_ast" /* ANALYZE_AST */],
172
- ["analyze_ast" /* ANALYZE_AST */]: ["apply_transforms" /* APPLY_TRANSFORMS */],
173
- ["apply_transforms" /* APPLY_TRANSFORMS */]: ["select_instructions" /* SELECT_INSTRUCTIONS */],
174
- ["select_instructions" /* SELECT_INSTRUCTIONS */]: ["generate_assembly" /* GENERATE_ASSEMBLY */],
175
- ["generate_assembly" /* GENERATE_ASSEMBLY */]: ["format_output" /* FORMAT_OUTPUT */],
176
- ["format_output" /* FORMAT_OUTPUT */]: ["serialize" /* SERIALIZE */],
177
- ["serialize" /* SERIALIZE */]: []
178
- // Terminal step
179
- };
180
- }
181
- });
182
-
183
- // src/traits/CultureTraits.ts
184
- function getBuiltinNorm(id) {
185
- return BUILTIN_NORMS.find((n) => n.id === id);
186
- }
187
- function normsByCategory(category) {
188
- return BUILTIN_NORMS.filter((n) => n.category === category);
189
- }
190
- function criticalMassForChange(norm, populationSize) {
191
- const percentages = { weak: 0.02, moderate: 0.25, strong: 0.5 };
192
- return Math.ceil(populationSize * percentages[norm.strength]);
193
- }
194
- function getAllContradictoryNorms() {
195
- return [...CONTRADICTORY_NORM_PAIRS, ...customContradictoryNorms];
196
- }
197
- function getFamilyCompatibility(familyA, familyB) {
198
- if (familyA === familyB) {
199
- return { rating: "compatible", reason: "Same cultural family." };
200
- }
201
- for (const entry of CULTURAL_FAMILY_COMPATIBILITY) {
202
- if (entry.familyA === familyA && entry.familyB === familyB || entry.familyA === familyB && entry.familyB === familyA) {
203
- return { rating: entry.rating, reason: entry.reason };
204
- }
205
- }
206
- return { rating: "compatible", reason: "No known incompatibility between these families." };
207
- }
208
- var BUILTIN_NORMS, CULTURAL_FAMILY_COMPATIBILITY, CONTRADICTORY_NORM_PAIRS, customContradictoryNorms;
209
- var init_CultureTraits = __esm({
210
- "src/traits/CultureTraits.ts"() {
211
- BUILTIN_NORMS = [
212
- // Safety norms
213
- {
214
- id: "no_griefing",
215
- name: "No Griefing",
216
- category: "safety",
217
- description: "Agents must not intentionally harm or obstruct others",
218
- enforcement: "hard",
219
- scope: "world",
220
- activationThreshold: 0,
221
- strength: "strong",
222
- forbiddenEffects: ["agent:kill", "inventory:destroy", "physics:teleport"]
223
- },
224
- {
225
- id: "resource_sharing",
226
- name: "Resource Sharing",
227
- category: "cooperation",
228
- description: "Agents should share resources when others are in need",
229
- enforcement: "soft",
230
- scope: "zone",
231
- activationThreshold: 0.5,
232
- strength: "moderate",
233
- requiredEffects: ["inventory:give"]
234
- },
235
- {
236
- id: "zone_respect",
237
- name: "Zone Respect",
238
- category: "territory",
239
- description: "Agents must request permission before entering owned zones",
240
- enforcement: "soft",
241
- scope: "zone",
242
- activationThreshold: 0.3,
243
- strength: "moderate",
244
- requiredEffects: ["agent:communicate"],
245
- forbiddenEffects: ["authority:zone"]
246
- },
247
- {
248
- id: "fair_trade",
249
- name: "Fair Trade",
250
- category: "exchange",
251
- description: "Trade exchanges must be mutually agreed upon",
252
- enforcement: "hard",
253
- scope: "world",
254
- activationThreshold: 0,
255
- strength: "strong",
256
- requiredEffects: ["inventory:trade", "agent:communicate"]
257
- },
258
- {
259
- id: "greeting_convention",
260
- name: "Greeting Convention",
261
- category: "communication",
262
- description: "Agents should acknowledge each other when first meeting in a session",
263
- enforcement: "advisory",
264
- scope: "session",
265
- activationThreshold: 0.6,
266
- strength: "weak",
267
- requiredEffects: ["agent:communicate"]
268
- },
269
- {
270
- id: "noise_courtesy",
271
- name: "Noise Courtesy",
272
- category: "safety",
273
- description: "Agents should not play global audio without zone permission",
274
- enforcement: "soft",
275
- scope: "zone",
276
- activationThreshold: 0.4,
277
- strength: "moderate",
278
- forbiddenEffects: ["audio:global"]
279
- },
280
- {
281
- id: "spawn_limits",
282
- name: "Spawn Limits",
283
- category: "cooperation",
284
- description: "Agents should not spawn excessive objects in shared spaces",
285
- enforcement: "hard",
286
- scope: "zone",
287
- activationThreshold: 0,
288
- strength: "strong",
289
- forbiddenEffects: ["render:spawn"]
290
- // Catches excessive spawning via budget
291
- },
292
- {
293
- id: "metanorm_enforcement",
294
- name: "Meta-Norm: Enforce Norms",
295
- category: "authority",
296
- description: "Agents who witness norm violations should report them (norm about enforcing norms)",
297
- enforcement: "advisory",
298
- scope: "world",
299
- activationThreshold: 0.7,
300
- strength: "weak",
301
- requiredEffects: ["agent:communicate", "agent:observe"]
302
- }
303
- ];
304
- CULTURAL_FAMILY_COMPATIBILITY = [
305
- // Incompatible pairs
306
- {
307
- familyA: "competitive",
308
- familyB: "cooperative",
309
- rating: "incompatible",
310
- reason: "Competitive agents pursue individual gain, cooperative agents pursue shared goals. Fundamental goal misalignment."
311
- },
312
- {
313
- familyA: "hierarchical",
314
- familyB: "egalitarian",
315
- rating: "incompatible",
316
- reason: "Hierarchical agents expect chain of command, egalitarian agents reject authority structures."
317
- },
318
- {
319
- familyA: "isolationist",
320
- familyB: "cooperative",
321
- rating: "incompatible",
322
- reason: "Isolationist agents refuse interaction, cooperative agents require mutual engagement."
323
- },
324
- // Cautious pairs (can work with mediation)
325
- {
326
- familyA: "competitive",
327
- familyB: "egalitarian",
328
- rating: "cautious",
329
- reason: "Competitive ranking conflicts with equal-voice principles. Needs mediation."
330
- },
331
- {
332
- familyA: "isolationist",
333
- familyB: "ritualistic",
334
- rating: "cautious",
335
- reason: "Isolationist independence conflicts with group ceremony requirements. Needs mediation."
336
- },
337
- {
338
- familyA: "mercantile",
339
- familyB: "cooperative",
340
- rating: "cautious",
341
- reason: "Mercantile agents expect value exchange, cooperative agents share freely. Needs mediation."
342
- },
343
- {
344
- familyA: "competitive",
345
- familyB: "hierarchical",
346
- rating: "cautious",
347
- reason: "Competitive agents may challenge authority. Needs clear ranking rules."
348
- },
349
- {
350
- familyA: "isolationist",
351
- familyB: "hierarchical",
352
- rating: "cautious",
353
- reason: "Isolationist agents resist authority. Needs minimal supervision protocols."
354
- }
355
- ];
356
- CONTRADICTORY_NORM_PAIRS = [
357
- {
358
- normA: "resource_sharing",
359
- normB: "spawn_limits",
360
- reason: "Resource sharing may require spawning items, but spawn limits restrict it."
361
- }
362
- // Users can extend this set via registerContradictoryNorms()
363
- ];
364
- customContradictoryNorms = [];
365
- }
366
- });
367
- function getKeystore(config) {
368
- if (!globalKeystore) {
369
- const masterKeyHex = process.env.AGENT_KEYSTORE_MASTER_KEY;
370
- const masterKey = masterKeyHex ? Buffer.from(masterKeyHex, "hex") : void 0;
371
- globalKeystore = new AgentKeystore({
372
- ...config,
373
- masterKey
374
- });
375
- }
376
- return globalKeystore;
377
- }
378
- var DEFAULT_TOKEN_LIFETIME, ENCRYPTION_ALGORITHM, KEY_LENGTH, IV_LENGTH, SALT_LENGTH, AgentKeystore, globalKeystore;
379
- var init_AgentKeystore = __esm({
380
- "src/compiler/identity/AgentKeystore.ts"() {
381
- init_AgentIdentity();
382
- DEFAULT_TOKEN_LIFETIME = 24 * 60 * 60 * 1e3;
383
- ENCRYPTION_ALGORITHM = "aes-256-gcm";
384
- KEY_LENGTH = 32;
385
- IV_LENGTH = 16;
386
- SALT_LENGTH = 64;
387
- AgentKeystore = class {
388
- constructor(config = {}) {
389
- /** In-memory credential cache (ephemeral, cleared on restart) */
390
- this.credentialCache = /* @__PURE__ */ new Map();
391
- /** Persistent encrypted storage (simulated with Map, replace with file/db in production) */
392
- this.encryptedStorage = /* @__PURE__ */ new Map();
393
- /** Secondary index: JWK thumbprint → AgentRole, for fast PoP key lookup */
394
- this.thumbprintIndex = /* @__PURE__ */ new Map();
395
- /** Audit log buffer */
396
- this.auditLog = [];
397
- this.masterKey = config.masterKey || crypto3.randomBytes(KEY_LENGTH);
398
- this.tokenLifetime = config.tokenLifetime || DEFAULT_TOKEN_LIFETIME;
399
- this.enableAuditLog = config.enableAuditLog ?? true;
400
- this.auditLogPath = config.auditLogPath || "./agent-keystore.audit.log";
401
- if (!config.masterKey && process.env.NODE_ENV === "production") {
402
- console.warn(
403
- "[KEYSTORE] Using generated master key. Set AGENT_KEYSTORE_MASTER_KEY environment variable in production."
404
- );
405
- }
406
- }
407
- /**
408
- * Encrypt sensitive data using AES-256-GCM
409
- */
410
- encrypt(plaintext) {
411
- const iv = crypto3.randomBytes(IV_LENGTH);
412
- const salt = crypto3.randomBytes(SALT_LENGTH);
413
- const key = crypto3.pbkdf2Sync(this.masterKey, salt, 1e5, KEY_LENGTH, "sha256");
414
- const cipher = crypto3.createCipheriv(ENCRYPTION_ALGORITHM, key, iv);
415
- let ciphertext = cipher.update(plaintext, "utf8", "hex");
416
- ciphertext += cipher.final("hex");
417
- const authTag = cipher.getAuthTag();
418
- return {
419
- ciphertext,
420
- iv: iv.toString("hex"),
421
- authTag: authTag.toString("hex"),
422
- salt: salt.toString("hex"),
423
- algorithm: ENCRYPTION_ALGORITHM,
424
- createdAt: (/* @__PURE__ */ new Date()).toISOString(),
425
- expiresAt: new Date(Date.now() + this.tokenLifetime).toISOString()
426
- };
427
- }
428
- /**
429
- * Decrypt sensitive data
430
- */
431
- decrypt(encrypted) {
432
- const iv = Buffer.from(encrypted.iv, "hex");
433
- const salt = Buffer.from(encrypted.salt, "hex");
434
- const authTag = Buffer.from(encrypted.authTag, "hex");
435
- const key = crypto3.pbkdf2Sync(this.masterKey, salt, 1e5, KEY_LENGTH, "sha256");
436
- const decipher = crypto3.createDecipheriv(ENCRYPTION_ALGORITHM, key, iv);
437
- decipher.setAuthTag(authTag);
438
- let plaintext = decipher.update(encrypted.ciphertext, "hex", "utf8");
439
- plaintext += decipher.final("utf8");
440
- return plaintext;
441
- }
442
- /**
443
- * Log audit event
444
- */
445
- logAudit(entry) {
446
- if (!this.enableAuditLog) return;
447
- this.auditLog.push(entry);
448
- if (process.env.NODE_ENV === "production") {
449
- console.info(`[AUDIT] ${entry.event} - ${entry.agentRole} - ${entry.timestamp}`);
450
- }
451
- }
452
- /**
453
- * Store agent credential securely
454
- */
455
- async storeCredential(credential) {
456
- const existing = this.credentialCache.get(credential.role);
457
- if (existing) {
458
- this.thumbprintIndex.delete(existing.keyPair.thumbprint);
459
- }
460
- this.credentialCache.set(credential.role, credential);
461
- this.thumbprintIndex.set(credential.keyPair.thumbprint, credential.role);
462
- const serialized = JSON.stringify({
463
- role: credential.role,
464
- token: credential.token,
465
- keyPair: credential.keyPair,
466
- createdAt: credential.createdAt.toISOString(),
467
- expiresAt: credential.expiresAt.toISOString()
468
- });
469
- const encrypted = this.encrypt(serialized);
470
- this.encryptedStorage.set(credential.role, encrypted);
471
- this.logAudit({
472
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
473
- event: "key_generated",
474
- agentRole: credential.role,
475
- details: {
476
- kid: credential.keyPair.kid,
477
- expiresAt: credential.expiresAt.toISOString()
478
- }
479
- });
480
- }
481
- /**
482
- * Retrieve agent credential
483
- *
484
- * Returns cached credential if valid, otherwise decrypts from storage.
485
- * Automatically rotates if expired.
486
- */
487
- async getCredential(role) {
488
- const cached = this.credentialCache.get(role);
489
- if (cached && cached.expiresAt > /* @__PURE__ */ new Date()) {
490
- this.logAudit({
491
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
492
- event: "key_accessed",
493
- agentRole: role,
494
- details: { source: "cache" }
495
- });
496
- return cached;
497
- }
498
- const encrypted = this.encryptedStorage.get(role);
499
- if (!encrypted) {
500
- return null;
501
- }
502
- if (new Date(encrypted.expiresAt) < /* @__PURE__ */ new Date()) {
503
- this.logAudit({
504
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
505
- event: "key_expired",
506
- agentRole: role
507
- });
508
- await this.rotateCredential(role);
509
- return this.getCredential(role);
510
- }
511
- const decrypted = this.decrypt(encrypted);
512
- const parsed = JSON.parse(decrypted);
513
- const credential = {
514
- role: parsed.role,
515
- token: parsed.token,
516
- keyPair: parsed.keyPair,
517
- createdAt: new Date(parsed.createdAt),
518
- expiresAt: new Date(parsed.expiresAt)
519
- };
520
- this.credentialCache.set(role, credential);
521
- this.logAudit({
522
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
523
- event: "key_accessed",
524
- agentRole: role,
525
- details: { source: "storage" }
526
- });
527
- return credential;
528
- }
529
- /**
530
- * Rotate agent credential (generate new keys and token)
531
- */
532
- async rotateCredential(role) {
533
- const keyPair = await generateAgentKeyPair(role);
534
- const credential = {
535
- role,
536
- token: "",
537
- // Placeholder, will be set by token issuer
538
- keyPair,
539
- createdAt: /* @__PURE__ */ new Date(),
540
- expiresAt: new Date(Date.now() + this.tokenLifetime)
541
- };
542
- await this.storeCredential(credential);
543
- this.logAudit({
544
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
545
- event: "key_rotated",
546
- agentRole: role,
547
- details: {
548
- oldKid: this.credentialCache.get(role)?.keyPair.kid,
549
- newKid: keyPair.kid
550
- }
551
- });
552
- return credential;
553
- }
554
- /**
555
- * Retrieve credential by JWK thumbprint (for PoP token verification).
556
- *
557
- * Returns the credential whose key pair matches the given JWK SHA-256
558
- * thumbprint, or null if no matching credential is found.
559
- *
560
- * Primary lookup uses the in-memory index; falls back to decrypting all
561
- * stored credentials when the index doesn't contain the thumbprint (e.g.
562
- * credentials stored before the index was introduced).
563
- */
564
- async getCredentialByThumbprint(thumbprint) {
565
- const role = this.thumbprintIndex.get(thumbprint);
566
- if (role) {
567
- return this.getCredential(role);
568
- }
569
- for (const [storedRole, encrypted] of this.encryptedStorage.entries()) {
570
- if (new Date(encrypted.expiresAt) < /* @__PURE__ */ new Date()) {
571
- continue;
572
- }
573
- const credential = await this.getCredential(storedRole);
574
- if (credential) {
575
- this.thumbprintIndex.set(credential.keyPair.thumbprint, storedRole);
576
- if (credential.keyPair.thumbprint === thumbprint) {
577
- return credential;
578
- }
579
- }
580
- }
581
- return null;
582
- }
583
- /**
584
- * Delete agent credential
585
- */
586
- async deleteCredential(role) {
587
- const credential = this.credentialCache.get(role);
588
- if (credential) {
589
- this.thumbprintIndex.delete(credential.keyPair.thumbprint);
590
- }
591
- this.credentialCache.delete(role);
592
- this.encryptedStorage.delete(role);
593
- this.logAudit({
594
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
595
- event: "key_deleted",
596
- agentRole: role
597
- });
598
- }
599
- /**
600
- * List all stored credentials (metadata only)
601
- */
602
- listCredentials() {
603
- return Array.from(this.encryptedStorage.entries()).map(([role, encrypted]) => ({
604
- role,
605
- createdAt: encrypted.createdAt,
606
- expiresAt: encrypted.expiresAt,
607
- isExpired: new Date(encrypted.expiresAt) < /* @__PURE__ */ new Date()
608
- }));
609
- }
610
- /**
611
- * Get audit log
612
- */
613
- getAuditLog() {
614
- return [...this.auditLog];
615
- }
616
- /**
617
- * Clear all credentials (use with caution)
618
- */
619
- clearAll() {
620
- this.credentialCache.clear();
621
- this.encryptedStorage.clear();
622
- this.thumbprintIndex.clear();
623
- this.logAudit({
624
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
625
- event: "key_deleted",
626
- agentRole: "orchestrator" /* ORCHESTRATOR */,
627
- details: { action: "clear_all" }
628
- });
629
- }
630
- };
631
- globalKeystore = null;
632
- }
633
- });
634
-
635
- // src/compiler/identity/CapabilityToken.ts
636
- var HOLOSCRIPT_RESOURCE_SCHEME, HOLOSCRIPT_RESOURCE_ALL, CapabilityActions, PERMISSION_TO_ACTION;
637
- var init_CapabilityToken = __esm({
638
- "src/compiler/identity/CapabilityToken.ts"() {
639
- HOLOSCRIPT_RESOURCE_SCHEME = "holoscript://";
640
- HOLOSCRIPT_RESOURCE_ALL = "holoscript://*";
641
- CapabilityActions = {
642
- // Source
643
- SOURCE_READ: "source/read",
644
- // Config
645
- CONFIG_READ: "config/read",
646
- // AST
647
- AST_READ: "ast/read",
648
- AST_WRITE: "ast/write",
649
- AST_TRANSFORM: "ast/transform",
650
- // IR
651
- IR_READ: "ir/read",
652
- IR_WRITE: "ir/write",
653
- IR_TRANSFORM: "ir/transform",
654
- // Code
655
- CODE_READ: "code/read",
656
- CODE_WRITE: "code/write",
657
- // Output
658
- OUTPUT_WRITE: "output/write",
659
- // Execution
660
- EXECUTE_OPTIMIZATION: "execute/optimization",
661
- EXECUTE_CODEGEN: "execute/codegen",
662
- EXECUTE_EXPORT: "execute/export",
663
- // Proof-of-Play (computation attestation)
664
- PROOF_OF_PLAY_WRITE: "proof_of_play/write",
665
- PROOF_OF_PLAY_READ: "proof_of_play/read",
666
- PROOF_OF_PLAY_VERIFY: "proof_of_play/verify",
667
- // Wildcard (orchestrator only)
668
- ALL: "*"
669
- };
670
- PERMISSION_TO_ACTION = {
671
- ["read:source" /* READ_SOURCE */]: CapabilityActions.SOURCE_READ,
672
- ["read:config" /* READ_CONFIG */]: CapabilityActions.CONFIG_READ,
673
- ["read:ast" /* READ_AST */]: CapabilityActions.AST_READ,
674
- ["read:ir" /* READ_IR */]: CapabilityActions.IR_READ,
675
- ["read:code" /* READ_CODE */]: CapabilityActions.CODE_READ,
676
- ["write:ast" /* WRITE_AST */]: CapabilityActions.AST_WRITE,
677
- ["write:ir" /* WRITE_IR */]: CapabilityActions.IR_WRITE,
678
- ["write:code" /* WRITE_CODE */]: CapabilityActions.CODE_WRITE,
679
- ["write:output" /* WRITE_OUTPUT */]: CapabilityActions.OUTPUT_WRITE,
680
- ["transform:ast" /* TRANSFORM_AST */]: CapabilityActions.AST_TRANSFORM,
681
- ["transform:ir" /* TRANSFORM_IR */]: CapabilityActions.IR_TRANSFORM,
682
- ["execute:optimization" /* EXECUTE_OPTIMIZATION */]: CapabilityActions.EXECUTE_OPTIMIZATION,
683
- ["execute:codegen" /* EXECUTE_CODEGEN */]: CapabilityActions.EXECUTE_CODEGEN,
684
- ["execute:export" /* EXECUTE_EXPORT */]: CapabilityActions.EXECUTE_EXPORT
685
- };
686
- Object.fromEntries(
687
- Object.entries(PERMISSION_TO_ACTION).map(([perm, action]) => [action, perm])
688
- );
689
- }
690
- });
691
- function base64urlEncode(data) {
692
- const buf = typeof data === "string" ? Buffer.from(data, "utf-8") : data;
693
- return buf.toString("base64url");
694
- }
695
- function base64urlDecode(str) {
696
- return Buffer.from(str, "base64url");
697
- }
698
- function getCapabilityTokenIssuer(config) {
699
- if (!globalCapabilityIssuer) {
700
- globalCapabilityIssuer = new CapabilityTokenIssuer(config);
701
- }
702
- return globalCapabilityIssuer;
703
- }
704
- var HoloScriptCapabilitySemantics, CapabilityTokenIssuer, globalCapabilityIssuer;
705
- var init_CapabilityTokenIssuer = __esm({
706
- "src/compiler/identity/CapabilityTokenIssuer.ts"() {
707
- init_AgentIdentity();
708
- init_CapabilityToken();
709
- HoloScriptCapabilitySemantics = class {
710
- /**
711
- * Check whether `child` is a valid attenuation (subset) of `parent`.
712
- */
713
- isSubsetOf(child, parent) {
714
- if (parent.can !== CapabilityActions.ALL && parent.can !== child.can) {
715
- return false;
716
- }
717
- if (parent.with === HOLOSCRIPT_RESOURCE_ALL) {
718
- return child.with.startsWith(HOLOSCRIPT_RESOURCE_SCHEME);
719
- }
720
- if (child.with === parent.with) {
721
- return true;
722
- }
723
- const parentNormalized = parent.with.endsWith("/") ? parent.with : parent.with + "/";
724
- if (child.with.startsWith(parentNormalized)) {
725
- return true;
726
- }
727
- return false;
728
- }
729
- /**
730
- * Check if `capability` authorises the given resource + action.
731
- */
732
- canAccess(capability, resource, action) {
733
- if (capability.can !== CapabilityActions.ALL && capability.can !== action) {
734
- return false;
735
- }
736
- if (capability.with === HOLOSCRIPT_RESOURCE_ALL) {
737
- return resource.startsWith(HOLOSCRIPT_RESOURCE_SCHEME);
738
- }
739
- if (capability.with === resource) {
740
- return true;
741
- }
742
- const capNormalized = capability.with.endsWith("/") ? capability.with : capability.with + "/";
743
- return resource.startsWith(capNormalized);
744
- }
745
- /**
746
- * Convert a legacy AgentPermission into a Capability.
747
- */
748
- fromPermission(permission, scope) {
749
- const action = PERMISSION_TO_ACTION[permission] || permission;
750
- const resource = scope ? `${HOLOSCRIPT_RESOURCE_SCHEME}${scope}` : HOLOSCRIPT_RESOURCE_ALL;
751
- return {
752
- with: resource,
753
- can: action
754
- };
755
- }
756
- };
757
- CapabilityTokenIssuer = class {
758
- constructor(config = {}) {
759
- /** Token store for proof resolution */
760
- this.tokenStore = /* @__PURE__ */ new Map();
761
- /** Nonce set for replay detection */
762
- this.usedNonces = /* @__PURE__ */ new Set();
763
- this.defaultLifetimeSec = config.defaultLifetimeSec ?? 86400;
764
- this.maxDelegationDepth = config.maxDelegationDepth ?? 10;
765
- this.semantics = config.semantics ?? new HoloScriptCapabilitySemantics();
766
- this.strictExpiration = config.strictExpiration ?? true;
767
- }
768
- // -----------------------------------------------------------------------
769
- // Root token issuance
770
- // -----------------------------------------------------------------------
771
- /**
772
- * Issue a root capability token (no parent proofs).
773
- *
774
- * Root tokens are typically issued by the orchestrator or a top-level
775
- * identity provider to grant initial capabilities.
776
- *
777
- * @param options Token creation options
778
- * @param keyPair Ed25519 key pair of the issuer (used for signing)
779
- * @returns Signed CapabilityToken
780
- */
781
- async issueRoot(options, keyPair) {
782
- const now = Math.floor(Date.now() / 1e3);
783
- const lifetime = options.lifetimeSec ?? this.defaultLifetimeSec;
784
- const nonce = crypto3.randomUUID();
785
- const payload = {
786
- iss: options.issuer,
787
- aud: options.audience,
788
- att: options.capabilities,
789
- prf: [],
790
- // root — no proofs
791
- exp: now + lifetime,
792
- nbf: options.notBeforeOffsetSec != null ? now + options.notBeforeOffsetSec : void 0,
793
- nnc: nonce,
794
- fct: options.facts
795
- };
796
- const token = this.sign(payload, keyPair);
797
- this.tokenStore.set(nonce, token);
798
- return token;
799
- }
800
- // -----------------------------------------------------------------------
801
- // Delegation with attenuation
802
- // -----------------------------------------------------------------------
803
- /**
804
- * Delegate (attenuate) an existing capability token to a new audience.
805
- *
806
- * Enforces:
807
- * 1. Every capability in the child MUST be a subset of at least one
808
- * capability in the parent.
809
- * 2. Child expiration MUST NOT exceed parent expiration.
810
- * 3. Delegation depth MUST NOT exceed `maxDelegationDepth`.
811
- *
812
- * @param options Delegation options including the parent token
813
- * @param keyPair Ed25519 key pair of the delegator (current holder)
814
- * @returns New signed CapabilityToken
815
- * @throws Error if attenuation invariants are violated
816
- */
817
- async delegate(options, keyPair) {
818
- const { parentToken, audience, capabilities, lifetimeSec, facts } = options;
819
- const parentPayload = parentToken.payload;
820
- for (const childCap of capabilities) {
821
- const covered = parentPayload.att.some(
822
- (parentCap) => this.semantics.isSubsetOf(childCap, parentCap)
823
- );
824
- if (!covered) {
825
- throw new Error(
826
- `Attenuation violation: capability {with: "${childCap.with}", can: "${childCap.can}"} is not a subset of any parent capability. Delegations can only narrow scope.`
827
- );
828
- }
829
- }
830
- const now = Math.floor(Date.now() / 1e3);
831
- const requestedLifetime = lifetimeSec ?? this.defaultLifetimeSec;
832
- const childExp = now + requestedLifetime;
833
- if (this.strictExpiration && childExp > parentPayload.exp) {
834
- throw new Error(
835
- `Expiration violation: delegated token expires at ${childExp} but parent expires at ${parentPayload.exp}. Child tokens cannot outlive their parents.`
836
- );
837
- }
838
- const effectiveExp = Math.min(childExp, parentPayload.exp);
839
- const currentDepth = parentPayload.prf.length + 1;
840
- if (currentDepth > this.maxDelegationDepth) {
841
- throw new Error(
842
- `Delegation depth ${currentDepth} exceeds maximum of ${this.maxDelegationDepth}.`
843
- );
844
- }
845
- const proofs = [...parentPayload.prf, parentPayload.nnc];
846
- const nonce = crypto3.randomUUID();
847
- const payload = {
848
- iss: parentPayload.aud,
849
- // delegator is the audience of the parent
850
- aud: audience,
851
- att: capabilities,
852
- prf: proofs,
853
- exp: effectiveExp,
854
- nbf: now,
855
- nnc: nonce,
856
- fct: facts
857
- };
858
- const token = this.sign(payload, keyPair);
859
- this.tokenStore.set(nonce, token);
860
- return token;
861
- }
862
- // -----------------------------------------------------------------------
863
- // Signing
864
- // -----------------------------------------------------------------------
865
- /**
866
- * Sign a capability token payload with an Ed25519 key pair.
867
- *
868
- * Produces a JWT-like structure: base64url(header).base64url(payload).base64url(sig)
869
- */
870
- sign(payload, keyPair) {
871
- const header = {
872
- alg: "EdDSA",
873
- typ: "JWT",
874
- ucv: "0.10.0"
875
- };
876
- const headerB64 = base64urlEncode(JSON.stringify(header));
877
- const payloadB64 = base64urlEncode(JSON.stringify(payload));
878
- const signingInput = `${headerB64}.${payloadB64}`;
879
- const privateKeyObj = crypto3.createPrivateKey(keyPair.privateKey);
880
- const signatureBuffer = crypto3.sign(null, Buffer.from(signingInput, "utf-8"), privateKeyObj);
881
- const signatureB64 = signatureBuffer.toString("base64url");
882
- const raw = `${headerB64}.${payloadB64}.${signatureB64}`;
883
- return {
884
- header,
885
- payload,
886
- signature: signatureB64,
887
- raw
888
- };
889
- }
890
- // -----------------------------------------------------------------------
891
- // Verification
892
- // -----------------------------------------------------------------------
893
- /**
894
- * Verify a capability token.
895
- *
896
- * Checks:
897
- * 1. Structural validity (three-part JWT)
898
- * 2. Ed25519 signature
899
- * 3. Expiration / not-before
900
- * 4. Replay (nonce uniqueness)
901
- * 5. Proof chain integrity (attenuation invariants)
902
- *
903
- * @param raw The raw JWT string (or a CapabilityToken object)
904
- * @param publicKey PEM-encoded Ed25519 public key of the issuer
905
- * @returns Verification result
906
- */
907
- verify(raw, publicKey) {
908
- const rawStr = typeof raw === "string" ? raw : raw.raw;
909
- const parts = rawStr.split(".");
910
- if (parts.length !== 3) {
911
- return {
912
- valid: false,
913
- error: "Malformed token: expected 3 parts",
914
- errorCode: "INVALID_SIGNATURE"
915
- };
916
- }
917
- const [headerB64, payloadB64, signatureB64] = parts;
918
- try {
919
- const pubKeyObj = crypto3.createPublicKey(publicKey);
920
- const signingInput = `${headerB64}.${payloadB64}`;
921
- const signatureBuffer = base64urlDecode(signatureB64);
922
- const isValid = crypto3.verify(
923
- null,
924
- Buffer.from(signingInput, "utf-8"),
925
- pubKeyObj,
926
- signatureBuffer
927
- );
928
- if (!isValid) {
929
- return {
930
- valid: false,
931
- error: "Invalid Ed25519 signature",
932
- errorCode: "INVALID_SIGNATURE"
933
- };
934
- }
935
- } catch {
936
- return {
937
- valid: false,
938
- error: "Signature verification failed",
939
- errorCode: "INVALID_SIGNATURE"
940
- };
941
- }
942
- let payload;
943
- try {
944
- payload = JSON.parse(base64urlDecode(payloadB64).toString("utf-8"));
945
- } catch {
946
- return {
947
- valid: false,
948
- error: "Malformed payload",
949
- errorCode: "INVALID_SIGNATURE"
950
- };
951
- }
952
- const now = Math.floor(Date.now() / 1e3);
953
- if (payload.exp <= now) {
954
- return {
955
- valid: false,
956
- payload,
957
- error: "Token expired",
958
- errorCode: "EXPIRED"
959
- };
960
- }
961
- if (payload.nbf != null && payload.nbf > now) {
962
- return {
963
- valid: false,
964
- payload,
965
- error: `Token not yet valid (nbf: ${payload.nbf}, now: ${now})`,
966
- errorCode: "NOT_YET_VALID"
967
- };
968
- }
969
- if (this.usedNonces.has(payload.nnc)) {
970
- return {
971
- valid: false,
972
- payload,
973
- error: "Nonce already used (replay detected)",
974
- errorCode: "REPLAY_DETECTED"
975
- };
976
- }
977
- this.usedNonces.add(payload.nnc);
978
- const chainResult = this.resolveChain(payload);
979
- return {
980
- valid: true,
981
- payload,
982
- chain: chainResult
983
- };
984
- }
985
- // -----------------------------------------------------------------------
986
- // Proof chain resolution
987
- // -----------------------------------------------------------------------
988
- /**
989
- * Resolve and verify the proof chain for a token payload.
990
- *
991
- * Walks back through `prf` references, checking attenuation invariants
992
- * at each step.
993
- */
994
- resolveChain(payload) {
995
- if (payload.prf.length === 0) {
996
- return {
997
- links: [
998
- {
999
- tokenId: payload.nnc,
1000
- issuer: payload.iss,
1001
- audience: payload.aud,
1002
- capabilities: payload.att,
1003
- issuedAt: payload.nbf ?? Math.floor(Date.now() / 1e3),
1004
- expiresAt: payload.exp
1005
- }
1006
- ],
1007
- rootAuthority: payload.iss,
1008
- verified: true,
1009
- verifiedAt: (/* @__PURE__ */ new Date()).toISOString()
1010
- };
1011
- }
1012
- const links = [];
1013
- for (const proofNonce of payload.prf) {
1014
- const parentToken = this.tokenStore.get(proofNonce);
1015
- if (!parentToken) {
1016
- return {
1017
- links,
1018
- rootAuthority: links.length > 0 ? links[0].issuer : payload.iss,
1019
- verified: false
1020
- };
1021
- }
1022
- links.push({
1023
- tokenId: parentToken.payload.nnc,
1024
- issuer: parentToken.payload.iss,
1025
- audience: parentToken.payload.aud,
1026
- capabilities: parentToken.payload.att,
1027
- issuedAt: parentToken.payload.nbf ?? 0,
1028
- expiresAt: parentToken.payload.exp
1029
- });
1030
- }
1031
- links.push({
1032
- tokenId: payload.nnc,
1033
- issuer: payload.iss,
1034
- audience: payload.aud,
1035
- capabilities: payload.att,
1036
- issuedAt: payload.nbf ?? 0,
1037
- expiresAt: payload.exp
1038
- });
1039
- let chainValid = true;
1040
- for (let i = 1; i < links.length; i++) {
1041
- const parent = links[i - 1];
1042
- const child = links[i];
1043
- if (child.issuer !== parent.audience) {
1044
- chainValid = false;
1045
- break;
1046
- }
1047
- for (const childCap of child.capabilities) {
1048
- const covered = parent.capabilities.some(
1049
- (parentCap) => this.semantics.isSubsetOf(childCap, parentCap)
1050
- );
1051
- if (!covered) {
1052
- chainValid = false;
1053
- break;
1054
- }
1055
- }
1056
- if (!chainValid) break;
1057
- if (child.expiresAt > parent.expiresAt) {
1058
- chainValid = false;
1059
- break;
1060
- }
1061
- }
1062
- return {
1063
- links,
1064
- rootAuthority: links[0].issuer,
1065
- verified: chainValid,
1066
- verifiedAt: chainValid ? (/* @__PURE__ */ new Date()).toISOString() : void 0
1067
- };
1068
- }
1069
- // -----------------------------------------------------------------------
1070
- // Convenience: issue from AgentRole
1071
- // -----------------------------------------------------------------------
1072
- /**
1073
- * Issue a root capability token for a given AgentRole.
1074
- *
1075
- * Automatically maps role permissions to capabilities using the bridge
1076
- * mappings defined in CapabilityToken.ts.
1077
- *
1078
- * @param role Agent role
1079
- * @param audience Audience identifier
1080
- * @param keyPair Ed25519 key pair
1081
- * @param scope Optional resource scope restriction
1082
- * @returns Signed root CapabilityToken
1083
- */
1084
- async issueForRole(role, audience, keyPair, scope) {
1085
- const permissions = getDefaultPermissions(role);
1086
- const capabilities = permissions.map((perm) => this.semantics.fromPermission(perm, scope));
1087
- const issuer = `agent:${role}`;
1088
- return this.issueRoot(
1089
- {
1090
- issuer,
1091
- audience,
1092
- capabilities
1093
- },
1094
- keyPair
1095
- );
1096
- }
1097
- // -----------------------------------------------------------------------
1098
- // Capability query
1099
- // -----------------------------------------------------------------------
1100
- /**
1101
- * Check whether a token grants access to a specific resource + action.
1102
- *
1103
- * Does NOT verify the signature — call `verify()` first if the token
1104
- * has not been verified yet.
1105
- */
1106
- hasCapability(token, resource, action) {
1107
- return token.payload.att.some((cap) => this.semantics.canAccess(cap, resource, action));
1108
- }
1109
- // -----------------------------------------------------------------------
1110
- // Store management
1111
- // -----------------------------------------------------------------------
1112
- /**
1113
- * Retrieve a stored token by its nonce (for proof resolution).
1114
- */
1115
- getStoredToken(nonce) {
1116
- return this.tokenStore.get(nonce);
1117
- }
1118
- /**
1119
- * Store an externally-created token (e.g. received from another agent).
1120
- */
1121
- storeToken(token) {
1122
- this.tokenStore.set(token.payload.nnc, token);
1123
- }
1124
- /**
1125
- * Clear all stored tokens and nonces (for testing).
1126
- */
1127
- reset() {
1128
- this.tokenStore.clear();
1129
- this.usedNonces.clear();
1130
- }
1131
- /**
1132
- * Get the semantics engine used by this issuer.
1133
- */
1134
- getSemantics() {
1135
- return this.semantics;
1136
- }
1137
- };
1138
- globalCapabilityIssuer = null;
1139
- }
1140
- });
1141
- function getTokenIssuer(config) {
1142
- if (!globalIssuer) {
1143
- globalIssuer = new AgentTokenIssuer({
1144
- ...config,
1145
- jwtSecret: process.env.AGENT_JWT_SECRET
1146
- });
1147
- }
1148
- return globalIssuer;
1149
- }
1150
- var DEFAULT_ISSUER, DEFAULT_JWT_SECRET, DEFAULT_TOKEN_EXPIRATION, AgentTokenIssuer, globalIssuer;
1151
- var init_AgentTokenIssuer = __esm({
1152
- "src/compiler/identity/AgentTokenIssuer.ts"() {
1153
- init_AgentIdentity();
1154
- init_AgentKeystore();
1155
- init_CapabilityToken();
1156
- init_CapabilityTokenIssuer();
1157
- DEFAULT_ISSUER = "holoscript-orchestrator";
1158
- DEFAULT_JWT_SECRET = process.env.AGENT_JWT_SECRET || "dev-secret-change-in-production";
1159
- DEFAULT_TOKEN_EXPIRATION = "24h";
1160
- AgentTokenIssuer = class {
1161
- constructor(config = {}) {
1162
- /** Active workflow state (for validation) */
1163
- this.workflowState = /* @__PURE__ */ new Map();
1164
- this.issuer = config.issuer || DEFAULT_ISSUER;
1165
- this.jwtSecret = config.jwtSecret || DEFAULT_JWT_SECRET;
1166
- this.tokenExpiration = config.tokenExpiration || DEFAULT_TOKEN_EXPIRATION;
1167
- this.strictWorkflowValidation = config.strictWorkflowValidation ?? true;
1168
- if (this.jwtSecret === DEFAULT_JWT_SECRET && process.env.NODE_ENV === "production") {
1169
- console.error(
1170
- "[TOKEN_ISSUER] Using default JWT secret in production! Set AGENT_JWT_SECRET environment variable."
1171
- );
1172
- }
1173
- }
1174
- /**
1175
- * Issue intent token for agent
1176
- *
1177
- * Creates a signed JWT with:
1178
- * - Standard claims (iss, sub, aud, exp, iat, jti)
1179
- * - Agent identity (role, checksum)
1180
- * - Permissions (RBAC)
1181
- * - Intent metadata (workflow context)
1182
- * - PoP binding (JWK thumbprint)
1183
- */
1184
- async issueToken(request) {
1185
- const {
1186
- agentConfig,
1187
- workflowStep,
1188
- workflowId,
1189
- initiatedBy,
1190
- delegationChain = [],
1191
- executionContext = {},
1192
- keyPair
1193
- } = request;
1194
- if (this.strictWorkflowValidation) {
1195
- const currentStep = this.workflowState.get(workflowId);
1196
- if (currentStep && !isValidWorkflowTransition(currentStep, workflowStep)) {
1197
- throw new Error(
1198
- `Invalid workflow transition: ${currentStep} \u2192 ${workflowStep} in workflow ${workflowId}`
1199
- );
1200
- }
1201
- }
1202
- const agentChecksum = calculateAgentChecksum(agentConfig);
1203
- const permissions = getDefaultPermissions(agentConfig.role);
1204
- const updatedDelegationChain = [...delegationChain, agentConfig.role];
1205
- const now = Math.floor(Date.now() / 1e3);
1206
- const payload = {
1207
- // Standard JWT claims
1208
- iss: this.issuer,
1209
- sub: `agent:${agentConfig.role}:${agentConfig.name}`,
1210
- aud: "holoscript-compiler",
1211
- exp: typeof this.tokenExpiration === "string" ? now + this.parseExpiration(this.tokenExpiration) : now + this.tokenExpiration,
1212
- iat: now,
1213
- jti: crypto3.randomUUID(),
1214
- // Agent-specific claims
1215
- agent_role: agentConfig.role,
1216
- agent_checksum: agentChecksum,
1217
- permissions,
1218
- scope: agentConfig.scope,
1219
- // Intent claims
1220
- intent: {
1221
- workflow_id: workflowId,
1222
- workflow_step: workflowStep,
1223
- executed_by: agentConfig.role,
1224
- initiated_by: initiatedBy,
1225
- delegation_chain: updatedDelegationChain,
1226
- execution_context: executionContext
1227
- },
1228
- // Proof-of-Possession (PoP) confirmation
1229
- cnf: {
1230
- jkt: keyPair.thumbprint
1231
- },
1232
- // Ed25519 public key for HTTP Message Signature verification
1233
- publicKey: keyPair.publicKey
1234
- };
1235
- const token = jwt.sign(payload, this.jwtSecret, {
1236
- algorithm: "HS256"
1237
- });
1238
- this.workflowState.set(workflowId, workflowStep);
1239
- const keystore = getKeystore();
1240
- await keystore.storeCredential({
1241
- role: agentConfig.role,
1242
- token,
1243
- keyPair,
1244
- createdAt: new Date(now * 1e3),
1245
- expiresAt: new Date(payload.exp * 1e3)
1246
- });
1247
- return token;
1248
- }
1249
- /**
1250
- * Verify agent token
1251
- *
1252
- * Validates:
1253
- * - Signature authenticity
1254
- * - Token expiration
1255
- * - Claims structure
1256
- * - Workflow step sequence (if strict mode)
1257
- */
1258
- verifyToken(token) {
1259
- try {
1260
- const decoded = jwt.verify(token, this.jwtSecret, {
1261
- issuer: this.issuer,
1262
- audience: "holoscript-compiler"
1263
- });
1264
- if (!decoded.agent_role || !decoded.agent_checksum || !decoded.intent) {
1265
- return {
1266
- valid: false,
1267
- error: "Missing required claims",
1268
- errorCode: "INVALID_CLAIMS"
1269
- };
1270
- }
1271
- if (this.strictWorkflowValidation) {
1272
- const currentStep = this.workflowState.get(decoded.intent.workflow_id);
1273
- if (currentStep && currentStep !== decoded.intent.workflow_step) {
1274
- return {
1275
- valid: false,
1276
- error: `Workflow step mismatch: expected ${currentStep}, got ${decoded.intent.workflow_step}`,
1277
- errorCode: "WORKFLOW_VIOLATION"
1278
- };
1279
- }
1280
- }
1281
- return {
1282
- valid: true,
1283
- payload: decoded
1284
- };
1285
- } catch (error) {
1286
- if (error instanceof Error && error.name === "TokenExpiredError") {
1287
- return {
1288
- valid: false,
1289
- error: "Token expired",
1290
- errorCode: "EXPIRED"
1291
- };
1292
- } else if (error instanceof Error && error.name === "JsonWebTokenError") {
1293
- return {
1294
- valid: false,
1295
- error: "Invalid signature or malformed token",
1296
- errorCode: "INVALID_SIGNATURE"
1297
- };
1298
- }
1299
- return {
1300
- valid: false,
1301
- error: error instanceof Error ? error.message : String(error),
1302
- errorCode: "INVALID_CLAIMS"
1303
- };
1304
- }
1305
- }
1306
- /**
1307
- * Extract token from Authorization header
1308
- */
1309
- extractToken(authHeader) {
1310
- if (!authHeader) return null;
1311
- if (authHeader.startsWith("Bearer ")) {
1312
- return authHeader.substring(7);
1313
- }
1314
- return authHeader;
1315
- }
1316
- /**
1317
- * Verify agent has required permission
1318
- */
1319
- hasPermission(token, required) {
1320
- const result = this.verifyToken(token);
1321
- if (!result.valid || !result.payload) return false;
1322
- return result.payload.permissions.includes(required);
1323
- }
1324
- /**
1325
- * Check if agent can perform operation
1326
- */
1327
- canPerformOperation(token, requiredPermission, expectedWorkflowStep) {
1328
- const result = this.verifyToken(token);
1329
- if (!result.valid || !result.payload) return false;
1330
- if (!result.payload.permissions.includes(requiredPermission)) {
1331
- return false;
1332
- }
1333
- if (expectedWorkflowStep && result.payload.intent.workflow_step !== expectedWorkflowStep) {
1334
- return false;
1335
- }
1336
- return true;
1337
- }
1338
- // ---------------------------------------------------------------------------
1339
- // UCAN Capability Token Methods (migration bridge)
1340
- // ---------------------------------------------------------------------------
1341
- /**
1342
- * Issue a UCAN capability token for an agent.
1343
- *
1344
- * Maps the agent's role to capabilities using the PERMISSION_TO_ACTION bridge
1345
- * constants defined in CapabilityToken.ts. This enables agents that currently
1346
- * use JWT tokens to obtain equivalent UCAN capability tokens for the gradual
1347
- * migration to capability-based authorization.
1348
- *
1349
- * @param options Capability token issuance options
1350
- * @returns Signed UCAN CapabilityToken
1351
- */
1352
- async issueCapabilityToken(options) {
1353
- const { agentConfig, audience, keyPair, scope, lifetimeSec, facts } = options;
1354
- const capIssuer = this.getCapabilityTokenIssuer();
1355
- const permissions = getDefaultPermissions(agentConfig.role);
1356
- const capabilities = permissions.map((perm) => {
1357
- const action = PERMISSION_TO_ACTION[perm] || perm;
1358
- const resource = scope ? `${HOLOSCRIPT_RESOURCE_SCHEME}${scope}` : HOLOSCRIPT_RESOURCE_ALL;
1359
- return { with: resource, can: action };
1360
- });
1361
- const issuer = `agent:${agentConfig.role}:${agentConfig.name}`;
1362
- return capIssuer.issueRoot(
1363
- {
1364
- issuer,
1365
- audience,
1366
- capabilities,
1367
- lifetimeSec,
1368
- facts: {
1369
- ...facts,
1370
- agent_version: agentConfig.version,
1371
- agent_role: agentConfig.role
1372
- }
1373
- },
1374
- keyPair
1375
- );
1376
- }
1377
- /**
1378
- * Issue both a JWT token and a UCAN capability token for the same agent
1379
- * and intent context.
1380
- *
1381
- * This method enables gradual migration from JWT-only authorization to
1382
- * UCAN capability-based authorization. Consuming services can validate
1383
- * either token during the transition period.
1384
- *
1385
- * @param request Standard JWT token request parameters
1386
- * @param capabilityOptions Additional options for the capability token
1387
- * (audience defaults to 'holoscript-compiler')
1388
- * @returns HybridTokenResult with both tokens
1389
- */
1390
- async issueHybridToken(request, capabilityOptions) {
1391
- const jwtToken = await this.issueToken(request);
1392
- const audience = capabilityOptions?.audience ?? "holoscript-compiler";
1393
- const capabilityToken = await this.issueCapabilityToken({
1394
- agentConfig: request.agentConfig,
1395
- audience,
1396
- keyPair: request.keyPair,
1397
- scope: capabilityOptions?.scope ?? request.agentConfig.scope,
1398
- lifetimeSec: capabilityOptions?.lifetimeSec,
1399
- facts: {
1400
- ...capabilityOptions?.facts,
1401
- workflow_id: request.workflowId,
1402
- workflow_step: request.workflowStep,
1403
- initiated_by: request.initiatedBy
1404
- }
1405
- });
1406
- const permissions = getDefaultPermissions(request.agentConfig.role);
1407
- const scope = capabilityOptions?.scope ?? request.agentConfig.scope;
1408
- const capabilities = permissions.map((perm) => {
1409
- const action = PERMISSION_TO_ACTION[perm] || perm;
1410
- const resource = scope ? `${HOLOSCRIPT_RESOURCE_SCHEME}${scope}` : HOLOSCRIPT_RESOURCE_ALL;
1411
- return { with: resource, can: action };
1412
- });
1413
- return {
1414
- jwt: jwtToken,
1415
- capabilityToken,
1416
- agentRole: request.agentConfig.role,
1417
- capabilities,
1418
- issuedAt: Math.floor(Date.now() / 1e3)
1419
- };
1420
- }
1421
- /**
1422
- * Delegate (attenuate) an existing UCAN capability token to a target agent.
1423
- *
1424
- * Creates a new UCAN token with a subset of the parent token's capabilities,
1425
- * enforcing UCAN attenuation invariants:
1426
- * - Every capability in the child MUST be a subset of the parent's capabilities
1427
- * - Child expiration MUST NOT exceed parent expiration
1428
- * - Delegation depth MUST NOT exceed the configured maximum
1429
- *
1430
- * @param parentToken The parent UCAN capability token to delegate from
1431
- * @param targetDID DID or agent identifier of the delegatee
1432
- * @param attenuatedCapabilities Capabilities to grant (must be subsets of parent)
1433
- * @param keyPair Delegator's Ed25519 key pair for signing
1434
- * @param lifetimeSec Optional lifetime in seconds
1435
- * @param facts Optional metadata
1436
- * @returns New signed CapabilityToken (attenuated delegation)
1437
- * @throws Error if attenuation invariants are violated
1438
- */
1439
- async delegateCapability(parentToken, targetDID, attenuatedCapabilities, keyPair, lifetimeSec, facts) {
1440
- const capIssuer = this.getCapabilityTokenIssuer();
1441
- capIssuer.storeToken(parentToken);
1442
- if (!keyPair) {
1443
- throw new Error(
1444
- "A key pair is required to sign the delegated capability token. Pass the delegator's AgentKeyPair."
1445
- );
1446
- }
1447
- return capIssuer.delegate(
1448
- {
1449
- parentToken,
1450
- audience: targetDID,
1451
- capabilities: attenuatedCapabilities,
1452
- lifetimeSec,
1453
- facts
1454
- },
1455
- keyPair
1456
- );
1457
- }
1458
- // ---------------------------------------------------------------------------
1459
- // Internal helpers
1460
- // ---------------------------------------------------------------------------
1461
- /**
1462
- * Get or create the CapabilityTokenIssuer instance used by this issuer.
1463
- * @internal
1464
- */
1465
- getCapabilityTokenIssuer() {
1466
- return getCapabilityTokenIssuer();
1467
- }
1468
- /**
1469
- * Get workflow state
1470
- */
1471
- getWorkflowState(workflowId) {
1472
- return this.workflowState.get(workflowId);
1473
- }
1474
- /**
1475
- * Reset workflow state (for testing)
1476
- */
1477
- resetWorkflowState(workflowId) {
1478
- if (workflowId) {
1479
- this.workflowState.delete(workflowId);
1480
- } else {
1481
- this.workflowState.clear();
1482
- }
1483
- }
1484
- /**
1485
- * Parse expiration string (e.g., '24h', '7d')
1486
- */
1487
- parseExpiration(exp) {
1488
- const match = exp.match(/^(\d+)([smhd])$/);
1489
- if (!match) {
1490
- throw new Error(`Invalid expiration format: ${exp}`);
1491
- }
1492
- const value = parseInt(match[1], 10);
1493
- const unit = match[2];
1494
- const multipliers = {
1495
- s: 1,
1496
- m: 60,
1497
- h: 60 * 60,
1498
- d: 60 * 60 * 24
1499
- };
1500
- return value * multipliers[unit];
1501
- }
1502
- };
1503
- globalIssuer = null;
1504
- }
1505
- });
1506
-
1507
- // src/compiler/CulturalCompatibilityChecker.ts
1508
- var DEFAULT_CONFIG, CODES, CulturalCompatibilityChecker;
1509
- var init_CulturalCompatibilityChecker = __esm({
1510
- "src/compiler/CulturalCompatibilityChecker.ts"() {
1511
- init_CultureTraits();
1512
- DEFAULT_CONFIG = {
1513
- cooperationThreshold: 0.5,
1514
- checkDialects: true,
1515
- validateNormReferences: true,
1516
- warnOnCautious: true
1517
- };
1518
- CODES = {
1519
- COOPERATION_OUT_OF_RANGE: "CULT001",
1520
- COOPERATION_MISMATCH: "CULT002",
1521
- FAMILY_INCOMPATIBLE: "CULT003",
1522
- FAMILY_CAUTIOUS: "CULT004",
1523
- DIALECT_MISMATCH: "CULT005",
1524
- NORM_CONTRADICTION: "CULT006",
1525
- NORM_UNKNOWN: "CULT007"
1526
- };
1527
- CulturalCompatibilityChecker = class {
1528
- constructor(config) {
1529
- this.config = { ...DEFAULT_CONFIG, ...config };
1530
- }
1531
- /**
1532
- * Update checker configuration.
1533
- */
1534
- setConfig(config) {
1535
- this.config = { ...this.config, ...config };
1536
- }
1537
- /**
1538
- * Get current checker configuration.
1539
- */
1540
- getConfig() {
1541
- return { ...this.config };
1542
- }
1543
- /**
1544
- * Check cultural compatibility of a set of agents in a composition.
1545
- *
1546
- * Performs pairwise checks across all four dimensions:
1547
- * 1. Validates individual profiles (cooperation_index range, norm references)
1548
- * 2. Checks cooperation_index deltas between all pairs
1549
- * 3. Checks cultural_family compatibility between all pairs
1550
- * 4. Checks prompt_dialect compatibility between all pairs
1551
- * 5. Checks for contradictory norms across the full composition
1552
- *
1553
- * @param agents Array of agent entries with their cultural profiles
1554
- * @returns Complete compatibility result with diagnostics
1555
- */
1556
- check(agents) {
1557
- const diagnostics = [];
1558
- for (const agent of agents) {
1559
- diagnostics.push(...this.validateProfile(agent));
1560
- }
1561
- let pairsChecked = 0;
1562
- for (let i = 0; i < agents.length; i++) {
1563
- for (let j = i + 1; j < agents.length; j++) {
1564
- const a = agents[i];
1565
- const b = agents[j];
1566
- pairsChecked++;
1567
- diagnostics.push(...this.checkCooperationIndex(a, b));
1568
- diagnostics.push(...this.checkCulturalFamily(a, b));
1569
- if (this.config.checkDialects) {
1570
- diagnostics.push(...this.checkPromptDialect(a, b));
1571
- }
1572
- }
1573
- }
1574
- diagnostics.push(...this.checkNormContradictions(agents));
1575
- const errors = diagnostics.filter((d) => d.severity === "error");
1576
- const warnings = diagnostics.filter((d) => d.severity === "warning");
1577
- return {
1578
- compatible: errors.length === 0,
1579
- diagnostics,
1580
- errors,
1581
- warnings,
1582
- pairsChecked
1583
- };
1584
- }
1585
- /**
1586
- * Quick check — returns true if the composition is compatible (no errors).
1587
- * Use `check()` for full diagnostics.
1588
- */
1589
- isCompatible(agents) {
1590
- return this.check(agents).compatible;
1591
- }
1592
- // ===========================================================================
1593
- // INDIVIDUAL PROFILE VALIDATION
1594
- // ===========================================================================
1595
- validateProfile(agent) {
1596
- const diagnostics = [];
1597
- const { profile, name } = agent;
1598
- if (profile.cooperation_index < 0 || profile.cooperation_index > 1) {
1599
- diagnostics.push({
1600
- code: CODES.COOPERATION_OUT_OF_RANGE,
1601
- severity: "error",
1602
- category: "cooperation_out_of_range",
1603
- message: `Agent "${name}" has cooperation_index ${profile.cooperation_index} which is outside the valid range [0, 1].`,
1604
- agents: [name, name],
1605
- suggestion: "Set cooperation_index to a value between 0.0 and 1.0."
1606
- });
1607
- }
1608
- if (this.config.validateNormReferences) {
1609
- const builtinIds = new Set(BUILTIN_NORMS.map((n) => n.id));
1610
- for (const normId of profile.norm_set) {
1611
- if (!builtinIds.has(normId)) {
1612
- diagnostics.push({
1613
- code: CODES.NORM_UNKNOWN,
1614
- severity: "warning",
1615
- category: "norm_unknown",
1616
- message: `Agent "${name}" references unknown norm "${normId}". It may be a custom norm not yet registered.`,
1617
- agents: [name, name],
1618
- suggestion: `Register the norm "${normId}" via BUILTIN_NORMS or ensure it exists in your custom norm registry.`
1619
- });
1620
- }
1621
- }
1622
- }
1623
- return diagnostics;
1624
- }
1625
- // ===========================================================================
1626
- // COOPERATION INDEX CHECK
1627
- // ===========================================================================
1628
- checkCooperationIndex(a, b) {
1629
- const delta = Math.abs(a.profile.cooperation_index - b.profile.cooperation_index);
1630
- if (delta > this.config.cooperationThreshold) {
1631
- return [
1632
- {
1633
- code: CODES.COOPERATION_MISMATCH,
1634
- severity: "error",
1635
- category: "cooperation_mismatch",
1636
- message: `Agents "${a.name}" (cooperation_index: ${a.profile.cooperation_index}) and "${b.name}" (cooperation_index: ${b.profile.cooperation_index}) have a cooperation delta of ${delta.toFixed(2)} which exceeds the threshold of ${this.config.cooperationThreshold}. These agents are unlikely to cooperate effectively.`,
1637
- agents: [a.name, b.name],
1638
- suggestion: `Adjust cooperation_index values to be within ${this.config.cooperationThreshold} of each other, or add a mediator agent with a middle cooperation_index.`
1639
- }
1640
- ];
1641
- }
1642
- return [];
1643
- }
1644
- // ===========================================================================
1645
- // CULTURAL FAMILY CHECK
1646
- // ===========================================================================
1647
- checkCulturalFamily(a, b) {
1648
- const { rating, reason } = getFamilyCompatibility(
1649
- a.profile.cultural_family,
1650
- b.profile.cultural_family
1651
- );
1652
- if (rating === "incompatible") {
1653
- return [
1654
- {
1655
- code: CODES.FAMILY_INCOMPATIBLE,
1656
- severity: "error",
1657
- category: "family_incompatible",
1658
- message: `Agents "${a.name}" (family: ${a.profile.cultural_family}) and "${b.name}" (family: ${b.profile.cultural_family}) belong to incompatible cultural families. ` + reason,
1659
- agents: [a.name, b.name],
1660
- suggestion: `Change one agent's cultural_family to a compatible type, or separate them into different compositions/zones.`
1661
- }
1662
- ];
1663
- }
1664
- if (rating === "cautious" && this.config.warnOnCautious) {
1665
- return [
1666
- {
1667
- code: CODES.FAMILY_CAUTIOUS,
1668
- severity: "warning",
1669
- category: "family_cautious",
1670
- message: `Agents "${a.name}" (family: ${a.profile.cultural_family}) and "${b.name}" (family: ${b.profile.cultural_family}) have cautious cultural compatibility. ` + reason,
1671
- agents: [a.name, b.name],
1672
- suggestion: "Consider adding a mediator agent or defining explicit interaction protocols."
1673
- }
1674
- ];
1675
- }
1676
- return [];
1677
- }
1678
- // ===========================================================================
1679
- // PROMPT DIALECT CHECK
1680
- // ===========================================================================
1681
- checkPromptDialect(a, b) {
1682
- if (a.profile.prompt_dialect !== b.profile.prompt_dialect) {
1683
- return [
1684
- {
1685
- code: CODES.DIALECT_MISMATCH,
1686
- severity: "warning",
1687
- category: "dialect_mismatch",
1688
- message: `Agents "${a.name}" (dialect: ${a.profile.prompt_dialect}) and "${b.name}" (dialect: ${b.profile.prompt_dialect}) use different prompt dialects. Inter-agent communication may be less efficient.`,
1689
- agents: [a.name, b.name],
1690
- suggestion: "Align prompt_dialect values for agents that need frequent communication, or add a translator agent that bridges both dialects."
1691
- }
1692
- ];
1693
- }
1694
- return [];
1695
- }
1696
- // ===========================================================================
1697
- // NORM CONTRADICTION CHECK
1698
- // ===========================================================================
1699
- /**
1700
- * Check for contradictory norms across the entire composition.
1701
- * This is an N-way check (not just pairwise) because norms from
1702
- * different agents can contradict each other.
1703
- */
1704
- checkNormContradictions(agents) {
1705
- const diagnostics = [];
1706
- const contradictions = getAllContradictoryNorms();
1707
- const normAgentMap = /* @__PURE__ */ new Map();
1708
- for (const agent of agents) {
1709
- for (const normId of agent.profile.norm_set) {
1710
- if (!normAgentMap.has(normId)) {
1711
- normAgentMap.set(normId, []);
1712
- }
1713
- normAgentMap.get(normId).push(agent.name);
1714
- }
1715
- }
1716
- for (const { normA, normB, reason } of contradictions) {
1717
- const agentsWithA = normAgentMap.get(normA) || [];
1718
- const agentsWithB = normAgentMap.get(normB) || [];
1719
- if (agentsWithA.length > 0 && agentsWithB.length > 0) {
1720
- for (const agentA of agentsWithA) {
1721
- for (const agentB of agentsWithB) {
1722
- if (agentA !== agentB) {
1723
- diagnostics.push({
1724
- code: CODES.NORM_CONTRADICTION,
1725
- severity: "error",
1726
- category: "norm_contradiction",
1727
- message: `Norm contradiction: agent "${agentA}" subscribes to "${normA}" and agent "${agentB}" subscribes to "${normB}". ${reason}`,
1728
- agents: [agentA, agentB],
1729
- suggestion: `Remove one of the contradictory norms, or separate agents "${agentA}" and "${agentB}" into different compositions.`
1730
- });
1731
- }
1732
- if (agentA === agentB) {
1733
- diagnostics.push({
1734
- code: CODES.NORM_CONTRADICTION,
1735
- severity: "error",
1736
- category: "norm_contradiction",
1737
- message: `Agent "${agentA}" subscribes to contradictory norms "${normA}" and "${normB}". ${reason}`,
1738
- agents: [agentA, agentA],
1739
- suggestion: `Remove one of the contradictory norms from agent "${agentA}".`
1740
- });
1741
- }
1742
- }
1743
- }
1744
- }
1745
- }
1746
- return diagnostics;
1747
- }
1748
- };
1749
- }
1750
- });
1751
-
1752
- // src/compiler/identity/ConfabulationValidator.ts
1753
- function getConfabulationValidator(config) {
1754
- if (!globalConfabulationValidator) {
1755
- globalConfabulationValidator = new ConfabulationValidator(config);
1756
- }
1757
- return globalConfabulationValidator;
1758
- }
1759
- var BUILT_IN_TRAIT_SCHEMAS, ConfabulationValidator, globalConfabulationValidator;
1760
- var init_ConfabulationValidator = __esm({
1761
- "src/compiler/identity/ConfabulationValidator.ts"() {
1762
- BUILT_IN_TRAIT_SCHEMAS = [
1763
- // =========================================================================
1764
- // INTERACTION TRAITS
1765
- // =========================================================================
1766
- {
1767
- name: "grabbable",
1768
- category: "interaction",
1769
- properties: [
1770
- {
1771
- name: "snap_to_hand",
1772
- type: "boolean",
1773
- defaultValue: true,
1774
- description: "Snap object to hand when grabbed"
1775
- },
1776
- {
1777
- name: "two_handed",
1778
- type: "boolean",
1779
- defaultValue: false,
1780
- description: "Require two hands to grab"
1781
- },
1782
- {
1783
- name: "haptic_on_grab",
1784
- type: "number",
1785
- defaultValue: 0.5,
1786
- min: 0,
1787
- max: 1,
1788
- description: "Haptic intensity on grab"
1789
- },
1790
- {
1791
- name: "grab_points",
1792
- type: "array",
1793
- defaultValue: [],
1794
- description: "Specific grab point positions"
1795
- },
1796
- {
1797
- name: "preserve_rotation",
1798
- type: "boolean",
1799
- defaultValue: false,
1800
- description: "Preserve rotation on grab"
1801
- },
1802
- {
1803
- name: "highlight",
1804
- type: "boolean",
1805
- defaultValue: true,
1806
- description: "Highlight when in grab range"
1807
- }
1808
- ]
1809
- },
1810
- {
1811
- name: "throwable",
1812
- category: "interaction",
1813
- requires: ["grabbable"],
1814
- properties: [
1815
- {
1816
- name: "velocity_multiplier",
1817
- type: "number",
1818
- defaultValue: 1,
1819
- min: 0,
1820
- max: 100,
1821
- description: "Multiplier for throw velocity"
1822
- },
1823
- {
1824
- name: "gravity",
1825
- type: "boolean",
1826
- defaultValue: true,
1827
- description: "Apply gravity after throw"
1828
- },
1829
- {
1830
- name: "max_velocity",
1831
- type: "number",
1832
- defaultValue: 50,
1833
- min: 0,
1834
- description: "Maximum throw velocity"
1835
- },
1836
- { name: "spin", type: "boolean", defaultValue: true, description: "Apply spin on throw" },
1837
- { name: "bounce", type: "boolean", defaultValue: false, description: "Bounce on impact" }
1838
- ]
1839
- },
1840
- {
1841
- name: "holdable",
1842
- category: "interaction",
1843
- requires: ["grabbable"],
1844
- properties: [
1845
- {
1846
- name: "offset",
1847
- type: "array",
1848
- defaultValue: [0, 0, 0],
1849
- description: "Position offset when held"
1850
- },
1851
- {
1852
- name: "rotation",
1853
- type: "array",
1854
- defaultValue: [0, 0, 0],
1855
- description: "Rotation offset when held"
1856
- }
1857
- ]
1858
- },
1859
- {
1860
- name: "clickable",
1861
- category: "interaction",
1862
- properties: [
1863
- { name: "highlight", type: "boolean", defaultValue: true, description: "Highlight on hover" },
1864
- {
1865
- name: "debounce",
1866
- type: "number",
1867
- defaultValue: 200,
1868
- min: 0,
1869
- description: "Debounce time in ms"
1870
- }
1871
- ]
1872
- },
1873
- {
1874
- name: "hoverable",
1875
- category: "interaction",
1876
- properties: [
1877
- {
1878
- name: "highlight_color",
1879
- type: "string",
1880
- defaultValue: "#ffffff",
1881
- description: "Color when hovered"
1882
- },
1883
- {
1884
- name: "scale_on_hover",
1885
- type: "number",
1886
- defaultValue: 1.1,
1887
- min: 0,
1888
- description: "Scale multiplier on hover"
1889
- },
1890
- {
1891
- name: "show_tooltip",
1892
- type: "boolean",
1893
- defaultValue: false,
1894
- description: "Show tooltip on hover"
1895
- },
1896
- {
1897
- name: "tooltip_offset",
1898
- type: "array",
1899
- defaultValue: [0, 0.2, 0],
1900
- description: "Tooltip offset from object"
1901
- },
1902
- { name: "glow", type: "boolean", defaultValue: false, description: "Glow effect on hover" }
1903
- ]
1904
- },
1905
- {
1906
- name: "draggable",
1907
- category: "interaction",
1908
- properties: [
1909
- {
1910
- name: "axis",
1911
- type: "enum",
1912
- enumValues: ["x", "y", "z", "xy", "xz", "yz", "all"],
1913
- defaultValue: "all",
1914
- description: "Constrain to axis"
1915
- },
1916
- { name: "bounds", type: "object", description: "Movement bounds" }
1917
- ]
1918
- },
1919
- {
1920
- name: "pointable",
1921
- category: "interaction",
1922
- properties: [
1923
- {
1924
- name: "highlight_on_point",
1925
- type: "boolean",
1926
- defaultValue: true,
1927
- description: "Highlight when pointed at"
1928
- },
1929
- {
1930
- name: "highlight_color",
1931
- type: "string",
1932
- defaultValue: "#00ff00",
1933
- description: "Highlight color"
1934
- },
1935
- {
1936
- name: "cursor_style",
1937
- type: "enum",
1938
- enumValues: ["pointer", "crosshair", "grab", "default"],
1939
- defaultValue: "pointer",
1940
- description: "Cursor style"
1941
- }
1942
- ]
1943
- },
1944
- {
1945
- name: "scalable",
1946
- category: "interaction",
1947
- properties: [
1948
- {
1949
- name: "min_scale",
1950
- type: "number",
1951
- defaultValue: 0.1,
1952
- min: 0,
1953
- description: "Minimum scale"
1954
- },
1955
- { name: "max_scale", type: "number", defaultValue: 10, min: 0, description: "Maximum scale" },
1956
- { name: "uniform", type: "boolean", defaultValue: true, description: "Uniform scaling" },
1957
- { name: "pivot", type: "array", defaultValue: [0, 0, 0], description: "Scale pivot point" }
1958
- ]
1959
- },
1960
- {
1961
- name: "rotatable",
1962
- category: "interaction",
1963
- properties: [
1964
- {
1965
- name: "axis",
1966
- type: "enum",
1967
- enumValues: ["x", "y", "z", "all"],
1968
- defaultValue: "all",
1969
- description: "Rotation axis constraint"
1970
- },
1971
- { name: "snap_angles", type: "array", defaultValue: [], description: "Snap rotation angles" },
1972
- {
1973
- name: "speed",
1974
- type: "number",
1975
- defaultValue: 1,
1976
- min: 0,
1977
- description: "Rotation speed multiplier"
1978
- }
1979
- ]
1980
- },
1981
- {
1982
- name: "snappable",
1983
- category: "interaction",
1984
- properties: [
1985
- {
1986
- name: "snap_points",
1987
- type: "array",
1988
- defaultValue: [],
1989
- description: "Snap target positions"
1990
- },
1991
- {
1992
- name: "snap_distance",
1993
- type: "number",
1994
- defaultValue: 0.3,
1995
- min: 0,
1996
- description: "Snap activation distance"
1997
- },
1998
- {
1999
- name: "snap_rotation",
2000
- type: "boolean",
2001
- defaultValue: false,
2002
- description: "Snap rotation as well"
2003
- },
2004
- {
2005
- name: "magnetic",
2006
- type: "boolean",
2007
- defaultValue: false,
2008
- description: "Magnetic snap effect"
2009
- }
2010
- ]
2011
- },
2012
- // =========================================================================
2013
- // PHYSICS TRAITS
2014
- // =========================================================================
2015
- {
2016
- name: "collidable",
2017
- category: "physics",
2018
- properties: [
2019
- {
2020
- name: "shape",
2021
- type: "enum",
2022
- enumValues: ["box", "sphere", "capsule", "mesh", "auto"],
2023
- defaultValue: "auto",
2024
- description: "Collision shape"
2025
- },
2026
- { name: "layer", type: "string", defaultValue: "default", description: "Collision layer" },
2027
- { name: "trigger", type: "boolean", defaultValue: false, description: "Is trigger collider" }
2028
- ]
2029
- },
2030
- {
2031
- name: "physics",
2032
- category: "physics",
2033
- properties: [
2034
- { name: "mass", type: "number", defaultValue: 1, min: 0, description: "Object mass in kg" },
2035
- {
2036
- name: "restitution",
2037
- type: "number",
2038
- defaultValue: 0.5,
2039
- min: 0,
2040
- max: 1,
2041
- description: "Bounciness (0-1)"
2042
- },
2043
- {
2044
- name: "friction",
2045
- type: "number",
2046
- defaultValue: 0.5,
2047
- min: 0,
2048
- max: 1,
2049
- description: "Surface friction (0-1)"
2050
- },
2051
- { name: "gravity", type: "boolean", defaultValue: true, description: "Affected by gravity" },
2052
- {
2053
- name: "linear_damping",
2054
- type: "number",
2055
- defaultValue: 0,
2056
- min: 0,
2057
- max: 1,
2058
- description: "Linear velocity damping"
2059
- },
2060
- {
2061
- name: "angular_damping",
2062
- type: "number",
2063
- defaultValue: 0.05,
2064
- min: 0,
2065
- max: 1,
2066
- description: "Angular velocity damping"
2067
- }
2068
- ]
2069
- },
2070
- {
2071
- name: "rigid",
2072
- category: "physics",
2073
- properties: [
2074
- {
2075
- name: "type",
2076
- type: "enum",
2077
- enumValues: ["dynamic", "static", "kinematic"],
2078
- defaultValue: "dynamic",
2079
- description: "Rigid body type"
2080
- },
2081
- { name: "mass", type: "number", defaultValue: 1, min: 0, description: "Mass in kg" }
2082
- ]
2083
- },
2084
- {
2085
- name: "kinematic",
2086
- category: "physics",
2087
- properties: [
2088
- {
2089
- name: "interpolation",
2090
- type: "boolean",
2091
- defaultValue: true,
2092
- description: "Interpolate movement"
2093
- }
2094
- ]
2095
- },
2096
- {
2097
- name: "trigger",
2098
- category: "physics",
2099
- properties: [
2100
- {
2101
- name: "shape",
2102
- type: "enum",
2103
- enumValues: ["box", "sphere", "capsule"],
2104
- defaultValue: "box",
2105
- description: "Trigger zone shape"
2106
- },
2107
- { name: "size", type: "array", description: "Trigger zone size" }
2108
- ]
2109
- },
2110
- {
2111
- name: "gravity",
2112
- category: "physics",
2113
- properties: [
2114
- { name: "strength", type: "number", defaultValue: 9.81, description: "Gravity strength" },
2115
- {
2116
- name: "direction",
2117
- type: "array",
2118
- defaultValue: [0, -1, 0],
2119
- description: "Gravity direction vector"
2120
- }
2121
- ]
2122
- },
2123
- // =========================================================================
2124
- // VISUAL TRAITS
2125
- // =========================================================================
2126
- {
2127
- name: "glowing",
2128
- category: "visual",
2129
- properties: [
2130
- { name: "color", type: "string", defaultValue: "#ffffff", description: "Glow color" },
2131
- { name: "intensity", type: "number", defaultValue: 1, min: 0, description: "Glow intensity" },
2132
- { name: "radius", type: "number", defaultValue: 1, min: 0, description: "Glow radius" }
2133
- ]
2134
- },
2135
- {
2136
- name: "emissive",
2137
- category: "visual",
2138
- properties: [
2139
- { name: "color", type: "string", defaultValue: "#ffffff", description: "Emissive color" },
2140
- {
2141
- name: "intensity",
2142
- type: "number",
2143
- defaultValue: 1,
2144
- min: 0,
2145
- description: "Emission intensity"
2146
- }
2147
- ]
2148
- },
2149
- {
2150
- name: "transparent",
2151
- category: "visual",
2152
- properties: [
2153
- {
2154
- name: "opacity",
2155
- type: "number",
2156
- defaultValue: 0.5,
2157
- min: 0,
2158
- max: 1,
2159
- description: "Opacity value (0-1)"
2160
- }
2161
- ]
2162
- },
2163
- {
2164
- name: "reflective",
2165
- category: "visual",
2166
- properties: [
2167
- {
2168
- name: "roughness",
2169
- type: "number",
2170
- defaultValue: 0.1,
2171
- min: 0,
2172
- max: 1,
2173
- description: "Surface roughness (0-1)"
2174
- },
2175
- {
2176
- name: "metalness",
2177
- type: "number",
2178
- defaultValue: 1,
2179
- min: 0,
2180
- max: 1,
2181
- description: "Metalness (0-1)"
2182
- }
2183
- ]
2184
- },
2185
- {
2186
- name: "animated",
2187
- category: "visual",
2188
- properties: [
2189
- { name: "clip", type: "string", description: "Animation clip name" },
2190
- { name: "loop", type: "boolean", defaultValue: true, description: "Loop animation" },
2191
- { name: "speed", type: "number", defaultValue: 1, min: 0, description: "Playback speed" },
2192
- { name: "autoplay", type: "boolean", defaultValue: true, description: "Auto-play on load" }
2193
- ]
2194
- },
2195
- {
2196
- name: "billboard",
2197
- category: "visual",
2198
- properties: [
2199
- {
2200
- name: "axis",
2201
- type: "enum",
2202
- enumValues: ["all", "y"],
2203
- defaultValue: "all",
2204
- description: "Billboard axis constraint"
2205
- }
2206
- ]
2207
- },
2208
- {
2209
- name: "color",
2210
- category: "visual",
2211
- properties: [
2212
- { name: "value", type: "string", description: "Color value (hex, named, or rgb)" }
2213
- ]
2214
- },
2215
- {
2216
- name: "material",
2217
- category: "visual",
2218
- properties: [
2219
- {
2220
- name: "type",
2221
- type: "enum",
2222
- enumValues: ["pbr", "standard", "unlit", "transparent", "volumetric", "custom", "neural"],
2223
- defaultValue: "pbr",
2224
- description: "Material type"
2225
- },
2226
- { name: "color", type: "string", description: "Base color" },
2227
- {
2228
- name: "metallic",
2229
- type: "number",
2230
- defaultValue: 0,
2231
- min: 0,
2232
- max: 1,
2233
- description: "Metalness (0-1)"
2234
- },
2235
- {
2236
- name: "roughness",
2237
- type: "number",
2238
- defaultValue: 0.5,
2239
- min: 0,
2240
- max: 1,
2241
- description: "Roughness (0-1)"
2242
- },
2243
- {
2244
- name: "opacity",
2245
- type: "number",
2246
- defaultValue: 1,
2247
- min: 0,
2248
- max: 1,
2249
- description: "Opacity (0-1)"
2250
- },
2251
- { name: "emissive", type: "string", description: "Emissive color" },
2252
- {
2253
- name: "emissive_intensity",
2254
- type: "number",
2255
- defaultValue: 0,
2256
- min: 0,
2257
- description: "Emissive intensity"
2258
- }
2259
- ]
2260
- },
2261
- {
2262
- name: "texture",
2263
- category: "visual",
2264
- properties: [
2265
- { name: "path", type: "string", required: true, description: "Texture file path or URL" },
2266
- {
2267
- name: "channel",
2268
- type: "enum",
2269
- enumValues: [
2270
- "baseColor",
2271
- "normalMap",
2272
- "roughnessMap",
2273
- "metallicMap",
2274
- "ambientOcclusionMap",
2275
- "emissionMap",
2276
- "heightMap",
2277
- "displacementMap"
2278
- ],
2279
- defaultValue: "baseColor",
2280
- description: "Texture channel"
2281
- },
2282
- { name: "scale", type: "object", description: "UV tiling scale" },
2283
- { name: "offset", type: "object", description: "UV offset" }
2284
- ]
2285
- },
2286
- // =========================================================================
2287
- // NETWORKING TRAITS
2288
- // =========================================================================
2289
- {
2290
- name: "networked",
2291
- category: "networking",
2292
- properties: [
2293
- {
2294
- name: "mode",
2295
- type: "enum",
2296
- enumValues: ["owner", "shared", "server"],
2297
- defaultValue: "owner",
2298
- description: "Sync authority mode"
2299
- },
2300
- { name: "syncProperties", type: "array", description: "Properties to synchronize" },
2301
- {
2302
- name: "syncRate",
2303
- type: "number",
2304
- defaultValue: 20,
2305
- min: 1,
2306
- max: 120,
2307
- description: "Sync rate in Hz"
2308
- },
2309
- {
2310
- name: "interpolation",
2311
- type: "boolean",
2312
- defaultValue: true,
2313
- description: "Enable interpolation"
2314
- },
2315
- {
2316
- name: "channel",
2317
- type: "enum",
2318
- enumValues: ["reliable", "unreliable", "ordered"],
2319
- defaultValue: "reliable",
2320
- description: "Network channel"
2321
- }
2322
- ]
2323
- },
2324
- {
2325
- name: "synced",
2326
- category: "networking",
2327
- properties: [
2328
- { name: "properties", type: "array", description: "Properties to sync" },
2329
- { name: "rate", type: "number", defaultValue: 30, min: 1, description: "Sync rate" }
2330
- ]
2331
- },
2332
- {
2333
- name: "persistent",
2334
- category: "networking",
2335
- properties: [
2336
- {
2337
- name: "storage",
2338
- type: "enum",
2339
- enumValues: ["local", "cloud", "blockchain"],
2340
- defaultValue: "local",
2341
- description: "Persistence backend"
2342
- },
2343
- { name: "key", type: "string", description: "Storage key" }
2344
- ]
2345
- },
2346
- {
2347
- name: "owned",
2348
- category: "networking",
2349
- properties: [
2350
- {
2351
- name: "transferable",
2352
- type: "boolean",
2353
- defaultValue: true,
2354
- description: "Can ownership be transferred"
2355
- }
2356
- ]
2357
- },
2358
- {
2359
- name: "host_only",
2360
- category: "networking",
2361
- properties: []
2362
- },
2363
- // =========================================================================
2364
- // BEHAVIOR TRAITS
2365
- // =========================================================================
2366
- {
2367
- name: "stackable",
2368
- category: "behavior",
2369
- properties: [
2370
- {
2371
- name: "stack_axis",
2372
- type: "enum",
2373
- enumValues: ["x", "y", "z"],
2374
- defaultValue: "y",
2375
- description: "Stacking axis"
2376
- },
2377
- {
2378
- name: "stack_offset",
2379
- type: "number",
2380
- defaultValue: 0,
2381
- description: "Offset between stacked objects"
2382
- },
2383
- {
2384
- name: "max_stack",
2385
- type: "number",
2386
- defaultValue: 10,
2387
- min: 1,
2388
- description: "Maximum stack height"
2389
- },
2390
- {
2391
- name: "snap_distance",
2392
- type: "number",
2393
- defaultValue: 0.5,
2394
- min: 0,
2395
- description: "Snap distance for stacking"
2396
- }
2397
- ]
2398
- },
2399
- {
2400
- name: "attachable",
2401
- category: "behavior",
2402
- properties: [
2403
- { name: "attach_point", type: "string", description: "Named attachment point" },
2404
- { name: "detachable", type: "boolean", defaultValue: true, description: "Can be detached" }
2405
- ]
2406
- },
2407
- {
2408
- name: "equippable",
2409
- category: "behavior",
2410
- requires: ["grabbable"],
2411
- properties: [
2412
- {
2413
- name: "slot",
2414
- type: "enum",
2415
- enumValues: ["head", "hand_left", "hand_right", "body", "back", "hip"],
2416
- description: "Equipment slot"
2417
- },
2418
- { name: "offset", type: "array", description: "Position offset when equipped" },
2419
- { name: "rotation", type: "array", description: "Rotation offset when equipped" }
2420
- ]
2421
- },
2422
- {
2423
- name: "consumable",
2424
- category: "behavior",
2425
- properties: [
2426
- { name: "uses", type: "number", defaultValue: 1, min: 1, description: "Number of uses" },
2427
- {
2428
- name: "destroy_on_use",
2429
- type: "boolean",
2430
- defaultValue: true,
2431
- description: "Destroy after last use"
2432
- }
2433
- ]
2434
- },
2435
- {
2436
- name: "destructible",
2437
- category: "behavior",
2438
- properties: [
2439
- { name: "health", type: "number", defaultValue: 100, min: 0, description: "Hit points" },
2440
- {
2441
- name: "fragments",
2442
- type: "number",
2443
- defaultValue: 8,
2444
- min: 1,
2445
- description: "Number of fragments"
2446
- }
2447
- ]
2448
- },
2449
- {
2450
- name: "breakable",
2451
- category: "behavior",
2452
- properties: [
2453
- {
2454
- name: "break_velocity",
2455
- type: "number",
2456
- defaultValue: 5,
2457
- min: 0,
2458
- description: "Velocity threshold to break"
2459
- },
2460
- {
2461
- name: "fragments",
2462
- type: "number",
2463
- defaultValue: 8,
2464
- min: 1,
2465
- description: "Number of fragments"
2466
- },
2467
- { name: "fragment_mesh", type: "string", description: "Custom fragment mesh" },
2468
- { name: "sound_on_break", type: "string", description: "Sound effect on break" },
2469
- { name: "respawn", type: "boolean", defaultValue: false, description: "Respawn after break" },
2470
- {
2471
- name: "respawn_time",
2472
- type: "number",
2473
- defaultValue: 5,
2474
- min: 0,
2475
- description: "Respawn delay in seconds"
2476
- }
2477
- ]
2478
- },
2479
- {
2480
- name: "character",
2481
- category: "behavior",
2482
- properties: [
2483
- {
2484
- name: "height",
2485
- type: "number",
2486
- defaultValue: 1.8,
2487
- min: 0,
2488
- description: "Character height"
2489
- },
2490
- { name: "speed", type: "number", defaultValue: 5, min: 0, description: "Movement speed" }
2491
- ]
2492
- },
2493
- // =========================================================================
2494
- // SPATIAL TRAITS
2495
- // =========================================================================
2496
- {
2497
- name: "anchor",
2498
- category: "spatial",
2499
- properties: [
2500
- {
2501
- name: "type",
2502
- type: "enum",
2503
- enumValues: ["plane", "point", "image", "face", "body"],
2504
- defaultValue: "plane",
2505
- description: "Anchor type"
2506
- },
2507
- {
2508
- name: "tracking",
2509
- type: "boolean",
2510
- defaultValue: true,
2511
- description: "Enable tracking updates"
2512
- }
2513
- ]
2514
- },
2515
- {
2516
- name: "tracked",
2517
- category: "spatial",
2518
- properties: [
2519
- {
2520
- name: "source",
2521
- type: "enum",
2522
- enumValues: ["hand", "head", "controller", "eye", "body"],
2523
- description: "Tracking source"
2524
- }
2525
- ]
2526
- },
2527
- {
2528
- name: "world_locked",
2529
- category: "spatial",
2530
- properties: [
2531
- {
2532
- name: "drift_correction",
2533
- type: "boolean",
2534
- defaultValue: true,
2535
- description: "Correct tracking drift"
2536
- }
2537
- ]
2538
- },
2539
- {
2540
- name: "hand_tracked",
2541
- category: "spatial",
2542
- properties: [
2543
- {
2544
- name: "hand",
2545
- type: "enum",
2546
- enumValues: ["left", "right", "both"],
2547
- defaultValue: "both",
2548
- description: "Which hand to track"
2549
- },
2550
- { name: "joint", type: "string", description: "Specific hand joint to track" }
2551
- ]
2552
- },
2553
- {
2554
- name: "eye_tracked",
2555
- category: "spatial",
2556
- properties: [
2557
- {
2558
- name: "dwell_time",
2559
- type: "number",
2560
- defaultValue: 1,
2561
- min: 0,
2562
- description: "Dwell activation time in seconds"
2563
- },
2564
- { name: "highlight", type: "boolean", defaultValue: true, description: "Highlight on gaze" }
2565
- ]
2566
- },
2567
- {
2568
- name: "position",
2569
- category: "spatial",
2570
- properties: [
2571
- { name: "x", type: "number", defaultValue: 0, description: "X position" },
2572
- { name: "y", type: "number", defaultValue: 0, description: "Y position" },
2573
- { name: "z", type: "number", defaultValue: 0, description: "Z position" }
2574
- ]
2575
- },
2576
- {
2577
- name: "rotation",
2578
- category: "spatial",
2579
- properties: [
2580
- { name: "x", type: "number", defaultValue: 0, description: "X rotation (degrees)" },
2581
- { name: "y", type: "number", defaultValue: 0, description: "Y rotation (degrees)" },
2582
- { name: "z", type: "number", defaultValue: 0, description: "Z rotation (degrees)" }
2583
- ]
2584
- },
2585
- {
2586
- name: "scale",
2587
- category: "spatial",
2588
- properties: [
2589
- { name: "x", type: "number", defaultValue: 1, min: 0, description: "X scale" },
2590
- { name: "y", type: "number", defaultValue: 1, min: 0, description: "Y scale" },
2591
- { name: "z", type: "number", defaultValue: 1, min: 0, description: "Z scale" }
2592
- ]
2593
- },
2594
- // =========================================================================
2595
- // AUDIO TRAITS
2596
- // =========================================================================
2597
- {
2598
- name: "spatial_audio",
2599
- category: "audio",
2600
- properties: [
2601
- { name: "src", type: "string", description: "Audio source file" },
2602
- {
2603
- name: "volume",
2604
- type: "number",
2605
- defaultValue: 1,
2606
- min: 0,
2607
- max: 1,
2608
- description: "Volume (0-1)"
2609
- },
2610
- {
2611
- name: "rolloff",
2612
- type: "enum",
2613
- enumValues: ["linear", "logarithmic", "inverse"],
2614
- defaultValue: "logarithmic",
2615
- description: "Distance rolloff model"
2616
- },
2617
- {
2618
- name: "refDistance",
2619
- type: "number",
2620
- defaultValue: 1,
2621
- min: 0,
2622
- description: "Reference distance"
2623
- },
2624
- {
2625
- name: "maxDistance",
2626
- type: "number",
2627
- defaultValue: 100,
2628
- min: 0,
2629
- description: "Max audible distance"
2630
- }
2631
- ]
2632
- },
2633
- {
2634
- name: "ambient",
2635
- category: "audio",
2636
- properties: [
2637
- { name: "src", type: "string", description: "Audio source file" },
2638
- {
2639
- name: "volume",
2640
- type: "number",
2641
- defaultValue: 0.5,
2642
- min: 0,
2643
- max: 1,
2644
- description: "Volume (0-1)"
2645
- },
2646
- { name: "loop", type: "boolean", defaultValue: true, description: "Loop playback" }
2647
- ]
2648
- },
2649
- {
2650
- name: "voice_activated",
2651
- category: "audio",
2652
- properties: [
2653
- {
2654
- name: "threshold",
2655
- type: "number",
2656
- defaultValue: 0.3,
2657
- min: 0,
2658
- max: 1,
2659
- description: "Voice activation threshold"
2660
- },
2661
- { name: "keyword", type: "string", description: "Activation keyword" }
2662
- ]
2663
- },
2664
- {
2665
- name: "sound",
2666
- category: "audio",
2667
- properties: [
2668
- { name: "src", type: "string", description: "Sound file path" },
2669
- { name: "volume", type: "number", defaultValue: 1, min: 0, max: 1, description: "Volume" },
2670
- { name: "loop", type: "boolean", defaultValue: false, description: "Loop playback" }
2671
- ]
2672
- },
2673
- // =========================================================================
2674
- // STATE TRAITS
2675
- // =========================================================================
2676
- {
2677
- name: "state",
2678
- category: "state",
2679
- properties: [{ name: "initial", type: "object", description: "Initial state values" }]
2680
- },
2681
- {
2682
- name: "reactive",
2683
- category: "state",
2684
- properties: [{ name: "bindings", type: "array", description: "Data bindings" }]
2685
- },
2686
- {
2687
- name: "observable",
2688
- category: "state",
2689
- properties: [{ name: "properties", type: "array", description: "Observable property names" }]
2690
- },
2691
- {
2692
- name: "computed",
2693
- category: "state",
2694
- properties: [
2695
- { name: "expression", type: "string", description: "Computed expression" },
2696
- { name: "dependencies", type: "array", description: "Dependency property names" }
2697
- ]
2698
- },
2699
- // =========================================================================
2700
- // ADVANCED TRAITS
2701
- // =========================================================================
2702
- {
2703
- name: "teleport",
2704
- category: "advanced",
2705
- properties: [
2706
- { name: "target", type: "string", description: "Teleport target position/name" },
2707
- {
2708
- name: "fade_duration",
2709
- type: "number",
2710
- defaultValue: 0.3,
2711
- min: 0,
2712
- description: "Fade transition duration"
2713
- }
2714
- ]
2715
- },
2716
- {
2717
- name: "ui_panel",
2718
- category: "advanced",
2719
- properties: [
2720
- {
2721
- name: "width",
2722
- type: "number",
2723
- defaultValue: 1,
2724
- min: 0,
2725
- description: "Panel width in meters"
2726
- },
2727
- {
2728
- name: "height",
2729
- type: "number",
2730
- defaultValue: 0.75,
2731
- min: 0,
2732
- description: "Panel height in meters"
2733
- },
2734
- { name: "curved", type: "boolean", defaultValue: false, description: "Curved panel" }
2735
- ]
2736
- },
2737
- {
2738
- name: "particle_system",
2739
- category: "advanced",
2740
- properties: [
2741
- { name: "count", type: "number", defaultValue: 100, min: 1, description: "Particle count" },
2742
- {
2743
- name: "lifetime",
2744
- type: "number",
2745
- defaultValue: 2,
2746
- min: 0,
2747
- description: "Particle lifetime in seconds"
2748
- },
2749
- { name: "speed", type: "number", defaultValue: 1, min: 0, description: "Emission speed" },
2750
- { name: "color", type: "string", defaultValue: "#ffffff", description: "Particle color" },
2751
- {
2752
- name: "shape",
2753
- type: "enum",
2754
- enumValues: ["point", "sphere", "cone", "box"],
2755
- defaultValue: "point",
2756
- description: "Emitter shape"
2757
- }
2758
- ]
2759
- },
2760
- {
2761
- name: "weather",
2762
- category: "advanced",
2763
- properties: [
2764
- {
2765
- name: "type",
2766
- type: "enum",
2767
- enumValues: ["rain", "snow", "fog", "wind", "storm"],
2768
- description: "Weather type"
2769
- },
2770
- {
2771
- name: "intensity",
2772
- type: "number",
2773
- defaultValue: 0.5,
2774
- min: 0,
2775
- max: 1,
2776
- description: "Weather intensity (0-1)"
2777
- }
2778
- ]
2779
- },
2780
- {
2781
- name: "day_night",
2782
- category: "advanced",
2783
- properties: [
2784
- {
2785
- name: "cycle_duration",
2786
- type: "number",
2787
- defaultValue: 300,
2788
- min: 1,
2789
- description: "Full cycle duration in seconds"
2790
- },
2791
- {
2792
- name: "start_time",
2793
- type: "number",
2794
- defaultValue: 0.5,
2795
- min: 0,
2796
- max: 1,
2797
- description: "Start time (0=midnight, 0.5=noon)"
2798
- }
2799
- ]
2800
- },
2801
- {
2802
- name: "lod",
2803
- category: "advanced",
2804
- properties: [
2805
- { name: "distances", type: "array", description: "LOD distance thresholds" },
2806
- { name: "meshes", type: "array", description: "Mesh paths for each LOD level" }
2807
- ]
2808
- },
2809
- {
2810
- name: "hand_tracking",
2811
- category: "advanced",
2812
- properties: [
2813
- {
2814
- name: "gesture_recognition",
2815
- type: "boolean",
2816
- defaultValue: true,
2817
- description: "Enable gesture recognition"
2818
- },
2819
- {
2820
- name: "mesh_visualization",
2821
- type: "boolean",
2822
- defaultValue: false,
2823
- description: "Show hand mesh"
2824
- }
2825
- ]
2826
- },
2827
- {
2828
- name: "haptic",
2829
- category: "advanced",
2830
- properties: [
2831
- {
2832
- name: "intensity",
2833
- type: "number",
2834
- defaultValue: 0.5,
2835
- min: 0,
2836
- max: 1,
2837
- description: "Haptic intensity (0-1)"
2838
- },
2839
- {
2840
- name: "duration",
2841
- type: "number",
2842
- defaultValue: 100,
2843
- min: 0,
2844
- description: "Duration in milliseconds"
2845
- },
2846
- {
2847
- name: "pattern",
2848
- type: "enum",
2849
- enumValues: ["pulse", "buzz", "click", "custom"],
2850
- defaultValue: "pulse",
2851
- description: "Haptic pattern"
2852
- }
2853
- ]
2854
- },
2855
- {
2856
- name: "portal",
2857
- category: "advanced",
2858
- properties: [
2859
- {
2860
- name: "destination",
2861
- type: "string",
2862
- required: true,
2863
- description: "Target scene/composition"
2864
- },
2865
- {
2866
- name: "size",
2867
- type: "number",
2868
- defaultValue: 2,
2869
- min: 0,
2870
- description: "Portal size in meters"
2871
- },
2872
- {
2873
- name: "shape",
2874
- type: "enum",
2875
- enumValues: ["circle", "rectangle"],
2876
- defaultValue: "circle",
2877
- description: "Portal shape"
2878
- }
2879
- ]
2880
- },
2881
- {
2882
- name: "mirror",
2883
- category: "advanced",
2884
- properties: [
2885
- { name: "size", type: "number", defaultValue: 2, min: 0, description: "Mirror plane size" },
2886
- { name: "tint", type: "string", defaultValue: "#ffffff", description: "Reflection tint" },
2887
- {
2888
- name: "orientation",
2889
- type: "enum",
2890
- enumValues: ["vertical", "horizontal", "face_camera"],
2891
- defaultValue: "vertical",
2892
- description: "Mirror orientation"
2893
- }
2894
- ]
2895
- }
2896
- ];
2897
- ConfabulationValidator = class {
2898
- constructor(config = {}) {
2899
- this.config = {
2900
- riskThreshold: config.riskThreshold ?? 50,
2901
- unknownPropertySeverity: config.unknownPropertySeverity ?? "warning",
2902
- validatePrerequisites: config.validatePrerequisites ?? true,
2903
- validateConflicts: config.validateConflicts ?? true,
2904
- validateRanges: config.validateRanges ?? true,
2905
- customSchemas: config.customSchemas ?? [],
2906
- strict: config.strict ?? false
2907
- };
2908
- this.schemaRegistry = /* @__PURE__ */ new Map();
2909
- for (const schema of BUILT_IN_TRAIT_SCHEMAS) {
2910
- this.schemaRegistry.set(schema.name, schema);
2911
- }
2912
- for (const schema of this.config.customSchemas) {
2913
- this.schemaRegistry.set(schema.name, schema);
2914
- }
2915
- }
2916
- // =========================================================================
2917
- // PUBLIC API
2918
- // =========================================================================
2919
- /**
2920
- * Validate an entire HoloComposition against trait schemas.
2921
- *
2922
- * Iterates over all objects in the composition, extracts their traits
2923
- * and properties, and validates against the schema registry.
2924
- */
2925
- validateComposition(composition) {
2926
- const startTime = Date.now();
2927
- const errors = [];
2928
- const warnings = [];
2929
- let traitsChecked = 0;
2930
- let propertiesChecked = 0;
2931
- for (const obj of composition.objects || []) {
2932
- const objResult = this.validateObject(obj);
2933
- errors.push(...objResult.errors);
2934
- warnings.push(...objResult.warnings);
2935
- traitsChecked += objResult.traitsChecked;
2936
- propertiesChecked += objResult.propertiesChecked;
2937
- }
2938
- if (composition.traitDefinitions) {
2939
- for (const traitDef of composition.traitDefinitions) {
2940
- if (traitDef.base) {
2941
- const baseSchema = this.schemaRegistry.get(traitDef.base);
2942
- if (!baseSchema) {
2943
- warnings.push({
2944
- code: "CONFAB_UNKNOWN_BASE_TRAIT",
2945
- message: `Trait "${traitDef.name}" extends unknown base trait "${traitDef.base}"`,
2946
- traitName: traitDef.name,
2947
- riskContribution: 10
2948
- });
2949
- }
2950
- }
2951
- }
2952
- }
2953
- const riskScore = this.calculateRiskScore(errors, warnings);
2954
- const valid = this.config.strict ? errors.length === 0 && warnings.length === 0 && riskScore <= this.config.riskThreshold : errors.length === 0 && riskScore <= this.config.riskThreshold;
2955
- return {
2956
- valid,
2957
- riskScore,
2958
- errors,
2959
- warnings,
2960
- traitsChecked,
2961
- propertiesChecked,
2962
- validationTimeMs: Date.now() - startTime
2963
- };
2964
- }
2965
- /**
2966
- * Validate a single trait's properties against its schema.
2967
- *
2968
- * @param traitName - Trait name (without @ prefix)
2969
- * @param properties - Property key-value pairs to validate
2970
- * @param objectName - Optional object context for error messages
2971
- */
2972
- validateTraitProperties(traitName, properties, objectName) {
2973
- const errors = [];
2974
- const warnings = [];
2975
- const normalizedName = traitName.startsWith("@") ? traitName.slice(1) : traitName;
2976
- const schema = this.schemaRegistry.get(normalizedName);
2977
- if (!schema) {
2978
- warnings.push({
2979
- code: "CONFAB_UNKNOWN_TRAIT" /* UNKNOWN_TRAIT */,
2980
- message: `Trait "@${normalizedName}" not found in schema registry (${this.schemaRegistry.size} schemas loaded)`,
2981
- objectName,
2982
- traitName: normalizedName,
2983
- riskContribution: 5
2984
- });
2985
- return { errors, warnings };
2986
- }
2987
- for (const [key, value] of Object.entries(properties)) {
2988
- const propSchema = schema.properties.find((p) => p.name === key);
2989
- if (!propSchema) {
2990
- const entry = {
2991
- code: "CONFAB_UNKNOWN_PROPERTY" /* UNKNOWN_PROPERTY */,
2992
- message: `Unknown property "${key}" on trait "@${normalizedName}". Known properties: ${schema.properties.map((p) => p.name).join(", ")}`,
2993
- objectName,
2994
- traitName: normalizedName,
2995
- propertyName: key,
2996
- riskContribution: 15
2997
- };
2998
- if (this.config.unknownPropertySeverity === "error") {
2999
- errors.push({ ...entry, suggestion: `Remove "${key}" or check spelling` });
3000
- } else {
3001
- warnings.push(entry);
3002
- }
3003
- continue;
3004
- }
3005
- const typeError = this.validatePropertyType(propSchema, value, normalizedName, objectName);
3006
- if (typeError) {
3007
- errors.push(typeError);
3008
- continue;
3009
- }
3010
- if (this.config.validateRanges) {
3011
- const rangeError = this.validatePropertyRange(
3012
- propSchema,
3013
- value,
3014
- normalizedName,
3015
- objectName
3016
- );
3017
- if (rangeError) {
3018
- errors.push(rangeError);
3019
- }
3020
- }
3021
- if (propSchema.type === "enum" && propSchema.enumValues) {
3022
- if (typeof value === "string" && !propSchema.enumValues.includes(value)) {
3023
- errors.push({
3024
- code: "CONFAB_INVALID_ENUM_VALUE" /* INVALID_ENUM_VALUE */,
3025
- message: `Invalid value "${value}" for property "${key}" on trait "@${normalizedName}". Allowed values: ${propSchema.enumValues.join(", ")}`,
3026
- objectName,
3027
- traitName: normalizedName,
3028
- propertyName: key,
3029
- suggestion: `Use one of: ${propSchema.enumValues.join(", ")}`,
3030
- riskContribution: 20
3031
- });
3032
- }
3033
- }
3034
- }
3035
- for (const propSchema of schema.properties) {
3036
- if (propSchema.required && !(propSchema.name in properties)) {
3037
- errors.push({
3038
- code: "CONFAB_MISSING_REQUIRED_PROPERTY" /* MISSING_REQUIRED_PROPERTY */,
3039
- message: `Missing required property "${propSchema.name}" on trait "@${normalizedName}"`,
3040
- objectName,
3041
- traitName: normalizedName,
3042
- propertyName: propSchema.name,
3043
- suggestion: `Add property "${propSchema.name}" (${propSchema.type})`,
3044
- riskContribution: 20
3045
- });
3046
- }
3047
- }
3048
- return { errors, warnings };
3049
- }
3050
- /**
3051
- * Check if a trait name is in the schema registry.
3052
- */
3053
- isKnownTrait(traitName) {
3054
- const normalized = traitName.startsWith("@") ? traitName.slice(1) : traitName;
3055
- return this.schemaRegistry.has(normalized);
3056
- }
3057
- /**
3058
- * Get the schema for a trait.
3059
- */
3060
- getTraitSchema(traitName) {
3061
- const normalized = traitName.startsWith("@") ? traitName.slice(1) : traitName;
3062
- return this.schemaRegistry.get(normalized);
3063
- }
3064
- /**
3065
- * Get all registered trait names.
3066
- */
3067
- getRegisteredTraits() {
3068
- return Array.from(this.schemaRegistry.keys());
3069
- }
3070
- /**
3071
- * Get the number of registered schemas.
3072
- */
3073
- get schemaCount() {
3074
- return this.schemaRegistry.size;
3075
- }
3076
- /**
3077
- * Register additional trait schemas at runtime.
3078
- */
3079
- registerSchema(schema) {
3080
- this.schemaRegistry.set(schema.name, schema);
3081
- }
3082
- /**
3083
- * Register multiple trait schemas at runtime.
3084
- */
3085
- registerSchemas(schemas) {
3086
- for (const schema of schemas) {
3087
- this.schemaRegistry.set(schema.name, schema);
3088
- }
3089
- }
3090
- // =========================================================================
3091
- // PRIVATE METHODS
3092
- // =========================================================================
3093
- /**
3094
- * Validate a single object's traits.
3095
- */
3096
- validateObject(obj) {
3097
- const errors = [];
3098
- const warnings = [];
3099
- let traitsChecked = 0;
3100
- let propertiesChecked = 0;
3101
- const objectTraitNames = [];
3102
- const authority = obj.provenance?.context?.authority;
3103
- if (authority === "system" || authority === "verified") {
3104
- return { errors, warnings, traitsChecked: 0, propertiesChecked: 0 };
3105
- }
3106
- if (obj.traits) {
3107
- for (const trait of obj.traits) {
3108
- traitsChecked++;
3109
- const traitName = trait.name.startsWith("@") ? trait.name.slice(1) : trait.name;
3110
- objectTraitNames.push(traitName);
3111
- const properties = {};
3112
- const traitExt = trait;
3113
- if (traitExt.args) {
3114
- for (const arg of traitExt.args) {
3115
- properties[arg.key] = arg.value;
3116
- propertiesChecked++;
3117
- }
3118
- } else if (trait.config) {
3119
- for (const [key, value] of Object.entries(trait.config)) {
3120
- properties[key] = value;
3121
- propertiesChecked++;
3122
- }
3123
- }
3124
- const result = this.validateTraitProperties(traitName, properties, obj.name);
3125
- errors.push(...result.errors);
3126
- warnings.push(...result.warnings);
3127
- }
3128
- }
3129
- if (this.config.validatePrerequisites) {
3130
- for (const traitName of objectTraitNames) {
3131
- const schema = this.schemaRegistry.get(traitName);
3132
- if (schema?.requires) {
3133
- for (const req of schema.requires) {
3134
- if (!objectTraitNames.includes(req)) {
3135
- errors.push({
3136
- code: "CONFAB_MISSING_REQUIRED_TRAIT" /* MISSING_REQUIRED_TRAIT */,
3137
- message: `Trait "@${traitName}" requires "@${req}" but it is not present on object "${obj.name}"`,
3138
- objectName: obj.name,
3139
- traitName,
3140
- suggestion: `Add @${req} to object "${obj.name}"`,
3141
- riskContribution: 15
3142
- });
3143
- }
3144
- }
3145
- }
3146
- }
3147
- }
3148
- if (this.config.validateConflicts) {
3149
- for (const traitName of objectTraitNames) {
3150
- const schema = this.schemaRegistry.get(traitName);
3151
- if (schema?.conflictsWith) {
3152
- for (const conflict of schema.conflictsWith) {
3153
- if (objectTraitNames.includes(conflict)) {
3154
- errors.push({
3155
- code: "CONFAB_CONFLICTING_TRAITS" /* CONFLICTING_TRAITS */,
3156
- message: `Traits "@${traitName}" and "@${conflict}" are mutually exclusive on object "${obj.name}"`,
3157
- objectName: obj.name,
3158
- traitName,
3159
- suggestion: `Remove either @${traitName} or @${conflict}`,
3160
- riskContribution: 25
3161
- });
3162
- }
3163
- }
3164
- }
3165
- }
3166
- }
3167
- if (obj.children) {
3168
- for (const child of obj.children) {
3169
- const childResult = this.validateObject(child);
3170
- errors.push(...childResult.errors);
3171
- warnings.push(...childResult.warnings);
3172
- traitsChecked += childResult.traitsChecked;
3173
- propertiesChecked += childResult.propertiesChecked;
3174
- }
3175
- }
3176
- return { errors, warnings, traitsChecked, propertiesChecked };
3177
- }
3178
- /**
3179
- * Validate that a property value matches its expected type.
3180
- */
3181
- validatePropertyType(propSchema, value, traitName, objectName) {
3182
- if (value === null || value === void 0) return null;
3183
- if (propSchema.type === "any") return null;
3184
- const actualType = typeof value;
3185
- switch (propSchema.type) {
3186
- case "string":
3187
- case "color":
3188
- if (actualType !== "string") {
3189
- return {
3190
- code: "CONFAB_TYPE_MISMATCH" /* TYPE_MISMATCH */,
3191
- message: `Property "${propSchema.name}" on "@${traitName}" expects ${propSchema.type} but got ${actualType}`,
3192
- objectName,
3193
- traitName,
3194
- propertyName: propSchema.name,
3195
- suggestion: `Convert value to a string`,
3196
- riskContribution: 20
3197
- };
3198
- }
3199
- break;
3200
- case "number":
3201
- if (actualType !== "number") {
3202
- return {
3203
- code: "CONFAB_TYPE_MISMATCH" /* TYPE_MISMATCH */,
3204
- message: `Property "${propSchema.name}" on "@${traitName}" expects number but got ${actualType}`,
3205
- objectName,
3206
- traitName,
3207
- propertyName: propSchema.name,
3208
- suggestion: `Use a numeric value`,
3209
- riskContribution: 20
3210
- };
3211
- }
3212
- break;
3213
- case "boolean":
3214
- if (actualType !== "boolean") {
3215
- return {
3216
- code: "CONFAB_TYPE_MISMATCH" /* TYPE_MISMATCH */,
3217
- message: `Property "${propSchema.name}" on "@${traitName}" expects boolean but got ${actualType}`,
3218
- objectName,
3219
- traitName,
3220
- propertyName: propSchema.name,
3221
- suggestion: `Use true or false`,
3222
- riskContribution: 20
3223
- };
3224
- }
3225
- break;
3226
- case "array":
3227
- case "vector3":
3228
- if (!Array.isArray(value)) {
3229
- return {
3230
- code: "CONFAB_TYPE_MISMATCH" /* TYPE_MISMATCH */,
3231
- message: `Property "${propSchema.name}" on "@${traitName}" expects ${propSchema.type} but got ${actualType}`,
3232
- objectName,
3233
- traitName,
3234
- propertyName: propSchema.name,
3235
- suggestion: `Use an array value, e.g., [0, 0, 0]`,
3236
- riskContribution: 20
3237
- };
3238
- }
3239
- break;
3240
- case "object":
3241
- if (actualType !== "object" || Array.isArray(value)) {
3242
- return {
3243
- code: "CONFAB_TYPE_MISMATCH" /* TYPE_MISMATCH */,
3244
- message: `Property "${propSchema.name}" on "@${traitName}" expects object but got ${Array.isArray(value) ? "array" : actualType}`,
3245
- objectName,
3246
- traitName,
3247
- propertyName: propSchema.name,
3248
- suggestion: `Use an object value, e.g., { key: value }`,
3249
- riskContribution: 20
3250
- };
3251
- }
3252
- break;
3253
- case "enum":
3254
- if (actualType !== "string") {
3255
- return {
3256
- code: "CONFAB_TYPE_MISMATCH" /* TYPE_MISMATCH */,
3257
- message: `Property "${propSchema.name}" on "@${traitName}" expects enum (string) but got ${actualType}`,
3258
- objectName,
3259
- traitName,
3260
- propertyName: propSchema.name,
3261
- suggestion: propSchema.enumValues ? `Use one of: ${propSchema.enumValues.join(", ")}` : `Use a string value`,
3262
- riskContribution: 20
3263
- };
3264
- }
3265
- break;
3266
- }
3267
- return null;
3268
- }
3269
- /**
3270
- * Validate that a numeric property value is within its allowed range.
3271
- */
3272
- validatePropertyRange(propSchema, value, traitName, objectName) {
3273
- if (typeof value !== "number") return null;
3274
- if (propSchema.min !== void 0 && value < propSchema.min) {
3275
- return {
3276
- code: "CONFAB_VALUE_OUT_OF_RANGE" /* VALUE_OUT_OF_RANGE */,
3277
- message: `Property "${propSchema.name}" on "@${traitName}" has value ${value} but minimum is ${propSchema.min}`,
3278
- objectName,
3279
- traitName,
3280
- propertyName: propSchema.name,
3281
- suggestion: `Use a value >= ${propSchema.min}`,
3282
- riskContribution: 15
3283
- };
3284
- }
3285
- if (propSchema.max !== void 0 && value > propSchema.max) {
3286
- return {
3287
- code: "CONFAB_VALUE_OUT_OF_RANGE" /* VALUE_OUT_OF_RANGE */,
3288
- message: `Property "${propSchema.name}" on "@${traitName}" has value ${value} but maximum is ${propSchema.max}`,
3289
- objectName,
3290
- traitName,
3291
- propertyName: propSchema.name,
3292
- suggestion: `Use a value <= ${propSchema.max}`,
3293
- riskContribution: 15
3294
- };
3295
- }
3296
- return null;
3297
- }
3298
- /**
3299
- * Calculate the overall confabulation risk score.
3300
- */
3301
- calculateRiskScore(errors, warnings) {
3302
- let score = 0;
3303
- for (const error of errors) {
3304
- score += error.riskContribution;
3305
- }
3306
- for (const warning of warnings) {
3307
- score += warning.riskContribution;
3308
- }
3309
- return Math.min(100, score);
3310
- }
3311
- };
3312
- globalConfabulationValidator = null;
3313
- }
3314
- });
3315
- function getRBAC(tokenIssuer) {
3316
- if (!globalRBAC) {
3317
- globalRBAC = new AgentRBAC(tokenIssuer);
3318
- }
3319
- return globalRBAC;
3320
- }
3321
- var RESOURCE_PERMISSION_MAP, AgentRBAC, globalRBAC;
3322
- var init_AgentRBAC = __esm({
3323
- "src/compiler/identity/AgentRBAC.ts"() {
3324
- init_AgentIdentity();
3325
- init_AgentTokenIssuer();
3326
- init_CulturalCompatibilityChecker();
3327
- init_ConfabulationValidator();
3328
- RESOURCE_PERMISSION_MAP = {
3329
- ["source_file" /* SOURCE_FILE */]: {
3330
- read: "read:source" /* READ_SOURCE */,
3331
- write: "write:ast" /* WRITE_AST */,
3332
- // Source modification creates AST
3333
- execute: "execute:optimization" /* EXECUTE_OPTIMIZATION */,
3334
- // Not applicable
3335
- transform: "transform:ast" /* TRANSFORM_AST */
3336
- // Not applicable
3337
- },
3338
- ["ast" /* AST */]: {
3339
- read: "read:ast" /* READ_AST */,
3340
- write: "write:ast" /* WRITE_AST */,
3341
- execute: "execute:optimization" /* EXECUTE_OPTIMIZATION */,
3342
- transform: "transform:ast" /* TRANSFORM_AST */
3343
- },
3344
- ["ir" /* IR */]: {
3345
- read: "read:ir" /* READ_IR */,
3346
- write: "write:ir" /* WRITE_IR */,
3347
- execute: "execute:codegen" /* EXECUTE_CODEGEN */,
3348
- transform: "transform:ir" /* TRANSFORM_IR */
3349
- },
3350
- ["code" /* CODE */]: {
3351
- read: "read:code" /* READ_CODE */,
3352
- write: "write:code" /* WRITE_CODE */,
3353
- execute: "execute:codegen" /* EXECUTE_CODEGEN */,
3354
- transform: "transform:ir" /* TRANSFORM_IR */
3355
- // Not applicable
3356
- },
3357
- ["output" /* OUTPUT */]: {
3358
- read: "read:code" /* READ_CODE */,
3359
- write: "write:output" /* WRITE_OUTPUT */,
3360
- execute: "execute:export" /* EXECUTE_EXPORT */,
3361
- transform: "write:output" /* WRITE_OUTPUT */
3362
- // Not applicable
3363
- },
3364
- ["config" /* CONFIG */]: {
3365
- read: "read:config" /* READ_CONFIG */,
3366
- write: "write:ast" /* WRITE_AST */,
3367
- // Config changes trigger rebuild
3368
- execute: "execute:optimization" /* EXECUTE_OPTIMIZATION */,
3369
- // Not applicable
3370
- transform: "transform:ast" /* TRANSFORM_AST */
3371
- // Not applicable
3372
- }
3373
- };
3374
- AgentRBAC = class {
3375
- constructor(tokenIssuer) {
3376
- /** Package scope restrictions (role → allowed paths) */
3377
- this.scopeRestrictions = /* @__PURE__ */ new Map();
3378
- /** Workflow step restrictions (role → allowed steps) */
3379
- this.workflowRestrictions = /* @__PURE__ */ new Map();
3380
- this.tokenIssuer = tokenIssuer || getTokenIssuer();
3381
- this.initializeWorkflowRestrictions();
3382
- }
3383
- /**
3384
- * Initialize default workflow step restrictions for each role
3385
- */
3386
- initializeWorkflowRestrictions() {
3387
- this.workflowRestrictions.set("syntax_analyzer" /* SYNTAX_ANALYZER */, [
3388
- "parse_tokens" /* PARSE_TOKENS */,
3389
- "build_ast" /* BUILD_AST */
3390
- ]);
3391
- this.workflowRestrictions.set("ast_optimizer" /* AST_OPTIMIZER */, [
3392
- "analyze_ast" /* ANALYZE_AST */,
3393
- "apply_transforms" /* APPLY_TRANSFORMS */
3394
- ]);
3395
- this.workflowRestrictions.set("code_generator" /* CODE_GENERATOR */, [
3396
- "select_instructions" /* SELECT_INSTRUCTIONS */,
3397
- "generate_assembly" /* GENERATE_ASSEMBLY */
3398
- ]);
3399
- this.workflowRestrictions.set("exporter" /* EXPORTER */, [
3400
- "format_output" /* FORMAT_OUTPUT */,
3401
- "serialize" /* SERIALIZE */
3402
- ]);
3403
- this.workflowRestrictions.set("orchestrator" /* ORCHESTRATOR */, Object.values(WorkflowStep));
3404
- }
3405
- /**
3406
- * Set scope restriction for an agent role
3407
- *
3408
- * Example: Restrict syntax analyzer to only process files in 'packages/core'
3409
- */
3410
- setScopeRestriction(role, allowedPaths) {
3411
- this.scopeRestrictions.set(role, allowedPaths);
3412
- }
3413
- /**
3414
- * Check if agent can access resource
3415
- */
3416
- checkAccess(request) {
3417
- const { token, resourceType, operation, resourcePath, expectedWorkflowStep } = request;
3418
- const verificationResult = this.tokenIssuer.verifyToken(token);
3419
- if (!verificationResult.valid) {
3420
- return {
3421
- allowed: false,
3422
- reason: `Token verification failed: ${verificationResult.error}`
3423
- };
3424
- }
3425
- const payload = verificationResult.payload;
3426
- const requiredPermission = RESOURCE_PERMISSION_MAP[resourceType][operation];
3427
- if (!payload.permissions.includes(requiredPermission)) {
3428
- return {
3429
- allowed: false,
3430
- reason: `Missing required permission: ${requiredPermission}`,
3431
- requiredPermission,
3432
- agentRole: payload.agent_role
3433
- };
3434
- }
3435
- if (resourcePath) {
3436
- const scopeAllowed = this.validateScope(payload, resourcePath);
3437
- if (!scopeAllowed) {
3438
- return {
3439
- allowed: false,
3440
- reason: `Resource path '${resourcePath}' is outside agent scope: ${payload.scope || "unrestricted"}`,
3441
- agentRole: payload.agent_role
3442
- };
3443
- }
3444
- }
3445
- if (expectedWorkflowStep) {
3446
- const currentStep = payload.intent.workflow_step;
3447
- if (currentStep !== expectedWorkflowStep) {
3448
- return {
3449
- allowed: false,
3450
- reason: `Workflow step mismatch: expected ${expectedWorkflowStep}, agent is at ${currentStep}`,
3451
- agentRole: payload.agent_role
3452
- };
3453
- }
3454
- }
3455
- const allowedSteps = this.workflowRestrictions.get(payload.agent_role);
3456
- if (allowedSteps && !allowedSteps.includes(payload.intent.workflow_step)) {
3457
- return {
3458
- allowed: false,
3459
- reason: `Role ${payload.agent_role} cannot execute workflow step ${payload.intent.workflow_step}`,
3460
- agentRole: payload.agent_role
3461
- };
3462
- }
3463
- return {
3464
- allowed: true,
3465
- agentRole: payload.agent_role
3466
- };
3467
- }
3468
- /**
3469
- * Validate resource path is within agent's scope
3470
- */
3471
- validateScope(payload, resourcePath) {
3472
- if (!payload.scope) {
3473
- return true;
3474
- }
3475
- const normalizedResource = path.normalize(resourcePath);
3476
- const normalizedScope = path.normalize(payload.scope);
3477
- return normalizedResource.startsWith(normalizedScope);
3478
- }
3479
- /**
3480
- * Convenience method: Check if agent can read source file
3481
- */
3482
- canReadSource(token, filePath) {
3483
- return this.checkAccess({
3484
- token,
3485
- resourceType: "source_file" /* SOURCE_FILE */,
3486
- operation: "read",
3487
- resourcePath: filePath
3488
- });
3489
- }
3490
- /**
3491
- * Convenience method: Check if agent can modify AST
3492
- */
3493
- canModifyAST(token, expectedWorkflowStep) {
3494
- return this.checkAccess({
3495
- token,
3496
- resourceType: "ast" /* AST */,
3497
- operation: "write",
3498
- expectedWorkflowStep
3499
- });
3500
- }
3501
- /**
3502
- * Convenience method: Check if agent can generate code
3503
- */
3504
- canGenerateCode(token) {
3505
- return this.checkAccess({
3506
- token,
3507
- resourceType: "code" /* CODE */,
3508
- operation: "write",
3509
- expectedWorkflowStep: "generate_assembly" /* GENERATE_ASSEMBLY */
3510
- });
3511
- }
3512
- /**
3513
- * Convenience method: Check if agent can export to output path
3514
- */
3515
- canExport(token, outputPath) {
3516
- return this.checkAccess({
3517
- token,
3518
- resourceType: "output" /* OUTPUT */,
3519
- operation: "write",
3520
- resourcePath: outputPath,
3521
- expectedWorkflowStep: "serialize" /* SERIALIZE */
3522
- });
3523
- }
3524
- /**
3525
- * Extract agent role from token (without full verification)
3526
- */
3527
- extractRole(token) {
3528
- const result = this.tokenIssuer.verifyToken(token);
3529
- return result.valid && result.payload ? result.payload.agent_role : null;
3530
- }
3531
- /**
3532
- * Get agent's current workflow step
3533
- */
3534
- getWorkflowStep(token) {
3535
- const result = this.tokenIssuer.verifyToken(token);
3536
- return result.valid && result.payload ? result.payload.intent.workflow_step : null;
3537
- }
3538
- // ===========================================================================
3539
- // CONFABULATION RISK LAYER (v1.1.0)
3540
- // ===========================================================================
3541
- /**
3542
- * Check access with confabulation gate.
3543
- *
3544
- * This is the primary enforcement point for AI-generated content. It chains:
3545
- * 1. Standard RBAC permission check (token, role, scope, workflow)
3546
- * 2. Confabulation schema validation (trait properties against 1,800+ schemas)
3547
- *
3548
- * If the RBAC check fails, the confabulation check is skipped (no point
3549
- * validating content from an unauthorized agent).
3550
- *
3551
- * @param request - Standard resource access request
3552
- * @param composition - The HoloComposition to validate for confabulation
3553
- * @param confabConfig - Optional confabulation validator configuration
3554
- * @returns Extended access decision with confabulation validation results
3555
- */
3556
- checkAccessWithConfabulationGate(request, composition, confabConfig) {
3557
- const rbacDecision = this.checkAccess(request);
3558
- if (!rbacDecision.allowed) {
3559
- return rbacDecision;
3560
- }
3561
- const validator = confabConfig ? new ConfabulationValidator(confabConfig) : getConfabulationValidator();
3562
- const confabResult = validator.validateComposition(composition);
3563
- if (!confabResult.valid) {
3564
- return {
3565
- allowed: false,
3566
- reason: `Confabulation detected (risk score: ${confabResult.riskScore}/100, ${confabResult.errors.length} error(s)): ` + confabResult.errors.map((e) => e.message).join("; "),
3567
- agentRole: rbacDecision.agentRole,
3568
- confabulation: confabResult
3569
- };
3570
- }
3571
- return {
3572
- ...rbacDecision,
3573
- confabulation: confabResult
3574
- };
3575
- }
3576
- /**
3577
- * Validate a composition for confabulation risk WITHOUT requiring an RBAC token.
3578
- *
3579
- * This is useful for the validate_holoscript MCP tool and the ai-validator
3580
- * package which may not have an agent token but still need to check for
3581
- * confabulated trait properties.
3582
- *
3583
- * @param composition - The HoloComposition to validate
3584
- * @param confabConfig - Optional confabulation validator configuration
3585
- * @returns Confabulation validation result
3586
- */
3587
- validateConfabulation(composition, confabConfig) {
3588
- const validator = confabConfig ? new ConfabulationValidator(confabConfig) : getConfabulationValidator();
3589
- return validator.validateComposition(composition);
3590
- }
3591
- // ===========================================================================
3592
- // CULTURAL PROFILE INTEGRATION
3593
- // ===========================================================================
3594
- /**
3595
- * Extract cultural profile metadata from an agent's JWT token.
3596
- *
3597
- * @param token - Agent JWT token
3598
- * @returns The cultural profile if present, or null
3599
- */
3600
- extractCulturalProfile(token) {
3601
- const result = this.tokenIssuer.verifyToken(token);
3602
- if (!result.valid || !result.payload) return null;
3603
- return result.payload.cultural_profile ?? null;
3604
- }
3605
- /**
3606
- * Validate cultural compatibility across multiple agent tokens.
3607
- *
3608
- * Extracts cultural profiles from each provided token and runs them
3609
- * through the CulturalCompatibilityChecker. Agents whose tokens
3610
- * do not contain cultural profiles are silently skipped.
3611
- *
3612
- * @param agentTokens - Map of agent name to JWT token
3613
- * @param normSets - Optional map of agent name to norm_set arrays
3614
- * (norms are composition-level, not token-level)
3615
- * @returns Cultural compatibility result, or null if fewer than 2 agents
3616
- * have cultural profiles
3617
- */
3618
- validateCulturalCompatibility(agentTokens, normSets) {
3619
- const entries = [];
3620
- for (const [name, token] of agentTokens) {
3621
- const profile = this.extractCulturalProfile(token);
3622
- if (profile) {
3623
- entries.push({
3624
- name,
3625
- profile: {
3626
- cooperation_index: profile.cooperation_index,
3627
- cultural_family: profile.cultural_family,
3628
- prompt_dialect: profile.prompt_dialect,
3629
- norm_set: normSets?.get(name) ?? []
3630
- }
3631
- });
3632
- }
3633
- }
3634
- if (entries.length < 2) return null;
3635
- const checker = new CulturalCompatibilityChecker();
3636
- return checker.check(entries);
3637
- }
3638
- };
3639
- globalRBAC = null;
3640
- }
3641
- });
3642
-
3643
- export { BUILTIN_NORMS, HOLOSCRIPT_RESOURCE_SCHEME, HoloScriptCapabilitySemantics, criticalMassForChange, getBuiltinNorm, getCapabilityTokenIssuer, getRBAC, getTokenIssuer, init_AgentRBAC, init_AgentTokenIssuer, init_CapabilityToken, init_CapabilityTokenIssuer, init_CultureTraits, normsByCategory };
3644
- //# sourceMappingURL=chunk-V42NTCFH.js.map
3645
- //# sourceMappingURL=chunk-V42NTCFH.js.map