@holoscript/core 7.0.0 → 8.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (345) hide show
  1. package/README.md +2 -2
  2. package/bin/holoscript.cjs +3 -0
  3. package/dist/GLTFPipeline-276GE64O.js +16 -0
  4. package/dist/GLTFPipeline-M7WSSJED.cjs +37 -0
  5. package/dist/HoloScriptPlusParser-7FBIFUFC.js +693 -0
  6. package/dist/HoloScriptPlusParser-A2W7OCN2.cjs +698 -0
  7. package/dist/HoloScriptPlusParser-F2Z56FJR.js +10 -0
  8. package/dist/HoloScriptPlusParser-WKHRIH6T.cjs +27 -0
  9. package/dist/HoloScriptRuntime-3URVTKPJ.js +10 -0
  10. package/dist/HoloScriptRuntime-SXEAEU2N.cjs +19 -0
  11. package/dist/USDZExporter-3FWJ25JI.cjs +1037 -0
  12. package/dist/USDZExporter-D2HQLQYK.js +1035 -0
  13. package/dist/agents/index.cjs +19 -0
  14. package/dist/agents/index.d.ts +100 -0
  15. package/dist/agents/index.js +17 -0
  16. package/dist/chunk-23J755AR.js +1046 -0
  17. package/dist/chunk-253GBQZY.cjs +627 -0
  18. package/dist/chunk-25IQCHTO.cjs +781 -0
  19. package/dist/chunk-2BSMSUCE.js +1941 -0
  20. package/dist/chunk-2M2DPHKB.js +762 -0
  21. package/dist/chunk-2YSNA2F2.cjs +1274 -0
  22. package/dist/chunk-3AO425MZ.cjs +886 -0
  23. package/dist/chunk-3FOKASKO.cjs +348 -0
  24. package/dist/chunk-3HYYMEXI.cjs +56578 -0
  25. package/dist/chunk-3NFFOWGG.js +4287 -0
  26. package/dist/chunk-3WZEJHUQ.cjs +116 -0
  27. package/dist/chunk-4C57PR42.js +468 -0
  28. package/dist/chunk-4N4SXXWF.js +769 -0
  29. package/dist/chunk-4PDEPEQW.cjs +41 -0
  30. package/dist/chunk-4R6SBXDB.js +45 -0
  31. package/dist/chunk-4V2E7U7Q.cjs +2015 -0
  32. package/dist/chunk-5FSKKMR7.cjs +2092 -0
  33. package/dist/chunk-5GLCTO44.js +161 -0
  34. package/dist/chunk-5JEU52DW.js +382 -0
  35. package/dist/chunk-5S7RKFGR.cjs +446 -0
  36. package/dist/chunk-5WUNN6ZN.cjs +428 -0
  37. package/dist/chunk-62FBK3B7.js +70 -0
  38. package/dist/chunk-6CTRH7HT.cjs +1985 -0
  39. package/dist/chunk-6DPSFNJB.cjs +847 -0
  40. package/dist/chunk-6EX3I5P4.cjs +130 -0
  41. package/dist/chunk-73FELZVJ.cjs +611 -0
  42. package/dist/chunk-7CUEMLDZ.cjs +6445 -0
  43. package/dist/chunk-7HIASF7S.cjs +814 -0
  44. package/dist/chunk-A6KINLZJ.js +236 -0
  45. package/dist/chunk-AIA52I7T.cjs +543 -0
  46. package/dist/chunk-ANXZFVY2.js +113 -0
  47. package/dist/chunk-AYBXB26F.js +2176 -0
  48. package/dist/chunk-B4TFTDG4.js +449 -0
  49. package/dist/chunk-BE4UJCQT.js +623 -0
  50. package/dist/chunk-BRQJKJGT.cjs +20 -0
  51. package/dist/chunk-C2A5DUMF.cjs +689 -0
  52. package/dist/chunk-C37BHB7N.cjs +636 -0
  53. package/dist/chunk-CBJY23VL.js +126 -0
  54. package/dist/chunk-CIWWXYHZ.cjs +50 -0
  55. package/dist/chunk-CXFDRBQU.cjs +672 -0
  56. package/dist/chunk-D54CNIAJ.cjs +413 -0
  57. package/dist/chunk-DAJXW4KX.js +725 -0
  58. package/dist/chunk-DTGBOSEM.cjs +319 -0
  59. package/dist/chunk-E7JP3BS3.cjs +61 -0
  60. package/dist/chunk-EKBKLK7P.js +1169 -0
  61. package/dist/chunk-EKYL4PE3.cjs +404 -0
  62. package/dist/chunk-EUDQTK7N.cjs +4310 -0
  63. package/dist/chunk-EXKSFGSX.cjs +274 -0
  64. package/dist/chunk-EXUP2BUM.cjs +1173 -0
  65. package/dist/chunk-F43YAA34.js +623 -0
  66. package/dist/chunk-FDSGHPAK.js +130 -0
  67. package/dist/chunk-FEWUHQNM.cjs +144 -0
  68. package/dist/chunk-FGGJQRLZ.js +270 -0
  69. package/dist/chunk-FHP6LXJS.js +415 -0
  70. package/dist/chunk-FJPADH77.cjs +666 -0
  71. package/dist/chunk-FYSPZT4V.cjs +169 -0
  72. package/dist/chunk-GIOYPNTH.js +5575 -0
  73. package/dist/chunk-GJNCFRJU.cjs +125 -0
  74. package/dist/chunk-GMP623FG.cjs +1508 -0
  75. package/dist/chunk-GQHQOPXZ.cjs +5580 -0
  76. package/dist/chunk-GQT4TYKY.cjs +4381 -0
  77. package/dist/chunk-GTU2Z2WW.cjs +262 -0
  78. package/dist/chunk-GYZE55MO.js +2007 -0
  79. package/dist/chunk-GZG4KA4E.js +529 -0
  80. package/dist/chunk-H652NHX5.js +600 -0
  81. package/dist/chunk-HCCQLAA4.cjs +74 -0
  82. package/dist/chunk-HINXWAOD.cjs +1049 -0
  83. package/dist/chunk-HYNTS5CP.js +422 -0
  84. package/dist/chunk-HZSPDCXV.cjs +457 -0
  85. package/dist/chunk-HZTDET3N.js +1399 -0
  86. package/dist/chunk-I6XZ5DZF.cjs +488 -0
  87. package/dist/chunk-ILRBGFVD.cjs +72 -0
  88. package/dist/chunk-IPWSXCCN.js +1183 -0
  89. package/dist/chunk-IUTY5WQ2.cjs +424 -0
  90. package/dist/chunk-IVSZDECV.js +882 -0
  91. package/dist/chunk-IVY74O6C.js +247 -0
  92. package/dist/chunk-IZM5VQZD.js +714 -0
  93. package/dist/chunk-J32ZJZJH.js +554 -0
  94. package/dist/chunk-J6M4FPK5.js +421 -0
  95. package/dist/chunk-JC5YBPSF.cjs +984 -0
  96. package/dist/chunk-JCLBKPMX.js +3813 -0
  97. package/dist/chunk-JD7CIZ33.js +1949 -0
  98. package/dist/chunk-JIYN45TV.cjs +2525 -0
  99. package/dist/chunk-JJBE3TIH.cjs +1189 -0
  100. package/dist/chunk-JX7YL6ZE.js +2252 -0
  101. package/dist/chunk-K4VVR7CN.cjs +2433 -0
  102. package/dist/chunk-KEFNV2WM.cjs +2257 -0
  103. package/dist/chunk-KH4CNH66.cjs +424 -0
  104. package/dist/chunk-KJLB4OPV.js +5731 -0
  105. package/dist/chunk-KKFZ3B6J.cjs +557 -0
  106. package/dist/chunk-KKP7JKN4.cjs +6002 -0
  107. package/dist/chunk-KPJL34Y7.cjs +186 -0
  108. package/dist/chunk-KQCN6AKJ.cjs +3042 -0
  109. package/dist/chunk-KVRSTFNH.cjs +72 -0
  110. package/dist/chunk-LICPB5HZ.cjs +1409 -0
  111. package/dist/chunk-LM2VU56C.cjs +37 -0
  112. package/dist/chunk-M56JSP4A.js +400 -0
  113. package/dist/chunk-MBOOR7X4.js +18 -0
  114. package/dist/chunk-MGE5Z4GS.js +608 -0
  115. package/dist/chunk-MXFUTKCO.js +56 -0
  116. package/dist/chunk-MYY4PMWX.cjs +264 -0
  117. package/dist/chunk-N75IH2HY.js +258 -0
  118. package/dist/chunk-NBMHU6SW.js +669 -0
  119. package/dist/chunk-NG77ATEW.cjs +778 -0
  120. package/dist/chunk-NGKREZ36.js +6384 -0
  121. package/dist/chunk-NHWSN2SD.cjs +718 -0
  122. package/dist/chunk-NV4VMVXU.js +421 -0
  123. package/dist/chunk-NW5G5FBQ.js +215 -0
  124. package/dist/chunk-NXZFOPVD.cjs +5737 -0
  125. package/dist/chunk-OBIYPYYS.cjs +1993 -0
  126. package/dist/chunk-OIQYIIO3.cjs +473 -0
  127. package/dist/chunk-OL46QLBJ.js +61 -0
  128. package/dist/chunk-OMXII44L.js +5386 -0
  129. package/dist/chunk-OR4Q2BGL.cjs +759 -0
  130. package/dist/chunk-OSYNRVOV.cjs +243 -0
  131. package/dist/chunk-PGANYCAG.cjs +220 -0
  132. package/dist/chunk-PHENW4MQ.js +65 -0
  133. package/dist/chunk-PHVRG4I2.js +844 -0
  134. package/dist/chunk-Q56TT7IL.js +483 -0
  135. package/dist/chunk-QPOQ7VPI.js +1491 -0
  136. package/dist/chunk-QPSKHBJP.js +5963 -0
  137. package/dist/chunk-QXH7QDSZ.js +1989 -0
  138. package/dist/chunk-R75BSDH7.cjs +50 -0
  139. package/dist/chunk-RARB3MBR.js +207 -0
  140. package/dist/chunk-RVBHAXFG.js +56160 -0
  141. package/dist/chunk-S3MDHNKB.cjs +490 -0
  142. package/dist/chunk-S4W6Z2MN.js +2426 -0
  143. package/dist/chunk-S6YWHCKV.cjs +410 -0
  144. package/dist/chunk-SIEXCILW.js +229 -0
  145. package/dist/chunk-SJBGLS25.cjs +2196 -0
  146. package/dist/chunk-SLU6UPJI.cjs +410 -0
  147. package/dist/chunk-SMIWS6DE.cjs +212 -0
  148. package/dist/chunk-T2QCTZMO.js +811 -0
  149. package/dist/chunk-T5J7ZKP3.cjs +4885 -0
  150. package/dist/chunk-TDCNJHWO.js +341 -0
  151. package/dist/chunk-TG7O4WBC.js +406 -0
  152. package/dist/chunk-THCK6ECW.js +2085 -0
  153. package/dist/chunk-TJHVSBP2.js +439 -0
  154. package/dist/chunk-TVHSPJ4N.cjs +606 -0
  155. package/dist/chunk-U44IKGG7.cjs +5390 -0
  156. package/dist/chunk-UJXISJBN.js +487 -0
  157. package/dist/chunk-UM6C3CGK.js +4375 -0
  158. package/dist/chunk-UMABK6SI.js +686 -0
  159. package/dist/chunk-UOIGFQXC.cjs +9750 -0
  160. package/dist/chunk-URG2SJLK.js +2521 -0
  161. package/dist/chunk-V6MKC2FZ.js +979 -0
  162. package/dist/chunk-VECQYRXL.js +474 -0
  163. package/dist/chunk-VJ3L7CHT.cjs +169 -0
  164. package/dist/chunk-VMLKSV26.js +1216 -0
  165. package/dist/chunk-VVKVQZI6.js +55 -0
  166. package/dist/chunk-W6RW64BB.cjs +1219 -0
  167. package/dist/chunk-W7VDOASB.cjs +639 -0
  168. package/dist/chunk-WDT3JTGM.cjs +483 -0
  169. package/dist/chunk-WJIHFLMJ.js +404 -0
  170. package/dist/chunk-WKX5AMOY.js +309 -0
  171. package/dist/chunk-WNNE3PO3.js +34 -0
  172. package/dist/chunk-WRKUDAZJ.js +3038 -0
  173. package/dist/chunk-WRLUBRKS.cjs +1943 -0
  174. package/dist/chunk-WRNEH5MO.js +3169 -0
  175. package/dist/chunk-WRWEX5ZF.js +658 -0
  176. package/dist/chunk-X3GJPRVK.cjs +3246 -0
  177. package/dist/chunk-XHIV6326.cjs +793 -0
  178. package/dist/chunk-XIVIE43A.cjs +729 -0
  179. package/dist/chunk-XJAN7CZG.cjs +432 -0
  180. package/dist/chunk-XKTPFXGA.js +164 -0
  181. package/dist/chunk-XL6INWKT.js +121 -0
  182. package/dist/chunk-XSFNHP2E.js +632 -0
  183. package/dist/chunk-XT6JY5W5.js +9684 -0
  184. package/dist/chunk-XUILI4KB.cjs +430 -0
  185. package/dist/chunk-XUUVDHIF.cjs +3962 -0
  186. package/dist/chunk-YF2I3MV3.js +46 -0
  187. package/dist/chunk-YIMN575O.js +4847 -0
  188. package/dist/chunk-YIVFJNYV.js +176 -0
  189. package/dist/chunk-YKGPCZEE.cjs +237 -0
  190. package/dist/chunk-YN6V7R3L.cjs +327 -0
  191. package/dist/chunk-YQELFNJV.js +39 -0
  192. package/dist/chunk-YYXH45E2.js +426 -0
  193. package/dist/chunk-ZBQXLH2L.js +756 -0
  194. package/dist/chunk-ZDSYWBIE.cjs +69 -0
  195. package/dist/chunk-ZU7NIRT6.js +325 -0
  196. package/dist/chunk-ZZ7RO2UQ.js +1243 -0
  197. package/dist/chunk-ZZEI7MV4.js +778 -0
  198. package/dist/cli/holoscript-runner.cjs +2255 -0
  199. package/dist/cli/holoscript-runner.js +2230 -0
  200. package/dist/codebase/index.cjs +336 -0
  201. package/dist/codebase/index.js +331 -0
  202. package/dist/compiler/agent-inference.cjs +31 -0
  203. package/dist/compiler/agent-inference.js +8 -0
  204. package/dist/compiler/android-xr.cjs +24 -0
  205. package/dist/compiler/android-xr.js +14 -0
  206. package/dist/compiler/android.cjs +24 -0
  207. package/dist/compiler/android.js +14 -0
  208. package/dist/compiler/ar.cjs +23 -0
  209. package/dist/compiler/ar.js +11 -0
  210. package/dist/compiler/babylon.cjs +21 -0
  211. package/dist/compiler/babylon.js +15 -0
  212. package/dist/compiler/business-quest.cjs +43 -0
  213. package/dist/compiler/business-quest.js +4 -0
  214. package/dist/compiler/coco.cjs +27 -0
  215. package/dist/compiler/coco.js +4 -0
  216. package/dist/compiler/context.cjs +25 -0
  217. package/dist/compiler/context.d.ts +28 -0
  218. package/dist/compiler/context.js +8 -0
  219. package/dist/compiler/domain-block-utils.cjs +605 -0
  220. package/dist/compiler/domain-block-utils.js +11 -0
  221. package/dist/compiler/dtdl.cjs +27 -0
  222. package/dist/compiler/dtdl.js +11 -0
  223. package/dist/compiler/gltf-pipeline.cjs +39 -0
  224. package/dist/compiler/gltf-pipeline.js +4 -0
  225. package/dist/compiler/godot.cjs +18 -0
  226. package/dist/compiler/godot.js +12 -0
  227. package/dist/compiler/incremental.cjs +34 -0
  228. package/dist/compiler/incremental.js +9 -0
  229. package/dist/compiler/index.cjs +5860 -0
  230. package/dist/compiler/index.d.ts +322 -21
  231. package/dist/compiler/index.js +5525 -0
  232. package/dist/compiler/ios.cjs +23 -0
  233. package/dist/compiler/ios.js +13 -0
  234. package/dist/compiler/llm-provider-capabilities.cjs +25 -0
  235. package/dist/compiler/llm-provider-capabilities.d.ts +43 -0
  236. package/dist/compiler/llm-provider-capabilities.js +8 -0
  237. package/dist/compiler/multi-layer.cjs +24 -0
  238. package/dist/compiler/multi-layer.js +15 -0
  239. package/dist/compiler/nodetoy.cjs +23 -0
  240. package/dist/compiler/nodetoy.js +4 -0
  241. package/dist/compiler/openxr.cjs +19 -0
  242. package/dist/compiler/openxr.js +13 -0
  243. package/dist/compiler/playcanvas.cjs +19 -0
  244. package/dist/compiler/playcanvas.js +13 -0
  245. package/dist/compiler/r3f.cjs +38 -0
  246. package/dist/compiler/r3f.d.ts +22 -0
  247. package/dist/compiler/r3f.js +16 -0
  248. package/dist/compiler/remotion.cjs +23 -0
  249. package/dist/compiler/remotion.js +4 -0
  250. package/dist/compiler/reproducibility.cjs +39 -0
  251. package/dist/compiler/reproducibility.js +4 -0
  252. package/dist/compiler/sdf.cjs +24 -0
  253. package/dist/compiler/sdf.js +12 -0
  254. package/dist/compiler/semantic-scene.cjs +31 -0
  255. package/dist/compiler/semantic-scene.js +4 -0
  256. package/dist/compiler/state.cjs +21 -0
  257. package/dist/compiler/state.js +11 -0
  258. package/dist/compiler/trait-composition.cjs +30 -0
  259. package/dist/compiler/trait-composition.js +9 -0
  260. package/dist/compiler/unity.cjs +19 -0
  261. package/dist/compiler/unity.js +13 -0
  262. package/dist/compiler/unreal.cjs +23 -0
  263. package/dist/compiler/unreal.js +13 -0
  264. package/dist/compiler/urdf.cjs +52 -0
  265. package/dist/compiler/urdf.js +12 -0
  266. package/dist/compiler/usd-physics.cjs +26 -0
  267. package/dist/compiler/usd-physics.js +9 -0
  268. package/dist/compiler/visionos.cjs +19 -0
  269. package/dist/compiler/visionos.js +13 -0
  270. package/dist/compiler/vrchat.cjs +22 -0
  271. package/dist/compiler/vrchat.js +12 -0
  272. package/dist/compiler/vrr.cjs +24 -0
  273. package/dist/compiler/vrr.js +12 -0
  274. package/dist/compiler/wasm.cjs +36 -0
  275. package/dist/compiler/wasm.js +12 -0
  276. package/dist/compiler/webgpu.cjs +18 -0
  277. package/dist/compiler/webgpu.js +12 -0
  278. package/dist/coordinators/index.cjs +1266 -0
  279. package/dist/coordinators/index.d.ts +72 -1
  280. package/dist/coordinators/index.js +1259 -0
  281. package/dist/debugger.cjs +24 -0
  282. package/dist/debugger.js +11 -0
  283. package/dist/entries/interop.cjs +64 -0
  284. package/dist/entries/interop.js +7 -0
  285. package/dist/entries/scripting.cjs +55 -0
  286. package/dist/entries/scripting.js +10 -0
  287. package/dist/hololand/index.cjs +146 -0
  288. package/dist/hololand/index.d.ts +70 -0
  289. package/dist/hololand/index.js +5 -0
  290. package/dist/index.cjs +43233 -0
  291. package/dist/index.d.ts +976 -21
  292. package/dist/index.js +39995 -0
  293. package/dist/math/tropical-spmv.cjs +45 -0
  294. package/dist/math/tropical-spmv.js +4 -0
  295. package/dist/math/vec3.cjs +57 -0
  296. package/dist/math/vec3.js +4 -0
  297. package/dist/ml-dsa-FSKBTE3W.cjs +1265 -0
  298. package/dist/ml-dsa-Z7JDKW4L.js +1265 -0
  299. package/dist/paper-0c-spike/index.cjs +150 -0
  300. package/dist/paper-0c-spike/index.js +141 -0
  301. package/dist/parser.cjs +61 -0
  302. package/dist/parser.d.ts +11 -0
  303. package/dist/parser.js +12 -0
  304. package/dist/playwright-3AT3AKTV.cjs +98673 -0
  305. package/dist/playwright-VZPDVUEQ.js +98660 -0
  306. package/dist/reconstruction/index.cjs +153 -0
  307. package/dist/reconstruction/index.d.ts +29 -2
  308. package/dist/reconstruction/index.js +8 -0
  309. package/dist/runtime.cjs +316 -0
  310. package/dist/runtime.d.ts +61 -0
  311. package/dist/runtime.js +31 -0
  312. package/dist/self-improvement/index.cjs +563 -0
  313. package/dist/self-improvement/index.js +545 -0
  314. package/dist/storage/index.cjs +38 -0
  315. package/dist/storage/index.js +5 -0
  316. package/dist/testing.cjs +25 -0
  317. package/dist/testing.d.ts +70 -0
  318. package/dist/testing.js +4 -0
  319. package/dist/traitDocs/traitDocs.cjs +33 -0
  320. package/dist/traitDocs/traitDocs.js +7 -0
  321. package/dist/traits/botanical-lotus.cjs +41 -0
  322. package/dist/traits/botanical-lotus.d.ts +172 -0
  323. package/dist/traits/botanical-lotus.js +4 -0
  324. package/dist/traits/engines/index.cjs +520 -0
  325. package/dist/traits/engines/index.js +380 -0
  326. package/dist/traits/index.cjs +24409 -0
  327. package/dist/traits/index.d.ts +171 -35
  328. package/dist/traits/index.js +21634 -0
  329. package/dist/traits/simulation-solver-factory.cjs +13 -0
  330. package/dist/traits/simulation-solver-factory.d.ts +23 -0
  331. package/dist/traits/simulation-solver-factory.js +4 -0
  332. package/dist/traits/webcam-gaze.cjs +35 -0
  333. package/dist/traits/webcam-gaze.d.ts +17 -0
  334. package/dist/traits/webcam-gaze.js +4 -0
  335. package/dist/type-checker.cjs +19 -0
  336. package/dist/type-checker.js +6 -0
  337. package/dist/world/index.cjs +947 -0
  338. package/dist/world/index.d.ts +147 -0
  339. package/dist/world/index.js +939 -0
  340. package/dist/world-model/index.cjs +1446 -0
  341. package/dist/world-model/index.d.ts +119 -0
  342. package/dist/world-model/index.js +1414 -0
  343. package/dist/wot/index.cjs +29 -0
  344. package/dist/wot/index.js +4 -0
  345. package/package.json +93 -49
@@ -0,0 +1,1989 @@
1
+ import { init_CompilerBase, CompilerBase } from './chunk-QPSKHBJP.js';
2
+ import { ANSCapabilityPath } from '@holoscript/core-types/ans';
3
+
4
+ // src/compiler/ContextCompiler.ts
5
+ init_CompilerBase();
6
+ var BANNED_DEFAULT_PATTERNS = [
7
+ { pattern: /\bgit\s+add\s+(?:-A|--all|\.)(?=\s|$)/i, rule: "F.001/F.011 - git add -A leaked .env twice" },
8
+ { pattern: /:\s*any\b|\bas\s+any\b|<any>/i, rule: "global CLAUDE.md - no `any` in TypeScript, use `unknown`" },
9
+ { pattern: /\bregex\b.+\.(?:hs|hsplus|holo)\b/i, rule: "F.014 - no regex on .hs/.hsplus/.holo, use @holoscript/core" },
10
+ { pattern: /\bmock\s+(?:the\s+)?(?:db|database)\b/i, rule: "founder-default - real DB in tests, mock-vs-prod divergence" }
11
+ ];
12
+ var VENDOR_AS_SUBSTRATE_PATTERNS = [
13
+ { pattern: /managed_agents_replaces_holomesh/i, rule: "W.GOLD.002 - vendor framework cannot replace HoloMesh" },
14
+ { pattern: /vector_store_as_source_of_truth/i, rule: "docs/LLM_CAPABILITIES.md hard-don'ts - vendor stores never source-of-truth" },
15
+ { pattern: /api_keys_as_identity/i, rule: "W.GOLD.004 - wallets are identity, API keys are sessions" }
16
+ ];
17
+ var KNOWN_DIAMOND_IDS = /* @__PURE__ */ new Set([
18
+ "W.GOLD.001",
19
+ // Architecture beats alignment
20
+ "P.GOLD.001",
21
+ // Failure knowledge decays slower than success knowledge
22
+ "W.GOLD.188",
23
+ // Algebraic Trust (paired with W.GOLD.189)
24
+ "W.GOLD.189"
25
+ // Algebraic Trust tri-layer (algebra + history + oracle)
26
+ // Add more as graduate.py promotes - verify against D:/GOLD/INDEX.md.
27
+ ]);
28
+ var DEFAULT_FLUENT_PROSE_CHARS = 150;
29
+ var ContextCompiler = class extends CompilerBase {
30
+ constructor(options = {}) {
31
+ super();
32
+ this.compilerName = "ContextCompiler";
33
+ this.options = {
34
+ formats: options.formats ?? ["claude_md"]
35
+ };
36
+ }
37
+ getRequiredCapability() {
38
+ return ANSCapabilityPath.AGENT_INFERENCE;
39
+ }
40
+ /**
41
+ * Compile a HoloScript context composition to agent-surface formats.
42
+ *
43
+ * Phases:
44
+ * 1. extract - walk the HoloComposition AST, collect all v1 traits
45
+ * into the typed ContextAST shape
46
+ * 2. validate - apply BLOCK rules (Diamond-invariant violations) +
47
+ * WARN rules (soft guidelines). BLOCK rules throw; WARN rules
48
+ * accumulate in diagnostics.
49
+ * 3. emit - dispatch to per-format emitters. Phase 1 ships claude_md
50
+ * and agents_md. cursor_rules + skill_md + anthropic_system_prompt
51
+ * + brain_includes + mcp_context_loader are filed follow-ups.
52
+ */
53
+ compile(composition, agentToken, outputPath) {
54
+ this.validateCompilerAccess(agentToken, outputPath);
55
+ const ast = this.extractContextAST(composition);
56
+ this.validate(ast);
57
+ const files = {};
58
+ for (const format of this.options.formats) {
59
+ switch (format) {
60
+ case "claude_md":
61
+ files["CLAUDE.md"] = this.emitClaudeMd(ast);
62
+ break;
63
+ case "agents_md":
64
+ files["AGENTS.md"] = this.emitAgentsMd(ast);
65
+ break;
66
+ case "cursor_rules": {
67
+ const cursorFiles = this.emitCursorRules(ast);
68
+ for (const [path, content] of Object.entries(cursorFiles)) {
69
+ files[path] = content;
70
+ }
71
+ break;
72
+ }
73
+ case "skill_md":
74
+ files["SKILL.md"] = this.emitSkillMd(ast);
75
+ break;
76
+ case "anthropic_system_prompt":
77
+ case "brain_includes":
78
+ case "mcp_context_loader":
79
+ throw new Error(
80
+ `Format "${format}" is a Phase 1+ follow-up; not yet emitted. See ai-ecosystem research/2026-05-06_context-as-compile-target.md section Recommended sequence for the rollout order.`
81
+ );
82
+ default: {
83
+ const exhaustive = format;
84
+ throw new Error(`Unknown emit format: ${String(exhaustive)}`);
85
+ }
86
+ }
87
+ }
88
+ return { files, ast, diagnostics: ast.warnings };
89
+ }
90
+ // --- Phase 1: extract -----------------------------------------------
91
+ extractContextAST(composition) {
92
+ const ast = {
93
+ visionPillars: [],
94
+ refusals: [],
95
+ hardDonts: [],
96
+ defaults: [],
97
+ graduatedWisdoms: [],
98
+ feedbacks: [],
99
+ escalations: [],
100
+ verifyTokens: [],
101
+ gapRules: [],
102
+ citationRules: [],
103
+ skills: [],
104
+ includes: [],
105
+ routines: [],
106
+ hardPhysicalGaps: [],
107
+ invocationModes: [],
108
+ dateDisciplines: [],
109
+ domainPreferences: [],
110
+ embodiedProjections: [],
111
+ editorialDefaults: [],
112
+ researchDefaults: [],
113
+ trackBAuthorities: [],
114
+ narrativeOpenings: [],
115
+ triggerPhrases: [],
116
+ proseAfters: [],
117
+ domainDispatches: [],
118
+ corpusMutabilities: [],
119
+ warnings: []
120
+ };
121
+ for (const trait of composition.traits ?? []) {
122
+ this.dispatchTrait(trait, ast);
123
+ }
124
+ for (const obj of composition.objects ?? []) {
125
+ this.extractFromObject(obj, ast);
126
+ }
127
+ return ast;
128
+ }
129
+ extractFromObject(obj, ast) {
130
+ const traits = obj.traits ?? [];
131
+ for (const trait of traits) {
132
+ this.dispatchTrait(trait, ast);
133
+ }
134
+ }
135
+ dispatchTrait(trait, ast) {
136
+ const cfg = trait.config;
137
+ switch (trait.name) {
138
+ case "identity": {
139
+ const allowedToolsList = stringListField(cfg, "allowed_tools");
140
+ ast.identity = {
141
+ name: stringField(cfg, "name", ""),
142
+ role: stringField(cfg, "role", ""),
143
+ domain: stringField(cfg, "domain", ""),
144
+ surface: stringField(cfg, "surface", "any") ?? "any",
145
+ noMonopoly: boolField(cfg, "no_monopoly", false),
146
+ description: stringFieldOrUndef(cfg, "description"),
147
+ allowedTools: allowedToolsList.length > 0 ? allowedToolsList : void 0,
148
+ commandTemplate: stringFieldOrUndef(cfg, "command_template")
149
+ };
150
+ break;
151
+ }
152
+ case "authority_order":
153
+ ast.authorityOrder = { tiers: stringListField(cfg, "tiers") };
154
+ break;
155
+ case "vision_pillar":
156
+ ast.visionPillars.push({
157
+ id: stringField(cfg, "id", ""),
158
+ claim: stringField(cfg, "claim", ""),
159
+ citation: stringFieldOrUndef(cfg, "citation")
160
+ });
161
+ break;
162
+ case "output_shape":
163
+ ast.outputShape = {
164
+ silentTo: stringField(cfg, "silent_to", ""),
165
+ loudTo: stringField(cfg, "loud_to", ""),
166
+ noMetaOutput: boolField(cfg, "no_meta_output", false),
167
+ surfaceHint: stringField(cfg, "surface_hint", "")
168
+ };
169
+ break;
170
+ case "production_rule":
171
+ ast.productionRule = {
172
+ noDevNoMockNoLocalhost: boolField(cfg, "no_dev_no_mock_no_localhost", false),
173
+ exception: stringFieldOrUndef(cfg, "exception")
174
+ };
175
+ break;
176
+ case "refusal":
177
+ ast.refusals.push({
178
+ name: stringField(cfg, "name", ""),
179
+ when: stringField(cfg, "when", ""),
180
+ do: stringField(cfg, "do", ""),
181
+ doNot: stringListField(cfg, "do_not"),
182
+ reason: stringFieldOrUndef(cfg, "reason")
183
+ });
184
+ break;
185
+ case "hard_dont":
186
+ ast.hardDonts.push({
187
+ name: stringField(cfg, "name", ""),
188
+ reason: stringField(cfg, "reason", ""),
189
+ alternative: stringFieldOrUndef(cfg, "alternative"),
190
+ appliesTo: stringListField(cfg, "applies_to")
191
+ });
192
+ break;
193
+ case "default":
194
+ ast.defaults.push({
195
+ name: stringField(cfg, "name", ""),
196
+ when: stringField(cfg, "when", ""),
197
+ do: stringField(cfg, "do", ""),
198
+ reason: stringFieldOrUndef(cfg, "reason")
199
+ });
200
+ break;
201
+ case "graduated_wisdom":
202
+ ast.graduatedWisdoms.push({
203
+ id: stringField(cfg, "id", ""),
204
+ claim: stringField(cfg, "claim", ""),
205
+ tier: stringField(cfg, "tier", "gold")
206
+ });
207
+ break;
208
+ case "feedback":
209
+ ast.feedbacks.push({
210
+ id: stringField(cfg, "id", ""),
211
+ claim: stringField(cfg, "claim", ""),
212
+ source: stringFieldOrUndef(cfg, "source")
213
+ });
214
+ break;
215
+ case "escalation":
216
+ ast.escalations.push({
217
+ trigger: stringField(cfg, "trigger", ""),
218
+ doAction: stringField(cfg, "do_action", ""),
219
+ recipient: stringField(cfg, "recipient", ""),
220
+ refuseToEscalateWhen: stringListField(cfg, "refuse_to_escalate_when")
221
+ });
222
+ break;
223
+ case "verify_token":
224
+ ast.verifyTokens.push({
225
+ meaning: stringField(cfg, "meaning", ""),
226
+ example: stringField(cfg, "example", "")
227
+ });
228
+ break;
229
+ case "gap_rule":
230
+ ast.gapRules.push({
231
+ name: stringField(cfg, "name", ""),
232
+ when: stringField(cfg, "when", ""),
233
+ do: stringListField(cfg, "do"),
234
+ doNot: stringListField(cfg, "do_not"),
235
+ reason: stringFieldOrUndef(cfg, "reason")
236
+ });
237
+ break;
238
+ case "citation_rule":
239
+ ast.citationRules.push({
240
+ fluentProseThresholdChars: numberField(
241
+ cfg,
242
+ "fluent_prose_threshold_chars",
243
+ DEFAULT_FLUENT_PROSE_CHARS
244
+ ),
245
+ required: stringListField(cfg, "required"),
246
+ exemption: stringFieldOrUndef(cfg, "exemption"),
247
+ reason: stringFieldOrUndef(cfg, "reason")
248
+ });
249
+ break;
250
+ case "skill":
251
+ ast.skills.push({
252
+ name: stringField(cfg, "name", ""),
253
+ invocableAs: stringField(cfg, "invocable_as", ""),
254
+ authority: stringField(cfg, "authority", ""),
255
+ authoritativeFor: stringListField(cfg, "authoritative_for"),
256
+ refusals: stringListField(cfg, "refusals")
257
+ });
258
+ break;
259
+ case "include":
260
+ ast.includes.push({
261
+ source: stringField(cfg, "source", ""),
262
+ selector: stringFieldOrUndef(cfg, "selector")
263
+ });
264
+ break;
265
+ case "routine":
266
+ ast.routines.push({
267
+ id: stringField(cfg, "id", ""),
268
+ schedule: stringField(cfg, "schedule", ""),
269
+ skill: stringField(cfg, "skill", ""),
270
+ promptRef: stringField(cfg, "prompt_ref", ""),
271
+ sla: stringField(cfg, "sla", ""),
272
+ outputDir: stringFieldOrUndef(cfg, "output_dir"),
273
+ cleanExitScript: stringFieldOrUndef(cfg, "clean_exit_script")
274
+ });
275
+ break;
276
+ case "hard_physical_gap":
277
+ ast.hardPhysicalGaps.push({
278
+ name: stringField(cfg, "name", ""),
279
+ reason: stringField(cfg, "reason", ""),
280
+ appliesTo: stringListField(cfg, "applies_to"),
281
+ alternative: stringFieldOrUndef(cfg, "alternative")
282
+ });
283
+ break;
284
+ case "invocation_mode":
285
+ ast.invocationModes.push({
286
+ mode: stringField(cfg, "mode", "explicit"),
287
+ when: stringField(cfg, "when", ""),
288
+ effect: stringField(cfg, "effect", ""),
289
+ example: stringFieldOrUndef(cfg, "example")
290
+ });
291
+ break;
292
+ case "date_discipline": {
293
+ const crossRefs = stringListField(cfg, "cross_references");
294
+ ast.dateDisciplines.push({
295
+ wisdomId: stringField(cfg, "wisdom_id", ""),
296
+ refusalContract: stringField(cfg, "refusal_contract", ""),
297
+ requiredComponents: stringListField(cfg, "required_components"),
298
+ shapeTemplate: stringField(cfg, "shape_template", ""),
299
+ reason: stringFieldOrUndef(cfg, "reason"),
300
+ crossReferences: crossRefs.length > 0 ? crossRefs : void 0
301
+ });
302
+ break;
303
+ }
304
+ case "domain_preference":
305
+ ast.domainPreferences.push({
306
+ domain: stringField(cfg, "domain", ""),
307
+ skills: stringListField(cfg, "skills"),
308
+ notes: stringFieldOrUndef(cfg, "notes"),
309
+ ceiling: stringFieldOrUndef(cfg, "ceiling")
310
+ });
311
+ break;
312
+ case "authority":
313
+ ast.trackBAuthorities.push({
314
+ target: stringField(cfg, "target", ""),
315
+ actionType: stringField(cfg, "action_type", ""),
316
+ requires: stringListField(cfg, "requires"),
317
+ founderRatificationRequired: boolField(
318
+ cfg,
319
+ "founder_ratification_required",
320
+ false
321
+ ),
322
+ notes: stringFieldOrUndef(cfg, "notes")
323
+ });
324
+ break;
325
+ case "embodied_projection":
326
+ ast.embodiedProjections.push({
327
+ surface: stringField(cfg, "surface", ""),
328
+ projectionKind: stringField(cfg, "projection_kind", "read-only"),
329
+ trigger: stringField(cfg, "trigger", ""),
330
+ notes: stringFieldOrUndef(cfg, "notes")
331
+ });
332
+ break;
333
+ case "editorial_default":
334
+ ast.editorialDefaults.push({
335
+ name: stringField(cfg, "name", ""),
336
+ paperId: stringFieldOrUndef(cfg, "paper_id"),
337
+ paperPhase: stringFieldOrUndef(cfg, "paper_phase"),
338
+ when: stringField(cfg, "when", ""),
339
+ do: stringField(cfg, "do", ""),
340
+ reason: stringFieldOrUndef(cfg, "reason")
341
+ });
342
+ break;
343
+ case "research_default":
344
+ ast.researchDefaults.push({
345
+ name: stringField(cfg, "name", ""),
346
+ paperId: stringFieldOrUndef(cfg, "paper_id"),
347
+ paperPhase: stringFieldOrUndef(cfg, "paper_phase"),
348
+ when: stringField(cfg, "when", ""),
349
+ do: stringField(cfg, "do", ""),
350
+ reason: stringFieldOrUndef(cfg, "reason")
351
+ });
352
+ break;
353
+ case "narrative_opening":
354
+ ast.narrativeOpenings.push({
355
+ posture: stringField(cfg, "posture", ""),
356
+ reason: stringFieldOrUndef(cfg, "reason")
357
+ });
358
+ break;
359
+ case "trigger_phrase":
360
+ ast.triggerPhrases.push({
361
+ phrase: stringField(cfg, "phrase", ""),
362
+ context: stringFieldOrUndef(cfg, "context")
363
+ });
364
+ break;
365
+ case "prose_after":
366
+ ast.proseAfters.push({
367
+ trait: stringField(cfg, "trait", ""),
368
+ paragraphs: stringListField(cfg, "paragraphs")
369
+ });
370
+ break;
371
+ case "domain_dispatch":
372
+ ast.domainDispatches.push({
373
+ domain: stringField(cfg, "domain", ""),
374
+ skills: stringListField(cfg, "skills")
375
+ });
376
+ break;
377
+ case "corpus_mutability":
378
+ ast.corpusMutabilities.push({
379
+ policy: stringField(cfg, "policy", ""),
380
+ description: stringField(cfg, "description", "")
381
+ });
382
+ break;
383
+ default:
384
+ ast.warnings.push({
385
+ severity: "warning",
386
+ rule: "unknown-trait",
387
+ message: `Trait "${trait.name}" is not in vocabulary v1. Ignored. Add to vocabulary if load-bearing.`
388
+ });
389
+ break;
390
+ }
391
+ }
392
+ // --- Phase 2: validate (BLOCK rules throw, WARN rules accumulate) --
393
+ validate(ast) {
394
+ for (const def of ast.defaults) {
395
+ for (const banned of BANNED_DEFAULT_PATTERNS) {
396
+ if (banned.pattern.test(def.do)) {
397
+ throw new ContextCompileError(
398
+ `@default "${def.name}" recommends a banned pattern (matches ${banned.pattern}). Rule: ${banned.rule}.`
399
+ );
400
+ }
401
+ }
402
+ }
403
+ for (const dont of ast.hardDonts) {
404
+ const haystack = `${dont.name} ${dont.reason}`;
405
+ for (const vendorPat of VENDOR_AS_SUBSTRATE_PATTERNS) {
406
+ if (vendorPat.pattern.test(haystack)) {
407
+ throw new ContextCompileError(
408
+ `@hard_dont "${dont.name}" appears to author a vendor-as-substrate pattern. Rule: ${vendorPat.rule}. (A correct hard_dont SAYS "do not adopt vendor as substrate" - this one's framing matches the inverse.)`
409
+ );
410
+ }
411
+ }
412
+ }
413
+ for (const wisdom of ast.graduatedWisdoms) {
414
+ if (wisdom.tier === "diamond" && !KNOWN_DIAMOND_IDS.has(wisdom.id)) {
415
+ throw new ContextCompileError(
416
+ `@graduated_wisdom "${wisdom.id}" claims tier="diamond" but is not in the compiler's known-Diamond set. Diamond declaration is founder-only (D:/GOLD/INDEX.md). If this is a new Diamond entry, update KNOWN_DIAMOND_IDS in ContextCompiler.ts in the same commit that lands the GOLD entry.`
417
+ );
418
+ }
419
+ }
420
+ const physicalGapNames = new Set(ast.hardPhysicalGaps.map((g) => g.name));
421
+ for (const skill of ast.skills) {
422
+ for (const claim of skill.authoritativeFor) {
423
+ if (physicalGapNames.has(claim)) {
424
+ throw new ContextCompileError(
425
+ `@skill "${skill.name}" claims authoritative_for="${claim}" but that's a @hard_physical_gap (Trezor/Quest 3/in-person - non-absorbable). Founder skill section "Hard physical gaps the skill never absorbs". Either remove the claim or, if the skill genuinely covers the decision-side (yes/no/when/how-much) without the embodied step, narrow the authoritative_for entry to make the boundary explicit.`
426
+ );
427
+ }
428
+ }
429
+ }
430
+ for (const wisdom of ast.graduatedWisdoms) {
431
+ if (wisdom.tier !== "diamond" && !/^[WPG]\.GOLD\.\d+$/.test(wisdom.id)) {
432
+ ast.warnings.push({
433
+ severity: "warning",
434
+ rule: "F.023 vault-id-format",
435
+ message: `@graduated_wisdom id "${wisdom.id}" doesn't match expected format (W.GOLD.NNN | P.GOLD.NNN | G.GOLD.NNN). Possible typo or stale citation.`
436
+ });
437
+ }
438
+ }
439
+ }
440
+ // --- Phase 3: emit -- compile_to_claude_md -------------------------
441
+ emitClaudeMd(ast) {
442
+ const lines = [];
443
+ if (ast.identity) {
444
+ lines.push(`# ${ast.identity.name}`);
445
+ lines.push("");
446
+ lines.push(`> **Role**: ${ast.identity.role}`);
447
+ lines.push(`> **Domain**: ${ast.identity.domain}`);
448
+ lines.push(`> **Surface**: ${ast.identity.surface}`);
449
+ if (ast.identity.noMonopoly) {
450
+ lines.push(
451
+ `> **No-monopoly rule**: this context applies the absorb-as-adapter architectural posture (per docs/LLM_CAPABILITIES.md section Architectural posture).`
452
+ );
453
+ }
454
+ lines.push("");
455
+ }
456
+ for (const opening of ast.narrativeOpenings) {
457
+ const postureLines = opening.posture.split(/\r?\n/);
458
+ for (const pl of postureLines) {
459
+ lines.push(`> ${pl}`);
460
+ }
461
+ if (opening.reason) {
462
+ const reasonLines = opening.reason.split(/\r?\n/);
463
+ for (const rl of reasonLines) {
464
+ lines.push(`> ${rl}`);
465
+ }
466
+ }
467
+ lines.push("");
468
+ }
469
+ if (ast.authorityOrder && ast.authorityOrder.tiers.length > 0) {
470
+ lines.push(`## Authority order (read top-down; the first match wins)`);
471
+ lines.push("");
472
+ ast.authorityOrder.tiers.forEach((tier, idx) => {
473
+ lines.push(`${idx + 1}. **${tier}**`);
474
+ });
475
+ lines.push("");
476
+ this.appendProseAfter(lines, ast, "authority_order");
477
+ }
478
+ if (ast.visionPillars.length > 0) {
479
+ lines.push(`## Vision pillars (follow; do not drift)`);
480
+ lines.push("");
481
+ ast.visionPillars.forEach((pillar, idx) => {
482
+ const cite = pillar.citation ? ` *(${pillar.citation})*` : "";
483
+ lines.push(`${idx + 1}. **${pillar.claim}**${cite}`);
484
+ });
485
+ lines.push("");
486
+ this.appendProseAfter(lines, ast, "vision_pillar");
487
+ }
488
+ if (ast.refusals.length > 0) {
489
+ lines.push(`## The Four Refusals`);
490
+ lines.push("");
491
+ lines.push(
492
+ `These are not guidelines. They are refusals. If you catch yourself about to do any of the following, stop and reframe before continuing.`
493
+ );
494
+ lines.push("");
495
+ for (const refusal of ast.refusals) {
496
+ lines.push(`### Refuse the ${refusal.name}`);
497
+ lines.push("");
498
+ lines.push(`**When**: ${refusal.when}`);
499
+ lines.push("");
500
+ lines.push(`**Do**: ${refusal.do}`);
501
+ lines.push("");
502
+ if (refusal.doNot.length > 0) {
503
+ lines.push(`**Do not**: ${refusal.doNot.map((d) => `\`${d}\``).join(", ")}`);
504
+ lines.push("");
505
+ }
506
+ if (refusal.reason) {
507
+ lines.push(`**Reason**: ${refusal.reason}`);
508
+ lines.push("");
509
+ }
510
+ }
511
+ this.appendProseAfter(lines, ast, "refusal");
512
+ }
513
+ if (ast.hardDonts.length > 0) {
514
+ lines.push(`## Hard don'ts (cross-provider red lines)`);
515
+ lines.push("");
516
+ lines.push(`| Name | Reason | Alternative |`);
517
+ lines.push(`|---|---|---|`);
518
+ for (const dont of ast.hardDonts) {
519
+ lines.push(
520
+ `| **${dont.name}** | ${dont.reason} | ${dont.alternative ?? "*(none)*"} |`
521
+ );
522
+ }
523
+ lines.push("");
524
+ this.appendProseAfter(lines, ast, "hard_dont");
525
+ }
526
+ if (ast.defaults.length > 0) {
527
+ lines.push(`## Known founder defaults (answer immediately)`);
528
+ lines.push("");
529
+ lines.push(`| When | Answer | Reason |`);
530
+ lines.push(`|---|---|---|`);
531
+ for (const def of ast.defaults) {
532
+ lines.push(
533
+ `| ${def.when} | **${def.do}** | ${def.reason ?? "*(no citation)*"} |`
534
+ );
535
+ }
536
+ lines.push("");
537
+ this.appendProseAfter(lines, ast, "default");
538
+ }
539
+ if (ast.domainPreferences.length > 0) {
540
+ lines.push("## Domain preferences (beyond engineering)");
541
+ lines.push("");
542
+ lines.push("| Domain | Skills to delegate to | Notes / ceiling |");
543
+ lines.push("|---|---|---|");
544
+ for (const pref of ast.domainPreferences) {
545
+ const skills = pref.skills.length > 0 ? pref.skills.map((s) => `\`${s}\``).join(", ") : "*(in-skill default)*";
546
+ const notesParts = [];
547
+ if (pref.ceiling) notesParts.push(`Ceiling: ${pref.ceiling}`);
548
+ if (pref.notes) notesParts.push(pref.notes);
549
+ const notes = notesParts.join("; ") || "";
550
+ lines.push(`| **${pref.domain}** | ${skills} | ${notes} |`);
551
+ }
552
+ lines.push("");
553
+ this.appendProseAfter(lines, ast, "domain_preference");
554
+ }
555
+ this.appendTrackBAuthority(lines, ast);
556
+ this.appendProseAfter(lines, ast, "authority");
557
+ this.appendPapersProgramDefaults(lines, ast);
558
+ this.appendProseAfter(lines, ast, "editorial_default");
559
+ this.appendProseAfter(lines, ast, "research_default");
560
+ if (ast.outputShape) {
561
+ lines.push(`## Output shape \u2014 SILENT-TO-JOSEPH, LOUD-TO-THE-AGENT`);
562
+ lines.push("");
563
+ lines.push(`- **Silent to**: ${ast.outputShape.silentTo}`);
564
+ lines.push(`- **Loud to**: ${ast.outputShape.loudTo}`);
565
+ if (ast.outputShape.noMetaOutput) {
566
+ lines.push(`- **No meta-output**: do not narrate the protocol back to the user`);
567
+ }
568
+ if (ast.outputShape.surfaceHint) {
569
+ lines.push(`- **Surface hint**: ${ast.outputShape.surfaceHint}`);
570
+ }
571
+ lines.push("");
572
+ this.appendProseAfter(lines, ast, "output_shape");
573
+ }
574
+ if (ast.productionRule) {
575
+ lines.push(`## Production-only rule (no dev, no mock, no localhost)`);
576
+ lines.push("");
577
+ if (ast.productionRule.noDevNoMockNoLocalhost) {
578
+ lines.push(`No dev. No mock. No localhost. The real service exists - hit it.`);
579
+ }
580
+ if (ast.productionRule.exception) {
581
+ lines.push("");
582
+ lines.push(`**Exception**: ${ast.productionRule.exception}`);
583
+ }
584
+ lines.push("");
585
+ this.appendProseAfter(lines, ast, "production_rule");
586
+ }
587
+ if (ast.hardPhysicalGaps.length > 0) {
588
+ lines.push(`## Hard physical gaps (skill never absorbs)`);
589
+ lines.push("");
590
+ for (const gap of ast.hardPhysicalGaps) {
591
+ lines.push(`- **${gap.name}** - ${gap.reason}`);
592
+ if (gap.alternative) {
593
+ lines.push(` - Alternative: ${gap.alternative}`);
594
+ }
595
+ }
596
+ lines.push("");
597
+ this.appendProseAfter(lines, ast, "hard_physical_gap");
598
+ }
599
+ if (ast.skills.length > 0) {
600
+ lines.push(`## Skills`);
601
+ lines.push("");
602
+ for (const skill of ast.skills) {
603
+ lines.push(`### \`${skill.invocableAs}\` - ${skill.name}`);
604
+ lines.push("");
605
+ lines.push(`**Authority**: ${skill.authority}`);
606
+ lines.push("");
607
+ if (skill.authoritativeFor.length > 0) {
608
+ lines.push(`**Authoritative for**: ${skill.authoritativeFor.join(", ")}`);
609
+ lines.push("");
610
+ }
611
+ if (skill.refusals && skill.refusals.length > 0) {
612
+ lines.push(`**Refusals enforced**: ${skill.refusals.join(", ")}`);
613
+ lines.push("");
614
+ }
615
+ }
616
+ this.appendProseAfter(lines, ast, "skill");
617
+ }
618
+ if (ast.invocationModes.length > 0) {
619
+ lines.push("## Invocation modes (Track D)");
620
+ lines.push("");
621
+ for (const mode of ast.invocationModes) {
622
+ lines.push(`### ${mode.mode}`);
623
+ lines.push("");
624
+ lines.push(`- **When**: ${mode.when}`);
625
+ lines.push(`- **Effect**: ${mode.effect}`);
626
+ if (mode.example) {
627
+ lines.push(`- **Example**: \`${mode.example}\``);
628
+ }
629
+ lines.push("");
630
+ }
631
+ this.appendProseAfter(lines, ast, "invocation_mode");
632
+ }
633
+ appendEmbodiedProjectionSection(lines, ast.embodiedProjections);
634
+ this.appendProseAfter(lines, ast, "embodied_projection");
635
+ if (ast.routines.length > 0) {
636
+ lines.push(`## Recurring routines (A-00X)`);
637
+ lines.push("");
638
+ lines.push(`| ID | Schedule | Skill | Output |`);
639
+ lines.push(`|---|---|---|---|`);
640
+ for (const routine of ast.routines) {
641
+ lines.push(
642
+ `| ${routine.id} | \`${routine.schedule}\` | ${routine.skill} | ${routine.outputDir ?? "*(varies)*"} |`
643
+ );
644
+ }
645
+ lines.push("");
646
+ this.appendProseAfter(lines, ast, "routine");
647
+ }
648
+ if (ast.escalations.length > 0) {
649
+ lines.push(`## Escape hatch`);
650
+ lines.push("");
651
+ for (const esc of ast.escalations) {
652
+ lines.push(`- **Trigger**: ${esc.trigger}`);
653
+ lines.push(` - **Action**: ${esc.doAction}`);
654
+ lines.push(` - **Recipient**: ${esc.recipient}`);
655
+ if (esc.refuseToEscalateWhen.length > 0) {
656
+ lines.push(
657
+ ` - **Refuse to escalate when**: ${esc.refuseToEscalateWhen.join(", ")}`
658
+ );
659
+ }
660
+ }
661
+ lines.push("");
662
+ this.appendProseAfter(lines, ast, "escalation");
663
+ }
664
+ if (ast.dateDisciplines.length > 0) {
665
+ const firstWisdom = ast.dateDisciplines[0]?.wisdomId;
666
+ const wisdomSuffix = ast.dateDisciplines.length === 1 && firstWisdom ? ` (${firstWisdom})` : "";
667
+ lines.push(`## Date discipline${wisdomSuffix}`);
668
+ lines.push("");
669
+ for (const d of ast.dateDisciplines) {
670
+ const wisdomLabel = d.wisdomId ? ` (${d.wisdomId})` : "";
671
+ lines.push(`### Refusal contract${wisdomLabel}`);
672
+ lines.push("");
673
+ lines.push(`**${d.refusalContract}**`);
674
+ lines.push("");
675
+ if (d.requiredComponents.length > 0) {
676
+ lines.push("**Required components** (all must be present):");
677
+ for (const comp of d.requiredComponents) {
678
+ lines.push(`- ${comp}`);
679
+ }
680
+ lines.push("");
681
+ }
682
+ if (d.shapeTemplate) {
683
+ lines.push("**Output shape**:");
684
+ lines.push("");
685
+ lines.push("```");
686
+ lines.push(d.shapeTemplate);
687
+ lines.push("```");
688
+ lines.push("");
689
+ }
690
+ if (d.reason) {
691
+ lines.push(`**Reason**: ${d.reason}`);
692
+ lines.push("");
693
+ }
694
+ if (d.crossReferences && d.crossReferences.length > 0) {
695
+ lines.push(`**Cross-references**: ${d.crossReferences.join(", ")}`);
696
+ lines.push("");
697
+ }
698
+ }
699
+ this.appendProseAfter(lines, ast, "date_discipline");
700
+ }
701
+ if (ast.citationRules.length > 0) {
702
+ lines.push(`## Citation discipline`);
703
+ lines.push("");
704
+ for (const rule of ast.citationRules) {
705
+ lines.push(
706
+ `- Fluent prose over **${rule.fluentProseThresholdChars} chars** must include one of: ${rule.required.join(", ")}`
707
+ );
708
+ if (rule.exemption) {
709
+ lines.push(` - Exemption: ${rule.exemption}`);
710
+ }
711
+ if (rule.reason) {
712
+ lines.push(` - Reason: ${rule.reason}`);
713
+ }
714
+ }
715
+ lines.push("");
716
+ this.appendProseAfter(lines, ast, "citation_rule");
717
+ }
718
+ if (ast.graduatedWisdoms.length > 0 || ast.feedbacks.length > 0) {
719
+ lines.push(`## Authority cross-references`);
720
+ lines.push("");
721
+ if (ast.graduatedWisdoms.length > 0) {
722
+ lines.push(`### GOLD-tier wisdom`);
723
+ lines.push("");
724
+ for (const wisdom of ast.graduatedWisdoms) {
725
+ lines.push(`- **${wisdom.id}** *(${wisdom.tier})* - ${wisdom.claim}`);
726
+ }
727
+ lines.push("");
728
+ }
729
+ if (ast.feedbacks.length > 0) {
730
+ lines.push(`### Feedback memory`);
731
+ lines.push("");
732
+ for (const fb of ast.feedbacks) {
733
+ const src = fb.source ? ` (${fb.source})` : "";
734
+ lines.push(`- **${fb.id}**${src} - ${fb.claim}`);
735
+ }
736
+ lines.push("");
737
+ }
738
+ this.appendProseAfter(lines, ast, "graduated_wisdom");
739
+ this.appendProseAfter(lines, ast, "feedback");
740
+ }
741
+ lines.push("---");
742
+ lines.push("");
743
+ lines.push(
744
+ `*Generated by HoloScript ContextCompiler (compile_to_claude_md). Source: HoloScript composition. Vocabulary: v3 (ratified 2026-05-07).*`
745
+ );
746
+ lines.push("");
747
+ return lines.join("\n");
748
+ }
749
+ // --- Phase 3: emit -- compile_to_agents_md -------------------------
750
+ /**
751
+ * Emit AGENTS.md - cross-tool agent context format. Read by Codex,
752
+ * Copilot, Cursor, Continue, Windsurf, Amp, Devin (any tool that
753
+ * follows the AGENTS.md convention seeded by the Codex docs).
754
+ *
755
+ * Differences from claude_md (per Phase 1 follow-up task spec):
756
+ * - "## Project principles" instead of "## Vision pillars"
757
+ * - "## Hard rules" instead of "## The Refusals" (Codex audience
758
+ * uses non-ritual rule-list framing; refusals + hard donts are
759
+ * merged into one flat ranked list under this single section)
760
+ * - "## Conventions" instead of "## Known defaults"
761
+ * - "## Workflows" instead of "## Skills" (Codex's closer term)
762
+ *
763
+ * Shared sections (authority order, output shape, production rule,
764
+ * hard physical gaps, recurring routines, escalation, citation
765
+ * discipline, authority cross-references) keep the same name across
766
+ * surfaces - those names are universal-context terms, not
767
+ * Claude-specific framings.
768
+ */
769
+ emitAgentsMd(ast) {
770
+ const lines = [];
771
+ lines.push("# AGENTS.md");
772
+ lines.push("");
773
+ if (ast.identity) {
774
+ lines.push(`> **Role**: ${ast.identity.role}`);
775
+ lines.push(`> **Domain**: ${ast.identity.domain}`);
776
+ lines.push(
777
+ `> **Surface**: ${ast.identity.surface} (cross-tool: read by Codex, Copilot, Cursor, Continue, Windsurf, Amp, Devin)`
778
+ );
779
+ if (ast.identity.noMonopoly) {
780
+ lines.push(
781
+ `> **No-monopoly rule**: this context applies the absorb-as-adapter architectural posture (per docs/LLM_CAPABILITIES.md section Architectural posture).`
782
+ );
783
+ }
784
+ lines.push("");
785
+ }
786
+ for (const opening of ast.narrativeOpenings) {
787
+ const postureLines = opening.posture.split(/\r?\n/);
788
+ for (const pl of postureLines) {
789
+ lines.push(`> ${pl}`);
790
+ }
791
+ if (opening.reason) {
792
+ const reasonLines = opening.reason.split(/\r?\n/);
793
+ for (const rl of reasonLines) {
794
+ lines.push(`> ${rl}`);
795
+ }
796
+ }
797
+ lines.push("");
798
+ }
799
+ if (ast.authorityOrder && ast.authorityOrder.tiers.length > 0) {
800
+ lines.push("## Authority order (read top-down; first match wins)");
801
+ lines.push("");
802
+ ast.authorityOrder.tiers.forEach((tier, idx) => {
803
+ lines.push(`${idx + 1}. **${tier}**`);
804
+ });
805
+ lines.push("");
806
+ this.appendProseAfter(lines, ast, "authority_order");
807
+ }
808
+ if (ast.visionPillars.length > 0) {
809
+ lines.push("## Project principles (follow; do not drift)");
810
+ lines.push("");
811
+ ast.visionPillars.forEach((pillar, idx) => {
812
+ const cite = pillar.citation ? ` *(${pillar.citation})*` : "";
813
+ lines.push(`${idx + 1}. **${pillar.claim}**${cite}`);
814
+ });
815
+ lines.push("");
816
+ this.appendProseAfter(lines, ast, "vision_pillar");
817
+ }
818
+ if (ast.refusals.length > 0 || ast.hardDonts.length > 0) {
819
+ lines.push("## Hard rules (The Four Refusals + cross-provider red lines)");
820
+ lines.push("");
821
+ lines.push(
822
+ "Rules below are non-negotiable. Each names what to do, what NOT to do, and why."
823
+ );
824
+ lines.push("");
825
+ for (const refusal of ast.refusals) {
826
+ lines.push(`### ${refusal.name}`);
827
+ lines.push("");
828
+ lines.push(`- **When**: ${refusal.when}`);
829
+ lines.push(`- **Do**: ${refusal.do}`);
830
+ if (refusal.doNot.length > 0) {
831
+ lines.push(`- **Do not**: ${refusal.doNot.map((d) => `\`${d}\``).join(", ")}`);
832
+ }
833
+ if (refusal.reason) {
834
+ lines.push(`- **Reason**: ${refusal.reason}`);
835
+ }
836
+ lines.push("");
837
+ }
838
+ for (const dont of ast.hardDonts) {
839
+ lines.push(`### ${dont.name}`);
840
+ lines.push("");
841
+ lines.push(`- **Reason**: ${dont.reason}`);
842
+ if (dont.alternative) {
843
+ lines.push(`- **Alternative**: ${dont.alternative}`);
844
+ }
845
+ if (dont.appliesTo.length > 0) {
846
+ lines.push(`- **Applies to**: ${dont.appliesTo.join(", ")}`);
847
+ }
848
+ lines.push("");
849
+ }
850
+ this.appendProseAfter(lines, ast, "refusal");
851
+ this.appendProseAfter(lines, ast, "hard_dont");
852
+ }
853
+ if (ast.defaults.length > 0) {
854
+ lines.push("## Conventions (answer immediately)");
855
+ lines.push("");
856
+ lines.push("| When | Do | Reason |");
857
+ lines.push("|---|---|---|");
858
+ for (const def of ast.defaults) {
859
+ lines.push(
860
+ `| ${def.when} | **${def.do}** | ${def.reason ?? "*(no citation)*"} |`
861
+ );
862
+ }
863
+ lines.push("");
864
+ this.appendProseAfter(lines, ast, "default");
865
+ }
866
+ if (ast.domainPreferences.length > 0) {
867
+ lines.push("## Domain preferences (beyond engineering)");
868
+ lines.push("");
869
+ lines.push("| Domain | Skills to delegate to | Notes / ceiling |");
870
+ lines.push("|---|---|---|");
871
+ for (const pref of ast.domainPreferences) {
872
+ const skills = pref.skills.length > 0 ? pref.skills.map((s) => `\`${s}\``).join(", ") : "*(in-skill default)*";
873
+ const notesParts = [];
874
+ if (pref.ceiling) notesParts.push(`Ceiling: ${pref.ceiling}`);
875
+ if (pref.notes) notesParts.push(pref.notes);
876
+ const notes = notesParts.join("; ") || "";
877
+ lines.push(`| **${pref.domain}** | ${skills} | ${notes} |`);
878
+ }
879
+ lines.push("");
880
+ this.appendProseAfter(lines, ast, "domain_preference");
881
+ }
882
+ this.appendTrackBAuthority(lines, ast);
883
+ this.appendProseAfter(lines, ast, "authority");
884
+ this.appendPapersProgramDefaults(lines, ast);
885
+ this.appendProseAfter(lines, ast, "editorial_default");
886
+ this.appendProseAfter(lines, ast, "research_default");
887
+ if (ast.outputShape) {
888
+ lines.push("## Output shape \u2014 SILENT-TO-JOSEPH, LOUD-TO-THE-AGENT");
889
+ lines.push("");
890
+ lines.push(`- **Silent to**: ${ast.outputShape.silentTo}`);
891
+ lines.push(`- **Loud to**: ${ast.outputShape.loudTo}`);
892
+ if (ast.outputShape.noMetaOutput) {
893
+ lines.push("- **No meta-output**: do not narrate the protocol back to the user");
894
+ }
895
+ if (ast.outputShape.surfaceHint) {
896
+ lines.push(`- **Surface hint**: ${ast.outputShape.surfaceHint}`);
897
+ }
898
+ lines.push("");
899
+ this.appendProseAfter(lines, ast, "output_shape");
900
+ }
901
+ if (ast.productionRule) {
902
+ lines.push("## Production-only rule (no dev, no mock, no localhost)");
903
+ lines.push("");
904
+ if (ast.productionRule.noDevNoMockNoLocalhost) {
905
+ lines.push("No dev. No mock. No localhost. The real service exists - hit it.");
906
+ }
907
+ if (ast.productionRule.exception) {
908
+ lines.push("");
909
+ lines.push(`**Exception**: ${ast.productionRule.exception}`);
910
+ }
911
+ lines.push("");
912
+ this.appendProseAfter(lines, ast, "production_rule");
913
+ }
914
+ if (ast.hardPhysicalGaps.length > 0) {
915
+ lines.push("## Hard physical gaps (never absorb)");
916
+ lines.push("");
917
+ for (const gap of ast.hardPhysicalGaps) {
918
+ lines.push(`- **${gap.name}** - ${gap.reason}`);
919
+ if (gap.alternative) {
920
+ lines.push(` - Alternative: ${gap.alternative}`);
921
+ }
922
+ }
923
+ lines.push("");
924
+ this.appendProseAfter(lines, ast, "hard_physical_gap");
925
+ }
926
+ if (ast.skills.length > 0) {
927
+ lines.push("## Workflows");
928
+ lines.push("");
929
+ for (const skill of ast.skills) {
930
+ lines.push(`### ${skill.name} (\`${skill.invocableAs}\`)`);
931
+ lines.push("");
932
+ lines.push(`- **Authority**: ${skill.authority}`);
933
+ if (skill.authoritativeFor.length > 0) {
934
+ lines.push(`- **Authoritative for**: ${skill.authoritativeFor.join(", ")}`);
935
+ }
936
+ if (skill.refusals && skill.refusals.length > 0) {
937
+ lines.push(`- **Enforces rules**: ${skill.refusals.join(", ")}`);
938
+ }
939
+ lines.push("");
940
+ }
941
+ this.appendProseAfter(lines, ast, "skill");
942
+ }
943
+ if (ast.invocationModes.length > 0) {
944
+ lines.push("## Invocation modes (Track D)");
945
+ lines.push("");
946
+ for (const mode of ast.invocationModes) {
947
+ lines.push(`### ${mode.mode}`);
948
+ lines.push("");
949
+ lines.push(`- **When**: ${mode.when}`);
950
+ lines.push(`- **Effect**: ${mode.effect}`);
951
+ if (mode.example) {
952
+ lines.push(`- **Example**: \`${mode.example}\``);
953
+ }
954
+ lines.push("");
955
+ }
956
+ this.appendProseAfter(lines, ast, "invocation_mode");
957
+ }
958
+ appendEmbodiedProjectionSection(lines, ast.embodiedProjections);
959
+ this.appendProseAfter(lines, ast, "embodied_projection");
960
+ if (ast.routines.length > 0) {
961
+ lines.push("## Recurring routines (A-00X)");
962
+ lines.push("");
963
+ lines.push("| ID | Schedule | Skill | Output |");
964
+ lines.push("|---|---|---|---|");
965
+ for (const routine of ast.routines) {
966
+ lines.push(
967
+ `| ${routine.id} | \`${routine.schedule}\` | ${routine.skill} | ${routine.outputDir ?? "*(varies)*"} |`
968
+ );
969
+ }
970
+ lines.push("");
971
+ this.appendProseAfter(lines, ast, "routine");
972
+ }
973
+ if (ast.escalations.length > 0) {
974
+ lines.push("## Escape hatch");
975
+ lines.push("");
976
+ for (const esc of ast.escalations) {
977
+ lines.push(`- **Trigger**: ${esc.trigger}`);
978
+ lines.push(` - **Action**: ${esc.doAction}`);
979
+ lines.push(` - **Recipient**: ${esc.recipient}`);
980
+ if (esc.refuseToEscalateWhen.length > 0) {
981
+ lines.push(
982
+ ` - **Refuse to escalate when**: ${esc.refuseToEscalateWhen.join(", ")}`
983
+ );
984
+ }
985
+ }
986
+ lines.push("");
987
+ this.appendProseAfter(lines, ast, "escalation");
988
+ }
989
+ if (ast.dateDisciplines.length > 0) {
990
+ const firstWisdom = ast.dateDisciplines[0]?.wisdomId;
991
+ const wisdomSuffix = ast.dateDisciplines.length === 1 && firstWisdom ? ` (${firstWisdom})` : "";
992
+ lines.push(`## Date discipline${wisdomSuffix}`);
993
+ lines.push("");
994
+ for (const d of ast.dateDisciplines) {
995
+ const wisdomLabel = d.wisdomId ? ` (${d.wisdomId})` : "";
996
+ lines.push(`### Refusal contract${wisdomLabel}`);
997
+ lines.push("");
998
+ lines.push(`**${d.refusalContract}**`);
999
+ lines.push("");
1000
+ if (d.requiredComponents.length > 0) {
1001
+ lines.push("**Required components** (all must be present):");
1002
+ for (const comp of d.requiredComponents) {
1003
+ lines.push(`- ${comp}`);
1004
+ }
1005
+ lines.push("");
1006
+ }
1007
+ if (d.shapeTemplate) {
1008
+ lines.push("**Output shape**:");
1009
+ lines.push("");
1010
+ lines.push("```");
1011
+ lines.push(d.shapeTemplate);
1012
+ lines.push("```");
1013
+ lines.push("");
1014
+ }
1015
+ if (d.reason) {
1016
+ lines.push(`**Reason**: ${d.reason}`);
1017
+ lines.push("");
1018
+ }
1019
+ if (d.crossReferences && d.crossReferences.length > 0) {
1020
+ lines.push(`**Cross-references**: ${d.crossReferences.join(", ")}`);
1021
+ lines.push("");
1022
+ }
1023
+ }
1024
+ this.appendProseAfter(lines, ast, "date_discipline");
1025
+ }
1026
+ if (ast.citationRules.length > 0) {
1027
+ lines.push("## Citation discipline");
1028
+ lines.push("");
1029
+ for (const rule of ast.citationRules) {
1030
+ lines.push(
1031
+ `- Fluent prose over **${rule.fluentProseThresholdChars} chars** must include one of: ${rule.required.join(", ")}`
1032
+ );
1033
+ if (rule.exemption) {
1034
+ lines.push(` - Exemption: ${rule.exemption}`);
1035
+ }
1036
+ if (rule.reason) {
1037
+ lines.push(` - Reason: ${rule.reason}`);
1038
+ }
1039
+ }
1040
+ lines.push("");
1041
+ this.appendProseAfter(lines, ast, "citation_rule");
1042
+ }
1043
+ if (ast.graduatedWisdoms.length > 0 || ast.feedbacks.length > 0) {
1044
+ lines.push("## Authority cross-references");
1045
+ lines.push("");
1046
+ if (ast.graduatedWisdoms.length > 0) {
1047
+ lines.push("### GOLD-tier wisdom");
1048
+ lines.push("");
1049
+ for (const wisdom of ast.graduatedWisdoms) {
1050
+ lines.push(`- **${wisdom.id}** *(${wisdom.tier})* - ${wisdom.claim}`);
1051
+ }
1052
+ lines.push("");
1053
+ }
1054
+ if (ast.feedbacks.length > 0) {
1055
+ lines.push("### Feedback memory");
1056
+ lines.push("");
1057
+ for (const fb of ast.feedbacks) {
1058
+ const src = fb.source ? ` (${fb.source})` : "";
1059
+ lines.push(`- **${fb.id}**${src} - ${fb.claim}`);
1060
+ }
1061
+ lines.push("");
1062
+ }
1063
+ this.appendProseAfter(lines, ast, "graduated_wisdom");
1064
+ this.appendProseAfter(lines, ast, "feedback");
1065
+ }
1066
+ lines.push("---");
1067
+ lines.push("");
1068
+ lines.push(
1069
+ `*Generated by HoloScript ContextCompiler (compile_to_agents_md). Source: HoloScript composition. Vocabulary: v3 (ratified 2026-05-07). Cross-tool: Codex, Copilot, Cursor, Continue, Windsurf, Amp, Devin.*`
1070
+ );
1071
+ lines.push("");
1072
+ return lines.join("\n");
1073
+ }
1074
+ // --- Phase 3: emit -- compile_to_cursor_rules ----------------------
1075
+ /**
1076
+ * Emit Cursor `.cursor/rules/*.mdc` files. Different output shape from
1077
+ * claude_md / agents_md - one file per rule rather than a single big
1078
+ * file (Cursor's idiom). Per spec:
1079
+ * research/2026-05-06_cursor-mdc-spec.md.
1080
+ *
1081
+ * Layout:
1082
+ * .cursor/rules/refusal-<name>.mdc (one per @refusal)
1083
+ * .cursor/rules/hard-dont-<name>.mdc (one per @hard_dont)
1084
+ * .cursor/rules/default-<name>.mdc (one per @default)
1085
+ * .cursor/rules/_ecosystem-context.mdc (top-level blocks: identity,
1086
+ * authority order, vision
1087
+ * pillars, production rule,
1088
+ * output shape, gaps, routines,
1089
+ * skill registry, cross-refs)
1090
+ *
1091
+ * Frontmatter v1: every file emits with `alwaysApply: true` and empty
1092
+ * `globs:`. Glob mapping from `applies_to` -> file patterns is deferred
1093
+ * to v2 (see spec memo § "What the emitter does NOT do (v1 scope)").
1094
+ *
1095
+ * Returns Record<string, string> with full repo-relative paths as keys
1096
+ * (e.g. ".cursor/rules/refusal-bandaid.mdc"). The consumer writes each
1097
+ * entry to disk at exactly that path.
1098
+ */
1099
+ emitCursorRules(ast) {
1100
+ const out = {};
1101
+ for (const refusal of ast.refusals) {
1102
+ const slug = toCursorSlug(refusal.name);
1103
+ const filename = `.cursor/rules/refusal-${slug}.mdc`;
1104
+ const description = oneLine(
1105
+ `Refusal: ${refusal.name} - ${refusal.reason ?? refusal.when}`
1106
+ );
1107
+ const body = [];
1108
+ body.push(`# Refusal: ${refusal.name}`);
1109
+ body.push("");
1110
+ body.push(`**When**: ${refusal.when}`);
1111
+ body.push("");
1112
+ body.push(`**Do**: ${refusal.do}`);
1113
+ body.push("");
1114
+ if (refusal.doNot.length > 0) {
1115
+ body.push(`**Do not**: ${refusal.doNot.map((d) => `\`${d}\``).join(", ")}`);
1116
+ body.push("");
1117
+ }
1118
+ if (refusal.reason) {
1119
+ body.push(`**Reason**: ${refusal.reason}`);
1120
+ body.push("");
1121
+ }
1122
+ out[filename] = wrapMdc(description, body);
1123
+ }
1124
+ for (const dont of ast.hardDonts) {
1125
+ const slug = toCursorSlug(dont.name);
1126
+ const filename = `.cursor/rules/hard-dont-${slug}.mdc`;
1127
+ const description = oneLine(`Hard don't: ${dont.name} - ${dont.reason}`);
1128
+ const body = [];
1129
+ body.push(`# Hard don't: ${dont.name}`);
1130
+ body.push("");
1131
+ body.push(`**Reason**: ${dont.reason}`);
1132
+ body.push("");
1133
+ if (dont.alternative) {
1134
+ body.push(`**Alternative**: ${dont.alternative}`);
1135
+ body.push("");
1136
+ }
1137
+ if (dont.appliesTo.length > 0) {
1138
+ body.push(`**Applies to**: ${dont.appliesTo.join(", ")}`);
1139
+ body.push("");
1140
+ }
1141
+ out[filename] = wrapMdc(description, body);
1142
+ }
1143
+ for (const def of ast.defaults) {
1144
+ const slug = toCursorSlug(def.name);
1145
+ const filename = `.cursor/rules/default-${slug}.mdc`;
1146
+ const description = oneLine(`Default: ${def.name} - ${def.when}`);
1147
+ const body = [];
1148
+ body.push(`# Default: ${def.name}`);
1149
+ body.push("");
1150
+ body.push(`**When**: ${def.when}`);
1151
+ body.push("");
1152
+ body.push(`**Do**: ${def.do}`);
1153
+ body.push("");
1154
+ if (def.reason) {
1155
+ body.push(`**Reason**: ${def.reason}`);
1156
+ body.push("");
1157
+ }
1158
+ out[filename] = wrapMdc(description, body);
1159
+ }
1160
+ const indexFilename = ".cursor/rules/_ecosystem-context.mdc";
1161
+ const indexDescription = ast.identity ? oneLine(`Ecosystem context for ${ast.identity.name} (${ast.identity.role})`) : "Ecosystem context (HoloScript-generated)";
1162
+ const idx = [];
1163
+ if (ast.identity) {
1164
+ idx.push(`# ${ast.identity.name}`);
1165
+ idx.push("");
1166
+ idx.push(`**Role**: ${ast.identity.role}`);
1167
+ idx.push(`**Domain**: ${ast.identity.domain}`);
1168
+ idx.push(`**Surface**: ${ast.identity.surface}`);
1169
+ if (ast.identity.noMonopoly) {
1170
+ idx.push("");
1171
+ idx.push(
1172
+ "No-monopoly rule: this context applies the absorb-as-adapter architectural posture (per docs/LLM_CAPABILITIES.md)."
1173
+ );
1174
+ }
1175
+ idx.push("");
1176
+ } else {
1177
+ idx.push("# Ecosystem context");
1178
+ idx.push("");
1179
+ }
1180
+ for (const opening of ast.narrativeOpenings) {
1181
+ const postureLines = opening.posture.split(/\r?\n/);
1182
+ for (const pl of postureLines) {
1183
+ idx.push(`> ${pl}`);
1184
+ }
1185
+ if (opening.reason) {
1186
+ const reasonLines = opening.reason.split(/\r?\n/);
1187
+ for (const rl of reasonLines) {
1188
+ idx.push(`> ${rl}`);
1189
+ }
1190
+ }
1191
+ idx.push("");
1192
+ }
1193
+ if (ast.authorityOrder && ast.authorityOrder.tiers.length > 0) {
1194
+ idx.push("## Authority order (read top-down; first match wins)");
1195
+ idx.push("");
1196
+ ast.authorityOrder.tiers.forEach((tier, i) => {
1197
+ idx.push(`${i + 1}. **${tier}**`);
1198
+ });
1199
+ idx.push("");
1200
+ this.appendProseAfter(idx, ast, "authority_order");
1201
+ }
1202
+ if (ast.visionPillars.length > 0) {
1203
+ idx.push("## Vision pillars (follow; do not drift)");
1204
+ idx.push("");
1205
+ ast.visionPillars.forEach((pillar, i) => {
1206
+ const cite = pillar.citation ? ` *(${pillar.citation})*` : "";
1207
+ idx.push(`${i + 1}. **${pillar.claim}**${cite}`);
1208
+ });
1209
+ idx.push("");
1210
+ this.appendProseAfter(idx, ast, "vision_pillar");
1211
+ }
1212
+ if (ast.domainPreferences.length > 0) {
1213
+ idx.push("## Domain preferences (beyond engineering)");
1214
+ idx.push("");
1215
+ idx.push("| Domain | Skills to delegate to | Notes / ceiling |");
1216
+ idx.push("|---|---|---|");
1217
+ for (const pref of ast.domainPreferences) {
1218
+ const skills = pref.skills.length > 0 ? pref.skills.map((s) => `\`${s}\``).join(", ") : "*(in-skill default)*";
1219
+ const notesParts = [];
1220
+ if (pref.ceiling) notesParts.push(`Ceiling: ${pref.ceiling}`);
1221
+ if (pref.notes) notesParts.push(pref.notes);
1222
+ const notes = notesParts.join("; ") || "";
1223
+ idx.push(`| **${pref.domain}** | ${skills} | ${notes} |`);
1224
+ }
1225
+ idx.push("");
1226
+ this.appendProseAfter(idx, ast, "domain_preference");
1227
+ }
1228
+ this.appendTrackBAuthority(idx, ast);
1229
+ this.appendProseAfter(idx, ast, "authority");
1230
+ this.appendPapersProgramDefaults(idx, ast);
1231
+ this.appendProseAfter(idx, ast, "editorial_default");
1232
+ this.appendProseAfter(idx, ast, "research_default");
1233
+ if (ast.outputShape) {
1234
+ idx.push("## Output shape \u2014 SILENT-TO-JOSEPH, LOUD-TO-THE-AGENT");
1235
+ idx.push("");
1236
+ idx.push(`- **Silent to**: ${ast.outputShape.silentTo}`);
1237
+ idx.push(`- **Loud to**: ${ast.outputShape.loudTo}`);
1238
+ if (ast.outputShape.noMetaOutput) {
1239
+ idx.push("- **No meta-output**: do not narrate the protocol back to the user");
1240
+ }
1241
+ if (ast.outputShape.surfaceHint) {
1242
+ idx.push(`- **Surface hint**: ${ast.outputShape.surfaceHint}`);
1243
+ }
1244
+ idx.push("");
1245
+ this.appendProseAfter(idx, ast, "output_shape");
1246
+ }
1247
+ if (ast.productionRule) {
1248
+ idx.push("## Production-only rule (no dev, no mock, no localhost)");
1249
+ idx.push("");
1250
+ if (ast.productionRule.noDevNoMockNoLocalhost) {
1251
+ idx.push("No dev. No mock. No localhost. The real service exists - hit it.");
1252
+ }
1253
+ if (ast.productionRule.exception) {
1254
+ idx.push("");
1255
+ idx.push(`**Exception**: ${ast.productionRule.exception}`);
1256
+ }
1257
+ idx.push("");
1258
+ this.appendProseAfter(idx, ast, "production_rule");
1259
+ }
1260
+ if (ast.hardPhysicalGaps.length > 0) {
1261
+ idx.push("## Hard physical gaps (skill never absorbs)");
1262
+ idx.push("");
1263
+ for (const gap of ast.hardPhysicalGaps) {
1264
+ idx.push(`- **${gap.name}** - ${gap.reason}`);
1265
+ if (gap.alternative) {
1266
+ idx.push(` - Alternative: ${gap.alternative}`);
1267
+ }
1268
+ }
1269
+ idx.push("");
1270
+ this.appendProseAfter(idx, ast, "hard_physical_gap");
1271
+ }
1272
+ if (ast.skills.length > 0) {
1273
+ idx.push("## Skill registry");
1274
+ idx.push("");
1275
+ for (const skill of ast.skills) {
1276
+ idx.push(`- **${skill.invocableAs}** (${skill.name}) - ${skill.authority}`);
1277
+ }
1278
+ idx.push("");
1279
+ this.appendProseAfter(idx, ast, "skill");
1280
+ }
1281
+ if (ast.invocationModes.length > 0) {
1282
+ idx.push("## Invocation modes (Track D)");
1283
+ idx.push("");
1284
+ for (const mode of ast.invocationModes) {
1285
+ idx.push(`### ${mode.mode}`);
1286
+ idx.push("");
1287
+ idx.push(`- **When**: ${mode.when}`);
1288
+ idx.push(`- **Effect**: ${mode.effect}`);
1289
+ if (mode.example) {
1290
+ idx.push(`- **Example**: \`${mode.example}\``);
1291
+ }
1292
+ idx.push("");
1293
+ }
1294
+ this.appendProseAfter(idx, ast, "invocation_mode");
1295
+ }
1296
+ appendEmbodiedProjectionSection(idx, ast.embodiedProjections);
1297
+ this.appendProseAfter(idx, ast, "embodied_projection");
1298
+ if (ast.routines.length > 0) {
1299
+ idx.push("## Recurring routines (A-00X)");
1300
+ idx.push("");
1301
+ idx.push("| ID | Schedule | Skill | Output |");
1302
+ idx.push("|---|---|---|---|");
1303
+ for (const routine of ast.routines) {
1304
+ idx.push(
1305
+ `| ${routine.id} | \`${routine.schedule}\` | ${routine.skill} | ${routine.outputDir ?? "*(varies)*"} |`
1306
+ );
1307
+ }
1308
+ idx.push("");
1309
+ this.appendProseAfter(idx, ast, "routine");
1310
+ }
1311
+ if (ast.escalations.length > 0) {
1312
+ idx.push("## Escape hatch");
1313
+ idx.push("");
1314
+ for (const esc of ast.escalations) {
1315
+ idx.push(`- **Trigger**: ${esc.trigger}`);
1316
+ idx.push(` - **Action**: ${esc.doAction}`);
1317
+ idx.push(` - **Recipient**: ${esc.recipient}`);
1318
+ if (esc.refuseToEscalateWhen.length > 0) {
1319
+ idx.push(
1320
+ ` - **Refuse to escalate when**: ${esc.refuseToEscalateWhen.join(", ")}`
1321
+ );
1322
+ }
1323
+ }
1324
+ idx.push("");
1325
+ this.appendProseAfter(idx, ast, "escalation");
1326
+ }
1327
+ if (ast.dateDisciplines.length > 0) {
1328
+ const firstWisdom = ast.dateDisciplines[0]?.wisdomId;
1329
+ const wisdomSuffix = ast.dateDisciplines.length === 1 && firstWisdom ? ` (${firstWisdom})` : "";
1330
+ idx.push(`## Date discipline${wisdomSuffix}`);
1331
+ idx.push("");
1332
+ for (const d of ast.dateDisciplines) {
1333
+ const wisdomLabel = d.wisdomId ? ` (${d.wisdomId})` : "";
1334
+ idx.push(`### Refusal contract${wisdomLabel}`);
1335
+ idx.push("");
1336
+ idx.push(`**${d.refusalContract}**`);
1337
+ idx.push("");
1338
+ if (d.requiredComponents.length > 0) {
1339
+ idx.push("**Required components** (all must be present):");
1340
+ for (const comp of d.requiredComponents) {
1341
+ idx.push(`- ${comp}`);
1342
+ }
1343
+ idx.push("");
1344
+ }
1345
+ if (d.shapeTemplate) {
1346
+ idx.push("**Output shape**:");
1347
+ idx.push("");
1348
+ idx.push("```");
1349
+ idx.push(d.shapeTemplate);
1350
+ idx.push("```");
1351
+ idx.push("");
1352
+ }
1353
+ if (d.reason) {
1354
+ idx.push(`**Reason**: ${d.reason}`);
1355
+ idx.push("");
1356
+ }
1357
+ if (d.crossReferences && d.crossReferences.length > 0) {
1358
+ idx.push(`**Cross-references**: ${d.crossReferences.join(", ")}`);
1359
+ idx.push("");
1360
+ }
1361
+ }
1362
+ this.appendProseAfter(idx, ast, "date_discipline");
1363
+ }
1364
+ if (ast.citationRules.length > 0) {
1365
+ idx.push("## Citation discipline");
1366
+ idx.push("");
1367
+ for (const rule of ast.citationRules) {
1368
+ idx.push(
1369
+ `- Fluent prose over **${rule.fluentProseThresholdChars} chars** must include one of: ${rule.required.join(", ")}`
1370
+ );
1371
+ if (rule.exemption) {
1372
+ idx.push(` - Exemption: ${rule.exemption}`);
1373
+ }
1374
+ if (rule.reason) {
1375
+ idx.push(` - Reason: ${rule.reason}`);
1376
+ }
1377
+ }
1378
+ idx.push("");
1379
+ this.appendProseAfter(idx, ast, "citation_rule");
1380
+ }
1381
+ if (ast.graduatedWisdoms.length > 0 || ast.feedbacks.length > 0) {
1382
+ idx.push("## Authority cross-references");
1383
+ idx.push("");
1384
+ if (ast.graduatedWisdoms.length > 0) {
1385
+ idx.push("### GOLD-tier wisdom");
1386
+ idx.push("");
1387
+ for (const wisdom of ast.graduatedWisdoms) {
1388
+ idx.push(`- **${wisdom.id}** *(${wisdom.tier})* - ${wisdom.claim}`);
1389
+ }
1390
+ idx.push("");
1391
+ }
1392
+ if (ast.feedbacks.length > 0) {
1393
+ idx.push("### Feedback memory");
1394
+ idx.push("");
1395
+ for (const fb of ast.feedbacks) {
1396
+ const src = fb.source ? ` (${fb.source})` : "";
1397
+ idx.push(`- **${fb.id}**${src} - ${fb.claim}`);
1398
+ }
1399
+ idx.push("");
1400
+ }
1401
+ this.appendProseAfter(idx, ast, "graduated_wisdom");
1402
+ this.appendProseAfter(idx, ast, "feedback");
1403
+ }
1404
+ idx.push("---");
1405
+ idx.push("");
1406
+ idx.push(
1407
+ "*Generated by HoloScript ContextCompiler (compile_to_cursor_rules). Source: HoloScript composition. Vocabulary: v3 (ratified 2026-05-07). Per-rule files emit alongside this index under .cursor/rules/.*"
1408
+ );
1409
+ idx.push("");
1410
+ out[indexFilename] = wrapMdc(indexDescription, idx);
1411
+ return out;
1412
+ }
1413
+ // --- Phase 3: emit -- compile_to_skill_md --------------------------
1414
+ /**
1415
+ * Emit SKILL.md - Claude Code skill format. Read by Claude Code's
1416
+ * skill discovery system at `~/.claude/skills/<name>/SKILL.md` and
1417
+ * `<repo>/.claude/skills/<name>/SKILL.md` (per-window per-repo
1418
+ * skills are loaded into the available-skills block at session start).
1419
+ *
1420
+ * Format differs from claude_md / agents_md / cursor_rules: Claude
1421
+ * Code parses a YAML frontmatter block at the top of the file
1422
+ * (`name:`, `description:`, `allowed-tools:`) for skill registration,
1423
+ * THEN reads the markdown body as the skill prompt. The frontmatter
1424
+ * is what makes a SKILL.md invocable as `/<name>`.
1425
+ *
1426
+ * Phase 2(a) target: this emitter is the dependency for self-hosting
1427
+ * the founder skill - `compositions/founder.hs` becomes source-of-
1428
+ * truth, `~/.claude/skills/founder/SKILL.md` becomes the emitted
1429
+ * artifact. Round-trip parity is the validation gate.
1430
+ *
1431
+ * Source fields:
1432
+ * - frontmatter `name:` <- ContextIdentity.name
1433
+ * - frontmatter `description:` <- ContextIdentity.description (required
1434
+ * for skill discovery; emitter throws if missing - Claude Code
1435
+ * refuses to register a skill without one)
1436
+ * - frontmatter `allowed-tools:` <- ContextIdentity.allowedTools
1437
+ * (defaults to a sensible cross-tool set if omitted)
1438
+ *
1439
+ * Body sections mirror agents_md / claude_md - same vocabulary, same
1440
+ * authority order, same refusals, etc. - so the agent's operational
1441
+ * behavior is consistent across surfaces.
1442
+ */
1443
+ emitSkillMd(ast) {
1444
+ if (!ast.identity) {
1445
+ throw new ContextCompileError(
1446
+ `compile_to_skill_md requires an @identity trait. Claude Code's skill discovery reads the YAML frontmatter \`name:\` field, which comes from ContextIdentity.name. Add an @identity block to the composition.`
1447
+ );
1448
+ }
1449
+ if (!ast.identity.description) {
1450
+ throw new ContextCompileError(
1451
+ `compile_to_skill_md requires @identity.description. Claude Code refuses to register a skill without a description (skill discovery gate). Add a 'description' field to the @identity trait.`
1452
+ );
1453
+ }
1454
+ const lines = [];
1455
+ lines.push("---");
1456
+ lines.push(`name: ${yamlScalar(ast.identity.name)}`);
1457
+ let enrichedDescription = ast.identity.description;
1458
+ if (ast.triggerPhrases.length > 0) {
1459
+ enrichedDescription += "\n\nTrigger phrases:";
1460
+ for (const tp of ast.triggerPhrases) {
1461
+ enrichedDescription += `
1462
+ - "${tp.phrase}"${tp.context ? ` (${tp.context})` : ""}`;
1463
+ }
1464
+ }
1465
+ lines.push(formatYamlDescription(enrichedDescription));
1466
+ const tools = ast.identity.allowedTools && ast.identity.allowedTools.length > 0 ? ast.identity.allowedTools : ["Bash", "Read", "Write", "Edit", "Grep", "Glob", "WebFetch"];
1467
+ lines.push(`allowed-tools: ${tools.join(", ")}`);
1468
+ lines.push("---");
1469
+ lines.push("");
1470
+ lines.push(`# ${ast.identity.name}`);
1471
+ lines.push("");
1472
+ lines.push(`> **Role**: ${ast.identity.role}`);
1473
+ lines.push(`> **Domain**: ${ast.identity.domain}`);
1474
+ lines.push(`> **Surface**: ${ast.identity.surface}`);
1475
+ if (ast.identity.noMonopoly) {
1476
+ lines.push(
1477
+ `> **No-monopoly rule**: this skill applies the absorb-as-adapter architectural posture (per docs/LLM_CAPABILITIES.md section Architectural posture).`
1478
+ );
1479
+ }
1480
+ lines.push("");
1481
+ if (ast.identity.commandTemplate) {
1482
+ lines.push(`**Command**: ${ast.identity.commandTemplate}`);
1483
+ lines.push("");
1484
+ }
1485
+ for (const opening of ast.narrativeOpenings) {
1486
+ const postureLines = opening.posture.split(/\r?\n/);
1487
+ for (const pl of postureLines) {
1488
+ lines.push(`> ${pl}`);
1489
+ }
1490
+ if (opening.reason) {
1491
+ const reasonLines = opening.reason.split(/\r?\n/);
1492
+ for (const rl of reasonLines) {
1493
+ lines.push(`> ${rl}`);
1494
+ }
1495
+ }
1496
+ lines.push("");
1497
+ }
1498
+ if (ast.authorityOrder && ast.authorityOrder.tiers.length > 0) {
1499
+ lines.push("## Authority order (read top-down; first match wins)");
1500
+ lines.push("");
1501
+ ast.authorityOrder.tiers.forEach((tier, idx) => {
1502
+ lines.push(`${idx + 1}. **${tier}**`);
1503
+ });
1504
+ lines.push("");
1505
+ this.appendProseAfter(lines, ast, "authority_order");
1506
+ }
1507
+ if (ast.visionPillars.length > 0) {
1508
+ lines.push("## Vision pillars (follow; do not drift)");
1509
+ lines.push("");
1510
+ ast.visionPillars.forEach((pillar, idx) => {
1511
+ const cite = pillar.citation ? ` *(${pillar.citation})*` : "";
1512
+ lines.push(`${idx + 1}. **${pillar.claim}**${cite}`);
1513
+ });
1514
+ lines.push("");
1515
+ this.appendProseAfter(lines, ast, "vision_pillar");
1516
+ }
1517
+ if (ast.refusals.length > 0) {
1518
+ lines.push("## The Four Refusals");
1519
+ lines.push("");
1520
+ lines.push(
1521
+ "These are not guidelines. They are refusals. If you catch yourself about to do any of the following, stop and reframe before continuing."
1522
+ );
1523
+ lines.push("");
1524
+ for (const refusal of ast.refusals) {
1525
+ lines.push(`### Refuse the ${refusal.name}`);
1526
+ lines.push("");
1527
+ lines.push(`**When**: ${refusal.when}`);
1528
+ lines.push("");
1529
+ lines.push(`**Do**: ${refusal.do}`);
1530
+ lines.push("");
1531
+ if (refusal.doNot.length > 0) {
1532
+ lines.push(`**Do not**: ${refusal.doNot.map((d) => `\`${d}\``).join(", ")}`);
1533
+ lines.push("");
1534
+ }
1535
+ if (refusal.reason) {
1536
+ lines.push(`**Reason**: ${refusal.reason}`);
1537
+ lines.push("");
1538
+ }
1539
+ }
1540
+ this.appendProseAfter(lines, ast, "refusal");
1541
+ }
1542
+ if (ast.hardDonts.length > 0) {
1543
+ lines.push("## Hard don'ts (cross-provider red lines)");
1544
+ lines.push("");
1545
+ lines.push(`| Name | Reason | Alternative |`);
1546
+ lines.push(`|---|---|---|`);
1547
+ for (const dont of ast.hardDonts) {
1548
+ lines.push(
1549
+ `| **${dont.name}** | ${dont.reason} | ${dont.alternative ?? "*(none)*"} |`
1550
+ );
1551
+ }
1552
+ lines.push("");
1553
+ this.appendProseAfter(lines, ast, "hard_dont");
1554
+ }
1555
+ if (ast.defaults.length > 0) {
1556
+ lines.push("## Known founder defaults (answer immediately)");
1557
+ lines.push("");
1558
+ lines.push(`| When | Answer | Reason |`);
1559
+ lines.push(`|---|---|---|`);
1560
+ for (const def of ast.defaults) {
1561
+ lines.push(
1562
+ `| ${def.when} | **${def.do}** | ${def.reason ?? "*(no citation)*"} |`
1563
+ );
1564
+ }
1565
+ lines.push("");
1566
+ this.appendProseAfter(lines, ast, "default");
1567
+ }
1568
+ if (ast.domainPreferences.length > 0) {
1569
+ lines.push("## Domain preferences (beyond engineering)");
1570
+ lines.push("");
1571
+ lines.push("| Domain | Skills to delegate to | Notes / ceiling |");
1572
+ lines.push("|---|---|---|");
1573
+ for (const pref of ast.domainPreferences) {
1574
+ const skills = pref.skills.length > 0 ? pref.skills.map((s) => `\`${s}\``).join(", ") : "*(in-skill default)*";
1575
+ const notesParts = [];
1576
+ if (pref.ceiling) notesParts.push(`Ceiling: ${pref.ceiling}`);
1577
+ if (pref.notes) notesParts.push(pref.notes);
1578
+ const notes = notesParts.join("; ") || "";
1579
+ lines.push(`| **${pref.domain}** | ${skills} | ${notes} |`);
1580
+ }
1581
+ lines.push("");
1582
+ this.appendProseAfter(lines, ast, "domain_preference");
1583
+ }
1584
+ this.appendTrackBAuthority(lines, ast);
1585
+ this.appendProseAfter(lines, ast, "authority");
1586
+ this.appendPapersProgramDefaults(lines, ast);
1587
+ this.appendProseAfter(lines, ast, "editorial_default");
1588
+ this.appendProseAfter(lines, ast, "research_default");
1589
+ if (ast.outputShape) {
1590
+ lines.push("## Output shape \u2014 SILENT-TO-JOSEPH, LOUD-TO-THE-AGENT");
1591
+ lines.push("");
1592
+ lines.push(`- **Silent to**: ${ast.outputShape.silentTo}`);
1593
+ lines.push(`- **Loud to**: ${ast.outputShape.loudTo}`);
1594
+ if (ast.outputShape.noMetaOutput) {
1595
+ lines.push("- **No meta-output**: do not narrate the protocol back to the user");
1596
+ }
1597
+ if (ast.outputShape.surfaceHint) {
1598
+ lines.push(`- **Surface hint**: ${ast.outputShape.surfaceHint}`);
1599
+ }
1600
+ lines.push("");
1601
+ this.appendProseAfter(lines, ast, "output_shape");
1602
+ }
1603
+ if (ast.productionRule) {
1604
+ lines.push("## Production-only rule (no dev, no mock, no localhost)");
1605
+ lines.push("");
1606
+ if (ast.productionRule.noDevNoMockNoLocalhost) {
1607
+ lines.push("No dev. No mock. No localhost. The real service exists - hit it.");
1608
+ }
1609
+ if (ast.productionRule.exception) {
1610
+ lines.push("");
1611
+ lines.push(`**Exception**: ${ast.productionRule.exception}`);
1612
+ }
1613
+ lines.push("");
1614
+ this.appendProseAfter(lines, ast, "production_rule");
1615
+ }
1616
+ if (ast.hardPhysicalGaps.length > 0) {
1617
+ lines.push("## Hard physical gaps (skill never absorbs)");
1618
+ lines.push("");
1619
+ for (const gap of ast.hardPhysicalGaps) {
1620
+ lines.push(`- **${gap.name}** - ${gap.reason}`);
1621
+ if (gap.alternative) {
1622
+ lines.push(` - Alternative: ${gap.alternative}`);
1623
+ }
1624
+ }
1625
+ lines.push("");
1626
+ this.appendProseAfter(lines, ast, "hard_physical_gap");
1627
+ }
1628
+ if (ast.skills.length > 0) {
1629
+ lines.push("## Skills this skill cross-references");
1630
+ lines.push("");
1631
+ for (const skill of ast.skills) {
1632
+ lines.push(`### \`${skill.invocableAs}\` - ${skill.name}`);
1633
+ lines.push("");
1634
+ lines.push(`**Authority**: ${skill.authority}`);
1635
+ lines.push("");
1636
+ if (skill.authoritativeFor.length > 0) {
1637
+ lines.push(`**Authoritative for**: ${skill.authoritativeFor.join(", ")}`);
1638
+ lines.push("");
1639
+ }
1640
+ if (skill.refusals && skill.refusals.length > 0) {
1641
+ lines.push(`**Refusals enforced**: ${skill.refusals.join(", ")}`);
1642
+ lines.push("");
1643
+ }
1644
+ }
1645
+ this.appendProseAfter(lines, ast, "skill");
1646
+ }
1647
+ if (ast.invocationModes.length > 0) {
1648
+ lines.push("## Invocation modes (Track D)");
1649
+ lines.push("");
1650
+ for (const mode of ast.invocationModes) {
1651
+ lines.push(`### ${mode.mode}`);
1652
+ lines.push("");
1653
+ lines.push(`- **When**: ${mode.when}`);
1654
+ lines.push(`- **Effect**: ${mode.effect}`);
1655
+ if (mode.example) {
1656
+ lines.push(`- **Example**: \`${mode.example}\``);
1657
+ }
1658
+ lines.push("");
1659
+ }
1660
+ this.appendProseAfter(lines, ast, "invocation_mode");
1661
+ }
1662
+ appendEmbodiedProjectionSection(lines, ast.embodiedProjections);
1663
+ this.appendProseAfter(lines, ast, "embodied_projection");
1664
+ if (ast.routines.length > 0) {
1665
+ lines.push("## Recurring routines (A-00X)");
1666
+ lines.push("");
1667
+ lines.push(`| ID | Schedule | Skill | Output |`);
1668
+ lines.push(`|---|---|---|---|`);
1669
+ for (const routine of ast.routines) {
1670
+ lines.push(
1671
+ `| ${routine.id} | \`${routine.schedule}\` | ${routine.skill} | ${routine.outputDir ?? "*(varies)*"} |`
1672
+ );
1673
+ }
1674
+ lines.push("");
1675
+ this.appendProseAfter(lines, ast, "routine");
1676
+ }
1677
+ if (ast.escalations.length > 0) {
1678
+ lines.push("## Escape hatch");
1679
+ lines.push("");
1680
+ for (const esc of ast.escalations) {
1681
+ lines.push(`- **Trigger**: ${esc.trigger}`);
1682
+ lines.push(` - **Action**: ${esc.doAction}`);
1683
+ lines.push(` - **Recipient**: ${esc.recipient}`);
1684
+ if (esc.refuseToEscalateWhen.length > 0) {
1685
+ lines.push(
1686
+ ` - **Refuse to escalate when**: ${esc.refuseToEscalateWhen.join(", ")}`
1687
+ );
1688
+ }
1689
+ }
1690
+ lines.push("");
1691
+ this.appendProseAfter(lines, ast, "escalation");
1692
+ }
1693
+ if (ast.dateDisciplines.length > 0) {
1694
+ const firstWisdom = ast.dateDisciplines[0]?.wisdomId;
1695
+ const wisdomSuffix = ast.dateDisciplines.length === 1 && firstWisdom ? ` (${firstWisdom})` : "";
1696
+ lines.push(`## Date discipline${wisdomSuffix}`);
1697
+ lines.push("");
1698
+ for (const d of ast.dateDisciplines) {
1699
+ const wisdomLabel = d.wisdomId ? ` (${d.wisdomId})` : "";
1700
+ lines.push(`### Refusal contract${wisdomLabel}`);
1701
+ lines.push("");
1702
+ lines.push(`**${d.refusalContract}**`);
1703
+ lines.push("");
1704
+ if (d.requiredComponents.length > 0) {
1705
+ lines.push("**Required components** (all must be present):");
1706
+ for (const comp of d.requiredComponents) {
1707
+ lines.push(`- ${comp}`);
1708
+ }
1709
+ lines.push("");
1710
+ }
1711
+ if (d.shapeTemplate) {
1712
+ lines.push("**Output shape**:");
1713
+ lines.push("");
1714
+ lines.push("```");
1715
+ lines.push(d.shapeTemplate);
1716
+ lines.push("```");
1717
+ lines.push("");
1718
+ }
1719
+ if (d.reason) {
1720
+ lines.push(`**Reason**: ${d.reason}`);
1721
+ lines.push("");
1722
+ }
1723
+ if (d.crossReferences && d.crossReferences.length > 0) {
1724
+ lines.push(`**Cross-references**: ${d.crossReferences.join(", ")}`);
1725
+ lines.push("");
1726
+ }
1727
+ }
1728
+ this.appendProseAfter(lines, ast, "date_discipline");
1729
+ }
1730
+ if (ast.citationRules.length > 0) {
1731
+ lines.push("## Citation discipline");
1732
+ lines.push("");
1733
+ for (const rule of ast.citationRules) {
1734
+ lines.push(
1735
+ `- Fluent prose over **${rule.fluentProseThresholdChars} chars** must include one of: ${rule.required.join(", ")}`
1736
+ );
1737
+ if (rule.exemption) {
1738
+ lines.push(` - Exemption: ${rule.exemption}`);
1739
+ }
1740
+ if (rule.reason) {
1741
+ lines.push(` - Reason: ${rule.reason}`);
1742
+ }
1743
+ }
1744
+ lines.push("");
1745
+ this.appendProseAfter(lines, ast, "citation_rule");
1746
+ }
1747
+ if (ast.graduatedWisdoms.length > 0 || ast.feedbacks.length > 0) {
1748
+ lines.push("## Authority cross-references");
1749
+ lines.push("");
1750
+ if (ast.graduatedWisdoms.length > 0) {
1751
+ lines.push("### GOLD-tier wisdom");
1752
+ lines.push("");
1753
+ for (const wisdom of ast.graduatedWisdoms) {
1754
+ lines.push(`- **${wisdom.id}** *(${wisdom.tier})* - ${wisdom.claim}`);
1755
+ }
1756
+ lines.push("");
1757
+ }
1758
+ if (ast.feedbacks.length > 0) {
1759
+ lines.push("### Feedback memory");
1760
+ lines.push("");
1761
+ for (const fb of ast.feedbacks) {
1762
+ const src = fb.source ? ` (${fb.source})` : "";
1763
+ lines.push(`- **${fb.id}**${src} - ${fb.claim}`);
1764
+ }
1765
+ lines.push("");
1766
+ }
1767
+ this.appendProseAfter(lines, ast, "graduated_wisdom");
1768
+ this.appendProseAfter(lines, ast, "feedback");
1769
+ }
1770
+ if (ast.domainDispatches.length > 0) {
1771
+ lines.push("## Domain \u2192 execution skill dispatch");
1772
+ lines.push("");
1773
+ lines.push(
1774
+ "The engine rules with founder defaults, then delegates execution to the right skill:"
1775
+ );
1776
+ lines.push("");
1777
+ lines.push("| Domain | Existing skills |");
1778
+ lines.push("|---|---|");
1779
+ for (const d of ast.domainDispatches) {
1780
+ const skills = d.skills.length > 0 ? d.skills.map((s) => `\`${s}\``).join(", ") : "*(in-skill default)*";
1781
+ lines.push(`| ${d.domain} | ${skills} |`);
1782
+ }
1783
+ lines.push("");
1784
+ this.appendProseAfter(lines, ast, "domain_dispatch");
1785
+ }
1786
+ if (ast.corpusMutabilities.length > 0) {
1787
+ lines.push("## Corpus mutability");
1788
+ lines.push("");
1789
+ for (const c of ast.corpusMutabilities) {
1790
+ lines.push(`- **${c.policy}**: ${c.description}`);
1791
+ }
1792
+ lines.push("");
1793
+ this.appendProseAfter(lines, ast, "corpus_mutability");
1794
+ }
1795
+ lines.push("---");
1796
+ lines.push("");
1797
+ lines.push(
1798
+ `*Generated by HoloScript ContextCompiler (compile_to_skill_md). Source: HoloScript composition. Vocabulary: v4 (2026-05-22). Phase 2(a) self-host target.*`
1799
+ );
1800
+ lines.push("");
1801
+ return lines.join("\n");
1802
+ }
1803
+ appendTrackBAuthority(lines, ast) {
1804
+ if (ast.trackBAuthorities.length === 0) {
1805
+ return;
1806
+ }
1807
+ const renderRows = (heading, rows) => {
1808
+ if (rows.length === 0) return;
1809
+ lines.push(`### ${heading}`);
1810
+ lines.push("");
1811
+ lines.push("| Target | Action type | Requires | Founder ratification | Notes |");
1812
+ lines.push("|---|---|---|---|---|");
1813
+ for (const row of rows) {
1814
+ const actionType = row.actionType ? `\`${mdTableCell(row.actionType)}\`` : "*(unspecified)*";
1815
+ const requires = row.requires.length > 0 ? row.requires.map((r) => mdTableCell(r)).join("<br>") : "*(none)*";
1816
+ const notes = row.notes ? mdTableCell(row.notes) : "";
1817
+ lines.push(
1818
+ `| ${mdTableCell(row.target)} | ${actionType} | ${requires} | ${row.founderRatificationRequired ? "Yes" : "No"} | ${notes} |`
1819
+ );
1820
+ }
1821
+ lines.push("");
1822
+ };
1823
+ const mutableTargets = ast.trackBAuthorities.filter(
1824
+ (row) => !row.founderRatificationRequired
1825
+ );
1826
+ const founderRatifiedTargets = ast.trackBAuthorities.filter(
1827
+ (row) => row.founderRatificationRequired
1828
+ );
1829
+ lines.push("## Self-edit + tier-write authority (Track B)");
1830
+ lines.push("");
1831
+ lines.push(
1832
+ "Every mutation requires backup-before-write, normal Edit/Write mutation, and append-only audit logging with a cited reason."
1833
+ );
1834
+ lines.push("");
1835
+ renderRows("Mutable targets", mutableTargets);
1836
+ renderRows("Founder-ratification-required targets", founderRatifiedTargets);
1837
+ }
1838
+ appendPapersProgramDefaults(lines, ast) {
1839
+ if (ast.editorialDefaults.length === 0 && ast.researchDefaults.length === 0) {
1840
+ return;
1841
+ }
1842
+ lines.push("## Papers program defaults");
1843
+ lines.push("");
1844
+ if (ast.editorialDefaults.length > 0) {
1845
+ lines.push("### Editorial defaults");
1846
+ lines.push("");
1847
+ lines.push("| Scope | Question | Answer | Reason |");
1848
+ lines.push("|---|---|---|---|");
1849
+ for (const def of ast.editorialDefaults) {
1850
+ lines.push(
1851
+ `| ${this.formatPaperDefaultScope(def)} | ${def.when} | **${def.do}** | ${def.reason ?? "*(no citation)*"} |`
1852
+ );
1853
+ }
1854
+ lines.push("");
1855
+ }
1856
+ if (ast.researchDefaults.length > 0) {
1857
+ lines.push("### Research-decision defaults");
1858
+ lines.push("");
1859
+ lines.push("| Scope | Question | Answer | Reason |");
1860
+ lines.push("|---|---|---|---|");
1861
+ for (const def of ast.researchDefaults) {
1862
+ lines.push(
1863
+ `| ${this.formatPaperDefaultScope(def)} | ${def.when} | **${def.do}** | ${def.reason ?? "*(no citation)*"} |`
1864
+ );
1865
+ }
1866
+ lines.push("");
1867
+ }
1868
+ }
1869
+ formatPaperDefaultScope(def) {
1870
+ const paperId = def.paperId?.trim();
1871
+ const paperPhase = def.paperPhase?.trim();
1872
+ if (paperId && paperPhase) return `${paperId} / ${paperPhase}`;
1873
+ if (paperId) return paperId;
1874
+ if (paperPhase) return paperPhase;
1875
+ return "program-wide";
1876
+ }
1877
+ /**
1878
+ * Emit @prose_after paragraphs for a given canonical trait name.
1879
+ * Called after the structured rendering of each section so prose
1880
+ * appears immediately after its target section in all emitters.
1881
+ */
1882
+ appendProseAfter(lines, ast, traitName) {
1883
+ const prose = ast.proseAfters.filter((p) => p.trait === traitName);
1884
+ for (const entry of prose) {
1885
+ for (const paragraph of entry.paragraphs) {
1886
+ lines.push(paragraph);
1887
+ }
1888
+ lines.push("");
1889
+ }
1890
+ }
1891
+ };
1892
+ var ContextCompileError = class extends Error {
1893
+ constructor(message) {
1894
+ super(message);
1895
+ this.name = "ContextCompileError";
1896
+ }
1897
+ };
1898
+ function createContextCompiler(options) {
1899
+ return new ContextCompiler(options);
1900
+ }
1901
+ function stringField(cfg, key, fallback) {
1902
+ const v = cfg[key];
1903
+ if (typeof v === "string") return v;
1904
+ return fallback;
1905
+ }
1906
+ function stringFieldOrUndef(cfg, key) {
1907
+ const v = cfg[key];
1908
+ return typeof v === "string" ? v : void 0;
1909
+ }
1910
+ function numberField(cfg, key, fallback) {
1911
+ const v = cfg[key];
1912
+ return typeof v === "number" && Number.isFinite(v) ? v : fallback;
1913
+ }
1914
+ function boolField(cfg, key, fallback) {
1915
+ const v = cfg[key];
1916
+ return typeof v === "boolean" ? v : fallback;
1917
+ }
1918
+ function mdTableCell(value) {
1919
+ return value.replace(/\|/g, "\\|").replace(/[\r\n]+/g, "<br>");
1920
+ }
1921
+ function yamlScalar(s) {
1922
+ if (/^[A-Za-z][A-Za-z0-9_-]*$/.test(s) && !YAML_RESERVED.has(s.toLowerCase())) {
1923
+ return s;
1924
+ }
1925
+ return JSON.stringify(s);
1926
+ }
1927
+ function formatYamlDescription(description) {
1928
+ if (!description.includes("\n")) {
1929
+ return `description: ${JSON.stringify(description)}`;
1930
+ }
1931
+ const lines = description.split("\n").map((line) => ` ${line}`);
1932
+ return `description: >
1933
+ ${lines.join("\n")}`;
1934
+ }
1935
+ var YAML_RESERVED = /* @__PURE__ */ new Set([
1936
+ "yes",
1937
+ "no",
1938
+ "true",
1939
+ "false",
1940
+ "on",
1941
+ "off",
1942
+ "null",
1943
+ "~"
1944
+ ]);
1945
+ function stringListField(cfg, key) {
1946
+ const v = cfg[key];
1947
+ if (!Array.isArray(v)) return [];
1948
+ return v.filter((x) => typeof x === "string");
1949
+ }
1950
+ function appendEmbodiedProjectionSection(lines, projections) {
1951
+ if (projections.length === 0) return;
1952
+ lines.push("## Embodied projections");
1953
+ lines.push("");
1954
+ for (const projection of projections) {
1955
+ const surface = projection.surface || "unspecified-surface";
1956
+ const kind = projection.projectionKind || "read-only";
1957
+ lines.push(`### ${surface} / ${kind}`);
1958
+ lines.push("");
1959
+ lines.push(`- **Surface**: ${surface}`);
1960
+ lines.push(`- **Projection kind**: ${kind}`);
1961
+ if (projection.trigger) {
1962
+ lines.push(`- **Trigger**: ${projection.trigger}`);
1963
+ }
1964
+ if (projection.notes) {
1965
+ lines.push(`- **Notes**: ${projection.notes}`);
1966
+ }
1967
+ lines.push("");
1968
+ }
1969
+ }
1970
+ function wrapMdc(description, bodyLines) {
1971
+ const front = ["---", `description: ${description}`, "globs:", "alwaysApply: true", "---", ""];
1972
+ return front.concat(bodyLines).join("\n");
1973
+ }
1974
+ function oneLine(s) {
1975
+ return s.replace(/[\r\n]+/g, " ").replace(/\s+/g, " ").trim();
1976
+ }
1977
+ function toCursorSlug(name) {
1978
+ const base = name.toLowerCase().replace(/[_\s]+/g, "-").replace(/[^a-z0-9-]+/g, "").replace(/-{2,}/g, "-").replace(/^-+|-+$/g, "");
1979
+ if (base.length > 0) return base;
1980
+ let h = 0;
1981
+ for (let i = 0; i < name.length; i += 1) {
1982
+ h = (h + name.charCodeAt(i)) % 1e6;
1983
+ }
1984
+ return `rule-${h.toString(36).padStart(4, "0")}`;
1985
+ }
1986
+
1987
+ export { ContextCompileError, ContextCompiler, createContextCompiler };
1988
+ //# sourceMappingURL=chunk-QXH7QDSZ.js.map
1989
+ //# sourceMappingURL=chunk-QXH7QDSZ.js.map