@holoscript/core 8.0.13 → 8.0.15

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 (191) hide show
  1. package/README.md +20 -13
  2. package/bin/holo-decision.mjs +133 -0
  3. package/bin/holoscript.cjs +0 -0
  4. package/dist/{GLTFPipeline-L76YTXKA.js → GLTFPipeline-FRBZIATS.js} +7 -7
  5. package/dist/{GLTFPipeline-ZWJN7GI6.cjs → GLTFPipeline-MTPP444P.cjs} +11 -11
  6. package/dist/{HoloCompositionParser-P4Y3CXKQ.js → HoloCompositionParser-2GVQAZ2X.js} +7 -7
  7. package/dist/HoloCompositionParser-3NDF6BMX.cjs +45 -0
  8. package/dist/HoloScriptPlusParser-URSIBEAW.cjs +30 -0
  9. package/dist/HoloScriptPlusParser-YCV6L7GI.js +13 -0
  10. package/dist/{HoloScriptRuntime-YBYXJHJN.cjs → HoloScriptRuntime-CRWI6C3P.cjs} +5 -5
  11. package/dist/{HoloScriptRuntime-UTRLJI5L.js → HoloScriptRuntime-IAZGHPFP.js} +4 -4
  12. package/dist/{SceneIRCompiler-63KA3M2F.js → SceneIRCompiler-BJQMKLWL.js} +7 -7
  13. package/dist/{SceneIRCompiler-KWUFHZ4O.cjs → SceneIRCompiler-RTPPDQAV.cjs} +12 -12
  14. package/dist/{chunk-FWCHPCD4.js → chunk-22AULOAL.js} +5 -5
  15. package/dist/{chunk-G35CAQ7I.cjs → chunk-2DJIS7TH.cjs} +5 -5
  16. package/dist/{chunk-LHUDAJQT.cjs → chunk-2PVEXEOL.cjs} +5 -5
  17. package/dist/{chunk-WWNCM473.js → chunk-2UP2J3OK.js} +4 -4
  18. package/dist/{chunk-HVX7QQYK.js → chunk-3AUYBQ5I.js} +3 -3
  19. package/dist/{chunk-TSTFYGGX.js → chunk-3MQAOMKD.js} +3 -3
  20. package/dist/{chunk-FWKEY4LD.js → chunk-4AGNARX6.js} +3 -3
  21. package/dist/{chunk-WNYXT4TE.cjs → chunk-4CQ7ULXZ.cjs} +3 -3
  22. package/dist/{chunk-U3D4SYQ5.js → chunk-5LCJDX5A.js} +3 -3
  23. package/dist/{chunk-IK6Z2HNC.js → chunk-6OQHLNTT.js} +2 -2
  24. package/dist/{chunk-EI3J6LTW.cjs → chunk-6RDHWSZM.cjs} +217 -217
  25. package/dist/{chunk-77QI552M.js → chunk-7AY66PZP.js} +3 -3
  26. package/dist/{chunk-7IDJDMPU.cjs → chunk-7FYSSI3C.cjs} +27 -2
  27. package/dist/{chunk-BP4KTMLY.js → chunk-7HDRN5BW.js} +4 -4
  28. package/dist/{chunk-SQAAWO4V.cjs → chunk-7YKNV2BE.cjs} +5 -5
  29. package/dist/{chunk-WTH23ISI.js → chunk-AAUQTR7I.js} +4 -4
  30. package/dist/{chunk-OC6GV5QH.cjs → chunk-AN3ZH7M7.cjs} +38 -38
  31. package/dist/{chunk-YW3I2FQL.js → chunk-ANMME7XT.js} +4 -2
  32. package/dist/{chunk-A4OOLBZD.js → chunk-ATRAK4RC.js} +5 -5
  33. package/dist/{chunk-BQJ3YBF3.js → chunk-AUF7HFOO.js} +724 -647
  34. package/dist/{chunk-2X3IPCBK.cjs → chunk-AUMTQV64.cjs} +7 -7
  35. package/dist/chunk-AUU4ACJP.cjs +1605 -0
  36. package/dist/{chunk-QQFB4RT2.cjs → chunk-BTVHY3UB.cjs} +2 -2
  37. package/dist/{chunk-ZK7KX5CD.cjs → chunk-CMEINO5I.cjs} +190 -74
  38. package/dist/{chunk-BCP4E7MD.cjs → chunk-CRUIGXF7.cjs} +26 -10
  39. package/dist/{chunk-2E6PP5UE.cjs → chunk-E2SNPMBO.cjs} +11 -11
  40. package/dist/{chunk-2BYAUHBO.js → chunk-E4YS5SIZ.js} +90 -25
  41. package/dist/{chunk-KFVNCW4Q.js → chunk-EKNWUSGW.js} +3 -3
  42. package/dist/{chunk-JEJ7TT54.js → chunk-ETIJOUIO.js} +4 -4
  43. package/dist/{chunk-FRSKLX6I.js → chunk-F33KLYOS.js} +12 -9
  44. package/dist/{chunk-GGR7QUKK.cjs → chunk-F47FEV4X.cjs} +40 -40
  45. package/dist/{chunk-J3UHV5T4.cjs → chunk-FCGTI7FO.cjs} +4 -4
  46. package/dist/{chunk-RRQIAJLQ.cjs → chunk-FGTXAVKG.cjs} +5 -5
  47. package/dist/{chunk-2KKOYZYI.cjs → chunk-FPGYWNNA.cjs} +5 -5
  48. package/dist/{chunk-65S62L4D.cjs → chunk-FQ4MYZYU.cjs} +20 -20
  49. package/dist/{chunk-UGQ3QNV6.js → chunk-FT4FGTR6.js} +24 -8
  50. package/dist/{chunk-Q4K2GEMW.cjs → chunk-FVNV4WHQ.cjs} +20 -17
  51. package/dist/{chunk-SJIRCTIS.cjs → chunk-HSGJFCVJ.cjs} +2 -2
  52. package/dist/{chunk-B3CWTCK2.js → chunk-IA7FCSRY.js} +27 -2
  53. package/dist/{chunk-OIBRWLPY.cjs → chunk-ILO2KMER.cjs} +55 -4
  54. package/dist/{chunk-ZRPALBQB.cjs → chunk-IPBSNGAN.cjs} +92 -27
  55. package/dist/{chunk-FHVPN7BN.js → chunk-IX2U3RQT.js} +3 -3
  56. package/dist/{chunk-QEDMOGF3.cjs → chunk-IYK6LMQ7.cjs} +7 -7
  57. package/dist/{chunk-G6EKZHXY.js → chunk-J3VVM6GV.js} +4 -4
  58. package/dist/{chunk-LMB555QB.cjs → chunk-J74S4ZMF.cjs} +18 -18
  59. package/dist/{chunk-36NPLOI4.cjs → chunk-JERWCCEJ.cjs} +4 -2
  60. package/dist/{chunk-RVNXBF2M.js → chunk-JTDDLCSP.js} +4 -4
  61. package/dist/{chunk-VTEXJOSD.cjs → chunk-K53L47NH.cjs} +30 -30
  62. package/dist/{chunk-IJU6AS67.cjs → chunk-LJTM5ONX.cjs} +23 -23
  63. package/dist/{chunk-G6KACNMO.js → chunk-LJVVOVA6.js} +4 -4
  64. package/dist/{chunk-PDXX5UI4.cjs → chunk-LNJKBQ2B.cjs} +38 -38
  65. package/dist/{chunk-EM2OGPYE.js → chunk-M2GDE3NV.js} +3 -3
  66. package/dist/{chunk-CP7V3ATL.js → chunk-MSZNGI5P.js} +52 -5
  67. package/dist/{chunk-P7JEKJTZ.cjs → chunk-N2BOTBPG.cjs} +27 -16
  68. package/dist/{chunk-LB3ZZMKT.cjs → chunk-NFALJJCH.cjs} +12 -12
  69. package/dist/{chunk-XF63CZ7E.cjs → chunk-NRZRBK25.cjs} +6 -6
  70. package/dist/{chunk-GZPUA2TL.cjs → chunk-NTSLNIY7.cjs} +10 -10
  71. package/dist/{chunk-Y57AVOM2.cjs → chunk-NZJOAWJM.cjs} +4 -4
  72. package/dist/{chunk-RXQNRZ5F.js → chunk-OG7RKWWX.js} +3 -3
  73. package/dist/{chunk-VVAAZITA.cjs → chunk-OQVHCYY4.cjs} +5 -5
  74. package/dist/{chunk-PJFTTSKE.js → chunk-PFZ5WLIP.js} +4 -4
  75. package/dist/{chunk-PXVAPGTR.cjs → chunk-PHLNABJD.cjs} +3788 -1138
  76. package/dist/{chunk-SQXAZHDG.js → chunk-PLK3DLTF.js} +3 -3
  77. package/dist/{chunk-QBY7LRN2.js → chunk-PMACVMHL.js} +3 -3
  78. package/dist/{chunk-DJ5BNRIS.js → chunk-PV2OXNP5.js} +3684 -1041
  79. package/dist/{chunk-F3YT6GUF.cjs → chunk-Q6VW7MGX.cjs} +14 -14
  80. package/dist/{chunk-DUG3OQAS.js → chunk-QC3CAVFN.js} +187 -70
  81. package/dist/{chunk-NQN5LFN4.cjs → chunk-QKLEDRHN.cjs} +19 -19
  82. package/dist/{chunk-2EGGAZT3.js → chunk-QS27OYBU.js} +3 -3
  83. package/dist/{chunk-4376VHNJ.js → chunk-RUB7WL6C.js} +3 -3
  84. package/dist/{chunk-5LVFTGKH.js → chunk-TW2AH2ZS.js} +3 -3
  85. package/dist/{chunk-AATYYLYK.js → chunk-TZM6DKSJ.js} +18 -7
  86. package/dist/{chunk-ESSEF6U2.js → chunk-U227RWXB.js} +3 -3
  87. package/dist/{chunk-TC7JEO6R.cjs → chunk-U6CQOM5Q.cjs} +711 -52
  88. package/dist/{chunk-Z557DVYN.js → chunk-ULT2QAV5.js} +4 -4
  89. package/dist/{chunk-S4O7CFHQ.cjs → chunk-VSO6HPDZ.cjs} +7 -7
  90. package/dist/{chunk-ONPVM4IV.js → chunk-WQJMSSJT.js} +698 -45
  91. package/dist/{chunk-GILYQ5VH.cjs → chunk-WXSDBWGM.cjs} +4 -4
  92. package/dist/{chunk-UTUD6GJI.js → chunk-X5PMMK7H.js} +3 -3
  93. package/dist/{chunk-IFW5IW4L.cjs → chunk-X5ZLSPU2.cjs} +742 -657
  94. package/dist/{chunk-QM7FJB5W.js → chunk-X727CQ7X.js} +5 -5
  95. package/dist/{chunk-566ZB4LZ.cjs → chunk-XHZYS4QO.cjs} +5 -5
  96. package/dist/{chunk-RZ2EPXO3.cjs → chunk-XRQCTTDC.cjs} +8 -8
  97. package/dist/{chunk-5FYMCVBY.js → chunk-YBIHSN55.js} +4 -4
  98. package/dist/{chunk-FG6PYGIZ.js → chunk-Z574GVI3.js} +4 -4
  99. package/dist/{chunk-ZVQMKUGJ.js → chunk-Z5V3KA7L.js} +2 -2
  100. package/dist/chunk-ZGDEOXGU.js +1571 -0
  101. package/dist/{chunk-IS7NTKY5.cjs → chunk-ZHW6TDZ6.cjs} +14 -14
  102. package/dist/{chunk-CKV5NYAE.js → chunk-ZPHCTPR6.js} +4 -4
  103. package/dist/{chunk-3IUHTGDD.cjs → chunk-ZXXC2GXB.cjs} +38 -38
  104. package/dist/cli/holoscript-runner.cjs +169 -20
  105. package/dist/cli/holoscript-runner.js +163 -14
  106. package/dist/compiler/agent-inference.cjs +8 -8
  107. package/dist/compiler/agent-inference.js +4 -4
  108. package/dist/compiler/android-xr.cjs +7 -7
  109. package/dist/compiler/android-xr.js +5 -5
  110. package/dist/compiler/android.cjs +6 -6
  111. package/dist/compiler/android.js +4 -4
  112. package/dist/compiler/context.cjs +6 -6
  113. package/dist/compiler/context.js +3 -3
  114. package/dist/compiler/daimon-seed.cjs +9 -9
  115. package/dist/compiler/daimon-seed.js +4 -4
  116. package/dist/compiler/domain-block-utils.cjs +165 -165
  117. package/dist/compiler/domain-block-utils.js +4 -4
  118. package/dist/compiler/dtdl.cjs +7 -7
  119. package/dist/compiler/dtdl.js +4 -4
  120. package/dist/compiler/gltf-pipeline.cjs +8 -8
  121. package/dist/compiler/gltf-pipeline.js +1 -1
  122. package/dist/compiler/godot.cjs +6 -6
  123. package/dist/compiler/godot.js +5 -5
  124. package/dist/compiler/incremental.cjs +8 -8
  125. package/dist/compiler/incremental.js +3 -3
  126. package/dist/compiler/index.cjs +2275 -212
  127. package/dist/compiler/index.d.ts +29 -1
  128. package/dist/compiler/index.js +2078 -66
  129. package/dist/compiler/ios.cjs +6 -6
  130. package/dist/compiler/ios.js +4 -4
  131. package/dist/compiler/llm-provider-capabilities.cjs +6 -6
  132. package/dist/compiler/llm-provider-capabilities.js +3 -3
  133. package/dist/compiler/openxr.cjs +6 -6
  134. package/dist/compiler/openxr.js +5 -5
  135. package/dist/compiler/sdf.cjs +7 -7
  136. package/dist/compiler/sdf.js +5 -5
  137. package/dist/compiler/state.cjs +6 -6
  138. package/dist/compiler/state.js +4 -4
  139. package/dist/compiler/trait-composition.cjs +7 -7
  140. package/dist/compiler/trait-composition.js +3 -3
  141. package/dist/compiler/unity.cjs +6 -6
  142. package/dist/compiler/unity.js +5 -5
  143. package/dist/compiler/unreal.cjs +7 -7
  144. package/dist/compiler/unreal.js +5 -5
  145. package/dist/compiler/urdf.cjs +14 -14
  146. package/dist/compiler/urdf.js +5 -5
  147. package/dist/compiler/usd-physics.cjs +7 -7
  148. package/dist/compiler/usd-physics.js +4 -4
  149. package/dist/compiler/visionos.cjs +6 -6
  150. package/dist/compiler/visionos.js +5 -5
  151. package/dist/compiler/vrchat.cjs +7 -7
  152. package/dist/compiler/vrchat.js +5 -5
  153. package/dist/compiler/wasm.cjs +10 -10
  154. package/dist/compiler/wasm.js +5 -5
  155. package/dist/compiler/webgpu.cjs +6 -6
  156. package/dist/compiler/webgpu.js +5 -5
  157. package/dist/constants.cjs +99 -99
  158. package/dist/constants.js +3 -3
  159. package/dist/debugger.cjs +5 -5
  160. package/dist/debugger.js +3 -3
  161. package/dist/{dist-GRMOP2UL.cjs → dist-YGATNURH.cjs} +705 -9
  162. package/dist/{dist-ZBUKU2JG.js → dist-ZEZXRCBG.js} +701 -10
  163. package/dist/entries/scripting.cjs +8 -8
  164. package/dist/entries/scripting.js +4 -4
  165. package/dist/evolution/index.cjs +20 -20
  166. package/dist/evolution/index.js +8 -8
  167. package/dist/index.cjs +1099 -826
  168. package/dist/index.d.ts +78 -5
  169. package/dist/index.js +265 -120
  170. package/dist/parser/HoloCompositionTypes.d.ts +1 -1
  171. package/dist/parser.cjs +21 -21
  172. package/dist/parser.js +7 -7
  173. package/dist/reconstruction/index.cjs +127 -38
  174. package/dist/reconstruction/index.d.ts +159 -0
  175. package/dist/reconstruction/index.js +11 -2
  176. package/dist/runtime.cjs +9 -9
  177. package/dist/runtime.d.ts +1 -0
  178. package/dist/runtime.js +3 -3
  179. package/dist/traitDocs/traitDocs.cjs +8 -8
  180. package/dist/traitDocs/traitDocs.js +2 -2
  181. package/dist/traits/botanical-lotus.d.ts +61 -0
  182. package/dist/traits/index.cjs +761 -673
  183. package/dist/traits/index.d.ts +65 -0
  184. package/dist/traits/index.js +102 -27
  185. package/dist/types/HoloScriptPlus.d.ts +1 -1
  186. package/package.json +71 -65
  187. package/dist/HoloCompositionParser-6GW2BZID.cjs +0 -45
  188. package/dist/HoloScriptPlusParser-HQV6IJAH.js +0 -13
  189. package/dist/HoloScriptPlusParser-RFNHRMPE.cjs +0 -30
  190. package/dist/chunk-DVHZD5HV.cjs +0 -639
  191. package/dist/chunk-G72754QB.js +0 -625
@@ -1,98 +1,173 @@
1
- export { ContextCompileError, ContextCompiler, createContextCompiler } from '../chunk-UTUD6GJI.js';
2
- export { LLMCapabilityCompileError, LLMProviderCapabilitiesCompiler, createLLMProviderCapabilitiesCompiler } from '../chunk-RXQNRZ5F.js';
3
- export { GLTF_PIPELINE_TOOLS, registerGLTFTools } from '../chunk-EM2OGPYE.js';
1
+ export { ContextCompileError, ContextCompiler, createContextCompiler } from '../chunk-X5PMMK7H.js';
2
+ export { LLMCapabilityCompileError, LLMProviderCapabilitiesCompiler, createLLMProviderCapabilitiesCompiler } from '../chunk-OG7RKWWX.js';
3
+ export { GLTF_PIPELINE_TOOLS, registerGLTFTools } from '../chunk-M2GDE3NV.js';
4
4
  export { BUSINESS_QUEST_TOOLS, buildVRRCompositionFromDraft, businessVRRDraftSchema, draftToHoloPreview, handleBusinessQuestToolCall, registerBusinessQuestTools, validateBusinessVRRDraft } from '../chunk-NWMJPTVL.js';
5
5
  export { NodeToyMapper, mapNodeToyToShader } from '../chunk-TG7O4WBC.js';
6
6
  export { createReproducibilityContext, parseReproducibilityFlags } from '../chunk-5GLCTO44.js';
7
- export { QuantumCircuitCompiler } from '../chunk-2BYAUHBO.js';
8
- import { init_NextJSAPICompiler, init_DialectRegistry, DialectRegistry, init_HoloMCPCompiler, init_OmnigentAgentYamlCompiler, init_NodeServiceCompiler, init_SDKCompiler, init_LlamaServerCompiler, init_holoscript_gbnf, init_registerBuiltinDialects, init_PCGGraphCompiler } from '../chunk-DJ5BNRIS.js';
9
- export { CodeEditorCompiler, CompileTimeAuthorityEffectError, CompilerBridge, DEFAULT_MATERIAL_KEYWORDS, DEFAULT_OBJECT_KEYWORDS, DEFAULT_PRIMITIVE_SHAPES, DialectRegistry, EdgeCompiler, FMUCompiler, GaussianSplattingCompiler, GaussianTrainCompiler, GaussianTrainConfigError, HOLOSCRIPT_GRAMMAR_PRESETS, HoloMCPCompiler, LlamaServerCompiler, NextJSAPICompiler, NodeServiceCompiler, OmnigentAgentYamlCompiler, PCGGraphCompiler, PCG_GRAPH_SCHEMA, REMOTE_TRAIN_EXECUTOR, REQUIRED_SANDBOX_AUTHORITY_EFFECT, SANDBOX_AUTHORITY_TRAIT, SCMCompiler, SDKCompiler, SHARED_SORT_SHADER_PATH, SOVEREIGN_TRAIN_EXECUTOR, SVGCompiler, SpatialPartitionPass, ThreeDTilesCompiler, USDZPipeline, absorbFMU, assertAuthorityEffects, bestCategoryForTraits, checkAuthorityEffects, collectAuthorityEffectNodes, compileAllToNextJSAPI, compilePCGGraphFromBlocks, compilePipelineSource, compilePipelineSourceToNode, compilePipelineSourceToPython, compilePipelineToNode, compilePipelineToPython, compileTo3DTiles, compileToFMU, compileToNextJSAPI, compileToPCGGraph, createGaussianSplattingCompiler, createGaussianTrainCompiler, createOmnigentAgentYamlCompiler, createThreeDTilesCompiler, detectMultiUserSharedSort, ensureDialectsBooted, generateHoloScriptGbnf, isHoloScriptGrammarPreset, pcgGraphToUnrealXml, quickSafetyCheck, registerBuiltinDialects, runSafetyPass, selectModality, selectModalityForAll, spatialPartition, streamWorldTiles } from '../chunk-DJ5BNRIS.js';
7
+ export { QuantumCircuitCompiler } from '../chunk-E4YS5SIZ.js';
8
+ import { init_NextJSAPICompiler, init_DialectRegistry, DialectRegistry, init_HoloMCPCompiler, init_OmnigentAgentYamlCompiler, init_NodeServiceCompiler, init_SDKCompiler, init_LlamaServerCompiler, init_holoscript_gbnf, init_registerBuiltinDialects, init_PCGGraphCompiler } from '../chunk-PV2OXNP5.js';
9
+ export { CodeEditorCompiler, CompileTimeAuthorityEffectError, CompilerBridge, ComputePhysicsCompiler, CpuPathTracer, DEFAULT_MATERIAL_KEYWORDS, DEFAULT_OBJECT_KEYWORDS, DEFAULT_PRIMITIVE_SHAPES, DesktopGPUCompiler, DialectRegistry, EdgeCompiler, FMUCompiler, GaussianSplattingCompiler, GaussianTrainCompiler, GaussianTrainConfigError, HOLOSCRIPT_GRAMMAR_PRESETS, HoloMCPCompiler, LlamaServerCompiler, MediaPipelineCompiler, NextJSAPICompiler, NodeServiceCompiler, OmnigentAgentYamlCompiler, PCGGraphCompiler, PCG_GRAPH_SCHEMA, PathTracerCompiler, PhysicsColliderCompiler, REMOTE_TRAIN_EXECUTOR, REQUIRED_SANDBOX_AUTHORITY_EFFECT, SANDBOX_AUTHORITY_TRAIT, SCMCompiler, SDKCompiler, SHARED_SORT_SHADER_PATH, SOVEREIGN_TRAIN_EXECUTOR, SVGCompiler, SpatialAudioCompiler, SpatialPartitionPass, ThreeDTilesCompiler, USDZPipeline, absorbFMU, assertAuthorityEffects, bestCategoryForTraits, checkAuthorityEffects, collectAuthorityEffectNodes, compileAllToNextJSAPI, compilePCGGraphFromBlocks, compilePipelineSource, compilePipelineSourceToNode, compilePipelineSourceToPython, compilePipelineToNode, compilePipelineToPython, compileTo3DTiles, compileToFMU, compileToNextJSAPI, compileToPCGGraph, createGaussianSplattingCompiler, createGaussianTrainCompiler, createOmnigentAgentYamlCompiler, createThreeDTilesCompiler, detectMultiUserSharedSort, ensureDialectsBooted, generateHoloScriptGbnf, isHoloScriptGrammarPreset, pcgGraphToUnrealXml, quickSafetyCheck, registerBuiltinDialects, runSafetyPass, selectModality, selectModalityForAll, spatialPartition, streamWorldTiles } from '../chunk-PV2OXNP5.js';
10
10
  export { generateHullGeometry, generateMembraneGeometry, generateSplineGeometry } from '../chunk-UDE4OZMR.js';
11
11
  import '../chunk-3F7ZZWIN.js';
12
- export { SceneIRCompiler } from '../chunk-QM7FJB5W.js';
12
+ export { SceneIRCompiler } from '../chunk-X727CQ7X.js';
13
13
  import '../chunk-2MQKNDNH.js';
14
- import { init_DaimonSeedCompiler } from '../chunk-QBY7LRN2.js';
15
- export { DaimonSeedCompiler, computeExportFidelity, createDaimonSeedCompiler, runHysteresisExp2 } from '../chunk-QBY7LRN2.js';
14
+ import { init_DaimonSeedCompiler } from '../chunk-PMACVMHL.js';
15
+ export { DaimonSeedCompiler, computeExportFidelity, createDaimonSeedCompiler, runHysteresisExp2 } from '../chunk-PMACVMHL.js';
16
16
  import { assertHoloMapManifestContract } from '../chunk-IXWGYWH6.js';
17
17
  export { COCOExporterImpl as COCOExporter } from '../chunk-Q56TT7IL.js';
18
18
  export { RemotionBridgeImpl as RemotionBridge } from '../chunk-YYXH45E2.js';
19
19
  export { SemanticSceneGraph } from '../chunk-HHRZ6STP.js';
20
- import { init_AgentInferenceExportTarget } from '../chunk-UGQ3QNV6.js';
21
- export { AgentInferenceCompiler, AgentInferenceExportTarget_default as AgentInferenceExportTarget, createAgentInferenceCompiler, createPythonAgentInferenceCompiler } from '../chunk-UGQ3QNV6.js';
22
- import { vrTraitRegistry } from '../chunk-BQJ3YBF3.js';
20
+ import { init_AgentInferenceExportTarget } from '../chunk-FT4FGTR6.js';
21
+ export { AgentInferenceCompiler, AgentInferenceExportTarget_default as AgentInferenceExportTarget, createAgentInferenceCompiler, createPythonAgentInferenceCompiler } from '../chunk-FT4FGTR6.js';
22
+ import { vrTraitRegistry, evaluateExpressionIR, parseExpressionToIR, ExpressionParseError } from '../chunk-AUF7HFOO.js';
23
23
  import '../chunk-6TRX6AR2.js';
24
- import '../chunk-ZVQMKUGJ.js';
24
+ import '../chunk-Z5V3KA7L.js';
25
25
  import { isWebGpuEnvironmentPresent } from '../chunk-K56UVEXV.js';
26
26
  import '../chunk-OG3MBHM3.js';
27
27
  import '../chunk-2M2DPHKB.js';
28
28
  import '../chunk-TDCNJHWO.js';
29
29
  import '../chunk-VKCTYLDN.js';
30
30
  import '../chunk-YQELFNJV.js';
31
- export { USDPhysicsCompiler } from '../chunk-FG6PYGIZ.js';
32
- import { init_SDFCompiler } from '../chunk-5FYMCVBY.js';
33
- export { SDFCompiler } from '../chunk-5FYMCVBY.js';
34
- import { init_StateCompiler } from '../chunk-KFVNCW4Q.js';
35
- export { StateCompiler } from '../chunk-KFVNCW4Q.js';
36
- export { TraitCompositionCompiler } from '../chunk-TSTFYGGX.js';
31
+ export { USDPhysicsCompiler } from '../chunk-Z574GVI3.js';
32
+ import { init_SDFCompiler } from '../chunk-YBIHSN55.js';
33
+ export { SDFCompiler } from '../chunk-YBIHSN55.js';
34
+ import { init_StateCompiler } from '../chunk-EKNWUSGW.js';
35
+ export { StateCompiler } from '../chunk-EKNWUSGW.js';
36
+ export { TraitCompositionCompiler } from '../chunk-3MQAOMKD.js';
37
37
  import '../chunk-DQRJ5RJG.js';
38
- export { IncrementalCompiler, createIncrementalCompiler } from '../chunk-RVNXBF2M.js';
38
+ export { IncrementalCompiler, createIncrementalCompiler } from '../chunk-JTDDLCSP.js';
39
39
  import '../chunk-4R6SBXDB.js';
40
- import { init_AndroidCompiler } from '../chunk-HVX7QQYK.js';
41
- export { AndroidCompiler } from '../chunk-HVX7QQYK.js';
42
- import { init_AndroidXRCompiler, init_AndroidXRTraitMap, AndroidXRCompiler, getTraitMapping, ANDROIDXR_TRAIT_MAP } from '../chunk-G6KACNMO.js';
43
- export { AndroidXRCompiler } from '../chunk-G6KACNMO.js';
40
+ import { init_AndroidCompiler } from '../chunk-3AUYBQ5I.js';
41
+ export { AndroidCompiler } from '../chunk-3AUYBQ5I.js';
42
+ import { init_AndroidXRCompiler, init_AndroidXRTraitMap, AndroidXRCompiler, getTraitMapping, ANDROIDXR_TRAIT_MAP } from '../chunk-LJVVOVA6.js';
43
+ export { AndroidXRCompiler } from '../chunk-LJVVOVA6.js';
44
44
  import '../chunk-CBSDJF3B.js';
45
- import { init_IOSCompiler } from '../chunk-77QI552M.js';
46
- export { IOSCompiler } from '../chunk-77QI552M.js';
47
- import { init_VisionOSCompiler, init_VisionOSTraitMap, getTraitMapping as getTraitMapping$1, listAllTraits, generateTraitCode } from '../chunk-Z557DVYN.js';
48
- export { VisionOSCompiler } from '../chunk-Z557DVYN.js';
49
- import { init_WASMCompiler } from '../chunk-PJFTTSKE.js';
50
- export { WASMCompiler } from '../chunk-PJFTTSKE.js';
51
- import { init_WebGPUCompiler, WebGPUCompiler } from '../chunk-ONPVM4IV.js';
52
- export { WebGPUCompiler } from '../chunk-ONPVM4IV.js';
53
- import { init_DTDLCompiler } from '../chunk-SQXAZHDG.js';
54
- export { DTDLCompiler } from '../chunk-SQXAZHDG.js';
55
- import { init_URDFCompiler } from '../chunk-AATYYLYK.js';
56
- export { URDFCompiler, createURDFCompiler } from '../chunk-AATYYLYK.js';
45
+ import { init_IOSCompiler } from '../chunk-7AY66PZP.js';
46
+ export { IOSCompiler } from '../chunk-7AY66PZP.js';
47
+ import { init_VisionOSCompiler, init_VisionOSTraitMap, getTraitMapping as getTraitMapping$1, listAllTraits, generateTraitCode } from '../chunk-ULT2QAV5.js';
48
+ export { VisionOSCompiler } from '../chunk-ULT2QAV5.js';
49
+ import { init_WASMCompiler } from '../chunk-PFZ5WLIP.js';
50
+ export { WASMCompiler } from '../chunk-PFZ5WLIP.js';
51
+ import { init_WebGPUCompiler, WebGPUCompiler } from '../chunk-WQJMSSJT.js';
52
+ export { WebGPUCompiler } from '../chunk-WQJMSSJT.js';
53
+ import { init_DTDLCompiler } from '../chunk-PLK3DLTF.js';
54
+ export { DTDLCompiler } from '../chunk-PLK3DLTF.js';
55
+ import { init_URDFCompiler } from '../chunk-TZM6DKSJ.js';
56
+ export { URDFCompiler, createURDFCompiler } from '../chunk-TZM6DKSJ.js';
57
57
  import '../chunk-JBQXZIWB.js';
58
- import { init_OpenXRCompiler } from '../chunk-WTH23ISI.js';
59
- export { OpenXRCompiler } from '../chunk-WTH23ISI.js';
60
- import { init_VRChatCompiler } from '../chunk-BP4KTMLY.js';
61
- export { VRChatCompiler } from '../chunk-BP4KTMLY.js';
62
- import { init_UnityCompiler } from '../chunk-CKV5NYAE.js';
63
- export { UnityCompiler } from '../chunk-CKV5NYAE.js';
64
- import '../chunk-WWNCM473.js';
58
+ import { init_OpenXRCompiler } from '../chunk-AAUQTR7I.js';
59
+ export { OpenXRCompiler } from '../chunk-AAUQTR7I.js';
60
+ import { init_VRChatCompiler } from '../chunk-7HDRN5BW.js';
61
+ export { VRChatCompiler } from '../chunk-7HDRN5BW.js';
62
+ import { init_UnityCompiler } from '../chunk-ZPHCTPR6.js';
63
+ export { UnityCompiler } from '../chunk-ZPHCTPR6.js';
64
+ import '../chunk-2UP2J3OK.js';
65
65
  import { init_PlatformConditionalCompilerMixin } from '../chunk-DJNH4HFW.js';
66
66
  export { PlatformConditionalCompilerMixin, createPlatformTarget, filterCompositionForPlatform, matchesPlatformConstraint, normalizePlatformName } from '../chunk-DJNH4HFW.js';
67
- import { init_GodotCompiler } from '../chunk-JEJ7TT54.js';
68
- export { GodotCompiler } from '../chunk-JEJ7TT54.js';
69
- import '../chunk-5LVFTGKH.js';
67
+ import { init_GodotCompiler } from '../chunk-ETIJOUIO.js';
68
+ export { GodotCompiler } from '../chunk-ETIJOUIO.js';
69
+ import '../chunk-TW2AH2ZS.js';
70
70
  import { init_PerceptualColorPass } from '../chunk-UCVZXQ63.js';
71
71
  export { SCIENTIFIC_COLOR_MAPS, analyzePerceptualColor, applyPerceptualColorPass, buildPerceptualGradient, buildPerceptualPalette, hexToSrgb, normalizeHexColor, srgbToHex } from '../chunk-UCVZXQ63.js';
72
- import { init_CompilerBase, init_CompilerDocumentationGenerator, CompilerBase } from '../chunk-DUG3OQAS.js';
73
- export { CompilerBase, CompilerDocumentationGenerator, UnauthorizedCompilerAccessError, createTestCompilerToken, isCapabilityTokenCredential } from '../chunk-DUG3OQAS.js';
74
- import { init_traitDocs, getTraitDoc, getAllTraitNames } from '../chunk-B3CWTCK2.js';
72
+ import { init_CompilerBase, init_CompilerDocumentationGenerator, CompilerBase } from '../chunk-QC3CAVFN.js';
73
+ export { CompilerBase, CompilerDocumentationGenerator, UnauthorizedCompilerAccessError, createTestCompilerToken, isCapabilityTokenCredential } from '../chunk-QC3CAVFN.js';
74
+ import { init_traitDocs, getTraitDoc, getAllTraitNames } from '../chunk-IA7FCSRY.js';
75
75
  import '../chunk-5CURIYGT.js';
76
76
  import '../chunk-33YHE7HX.js';
77
77
  import '../chunk-GLEJ2TLS.js';
78
78
  import '../chunk-SYTRBGDS.js';
79
79
  import '../chunk-UNMVGZVW.js';
80
- import '../chunk-2EGGAZT3.js';
81
- import '../chunk-YW3I2FQL.js';
80
+ import '../chunk-QS27OYBU.js';
81
+ import '../chunk-ANMME7XT.js';
82
82
  import '../chunk-7I74JWPW.js';
83
83
  import '../chunk-2I3XAGMF.js';
84
84
  import '../chunk-MD4IVS42.js';
85
85
  import { ExpressionEvaluator } from '../chunk-XL6INWKT.js';
86
- import '../chunk-IK6Z2HNC.js';
86
+ import '../chunk-6OQHLNTT.js';
87
87
  import '../chunk-PHENW4MQ.js';
88
88
  import '../chunk-ZVFHPMC5.js';
89
89
  import { init_safeJsonParse, readJson } from '../chunk-RAN3ECAS.js';
90
90
  import '../chunk-W4GABFCR.js';
91
91
  import { ANSCapabilityPath } from '@holoscript/core-types/ans';
92
+ import { createHash } from 'crypto';
92
93
 
93
94
  // src/compiler/index.ts
94
95
  init_CompilerBase();
95
96
  init_CompilerDocumentationGenerator();
97
+
98
+ // src/compiler/SceneIRTsxEmitter.ts
99
+ var GENERATED_HEADER = "// @generated by HoloScript SceneIRTsxEmitter -- DO NOT EDIT";
100
+ function emitSceneIRTsx(root, options = {}) {
101
+ const componentName = sanitizeComponentName(options.componentName ?? root.id ?? "HoloScene");
102
+ const sceneConstName = `${componentName}SceneIR`;
103
+ const imports = [
104
+ options.includeCanvas ?? true ? "import { Canvas } from '@react-three/fiber';" : "",
105
+ "import { HoloSceneIRRenderer } from '@holoscript/r3f-renderer';"
106
+ ].filter(Boolean);
107
+ const source = options.sourcePath ? `// source: ${options.sourcePath}
108
+ ` : "";
109
+ if (options.includeCanvas === false) {
110
+ return [
111
+ GENERATED_HEADER,
112
+ source.trimEnd(),
113
+ ...imports,
114
+ "",
115
+ `const ${sceneConstName} = ${json(root)};`,
116
+ "",
117
+ `export function ${componentName}() {`,
118
+ ` return <HoloSceneIRRenderer node={${sceneConstName}} />;`,
119
+ "}",
120
+ "",
121
+ `export default ${componentName};`,
122
+ ""
123
+ ].filter((line, idx) => line !== "" || idx !== 1).join("\n");
124
+ }
125
+ return [
126
+ GENERATED_HEADER,
127
+ source.trimEnd(),
128
+ ...imports,
129
+ "",
130
+ `const ${sceneConstName} = ${json(root)};`,
131
+ "",
132
+ `export function ${componentName}() {`,
133
+ " return (",
134
+ " <Canvas>",
135
+ ` <HoloSceneIRRenderer node={${sceneConstName}} />`,
136
+ " </Canvas>",
137
+ " );",
138
+ "}",
139
+ "",
140
+ `export default ${componentName};`,
141
+ ""
142
+ ].filter((line, idx) => line !== "" || idx !== 1).join("\n");
143
+ }
144
+ function sanitizeComponentName(name) {
145
+ const words = name.replace(/[^A-Za-z0-9_$]+/g, " ").trim().split(/\s+/).filter(Boolean);
146
+ const joined = words.map((word) => word[0].toUpperCase() + word.slice(1)).join("");
147
+ const candidate = joined || "HoloScene";
148
+ return /^[A-Za-z_$]/.test(candidate) ? candidate : `HoloScene${candidate}`;
149
+ }
150
+ function json(value) {
151
+ return JSON.stringify(normalizeValue(value), null, 2).replace(/</g, "\\u003c");
152
+ }
153
+ function normalizeValue(value) {
154
+ if (ArrayBuffer.isView(value) && !(value instanceof DataView)) {
155
+ return Array.from(value);
156
+ }
157
+ if (Array.isArray(value)) {
158
+ return value.map((entry) => normalizeValue(entry));
159
+ }
160
+ if (value && typeof value === "object") {
161
+ const out = {};
162
+ for (const [key, entry] of Object.entries(value)) {
163
+ out[key] = normalizeValue(entry);
164
+ }
165
+ return out;
166
+ }
167
+ return value;
168
+ }
169
+
170
+ // src/compiler/index.ts
96
171
  init_PerceptualColorPass();
97
172
  init_UnityCompiler();
98
173
  init_GodotCompiler();
@@ -133,7 +208,7 @@ init_CompilerBase();
133
208
  // src/compiler/Native2DCompiler.ts
134
209
  init_CompilerBase();
135
210
  init_safeJsonParse();
136
- var Native2DCompiler = class extends CompilerBase {
211
+ var _Native2DCompiler = class _Native2DCompiler extends CompilerBase {
137
212
  constructor() {
138
213
  super(...arguments);
139
214
  this.compilerName = "Native2DCompiler";
@@ -146,7 +221,22 @@ var Native2DCompiler = class extends CompilerBase {
146
221
  this._stateFields = /* @__PURE__ */ new Map();
147
222
  this._fetchCalls = [];
148
223
  this._hookCalls = [];
224
+ this._computedBindings = [];
149
225
  this._options = {};
226
+ /** Honest mode (composition-level `@honest`): every data-bound element MUST carry
227
+ * `@provenance_bound` or the compiler refuses to emit it (HONEST-UNSOURCED). This is
228
+ * the Receipt-Bound Surface constitution — the surface cannot emit an unsourced pixel. */
229
+ this._honestMode = false;
230
+ this._verifiedViewMode = false;
231
+ /** Valid projection roots: composition state keys + @fetch into-slots (pre-scanned). */
232
+ this._projectionRoots = /* @__PURE__ */ new Set();
233
+ /**
234
+ * Verified projections collected during traversal (@verified_view v1): the machine-readable
235
+ * view contract that co-emits with the surface — a portable, hash-bound receipt of what
236
+ * every element renders, so an independent consumer can re-derive it from the ARTIFACT
237
+ * (not the source). Populated by resolveProjection; emitted as `export const holoViewContract`.
238
+ */
239
+ this._collectedProjections = [];
150
240
  }
151
241
  // @ts-expect-error During migration
152
242
  compile(composition, agentToken, outputPath, options) {
@@ -166,13 +256,46 @@ var Native2DCompiler = class extends CompilerBase {
166
256
  this._stateFields.clear();
167
257
  this._fetchCalls = [];
168
258
  this._hookCalls = [];
259
+ this._computedBindings = [];
169
260
  this._options = options || {};
261
+ this._honestMode = (composition?.traits ?? []).some((t) => t?.name === "honest");
262
+ this._verifiedViewMode = (composition?.traits ?? []).some((t) => t?.name === "verified_view");
170
263
  const safeName = name.replace(/[^a-zA-Z0-9]/g, "");
171
264
  if (composition?.state?.properties) {
172
265
  for (const prop of composition.state.properties) {
173
266
  this._stateFields.set(prop.key, prop.value ?? null);
174
267
  }
175
268
  }
269
+ this._projectionRoots = new Set(this._stateFields.keys());
270
+ this._collectedProjections = [];
271
+ const scanProjectionRoots = (objs) => {
272
+ for (const o of objs) {
273
+ for (const t of o.traits ?? []) {
274
+ if (t?.name === "fetch") {
275
+ const into = t.config?.into;
276
+ this._projectionRoots.add(typeof into === "string" && into ? into : "data");
277
+ }
278
+ if (t?.name === "each") {
279
+ const as = t.config?.as;
280
+ this._projectionRoots.add(typeof as === "string" && as ? as : "item");
281
+ }
282
+ if (t?.name === "computed") {
283
+ const nm = t.config?.name;
284
+ if (typeof nm === "string" && nm) this._projectionRoots.add(nm);
285
+ }
286
+ if (t?.name === "hook") {
287
+ const returns = t.config?.returns;
288
+ if (typeof returns === "string") {
289
+ for (const r of returns.split(",").map((s) => s.trim())) {
290
+ if (r) this._projectionRoots.add(r);
291
+ }
292
+ }
293
+ }
294
+ }
295
+ if (Array.isArray(o.children)) scanProjectionRoots(o.children);
296
+ }
297
+ };
298
+ scanProjectionRoots(objects);
176
299
  const jsx = objects.map((obj) => this.generateReactNode(obj)).join("\n ");
177
300
  const imports = [];
178
301
  const reactImports = /* @__PURE__ */ new Set();
@@ -190,6 +313,17 @@ var Native2DCompiler = class extends CompilerBase {
190
313
  for (const h of this._hookCalls) {
191
314
  imports.push(`import { ${h.name} } from '${h.import}';`);
192
315
  }
316
+ const computedImports = /* @__PURE__ */ new Map();
317
+ for (const b of this._computedBindings) {
318
+ if (b.from && b.uses.length) {
319
+ const set = computedImports.get(b.from) || /* @__PURE__ */ new Set();
320
+ b.uses.forEach((u) => set.add(u));
321
+ computedImports.set(b.from, set);
322
+ }
323
+ }
324
+ for (const [from, uses] of computedImports) {
325
+ imports.push(`import { ${[...uses].join(", ")} } from '${from}';`);
326
+ }
193
327
  const stateHooks = [];
194
328
  for (const [key, value] of this._stateFields) {
195
329
  const capitalKey = key.charAt(0).toUpperCase() + key.slice(1);
@@ -212,25 +346,36 @@ var Native2DCompiler = class extends CompilerBase {
212
346
  const hookBindings = [];
213
347
  for (const h of this._hookCalls) {
214
348
  const members = h.returns.split(",").map((s) => s.trim()).filter((s) => /^[A-Za-z_$][\w$]*$/.test(s));
349
+ const call = `${h.name}(${h.args ?? ""})`;
215
350
  hookBindings.push(
216
- members.length > 0 ? ` const { ${members.join(", ")} } = ${h.name}();` : ` ${h.name}();`
351
+ members.length > 0 ? ` const { ${members.join(", ")} } = ${call};` : ` ${call};`
217
352
  );
218
353
  }
354
+ const computedLines = [];
355
+ for (const b of this._computedBindings) {
356
+ computedLines.push(` const ${b.name} = ${b.expr};`);
357
+ }
358
+ const viewContract = this.buildViewContract();
359
+ const rootAttrs = viewContract ? ` data-holo-view-contract="${viewContract.hash}"` : "";
360
+ const contractExport = viewContract ? `
361
+
362
+ export const holoViewContract = ${viewContract.json} as const;` : "";
219
363
  return `${imports.join("\n")}
220
364
 
221
365
  // @generated by HoloScript Native2DCompiler \u2014 DO NOT EDIT
222
366
  export function ${safeName}Component() {${hookBindings.length > 0 ? "\n" + hookBindings.join("\n") : ""}
223
367
  ${stateHooks.join("\n")}
224
368
  ${fetchEffects.join("\n")}
369
+ ${computedLines.join("\n")}
225
370
 
226
371
  return (
227
- <div className="holoscript-2d-root w-full h-full">
372
+ <div className="holoscript-2d-root w-full h-full"${rootAttrs}>
228
373
  ${jsx}
229
374
  </div>
230
375
  );
231
376
  }
232
377
 
233
- export default ${safeName}Component;
378
+ export default ${safeName}Component;${contractExport}
234
379
  `;
235
380
  }
236
381
  generateReactNode(obj) {
@@ -272,8 +417,39 @@ export default ${safeName}Component;
272
417
  if (/['"`\\]/.test(importPath)) {
273
418
  throw new Error(`Native2DCompiler @hook: invalid import path ${JSON.stringify(importPath)}`);
274
419
  }
420
+ let hookArgs = "";
421
+ if (traits.hook.args != null) {
422
+ hookArgs = String(traits.hook.args);
423
+ if (!/^[a-zA-Z0-9_$.,(){}\[\]'"/\s*+\-%<>=?:!&|]+$/.test(hookArgs)) {
424
+ throw new Error(`Native2DCompiler @hook: unsafe args ${JSON.stringify(hookArgs)}`);
425
+ }
426
+ }
275
427
  if (!this._hookCalls.some((h) => h.name === hookName)) {
276
- this._hookCalls.push({ name: hookName, import: importPath, returns: String(traits.hook.returns || "") });
428
+ this._hookCalls.push({
429
+ name: hookName,
430
+ import: importPath,
431
+ returns: String(traits.hook.returns || ""),
432
+ args: hookArgs || void 0
433
+ });
434
+ }
435
+ }
436
+ if (traits.computed?.name && traits.computed?.expr) {
437
+ const cname = String(traits.computed.name);
438
+ const expr = String(traits.computed.expr);
439
+ if (!/^[A-Za-z_$][\w$]*$/.test(cname)) {
440
+ throw new Error(`Native2DCompiler @computed: invalid name ${JSON.stringify(cname)}`);
441
+ }
442
+ if (!/^[a-zA-Z0-9_$.,()\[\]'"/\s*+\-%<>=?:!&|]+$/.test(expr)) {
443
+ throw new Error(`Native2DCompiler @computed: unsafe expr ${JSON.stringify(expr)}`);
444
+ }
445
+ const from = traits.computed.from ? String(traits.computed.from) : "";
446
+ if (from && /['"`\\]/.test(from)) {
447
+ throw new Error(`Native2DCompiler @computed: invalid import path ${JSON.stringify(from)}`);
448
+ }
449
+ const usesRaw = traits.computed.uses;
450
+ const uses = (Array.isArray(usesRaw) ? usesRaw : usesRaw ? [usesRaw] : []).map(String).filter((u) => /^[A-Za-z_$][\w$]*$/.test(u));
451
+ if (!this._computedBindings.some((b) => b.name === cname)) {
452
+ this._computedBindings.push({ name: cname, expr, from: from || void 0, uses });
277
453
  }
278
454
  }
279
455
  let tag = traits.theme?.tag || traits.panel?.tag || (typeof obj.type === "string" ? obj.type.toLowerCase() : void 0) || "div";
@@ -307,6 +483,10 @@ export default ${safeName}Component;
307
483
  const styles = this.buildStyles(traits);
308
484
  const classes = this.buildClasses(traits);
309
485
  let props = ``;
486
+ const prov = this.resolveProvenance(traits, obj);
487
+ if (prov) props += prov.propsStr;
488
+ const proj = this.resolveProjection(traits, obj);
489
+ if (proj) props += proj;
310
490
  if (traits.theme?.className) {
311
491
  classes.push(traits.theme.className);
312
492
  }
@@ -329,10 +509,15 @@ export default ${safeName}Component;
329
509
  props += ` style={${JSON.stringify(combinedStyles)}}`;
330
510
  }
331
511
  if (tierExpr) {
332
- const staticPrefix = classes.length > 0 ? `${classes.join(" ")} ` : "";
512
+ const tierFamilies = this.tierColorFamilies(traits);
513
+ const cleaned = this.stripColorFamilies(
514
+ this.resolveColorConflicts(classes.join(" ")),
515
+ tierFamilies
516
+ );
517
+ const staticPrefix = cleaned ? `${cleaned} ` : "";
333
518
  props += ` className={\`${staticPrefix}\${${tierExpr}}\`}`;
334
519
  } else if (classes.length > 0) {
335
- props += ` className="${classes.join(" ")}"`;
520
+ props += ` className="${this.resolveColorConflicts(classes.join(" "))}"`;
336
521
  }
337
522
  if (traits.theme?.attributes) {
338
523
  try {
@@ -383,7 +568,10 @@ export default ${safeName}Component;
383
568
  if (stateVar) {
384
569
  const setter = `set${stateVar.charAt(0).toUpperCase()}${stateVar.slice(1)}`;
385
570
  const valueExpr = subPath ? `${stateVar}.${subPath}` : stateVar;
386
- props += ` value={${valueExpr}} onChange={(e) => ${setter}(e.target.value)}`;
571
+ const inputType = String(traits.input?.type || "").toLowerCase();
572
+ const numeric = traits.model.cast === "number" || inputType === "range" || inputType === "number";
573
+ const getter = numeric ? "Number(e.target.value)" : "e.target.value";
574
+ props += ` value={${valueExpr}} onChange={(e) => ${setter}(${getter})}`;
387
575
  }
388
576
  }
389
577
  if (traits.image?.src) props += ` src="${traits.image.src}"`;
@@ -392,6 +580,9 @@ export default ${safeName}Component;
392
580
  if (traits.input?.placeholder) props += ` placeholder="${traits.input.placeholder}"`;
393
581
  if (traits.input?.type) props += ` type="${traits.input.type}"`;
394
582
  if (traits.input?.required) props += ` required`;
583
+ if (traits.input?.min != null) props += ` min="${String(traits.input.min)}"`;
584
+ if (traits.input?.max != null) props += ` max="${String(traits.input.max)}"`;
585
+ if (traits.input?.step != null) props += ` step="${String(traits.input.step)}"`;
395
586
  if (traits.button?.type) props += ` type="${traits.button.type}"`;
396
587
  const childrenMarkup = (obj.children || obj.objects || []).map((child) => this.generateReactNode(child)).join("\n");
397
588
  const content = traits.text?.content || traits.button?.content || traits.link?.content || traits.icon?.name;
@@ -401,12 +592,23 @@ export default ${safeName}Component;
401
592
  } else if (content) {
402
593
  safeContent = `{\`${content.replace(/`/g, "\\`").replace(/\$/g, "\\$")}\`}`;
403
594
  }
595
+ if (prov && safeContent && _Native2DCompiler.PROVENANCE_GLYPH[prov.cls]) {
596
+ safeContent += `<sup className="holo-prov-mark" title=${JSON.stringify(
597
+ `provenance: ${prov.cls}`
598
+ )}>${_Native2DCompiler.PROVENANCE_GLYPH[prov.cls]}</sup>`;
599
+ }
404
600
  const each = this.buildEachIterator(traits);
405
601
  const keyProp = each ? ` key={i}` : "";
406
602
  let element;
407
603
  if (tag === "style") {
408
604
  const escapedStyle = (content || "").replace(/`/g, "\\`").replace(/\$/g, "\\$");
409
605
  element = `<style${keyProp} dangerouslySetInnerHTML={{ __html: \`${escapedStyle}\` }} />`;
606
+ } else if (traits.sparkline?.state) {
607
+ element = this.buildSparklineElement(traits, props, keyProp);
608
+ } else if (traits.chart?.state) {
609
+ element = this.buildChartElement(traits, props, keyProp);
610
+ } else if (traits.live_proof?.claim) {
611
+ element = this.buildLiveProofElement(traits, keyProp);
410
612
  } else if (tag === "img" || tag === "input") {
411
613
  element = `<${tag}${props}${keyProp} />`;
412
614
  } else {
@@ -913,7 +1115,13 @@ export default ${safeName}Component;
913
1115
  * : (snap?.fps ?? 0) >= 30 ? "text-amber-400"
914
1116
  * : "text-red-400"
915
1117
  *
916
- * Each tier may specify `gte` (>=), `gt` (>), `lte` (<=), and/or `lt` (<).
1118
+ * Each tier may specify `gte` (>=), `gt` (>), `lte` (<=), and/or `lt` (<) for
1119
+ * numeric thresholds, OR `eq`/`neq` for exact-match categories (e.g. a
1120
+ * security audit outcome: `{ eq: "denied", className: "text-red-400" }`).
1121
+ * `eq`/`neq` accept a string or a number; string operands pass the same
1122
+ * injection guard as `@when eq` and are emitted via JSON.stringify. When any
1123
+ * tier compares strings, the bound value is coerced to `''` (not `0`) so the
1124
+ * cascade stays total before state loads without mis-coercing a string to 0.
917
1125
  * Conditions on one tier are AND-ed. A tier with no bounds is the
918
1126
  * unconditional fallback (its className is the trailing `:` branch). If no
919
1127
  * tier is unconditional, an empty-string fallback is appended so the
@@ -927,8 +1135,11 @@ export default ${safeName}Component;
927
1135
  String(bind.path || ""),
928
1136
  "@bind tiers"
929
1137
  );
930
- const valueRef = `(${baseExpr} ?? 0)`;
931
1138
  const tiers = bind.tiers;
1139
+ const usesStringCompare = tiers.some(
1140
+ (t) => typeof t.eq === "string" || typeof t.neq === "string"
1141
+ );
1142
+ const valueRef = usesStringCompare ? `(${baseExpr} ?? '')` : `(${baseExpr} ?? 0)`;
932
1143
  const branches = [];
933
1144
  for (const tier of tiers) {
934
1145
  const className = typeof tier.className === "string" ? tier.className : "";
@@ -937,6 +1148,16 @@ export default ${safeName}Component;
937
1148
  if (typeof tier.gt === "number") conditions.push(`${valueRef} > ${tier.gt}`);
938
1149
  if (typeof tier.lte === "number") conditions.push(`${valueRef} <= ${tier.lte}`);
939
1150
  if (typeof tier.lt === "number") conditions.push(`${valueRef} < ${tier.lt}`);
1151
+ if (typeof tier.eq === "number") conditions.push(`${valueRef} === ${tier.eq}`);
1152
+ else if (typeof tier.eq === "string")
1153
+ conditions.push(
1154
+ `${valueRef} === ${JSON.stringify(this.assertSafeLiteral(tier.eq, "@bind tier eq"))}`
1155
+ );
1156
+ if (typeof tier.neq === "number") conditions.push(`${valueRef} !== ${tier.neq}`);
1157
+ else if (typeof tier.neq === "string")
1158
+ conditions.push(
1159
+ `${valueRef} !== ${JSON.stringify(this.assertSafeLiteral(tier.neq, "@bind tier neq"))}`
1160
+ );
940
1161
  branches.push({
941
1162
  condition: conditions.length > 0 ? conditions.join(" && ") : null,
942
1163
  className
@@ -959,6 +1180,309 @@ export default ${safeName}Component;
959
1180
  fallback
960
1181
  );
961
1182
  }
1183
+ /**
1184
+ * @sparkline: render a bound numeric array as an inline SVG polyline — the
1185
+ * smallest slice of native data-viz (no axes/legend). The points are computed
1186
+ * at render time from the array, normalized into a fixed viewBox
1187
+ * (`width`×`height`, default 100×30) with `preserveAspectRatio="none"` so the
1188
+ * SVG fills its CSS box. `state`(+optional `path`) is the array; `valueKey`
1189
+ * reads a number out of object items (e.g. items `{sizeKb}` → valueKey
1190
+ * "sizeKb"); `stroke` is a themeable line-color class (default
1191
+ * `stroke-studio-accent`). Container styling (`@theme`/`@layout`) rides in on
1192
+ * `props`. Dependency-free, injection-safe: identifiers are validated and the
1193
+ * points expression uses string concatenation (no inner template literals).
1194
+ */
1195
+ buildSparklineElement(traits, props, keyProp) {
1196
+ const sp = traits.sparkline;
1197
+ const state = this.assertSafeDotPath(String(sp.state), "@sparkline state");
1198
+ const path = sp.path ? String(sp.path) : "";
1199
+ if (path) this.assertSafeDotPath(path, "@sparkline path");
1200
+ const arrayRef = this.buildStatePathExpr(state, path, "@sparkline");
1201
+ const W = Number.isInteger(sp.width) && sp.width > 0 ? sp.width : 100;
1202
+ const H = Number.isInteger(sp.height) && sp.height > 0 ? sp.height : 30;
1203
+ let valueExpr = "d";
1204
+ if (sp.valueKey != null) {
1205
+ const vk = String(sp.valueKey);
1206
+ if (!/^[A-Za-z_$][\w$]*$/.test(vk)) {
1207
+ throw new Error(`Native2DCompiler @sparkline: invalid valueKey ${JSON.stringify(vk)}`);
1208
+ }
1209
+ valueExpr = `d?.${vk}`;
1210
+ }
1211
+ const stroke = typeof sp.stroke === "string" ? this.assertSafeLiteral(sp.stroke, "@sparkline stroke") : "stroke-studio-accent";
1212
+ const strokeWidth = /^[0-9]+(\.[0-9]+)?$/.test(String(sp.strokeWidth ?? "")) ? String(sp.strokeWidth) : "1.5";
1213
+ const points = `((__a) => { const __v = (__a ?? []).map((d) => Number(${valueExpr}) || 0); if (!__v.length) return ''; const __mn = Math.min(...__v), __mx = Math.max(...__v), __r = (__mx - __mn) || 1, __sx = __v.length > 1 ? ${W} / (__v.length - 1) : 0; return __v.map((y, i) => (i * __sx).toFixed(2) + ',' + (${H} - ((y - __mn) / __r) * ${H}).toFixed(2)).join(' '); })(${arrayRef})`;
1214
+ return `<svg${props}${keyProp} data-baseline="min" viewBox="0 0 ${W} ${H}" preserveAspectRatio="none">
1215
+ <polyline fill="none" className="${stroke}" strokeWidth="${strokeWidth}" points={${points}} />
1216
+ </svg>`;
1217
+ }
1218
+ /**
1219
+ * @chart: the fuller native data-viz primitive — a bar / line / area chart with
1220
+ * a baseline axis and (bar) crisp category labels. Unlike @sparkline (fill-the-box,
1221
+ * no axes), @chart uses a fixed-aspect viewBox with margins so `<text>` labels stay
1222
+ * undistorted. Geometry is computed at render time from the bound array; a bar chart
1223
+ * emits one `<rect>` per item, line/area emit a `<polyline>`/`<polygon>` over the
1224
+ * plot region. Injection-safe: `state`/`path`/`valueKey`/`labelKey` are validated
1225
+ * identifiers/dot-paths, `stroke`/`fill` pass the literal guard, and the point math
1226
+ * uses string concatenation (no inner template literals).
1227
+ *
1228
+ * `@chart { kind: "bar"|"line"|"area", state, path?, valueKey?, labelKey?,
1229
+ * width?, height?, stroke?, fill? }`
1230
+ */
1231
+ buildChartElement(traits, props, keyProp) {
1232
+ const ch = traits.chart;
1233
+ const kind = ch.kind === "line" || ch.kind === "area" ? ch.kind : "bar";
1234
+ const state = this.assertSafeDotPath(String(ch.state), "@chart state");
1235
+ const path = ch.path ? String(ch.path) : "";
1236
+ if (path) this.assertSafeDotPath(path, "@chart path");
1237
+ const arrayRef = this.buildStatePathExpr(state, path, "@chart");
1238
+ let valueExpr = "d";
1239
+ if (ch.valueKey != null) {
1240
+ const vk = String(ch.valueKey);
1241
+ if (!/^[A-Za-z_$][\w$]*$/.test(vk)) {
1242
+ throw new Error(`Native2DCompiler @chart: invalid valueKey ${JSON.stringify(vk)}`);
1243
+ }
1244
+ valueExpr = `d?.${vk}`;
1245
+ }
1246
+ let labelKey = "";
1247
+ if (ch.labelKey != null) {
1248
+ labelKey = String(ch.labelKey);
1249
+ if (!/^[A-Za-z_$][\w$]*$/.test(labelKey)) {
1250
+ throw new Error(`Native2DCompiler @chart: invalid labelKey ${JSON.stringify(labelKey)}`);
1251
+ }
1252
+ }
1253
+ let classKey = "";
1254
+ if (ch.classKey != null) {
1255
+ classKey = String(ch.classKey);
1256
+ if (!/^[A-Za-z_$][\w$]*$/.test(classKey)) {
1257
+ throw new Error(`Native2DCompiler @chart: invalid classKey ${JSON.stringify(classKey)}`);
1258
+ }
1259
+ }
1260
+ const W = Number.isInteger(ch.width) && ch.width > 0 ? ch.width : 280;
1261
+ const H = Number.isInteger(ch.height) && ch.height > 0 ? ch.height : 140;
1262
+ const stroke = typeof ch.stroke === "string" ? this.assertSafeLiteral(ch.stroke, "@chart stroke") : "stroke-studio-accent";
1263
+ const fill = typeof ch.fill === "string" ? this.assertSafeLiteral(ch.fill, "@chart fill") : "fill-studio-accent";
1264
+ const PX = 6;
1265
+ const PT = 8;
1266
+ const PB = labelKey && kind === "bar" ? 16 : 6;
1267
+ const plotW = W - 2 * PX;
1268
+ const plotH = H - PT - PB;
1269
+ const baselineY = H - PB;
1270
+ const baseline = `<line x1="${PX}" y1="${baselineY}" x2="${W - PX}" y2="${baselineY}" className="stroke-studio-border" strokeWidth="0.5" />`;
1271
+ const provDefs = classKey ? `<defs><pattern id="holo-hatch" width="4" height="4" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"><line x1="0" y1="0" x2="0" y2="4" className="stroke-studio-accent" strokeWidth="1.2" /></pattern><pattern id="holo-dots" width="3" height="3" patternUnits="userSpaceOnUse"><circle cx="1.5" cy="1.5" r="0.6" className="fill-studio-accent" /></pattern></defs>` : "";
1272
+ let body;
1273
+ if (kind === "bar") {
1274
+ const label = labelKey ? `<text x={__x + __bw / 2} y={${H - 4}} textAnchor="middle" className="fill-studio-muted" fontSize="6">{String(d?.${labelKey} ?? '')}</text>` : "";
1275
+ const provFill = classKey ? ` fill={d?.${classKey} === "inferred" ? "url(#holo-hatch)" : d?.${classKey} === "generative" ? "url(#holo-dots)" : undefined} data-provenance-class={String(d?.${classKey} ?? "")}` : "";
1276
+ body = `{((__a) => { const __d = (__a ?? []); const __v = __d.map((d) => Number(${valueExpr}) || 0); const __max = Math.max(1, ...__v); const __n = __d.length || 1; const __slot = ${plotW} / __n; const __bw = Math.max(1, Math.min(__slot * 0.62, __slot - 1)); return __d.map((d, i) => { const __h = Math.max(0, Number(${valueExpr}) || 0) / __max * ${plotH}; const __x = ${PX} + i * __slot + (__slot - __bw) / 2; const __y = ${baselineY} - __h; return (<g key={i}><rect x={__x} y={__y} width={__bw} height={__h} className="${fill}"${provFill} rx="0.5" />${label}</g>); }); })(${arrayRef})}`;
1277
+ } else {
1278
+ const norm = this._honestMode ? `const __mn = 0, __r = Math.max(1, ...__v), ` : `const __mn = Math.min(...__v), __mx = Math.max(...__v), __r = (__mx - __mn) || 1, `;
1279
+ const yExpr = this._honestMode ? "Math.max(0, y)" : "y";
1280
+ const pts = `((__a) => { const __v = (__a ?? []).map((d) => Number(${valueExpr}) || 0); if (!__v.length) return ''; ` + norm + `__sx = __v.length > 1 ? ${plotW} / (__v.length - 1) : 0; return __v.map((y, i) => (${PX} + i * __sx).toFixed(2) + ',' + (${baselineY} - ((${yExpr} - __mn) / __r) * ${plotH}).toFixed(2)).join(' '); })(${arrayRef})`;
1281
+ const line = `<polyline fill="none" className="${stroke}" strokeWidth="1.5" points={${pts}} />`;
1282
+ if (kind === "area") {
1283
+ const areaPts = `((__p) => __p ? __p + ' ' + ${W - PX} + ',' + ${baselineY} + ' ' + ${PX} + ',' + ${baselineY} : '')(${pts})`;
1284
+ body = `<polygon className="${fill}" fillOpacity="0.25" points={${areaPts}} />
1285
+ ${line}`;
1286
+ } else {
1287
+ body = line;
1288
+ }
1289
+ }
1290
+ const baselineAttr = ` data-baseline="${kind === "bar" || this._honestMode ? "zero" : "min"}"`;
1291
+ const clampedAttr = kind === "bar" || this._honestMode ? ` data-clamped={String(((__a) => (__a ?? []).some((d) => (Number(${valueExpr}) || 0) < 0))(${arrayRef}))}` : "";
1292
+ return `<svg${props}${keyProp}${baselineAttr}${clampedAttr} viewBox="0 0 ${W} ${H}">
1293
+ ${provDefs}
1294
+ ${baseline}
1295
+ ${body}
1296
+ </svg>`;
1297
+ }
1298
+ /**
1299
+ * Receipt-Bound Surface enforcement + emission (@honest / @provenance_bound).
1300
+ *
1301
+ * A "data-bound" element (one that renders a value from state via @bind/@chart/
1302
+ * @sparkline/@model) must, in honest mode, carry `@provenance_bound {source, class}`
1303
+ * — otherwise the compiler THROWS (HONEST-UNSOURCED): the surface cannot emit an
1304
+ * unsourced pixel. When provenance IS present, this returns the inline receipt
1305
+ * attributes (`data-holo-provenance` = a machine-readable {source,class,confidence}
1306
+ * an independent consumer can re-derive against, `data-provenance-class`) plus the
1307
+ * class so the caller can add a visible honesty glyph to text values. An unknown
1308
+ * class is rejected (fail toward lower trust — never silently upgraded to measured).
1309
+ * Returns null when the element is not provenance-bound (no attributes, no glyph).
1310
+ */
1311
+ /**
1312
+ * @verified_view / @projects — the admission gate for agent-authored
1313
+ * surfaces (slice 4 of the Receipt-Bound Surface, honest v0).
1314
+ *
1315
+ * `@projects { node: "stats.sessions" }` is the AUTHOR'S CLAIM of which
1316
+ * world-model node an element renders. This compiler owns the actual data
1317
+ * path (@bind/@chart/@sparkline/@model → state[.path]), so the claim is
1318
+ * verified as compiler-owned DATA-FLOW — the two sides are independently
1319
+ * authored, which is exactly what the shallow "source is non-empty" version
1320
+ * (rejected as theater in the slice-4 warning) lacks. Checks, all fatal
1321
+ * (VIEW-UNGROUNDED):
1322
+ * 1. a declared projection must MATCH the element's actual bound path —
1323
+ * "the agent says sessions but wired revenue" fails to compile;
1324
+ * 2. a projection must root in a REAL node (composition state or a @fetch
1325
+ * into-slot) — a hallucinated node fails to compile;
1326
+ * 3. a projection on an element with NO data binding is a lie by
1327
+ * construction — fails to compile;
1328
+ * 4. under composition-level `@verified_view`, every data-bound element
1329
+ * MUST declare a projection (mirrors HONEST-UNSOURCED).
1330
+ * Checks 1–3 are always-on (a lying receipt is worse than none); check 4 is
1331
+ * the mode. Verified elements emit `data-holo-projects` so independent
1332
+ * consumers can re-check the claim against the artifact. HONEST SCOPE:
1333
+ * runtime re-derivation against a live graph.holo world model (the full
1334
+ * research-spec `projects:` semantics + SimulationContract co-emission) is
1335
+ * v1+ — this v0 proves what the compiler can prove, statically.
1336
+ */
1337
+ resolveProjection(traits, obj) {
1338
+ const nm = () => String(obj.name ?? "element");
1339
+ const src = traits.bind?.state ? { state: traits.bind.state, path: traits.bind.path } : traits.chart?.state ? { state: traits.chart.state, path: traits.chart.path } : traits.sparkline?.state ? { state: traits.sparkline.state, path: traits.sparkline.path } : traits.model?.state ? { state: traits.model.state, path: traits.model.path } : (
1340
+ // @each renders a LIST from state — the element's provenance is the bound array.
1341
+ traits.each?.state ? { state: traits.each.state, path: traits.each.path } : null
1342
+ );
1343
+ const actualPath = src ? `${String(src.state)}${src.path ? "." + String(src.path) : ""}` : null;
1344
+ const pj = traits.projects;
1345
+ if (!pj) {
1346
+ if (this._verifiedViewMode && actualPath) {
1347
+ throw new Error(
1348
+ `Native2DCompiler @verified_view: VIEW-UNGROUNDED \u2014 "${nm()}" renders data without @projects {node}; an agent-authored surface ships only if every element declares what it renders`
1349
+ );
1350
+ }
1351
+ return null;
1352
+ }
1353
+ const node = this.assertSafeDotPath(String(pj.node ?? ""), "@projects node");
1354
+ if (!actualPath) {
1355
+ throw new Error(
1356
+ `Native2DCompiler @projects: VIEW-UNGROUNDED \u2014 "${nm()}" claims to project "${node}" but has no data binding at all; the claim is a lie by construction`
1357
+ );
1358
+ }
1359
+ if (node !== actualPath) {
1360
+ throw new Error(
1361
+ `Native2DCompiler @projects: VIEW-UNGROUNDED \u2014 "${nm()}" claims to project "${node}" but is actually bound to "${actualPath}"; the surface would lie about its source`
1362
+ );
1363
+ }
1364
+ const root = node.split(".")[0];
1365
+ if (!this._projectionRoots.has(root)) {
1366
+ throw new Error(
1367
+ `Native2DCompiler @projects: VIEW-UNGROUNDED \u2014 "${nm()}" projects "${node}" but no state node "${root}" exists (hallucinated node; declared state keys and @fetch slots: ${[...this._projectionRoots].join(", ") || "none"})`
1368
+ );
1369
+ }
1370
+ const b = traits.bind;
1371
+ const identity = !!b?.state && b.precision === void 0 && b.prefix === void 0 && b.suffix === void 0 && !b.tiers && !traits.chart && !traits.sparkline && !traits.each && !traits.model;
1372
+ let transform;
1373
+ if (b?.state && !traits.chart && !traits.sparkline && !traits.each && !traits.model && (b.precision !== void 0 || b.prefix !== void 0 || b.suffix !== void 0)) {
1374
+ transform = {};
1375
+ if (typeof b.precision === "number") transform.precision = b.precision;
1376
+ if (b.prefix !== void 0) transform.prefix = String(b.prefix);
1377
+ if (b.suffix !== void 0) transform.suffix = String(b.suffix);
1378
+ }
1379
+ let entity;
1380
+ if (pj.entity !== void 0) {
1381
+ const e = String(pj.entity);
1382
+ if (!/^[A-Za-z0-9_.:-]+$/.test(e)) {
1383
+ throw new Error(
1384
+ `Native2DCompiler @projects: invalid entity id ${JSON.stringify(e)} on "${nm()}" (allowed: alphanumerics and . : _ -)`
1385
+ );
1386
+ }
1387
+ entity = e;
1388
+ }
1389
+ this._collectedProjections.push({
1390
+ element: nm(),
1391
+ node,
1392
+ ...entity ? { entity } : {},
1393
+ identity,
1394
+ ...transform ? { transform } : {}
1395
+ });
1396
+ return ` data-holo-projects="${node}"`;
1397
+ }
1398
+ /**
1399
+ * @verified_view v1 — build the co-emitted view contract: a portable, sha256-bound JSON
1400
+ * receipt of every verified projection plus the valid state roots. The contract travels
1401
+ * WITH the compiled artifact (`export const holoViewContract` + a `data-holo-view-contract`
1402
+ * hash on the root), so an independent consumer re-derives the projection set from the
1403
+ * emitted `data-holo-projects` attributes and checks it against this contract — the two
1404
+ * emission paths cannot silently drift, and the surface's honesty becomes one verifiable
1405
+ * receipt instead of N scattered attributes (W.772). Returns null outside @verified_view
1406
+ * mode (un-gated surfaces carry no contract). Canonical: projections sorted by
1407
+ * (element, node) and roots sorted, so the hash is stable across traversal order.
1408
+ *
1409
+ * NOTE (v1 scope): this makes the projection contract portable and independently
1410
+ * re-checkable from the ARTIFACT — the foundation for runtime re-derivation. Verifying the
1411
+ * bound value against a LIVE graph.holo world model at runtime is the deeper v1 still to be
1412
+ * designed.
1413
+ */
1414
+ buildViewContract() {
1415
+ if (!this._verifiedViewMode) return null;
1416
+ const projections = [...this._collectedProjections].sort(
1417
+ (a, b) => a.element === b.element ? a.node.localeCompare(b.node) : a.element.localeCompare(b.element)
1418
+ );
1419
+ const stateRoots = [...this._projectionRoots].sort();
1420
+ const body = { version: _Native2DCompiler.VIEW_CONTRACT_VERSION, projections, stateRoots };
1421
+ const hash = createHash("sha256").update(JSON.stringify(body)).digest("hex");
1422
+ return { json: JSON.stringify({ ...body, contractHash: hash }), hash };
1423
+ }
1424
+ resolveProvenance(traits, obj) {
1425
+ const dataBound = !!(traits.bind?.state || traits.chart?.state && !traits.chart?.classKey || traits.sparkline?.state || traits.model);
1426
+ const pb = traits.provenance_bound;
1427
+ if (this._honestMode && dataBound && !pb) {
1428
+ const nm = String(obj.name ?? "element");
1429
+ throw new Error(
1430
+ `Native2DCompiler @honest: HONEST-UNSOURCED \u2014 "${nm}" renders data without @provenance_bound {source, class}; the surface cannot emit an unsourced pixel`
1431
+ );
1432
+ }
1433
+ if (!pb) return null;
1434
+ const cls = String(pb.class ?? "");
1435
+ if (!_Native2DCompiler.PROVENANCE_CLASSES.has(cls)) {
1436
+ throw new Error(
1437
+ `Native2DCompiler @provenance_bound: invalid class ${JSON.stringify(cls)} \u2014 expected measured|derived|inferred|generative (unknown classes fail toward lower trust, never default to measured)`
1438
+ );
1439
+ }
1440
+ const source = this.assertSafeLiteral(String(pb.source ?? ""), "@provenance_bound source");
1441
+ const receipt = { source, class: cls };
1442
+ if (pb.confidence != null) {
1443
+ const c = Number(pb.confidence);
1444
+ if (Number.isFinite(c) && c >= 0 && c <= 1) receipt.confidence = c;
1445
+ }
1446
+ const propsStr = ` data-holo-provenance='${JSON.stringify(receipt)}' data-provenance-class="${cls}"`;
1447
+ return { propsStr, cls };
1448
+ }
1449
+ /**
1450
+ * @live_proof: the falsifiable surface — the receipt is load-bearing RENDER STATE.
1451
+ *
1452
+ * `@live_proof { claim, label? }` declares a boolean claim over state (a theorem the
1453
+ * element asserts). It compiles to a self-styled verdict badge whose colour + text
1454
+ * FLIP live as the claim breaks: `✓ <label> holds` (green) vs `✗ <label> FALSIFIED`
1455
+ * (red). Because the claim re-evaluates on every render, dragging a bound parameter
1456
+ * (via a sibling @model slider) past the point where the theorem fails flips the
1457
+ * badge in-band — FALSIFIED is a render state, not a console log.
1458
+ *
1459
+ * DISCIPLINE (W.767/W.769): the claim must re-derive from INDEPENDENT state fields
1460
+ * (e.g. `capacity >= load * factor`), never re-read the displayed value — a
1461
+ * self-referential claim proves nothing. The compiler cannot enforce independence,
1462
+ * but the emitted `data-proof-claim` makes the predicate auditable. The claim is
1463
+ * injection-safe (same char-class as @computed; no backticks/semicolons).
1464
+ *
1465
+ * HONESTY LABEL (@verified_view v1 groundwork): the emitted `data-proof-state` re-runs the
1466
+ * SAME `cond` the badge renders from, so today it proves DISPLAY-FAITHFULNESS (the badge
1467
+ * matches its own formula), NOT independently-verified TRUTH of the claim. We refuse to let
1468
+ * that masquerade — `data-proof-independence="self-referential"` marks it so no consumer (or
1469
+ * the moat's own claims) mistakes it for a real proof. A v1 runtime verifier that re-derives
1470
+ * the claim's inputs through a path the render did not author (an external state store or a
1471
+ * solver/StateAuthority oracle) flips this to `"verified"`. Until that oracle exists, honest
1472
+ * labeling is the only non-theatre option (see research/2026-07-10_verified-view-v1-design.md).
1473
+ */
1474
+ buildLiveProofElement(traits, keyProp) {
1475
+ const lp = traits.live_proof;
1476
+ const claim = String(lp.claim ?? "");
1477
+ if (!claim.trim() || !/^[a-zA-Z0-9_$.,()\[\]'"/\s*+\-%<>=?:!&|]+$/.test(claim)) {
1478
+ throw new Error(`Native2DCompiler @live_proof: unsafe or empty claim ${JSON.stringify(claim)}`);
1479
+ }
1480
+ const label = lp.label != null ? this.assertSafeLiteral(String(lp.label), "@live_proof label") : "Claim";
1481
+ const cond = `(${claim})`;
1482
+ return `<div${keyProp} data-proof-claim={${JSON.stringify(claim)}} data-proof-independence="self-referential" data-proof-state={${cond} ? "pass" : "falsified"} className={\`rounded-md p-2 text-xs font-semibold \${${cond} ? "bg-studio-success/10 text-studio-success" : "bg-studio-error/10 text-studio-error"}\`}>
1483
+ {${cond} ? "\u2713 ${label} holds" : "\u2717 ${label} FALSIFIED"}
1484
+ </div>`;
1485
+ }
962
1486
  buildHTMLBindAttributes(traits, staticClassName) {
963
1487
  const bind = traits.bind;
964
1488
  if (!bind?.state) return "";
@@ -1214,6 +1738,78 @@ export default ${safeName}Component;
1214
1738
  }
1215
1739
  return styles;
1216
1740
  }
1741
+ /**
1742
+ * Resolve conflicting Tailwind COLOR utilities in a STATIC class string, keeping the LAST
1743
+ * of each color family. A node's @theme className is appended AFTER the variant defaults
1744
+ * (buildClasses), so this lets an authored token color win over a hardcoded default color
1745
+ * (e.g. @theme `text-studio-muted` overrides the caption default `text-gray-500`) — which
1746
+ * class actually wins otherwise depends on Tailwind's CSS emission order, not the class
1747
+ * attribute, so the default's raw color leaks unpredictably. Only color families are deduped
1748
+ * (text/bg/border/ring/…, incl. variant prefixes like hover:/focus:); sizes, spacing, and
1749
+ * layout are untouched, and text-<size> / border-<width> / ring-<width> are never colors.
1750
+ */
1751
+ /**
1752
+ * The Tailwind COLOR family a token belongs to (incl. variant prefixes like
1753
+ * hover:/focus:), or null for a non-color token. Shared by conflict-resolution
1754
+ * and tier-family stripping. text-<size> / text-<align> / border|ring|divide-<width>
1755
+ * and arbitrary values ([10px], [#fff]) are NOT colors.
1756
+ */
1757
+ colorFamilyKey(t) {
1758
+ const m = t.match(
1759
+ /^((?:[a-z-]+:)*)(text|bg|border|ring|ring-offset|divide|accent|fill|stroke|placeholder|caret|decoration|from|to|via)-(.+)$/
1760
+ );
1761
+ if (!m) return null;
1762
+ const [, variant, prop, rest] = m;
1763
+ if (rest.startsWith("[")) return null;
1764
+ if (prop === "text") {
1765
+ if (_Native2DCompiler.TEXT_SIZE_TOKENS.has(`text-${rest}`)) return null;
1766
+ if (["left", "center", "right", "justify", "start", "end"].includes(rest)) return null;
1767
+ }
1768
+ if (prop === "border" || prop === "divide") {
1769
+ if (/^([xytrbles]|\d+|[xytrbles]-\d+)$/.test(rest)) return null;
1770
+ }
1771
+ if (prop === "ring" && /^(\d+|inset)$/.test(rest)) return null;
1772
+ return `${variant}${prop}`;
1773
+ }
1774
+ resolveColorConflicts(classStr) {
1775
+ const tokens = classStr.split(/\s+/).filter(Boolean);
1776
+ const lastIndex = /* @__PURE__ */ new Map();
1777
+ tokens.forEach((t, i) => {
1778
+ const k = this.colorFamilyKey(t);
1779
+ if (k) lastIndex.set(k, i);
1780
+ });
1781
+ return tokens.filter((t, i) => {
1782
+ const k = this.colorFamilyKey(t);
1783
+ return k === null || lastIndex.get(k) === i;
1784
+ }).join(" ");
1785
+ }
1786
+ /**
1787
+ * The set of color families a @bind's tier classNames assign — so the caller
1788
+ * can strip those families from the static prefix (the dynamic tier cascade
1789
+ * owns them, and the static default would otherwise leak a raw color).
1790
+ */
1791
+ tierColorFamilies(traits) {
1792
+ const families = /* @__PURE__ */ new Set();
1793
+ const tiers = traits?.bind?.tiers;
1794
+ if (!Array.isArray(tiers)) return families;
1795
+ for (const tier of tiers) {
1796
+ const cn = typeof tier?.className === "string" ? tier.className : "";
1797
+ for (const tok of cn.split(/\s+/).filter(Boolean)) {
1798
+ const k = this.colorFamilyKey(tok);
1799
+ if (k) families.add(k);
1800
+ }
1801
+ }
1802
+ return families;
1803
+ }
1804
+ /** Drop every token whose color family is in `families` (removes a static
1805
+ * default color that a dynamic @bind tier cascade will always override). */
1806
+ stripColorFamilies(classStr, families) {
1807
+ if (families.size === 0) return classStr;
1808
+ return classStr.split(/\s+/).filter(Boolean).filter((t) => {
1809
+ const k = this.colorFamilyKey(t);
1810
+ return k === null || !families.has(k);
1811
+ }).join(" ");
1812
+ }
1217
1813
  buildClasses(traits) {
1218
1814
  const classes = [];
1219
1815
  if (traits.text) {
@@ -1256,6 +1852,48 @@ export default ${safeName}Component;
1256
1852
  return str.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
1257
1853
  }
1258
1854
  };
1855
+ /** Version tag for the co-emitted `holoViewContract` (@verified_view v1). */
1856
+ _Native2DCompiler.VIEW_CONTRACT_VERSION = "holo-view-contract-v1";
1857
+ /**
1858
+ * 2D data-value provenance vocabulary, ordered by TRUST (highest → lowest),
1859
+ * aligned to the shipped 3D PointProvenanceClass idiom (observed | interpolated |
1860
+ * nlos-inferred | generative-extended). An UNKNOWN class is REJECTED, never
1861
+ * silently upgraded to `measured` — provenance fails toward lower trust, so a
1862
+ * typo can never make an inferred value read as sensor-attested.
1863
+ */
1864
+ _Native2DCompiler.PROVENANCE_CLASSES = /* @__PURE__ */ new Set([
1865
+ "measured",
1866
+ // source-attested: a real sensor reading, DB value, on-chain fact
1867
+ "derived",
1868
+ // computed from measured values by a transparent bounded function
1869
+ "inferred",
1870
+ // model/heuristic estimate (a forecast) — honest that it is a guess
1871
+ "generative"
1872
+ // produced by a generative model (LLM-authored value)
1873
+ ]);
1874
+ /** Visible honesty glyph appended to a non-`measured` text value (measured = trusted, no marker). */
1875
+ _Native2DCompiler.PROVENANCE_GLYPH = {
1876
+ measured: "",
1877
+ derived: "\xB0",
1878
+ inferred: "~",
1879
+ generative: "\u2726"
1880
+ };
1881
+ _Native2DCompiler.TEXT_SIZE_TOKENS = /* @__PURE__ */ new Set([
1882
+ "text-xs",
1883
+ "text-sm",
1884
+ "text-base",
1885
+ "text-lg",
1886
+ "text-xl",
1887
+ "text-2xl",
1888
+ "text-3xl",
1889
+ "text-4xl",
1890
+ "text-5xl",
1891
+ "text-6xl",
1892
+ "text-7xl",
1893
+ "text-8xl",
1894
+ "text-9xl"
1895
+ ]);
1896
+ var Native2DCompiler = _Native2DCompiler;
1259
1897
 
1260
1898
  // src/compiler/NextJSCompiler.ts
1261
1899
  function findTrait(composition, traitName2) {
@@ -1584,6 +2222,1306 @@ init_HoloMCPCompiler();
1584
2222
  init_AgentInferenceExportTarget();
1585
2223
  init_OmnigentAgentYamlCompiler();
1586
2224
  init_DaimonSeedCompiler();
2225
+
2226
+ // src/compiler/HSIIRCompiler.ts
2227
+ init_CompilerBase();
2228
+ var HSI_IR_SCHEMA_VERSION = "holoscript.hsi-ir.v0.1.0";
2229
+ var HSI_TRACE_SCHEMA_VERSION = "holoscript.hsi-trace.v0.1.0";
2230
+ var HSI_LEARNING_GRAPH_SCHEMA_VERSION = "holoscript.learning-graph.v0.1.0";
2231
+ var HSI_AUDIT_SCHEMA_VERSION = "holoscript.hsi-audit.v0.1.0";
2232
+ var HSIAdmissionError = class extends Error {
2233
+ constructor(code, message) {
2234
+ super(`[${code}] ${message}`);
2235
+ this.name = "HSIAdmissionError";
2236
+ this.code = code;
2237
+ }
2238
+ };
2239
+ function hsiStableStringify(value) {
2240
+ if (value === null || typeof value !== "object") {
2241
+ return JSON.stringify(value) ?? "null";
2242
+ }
2243
+ if (Array.isArray(value)) {
2244
+ return `[${value.map((item) => hsiStableStringify(item)).join(",")}]`;
2245
+ }
2246
+ const record = value;
2247
+ const keys = Object.keys(record).filter((key) => record[key] !== void 0).sort();
2248
+ return `{${keys.map((key) => `${JSON.stringify(key)}:${hsiStableStringify(record[key])}`).join(",")}}`;
2249
+ }
2250
+ function hsiSha256(value) {
2251
+ return `sha256:${createHash("sha256").update(hsiStableStringify(value)).digest("hex")}`;
2252
+ }
2253
+ function hsiSourceTextDigest(source) {
2254
+ return `sha256:${createHash("sha256").update(source.replace(/\r\n/g, "\n")).digest("hex")}`;
2255
+ }
2256
+
2257
+ // src/compiler/HSIIRCompiler.ts
2258
+ var HSI_OBSERVATION_MEDIATOR_EDGE = "shields";
2259
+ var ASSIGN_OPERATORS = /* @__PURE__ */ new Set(["=", "+=", "-=", "*=", "/="]);
2260
+ var BINARY_OPERATORS = /* @__PURE__ */ new Set([
2261
+ "+",
2262
+ "-",
2263
+ "*",
2264
+ "/",
2265
+ "%",
2266
+ "===",
2267
+ "!==",
2268
+ "==",
2269
+ "!=",
2270
+ "<",
2271
+ ">",
2272
+ "<=",
2273
+ ">=",
2274
+ "&&",
2275
+ "||"
2276
+ ]);
2277
+ function spanOf(node) {
2278
+ const loc = node?.loc;
2279
+ if (!loc) return void 0;
2280
+ return {
2281
+ line: loc.start.line,
2282
+ column: loc.start.column,
2283
+ endLine: loc.end.line,
2284
+ endColumn: loc.end.column
2285
+ };
2286
+ }
2287
+ function scalarType(value) {
2288
+ if (value === null) return "null";
2289
+ return typeof value;
2290
+ }
2291
+ function asScalar(value, where) {
2292
+ if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
2293
+ return value;
2294
+ }
2295
+ throw new HSIAdmissionError(
2296
+ "unsupported-value",
2297
+ `${where}: HS-Core v0 admits scalar values only, got ${Array.isArray(value) ? "array" : typeof value}`
2298
+ );
2299
+ }
2300
+ function asTriple(value, where) {
2301
+ let arr;
2302
+ if (Array.isArray(value)) {
2303
+ arr = value;
2304
+ } else if (typeof value === "object" && value !== null && "x" in value) {
2305
+ const vec = value;
2306
+ arr = [vec["x"], vec["y"], vec["z"]];
2307
+ }
2308
+ if (!arr || arr.length !== 3 || !arr.every((n) => typeof n === "number" && Number.isFinite(n))) {
2309
+ throw new HSIAdmissionError("invalid-spatial", `${where}: position/scale must be a finite numeric triple`);
2310
+ }
2311
+ return [arr[0], arr[1], arr[2]];
2312
+ }
2313
+ function collectSlots(ir, into) {
2314
+ switch (ir.kind) {
2315
+ case "Identifier":
2316
+ into.add(ir.name);
2317
+ return;
2318
+ case "BinaryExpression":
2319
+ collectSlots(ir.left, into);
2320
+ collectSlots(ir.right, into);
2321
+ return;
2322
+ case "UnaryExpression":
2323
+ collectSlots(ir.argument, into);
2324
+ return;
2325
+ case "MemberExpression":
2326
+ collectSlots(ir.object, into);
2327
+ return;
2328
+ case "CallExpression":
2329
+ for (const arg of ir.arguments) collectSlots(arg, into);
2330
+ return;
2331
+ case "Literal":
2332
+ return;
2333
+ }
2334
+ }
2335
+ function assertSlots(ir, allowed, where) {
2336
+ const used = /* @__PURE__ */ new Set();
2337
+ collectSlots(ir, used);
2338
+ for (const name of used) {
2339
+ if (!allowed.has(name)) {
2340
+ throw new HSIAdmissionError("unknown-slot", `${where}: expression reads undeclared slot "${name}"`);
2341
+ }
2342
+ }
2343
+ return [...used].sort();
2344
+ }
2345
+ function lowerHoloExpression(expr, where) {
2346
+ switch (expr.type) {
2347
+ case "Literal":
2348
+ return { kind: "Literal", value: expr.value };
2349
+ case "Identifier":
2350
+ return { kind: "Identifier", name: expr.name };
2351
+ case "BinaryExpression": {
2352
+ if (!BINARY_OPERATORS.has(expr.operator)) {
2353
+ throw new HSIAdmissionError("unsupported-operator", `${where}: operator "${expr.operator}"`);
2354
+ }
2355
+ return {
2356
+ kind: "BinaryExpression",
2357
+ operator: expr.operator,
2358
+ left: lowerHoloExpression(expr.left, where),
2359
+ right: lowerHoloExpression(expr.right, where)
2360
+ };
2361
+ }
2362
+ case "UnaryExpression":
2363
+ return {
2364
+ kind: "UnaryExpression",
2365
+ operator: expr.operator,
2366
+ argument: lowerHoloExpression(expr.argument, where)
2367
+ };
2368
+ case "MemberExpression": {
2369
+ if (expr.computed) {
2370
+ throw new HSIAdmissionError("unsupported-expression", `${where}: computed member access`);
2371
+ }
2372
+ return {
2373
+ kind: "MemberExpression",
2374
+ object: lowerHoloExpression(expr.object, where),
2375
+ property: expr.property
2376
+ };
2377
+ }
2378
+ default:
2379
+ throw new HSIAdmissionError("unsupported-expression", `${where}: ${expr.type} is outside HS-Core v0`);
2380
+ }
2381
+ }
2382
+ function lowerEntities(composition) {
2383
+ const templates = /* @__PURE__ */ new Map();
2384
+ for (const template of composition.templates ?? []) {
2385
+ if (templates.has(template.name)) {
2386
+ throw new HSIAdmissionError("duplicate-template", `template "${template.name}" declared twice`);
2387
+ }
2388
+ templates.set(template.name, template);
2389
+ }
2390
+ const entities = /* @__PURE__ */ new Map();
2391
+ for (const obj of composition.objects ?? []) {
2392
+ if (entities.has(obj.name)) {
2393
+ throw new HSIAdmissionError("duplicate-entity", `entity "${obj.name}" declared twice`);
2394
+ }
2395
+ if ((obj.children ?? []).length > 0) {
2396
+ throw new HSIAdmissionError("unsupported-value", `entity "${obj.name}": nested children are outside HS-Core v0`);
2397
+ }
2398
+ const components = {};
2399
+ const traitNames = /* @__PURE__ */ new Set();
2400
+ let template;
2401
+ if (obj.template !== void 0) {
2402
+ template = templates.get(obj.template);
2403
+ if (!template) {
2404
+ throw new HSIAdmissionError("unknown-archetype", `entity "${obj.name}" uses missing template "${obj.template}"`);
2405
+ }
2406
+ for (const prop of template.properties ?? []) {
2407
+ if (prop.key === "position" || prop.key === "scale") continue;
2408
+ components[prop.key] = asScalar(prop.value, `template "${template.name}".${prop.key}`);
2409
+ }
2410
+ for (const trait of template.traits ?? []) traitNames.add(trait.name);
2411
+ }
2412
+ let position;
2413
+ let scale;
2414
+ for (const prop of obj.properties ?? []) {
2415
+ if (prop.key === "position") {
2416
+ position = asTriple(prop.value, `entity "${obj.name}".position`);
2417
+ continue;
2418
+ }
2419
+ if (prop.key === "scale") {
2420
+ scale = asTriple(prop.value, `entity "${obj.name}".scale`);
2421
+ continue;
2422
+ }
2423
+ components[prop.key] = asScalar(prop.value, `entity "${obj.name}".${prop.key}`);
2424
+ }
2425
+ for (const trait of obj.traits ?? []) traitNames.add(trait.name);
2426
+ const opaqueValue = components["opaque"];
2427
+ const opacity = opaqueValue === void 0 ? "unknown" : opaqueValue === true ? "opaque" : "transparent";
2428
+ delete components["opaque"];
2429
+ const role = typeof components["role"] === "string" ? components["role"] : void 0;
2430
+ const entity = {
2431
+ id: `entity:${obj.name}`,
2432
+ name: obj.name,
2433
+ opacity,
2434
+ components,
2435
+ traits: [...traitNames].sort(),
2436
+ sourceSpan: spanOf(obj)
2437
+ };
2438
+ if (obj.template !== void 0) entity.archetype = obj.template;
2439
+ if (role !== void 0) entity.role = role;
2440
+ if (position === void 0 && obj.position !== void 0) {
2441
+ position = asTriple(obj.position, `entity "${obj.name}".position`);
2442
+ }
2443
+ if (scale === void 0 && obj.scale !== void 0) {
2444
+ scale = asTriple(obj.scale, `entity "${obj.name}".scale`);
2445
+ }
2446
+ if (position !== void 0) entity.position = position;
2447
+ if (scale !== void 0) entity.scale = scale;
2448
+ entities.set(obj.name, entity);
2449
+ }
2450
+ return { templates, entities };
2451
+ }
2452
+ function lowerRelations(composition, entities) {
2453
+ const relations = [];
2454
+ const connections = composition.connections ?? [];
2455
+ for (const conn of connections) {
2456
+ for (const endpoint of [conn.from, conn.to]) {
2457
+ if (!entities.has(endpoint)) {
2458
+ throw new HSIAdmissionError(
2459
+ "unknown-relation-endpoint",
2460
+ `connection ${conn.from} -> ${conn.to} references undeclared entity "${endpoint}"`
2461
+ );
2462
+ }
2463
+ }
2464
+ const edgeType = conn.edgeType ?? "connects";
2465
+ relations.push({
2466
+ id: `relation:${conn.from}->${conn.to}:${edgeType}`,
2467
+ from: conn.from,
2468
+ to: conn.to,
2469
+ edgeType,
2470
+ sourceSpan: spanOf(conn)
2471
+ });
2472
+ }
2473
+ return relations;
2474
+ }
2475
+ function lowerState(composition) {
2476
+ const fields = [];
2477
+ const seen = /* @__PURE__ */ new Set();
2478
+ for (const prop of composition.state?.properties ?? []) {
2479
+ if (seen.has(prop.key)) {
2480
+ throw new HSIAdmissionError("duplicate-state-key", `state key "${prop.key}" declared twice`);
2481
+ }
2482
+ seen.add(prop.key);
2483
+ const baseline = asScalar(prop.value, `state.${prop.key}`);
2484
+ fields.push({
2485
+ id: `state:world.${prop.key}`,
2486
+ key: prop.key,
2487
+ baseline,
2488
+ valueType: scalarType(baseline),
2489
+ reactive: prop.reactive === true,
2490
+ sourceSpan: spanOf(prop)
2491
+ });
2492
+ }
2493
+ return fields;
2494
+ }
2495
+ function deriveObservationPolicy(entities, relations) {
2496
+ const rules = [];
2497
+ const observers = [...entities.values()].filter((e) => e.role === "agent");
2498
+ const mediatorsByTarget = /* @__PURE__ */ new Map();
2499
+ for (const rel of relations) {
2500
+ if (rel.edgeType !== HSI_OBSERVATION_MEDIATOR_EDGE) continue;
2501
+ const list = mediatorsByTarget.get(rel.to) ?? [];
2502
+ list.push(entities.get(rel.from));
2503
+ mediatorsByTarget.set(rel.to, list);
2504
+ }
2505
+ for (const observer of observers) {
2506
+ for (const observed of entities.values()) {
2507
+ if (observed.name === observer.name) continue;
2508
+ if (observed.role === "barrier") continue;
2509
+ const mediators = (mediatorsByTarget.get(observed.name) ?? []).slice().sort((a, b) => a.name.localeCompare(b.name));
2510
+ const access = mediators.some((m) => m.opacity === "opaque") ? "blocked" : mediators.some((m) => m.opacity === "unknown") ? "unknown" : "visible";
2511
+ rules.push({
2512
+ id: `obs:${observer.name}->${observed.name}`,
2513
+ observer: observer.name,
2514
+ observed: observed.name,
2515
+ access,
2516
+ mediators: mediators.map((m) => m.name)
2517
+ });
2518
+ }
2519
+ }
2520
+ return rules;
2521
+ }
2522
+ function lowerStatements(statements, handlerEvent, stateSlots, counter) {
2523
+ const effects = [];
2524
+ for (const stmt of statements) {
2525
+ const ordinal = counter.n++;
2526
+ const id = `effect:${handlerEvent}#${ordinal}`;
2527
+ switch (stmt.type) {
2528
+ case "Assignment": {
2529
+ if (!ASSIGN_OPERATORS.has(stmt.operator)) {
2530
+ throw new HSIAdmissionError("unsupported-operator", `${id}: assignment operator "${stmt.operator}"`);
2531
+ }
2532
+ const target = stmt.target.startsWith("state.") ? stmt.target.slice("state.".length) : stmt.target;
2533
+ if (!stateSlots.has(target)) {
2534
+ throw new HSIAdmissionError("unknown-assignment-target", `${id}: "${stmt.target}" is not a declared state key`);
2535
+ }
2536
+ const value = lowerHoloExpression(stmt.value, id);
2537
+ assertSlots(value, stateSlots, id);
2538
+ effects.push({ kind: "assign", id, target, operator: stmt.operator, value, sourceSpan: spanOf(stmt) });
2539
+ break;
2540
+ }
2541
+ case "EmitStatement": {
2542
+ effects.push({ kind: "emit", id, event: stmt.event, sourceSpan: spanOf(stmt) });
2543
+ break;
2544
+ }
2545
+ case "IfStatement": {
2546
+ const condition = lowerHoloExpression(stmt.condition, id);
2547
+ assertSlots(condition, stateSlots, id);
2548
+ effects.push({
2549
+ kind: "branch",
2550
+ id,
2551
+ condition,
2552
+ then: lowerStatements(stmt.consequent, handlerEvent, stateSlots, counter),
2553
+ else: lowerStatements(stmt.alternate ?? [], handlerEvent, stateSlots, counter),
2554
+ sourceSpan: spanOf(stmt)
2555
+ });
2556
+ break;
2557
+ }
2558
+ default:
2559
+ throw new HSIAdmissionError("unsupported-statement", `${id}: ${stmt.type} is outside HS-Core v0`);
2560
+ }
2561
+ }
2562
+ return effects;
2563
+ }
2564
+ function lowerEventHandlers(composition, stateSlots) {
2565
+ const logic = composition.logic;
2566
+ const handlers = [];
2567
+ const seen = /* @__PURE__ */ new Set();
2568
+ for (const handler of logic?.handlers ?? []) {
2569
+ if (seen.has(handler.event)) {
2570
+ throw new HSIAdmissionError("duplicate-handler", `handler "${handler.event}" declared twice`);
2571
+ }
2572
+ seen.add(handler.event);
2573
+ handlers.push({
2574
+ id: `event:${handler.event}`,
2575
+ event: handler.event,
2576
+ effects: lowerStatements(handler.body, handler.event, stateSlots, { n: 0 }),
2577
+ sourceSpan: spanOf(handler)
2578
+ });
2579
+ }
2580
+ return handlers;
2581
+ }
2582
+ function lowerMachine(machine) {
2583
+ const stateNames = Object.keys(machine.states ?? {});
2584
+ if (stateNames.length === 0) {
2585
+ throw new HSIAdmissionError("admission-skewed", `state machine "${machine.name}" declares no states`);
2586
+ }
2587
+ if (!stateNames.includes(machine.initialState)) {
2588
+ throw new HSIAdmissionError(
2589
+ "unknown-initial-state",
2590
+ `state machine "${machine.name}": initial state "${machine.initialState}" is not declared`
2591
+ );
2592
+ }
2593
+ const inputs = (machine.inputs ?? []).map((input) => ({
2594
+ id: `input:${machine.name}.${input.name}`,
2595
+ name: input.name,
2596
+ inputType: input.inputType,
2597
+ baseline: input.default !== void 0 ? input.default : input.inputType === "bool" || input.inputType === "trigger" ? false : 0
2598
+ }));
2599
+ const inputSlots = new Set(inputs.map((i) => i.name));
2600
+ const allTransitions = [];
2601
+ for (const t of machine.transitions ?? []) {
2602
+ allTransitions.push({ from: t.from && t.from !== "any" ? t.from : t.from ?? "any", t });
2603
+ }
2604
+ for (const stateName of stateNames) {
2605
+ for (const t of machine.states[stateName]?.transitions ?? []) {
2606
+ allTransitions.push({ from: t.from ?? stateName, t });
2607
+ }
2608
+ }
2609
+ const ordinals = /* @__PURE__ */ new Map();
2610
+ const transitions = allTransitions.map(({ from, t }, declarationOrdinal) => {
2611
+ if (from !== "any" && !stateNames.includes(from)) {
2612
+ throw new HSIAdmissionError(
2613
+ "unknown-transition-endpoint",
2614
+ `state machine "${machine.name}": transition from undeclared state "${from}"`
2615
+ );
2616
+ }
2617
+ if (!stateNames.includes(t.target)) {
2618
+ throw new HSIAdmissionError(
2619
+ "unknown-transition-endpoint",
2620
+ `state machine "${machine.name}": transition to undeclared state "${t.target}"`
2621
+ );
2622
+ }
2623
+ const baseId = `transition:${machine.name}.${from}->${t.target}`;
2624
+ const ordinal = ordinals.get(baseId) ?? 0;
2625
+ ordinals.set(baseId, ordinal + 1);
2626
+ const id = `${baseId}#${ordinal}`;
2627
+ let guard;
2628
+ if (t.condition) {
2629
+ guard = lowerHoloExpression(t.condition, id);
2630
+ } else if ((t.conditions ?? []).length > 0) {
2631
+ for (const cond of t.conditions) {
2632
+ const clause = {
2633
+ kind: "BinaryExpression",
2634
+ operator: cond.operator,
2635
+ left: { kind: "Identifier", name: cond.parameter },
2636
+ right: { kind: "Literal", value: cond.value }
2637
+ };
2638
+ guard = guard ? { kind: "BinaryExpression", operator: cond.chain === "or" ? "||" : "&&", left: guard, right: clause } : clause;
2639
+ }
2640
+ }
2641
+ if (!guard) {
2642
+ throw new HSIAdmissionError("admission-skewed", `${id}: transition has neither guard nor trigger condition`);
2643
+ }
2644
+ const reads = assertSlots(guard, inputSlots, id);
2645
+ const transition = {
2646
+ id,
2647
+ from,
2648
+ target: t.target,
2649
+ priority: declarationOrdinal,
2650
+ guard,
2651
+ reads,
2652
+ sourceSpan: spanOf(t)
2653
+ };
2654
+ if (t.event !== void 0) transition.event = t.event;
2655
+ return transition;
2656
+ });
2657
+ return {
2658
+ id: `machine:${machine.name}`,
2659
+ name: machine.name,
2660
+ initialState: machine.initialState,
2661
+ states: [...stateNames].sort(),
2662
+ inputs,
2663
+ transitions,
2664
+ sourceSpan: spanOf(machine)
2665
+ };
2666
+ }
2667
+ function lowerPredicates(composition, stateSlots) {
2668
+ const predicates = [];
2669
+ const slotList = [...stateSlots];
2670
+ const lowerClause = (kind, name, expr) => {
2671
+ const id = `${kind}:${name}`;
2672
+ let ir;
2673
+ try {
2674
+ ir = parseExpressionToIR(expr, slotList);
2675
+ } catch (error) {
2676
+ if (error instanceof ExpressionParseError) {
2677
+ throw new HSIAdmissionError("unparseable-clause", `${id}: ${error.message}`);
2678
+ }
2679
+ throw error;
2680
+ }
2681
+ return { id, name, kind, expression: ir, reads: assertSlots(ir, stateSlots, id), sourceSpan: spanOf(composition.contract) };
2682
+ };
2683
+ for (const clause of composition.contract?.preconditions ?? []) {
2684
+ predicates.push(lowerClause("precondition", clause.name, clause.expr));
2685
+ }
2686
+ for (const clause of composition.contract?.invariants ?? []) {
2687
+ predicates.push(lowerClause("invariant", clause.name, clause.expr));
2688
+ }
2689
+ for (const achievement of composition.achievements ?? []) {
2690
+ const id = `goal:${achievement.name}`;
2691
+ const ir = lowerHoloExpression(achievement.condition, id);
2692
+ predicates.push({
2693
+ id,
2694
+ name: achievement.name,
2695
+ kind: "goal",
2696
+ expression: ir,
2697
+ reads: assertSlots(ir, stateSlots, id),
2698
+ sourceSpan: spanOf(achievement)
2699
+ });
2700
+ }
2701
+ return predicates;
2702
+ }
2703
+ function lowerCompositionToHSIIR(composition, options = {}) {
2704
+ if (!composition || composition.type !== "Composition" || typeof composition.name !== "string" || composition.name.length === 0) {
2705
+ throw new HSIAdmissionError("empty-world", "input is not a named HoloComposition");
2706
+ }
2707
+ const { entities } = lowerEntities(composition);
2708
+ const stateFields = lowerState(composition);
2709
+ if (entities.size === 0 && stateFields.length === 0) {
2710
+ throw new HSIAdmissionError("empty-world", `composition "${composition.name}" declares no entities and no state`);
2711
+ }
2712
+ const relations = lowerRelations(composition, entities);
2713
+ const observationPolicy = deriveObservationPolicy(entities, relations);
2714
+ const stateSlots = new Set(stateFields.map((f) => f.key));
2715
+ const eventHandlers = lowerEventHandlers(composition, stateSlots);
2716
+ const machines = (composition.stateMachines ?? []).map(lowerMachine);
2717
+ const predicates = lowerPredicates(composition, stateSlots);
2718
+ const sourceDigest = options.sourceText !== void 0 ? hsiSourceTextDigest(options.sourceText) : hsiSha256({ compositionName: composition.name, note: "no-source-text-provided" });
2719
+ const byId = (items) => [...items].sort((a, b) => a.id.localeCompare(b.id));
2720
+ const docWithoutDigest = {
2721
+ schemaVersion: HSI_IR_SCHEMA_VERSION,
2722
+ kind: "HSIIR",
2723
+ world: { name: composition.name, sourceDigest },
2724
+ entities: byId([...entities.values()]),
2725
+ relations: byId(relations),
2726
+ state: byId(stateFields),
2727
+ observationPolicy: byId(observationPolicy),
2728
+ eventHandlers: byId(eventHandlers),
2729
+ machines: byId(machines),
2730
+ predicates: byId(predicates),
2731
+ declaredUnknowns: [
2732
+ "action-capabilities",
2733
+ "action-costs",
2734
+ "beliefs",
2735
+ "first-class-observations",
2736
+ "memory-events",
2737
+ "receipt-shape"
2738
+ ],
2739
+ provenance: { compiler: "HSIIRCompiler" }
2740
+ };
2741
+ const deterministicDigest = hsiSha256(docWithoutDigest);
2742
+ return {
2743
+ ...docWithoutDigest,
2744
+ provenance: { compiler: "HSIIRCompiler", deterministicDigest }
2745
+ };
2746
+ }
2747
+ var HSIIRCompiler = class extends CompilerBase {
2748
+ constructor(options = {}) {
2749
+ super();
2750
+ this.compilerName = "HSIIRCompiler";
2751
+ this.options = options;
2752
+ }
2753
+ getRequiredCapability() {
2754
+ return ANSCapabilityPath.HSI_IR;
2755
+ }
2756
+ compile(composition, agentToken, outputPath) {
2757
+ this.validateCompilerAccess(agentToken, outputPath);
2758
+ return JSON.stringify(lowerCompositionToHSIIR(composition, this.options), null, 2);
2759
+ }
2760
+ compileToFiles(composition, agentToken = "") {
2761
+ return { [this.defaultOutputFileName()]: this.compile(composition, agentToken) };
2762
+ }
2763
+ defaultOutputFileName() {
2764
+ return "hsi-ir.json";
2765
+ }
2766
+ };
2767
+ function createHSIIRCompiler(options) {
2768
+ return new HSIIRCompiler(options);
2769
+ }
2770
+
2771
+ // src/compiler/HSIExactTrace.ts
2772
+ function snapshot(world) {
2773
+ const state = {};
2774
+ for (const key of Object.keys(world.state).sort()) state[key] = world.state[key];
2775
+ const machineStates = {};
2776
+ for (const name of [...world.machines.keys()].sort()) {
2777
+ machineStates[name] = world.machines.get(name).current;
2778
+ }
2779
+ return { state, machineStates, stateDigest: hsiSha256({ state, machineStates }) };
2780
+ }
2781
+ function evaluateGuard(guard, context) {
2782
+ return evaluateExpressionIR(guard, context) === true;
2783
+ }
2784
+ function applyOperator(operator, before, operand, where) {
2785
+ if (operator === "=") {
2786
+ if (operand === null || typeof operand === "string" || typeof operand === "number" || typeof operand === "boolean") {
2787
+ return operand;
2788
+ }
2789
+ throw new HSIAdmissionError("unsupported-value", `${where}: assignment produced a non-scalar value`);
2790
+ }
2791
+ if (typeof before !== "number" || typeof operand !== "number" || !Number.isFinite(operand)) {
2792
+ throw new HSIAdmissionError(
2793
+ "unsupported-value",
2794
+ `${where}: compound assignment requires numeric operands (got ${typeof before} ${operator} ${typeof operand})`
2795
+ );
2796
+ }
2797
+ switch (operator) {
2798
+ case "+=":
2799
+ return before + operand;
2800
+ case "-=":
2801
+ return before - operand;
2802
+ case "*=":
2803
+ return before * operand;
2804
+ case "/=": {
2805
+ if (operand === 0) {
2806
+ throw new HSIAdmissionError("unsupported-value", `${where}: division by zero`);
2807
+ }
2808
+ return before / operand;
2809
+ }
2810
+ }
2811
+ }
2812
+ function runEffects(effects, world, records, emitted) {
2813
+ for (const effect of effects) {
2814
+ switch (effect.kind) {
2815
+ case "assign": {
2816
+ const before = world.state[effect.target];
2817
+ const operand = evaluateExpressionIR(effect.value, world.state);
2818
+ const after = applyOperator(effect.operator, before, operand, effect.id);
2819
+ world.state[effect.target] = after;
2820
+ records.push({ sourceId: effect.id, target: effect.target, before, after });
2821
+ break;
2822
+ }
2823
+ case "emit": {
2824
+ emitted.push(effect.event);
2825
+ break;
2826
+ }
2827
+ case "branch": {
2828
+ const taken = evaluateGuard(effect.condition, world.state);
2829
+ runEffects(taken ? effect.then : effect.else, world, records, emitted);
2830
+ break;
2831
+ }
2832
+ }
2833
+ }
2834
+ }
2835
+ function evaluateTransitions(world, ir) {
2836
+ const fired = [];
2837
+ for (const machineIR of ir.machines) {
2838
+ const runtime = world.machines.get(machineIR.name);
2839
+ const context = { ...runtime.inputs };
2840
+ for (const trigger of runtime.triggers) context[trigger] = true;
2841
+ const candidates = [...machineIR.transitions].sort((a, b) => a.priority - b.priority);
2842
+ for (const transition of candidates) {
2843
+ if (transition.from !== "any" && transition.from !== runtime.current) continue;
2844
+ if (!transition.guard) continue;
2845
+ if (evaluateGuard(transition.guard, context)) {
2846
+ fired.push({
2847
+ machine: machineIR.name,
2848
+ transitionId: transition.id,
2849
+ from: runtime.current,
2850
+ to: transition.target
2851
+ });
2852
+ runtime.current = transition.target;
2853
+ break;
2854
+ }
2855
+ }
2856
+ runtime.triggers.clear();
2857
+ }
2858
+ return fired;
2859
+ }
2860
+ function checkInvariants(world, ir) {
2861
+ const violations = [];
2862
+ for (const predicate of ir.predicates) {
2863
+ if (predicate.kind !== "invariant") continue;
2864
+ if (!evaluateGuard(predicate.expression, world.state)) violations.push(predicate.id);
2865
+ }
2866
+ return violations;
2867
+ }
2868
+ function runExactTrace(ir, scenario) {
2869
+ const world = { state: {}, machines: /* @__PURE__ */ new Map() };
2870
+ for (const field of ir.state) world.state[field.key] = field.baseline;
2871
+ for (const machine of ir.machines) {
2872
+ const inputs = {};
2873
+ for (const input of machine.inputs) {
2874
+ inputs[input.name] = input.inputType === "trigger" ? false : input.baseline;
2875
+ }
2876
+ world.machines.set(machine.name, {
2877
+ name: machine.name,
2878
+ current: machine.initialState,
2879
+ inputs,
2880
+ triggers: /* @__PURE__ */ new Set()
2881
+ });
2882
+ }
2883
+ const preconditionResults = ir.predicates.filter((p) => p.kind === "precondition").map((p) => ({ id: p.id, holds: evaluateGuard(p.expression, world.state) }));
2884
+ const initial = snapshot(world);
2885
+ const steps = [];
2886
+ let valid = preconditionResults.every((r) => r.holds);
2887
+ scenario.forEach((step, ordinal) => {
2888
+ const effects = [];
2889
+ const emitted = [];
2890
+ let transitions = [];
2891
+ switch (step.kind) {
2892
+ case "set-input": {
2893
+ const machine = world.machines.get(step.machine);
2894
+ if (!machine || !(step.input in machine.inputs)) {
2895
+ throw new HSIAdmissionError(
2896
+ "unknown-slot",
2897
+ `scenario step ${ordinal}: unknown machine input ${step.machine}.${step.input}`
2898
+ );
2899
+ }
2900
+ machine.inputs[step.input] = step.value;
2901
+ transitions = evaluateTransitions(world, ir);
2902
+ break;
2903
+ }
2904
+ case "fire-trigger": {
2905
+ const machine = world.machines.get(step.machine);
2906
+ const declared = ir.machines.find((m) => m.name === step.machine)?.inputs.find((i) => i.name === step.input && i.inputType === "trigger");
2907
+ if (!machine || !declared) {
2908
+ throw new HSIAdmissionError(
2909
+ "unknown-slot",
2910
+ `scenario step ${ordinal}: unknown trigger ${step.machine}.${step.input}`
2911
+ );
2912
+ }
2913
+ machine.triggers.add(step.input);
2914
+ transitions = evaluateTransitions(world, ir);
2915
+ break;
2916
+ }
2917
+ case "fire-event": {
2918
+ const handler = ir.eventHandlers.find((h) => h.event === step.event);
2919
+ if (!handler) {
2920
+ throw new HSIAdmissionError(
2921
+ "unknown-slot",
2922
+ `scenario step ${ordinal}: no handler for event "${step.event}"`
2923
+ );
2924
+ }
2925
+ runEffects(handler.effects, world, effects, emitted);
2926
+ break;
2927
+ }
2928
+ }
2929
+ const invariantViolations = checkInvariants(world, ir);
2930
+ if (invariantViolations.length > 0) valid = false;
2931
+ steps.push({
2932
+ ordinal,
2933
+ step,
2934
+ transitions,
2935
+ effects,
2936
+ emitted,
2937
+ invariantViolations,
2938
+ stateDigest: snapshot(world).stateDigest
2939
+ });
2940
+ });
2941
+ const final = snapshot(world);
2942
+ const traceWithoutDigest = {
2943
+ schemaVersion: HSI_TRACE_SCHEMA_VERSION,
2944
+ kind: "HSITrace",
2945
+ worldDigest: ir.provenance.deterministicDigest,
2946
+ preconditionResults,
2947
+ initial,
2948
+ steps,
2949
+ final,
2950
+ valid
2951
+ };
2952
+ return { ...traceWithoutDigest, deterministicDigest: hsiSha256(traceWithoutDigest) };
2953
+ }
2954
+ function splitFor(nodeId, worldDigest) {
2955
+ const digest = createHash("sha256").update(`${nodeId}|${worldDigest}`).digest();
2956
+ return digest[0] % 4 === 0 ? "eval" : "train";
2957
+ }
2958
+ function collectAssignTargets(effects, into, reads) {
2959
+ for (const effect of effects) {
2960
+ if (effect.kind === "assign") {
2961
+ into.add(effect.target);
2962
+ const stack = [effect.value];
2963
+ while (stack.length > 0) {
2964
+ const node = stack.pop();
2965
+ if (node.kind === "Identifier") reads.add(node.name);
2966
+ else if (node.kind === "BinaryExpression") stack.push(node.left, node.right);
2967
+ else if (node.kind === "UnaryExpression") stack.push(node.argument);
2968
+ else if (node.kind === "MemberExpression") stack.push(node.object);
2969
+ else if (node.kind === "CallExpression") stack.push(...node.arguments);
2970
+ }
2971
+ } else if (effect.kind === "branch") {
2972
+ collectAssignTargets(effect.then, into, reads);
2973
+ collectAssignTargets(effect.else, into, reads);
2974
+ }
2975
+ }
2976
+ }
2977
+ function projectLearningGraph(ir) {
2978
+ const worldDigest = ir.provenance.deterministicDigest;
2979
+ const nodes = [];
2980
+ const edges = [];
2981
+ const addNode = (node) => {
2982
+ nodes.push({ ...node, split: splitFor(node.id, worldDigest) });
2983
+ };
2984
+ const addEdge = (edgeType, from, to, label) => {
2985
+ const edge = { id: `edge:${edgeType}:${from}->${to}`, edgeType, from, to };
2986
+ if (label !== void 0) edge.label = label;
2987
+ edges.push(edge);
2988
+ };
2989
+ const worldId = `entity:${ir.world.name}`;
2990
+ addNode({ id: worldId, nodeType: "entity", baseline: null, unknowns: [] });
2991
+ for (const entity of ir.entities) {
2992
+ addNode({
2993
+ id: entity.id,
2994
+ nodeType: "entity",
2995
+ baseline: null,
2996
+ unknowns: entity.opacity === "unknown" ? ["opacity"] : [],
2997
+ sourceSpan: entity.sourceSpan
2998
+ });
2999
+ addEdge("contains", worldId, entity.id);
3000
+ }
3001
+ for (const field of ir.state) {
3002
+ addNode({
3003
+ id: field.id,
3004
+ nodeType: "state",
3005
+ baseline: field.baseline,
3006
+ unknowns: [],
3007
+ sourceSpan: field.sourceSpan
3008
+ });
3009
+ addEdge("contains", worldId, field.id);
3010
+ }
3011
+ for (const rule of ir.observationPolicy) {
3012
+ addNode({
3013
+ id: rule.id,
3014
+ nodeType: "observation",
3015
+ baseline: null,
3016
+ unknowns: rule.access === "unknown" ? ["access"] : []
3017
+ });
3018
+ addEdge("observes", `entity:${rule.observer}`, rule.id, rule.access);
3019
+ addEdge("refers-to", rule.id, `entity:${rule.observed}`);
3020
+ for (const mediator of rule.mediators) {
3021
+ addEdge("refers-to", rule.id, `entity:${mediator}`, "mediator");
3022
+ }
3023
+ }
3024
+ for (const handler of ir.eventHandlers) {
3025
+ addNode({ id: handler.id, nodeType: "event", baseline: null, unknowns: [], sourceSpan: handler.sourceSpan });
3026
+ const targets = /* @__PURE__ */ new Set();
3027
+ const reads = /* @__PURE__ */ new Set();
3028
+ collectAssignTargets(handler.effects, targets, reads);
3029
+ for (const target of [...targets].sort()) {
3030
+ addEdge("affects", handler.id, `state:world.${target}`);
3031
+ }
3032
+ for (const read of [...reads].sort()) {
3033
+ if (!targets.has(read)) addEdge("requires", handler.id, `state:world.${read}`);
3034
+ }
3035
+ }
3036
+ for (const machine of ir.machines) {
3037
+ for (const transition of machine.transitions) {
3038
+ addNode({
3039
+ id: transition.id,
3040
+ nodeType: "action",
3041
+ baseline: null,
3042
+ unknowns: [],
3043
+ sourceSpan: transition.sourceSpan
3044
+ });
3045
+ for (const read of transition.reads) {
3046
+ addEdge("requires", transition.id, `input:${machine.name}.${read}`);
3047
+ }
3048
+ addEdge("causes", transition.id, `machineState:${machine.name}.${transition.target}`);
3049
+ if (transition.from !== "any") {
3050
+ addEdge("precedes", `machineState:${machine.name}.${transition.from}`, transition.id);
3051
+ }
3052
+ }
3053
+ for (const stateName of machine.states) {
3054
+ addNode({ id: `machineState:${machine.name}.${stateName}`, nodeType: "state", baseline: null, unknowns: [] });
3055
+ addEdge("contains", worldId, `machineState:${machine.name}.${stateName}`);
3056
+ }
3057
+ for (const input of machine.inputs) {
3058
+ addNode({ id: input.id, nodeType: "state", baseline: input.baseline, unknowns: [] });
3059
+ addEdge("contains", worldId, input.id);
3060
+ }
3061
+ }
3062
+ for (const predicate of ir.predicates) {
3063
+ addNode({
3064
+ id: predicate.id,
3065
+ nodeType: "objective",
3066
+ baseline: null,
3067
+ unknowns: [],
3068
+ sourceSpan: predicate.sourceSpan
3069
+ });
3070
+ for (const read of predicate.reads) {
3071
+ addEdge("refers-to", predicate.id, `state:world.${read}`);
3072
+ }
3073
+ }
3074
+ nodes.sort((a, b) => a.id.localeCompare(b.id));
3075
+ edges.sort((a, b) => a.id.localeCompare(b.id));
3076
+ const graphWithoutDigest = {
3077
+ schemaVersion: HSI_LEARNING_GRAPH_SCHEMA_VERSION,
3078
+ kind: "HSILearningGraph",
3079
+ worldDigest,
3080
+ emittedFrom: worldDigest,
3081
+ nodes,
3082
+ edges,
3083
+ interventions: [
3084
+ "intervention:flip-opacity",
3085
+ "intervention:raise-guard-threshold"
3086
+ ]
3087
+ };
3088
+ return { ...graphWithoutDigest, deterministicDigest: hsiSha256(graphWithoutDigest) };
3089
+ }
3090
+
3091
+ // src/compiler/HSIAuditVerifier.ts
3092
+ function renamed(name, map) {
3093
+ return map[name] ?? name;
3094
+ }
3095
+ function renameExpression(expr, map) {
3096
+ switch (expr.type) {
3097
+ case "Identifier":
3098
+ expr.name = renamed(expr.name, map);
3099
+ return;
3100
+ case "BinaryExpression":
3101
+ renameExpression(expr.left, map);
3102
+ renameExpression(expr.right, map);
3103
+ return;
3104
+ case "UnaryExpression":
3105
+ renameExpression(expr.argument, map);
3106
+ return;
3107
+ case "MemberExpression":
3108
+ renameExpression(expr.object, map);
3109
+ return;
3110
+ case "CallExpression":
3111
+ renameExpression(expr.callee, map);
3112
+ for (const arg of expr.arguments) renameExpression(arg, map);
3113
+ return;
3114
+ default:
3115
+ return;
3116
+ }
3117
+ }
3118
+ function renameStatements(statements, map) {
3119
+ for (const stmt of statements) {
3120
+ switch (stmt.type) {
3121
+ case "Assignment": {
3122
+ const target = stmt.target.startsWith("state.") ? stmt.target.slice("state.".length) : stmt.target;
3123
+ const prefix = stmt.target.startsWith("state.") ? "state." : "";
3124
+ stmt.target = `${prefix}${renamed(target, map)}`;
3125
+ renameExpression(stmt.value, map);
3126
+ break;
3127
+ }
3128
+ case "IfStatement":
3129
+ renameExpression(stmt.condition, map);
3130
+ renameStatements(stmt.consequent, map);
3131
+ renameStatements(stmt.alternate ?? [], map);
3132
+ break;
3133
+ }
3134
+ }
3135
+ }
3136
+ function renameRawExpr(expr, map) {
3137
+ return expr.replace(/[A-Za-z_][A-Za-z0-9_]*/g, (token) => renamed(token, map));
3138
+ }
3139
+ function renameComposition(composition, map) {
3140
+ for (const template of composition.templates ?? []) {
3141
+ template.name = renamed(template.name, map);
3142
+ }
3143
+ for (const obj of composition.objects ?? []) {
3144
+ obj.name = renamed(obj.name, map);
3145
+ if (obj.template !== void 0) obj.template = renamed(obj.template, map);
3146
+ }
3147
+ const connections = composition.connections;
3148
+ for (const conn of connections ?? []) {
3149
+ conn.from = renamed(conn.from, map);
3150
+ conn.to = renamed(conn.to, map);
3151
+ }
3152
+ for (const prop of composition.state?.properties ?? []) {
3153
+ prop.key = renamed(prop.key, map);
3154
+ }
3155
+ const logic = composition.logic;
3156
+ for (const handler of logic?.handlers ?? []) {
3157
+ renameStatements(handler.body, map);
3158
+ }
3159
+ for (const machine of composition.stateMachines ?? []) {
3160
+ machine.name = renamed(machine.name, map);
3161
+ machine.initialState = renamed(machine.initialState, map);
3162
+ const renamedStates = {};
3163
+ for (const [stateName, stateNode] of Object.entries(machine.states ?? {})) {
3164
+ stateNode.name = renamed(stateName, map);
3165
+ renamedStates[renamed(stateName, map)] = stateNode;
3166
+ for (const t of stateNode.transitions ?? []) {
3167
+ if (t.from && t.from !== "any") t.from = renamed(t.from, map);
3168
+ t.target = renamed(t.target, map);
3169
+ if (t.condition) renameExpression(t.condition, map);
3170
+ for (const cond of t.conditions ?? []) cond.parameter = renamed(cond.parameter, map);
3171
+ }
3172
+ }
3173
+ machine.states = renamedStates;
3174
+ for (const input of machine.inputs ?? []) {
3175
+ input.name = renamed(input.name, map);
3176
+ }
3177
+ for (const t of machine.transitions ?? []) {
3178
+ if (t.from && t.from !== "any") t.from = renamed(t.from, map);
3179
+ t.target = renamed(t.target, map);
3180
+ if (t.condition) renameExpression(t.condition, map);
3181
+ for (const cond of t.conditions ?? []) cond.parameter = renamed(cond.parameter, map);
3182
+ }
3183
+ }
3184
+ if (composition.contract) {
3185
+ for (const clause of [...composition.contract.preconditions, ...composition.contract.invariants]) {
3186
+ clause.expr = renameRawExpr(clause.expr, map);
3187
+ }
3188
+ }
3189
+ for (const achievement of composition.achievements ?? []) {
3190
+ renameExpression(achievement.condition, map);
3191
+ }
3192
+ }
3193
+ var ID_TOKEN_PATTERN = /[A-Za-z_][A-Za-z0-9_]*/g;
3194
+ function renameIdString(id, map) {
3195
+ return id.replace(ID_TOKEN_PATTERN, (token) => renamed(token, map));
3196
+ }
3197
+ function renameTrace(trace, map) {
3198
+ const renameSnapshot = (snap) => {
3199
+ const state = {};
3200
+ for (const [key, value] of Object.entries(snap.state)) state[renamed(key, map)] = value;
3201
+ const machineStates = {};
3202
+ for (const [machine, current] of Object.entries(snap.machineStates)) {
3203
+ machineStates[renamed(machine, map)] = renamed(current, map);
3204
+ }
3205
+ return { state, machineStates, stateDigest: hsiSha256({ state: sortRecord(state), machineStates: sortRecord(machineStates) }) };
3206
+ };
3207
+ const sortRecord = (record) => {
3208
+ const out = {};
3209
+ for (const key of Object.keys(record).sort()) out[key] = record[key];
3210
+ return out;
3211
+ };
3212
+ const stepsRenamed = trace.steps.map((step) => {
3213
+ const scenario = step.step.kind === "fire-event" ? step.step : step.step.kind === "set-input" ? { kind: "set-input", machine: renamed(step.step.machine, map), input: renamed(step.step.input, map), value: step.step.value } : { kind: "fire-trigger", machine: renamed(step.step.machine, map), input: renamed(step.step.input, map) };
3214
+ return {
3215
+ ...step,
3216
+ step: scenario,
3217
+ transitions: step.transitions.map((t) => ({
3218
+ machine: renamed(t.machine, map),
3219
+ transitionId: renameIdString(t.transitionId, map),
3220
+ from: renamed(t.from, map),
3221
+ to: renamed(t.to, map)
3222
+ })),
3223
+ effects: step.effects.map((e) => ({ ...e, target: renamed(e.target, map), sourceId: renameIdString(e.sourceId, map) })),
3224
+ invariantViolations: step.invariantViolations.map((id) => renameIdString(id, map)),
3225
+ stateDigest: ""
3226
+ };
3227
+ });
3228
+ const initial = renameSnapshot(trace.initial);
3229
+ const final = renameSnapshot(trace.final);
3230
+ const traceWithoutDigest = {
3231
+ schemaVersion: trace.schemaVersion,
3232
+ kind: trace.kind,
3233
+ worldDigest: "",
3234
+ preconditionResults: trace.preconditionResults.map((r) => ({ id: renameIdString(r.id, map), holds: r.holds })),
3235
+ initial,
3236
+ steps: stepsRenamed,
3237
+ final,
3238
+ valid: trace.valid
3239
+ };
3240
+ return { ...traceWithoutDigest, deterministicDigest: "" };
3241
+ }
3242
+ function behavioralProjection(trace) {
3243
+ return {
3244
+ preconditionResults: trace.preconditionResults,
3245
+ initial: { state: trace.initial.state, machineStates: trace.initial.machineStates },
3246
+ steps: trace.steps.map((s) => ({
3247
+ ordinal: s.ordinal,
3248
+ step: s.step,
3249
+ transitions: s.transitions,
3250
+ effects: s.effects,
3251
+ emitted: s.emitted,
3252
+ invariantViolations: s.invariantViolations
3253
+ })),
3254
+ final: { state: trace.final.state, machineStates: trace.final.machineStates },
3255
+ valid: trace.valid
3256
+ };
3257
+ }
3258
+ function reorderComposition(composition) {
3259
+ composition.templates = [...composition.templates ?? []].reverse();
3260
+ composition.objects = [...composition.objects ?? []].reverse();
3261
+ const holder = composition;
3262
+ if (holder.connections) holder.connections = [...holder.connections].reverse();
3263
+ if (composition.state?.properties) {
3264
+ composition.state.properties = [...composition.state.properties].reverse();
3265
+ }
3266
+ if (composition.contract) {
3267
+ composition.contract.invariants = [...composition.contract.invariants].reverse();
3268
+ }
3269
+ }
3270
+ function applyIntervention(composition, intervention) {
3271
+ if (intervention.kind === "set-opacity") {
3272
+ const obj = (composition.objects ?? []).find((o) => o.name === intervention.entity);
3273
+ if (!obj) {
3274
+ throw new HSIAdmissionError("admission-skewed", `intervention targets unknown entity "${intervention.entity}"`);
3275
+ }
3276
+ const existing = obj.properties.findIndex((p) => p.key === "opaque");
3277
+ if (existing >= 0) obj.properties.splice(existing, 1);
3278
+ if (intervention.opaque !== void 0) {
3279
+ obj.properties.push({ type: "ObjectProperty", key: "opaque", value: intervention.opaque });
3280
+ } else {
3281
+ const template = (composition.templates ?? []).find((t) => t.name === obj.template);
3282
+ if (template) {
3283
+ template.properties = (template.properties ?? []).filter((p) => p.key !== "opaque");
3284
+ }
3285
+ }
3286
+ return;
3287
+ }
3288
+ const machine = (composition.stateMachines ?? []).find((m) => m.name === intervention.machine);
3289
+ if (!machine) {
3290
+ throw new HSIAdmissionError("admission-skewed", `intervention targets unknown machine "${intervention.machine}"`);
3291
+ }
3292
+ const transitions = [
3293
+ ...machine.transitions ?? [],
3294
+ ...Object.values(machine.states ?? {}).flatMap((s) => s.transitions ?? [])
3295
+ ];
3296
+ const transition = transitions.find(
3297
+ (t) => (t.from ?? "") === intervention.fromState && t.target === intervention.toState
3298
+ );
3299
+ if (!transition) {
3300
+ throw new HSIAdmissionError(
3301
+ "admission-skewed",
3302
+ `intervention targets unknown transition ${intervention.fromState} -> ${intervention.toState}`
3303
+ );
3304
+ }
3305
+ if (transition.condition?.type === "BinaryExpression" && transition.condition.right.type === "Literal") {
3306
+ transition.condition.right.value = intervention.value;
3307
+ }
3308
+ for (const cond of transition.conditions ?? []) {
3309
+ if (typeof cond.value === "number") cond.value = intervention.value;
3310
+ }
3311
+ }
3312
+ function generateAuditCases(ir) {
3313
+ const cases = [
3314
+ {
3315
+ id: "audit:admission-empty",
3316
+ kind: "admission-empty",
3317
+ description: "An empty composition (no entities, no state) must fail admission.",
3318
+ expectation: "HSIAdmissionError(empty-world)"
3319
+ },
3320
+ {
3321
+ id: "audit:admission-missing-archetype",
3322
+ kind: "admission-skewed",
3323
+ description: "An object using an undeclared template must fail admission.",
3324
+ expectation: "HSIAdmissionError(unknown-archetype)"
3325
+ },
3326
+ {
3327
+ id: "audit:admission-dangling-relation",
3328
+ kind: "admission-skewed",
3329
+ description: "A connection to an undeclared entity must fail admission.",
3330
+ expectation: "HSIAdmissionError(unknown-relation-endpoint)"
3331
+ },
3332
+ {
3333
+ id: "audit:alpha-rename",
3334
+ kind: "alpha-rename",
3335
+ description: "Consistent renaming of declared names preserves behavior (trace modulo names).",
3336
+ expectation: "behavioralProjection(renameTrace(base)) === behavioralProjection(trace(renamed))"
3337
+ },
3338
+ {
3339
+ id: "audit:declaration-reorder",
3340
+ kind: "declaration-reorder",
3341
+ description: "Reordering independent declarations yields a byte-identical IR.",
3342
+ expectation: "deterministicDigest(base) === deterministicDigest(reordered)"
3343
+ },
3344
+ {
3345
+ id: "audit:regenerate-determinism",
3346
+ kind: "regenerate-determinism",
3347
+ description: "Re-lowering and re-tracing from the same source is byte-identical.",
3348
+ expectation: "all artifact digests equal across two independent regenerations"
3349
+ }
3350
+ ];
3351
+ const opaqueMediator = ir.entities.find(
3352
+ (e) => e.opacity === "opaque" && ir.observationPolicy.some((r) => r.mediators.includes(e.name) && r.access === "blocked")
3353
+ );
3354
+ if (opaqueMediator) {
3355
+ cases.push({
3356
+ id: "audit:counterfactual-opacity",
3357
+ kind: "counterfactual-intervention",
3358
+ description: `Making "${opaqueMediator.name}" transparent must change at least one observation access verdict.`,
3359
+ intervention: { kind: "set-opacity", id: "intervention:flip-opacity", entity: opaqueMediator.name, opacity: "transparent" },
3360
+ expectation: "observationPolicy access verdicts differ from base IR"
3361
+ });
3362
+ }
3363
+ const guardedTransition = ir.machines.flatMap((m) => m.transitions.map((t) => ({ machine: m.name, t }))).find(({ t }) => t.guard?.kind === "BinaryExpression" && t.guard.right.kind === "Literal" && typeof t.guard.right.value === "number");
3364
+ if (guardedTransition) {
3365
+ cases.push({
3366
+ id: "audit:counterfactual-guard",
3367
+ kind: "counterfactual-intervention",
3368
+ description: `Raising the numeric guard of ${guardedTransition.t.id} beyond scenario inputs must change the exact trace.`,
3369
+ intervention: {
3370
+ kind: "set-transition-guard-literal",
3371
+ id: "intervention:raise-guard-threshold",
3372
+ machine: guardedTransition.machine,
3373
+ transitionId: guardedTransition.t.id,
3374
+ value: 1e6
3375
+ },
3376
+ expectation: "trace deterministicDigest differs and at least one step fires different transitions"
3377
+ });
3378
+ }
3379
+ return cases;
3380
+ }
3381
+ function clone(value) {
3382
+ return structuredClone(value);
3383
+ }
3384
+ function expectAdmissionFailure(fn, expectedCode) {
3385
+ try {
3386
+ fn();
3387
+ return "fail";
3388
+ } catch (error) {
3389
+ return error instanceof HSIAdmissionError && error.code === expectedCode ? "pass" : "fail";
3390
+ }
3391
+ }
3392
+ function runHSIAudit(input) {
3393
+ const { composition, sourceText, scenario, renameMap } = input;
3394
+ const baseIR = lowerCompositionToHSIIR(clone(composition), { sourceText });
3395
+ const baseTrace = runExactTrace(baseIR, scenario);
3396
+ const cases = generateAuditCases(baseIR);
3397
+ const checks = [];
3398
+ for (const auditCase of cases) {
3399
+ let status = "fail";
3400
+ let detail = auditCase.expectation;
3401
+ try {
3402
+ switch (auditCase.id) {
3403
+ case "audit:admission-empty": {
3404
+ const empty = {
3405
+ ...clone(composition),
3406
+ name: "EmptyWorld",
3407
+ templates: [],
3408
+ objects: [],
3409
+ state: void 0,
3410
+ stateMachines: [],
3411
+ contract: void 0,
3412
+ achievements: []
3413
+ };
3414
+ empty.connections = [];
3415
+ empty.logic = void 0;
3416
+ status = expectAdmissionFailure(() => lowerCompositionToHSIIR(empty), "empty-world");
3417
+ break;
3418
+ }
3419
+ case "audit:admission-missing-archetype": {
3420
+ const skewed = clone(composition);
3421
+ if (skewed.objects.length === 0) throw new Error("fixture has no objects");
3422
+ skewed.objects[0].template = "GhostTemplate";
3423
+ status = expectAdmissionFailure(() => lowerCompositionToHSIIR(skewed), "unknown-archetype");
3424
+ break;
3425
+ }
3426
+ case "audit:admission-dangling-relation": {
3427
+ const skewed = clone(composition);
3428
+ const holder = skewed;
3429
+ holder.connections = [...holder.connections ?? [], { from: "NoSuchEntity", to: "AlsoMissing" }];
3430
+ status = expectAdmissionFailure(() => lowerCompositionToHSIIR(skewed), "unknown-relation-endpoint");
3431
+ break;
3432
+ }
3433
+ case "audit:alpha-rename": {
3434
+ const renamedComposition = clone(composition);
3435
+ renameComposition(renamedComposition, renameMap);
3436
+ const renamedIR = lowerCompositionToHSIIR(renamedComposition);
3437
+ const renamedScenario = scenario.map(
3438
+ (step) => step.kind === "fire-event" ? step : step.kind === "set-input" ? { ...step, machine: renameMap[step.machine] ?? step.machine, input: renameMap[step.input] ?? step.input } : { ...step, machine: renameMap[step.machine] ?? step.machine, input: renameMap[step.input] ?? step.input }
3439
+ );
3440
+ const renamedTrace = runExactTrace(renamedIR, renamedScenario);
3441
+ const expected = hsiStableStringify(behavioralProjection(renameTrace(baseTrace, renameMap)));
3442
+ const actual = hsiStableStringify(behavioralProjection(renamedTrace));
3443
+ status = expected === actual ? "pass" : "fail";
3444
+ if (status === "fail") detail = "renamed trace diverged from rename-projected base trace";
3445
+ break;
3446
+ }
3447
+ case "audit:declaration-reorder": {
3448
+ const reordered = clone(composition);
3449
+ reorderComposition(reordered);
3450
+ const reorderedIR = lowerCompositionToHSIIR(reordered, { sourceText });
3451
+ status = reorderedIR.provenance.deterministicDigest === baseIR.provenance.deterministicDigest ? "pass" : "fail";
3452
+ if (status === "fail") detail = "reordered IR digest differs from base IR digest";
3453
+ break;
3454
+ }
3455
+ case "audit:regenerate-determinism": {
3456
+ const secondIR = lowerCompositionToHSIIR(clone(composition), { sourceText });
3457
+ const secondTrace = runExactTrace(secondIR, scenario);
3458
+ status = secondIR.provenance.deterministicDigest === baseIR.provenance.deterministicDigest && secondTrace.deterministicDigest === baseTrace.deterministicDigest ? "pass" : "fail";
3459
+ if (status === "fail") detail = "regeneration produced different digests";
3460
+ break;
3461
+ }
3462
+ case "audit:counterfactual-opacity": {
3463
+ const intervention = auditCase.intervention;
3464
+ if (intervention.kind !== "set-opacity") throw new Error("case/intervention mismatch");
3465
+ const intervened = clone(composition);
3466
+ applyIntervention(intervened, {
3467
+ id: intervention.id,
3468
+ kind: "set-opacity",
3469
+ entity: intervention.entity,
3470
+ opaque: intervention.opacity === "opaque" ? true : intervention.opacity === "transparent" ? false : void 0
3471
+ });
3472
+ const intervenedIR = lowerCompositionToHSIIR(intervened);
3473
+ const baseAccess = hsiStableStringify(baseIR.observationPolicy);
3474
+ const newAccess = hsiStableStringify(intervenedIR.observationPolicy);
3475
+ status = baseAccess !== newAccess ? "pass" : "fail";
3476
+ if (status === "fail") detail = "opacity intervention did not change any observation verdict";
3477
+ break;
3478
+ }
3479
+ case "audit:counterfactual-guard": {
3480
+ const intervention = auditCase.intervention;
3481
+ if (intervention.kind !== "set-transition-guard-literal") throw new Error("case/intervention mismatch");
3482
+ const parsed = /transition:([^.]+)\.([^-]+)->([^#]+)#/.exec(intervention.transitionId);
3483
+ if (!parsed) throw new Error(`unparseable transition id ${intervention.transitionId}`);
3484
+ const intervened = clone(composition);
3485
+ applyIntervention(intervened, {
3486
+ id: intervention.id,
3487
+ kind: "set-guard-literal",
3488
+ machine: parsed[1],
3489
+ fromState: parsed[2],
3490
+ toState: parsed[3],
3491
+ value: intervention.value
3492
+ });
3493
+ const intervenedIR = lowerCompositionToHSIIR(intervened);
3494
+ const intervenedTrace = runExactTrace(intervenedIR, scenario);
3495
+ const digestDiffers = intervenedTrace.deterministicDigest !== baseTrace.deterministicDigest;
3496
+ const stepDiffers = baseTrace.steps.some(
3497
+ (step, i) => hsiStableStringify(step.transitions) !== hsiStableStringify(intervenedTrace.steps[i]?.transitions)
3498
+ );
3499
+ status = digestDiffers && stepDiffers ? "pass" : "fail";
3500
+ if (status === "fail") detail = "guard intervention did not change the exact trace";
3501
+ break;
3502
+ }
3503
+ default:
3504
+ detail = `unrecognized audit case ${auditCase.id}`;
3505
+ }
3506
+ } catch (error) {
3507
+ status = "fail";
3508
+ detail = `${detail} \u2014 threw: ${error.message}`;
3509
+ }
3510
+ checks.push({ caseId: auditCase.id, status, detail });
3511
+ }
3512
+ const overall = checks.every((c) => c.status === "pass") ? "pass" : "fail";
3513
+ const manifestWithoutDigest = {
3514
+ schemaVersion: HSI_AUDIT_SCHEMA_VERSION,
3515
+ kind: "HSIAuditManifest",
3516
+ worldDigest: baseIR.provenance.deterministicDigest,
3517
+ verifier: "HSIAuditVerifier",
3518
+ checks,
3519
+ overall
3520
+ };
3521
+ return { ...manifestWithoutDigest, deterministicDigest: hsiSha256(manifestWithoutDigest) };
3522
+ }
3523
+
3524
+ // src/compiler/index.ts
1587
3525
  init_PlatformConditionalCompilerMixin();
1588
3526
 
1589
3527
  // src/compiler/authority/AuthoritySymbolGraph.ts
@@ -3180,7 +5118,7 @@ async function runTier3CpuDirectExecutor(op) {
3180
5118
  }
3181
5119
  async function runTier1BrowserSnn(op) {
3182
5120
  try {
3183
- const snnWebgpu = await import('../dist-ZBUKU2JG.js');
5121
+ const snnWebgpu = await import('../dist-ZEZXRCBG.js');
3184
5122
  const { GPUContext, LIFSimulator, DEFAULT_LIF_PARAMS } = snnWebgpu;
3185
5123
  const ctx = new GPUContext();
3186
5124
  await ctx.initialize();
@@ -3285,8 +5223,8 @@ async function sha256Hex(input) {
3285
5223
  const digest = await subtle.digest("SHA-256", new TextEncoder().encode(input));
3286
5224
  return bytesToHex(new Uint8Array(digest));
3287
5225
  }
3288
- const { createHash } = await import('crypto');
3289
- return createHash("sha256").update(input).digest("hex");
5226
+ const { createHash: createHash4 } = await import('crypto');
5227
+ return createHash4("sha256").update(input).digest("hex");
3290
5228
  }
3291
5229
  function bytesToHex(bytes) {
3292
5230
  return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
@@ -4099,6 +6037,18 @@ platformPluginRegistry.register(new AndroidARCorePlugin());
4099
6037
  var SOVEREIGN_TARGETS = [
4100
6038
  "webgpu",
4101
6039
  // WebGPUCompiler → WGSL compute+render shaders on our own WebGPU device (WebGPURenderer)
6040
+ "audio",
6041
+ // SpatialAudioCompiler → our own Web Audio graph (HRTF PannerNode + Convolver reverb + filters); no third-party audio engine
6042
+ "desktop-gpu",
6043
+ // DesktopGPUCompiler → standalone Rust wgpu project (Vulkan/Metal/DX12), renders the scene offscreen on the machine's own GPU; no browser, no third-party engine. Verified on Jetson Orin/Vulkan.
6044
+ "pathtrace",
6045
+ // PathTracerCompiler → standalone Rust wgpu COMPUTE path tracer (cosine-weighted GI, emissive area lights, multi-sample) → tonemapped PNG; our own tracer, no Cycles/OptiX. Verified on Jetson Orin/Vulkan.
6046
+ "pathtrace-cpu",
6047
+ // CpuPathTracer → the no-GPU fallback: pure-TS CPU path tracer (same algorithm + shared scene extraction) → PNG. Runs offline GI anywhere Node/JS runs (server/CI/old device). The "runs anywhere / no-WebGPU compute fallback" gap.
6048
+ "media",
6049
+ // MediaPipelineCompiler → renders an animated turntable of the scene (CPU) and encodes it to an APNG with our OWN encoder (node:zlib only, no ffmpeg/codec/muxer). The video/media-pipeline gap; a moving picture from a .holo.
6050
+ "physics-sim",
6051
+ // ComputePhysicsCompiler → WGSL COMPUTE rigid-body solver (gravity + sphere/sphere + sphere/AABB collisions, restitution, double-buffered) that steps on the GPU + renders the settled state. Our own solver, no third-party physics engine. Consumes the collider vocabulary; the DYNAMICS layer on top of PhysicsColliderCompiler. Verified on Jetson Orin/Vulkan.
4102
6052
  "character-webgpu",
4103
6053
  // CharacterWebGPUCompiler → authored .holo character → CharacterDrawSpec run by our renderCharacter (sovereign skinned-character path)
4104
6054
  "nir",
@@ -4140,6 +6090,8 @@ var BRIDGE_TARGETS = [
4140
6090
  // Meta Quest (Horizon OS / Meta Spatial SDK) — emits a native Kotlin app to Meta's runtime
4141
6091
  "ios",
4142
6092
  "visionos",
6093
+ "r3f",
6094
+ // SceneIR -> generated TSX shell consumed by React Three Fiber; HoloScript owns SceneIR, R3F is the host runtime bridge
4143
6095
  "usd",
4144
6096
  "usdz",
4145
6097
  "fmu",
@@ -4320,9 +6272,69 @@ var SOVEREIGN_ENGINES = [
4320
6272
  tests: true,
4321
6273
  promoted: false,
4322
6274
  note: "Signed-distance-field \u2192 raymarch WGSL/GLSL. Native GPU renderer codegen."
6275
+ },
6276
+ {
6277
+ id: "spatial-audio",
6278
+ name: "SpatialAudioCompiler",
6279
+ file: "packages/core/src/compiler/SpatialAudioCompiler.ts",
6280
+ kind: "compiler",
6281
+ maturity: "real",
6282
+ tests: true,
6283
+ promoted: false,
6284
+ note: "The audio peer of WebGPU: emits our OWN Web Audio graph (HRTF PannerNode + Convolver reverb from synthesized rt60 impulses + directivity/occlusion/portal filters) from @audio_source/@audio_listener/@reverb_zone/@audio_material/@audio_occlusion/@audio_portal traits. Sovereign \u2014 no FMOD/Wwise/Resonance. Fills the #1 spatial-computing gap (no audio compiler existed)."
6285
+ },
6286
+ {
6287
+ id: "desktop-gpu",
6288
+ name: "DesktopGPUCompiler",
6289
+ file: "packages/core/src/compiler/DesktopGPUCompiler.ts",
6290
+ kind: "compiler",
6291
+ maturity: "real",
6292
+ tests: true,
6293
+ promoted: false,
6294
+ note: `Sovereign native-desktop GPU: emits a self-contained Rust wgpu project (Vulkan/Metal/DX12) that renders the scene offscreen to a PNG on the machine's OWN GPU \u2014 standalone, no browser, no third-party engine. WebGPU is browser/runtime-bound; this is the "runs standalone at native perf" gap. Matrices computed in the compiler; geometry generators + wgpu host emitted. VERIFIED on real hardware: Jetson Orin (Tegra) via Vulkan rendered a 6-object scene offscreen to PNG (adapter=NVIDIA Tegra Orin, backend=Vulkan). Consumes the same geometry-registry + geometry-purpose vocabulary as render/physics/audio.`
6295
+ },
6296
+ {
6297
+ id: "path-tracer",
6298
+ name: "PathTracerCompiler",
6299
+ file: "packages/core/src/compiler/PathTracerCompiler.ts",
6300
+ kind: "compiler",
6301
+ maturity: "real",
6302
+ tests: true,
6303
+ promoted: false,
6304
+ note: "Sovereign OFFLINE path-traced render \u2014 the film-grade-still gap the rasterizers (WebGPU/desktop-gpu) do not fill. Emits a self-contained Rust wgpu COMPUTE program: our OWN GPU path tracer (no Cycles/OptiX) that traces cosine-weighted diffuse bounces against analytic sphere/box primitives, accumulates many samples, and tonemaps to PNG. Global illumination \u2014 soft shadows, colour bleeding, emissive area lights. VERIFIED on Jetson Orin (Tegra/Vulkan): a Cornell-box scene rendered with visible GI colour-bleed + soft shadows. Fifth consumer of the shared geometry-registry + geometry-purpose vocabulary."
6305
+ },
6306
+ {
6307
+ id: "cpu-path-tracer",
6308
+ name: "CpuPathTracer",
6309
+ file: "packages/core/src/compiler/CpuPathTracer.ts",
6310
+ kind: "runtime",
6311
+ maturity: "real",
6312
+ tests: true,
6313
+ promoted: false,
6314
+ note: 'The sovereign no-GPU FALLBACK: a pure-TypeScript CPU path tracer that RUNS (not emits) the same GI algorithm as PathTracerCompiler, sharing extractRaytraceScene so the two render the same scene. Renders offline global-illumination stills anywhere Node/JS runs \u2014 server, CI, old device, no WebGPU/GPU needed. Ships its own PNG encoder (node:zlib), zero deps. Fills the "runs anywhere / no-WebGPU compute fallback" gap the audit named (compiler-wasm is a parser, not a compute backend).'
6315
+ },
6316
+ {
6317
+ id: "media-pipeline",
6318
+ name: "MediaPipelineCompiler",
6319
+ file: "packages/core/src/compiler/MediaPipelineCompiler.ts",
6320
+ kind: "runtime",
6321
+ maturity: "real",
6322
+ tests: true,
6323
+ promoted: false,
6324
+ note: "The sovereign VIDEO / media-pipeline: renders an animated turntable of the scene (orbiting camera, fast CPU flat projector over the shared raytrace-scene extraction) and encodes the frame sequence to an APNG with our OWN encoder (acTL/fcTL/fdAT via node:zlib) \u2014 no ffmpeg / codec / muxer dependency. A moving picture from a .holo, runs anywhere Node runs. Fills the media-pipeline gap the audit named; browser-native WebCodecs H.264/WebM is the follow-on encode path."
6325
+ },
6326
+ {
6327
+ id: "compute-physics",
6328
+ name: "ComputePhysicsCompiler",
6329
+ file: "packages/core/src/compiler/ComputePhysicsCompiler.ts",
6330
+ kind: "compiler",
6331
+ maturity: "real",
6332
+ tests: true,
6333
+ promoted: false,
6334
+ note: "The sovereign GPU rigid-body SIMULATION \u2014 the dynamics layer PhysicsColliderCompiler was missing. Emits a Rust wgpu program with a WGSL COMPUTE solver: gravity + sphere/sphere + sphere/static-AABB collisions with restitution + friction, double-buffered (gather, race-free), stepped N times on the GPU; then renders the settled state to PNG. Our own solver, no third-party physics engine. One .holo drives BOTH render and sim (Grok + Claude converged design). Dynamic bodies = @rigid_body spheres; statics = scene boxes. VERIFIED on Jetson Orin (Tegra/Vulkan): spheres dropped above a floor fall, collide and settle. Hooks the physics-discovery / provenance goals."
4323
6335
  }
4324
6336
  ];
4325
6337
 
4326
- export { AgentTrustLedger, AlphaTracker, AndroidARCorePlugin, AuthoritySymbolGraph, BRIDGE_TARGETS, COLYSEUS_CONSTANT_TIERS, COLYSEUS_EMIT_FILE, COLYSEUS_SCHEMA_FIELD_TIERS, DEFAULT_DISPATCH_LATENCY_OPERATION, DispatchPolicy, DispatchTier, MCPConfigCompiler, MultiLayerCompiler, NATIVE_COMPILE_MODES, NextJSCompiler, ProvenanceBoundsChecker, SOVEREIGN_ENGINES, SOVEREIGN_TARGETS, Vector2DCompiler, WebGPUWGSLPlugin, buildColyseusAuthorityGraph, buildColyseusCrossFileContext, byzantineResilientMerge, createAuthoritySymbolGraph, createDefaultDispatchLatencyScenarios, createProvenanceBoundsChecker, createTier3CpuDirectOutput, detectWasmRuntime, formatDispatchLatencyBenchmarkReport, generateTraitForTarget, getAllManifests, getTraitInfo, isBridgeTarget, isSovereignTarget, listTraitsForTarget, manifestFromPlugin, mergeSocialCausalModels, mostRestrictiveTier, platformPluginRegistry, queryTrait, recommendDispatchPolicyDefaults, runCompilerWasmSnnEmulator, runDispatchPolicyLatencyBenchmark, splitServerAuthority, targetSovereignty, traitExists };
6338
+ export { AgentTrustLedger, AlphaTracker, AndroidARCorePlugin, AuthoritySymbolGraph, BRIDGE_TARGETS, COLYSEUS_CONSTANT_TIERS, COLYSEUS_EMIT_FILE, COLYSEUS_SCHEMA_FIELD_TIERS, DEFAULT_DISPATCH_LATENCY_OPERATION, DispatchPolicy, DispatchTier, HSIAdmissionError, HSIIRCompiler, HSI_AUDIT_SCHEMA_VERSION, HSI_IR_SCHEMA_VERSION, HSI_LEARNING_GRAPH_SCHEMA_VERSION, HSI_OBSERVATION_MEDIATOR_EDGE, HSI_TRACE_SCHEMA_VERSION, MCPConfigCompiler, MultiLayerCompiler, NATIVE_COMPILE_MODES, NextJSCompiler, ProvenanceBoundsChecker, SOVEREIGN_ENGINES, SOVEREIGN_TARGETS, Vector2DCompiler, WebGPUWGSLPlugin, applyIntervention, behavioralProjection, buildColyseusAuthorityGraph, buildColyseusCrossFileContext, byzantineResilientMerge, createAuthoritySymbolGraph, createDefaultDispatchLatencyScenarios, createHSIIRCompiler, createProvenanceBoundsChecker, createTier3CpuDirectOutput, detectWasmRuntime, emitSceneIRTsx, formatDispatchLatencyBenchmarkReport, generateAuditCases, generateTraitForTarget, getAllManifests, getTraitInfo, hsiSha256, hsiSourceTextDigest, hsiStableStringify, isBridgeTarget, isSovereignTarget, listTraitsForTarget, lowerCompositionToHSIIR, lowerHoloExpression, manifestFromPlugin, mergeSocialCausalModels, mostRestrictiveTier, platformPluginRegistry, projectLearningGraph, queryTrait, recommendDispatchPolicyDefaults, renameComposition, renameTrace, reorderComposition, runCompilerWasmSnnEmulator, runDispatchPolicyLatencyBenchmark, runExactTrace, runHSIAudit, splitServerAuthority, targetSovereignty, traitExists };
4327
6339
  //# sourceMappingURL=index.js.map
4328
6340
  //# sourceMappingURL=index.js.map