@xgent-ai/skills 0.7.5 → 0.7.7

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 (717) hide show
  1. package/.claude/hooks/xgent-statusline.js +32 -18
  2. package/README.md +61 -35
  3. package/bin/phoenix-diagram.js +14 -0
  4. package/bin/xgent-skills.js +166 -240
  5. package/dist/phoenix-diagram/LICENSE +21 -0
  6. package/dist/phoenix-diagram/NOTICE.md +34 -0
  7. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/005fc765ddc5115da796cca915baa9557abae13ff35e0a47c47affc56f6c414d.txt +272 -0
  8. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/010492e490b92ec85db01daad2a290ea5959f29314a1c4ff25e7a172e223abf9.txt +18 -0
  9. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/01c266bced4a434da0051174d6bee16a4c82cf634e2679b6155d40d75012390f.txt +3 -0
  10. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/0218327e7a480793ffdd4eb792379a9709e5c135c7ba267f709d6f6d4d70af0a.txt +201 -0
  11. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/02bb8c3b4e70190e3986c0404ad2fd8d639b4f534252d82379cc1b502b6d1812.txt +191 -0
  12. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/0444c6991eead6822f7b9102e654448d51624431119546492e8b231db42c48bb.txt +25 -0
  13. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/0552c898248eadfc130df0c0e8f6f82776fcb3f1dd5a5af2fa991b5baff9367a.txt +21 -0
  14. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/0ab4d106b6faac07fb6a051815fd1b4d862d730895e2d7d7358c2f13565e7a38.txt +20 -0
  15. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/0b28172679e0009b655da42797c03fd163a3379d5cfa67ba1f1655e974a2a1a9.txt +25 -0
  16. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/0d3f7c086c6b6cf3ea4aac714e9aa3e1fb02e355ce35bd21c56acf8d04390885.txt +21 -0
  17. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/0dd882e53de11566d50f8e8e2d5a651bcf3fabee4987d70f306233cf39094ba7.txt +21 -0
  18. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/0f96a83840e146e43c0ec96a22ec1f392e0680e6c1226e6f3ba87e0740af850f.txt +21 -0
  19. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/117829c3ca21efb132d81a44b55363d395ab8eea18526873bc828da4c0e5f038.txt +21 -0
  20. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/123a331b5dbf04c30097fa43b8f858bc85df671fe776de498d01f3d6b7c1f69e.txt +25 -0
  21. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/1a2f5c12ddc934d58956aa5dbdd3255fe55fd957633ab7d0d39e4f0daa73f7df.txt +26 -0
  22. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/1f256ecad192880510e84ad60474eab7589218784b9a50bc7ceee34c2b91f1d5.txt +373 -0
  23. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/1f485f0d6125658861351e3d6084ea90fefe78f89450be9915044b7c56d5a75a.txt +15 -0
  24. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/209fbbe0ad52d9235e37badf9cadfe4dbdc87203179c0899e738b39ade42177b.txt +26 -0
  25. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/20c7855c364d57ea4c97889a5e8d98470a9952dade37bd9248b9a54431670e5e.txt +25 -0
  26. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/20fe7b00e904ed690e3b9fd6073784d3fc428141dbd10b81c01fd143d0797f58.txt +176 -0
  27. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/219920e865eee70b7dcfc948a86b099e7f4fe2de01bcca2ca9a20c0a033f2b59.txt +7 -0
  28. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/23860c2a7b5d96b21569afedf033469bab9fe14a1b24a35068b8641c578ce24d.txt +7 -0
  29. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3.txt +23 -0
  30. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5.txt +220 -0
  31. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/27995d58ad5c1145c1a8cd86244ce844886958a35eb2b78c6b772748669999ac.txt +25 -0
  32. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/28a9529c7d0bb4dc51f4bf5c116a3d16ef247a052f7591466768ddf563fd1cf5.txt +428 -0
  33. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/29e9fe5074bd27e0e5d5d110394fbbcd841baee2651a3c4b4560a632702cede4.txt +26 -0
  34. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/30fefc3a7d6a0041541858293bcbea2dde4caa4c0a5802f996a7f7e8c0085652.txt +23 -0
  35. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/3521672491a3479422d5fe1aca6645dd2984090f85da6e5205abfb18fb7a6897.txt +25 -0
  36. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/35242e7a83f69875e6edeff02291e688c97caafe2f8902e4e19b49d3e78b4cab.txt +176 -0
  37. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/36516aefdc84c5d5a1e7485425913a22dbda69eb1930c5e84d6ae4972b5194b9.txt +23 -0
  38. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/375bdbf54d6584debb4bcc5bce1c9dcfdd581f977c9a8469113dbdf208f4c927.txt +131 -0
  39. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397.txt +25 -0
  40. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/391a5396cec6230bfabd4ef4eb2350eb895bc5efce377a2218f5702ed020d3e3.txt +20 -0
  41. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/39712155836e5c10ef1b07037b606e4ad2d633e72205d162fdd7e2290aa54f15.txt +21 -0
  42. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/3bb1e548250b3acc43febde65a5cdba9f2e0a3288018aa41f009a3c59ffab51a.txt +390 -0
  43. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/3bc70e239e91272782006c638fc0452a714d384224f11f0923036b7be07cf9b5.txt +21 -0
  44. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/3f3d9e0024b1921b067d6f7f88deb4a60cbe7a78e76c64e3f1d7fc3b779b9d04.txt +373 -0
  45. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/3f941b3b89cf7b8370ceb83cc76d2120d471b58735d8ca60238a751a48d7f72f.txt +359 -0
  46. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/3fa4ca83dcc9237839b1bdeb2e6d16bdfb5ec0c5ce42b24694d8bbf0dcbef72c.txt +25 -0
  47. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/42fa16951ce7f24b5a467a40e5b449a1d41e662f97ca779864f053f39e097737.txt +26 -0
  48. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/4455bf75a91154108304cb283e0fea9948c14f13e20d60887cf2552449dea3b1.txt +21 -0
  49. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/451167c55c0fa447cc2d5632714f5e3c567fe4f1e1badefab2c1333852198aca.txt +542 -0
  50. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/45f522cacecb1023856e46df79ca625dfc550c94910078bd8aec6e02880b3d42.txt +25 -0
  51. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/45fd05c4865e7c350b98ad7ac50e1b15462d49af4a91e9b0c9dd933dc9a69742.txt +201 -0
  52. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/4789210f4df8abc03fce1cddd9c2ba517f184840687f2815d741de282c1aa93a.txt +228 -0
  53. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/4cada0bd02ea3692eee6f16400d86c6508bbd3bafb2b65fed0419f36d4f83e8f.txt +25 -0
  54. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/516b24e051bf5630880ebbd55c40a25ce9552ebaf8970a53e8976eb70e522406.txt +201 -0
  55. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/553fffcd9b1cb158bc3e9edc35da85ca5c3b3d7d2e61c883ebcfa8a65814b583.txt +13 -0
  56. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/5757a1f28eff735a8b5e7425478f367812d71e974530f5bedd01219480965f4a.txt +51 -0
  57. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/5b698ca13897be3afdb7174256fa1574f8c6892b8bea1a66dd6469d3fe27885a.txt +19 -0
  58. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/5e05b024f653a5ce199e77cbbbd42fb5553562ec714b819421ed0c3e552a75d7.txt +25 -0
  59. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/60a7062291b01ba068f300612cdbdc20382ac1d4934f07bcdd7167c15299f309.txt +25 -0
  60. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/62065228e42caebca7e7d7db1204cbb867033de5982ca4009928915e4095f3a3.txt +25 -0
  61. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a.txt +176 -0
  62. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb.txt +25 -0
  63. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/65f94e99ddaf4f5d1782a6dae23f35d4293a9a01444a13135a6887017d353cee.txt +25 -0
  64. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/6df43f6f4b5d4587f3d8d71e45532c688fd168afa5fe89d571cb32fa09c4ef51.txt +187 -0
  65. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/709e3175b4212f7b13aa93971c9f62ff8c69ec45ad8c6532a7e0c41d7a7d6f8c.txt +25 -0
  66. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/71674605ec4c087fe9eb534e3e4f9e26eb2e4aabcd76a29fd156c6a844d44b3d.txt +21 -0
  67. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/7365cc8878a1d7ce155a58c4ca09c3d7a6be413efa5334a80ea842912b669349.txt +25 -0
  68. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/7abd9b6960dcf7d4d0a48606a5b71bfe37d472db68d70637f3a58a56785f1621.txt +13 -0
  69. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/7b63ecd5f1902af1b63729947373683c32745c16a10e8e6292e2e2dcd7e90ae0.txt +25 -0
  70. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/7ca6700600dfa9c9497bf5556365067daa802c871ea78239f129309c7a2048f7.txt +21 -0
  71. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/7cfafc877eccc46c0e346ccbaa5c51bb6b894d2b818e617d970211e232785ad4.txt +15 -0
  72. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/7e12e5df4bae12cb21581ba157ced20e1986a0508dd10d0e8a4ab9a4cf94e85c.txt +24 -0
  73. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/7e5886959f67f8c75063a9d55cd3cb08c5a8cbea9a944fa1df2d4ae038f53721.txt +21 -0
  74. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/7fea0ee51a4ca5d5cea7464135fd55e8b09caf3a61da3d451ac8a22af95c033f.txt +20 -0
  75. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/8173d5c29b4f956d532781d2b86e4e30f83e6b7878dce18c919451d6ba707c90.txt +201 -0
  76. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/83c1763356e822adde0a2cae748d938a73fdc263849ccff6b27776dff213bd32.txt +24 -0
  77. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/86dd7f026f916daf7511e39951ad8ea8cf55a8db67ae64060dacf829761c18f3.txt +25 -0
  78. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/8a35369f3ca263b3c62fbb5032947e53b6bfebc6c8a4d1bb982de1c069f6fba5.txt +21 -0
  79. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/8b43ce8accd61e9d370b5ca9e9c4f953279b5c239926c62315b40e24df51b726.txt +25 -0
  80. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/8bb1b50b0e5c9399ae33bd35fab2769010fa6c14e8860c729a52295d84896b7a.txt +201 -0
  81. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/8bce3b45e49ecd1461f223b46de133d8f62cd39f745cfdaf81bee554b908bd42.txt +21 -0
  82. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/8c7516d4b27b1e495be5e38b612298b63de48d05f49cdac94f70f3cd70f8864b.txt +25 -0
  83. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/9046848b63a5c92bff14e4accca80bd987e0623b74adf9226ce5198d312b79d5.txt +30 -0
  84. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/90eb64f0279b0d9432accfa6023ff803bc4965212383697eee27a0f426d5f8d5.txt +12 -0
  85. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/9117d922e667125508dde62b02c1f57ed22f5ad21eb536aa2e2d99e1c796e639.txt +25 -0
  86. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/9387c2d197e2370a740ca457dae1662c56de56b811ee4862024343961307f9bf.txt +19 -0
  87. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/946c9835d8034d24404f8cfec5f4654cee5dad17e944afc3d06d742cf2882831.txt +240 -0
  88. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/95bd3988beee069fa2848f648dab43cc6e0b2add2ad6bcb17360caf749802bcc.txt +176 -0
  89. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/9ba9550ad48438d0836ddab3da480b3b69ffa0aac7b7878b5a0039e7ab429411.txt +396 -0
  90. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/9d185ac6703c4b0453974c0d85e9eee43e6941009296bb1f5eb0b54e2329e9f3.txt +202 -0
  91. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/9e0dfd2dd4173a530e238cb6adb37aa78c34c6bc7444e0e10c1ab5d8881f63ba.txt +25 -0
  92. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/9f2ae19ef94ba82887729a4a1617ff25eede56611dd21a4b2c6f797df30fca33.txt +2013 -0
  93. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/9fa38f610a00115dd1f612bdd3559e3b381ea579538b6ff25a5899da250a5fce.txt +21 -0
  94. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/a00511478c83ebb464ef19d840f061c7444adc4636bb561900e75c5808cfc6cc.txt +21 -0
  95. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/a2010f343487d3f7618affe54f789f5487602331c0a8d03f49e9a7c547cf0499.txt +121 -0
  96. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/a5dea80c1f383cb5f80a6bb0da5e55a2beb9f24adb123ce6300af2cbaaa3bf65.txt +19 -0
  97. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2.txt +201 -0
  98. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/a825bd853ab71619a4923d7b4311221427848070ff44d990da39b0b274c1683f.txt +21 -0
  99. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/a9040321c3712d8fd0b09cf52b17445de04a23a10165049ae187cd39e5c86be5.txt +201 -0
  100. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/aaff376532ea30a0cd5330b9502ad4a4c8bf769c539c87ffe78819d188a18ebf.txt +201 -0
  101. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/ae9baa7beea910273c2f384c2a6b721fb7bd02bda3436074a1072e4ee689f985.txt +25 -0
  102. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/b1181a40b2a7b25cf66fd01481713bc1005df082c53ef73e851e55071b102744.txt +19 -0
  103. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/b38f11f6096706e6de553dabe2a7ed142d59b6fa8c97e290c67496154745cdd5.txt +25 -0
  104. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/b3d734001a94efff3579978d953391aa7115f877657d25eb54037a43875d078a.txt +9 -0
  105. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/b40930bbcf80744c86c46a12bc9da056641d722716c378f5659b9e555ef833e1.txt +201 -0
  106. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/b4eb00df6e2a4d22518fcaa6a2b4646f249b3a3c9814509b22bd2091f1392ff1.txt +27 -0
  107. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/b68ad1a3367b825447089e1f8d6829b97f47a89eb78d2f4ebaef4672f5606186.txt +22 -0
  108. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/b7e650f3fce5c53249d1cdc608b54df156a97edd636cf9d23498d0cfe7aec63e.txt +19 -0
  109. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/c09aae9d3c77b531f56351a9947bc7446511d6b025b3255312d3e3442a9a7583.txt +21 -0
  110. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/c16f8dcf1a368b83be78d826ea23de4079fe1b4469a0ab9ee20563f37ff3d44b.txt +201 -0
  111. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/c2cfccb812fe482101a8f04597dfc5a9991a6b2748266c47ac91b6a5aae15383.txt +21 -0
  112. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/c30152c94a6d75e021adbc52b3a52470366a46edb917e17deae3259251af244c.txt +42 -0
  113. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/c394e3bda1f3b9378f30a7cab11242887eeeafc73c7bef36a0fe13e09691e18b.txt +17 -0
  114. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4.txt +201 -0
  115. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/c962ee4d1d05ddc138b202b2540219ebc57893fcf97b364852094a9a94ce1365.txt +7 -0
  116. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/c9a75f18b9ab2927829a208fc6aa2cf4e63b8420887ba29cdb265d6619ae82d5.txt +25 -0
  117. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30.txt +202 -0
  118. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/d1fc1bc0d155df60b2e7705b6b2ae02a05c96f948e1cec6e2fb86360b09f346b.txt +29 -0
  119. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/d5c22aa3118d240e877ad41c5d9fa232f9c77d757d4aac0c2f943afc0a95e0ef.txt +25 -0
  120. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/d5fca2653c88ad02d197faead77e22b80c70636b5bec6e02f2805f389a21b86d.txt +10 -0
  121. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/db11fec9946737df39ca3898d9cd8c10ec6f6c3a884a6802b0ad0b81b4e8f23a.txt +1 -0
  122. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/dc91f8200e4b2a1f9261035d4c18c33c246911a6c0f7b543d75347e61b249cff.txt +25 -0
  123. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/ddea4e94a1c35ed9826e54e13a5b50b8f81b21665a00ca07c8861f1859e56b6b.txt +14 -0
  124. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/e271993808fec50ab29350b39539cdec611a9103f827e0aa26d61da70e2d33f8.txt +61 -0
  125. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/e66c269d4819aaab34b49ef5220c4ddab6756f21bb5180761a4eb8561f2b7bbd.txt +438 -0
  126. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/ecc269ef87fd38a1d98e30bfac9ba964a9dbd9315c3770fed98d4d7cb5882055.txt +25 -0
  127. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/efcfee7981ff72431fffb06925cad00a23dce079ed4354f61030ad5abdb78829.txt +22 -0
  128. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/f025ccfb7dfb6bdfedc75ca0f67acc69e6fb4998143d834f7c2f38a29989680f.txt +13 -0
  129. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/f367c1b8e1aa262435251e442901da4607b4650e0e63a026f5044473ecfb90f2.txt +46 -0
  130. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/f51ac2c59a222f7476ce507ca879960e2b64ea64bb2786eefdbeb7b0b538d1b7.txt +25 -0
  131. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/f7715d38a3fa1b4ac97c5729740752505a39cb92ee83ab5b102aeb5eaa7cdea4.txt +25 -0
  132. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/f7db81051789b729fea528a63ec4c938fdcb93d9d61d97dc8cc2e9df6d47f2a1.txt +39 -0
  133. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/f9c4c77baa3828004ee54b8a4f2db2e88ed44a6237a493965bf551fac0fcb62d.txt +17 -0
  134. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85.txt +373 -0
  135. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/fb77f0a9c53e473abe5103c8632ef9f0f2874d4fb3f17cb2d8c661aab9cee9d7.txt +25 -0
  136. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/ff8f68cb076caf8cefe7a6430d4ac086ce6af2ca8ce2c4e5a2004d4552ef52a2.txt +25 -0
  137. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/ff92bed461f50338dd703a9ba9aee496a425957873df1d91192776e4bdf5dda7.txt +74 -0
  138. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/rust-std-1.99.1/COPYRIGHT-library.html +29357 -0
  139. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/rust-std-1.99.1/licenses/Apache-2.0.txt +73 -0
  140. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/rust-std-1.99.1/licenses/BSD-2-Clause.txt +9 -0
  141. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/rust-std-1.99.1/licenses/CC-BY-SA-4.0.txt +427 -0
  142. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/rust-std-1.99.1/licenses/GCC-exception-3.1.txt +30 -0
  143. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/rust-std-1.99.1/licenses/GPL-2.0-only.txt +133 -0
  144. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/rust-std-1.99.1/licenses/GPL-3.0-or-later.txt +202 -0
  145. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/rust-std-1.99.1/licenses/ISC.txt +7 -0
  146. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/rust-std-1.99.1/licenses/LLVM-exception.txt +15 -0
  147. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/rust-std-1.99.1/licenses/MIT.txt +9 -0
  148. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/rust-std-1.99.1/licenses/NCSA.txt +29 -0
  149. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/rust-std-1.99.1/licenses/OFL-1.1.txt +43 -0
  150. package/dist/phoenix-diagram/THIRD-PARTY-LICENSES/rust-std-1.99.1/licenses/Unicode-3.0.txt +39 -0
  151. package/dist/phoenix-diagram/THIRD-PARTY-NOTICES.md +210 -0
  152. package/dist/phoenix-diagram/THIRD-PARTY.json +5459 -0
  153. package/dist/phoenix-diagram/VERSION.json +39 -0
  154. package/dist/phoenix-diagram/bundle/ENGINE.json +39 -0
  155. package/dist/phoenix-diagram/bundle/SKILL.md +109 -0
  156. package/dist/phoenix-diagram/bundle/examples/minimal.architecture.json +11 -0
  157. package/dist/phoenix-diagram/bundle/examples/minimal.class.json +23 -0
  158. package/dist/phoenix-diagram/bundle/examples/minimal.dataflow.json +11 -0
  159. package/dist/phoenix-diagram/bundle/examples/minimal.erd.json +25 -0
  160. package/dist/phoenix-diagram/bundle/examples/minimal.lifecycle.json +11 -0
  161. package/dist/phoenix-diagram/bundle/examples/minimal.sequence.json +13 -0
  162. package/dist/phoenix-diagram/bundle/examples/minimal.timeline.json +15 -0
  163. package/dist/phoenix-diagram/bundle/examples/minimal.tree.json +13 -0
  164. package/dist/phoenix-diagram/bundle/examples/minimal.waterfall.json +12 -0
  165. package/dist/phoenix-diagram/bundle/examples/minimal.workflow.json +12 -0
  166. package/dist/phoenix-diagram/bundle/manifest.json +253 -0
  167. package/dist/phoenix-diagram/bundle/references/architecture-compare.md +111 -0
  168. package/dist/phoenix-diagram/bundle/references/authoring-defaults.md +42 -0
  169. package/dist/phoenix-diagram/bundle/references/brand-marks.md +52 -0
  170. package/dist/phoenix-diagram/bundle/references/compatibility.md +22 -0
  171. package/dist/phoenix-diagram/bundle/references/delivery-contract.md +127 -0
  172. package/dist/phoenix-diagram/bundle/references/extending-types.md +14 -0
  173. package/dist/phoenix-diagram/bundle/references/migration.md +57 -0
  174. package/dist/phoenix-diagram/bundle/references/preview.md +45 -0
  175. package/dist/phoenix-diagram/bundle/references/repository-authoring.md +29 -0
  176. package/dist/phoenix-diagram/bundle/references/viewer-runtime.md +27 -0
  177. package/dist/phoenix-diagram/bundle/schemas/README.md +23 -0
  178. package/dist/phoenix-diagram/bundle/schemas/architecture.schema.json +329 -0
  179. package/dist/phoenix-diagram/bundle/schemas/class.schema.json +348 -0
  180. package/dist/phoenix-diagram/bundle/schemas/common.schema.json +358 -0
  181. package/{skills/archify → dist/phoenix-diagram/bundle}/schemas/dataflow.schema.json +36 -8
  182. package/dist/phoenix-diagram/bundle/schemas/erd.schema.json +384 -0
  183. package/dist/phoenix-diagram/bundle/schemas/lifecycle.schema.json +202 -0
  184. package/{skills/archify → dist/phoenix-diagram/bundle}/schemas/sequence.schema.json +41 -10
  185. package/dist/phoenix-diagram/bundle/schemas/timeline.schema.json +170 -0
  186. package/dist/phoenix-diagram/bundle/schemas/tree.schema.json +144 -0
  187. package/dist/phoenix-diagram/bundle/schemas/waterfall.schema.json +150 -0
  188. package/{skills/archify → dist/phoenix-diagram/bundle}/schemas/workflow.schema.json +42 -10
  189. package/dist/phoenix-diagram/bundle/scripts/phoenix-bootstrap.cjs +589 -0
  190. package/dist/phoenix-diagram/bundle/scripts/phoenix-diagram +6 -0
  191. package/dist/phoenix-diagram/bundle/scripts/phoenix-launcher.cjs +10 -0
  192. package/dist/phoenix-ui/THIRD-PARTY.json +164 -158
  193. package/dist/phoenix-ui/VERSION.json +17 -17
  194. package/dist/phoenix-ui/bundle/blobs/00727f7b333a7be8ac7740aa257a3a3f691db8ae545a6afab2b787acab5e88df +46 -0
  195. package/dist/phoenix-ui/bundle/blobs/{547e3c89d5b8feeddd67e43131fd84b95253eb42bf7d730b4e471dba011f6e51 → 00f4a6a630f31eb05fbdd5725e4a294233d24574bd70f4f32f4597d8256a7c1c} +0 -4
  196. package/dist/phoenix-ui/bundle/blobs/{41400e182e2180a567923d58bfa935d2799a54f2a747b2c5813c3884c84f768b → 04057592e18ea9dd3c4edcac14cde3fa5b75239c2552d4459db8e047068f61a8} +6 -7
  197. package/dist/phoenix-ui/bundle/blobs/{34571f7d46632205d518d15cb008457494dfad745c6b483bb11d63ca3a22ac48 → 0cb3bf26e1980b0e530373fb32edbe5864a171492a04e2abe1952ffe78bff231} +6 -7
  198. package/dist/phoenix-ui/bundle/blobs/{852d2943678a76c33b2f7a090d2ca6c152cd120e9ae62775fcc91519b9289011 → 0e684572eb98d24b39cd70fa23e66c163178f5a11756dcf8a98fe2335636b33f} +6 -3
  199. package/dist/phoenix-ui/bundle/blobs/{d17b3a454146e74ef4ecf69d7b72a8fa45c4fe1c695dffb0d36690b653cd2d8f → 10553c45c7bf38e527a57a281c4365152a768b4dd7ef597ff34ae841e9ff7d41} +6 -7
  200. package/dist/phoenix-ui/bundle/blobs/{e49257c0fd32b195cccb16fbfda769c007be6b38f25aceefecd23cfff9366cec → 125bc7030d7f2ba789d7b1d5f474af34f8902b764e7bc351b98f1f6f55779929} +6 -3
  201. package/dist/phoenix-ui/bundle/blobs/{74dbcbbad6c3831e95abb38775dd488c59ae9f1d44a95f5fd4bc0051577488fa → 13cf6c054ed424e2eb639ea12d20a4aa2b1c85eeb00afa8cbd8a30c6c22aadd8} +1 -1
  202. package/dist/phoenix-ui/bundle/blobs/1832ff9624cebd30370eb0e806665c656ac879215f93d33bcc0750baa47459dc +46 -0
  203. package/dist/phoenix-ui/bundle/blobs/{8e7de5ca347036a07f5f1e9cab942d8ff378d029bc101fa6d126406f3298c9db → 1864a10c29e7062cca5e49d1790dc7d9d8ea777bfa2ab6fd941635965cd0084d} +1 -1
  204. package/dist/phoenix-ui/bundle/blobs/{784722b72224a7005a80cdcd6408dd2b25b23fd9619d0f6c8788f7ac681fad4c → 1ecc81de39d28b85b95e797bcc338d4213a50231c3315a741d14571fd22c844f} +6 -7
  205. package/dist/phoenix-ui/bundle/blobs/{b8c614dc7c2eb30ee0f864fec116dbcafb39e5a199dce66d0c1a88b13f76265a → 2079e4146039a8dadf19a39237cbdc0b8b54ea1fa16d320716c2cbf58161c835} +1 -1
  206. package/dist/phoenix-ui/bundle/blobs/{dba6e4a09c5d752e5ddebe7c2c1aefc9c4b2a84e01a3178599579778ed2d09e9 → 2813aa68c0804a7fe061d88201d8a684cac9987b48511e1e2cbfe0a869a67a82} +6 -7
  207. package/dist/phoenix-ui/bundle/blobs/{2889c2817b5079abff254bb6d13f92dbde0fabc38be4acc7d20e613eef5e5829 → 2873e340be947c83c3d03520139b73524fd166a34063d2693d3b711021ea5b87} +6 -7
  208. package/dist/phoenix-ui/bundle/blobs/{64c4aa2d1c24ae5028e987498ac544020d48600a51d9654b2df562681ba480f2 → 298ef41899acefa056eccf2345378078832db6d868d2377f471f896d5c1599f9} +6 -14
  209. package/dist/phoenix-ui/bundle/blobs/{1b7174a6f3f49a8efc8f7fa74ff84cf8960e2646b9bc976e4129a7c8ad608faa → 2b5cef2a14a5b1256ec6de9172a4f57f227948ced1921ef86e899f48524d7fb8} +1 -1
  210. package/dist/phoenix-ui/bundle/blobs/{f148f630f43f3c91cf10feeda5a3c21448ca0683ce82d0fe763c1b43dee584d6 → 2d376cbbf7ec1e262614aac4f1b200e8f60e86e940c7137a2a26788bc857e509} +6 -7
  211. package/dist/phoenix-ui/bundle/blobs/2e5985a6eb339d70cfa25f6d2b420a0ef286caa8467f0226eb841702ec438d0b +46 -0
  212. package/dist/phoenix-ui/bundle/blobs/{7e199833376de5d2b6e088ee2965b448f94da842f28ccbd707e1cc3a295147c8 → 3322d691bf7b578b38723576df6b266993b2afb9e567b0cd1ded898ffe1dc17e} +1 -1
  213. package/dist/phoenix-ui/bundle/blobs/{f82bfc4c6bc9169d4978d5e16fb925f6e152fdd21dc6a2fae719dfdc1645581f → 3625c5c2750f117021232ce81c1e39ac5ef7c21445729327b88cf54dfc937df0} +6 -3
  214. package/dist/phoenix-ui/bundle/blobs/{2ceacad745665f79fd7ad5565646426a36a1b508c0469b931d0f202fad45a80b → 36310febe3e7bd4c9b21407603f2a04afefdc87b7821758bb47098b1b2876765} +6 -3
  215. package/dist/phoenix-ui/bundle/blobs/{24d92a176573768bfffaf8f9c6483e58bceb5bf2a095d1cdf3d3a2c0bcda0707 → 3a9c2daf4ef284ca83b0e7f6fef3a5300e273c32b20769e090463cb8a8b0b06f} +1 -1
  216. package/dist/phoenix-ui/bundle/blobs/{153e377c44b162cf0074698a61716db7f664db78f5635efa926bed484de4f54c → 3ce1a44efe39b93e7a39307c6a5e5f514e938fbae818e358986b4db1b05883ca} +1 -1
  217. package/dist/phoenix-ui/bundle/blobs/{ad8ad0b7acf6c88ef9ce0ee1a640c2200da77821f0d97d605d4f1d4a10e5897a → 403fcde498d75abec7844ee31434201152ac229f7675772164d69563f0572da4} +1 -1
  218. package/dist/phoenix-ui/bundle/blobs/{e8ee6c08e94b80324173d89d6f4cdc5b4829ea6858b3a11fc186588a490cada4 → 45d0e7eff0923c40296e971318756617944c4f1c97f03126cd74c0f8c629f8a4} +3 -1
  219. package/dist/phoenix-ui/bundle/blobs/{e23dabf908842be08751fc4e7f3b586e8c6b1ca0fc30303ec5317c77f83dcf26 → 4c0f396bfa85171f61972d3f3765733318769bb53fe06d2cdcb5d7f64578b5b8} +1 -1
  220. package/dist/phoenix-ui/bundle/blobs/{a5517d32c1539c388c47c00879a0d807ed2989647bfa8c0844ef22328f75f5be → 4f6563876e0e0cc51c38a06767b8800eb3238611e9fdd11e5ff9dd487c742e74} +1 -1
  221. package/dist/phoenix-ui/bundle/blobs/{a9d2203acd45ca33a13d5c68b02b23ed512425ac15f0e8438318ed124b43729d → 4fcada229d0c689c1a493d13184145a81ff40c498e882142ae390bda8e5b2492} +15 -0
  222. package/dist/phoenix-ui/bundle/blobs/5293adc55cf66068b6df20468ad9e91433fd1c48e75d66c86f874aca951a8fb9 +46 -0
  223. package/dist/phoenix-ui/bundle/blobs/{96e2e6bd4fcf9a2c6da65fb029f96d9176308fae2efd9d8653d3b8d838960e07 → 5436f0301ec258f3badcc6842019ee29a9b870d2727dc425fbc9cc0f4f88a284} +3 -1
  224. package/dist/phoenix-ui/bundle/blobs/{d0f4939e86a62b0ca437d51a997ceba7e77d64566b7fa8ca2747487e31ca819d → 54a09a4afdffca3cc135e5007716ea684dc1ed7a78349de859225c55a2fed810} +6 -7
  225. package/dist/phoenix-ui/bundle/blobs/{d5102701d41f7c6195d410a873f742ac72c428b04196e47df5555c5ccaf80504 → 55277fa15eb4bd2f09bf7bb24c4e79df417b06654b1e10f502c7928b192fd7cc} +6 -3
  226. package/dist/phoenix-ui/bundle/blobs/{878064e46af4e4109bab405f965e4149bee40bbe8912ffede10b74cec6cff027 → 567c3f42394f9aee9b048a001016a7ba9d8773d78027f8c995c379886634e719} +6 -3
  227. package/dist/phoenix-ui/bundle/blobs/57c8f33a7401f918566b8a4883871a69ef2223438c51f158c67f69e3250be465 +46 -0
  228. package/dist/phoenix-ui/bundle/blobs/{bc29e115fd337dda2cc7fc70b868dc18e426b08ec186fd270fcfe96bb2efaa5d → 61450dbef64859e3136cd17ae3e997134d5df5721d96985c4e07367f38522129} +6 -3
  229. package/dist/phoenix-ui/bundle/blobs/{e3c1e925be0b2deb0e3765b83ab94b86560292364f275e98bb23a8bdf2c2e049 → 656bbfda3e72b40d53b5832293dc8700ad8a784e804a6246271bf0ea23527822} +1 -1
  230. package/dist/phoenix-ui/bundle/blobs/{ffcaa5c58e779ec74d18bfc3013ad8003f6e7a23f629c1a3b878618961a8b6a3 → 68b454a99ba72c3b9b93ed96c4267847297169f6a5bf321b20e60d637c271068} +6 -3
  231. package/dist/phoenix-ui/bundle/blobs/68e44832c82b873b0aeb2da56def7b1de5f612c019445e5e28238c690124cbbe +46 -0
  232. package/dist/phoenix-ui/bundle/blobs/{45bbd4a8e02ca0012216c5c68e1dcd655ae0046bd50ba4295ef1f58ec4a0957c → 6b8d4c71355429a0b16bf367163fea46103a0a99b4e34f87608a39d85b1b980a} +6 -3
  233. package/dist/phoenix-ui/bundle/blobs/{264815d0080e4862715a4f82542e66241c6563f07259d32aed4a17bbc329b9cc → 6cef874722442de7c60ea96f4221dc54cc4250a270cd05a1e818b58c5b43e232} +6 -7
  234. package/dist/phoenix-ui/bundle/blobs/{2028a857c0476324a4256faf66693e2a869275e53a88d2b182a28b62c2a17893 → 7181f1f4c452c4345695f9100f6deb610f54f4c55f126043433a65b8491fc680} +6 -7
  235. package/dist/phoenix-ui/bundle/blobs/{ccb76aabba47938d518a5d46a09d7e70c4a9222bc391e163763f2a7f12d30437 → 75850a8c9d2a8259f71ef1f86dd5d1325415227c1887e81a3467ae1ee400979f} +1 -1
  236. package/dist/phoenix-ui/bundle/blobs/{4b03cdb5b17d534b5c7e84b079c066f59e8b60b9e454671a453867c4aeb9920d → 77bcc6c2d6ac00a8bfead3b6c6b5fc69f4b60bf086ebbc89271e1b23003168c9} +1 -1
  237. package/dist/phoenix-ui/bundle/blobs/{9520e25a381c82af6f46e175b7c347d1dc513d933dd6cf8c52570c72abb4ca7f → 792552563745d208594cf4ade19110f2c811a0e1a2661ae1ef43a185ccff5a69} +1 -1
  238. package/dist/phoenix-ui/bundle/blobs/{f7c8af35acf71a96056afb6afcff6a3ea42f65561f02652d04e11ad9ece9b8e9 → 7acd9b6f2f61b509c6a518508b8b52c2f0de67cdea4fd3f3d383b3ce8b38cf5e} +6 -7
  239. package/dist/phoenix-ui/bundle/blobs/7bacc1e3da7e8b7127ca3f8f69a2422098b9b2d23fbedefc56dfe76117c1c0e3 +46 -0
  240. package/dist/phoenix-ui/bundle/blobs/{78662176c1d31cec2d640f70df203f93cc1aec604cfc31619f4d2c62ab78861b → 8078b804bea630ed9c4ea07ec2f8ac92aba4128725860a66599eda90390d98f6} +6 -3
  241. package/dist/phoenix-ui/bundle/blobs/{2291169748fe0c4c80634dff3083e7464f82d4358b9b2186759b316e612d466f → 88b150cb804bc141b80a5687a091f61b99627155c465a27adb88546ef615af92} +6 -3
  242. package/dist/phoenix-ui/bundle/blobs/{bde88bf5ac59d744440d9b65f95ceaae01c803b101d48e6afd644a06eeb5de63 → 90f8b07ec12b78e633e306322cda58415aea70d8e0f9ff85bd439361c01dabe1} +6 -3
  243. package/dist/phoenix-ui/bundle/blobs/{486145071d3445e82774f1b39b2bb15986ce52277e798a31ef7e9c27afb42af3 → 95b2944686e8258a655c3b5e6db68593e24e5199354e46aac553918ea2c0f55a} +1 -1
  244. package/dist/phoenix-ui/bundle/blobs/{a1998e37084c11f496d4970f86a85d5a6375bbeaa4797b9f42bbac2d44048d23 → 979639f0e8859d600a8db57e733566d9ad37ff8258c3e05a6f9c0f3008e92373} +1 -1
  245. package/dist/phoenix-ui/bundle/blobs/{3173293607055ea6e1a153ec6f51fb8154782157c8a61abf411da1f41be61728 → 9eaaa00049844060f842fe7fb73cc8edc4be5225cf38a96f33bda3ffc381456c} +6 -7
  246. package/dist/phoenix-ui/bundle/blobs/{69086f7cb235b35ccc230e1f2da41cbb10cea8f0636b6d4514672113a3adc2cb → a420bbda622399399a6b5c7c3614dcaebc6c62faceaf7b3c83c97db53d26b165} +1 -1
  247. package/dist/phoenix-ui/bundle/blobs/a63054b8920905045753facece83f154bf806158c6f46ef380036e7a82d4fde5 +46 -0
  248. package/dist/phoenix-ui/bundle/blobs/{e802e4f7bdc89050a9c0f2ca506e1d493a2316e6e810c0336c57aa073717ef3e → a63788c764b0e4fdcbc029d46093016310edcbcf702d62688e5aaac7ddeee6fd} +3 -1
  249. package/dist/phoenix-ui/bundle/blobs/{827a211ea03d2cb44b4ea1bc81ba1a6dc51a87fa16d6692997c4e4751241c815 → acfc4c26b135d5b27fc0930738486c9d43d379704102fab45564320180942e4b} +4 -2
  250. package/dist/phoenix-ui/bundle/blobs/{8da14f3eabac53c990a66e721387367b46cb676cc4204e8c67d6f88c95a6217f → ad243ca615349127aa422bccc1a6604ad17149735659087ca5bab3c5fae97f4e} +6 -7
  251. package/dist/phoenix-ui/bundle/blobs/b63931066e2b2623d012e1a3c1a0769cc43ed6640460c3899669b45539d6a20d +46 -0
  252. package/dist/phoenix-ui/bundle/blobs/{bb65af58ecc3e0c0093dc9a705a7ab643035e4e592c3adb93583c82d1aef1f51 → bde793ab5ad776f7e6f6d25ce2b838c1b5022054a1dad5502a873423eb0ad917} +6 -7
  253. package/dist/phoenix-ui/bundle/blobs/{8de7c97949b0bc4194b3be7645e4b13e9419767927482d01cf19476f6cbeda14 → c0a70ab2889e5c16e1f09249aefad948ce352c42cfe2b5afb758a4524e1b21b6} +6 -3
  254. package/dist/phoenix-ui/bundle/blobs/{60b2914df394800688c4e20f4eb34e117cd430df9954cf4d48574734507723f4 → c9ee9006ae6c0194a5d39a9f0cb275c52d74a71ea3f6dc2b4c1c7bd89f48a2c0} +1 -1
  255. package/dist/phoenix-ui/bundle/blobs/{6d8315e307eab11d3236935daf7267746cce6da3b51296e6999651ac97bda3a3 → cadc2daefcf238aab981fa56388381d3d5ab9c0686bb9dd8187035c9933dfcee} +6 -3
  256. package/dist/phoenix-ui/bundle/blobs/{d7b744fcc95164d96d9f811a93e2e8a374887146eb762ef775f3d3c7f27abc8d → cbea5728b90f58ff047be6ec4f14eed9d63c7148f5db99b5f147d2f17b472317} +1 -1
  257. package/dist/phoenix-ui/bundle/blobs/d408a4fea71b656aa8a5f6b5c037815a6e4229df336629ebddf4b5c85ed82fac +46 -0
  258. package/dist/phoenix-ui/bundle/blobs/{6ff950a5729ad9ea480ddf8c1b489b1c84189bbf7d6034b3b5a98e7c11a28cec → d9ae0c782d8a77787561536c0d7bc3b61175d59303f3cb8c20796f85140c6984} +1 -1
  259. package/dist/phoenix-ui/bundle/blobs/{1d53e2226465b1047faec7cda2e743e61540ea69e073a3a4057e8d86b277405f → e2932d63eb7f52a82960a19ba79bc800ef4f212164e098f96dee7a4326302f38} +1 -1
  260. package/dist/phoenix-ui/bundle/blobs/{fa576f6655b235bdea535198647305b7a3855e810180cbdf5d4c246c03c7d190 → e381bcfec42ac541d574011460600cf0818aa0e3362e8c6d205b4157890bf821} +6 -7
  261. package/dist/phoenix-ui/bundle/blobs/{8fbce5b4859e6011afa83b1c07c4436589cd7181f9cb997538f4c27f196d0d34 → e415657d8725d9b60ece42cc18581da177c42fc47cb11e501db722a5f524ecf7} +6 -7
  262. package/dist/phoenix-ui/bundle/blobs/{546a8428a2d8628bb3496fadb8c36a6dd65a33464291f214ceb581828f37081b → e46d63e5f8a6ead1d44c8b6302a0c7247af8585b975ab5715518381777622ede} +6 -3
  263. package/dist/phoenix-ui/bundle/blobs/ee63b3f9b354d69443d05ea4a338af56546897335ace7533546e10be56ea2207 +46 -0
  264. package/dist/phoenix-ui/bundle/blobs/{c23617601e9c4d97b775c175a5ce1642c40459b157d0821609fe1d253b83ced8 → ef7d57633252f4604749447608850e299c277f7dd1a32776685df0724b1051c8} +6 -7
  265. package/dist/phoenix-ui/bundle/blobs/{0581c8428246f43c5374393878a29e38f2b1865df87e6f13f2309b8eae54e76f → f0652c6ce41e6949133360178f192ea4ee9f6129a018c7a8b6652870c2330392} +1 -1
  266. package/dist/phoenix-ui/bundle/blobs/{cfac9eaf96481a8874391e5cecc6149abea1f1f19622f77f1ebb9e1876720e91 → f06c9d797ca2ac8c6a49d3dcd2e99d1b4df8bc9637a49c7e80f3161f49d06b1b} +4 -2
  267. package/dist/phoenix-ui/bundle/blobs/{d50780cb0a345051ae3fb12c5f8249a5dac9324d6a1963f04d03aaf769ffc27c → f077545caeb3ecb9f51a3f703a09736ca924869f4b4345c1b1ffbd9bf927a287} +6 -3
  268. package/dist/phoenix-ui/bundle/blobs/f781c5874bcd79ebe1b3b012275b9af7eae6c4867e9a16e29bb3d3ed3dc1940b +46 -0
  269. package/dist/phoenix-ui/bundle/blobs/fa10c0c926997387c89b7c1070e25b1b2b53ee891741e3c450a89ec6c6dcaf7d +46 -0
  270. package/dist/phoenix-ui/bundle/blobs/fb1a36ab7116b0c6709b89720cdded29d80982114c2f87cad614e01e126270dd +46 -0
  271. package/dist/phoenix-ui/bundle/blobs/fbd3214fc12ba70d9c69a995742ba73dc5365823af63afdc93c0c8a8f0c484af +46 -0
  272. package/dist/phoenix-ui/bundle/blobs/{77682e9d63b484f94a699f2c0b393e4540797d311362c384a3d643aec11d6985 → fea19b8381ec10ff8ed1923a336332974bbb552227ed215e7ddaaf0ec0112c1d} +1 -1
  273. package/dist/phoenix-ui/bundle/manifest.json +126 -126
  274. package/docs/phoenix-diagram.md +173 -0
  275. package/docs/phoenix-ui.md +40 -12
  276. package/package.json +14 -10
  277. package/skills/agi-mode/SKILL.md +3 -1
  278. package/skills/agi-mode/assets/sdlc/event.md +4 -5
  279. package/skills/agi-mode/assets/sdlc/object-status.md +1 -1
  280. package/skills/agi-mode/assets/sdlc/protocol.md +4 -2
  281. package/skills/agi-mode/evals/scenarios.md +108 -3
  282. package/skills/agi-mode/playbooks/authoring-a-skill.md +13 -2
  283. package/skills/agi-mode/playbooks/eval.md +19 -3
  284. package/skills/agi-mode/playbooks/hillclimb.md +4 -2
  285. package/skills/agi-mode/playbooks/reflection.md +1 -1
  286. package/skills/agi-mode/playbooks/sdlc.md +10 -6
  287. package/skills/agi-mode/playbooks/what-next.md +6 -2
  288. package/skills/agi-mode/references/eval-protocol.md +13 -4
  289. package/skills/agi-mode/references/interface-design.md +1 -0
  290. package/skills/agi-mode/references/remote-evolution.md +178 -0
  291. package/skills/agi-mode/references/skill-evolution.md +2 -0
  292. package/skills/agi-mode/scripts/evolution/compare.py +569 -0
  293. package/skills/agi-mode/scripts/evolution/evolution.py +2886 -0
  294. package/skills/agi-mode/scripts/evolution/examples/public-smoke.json +128 -0
  295. package/skills/agi-mode/scripts/evolution/examples/quality-calibration.json +128 -0
  296. package/skills/agi-mode/scripts/evolution/examples/quality-rubric.json +133 -0
  297. package/skills/agi-mode/scripts/evolution/protocol.py +1586 -0
  298. package/skills/agi-mode/scripts/evolution/pyproject.toml +16 -0
  299. package/skills/agi-mode/scripts/evolution/quality.py +689 -0
  300. package/skills/agi-mode/scripts/evolution/remote.py +2303 -0
  301. package/skills/agi-mode/scripts/evolution/tests/support.py +201 -0
  302. package/skills/agi-mode/scripts/evolution/tests/test_apply.py +643 -0
  303. package/skills/agi-mode/scripts/evolution/tests/test_bounded_exploration.py +236 -0
  304. package/skills/agi-mode/scripts/evolution/tests/test_bundles.py +414 -0
  305. package/skills/agi-mode/scripts/evolution/tests/test_calibration.py +460 -0
  306. package/skills/agi-mode/scripts/evolution/tests/test_compare.py +377 -0
  307. package/skills/agi-mode/scripts/evolution/tests/test_protocol.py +357 -0
  308. package/skills/agi-mode/scripts/evolution/tests/test_quality.py +647 -0
  309. package/skills/agi-mode/scripts/evolution/tests/test_remote.py +857 -0
  310. package/skills/agi-mode/scripts/evolution/tests/test_search.py +1109 -0
  311. package/skills/agi-mode/scripts/evolution/tests/test_typesafe.py +624 -0
  312. package/skills/agi-mode/scripts/evolution/tests/test_verifier_context.py +132 -0
  313. package/skills/agi-mode/scripts/evolution/typesafe_worker.py +145 -0
  314. package/skills/agi-mode/scripts/evolution/uv.lock +2548 -0
  315. package/skills/apply-code-review/SKILL.md +1 -0
  316. package/skills/apply-code-review/agents/openai.yaml +2 -0
  317. package/skills/apply-doc-review/SKILL.md +1 -0
  318. package/skills/apply-doc-review/agents/openai.yaml +2 -0
  319. package/skills/apply-ui-review/SKILL.md +1 -0
  320. package/skills/apply-ui-review/agents/openai.yaml +2 -0
  321. package/skills/autoresearch/SKILL.md +1 -0
  322. package/skills/clean-artifacts/SKILL.md +52 -0
  323. package/skills/clean-artifacts/agents/openai.yaml +4 -0
  324. package/skills/clean-artifacts/evals/scenarios.md +13 -0
  325. package/skills/clean-artifacts/references/history-cleanup.md +41 -0
  326. package/skills/crd/SKILL.md +100 -65
  327. package/skills/crd/assets/cr-template.md +15 -0
  328. package/skills/crd-respond/SKILL.md +17 -5
  329. package/skills/crd-respond/agents/openai.yaml +2 -2
  330. package/skills/crd-respond/assets/response-template.md +7 -0
  331. package/skills/crd-respond/evals/scenarios.md +7 -0
  332. package/skills/create-verification-skill/SKILL.md +1 -0
  333. package/skills/debugging/SKILL.md +1 -0
  334. package/skills/design-md/SKILL.md +1 -0
  335. package/skills/design-reference/SKILL.md +6 -2
  336. package/skills/design-reference/evals/scenarios.md +4 -0
  337. package/skills/dev-plan/SKILL.md +11 -6
  338. package/skills/dev-plan/references/execution-workflow.md +1 -1
  339. package/skills/dev-plan/references/plan-skeleton.md +234 -69
  340. package/skills/dev-plan/scripts/check_plan.py +1 -1
  341. package/skills/documentation-writer/SKILL.md +19 -14
  342. package/skills/documentation-writer/references/architecture.md +6 -2
  343. package/skills/documentation-writer/references/user-manual.md +2 -2
  344. package/skills/elintp/SKILL.md +12 -6
  345. package/skills/experience-capture/SKILL.md +1 -0
  346. package/skills/gdpr-compliant/SKILL.md +1 -0
  347. package/skills/kpi-dashboard-design/SKILL.md +1 -0
  348. package/skills/landing-page-conversion-audit/SKILL.md +1 -0
  349. package/skills/mcp-release-qa/SKILL.md +2 -1
  350. package/skills/meeting-minutes/SKILL.md +1 -0
  351. package/skills/optimize-agents-md/SKILL.md +128 -0
  352. package/skills/optimize-agents-md/assets/coding-principles.md +118 -0
  353. package/skills/phoenix-diagram/ENGINE.json +39 -0
  354. package/skills/phoenix-diagram/SKILL.md +109 -0
  355. package/skills/phoenix-diagram/examples/legacy.agent-tool-call.workflow.json +94 -0
  356. package/skills/phoenix-diagram/examples/legacy.async-job-roundtrip.sequence.json +61 -0
  357. package/skills/phoenix-diagram/examples/legacy.deployment-release.lifecycle.json +49 -0
  358. package/skills/phoenix-diagram/examples/legacy.product-analytics.dataflow.json +76 -0
  359. package/skills/{archify/test/fixtures/v1-baseline/web-app.architecture.json → phoenix-diagram/examples/legacy.web-app.architecture.json} +16 -11
  360. package/skills/phoenix-diagram/examples/minimal.architecture.json +11 -0
  361. package/skills/phoenix-diagram/examples/minimal.class.json +23 -0
  362. package/skills/phoenix-diagram/examples/minimal.dataflow.json +11 -0
  363. package/skills/phoenix-diagram/examples/minimal.erd.json +25 -0
  364. package/skills/phoenix-diagram/examples/minimal.lifecycle.json +11 -0
  365. package/skills/phoenix-diagram/examples/minimal.sequence.json +13 -0
  366. package/skills/phoenix-diagram/examples/minimal.timeline.json +15 -0
  367. package/skills/phoenix-diagram/examples/minimal.tree.json +13 -0
  368. package/skills/phoenix-diagram/examples/minimal.waterfall.json +12 -0
  369. package/skills/phoenix-diagram/examples/minimal.workflow.json +12 -0
  370. package/skills/phoenix-diagram/references/architecture-compare.md +111 -0
  371. package/skills/phoenix-diagram/references/authoring-defaults.md +42 -0
  372. package/skills/phoenix-diagram/references/brand-marks.md +52 -0
  373. package/skills/phoenix-diagram/references/compatibility.md +22 -0
  374. package/skills/phoenix-diagram/references/delivery-contract.md +127 -0
  375. package/skills/phoenix-diagram/references/extending-types.md +14 -0
  376. package/skills/phoenix-diagram/references/migration.md +57 -0
  377. package/skills/phoenix-diagram/references/preview.md +45 -0
  378. package/skills/phoenix-diagram/references/repository-authoring.md +29 -0
  379. package/skills/phoenix-diagram/references/viewer-runtime.md +27 -0
  380. package/skills/phoenix-diagram/schemas/README.md +23 -0
  381. package/skills/phoenix-diagram/schemas/architecture.schema.json +329 -0
  382. package/skills/phoenix-diagram/schemas/class.schema.json +348 -0
  383. package/skills/phoenix-diagram/schemas/common.schema.json +358 -0
  384. package/skills/{archify/schemas/lifecycle.schema.json → phoenix-diagram/schemas/dataflow.schema.json} +63 -58
  385. package/skills/phoenix-diagram/schemas/erd.schema.json +384 -0
  386. package/skills/phoenix-diagram/schemas/lifecycle.schema.json +202 -0
  387. package/skills/phoenix-diagram/schemas/sequence.schema.json +254 -0
  388. package/skills/phoenix-diagram/schemas/timeline.schema.json +170 -0
  389. package/skills/phoenix-diagram/schemas/tree.schema.json +144 -0
  390. package/skills/phoenix-diagram/schemas/waterfall.schema.json +150 -0
  391. package/skills/phoenix-diagram/schemas/workflow.schema.json +460 -0
  392. package/skills/phoenix-diagram/scripts/phoenix-bootstrap.cjs +589 -0
  393. package/skills/phoenix-diagram/scripts/phoenix-diagram +6 -0
  394. package/skills/phoenix-diagram/scripts/phoenix-launcher.cjs +10 -0
  395. package/skills/phoenix-ui/GENERATED.json +255 -240
  396. package/skills/phoenix-ui/SKILL.md +7 -4
  397. package/skills/phoenix-ui/evals/scenarios.md +8 -1
  398. package/skills/phoenix-ui/reference/craft-floor.md +3 -1
  399. package/skills/phoenix-ui/reference/critique.md +6 -14
  400. package/skills/phoenix-ui/reference/init.md +1 -1
  401. package/skills/phoenix-ui/reference/live.md +1 -1
  402. package/skills/phoenix-ui/reference/operate.md +15 -0
  403. package/skills/phoenix-ui/scripts/ENGINE.json +17 -17
  404. package/skills/phoenix-ui/scripts/phoenix-bootstrap.cjs +0 -4
  405. package/skills/portal-app-exchange/SKILL.md +1 -0
  406. package/skills/portal-dev-setup/SKILL.md +71 -12
  407. package/skills/portal-dev-setup/scripts/onebox.sh +69 -6
  408. package/skills/portal-external-app/SKILL.md +55 -16
  409. package/skills/portal-external-app/references/config-placement.md +108 -2
  410. package/skills/portal-external-app/references/registration-and-onebox.md +56 -2
  411. package/skills/portal-logging/SKILL.md +1 -0
  412. package/skills/portal-micro-app/SKILL.md +2 -1
  413. package/skills/portal-micro-app/references/sdk-reference.md +3 -1
  414. package/skills/prd/SKILL.md +238 -159
  415. package/skills/prd/evals/scenarios.md +13 -0
  416. package/skills/prd/references/prd-skeleton.md +14 -4
  417. package/skills/react/SKILL.md +1 -0
  418. package/skills/resolve-blocked/SKILL.md +46 -19
  419. package/skills/resolve-blocked/agents/openai.yaml +2 -2
  420. package/skills/resolve-blocked/evals/scenarios.md +22 -0
  421. package/skills/resolve-blocked/references/decisions-contract.md +7 -4
  422. package/skills/review-code/SKILL.md +308 -46
  423. package/skills/review-code/agents/openai.yaml +2 -0
  424. package/skills/review-dev-plan/SKILL.md +88 -33
  425. package/skills/review-dev-plan/agents/openai.yaml +2 -0
  426. package/skills/review-dev-plan/references/report-contract.md +53 -19
  427. package/skills/review-dev-plan/references/review-lenses.md +2 -1
  428. package/skills/review-prd/SKILL.md +90 -34
  429. package/skills/review-prd/agents/openai.yaml +2 -0
  430. package/skills/review-prd/references/report-contract.md +54 -18
  431. package/skills/review-prd-dev-gaps/SKILL.md +1 -0
  432. package/skills/review-prd-dev-gaps/agents/openai.yaml +2 -0
  433. package/skills/review-ui/SKILL.md +369 -71
  434. package/skills/review-ui/agents/openai.yaml +2 -0
  435. package/skills/review-ui/evals/scenarios.md +2 -0
  436. package/skills/rust/SKILL.md +76 -84
  437. package/skills/rust/references/api-design.md +97 -0
  438. package/skills/rust/references/{chapter_10.md → async-tokio.md} +42 -18
  439. package/skills/rust/references/behavioral-patterns.md +49 -0
  440. package/skills/rust/references/bevy.md +95 -0
  441. package/skills/rust/references/{chapter_02.md → clippy-and-linting.md} +26 -15
  442. package/skills/rust/references/{chapter_01.md → coding-idioms.md} +58 -7
  443. package/skills/rust/references/crates-and-dependencies.md +66 -0
  444. package/skills/rust/references/{chapter_08.md → documentation.md} +30 -3
  445. package/skills/rust/references/{chapter_04.md → error-handling.md} +32 -6
  446. package/skills/rust/references/{chapter_06.md → generics-and-dispatch.md} +28 -11
  447. package/skills/rust/references/macros.md +45 -0
  448. package/skills/rust/references/{chapter_03.md → performance.md} +25 -2
  449. package/skills/rust/references/{chapter_09.md → pointers-and-ownership.md} +37 -17
  450. package/skills/rust/references/{chapter_05.md → testing.md} +18 -2
  451. package/skills/rust/references/{chapter_07.md → type-state.md} +5 -1
  452. package/skills/rust/references/unsafe-and-ffi.md +56 -0
  453. package/skills/rust-port/SKILL.md +144 -0
  454. package/skills/rust-review/SKILL.md +177 -0
  455. package/skills/security-audit/SKILL.md +1 -0
  456. package/skills/spec-human-decision/SKILL.md +1 -0
  457. package/skills/sql-optimization/SKILL.md +1 -0
  458. package/skills/story-points/SKILL.md +1 -0
  459. package/skills/swarm/SKILL.md +1 -0
  460. package/skills/test-plan/SKILL.md +1 -0
  461. package/skills/ui-loop/SKILL.md +39 -0
  462. package/skills/ui-loop/agents/openai.yaml +3 -0
  463. package/skills/ui-pattern-research/SKILL.md +1 -0
  464. package/skills/use-llm-gateway/SKILL.md +58 -0
  465. package/skills/use-llm-gateway/agents/openai.yaml +4 -0
  466. package/skills/use-llm-gateway/references/api.md +129 -0
  467. package/skills/use-llm-gateway/references/recovery.md +86 -0
  468. package/skills/use-prompt-dsl/SKILL.md +165 -0
  469. package/skills/use-prompt-dsl/references/examples.md +726 -0
  470. package/skills/use-prompt-dsl/references/language.md +938 -0
  471. package/skills/use-rustify-docs/SKILL.md +60 -0
  472. package/skills/use-rustify-docs/agents/openai.yaml +4 -0
  473. package/skills/use-rustify-docs/references/rustify-docs.md +138 -0
  474. package/skills/use-task-gateway/SKILL.md +60 -0
  475. package/skills/use-task-gateway/agents/openai.yaml +3 -0
  476. package/skills/use-task-gateway/references/authentication.md +75 -0
  477. package/skills/use-task-gateway/references/task-api.md +121 -0
  478. package/skills/use-task-gateway/references/workers.md +85 -0
  479. package/skills/use-task-gateway/references/workflow-actions.md +66 -0
  480. package/skills/use-workflow-service/SKILL.md +57 -0
  481. package/skills/use-workflow-service/agents/openai.yaml +3 -0
  482. package/skills/use-workflow-service/references/action-provider.md +84 -0
  483. package/skills/use-workflow-service/references/authentication.md +76 -0
  484. package/skills/use-workflow-service/references/authoring.md +62 -0
  485. package/skills/use-workflow-service/references/mcp.md +47 -0
  486. package/skills/use-workflow-service/references/open-api.md +88 -0
  487. package/skills/use-workflow-service/references/orchestration-choice.md +63 -0
  488. package/skills/working-with-mbx/SKILL.md +1 -0
  489. package/skills/working-with-mise/SKILL.md +1 -0
  490. package/skills/xgent-app-release/SKILL.md +114 -16
  491. package/skills/xgent-app-release/references/build-and-package.md +2 -1
  492. package/skills/xgent-app-release/references/publish-api.md +6 -1
  493. package/skills/xgent-app-release/references/troubleshooting.md +2 -1
  494. package/skills/xgent-app-release/references/verify-preflight.mjs +21 -1
  495. package/skills/xgent-app-release/scripts/preflight.mjs +42 -3
  496. package/skills/xgent-image-push/SKILL.md +1 -0
  497. package/skills/xgent-init/SKILL.md +1 -0
  498. package/docs/claude-context-goal-guard.md +0 -124
  499. package/docs/codex-context-goal-guard.md +0 -109
  500. package/hooks/claude/context-goal-guard.js +0 -139
  501. package/hooks/claude/settings.example.json +0 -26
  502. package/hooks/codex/context-goal-guard.py +0 -189
  503. package/hooks/codex/hooks.example.json +0 -26
  504. package/skills/archify/SKILL.md +0 -137
  505. package/skills/archify/assets/template.html +0 -14937
  506. package/skills/archify/bin/archify.mjs +0 -2139
  507. package/skills/archify/bin/open-artifact.mjs +0 -86
  508. package/skills/archify/bin/preview.mjs +0 -653
  509. package/skills/archify/bin/visual-check.mjs +0 -829
  510. package/skills/archify/brand-marks/README.md +0 -31
  511. package/skills/archify/brand-marks/catalog.json +0 -131
  512. package/skills/archify/delta/architecture-delta.mjs +0 -1232
  513. package/skills/archify/examples/agent-run.lifecycle.json +0 -60
  514. package/skills/archify/examples/brand-aware-delivery.architecture.json +0 -47
  515. package/skills/archify/examples/cache-miss-request.sequence.json +0 -82
  516. package/skills/archify/examples/checkout-platform.base.architecture.json +0 -31
  517. package/skills/archify/examples/checkout-platform.head.architecture.json +0 -31
  518. package/skills/archify/examples/dataflow-product-analytics.html +0 -15048
  519. package/skills/archify/examples/event-stream.dataflow.json +0 -57
  520. package/skills/archify/examples/incident-response.workflow.json +0 -64
  521. package/skills/archify/examples/lifecycle-agent-run.html +0 -14983
  522. package/skills/archify/examples/production-deployment.architecture.json +0 -71
  523. package/skills/archify/examples/release-delivery.workflow.json +0 -62
  524. package/skills/archify/examples/sequence-cache-miss-request.html +0 -15063
  525. package/skills/archify/examples/web-app-rendered.html +0 -15012
  526. package/skills/archify/examples/workflow-agent-tool-call-rendered.html +0 -15054
  527. package/skills/archify/migrations/workflow-v2.mjs +0 -279
  528. package/skills/archify/package-lock.json +0 -149
  529. package/skills/archify/package.json +0 -39
  530. package/skills/archify/recipes/scenarios.mjs +0 -391
  531. package/skills/archify/references/authoring-contract.md +0 -247
  532. package/skills/archify/references/brand-marks.md +0 -65
  533. package/skills/archify/references/delivery-contract.md +0 -138
  534. package/skills/archify/references/viewer-runtime.md +0 -45
  535. package/skills/archify/renderers/architecture/grid.mjs +0 -62
  536. package/skills/archify/renderers/architecture/render-architecture.mjs +0 -1078
  537. package/skills/archify/renderers/dataflow/README.md +0 -104
  538. package/skills/archify/renderers/dataflow/render-dataflow.mjs +0 -483
  539. package/skills/archify/renderers/lifecycle/README.md +0 -115
  540. package/skills/archify/renderers/lifecycle/render-lifecycle.mjs +0 -561
  541. package/skills/archify/renderers/sequence/README.md +0 -114
  542. package/skills/archify/renderers/sequence/render-sequence.mjs +0 -464
  543. package/skills/archify/renderers/shared/brand-marks.mjs +0 -563
  544. package/skills/archify/renderers/shared/cli.mjs +0 -218
  545. package/skills/archify/renderers/shared/desktop-readability.mjs +0 -26
  546. package/skills/archify/renderers/shared/diagnostics.mjs +0 -160
  547. package/skills/archify/renderers/shared/engineering-profiles.mjs +0 -157
  548. package/skills/archify/renderers/shared/generated-brand-marks.mjs +0 -2003
  549. package/skills/archify/renderers/shared/generated-validators.mjs +0 -13
  550. package/skills/archify/renderers/shared/geometry.mjs +0 -1423
  551. package/skills/archify/renderers/shared/i18n.mjs +0 -595
  552. package/skills/archify/renderers/shared/layout-report.mjs +0 -40
  553. package/skills/archify/renderers/shared/legend.mjs +0 -217
  554. package/skills/archify/renderers/shared/output-path.mjs +0 -340
  555. package/skills/archify/renderers/shared/repository-evidence.mjs +0 -239
  556. package/skills/archify/renderers/shared/repository-location.mjs +0 -58
  557. package/skills/archify/renderers/shared/text-fit.mjs +0 -49
  558. package/skills/archify/renderers/shared/utils.mjs +0 -232
  559. package/skills/archify/renderers/shared/validator.mjs +0 -86
  560. package/skills/archify/renderers/workflow/README.md +0 -223
  561. package/skills/archify/renderers/workflow/render-workflow.mjs +0 -35
  562. package/skills/archify/renderers/workflow/workflow-compiler.mjs +0 -4400
  563. package/skills/archify/renderers/workflow/workflow-migration-geometry.mjs +0 -144
  564. package/skills/archify/schemas/README.md +0 -211
  565. package/skills/archify/schemas/architecture.schema.json +0 -178
  566. package/skills/archify/schemas/common.schema.json +0 -115
  567. package/skills/archify/scripts/check-render-output.mjs +0 -916
  568. package/skills/archify/scripts/check-update.mjs +0 -1667
  569. package/skills/archify/scripts/generate-brand-marks.mjs +0 -141
  570. package/skills/archify/scripts/generate-validators.mjs +0 -66
  571. package/skills/archify/scripts/render-examples.mjs +0 -26
  572. package/skills/archify/scripts/update-contract.mjs +0 -182
  573. package/skills/archify/skill-release.json +0 -10
  574. package/skills/archify/test/adaptive-reader-layout.test.mjs +0 -86
  575. package/skills/archify/test/animation.test.mjs +0 -179
  576. package/skills/archify/test/architecture-compare-recovery.test.mjs +0 -157
  577. package/skills/archify/test/architecture-delta-markers.test.mjs +0 -137
  578. package/skills/archify/test/architecture-delta.test.mjs +0 -705
  579. package/skills/archify/test/artifact-receipt-flush.test.mjs +0 -126
  580. package/skills/archify/test/authored-reachability.test.mjs +0 -95
  581. package/skills/archify/test/authoring-safety-contract.test.mjs +0 -54
  582. package/skills/archify/test/automatic-port-spread.test.mjs +0 -376
  583. package/skills/archify/test/base-input-compatibility.test.mjs +0 -42
  584. package/skills/archify/test/brand-marks.test.mjs +0 -678
  585. package/skills/archify/test/chapter-delta-preview.test.mjs +0 -157
  586. package/skills/archify/test/chapter-handoff.test.mjs +0 -97
  587. package/skills/archify/test/chapter-rail.test.mjs +0 -86
  588. package/skills/archify/test/checkout-line-endings.test.mjs +0 -72
  589. package/skills/archify/test/ci-scope.test.mjs +0 -59
  590. package/skills/archify/test/clean-skill-staging.test.mjs +0 -440
  591. package/skills/archify/test/cli-output-types.test.mjs +0 -201
  592. package/skills/archify/test/cli.test.mjs +0 -986
  593. package/skills/archify/test/community-proof-intake.test.mjs +0 -125
  594. package/skills/archify/test/cursor-onboarding.test.mjs +0 -74
  595. package/skills/archify/test/degraded.test.mjs +0 -161
  596. package/skills/archify/test/delivery-contract.test.mjs +0 -52
  597. package/skills/archify/test/desktop-reader-browser.test.mjs +0 -80
  598. package/skills/archify/test/diagram-guide.test.mjs +0 -92
  599. package/skills/archify/test/engineering-profile.test.mjs +0 -209
  600. package/skills/archify/test/export-browser.test.mjs +0 -305
  601. package/skills/archify/test/export-cleanup-browser.test.mjs +0 -294
  602. package/skills/archify/test/finder-browser.test.mjs +0 -274
  603. package/skills/archify/test/finder.test.mjs +0 -104
  604. package/skills/archify/test/fixtures/automatic-routing-node-border-clearance.workflow.json +0 -40
  605. package/skills/archify/test/fixtures/fail-migration-cleanup.mjs +0 -17
  606. package/skills/archify/test/fixtures/issue-126/custom-widths.workflow.json +0 -18
  607. package/skills/archify/test/fixtures/issue-126/explicit-route.workflow.json +0 -28
  608. package/skills/archify/test/fixtures/issue-126/explicit-viewbox.workflow.json +0 -19
  609. package/skills/archify/test/fixtures/issue-126/labels.workflow.json +0 -18
  610. package/skills/archify/test/fixtures/v1-baseline/agent-run.lifecycle.json +0 -64
  611. package/skills/archify/test/fixtures/v1-baseline/agent-tool-call.workflow.json +0 -88
  612. package/skills/archify/test/fixtures/v1-baseline/cache-miss-request.sequence.json +0 -75
  613. package/skills/archify/test/fixtures/v1-baseline/event-stream.dataflow.json +0 -57
  614. package/skills/archify/test/fixtures/v1-baseline/product-analytics.dataflow.json +0 -70
  615. package/skills/archify/test/fixtures/v1-baseline/production-deployment.architecture.json +0 -71
  616. package/skills/archify/test/fixtures/v1-workflow-700x400.workflow.json +0 -22
  617. package/skills/archify/test/fixtures/v1-workflow-explicit-coordinates.workflow.json +0 -47
  618. package/skills/archify/test/focus-browser.test.mjs +0 -226
  619. package/skills/archify/test/gallery.test.mjs +0 -130
  620. package/skills/archify/test/generate-validators.test.mjs +0 -59
  621. package/skills/archify/test/generate-viewer.test.mjs +0 -165
  622. package/skills/archify/test/generated-artifact-xml.test.mjs +0 -88
  623. package/skills/archify/test/geometry.test.mjs +0 -739
  624. package/skills/archify/test/golden.mjs +0 -207
  625. package/skills/archify/test/grid.test.mjs +0 -47
  626. package/skills/archify/test/guide-page.test.mjs +0 -85
  627. package/skills/archify/test/guide.test.mjs +0 -81
  628. package/skills/archify/test/guided-views-browser.test.mjs +0 -460
  629. package/skills/archify/test/guided-views.test.mjs +0 -144
  630. package/skills/archify/test/helpers/desktop-browser.mjs +0 -48
  631. package/skills/archify/test/helpers/offline-fonts.mjs +0 -76
  632. package/skills/archify/test/helpers/viewer-click.mjs +0 -72
  633. package/skills/archify/test/helpers/xml.mjs +0 -37
  634. package/skills/archify/test/i18n.test.mjs +0 -422
  635. package/skills/archify/test/intent-trace-browser.test.mjs +0 -284
  636. package/skills/archify/test/intent-trace.test.mjs +0 -111
  637. package/skills/archify/test/landing.test.mjs +0 -97
  638. package/skills/archify/test/layout-rules.test.mjs +0 -1498
  639. package/skills/archify/test/legend-contract.test.mjs +0 -404
  640. package/skills/archify/test/motion-governor-browser.test.mjs +0 -342
  641. package/skills/archify/test/motion-governor.test.mjs +0 -111
  642. package/skills/archify/test/offline-font-browser.test.mjs +0 -210
  643. package/skills/archify/test/offline-self-containment.test.mjs +0 -80
  644. package/skills/archify/test/open-artifact.test.mjs +0 -118
  645. package/skills/archify/test/ordinary-model-floor.test.mjs +0 -1052
  646. package/skills/archify/test/output-path.test.mjs +0 -587
  647. package/skills/archify/test/presentation.test.mjs +0 -71
  648. package/skills/archify/test/preset-tryon.test.mjs +0 -113
  649. package/skills/archify/test/preview-contract.test.mjs +0 -40
  650. package/skills/archify/test/preview.test.mjs +0 -530
  651. package/skills/archify/test/proof-aperture.test.mjs +0 -78
  652. package/skills/archify/test/reach-share-card.test.mjs +0 -149
  653. package/skills/archify/test/reader-layout-browser.test.mjs +0 -320
  654. package/skills/archify/test/readme-showcase.test.mjs +0 -319
  655. package/skills/archify/test/real-repository-proof.test.mjs +0 -209
  656. package/skills/archify/test/relationship-direct-explorer.test.mjs +0 -115
  657. package/skills/archify/test/relationship-lens.test.mjs +0 -128
  658. package/skills/archify/test/relationship-permalink.test.mjs +0 -130
  659. package/skills/archify/test/relationship-pulse.test.mjs +0 -122
  660. package/skills/archify/test/release-identity.test.mjs +0 -476
  661. package/skills/archify/test/release-package-gates.test.mjs +0 -750
  662. package/skills/archify/test/render-output-checks.test.mjs +0 -588
  663. package/skills/archify/test/renderer-diagnostic-boundary.test.mjs +0 -107
  664. package/skills/archify/test/repair-receipt.test.mjs +0 -181
  665. package/skills/archify/test/repository-evidence-replacement.test.mjs +0 -136
  666. package/skills/archify/test/repository-evidence.test.mjs +0 -605
  667. package/skills/archify/test/repository-language-metadata.test.mjs +0 -67
  668. package/skills/archify/test/route-journey.test.mjs +0 -125
  669. package/skills/archify/test/route-probe-browser.test.mjs +0 -363
  670. package/skills/archify/test/route-probe.test.mjs +0 -114
  671. package/skills/archify/test/route-share-card.test.mjs +0 -163
  672. package/skills/archify/test/semantic-camera.test.mjs +0 -88
  673. package/skills/archify/test/semantic-flow.test.mjs +0 -90
  674. package/skills/archify/test/semantic-legend-gateway.test.mjs +0 -156
  675. package/skills/archify/test/semantic-lens-browser.test.mjs +0 -372
  676. package/skills/archify/test/semantic-lens.test.mjs +0 -103
  677. package/skills/archify/test/semantic-passport.test.mjs +0 -99
  678. package/skills/archify/test/semantic-radar.test.mjs +0 -735
  679. package/skills/archify/test/semantic-zoom.test.mjs +0 -86
  680. package/skills/archify/test/sequence-column-fit.test.mjs +0 -137
  681. package/skills/archify/test/settled-flow.test.mjs +0 -97
  682. package/skills/archify/test/share-card-export.test.mjs +0 -132
  683. package/skills/archify/test/site-language-continuity.test.mjs +0 -569
  684. package/skills/archify/test/site-language-integration.mjs +0 -9
  685. package/skills/archify/test/skill-metadata.test.mjs +0 -84
  686. package/skills/archify/test/stable-update-manifest.test.mjs +0 -167
  687. package/skills/archify/test/start-page.test.mjs +0 -312
  688. package/skills/archify/test/story-beat-navigator.test.mjs +0 -103
  689. package/skills/archify/test/story-carrier.test.mjs +0 -90
  690. package/skills/archify/test/story-director-strip.test.mjs +0 -91
  691. package/skills/archify/test/story-follow-camera.test.mjs +0 -103
  692. package/skills/archify/test/story-horizon.test.mjs +0 -91
  693. package/skills/archify/test/story-moment-link.test.mjs +0 -93
  694. package/skills/archify/test/story-shelf.test.mjs +0 -84
  695. package/skills/archify/test/story-trail.test.mjs +0 -81
  696. package/skills/archify/test/toolbar-polish.test.mjs +0 -57
  697. package/skills/archify/test/update-contract.test.mjs +0 -133
  698. package/skills/archify/test/update-notifier.test.mjs +0 -3317
  699. package/skills/archify/test/v1-compatibility.test.mjs +0 -329
  700. package/skills/archify/test/vertical-edge.test.mjs +0 -68
  701. package/skills/archify/test/viewer-camera-browser.test.mjs +0 -395
  702. package/skills/archify/test/viewer-chrome-layout.test.mjs +0 -1104
  703. package/skills/archify/test/viewer-identifiers-browser.test.mjs +0 -135
  704. package/skills/archify/test/visual-check.test.mjs +0 -400
  705. package/skills/archify/test/webm-artifact.smoke.mjs +0 -1855
  706. package/skills/archify/test/workflow-compiler-hard-contract.test.mjs +0 -2136
  707. package/skills/archify/test/workflow-compiler.test.mjs +0 -1163
  708. package/skills/archify/test/workflow-migration.test.mjs +0 -620
  709. package/skills/archify/test/workflow-semantic-contract.test.mjs +0 -131
  710. /package/{skills/archify/THIRD_PARTY_NOTICES.md → dist/phoenix-diagram/THIRD-PARTY-LICENSES/0b7fb59365dc21c93b0f62526d74ee913aeec9ae532c112bc76afa7edcd56e14.txt} +0 -0
  711. /package/{skills/archify/LICENSE → dist/phoenix-diagram/THIRD-PARTY-LICENSES/b799ab081703e7821ae5096d2c1abdf14bbdc75e8ea1c4045998c36ed6db9706.txt} +0 -0
  712. /package/{skills/archify/assets/JetBrainsMono-OFL.txt → dist/phoenix-diagram/THIRD-PARTY-LICENSES/c1ab7c666206842a02b35b30770dac0d7a10156ed401c9defc3f02a754d89e90.txt} +0 -0
  713. /package/{skills/archify/examples/agent-tool-call.workflow.json → dist/phoenix-diagram/bundle/examples/legacy.agent-tool-call.workflow.json} +0 -0
  714. /package/{skills/archify/examples/async-job-roundtrip.sequence.json → dist/phoenix-diagram/bundle/examples/legacy.async-job-roundtrip.sequence.json} +0 -0
  715. /package/{skills/archify/examples/deployment-release.lifecycle.json → dist/phoenix-diagram/bundle/examples/legacy.deployment-release.lifecycle.json} +0 -0
  716. /package/{skills/archify/examples/product-analytics.dataflow.json → dist/phoenix-diagram/bundle/examples/legacy.product-analytics.dataflow.json} +0 -0
  717. /package/{skills/archify/examples/web-app.architecture.json → dist/phoenix-diagram/bundle/examples/legacy.web-app.architecture.json} +0 -0
@@ -0,0 +1,1586 @@
1
+ """Validate and freeze experiment inputs without importing a remote runtime."""
2
+
3
+ from copy import deepcopy
4
+ from dataclasses import dataclass, field
5
+ from datetime import datetime
6
+ import errno
7
+ import hashlib
8
+ import json
9
+ import math
10
+ import os
11
+ from pathlib import Path, PurePosixPath
12
+ import re
13
+ import stat
14
+ import subprocess
15
+ import tempfile
16
+ import uuid
17
+
18
+
19
+ VERSIONS = {"harbor_version": "0.24.0", "codex_version": "0.162.1"}
20
+ PRO_V2_REVISION = "66f92766bba642462d4bbe5479e83f91f9211862"
21
+ PHASES = {"prepared", "starting", "running", "capturing", "captured"}
22
+ ROLES = {"optimizer", "trial", "grader", "probe"}
23
+
24
+
25
+ class ProtocolError(ValueError):
26
+ pass
27
+
28
+
29
+ def canonical(value):
30
+ return json.dumps(
31
+ value,
32
+ ensure_ascii=False,
33
+ sort_keys=True,
34
+ separators=(",", ":"),
35
+ allow_nan=False,
36
+ ).encode("utf-8")
37
+
38
+
39
+ def sha256(content):
40
+ return hashlib.sha256(content).hexdigest()
41
+
42
+
43
+ def task_contract(case):
44
+ return ("\n\n".join(case["observable_requirements"]) + "\n").encode("utf-8")
45
+
46
+
47
+ def parse_json(content):
48
+ def pairs(items):
49
+ result = {}
50
+ for key, value in items:
51
+ if key in result:
52
+ raise ProtocolError(f"duplicate JSON field: {key}")
53
+ result[key] = value
54
+ return result
55
+
56
+ def invalid_constant(value):
57
+ raise ProtocolError(f"nonfinite JSON number: {value}")
58
+
59
+ return json.loads(
60
+ content.decode("utf-8") if isinstance(content, bytes) else content,
61
+ object_pairs_hook=pairs,
62
+ parse_constant=invalid_constant,
63
+ )
64
+
65
+
66
+ def load_json(path):
67
+ return parse_json(Path(path).read_text(encoding="utf-8"))
68
+
69
+
70
+ def fields(value, label, required, optional=()):
71
+ if not isinstance(value, dict):
72
+ raise ProtocolError(f"{label}: expected object")
73
+ missing = set(required) - value.keys()
74
+ unknown = value.keys() - set(required) - set(optional)
75
+ if missing or unknown:
76
+ raise ProtocolError(
77
+ f"{label}: missing fields {sorted(missing)}, unknown fields {sorted(unknown)}"
78
+ )
79
+ return value
80
+
81
+
82
+ def text(value, label):
83
+ if not isinstance(value, str) or not value.strip():
84
+ raise ProtocolError(f"{label}: expected nonempty string")
85
+ return value
86
+
87
+
88
+ def number(value, label, minimum=0, maximum=None, integer=False):
89
+ if type(value) not in (int, float) or not math.isfinite(value) or value < minimum:
90
+ raise ProtocolError(f"{label}: expected finite number >= {minimum}")
91
+ if integer and type(value) is not int:
92
+ raise ProtocolError(f"{label}: expected integer")
93
+ if maximum is not None and value > maximum:
94
+ raise ProtocolError(f"{label}: exceeds {maximum}")
95
+ return value
96
+
97
+
98
+ def boolean(value, label):
99
+ if type(value) is not bool:
100
+ raise ProtocolError(f"{label}: expected boolean")
101
+ return value
102
+
103
+
104
+ def choice(value, options, label):
105
+ if not isinstance(value, str) or value not in options:
106
+ raise ProtocolError(f"{label}: expected one of {sorted(options)}")
107
+ return value
108
+
109
+
110
+ def rows(value, label, empty=False):
111
+ if not isinstance(value, list) or (not empty and not value):
112
+ raise ProtocolError(
113
+ f"{label}: expected {'possibly empty ' if empty else 'nonempty '}list"
114
+ )
115
+ return value
116
+
117
+
118
+ def fingerprint(value, label, length=64):
119
+ if not isinstance(value, str) or not re.fullmatch(f"[0-9a-f]{{{length}}}", value):
120
+ raise ProtocolError(f"{label}: expected {length}-character content hash")
121
+ return value
122
+
123
+
124
+ def relative_path(name):
125
+ text(name, "path")
126
+ path = PurePosixPath(name)
127
+ if (
128
+ path.is_absolute()
129
+ or ".." in path.parts
130
+ or "\\" in name
131
+ or path.as_posix() != name
132
+ or name == "."
133
+ ):
134
+ raise ProtocolError(f"path must be canonical and relative: {name}")
135
+ if "\x00" in name:
136
+ raise ProtocolError("path contains NUL")
137
+ return name
138
+
139
+
140
+ def remote_path(name):
141
+ text(name, "remote path")
142
+ path = PurePosixPath(name)
143
+ if (
144
+ not path.is_absolute()
145
+ or ".." in path.parts
146
+ or path.as_posix() != name
147
+ or "\x00" in name
148
+ or name == "/"
149
+ ):
150
+ raise ProtocolError(
151
+ "remote paths must be canonical, absolute and below the root"
152
+ )
153
+ return name
154
+
155
+
156
+ def export_path(name):
157
+ relative_path(name)
158
+ parts = PurePosixPath(name).parts
159
+ for index, part in enumerate(parts):
160
+ if (
161
+ part == ".git"
162
+ or part == ".env"
163
+ or part.startswith(".env.")
164
+ or part in {".mcp.json", "auth.json", "credentials.json"}
165
+ ):
166
+ raise ProtocolError(
167
+ f"host configuration or credential path cannot be exported: {name}"
168
+ )
169
+ if part in {".codex", ".claude", ".agents"} and parts[
170
+ index + 1 : index + 2
171
+ ] != ("skills",):
172
+ raise ProtocolError(f"host configuration cannot be exported: {name}")
173
+ return name
174
+
175
+
176
+ def path_list(value, label, empty=False):
177
+ names = [export_path(name) for name in rows(value, label, empty)]
178
+ if len(names) != len(set(names)):
179
+ raise ProtocolError(f"{label}: duplicate paths")
180
+ return names
181
+
182
+
183
+ def covered(name, allowed):
184
+ return any(name == prefix or name.startswith(prefix + "/") for prefix in allowed)
185
+
186
+
187
+ def directory(name, base):
188
+ path = Path(text(name, "directory"))
189
+ if not path.is_absolute():
190
+ path = base / path
191
+ path = path.resolve(strict=True)
192
+ if not path.is_dir():
193
+ raise ProtocolError("expected directory")
194
+ return path
195
+
196
+
197
+ def read_file(root, name):
198
+ export_path(name)
199
+ # O_NONBLOCK avoids opening a FIFO before checking its type; O_NOFOLLOW
200
+ # and directory descriptors keep every lookup inside the authorized root.
201
+ directory_fd = os.open(root, os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW)
202
+ try:
203
+ parts = PurePosixPath(name).parts
204
+ for part in parts[:-1]:
205
+ child_fd = os.open(
206
+ part, os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW, dir_fd=directory_fd
207
+ )
208
+ os.close(directory_fd)
209
+ directory_fd = child_fd
210
+ descriptor = os.open(
211
+ parts[-1], os.O_RDONLY | os.O_NONBLOCK | os.O_NOFOLLOW, dir_fd=directory_fd
212
+ )
213
+ except OSError as error:
214
+ if error.errno in {errno.ELOOP, errno.ENOTDIR}:
215
+ raise ProtocolError(
216
+ f"symlink or invalid directory cannot be exported: {name}"
217
+ ) from None
218
+ raise
219
+ finally:
220
+ os.close(directory_fd)
221
+ with os.fdopen(descriptor, "rb") as stream:
222
+ info = os.fstat(stream.fileno())
223
+ if not stat.S_ISREG(info.st_mode):
224
+ raise ProtocolError(f"only regular files can be exported: {name}")
225
+ mode = stat.S_IMODE(info.st_mode)
226
+ if mode & 0o7000:
227
+ raise ProtocolError(f"special permission bits are not supported: {name}")
228
+ content = stream.read()
229
+ return {"content": content, "sha256": sha256(content), "mode": mode}
230
+
231
+
232
+ def manifest(files):
233
+ return {
234
+ name: {
235
+ "sha256": row["sha256"],
236
+ "mode": row["mode"],
237
+ "size": len(row["content"]),
238
+ }
239
+ for name, row in sorted(files.items())
240
+ }
241
+
242
+
243
+ def bundle_hash(files):
244
+ return sha256(canonical(manifest(files)))
245
+
246
+
247
+ def git(root, *args):
248
+ result = subprocess.run(["git", "-C", str(root), *args], capture_output=True)
249
+ if result.returncode:
250
+ # Git diagnostics may include credential-bearing remote URLs.
251
+ raise ProtocolError("repository or base commit could not be read")
252
+ return result.stdout
253
+
254
+
255
+ def repository_files(spec):
256
+ root = Path(spec["target"]["repo"])
257
+ base = spec["target"]["base_commit"]
258
+ top = Path(os.fsdecode(git(root, "rev-parse", "--show-toplevel")).strip()).resolve()
259
+ if top != root:
260
+ raise ProtocolError("target.repo must be the repository root")
261
+ if git(root, "rev-parse", base + "^{commit}").decode().strip() != base:
262
+ raise ProtocolError("base_commit must identify an existing commit")
263
+ if git(root, "rev-parse", "HEAD").decode().strip() != base:
264
+ raise ProtocolError(
265
+ "checkout HEAD must match base_commit before including dirty files"
266
+ )
267
+ entries = git(root, "ls-tree", "-rz", "--full-tree", base).split(b"\x00")
268
+ tracked = {}
269
+ for entry in entries:
270
+ if not entry:
271
+ continue
272
+ meta, raw_name = entry.split(b"\t", 1)
273
+ mode, kind, _ = meta.decode().split()
274
+ tracked[os.fsdecode(raw_name)] = (mode, kind)
275
+ selected = set()
276
+ for prefix in spec["source"]["paths"]:
277
+ matches = {name for name in tracked if covered(name, [prefix])}
278
+ if not matches:
279
+ raise ProtocolError(
280
+ f"source path has no files at the base commit: {prefix}"
281
+ )
282
+ selected.update(matches)
283
+ for name in spec["source"]["new_paths"]:
284
+ if name in tracked:
285
+ raise ProtocolError(f"new_path already exists at base commit: {name}")
286
+ selected.add(name)
287
+ result, deleted = {}, []
288
+ for name in sorted(selected):
289
+ export_path(name)
290
+ if not covered(name, spec["authority"]["export_paths"]):
291
+ raise ProtocolError(f"file outside export authority: {name}")
292
+ if name in tracked and tracked[name] not in {
293
+ ("100644", "blob"),
294
+ ("100755", "blob"),
295
+ }:
296
+ raise ProtocolError(f"symlinks and submodules cannot be exported: {name}")
297
+ try:
298
+ result[name] = read_file(root, name)
299
+ except FileNotFoundError:
300
+ if name not in tracked:
301
+ raise ProtocolError(f"missing authorized new file: {name}") from None
302
+ deleted.append(name)
303
+ for name in spec["target"]["allowed_paths"]:
304
+ if name in tracked and name not in selected:
305
+ raise ProtocolError(f"target file is missing from source allowlist: {name}")
306
+ return result, deleted
307
+
308
+
309
+ def validate_target(spec, base):
310
+ target = fields(
311
+ spec["target"],
312
+ "target",
313
+ {
314
+ "kind",
315
+ "repo",
316
+ "repo_id",
317
+ "base_commit",
318
+ "allowed_paths",
319
+ "surfaces",
320
+ "protected_rules",
321
+ },
322
+ {"compatible_bases"},
323
+ )
324
+ choice(target["kind"], {"skill", "agents"}, "target.kind")
325
+ target["repo"] = str(directory(target["repo"], base))
326
+ text(target["repo_id"], "target.repo_id")
327
+ fingerprint(target["base_commit"], "target.base_commit", 40)
328
+ for revision in rows(
329
+ target.get("compatible_bases", []), "compatible_bases", empty=True
330
+ ):
331
+ fingerprint(revision, "compatible base", 40)
332
+ git(
333
+ Path(target["repo"]),
334
+ "merge-base",
335
+ "--is-ancestor",
336
+ revision,
337
+ target["base_commit"],
338
+ )
339
+ allowed = path_list(target["allowed_paths"], "target.allowed_paths")
340
+ surfaces = fields(target["surfaces"], "target.surfaces", {"skill", "agents"})
341
+ for surface in surfaces:
342
+ path_list(surfaces[surface], f"surfaces.{surface}", empty=True)
343
+ all_paths = surfaces["skill"] + surfaces["agents"]
344
+ if set(all_paths) != set(allowed) or len(set(all_paths)) != len(all_paths):
345
+ raise ProtocolError("instruction surfaces must partition allowed_paths")
346
+ if not surfaces[target["kind"]]:
347
+ raise ProtocolError("target kind must have a nonempty instruction surface")
348
+ for rule in rows(target["protected_rules"], "protected_rules", empty=True):
349
+ fields(rule, "protected_rule", {"path", "text", "kind", "verification"})
350
+ if relative_path(rule["path"]) not in allowed:
351
+ raise ProtocolError("protected rule is outside the target")
352
+ text(rule["text"], "protected_rule.text")
353
+ choice(
354
+ rule["kind"],
355
+ {"principle", "authority", "scope", "fact"},
356
+ "protected_rule.kind",
357
+ )
358
+ choice(
359
+ rule["verification"],
360
+ {"exact", "independent"},
361
+ "protected_rule.verification",
362
+ )
363
+ authority = fields(
364
+ spec["authority"],
365
+ "authority",
366
+ {
367
+ "repo",
368
+ "export_paths",
369
+ "write_paths",
370
+ "remote_host",
371
+ "remote_root",
372
+ "auth_path",
373
+ "allow_remote",
374
+ "allow_apply",
375
+ "allow_unverified",
376
+ },
377
+ {"evaluation_root", "allow_typesafe_auxiliary"} if spec["schema_version"] == 2 else (),
378
+ )
379
+ authority["repo"] = str(directory(authority["repo"], base))
380
+ if authority["repo"] != target["repo"]:
381
+ raise ProtocolError("authority.repo does not match target.repo")
382
+ for name in ["export_paths", "write_paths"]:
383
+ path_list(authority[name], "authority." + name, empty=name == "write_paths")
384
+ if any(name not in allowed for name in authority["write_paths"]):
385
+ raise ProtocolError("write authority must enumerate target files exactly")
386
+ for name in ["allow_remote", "allow_apply", "allow_unverified"]:
387
+ boolean(authority[name], "authority." + name)
388
+ if "allow_typesafe_auxiliary" in authority:
389
+ boolean(authority["allow_typesafe_auxiliary"], "authority.allow_typesafe_auxiliary")
390
+ if not authority["allow_remote"]:
391
+ raise ProtocolError("remote export and execution have not been authorized")
392
+ source = fields(spec["source"], "source", {"paths", "new_paths"}, {"fixed_skill_roots"})
393
+ path_list(source["paths"], "source.paths")
394
+ path_list(source["new_paths"], "source.new_paths", empty=True)
395
+ if "fixed_skill_roots" in source:
396
+ path_list(source["fixed_skill_roots"], "source.fixed_skill_roots", empty=True)
397
+ if any(
398
+ not covered(name, authority["export_paths"])
399
+ for name in source["paths"] + source["new_paths"]
400
+ ):
401
+ raise ProtocolError("source allowlist exceeds export authority")
402
+
403
+
404
+ def validate_runtime(spec):
405
+ runtime = fields(
406
+ spec["runtime"],
407
+ "runtime",
408
+ {
409
+ "provider",
410
+ "ssh_target",
411
+ "remote_root",
412
+ "docker_binary",
413
+ "docker_version",
414
+ "codex_architecture",
415
+ "authentication",
416
+ *VERSIONS,
417
+ },
418
+ {"model", "effort", "tools", "sampling", "apparmor_profile", "model_proxy"},
419
+ )
420
+ choice(runtime["provider"], {"ssh"}, "runtime.provider")
421
+ if "model_proxy" in runtime and not re.fullmatch(
422
+ r"https?://[A-Za-z0-9][A-Za-z0-9.-]*:[0-9]{1,5}",
423
+ text(runtime["model_proxy"], "model_proxy"),
424
+ ):
425
+ raise ProtocolError(
426
+ "model_proxy must name an existing HTTP proxy without credentials or paths"
427
+ )
428
+ if "apparmor_profile" in runtime and not re.fullmatch(
429
+ r"[A-Za-z0-9][A-Za-z0-9_.-]{0,127}",
430
+ text(runtime["apparmor_profile"], "apparmor_profile"),
431
+ ):
432
+ raise ProtocolError(
433
+ "apparmor_profile must name an existing profile without options"
434
+ )
435
+ choice(
436
+ runtime["codex_architecture"],
437
+ {"aarch64", "x86_64"},
438
+ "runtime.codex_architecture",
439
+ )
440
+ if not re.fullmatch(
441
+ r"(?:[A-Za-z0-9._-]+@)?[A-Za-z0-9][A-Za-z0-9._-]*",
442
+ text(runtime["ssh_target"], "ssh_target"),
443
+ ):
444
+ raise ProtocolError(
445
+ "ssh_target must be a host or user@host without SSH options"
446
+ )
447
+ for key in ["remote_root", "docker_binary"]:
448
+ remote_path(runtime[key])
449
+ if not re.fullmatch(
450
+ r"[0-9]+\.[0-9]+\.[0-9]+", text(runtime["docker_version"], "docker_version")
451
+ ):
452
+ raise ProtocolError("docker_version must be explicit")
453
+ authority = spec["authority"]
454
+ if (authority["remote_host"], authority["remote_root"]) != (
455
+ runtime["ssh_target"],
456
+ runtime["remote_root"],
457
+ ):
458
+ raise ProtocolError("remote host or output root is outside authority")
459
+ authentication = runtime["authentication"]
460
+ if authentication is not None:
461
+ fields(authentication, "authentication", {"mode", "path"})
462
+ choice(authentication["mode"], {"remote_codex_login"}, "authentication.mode")
463
+ remote_path(authentication["path"])
464
+ auth_path = None if authentication is None else authentication["path"]
465
+ if authority["auth_path"] != auth_path:
466
+ raise ProtocolError("authentication source is outside authority")
467
+ for key, version in VERSIONS.items():
468
+ if runtime[key] != version:
469
+ raise ProtocolError(f"runtime.{key}: expected {version}")
470
+ if spec["mode"] != "smoke" or "model" in runtime:
471
+ if authentication is None:
472
+ raise ProtocolError(
473
+ "model execution requires explicitly authorized remote Codex login"
474
+ )
475
+ for key in ["model", "effort", "tools", "sampling"]:
476
+ if key not in runtime:
477
+ raise ProtocolError(f"runtime.{key}: required for model execution")
478
+ text(runtime["model"], "runtime.model")
479
+ choice(
480
+ runtime["effort"],
481
+ {"minimal", "low", "medium", "high", "xhigh"},
482
+ "runtime.effort",
483
+ )
484
+ tools = rows(runtime["tools"], "runtime.tools")
485
+ if any(tool != "shell" for tool in tools) or len(tools) != len(set(tools)):
486
+ raise ProtocolError("only the explicit shell tool is supported")
487
+ sampling = fields(runtime["sampling"], "runtime.sampling", {"seed"})
488
+ if sampling["seed"] is not None:
489
+ raise ProtocolError(
490
+ "this Codex runtime has no controllable sampling seed; record null"
491
+ )
492
+
493
+
494
+ def validate_measurement(spec):
495
+ budget = fields(
496
+ spec["budget"],
497
+ "budget",
498
+ {
499
+ "max_candidates",
500
+ "max_trials",
501
+ "max_parallel_trials",
502
+ "per_trial_timeout_sec",
503
+ "total_deadline_sec",
504
+ "recovery_window_sec",
505
+ "max_retries",
506
+ },
507
+ {"max_auxiliary_calls"} if spec["schema_version"] == 2 else (),
508
+ )
509
+ for key, value in budget.items():
510
+ number(
511
+ value,
512
+ "budget." + key,
513
+ minimum=0 if key in {"max_retries", "max_auxiliary_calls"} else 1,
514
+ integer=key.startswith("max_"),
515
+ )
516
+ if budget["max_parallel_trials"] > budget["max_trials"]:
517
+ raise ProtocolError("parallel trials exceed total trials")
518
+ if (
519
+ budget["per_trial_timeout_sec"] + budget["recovery_window_sec"]
520
+ > budget["total_deadline_sec"]
521
+ ):
522
+ raise ProtocolError("trial timeout and recovery window exceed total deadline")
523
+ measurement = fields(
524
+ spec["measurement"],
525
+ "measurement",
526
+ {
527
+ "objective",
528
+ "primary_metric",
529
+ "minimum_effect",
530
+ "confidence_level",
531
+ "minimum_groups",
532
+ "repeats",
533
+ "seed",
534
+ "checkpoint",
535
+ "confirmation",
536
+ "weights",
537
+ },
538
+ {"quality_loss_limit", "minimum_cost_effect"}
539
+ | ({"minimum_effect_reason", "search_policy"} if spec["schema_version"] == 2 else set()),
540
+ )
541
+ choice(
542
+ measurement["objective"],
543
+ {"quality", "cost_at_quality"},
544
+ "measurement.objective",
545
+ )
546
+ choice(
547
+ measurement["primary_metric"],
548
+ {"task_quality"} if spec["schema_version"] == 2 else {"task_success"},
549
+ "measurement.primary_metric",
550
+ )
551
+ if spec["schema_version"] == 2:
552
+ if measurement["objective"] != "quality":
553
+ raise ProtocolError("v2 supports the frozen quality objective only")
554
+ text(measurement.get("minimum_effect_reason"), "minimum_effect_reason")
555
+ if spec["runtime"]["model"] != "gpt-6.1-sol" or spec["runtime"]["effort"] != "high":
556
+ raise ProtocolError("v2 quality experiments require gpt-6.1-sol/high")
557
+ if "search_policy" in measurement:
558
+ text(measurement["search_policy"], "measurement.search_policy")
559
+ choice(measurement["search_policy"], {"strict", "bounded_exploration_v1"}, "measurement.search_policy")
560
+ if measurement.get("search_policy") == "bounded_exploration_v1":
561
+ if spec["mode"] != "search" or budget["max_candidates"] != 1:
562
+ raise ProtocolError("bounded exploration requires search with exactly one candidate limit")
563
+ if spec["authority"]["allow_apply"] is not False or spec["authority"]["write_paths"]:
564
+ raise ProtocolError("bounded exploration cannot have apply or write authority")
565
+ number(measurement["minimum_effect"], "minimum_effect", maximum=1)
566
+ number(
567
+ measurement["confidence_level"], "confidence_level", minimum=0.5, maximum=0.999
568
+ )
569
+ number(measurement["minimum_groups"], "minimum_groups", minimum=2, integer=True)
570
+ number(measurement["repeats"], "repeats", minimum=1, integer=True)
571
+ number(measurement["seed"], "seed", integer=True)
572
+ choice(measurement["checkpoint"], {"fixed"}, "measurement.checkpoint")
573
+ choice(measurement["confirmation"], {"once"}, "measurement.confirmation")
574
+ if measurement["objective"] == "cost_at_quality":
575
+ for key in ["quality_loss_limit", "minimum_cost_effect"]:
576
+ if key not in measurement:
577
+ raise ProtocolError(f"measurement.{key}: required for cost objective")
578
+ number(
579
+ measurement[key],
580
+ key,
581
+ maximum=1 if key == "quality_loss_limit" else None,
582
+ )
583
+ else:
584
+ for key in ["quality_loss_limit", "minimum_cost_effect"]:
585
+ if key in measurement:
586
+ number(
587
+ measurement[key],
588
+ key,
589
+ maximum=1 if key == "quality_loss_limit" else None,
590
+ )
591
+ for guardrail in rows(spec["guardrails"], "guardrails"):
592
+ fields(guardrail, "guardrail", {"name", "minimum"})
593
+ text(guardrail["name"], "guardrail.name")
594
+ number(guardrail["minimum"], "guardrail.minimum", maximum=1)
595
+ names = [item["name"] for item in spec["guardrails"]]
596
+ if len(names) != len(set(names)):
597
+ raise ProtocolError("duplicate guardrail name")
598
+
599
+
600
+ def verify_public_source(case, root, views):
601
+ if case["source"]["kind"] != "pro_v2":
602
+ return
603
+ top = Path(os.fsdecode(git(root, "rev-parse", "--show-toplevel")).strip()).resolve()
604
+ if git(top, "rev-parse", "HEAD").decode().strip() != PRO_V2_REVISION:
605
+ raise ProtocolError("public task checkout is not at the fixed source revision")
606
+ prefix = root.relative_to(top).as_posix()
607
+ if len(PurePosixPath(prefix).parts) != 3 or not prefix.startswith("v2/tasks/"):
608
+ raise ProtocolError(
609
+ "public task must come from the fixed source task directory"
610
+ )
611
+ files = {name: row for view in views.values() for name, row in view.items()}
612
+ tracked = {}
613
+ for entry in git(
614
+ top, "ls-tree", "-rz", "--full-tree", PRO_V2_REVISION, "--", prefix
615
+ ).split(b"\x00"):
616
+ if not entry:
617
+ continue
618
+ metadata, name = entry.split(b"\t", 1)
619
+ mode, kind, digest = metadata.decode().split()
620
+ relative = PurePosixPath(os.fsdecode(name)).relative_to(prefix).as_posix()
621
+ tracked[relative] = (mode, kind, digest)
622
+ if set(files) != set(tracked):
623
+ raise ProtocolError("public task views must account for every frozen task file")
624
+ for name, row in files.items():
625
+ mode, kind, digest = tracked[name]
626
+ blob_id = hashlib.sha1(
627
+ b"blob " + str(len(row["content"])).encode() + b"\x00" + row["content"]
628
+ ).hexdigest()
629
+ expected_mode = "100755" if row["mode"] & 0o111 else "100644"
630
+ if kind != "blob" or mode != expected_mode or blob_id != digest:
631
+ raise ProtocolError(
632
+ "public task file differs from the fixed source revision"
633
+ )
634
+
635
+
636
+ def task_files(spec, base):
637
+ case_files, ids, split_groups, split_families, split_tasks = {}, set(), {}, {}, {}
638
+ family_groups, task_groups = {}, {}
639
+ for case in rows(spec["cases"], "cases"):
640
+ fields(
641
+ case,
642
+ "case",
643
+ {
644
+ "case_id",
645
+ "group_id",
646
+ "repo_id",
647
+ "base_commit",
648
+ "split",
649
+ "task_path",
650
+ "source",
651
+ "public_paths",
652
+ "grader_paths",
653
+ "oracle_paths",
654
+ "image",
655
+ "observable_requirements",
656
+ "information_cutoff",
657
+ },
658
+ {"grader_ref", "platform", "repo_path"},
659
+ )
660
+ for key in ["case_id", "group_id", "repo_id"]:
661
+ text(case[key], "case." + key)
662
+ if case["case_id"] in ids:
663
+ raise ProtocolError("duplicate case_id")
664
+ ids.add(case["case_id"])
665
+ fingerprint(case["base_commit"], "case.base_commit", 40)
666
+ choice(case["split"], {"search", "validation", "confirmation"}, "case.split")
667
+ source = fields(case["source"], "case.source", {"kind", "revision", "family"})
668
+ choice(source["kind"], {"repo", "pro_v2"}, "case.source.kind")
669
+ text(source["family"], "case.source.family")
670
+ fingerprint(source["revision"], "case.source.revision", 40)
671
+ expected_revision = (
672
+ PRO_V2_REVISION if source["kind"] == "pro_v2" else case["base_commit"]
673
+ )
674
+ if source["revision"] != expected_revision:
675
+ raise ProtocolError("task source revision does not match the frozen source")
676
+ target = spec["target"]
677
+ if target["kind"] == "agents" and (
678
+ case["repo_id"] != target["repo_id"]
679
+ or case["base_commit"]
680
+ not in [target["base_commit"], *target.get("compatible_bases", [])]
681
+ ):
682
+ raise ProtocolError(
683
+ "AGENTS task must match the target repository and an explicitly compatible base"
684
+ )
685
+ if not re.fullmatch(
686
+ r"[^\s]+@sha256:[0-9a-f]{64}", text(case["image"], "case.image")
687
+ ):
688
+ raise ProtocolError("task image must be pinned by digest")
689
+ case.setdefault("platform", "linux/amd64")
690
+ platforms = {"linux/amd64"}
691
+ if spec["schema_version"] == 2 and source["kind"] == "repo":
692
+ platforms.add("linux/arm64")
693
+ choice(case["platform"], platforms, "case.platform")
694
+ for item in rows(case["observable_requirements"], "observable_requirements"):
695
+ text(item, "observable requirement")
696
+ try:
697
+ cutoff = datetime.fromisoformat(
698
+ text(case["information_cutoff"], "information_cutoff").replace(
699
+ "Z", "+00:00"
700
+ )
701
+ )
702
+ except ValueError:
703
+ raise ProtocolError("information_cutoff must be an ISO timestamp") from None
704
+ if cutoff.tzinfo is None:
705
+ raise ProtocolError("information_cutoff must include timezone")
706
+ root = directory(case["task_path"], base)
707
+ case["task_path"] = str(root)
708
+ views = {}
709
+ for key in ["public_paths", "grader_paths", "oracle_paths"]:
710
+ names = path_list(case[key], "case." + key)
711
+ views[key] = {name: read_file(root, name) for name in names}
712
+ if "instruction.md" not in views["public_paths"]:
713
+ raise ProtocolError("public task view must contain instruction.md")
714
+ if "repo_path" not in case:
715
+ match = re.search(
716
+ r"A code repository is available in the `([^`]+)` directory",
717
+ views["public_paths"]["instruction.md"]["content"].decode("utf-8"),
718
+ )
719
+ if match is None:
720
+ raise ProtocolError(
721
+ "case.repo_path is required when the public task does not declare it"
722
+ )
723
+ case["repo_path"] = match[1]
724
+ remote_path(case["repo_path"])
725
+ if any(
726
+ covered(case["repo_path"], [name])
727
+ for name in [
728
+ "/evolution-control",
729
+ "/evolution-input",
730
+ "/home/evolution",
731
+ "/tests",
732
+ "/solution",
733
+ ]
734
+ ):
735
+ raise ProtocolError(
736
+ "task repository overlaps the runtime control namespace"
737
+ )
738
+ public = set(views["public_paths"])
739
+ private = set(views["grader_paths"]) | set(views["oracle_paths"])
740
+ if public & private or any(
741
+ PurePosixPath(name).parts[0] in {"tests", "solution", "answers"}
742
+ for name in public
743
+ ):
744
+ raise ProtocolError("public task view exposes grader or oracle")
745
+ public_inodes = {(root / name).stat().st_ino for name in public}
746
+ private_inodes = {(root / name).stat().st_ino for name in private}
747
+ if public_inodes & private_inodes:
748
+ raise ProtocolError("public task view aliases private material")
749
+ verify_public_source(case, root, views)
750
+ grader_ref = bundle_hash(views["grader_paths"])
751
+ if "grader_ref" in case and case["grader_ref"] != grader_ref:
752
+ raise ProtocolError("grader_ref does not match the actual grading files")
753
+ case["grader_ref"] = grader_ref
754
+ identity = bundle_hash(views["public_paths"])
755
+ for mapping, key in [
756
+ (family_groups, (case["repo_id"], source["family"])),
757
+ (task_groups, (case["repo_id"], identity)),
758
+ ]:
759
+ if mapping.setdefault(key, case["group_id"]) != case["group_id"]:
760
+ raise ProtocolError(
761
+ "related task sources cannot count as independent groups"
762
+ )
763
+ for mapping, key in [
764
+ (split_groups, (case["repo_id"], case["group_id"])),
765
+ (split_families, (case["repo_id"], source["family"])),
766
+ (split_tasks, (case["repo_id"], identity)),
767
+ ]:
768
+ if key in mapping and mapping[key] != case["split"]:
769
+ raise ProtocolError(
770
+ "related tasks cannot cross search/validation/confirmation splits"
771
+ )
772
+ mapping[key] = case["split"]
773
+ case_files[case["case_id"]] = views
774
+ splits = {case["split"] for case in spec["cases"]}
775
+ bounded_exploration = (spec["schema_version"] == 2 and spec["mode"] == "search"
776
+ and spec["measurement"].get("search_policy") == "bounded_exploration_v1")
777
+ if "search" not in splits or (
778
+ spec["mode"] not in {"smoke", "calibrate"} and not bounded_exploration and "confirmation" not in splits
779
+ ):
780
+ raise ProtocolError(
781
+ "mode requires search and, for comparisons, heldout confirmation tasks"
782
+ )
783
+ if spec["mode"] == "calibrate" and splits != {"search"}:
784
+ raise ProtocolError("calibrate does not expose confirmation or validation tasks")
785
+ weights = spec["measurement"]["weights"]
786
+ if not isinstance(weights, dict) or set(weights) != ids:
787
+ raise ProtocolError("measurement.weights must name every case exactly once")
788
+ for weight in weights.values():
789
+ number(weight, "case weight", minimum=0.000001)
790
+ return case_files
791
+
792
+
793
+ def skill_name(content):
794
+ header = re.match(rb"\A---\r?\n(.*?)\r?\n---(?:\r?\n|\Z)", content, re.DOTALL)
795
+ if header is None:
796
+ return None
797
+ name = re.search(
798
+ rb"(?m)^name:[ \t]*['\"]?([a-z0-9][a-z0-9-]*)['\"]?[ \t]*(?:#.*)?$", header[1]
799
+ )
800
+ return name[1].decode() if name else None
801
+
802
+
803
+ def condition_bundles(spec, baseline):
804
+ target = spec["target"]
805
+ surfaces = target["surfaces"]
806
+ skill_roots = {
807
+ str(PurePosixPath(path).parent)
808
+ for path in surfaces["skill"]
809
+ if PurePosixPath(path).name == "SKILL.md"
810
+ }
811
+ for root in skill_roots:
812
+ if any(
813
+ covered(path, [root]) and path not in surfaces["skill"] for path in baseline
814
+ ):
815
+ raise ProtocolError(
816
+ "skill surface omits files belonging to the target skill"
817
+ )
818
+ target_skills = [
819
+ baseline[path]["content"]
820
+ for path in surfaces["skill"]
821
+ if path in baseline and PurePosixPath(path).name == "SKILL.md"
822
+ ]
823
+ target_names = {skill_name(content) for content in target_skills}
824
+ if surfaces["skill"] and (not target_skills or None in target_names):
825
+ raise ProtocolError(
826
+ "target skill requires SKILL.md with a canonical name field"
827
+ )
828
+ for path, row in baseline.items():
829
+ if (
830
+ path not in surfaces["skill"]
831
+ and PurePosixPath(path).name == "SKILL.md"
832
+ and (
833
+ row["content"] in target_skills
834
+ or skill_name(row["content"]) in target_names
835
+ )
836
+ ):
837
+ raise ProtocolError(
838
+ "target skill has another readable copy outside its surface"
839
+ )
840
+ bundles, levels, differences = {}, {"skill": {}, "agents": {}}, {}
841
+ for condition in rows(spec["conditions"], "conditions"):
842
+ fields(condition, "condition", {"condition_id", "skill", "agents", "overrides"})
843
+ name = text(condition["condition_id"], "condition_id")
844
+ if name in bundles:
845
+ raise ProtocolError("duplicate condition_id")
846
+ choice(
847
+ condition["skill"],
848
+ {"absent", "baseline", "candidate", "fixed"},
849
+ "condition.skill",
850
+ )
851
+ choice(
852
+ condition["agents"],
853
+ {"minimal", "baseline", "candidate", "fixed"},
854
+ "condition.agents",
855
+ )
856
+ if not isinstance(condition["overrides"], dict):
857
+ raise ProtocolError("condition.overrides must be a path-to-content object")
858
+ files = deepcopy(baseline)
859
+ changed = []
860
+ for path, content in condition["overrides"].items():
861
+ export_path(path)
862
+ if path not in target["allowed_paths"]:
863
+ raise ProtocolError(f"condition changes an undeclared surface: {path}")
864
+ if content is None:
865
+ files.pop(path, None)
866
+ elif isinstance(content, str):
867
+ raw = content.encode("utf-8")
868
+ files[path] = {
869
+ "content": raw,
870
+ "sha256": sha256(raw),
871
+ "mode": baseline.get(path, {}).get("mode", 0o644),
872
+ }
873
+ else:
874
+ raise ProtocolError("condition content must be text or null")
875
+ if baseline.get(path) != files.get(path):
876
+ changed.append(path)
877
+ for rule in target["protected_rules"]:
878
+ if condition["skill"] == "absent" and rule["path"] in surfaces["skill"]:
879
+ continue
880
+ if rule["verification"] == "exact" and rule[
881
+ "text"
882
+ ].encode() not in files.get(rule["path"], {}).get("content", b""):
883
+ raise ProtocolError(
884
+ f"condition removes a protected rule from {rule['path']}"
885
+ )
886
+ for surface, paths in surfaces.items():
887
+ level = condition[surface]
888
+ content_hash = bundle_hash(
889
+ {path: files[path] for path in paths if path in files}
890
+ )
891
+ prior = levels[surface]
892
+ if level in prior and prior[level] != content_hash:
893
+ raise ProtocolError(f"same {surface} level has different bytes")
894
+ if level not in prior and content_hash in prior.values():
895
+ raise ProtocolError(f"different {surface} levels have identical bytes")
896
+ prior[level] = content_hash
897
+ if not paths and level != "fixed":
898
+ raise ProtocolError(f"{surface} factor is declared without a surface")
899
+ if level == "absent" and any(path in files for path in paths):
900
+ raise ProtocolError(
901
+ "absent skill condition still contains target skill files"
902
+ )
903
+ if level in {"baseline", "fixed"} and any(
904
+ files.get(path) != baseline.get(path) for path in paths
905
+ ):
906
+ raise ProtocolError(
907
+ f"{surface} baseline/fixed condition changes actual bytes"
908
+ )
909
+ bundles[name] = files
910
+ differences[name] = sorted(changed)
911
+ initial = text(spec["baseline_condition"], "baseline_condition")
912
+ if initial not in bundles or bundles[initial] != baseline:
913
+ raise ProtocolError(
914
+ "baseline_condition must reproduce the actual initial bytes"
915
+ )
916
+ if spec["mode"] not in {"smoke", "calibrate"}:
917
+ selected = spec.get("candidate_condition")
918
+ if selected is not None:
919
+ text(selected, "candidate_condition")
920
+ if spec["mode"] == "compare" and (
921
+ selected not in bundles or selected == initial
922
+ ):
923
+ raise ProtocolError(
924
+ "compare requires a distinct frozen candidate_condition"
925
+ )
926
+ if target["kind"] == "skill" and "absent" not in levels["skill"]:
927
+ raise ProtocolError("skill comparison requires a no-target-skill control")
928
+ return bundles, differences
929
+
930
+
931
+ def candidate_from_patch(job, parent, proposal, patch, *, search_records=None):
932
+ fields(
933
+ proposal,
934
+ "proposal",
935
+ {
936
+ "parent_hash",
937
+ "hypothesis",
938
+ "expected_effect",
939
+ "counterexample",
940
+ "changed_paths",
941
+ } | ({"mechanism"} if job.spec["schema_version"] == 2 else set()),
942
+ )
943
+ if proposal["parent_hash"] != bundle_hash(parent):
944
+ raise ProtocolError("proposal does not name the frozen parent")
945
+ for key in ["hypothesis", "expected_effect", "counterexample"]:
946
+ text(proposal[key], "proposal." + key)
947
+ if job.spec["schema_version"] == 2:
948
+ from quality import continuous_item
949
+
950
+ mechanism = fields(proposal["mechanism"], "one mechanism", {
951
+ "criterion_id", "patch_sha256", "cause", "expected_criteria", "regression_risk"})
952
+ for key in ("criterion_id", "cause", "regression_risk"):
953
+ text(mechanism[key], "mechanism." + key)
954
+ fingerprint(mechanism["patch_sha256"], "mechanism artifact")
955
+ rubrics = {c["case_id"]: parse_json(job.evaluation_files[job.spec["evaluation"]["rubrics"][c["case_id"]]]["content"])
956
+ for c in job.spec["cases"] if c["split"] == "search"}
957
+ known = {c["criterion_id"] for r in rubrics.values() for c in r["criteria"]}
958
+ expected = rows(mechanism["expected_criteria"], "expected quality criteria")
959
+ if any(not isinstance(name, str) or name not in known for name in expected) or len(set(expected)) != len(expected) or mechanism["criterion_id"] not in expected:
960
+ raise ProtocolError("mechanism must target the observed public quality criterion")
961
+ supported = False
962
+ for record in search_records or []:
963
+ if not (record.get("schema_version") == 2 and record.get("purpose") == "task"
964
+ and record.get("split") == "search" and record.get("status") in {"ok", "behavior_failure"}
965
+ and record.get("candidate_hash") == proposal["parent_hash"]
966
+ and record.get("patch_sha256") == mechanism["patch_sha256"]
967
+ and type(record.get("task_success")) is int and record["task_success"] in (0, 1)
968
+ and record.get("quality_status") == "valid"):
969
+ continue
970
+ criterion = next((c for c in rubrics.get(record.get("case_id"), {}).get("criteria", [])
971
+ if c["criterion_id"] == mechanism["criterion_id"]), None)
972
+ component = record.get("quality_components", {}).get(mechanism["criterion_id"], {})
973
+ if (criterion is not None
974
+ and (not criterion["gate"] or mechanism["criterion_id"] in record.get("failed_gates", []))
975
+ and component.get("status") == "valid" and type(component.get("level")) in (int, float)
976
+ and (0 <= component["level"] < 1 if continuous_item(rubrics[record["case_id"]], criterion)
977
+ else component["level"] in (0, 0.5))):
978
+ supported = True
979
+ break
980
+ if not supported:
981
+ raise ProtocolError("mechanism lacks a measured current-parent search weakness")
982
+ declared = path_list(proposal["changed_paths"], "proposal.changed_paths")
983
+ allowed = job.spec["target"]["allowed_paths"]
984
+ if any(name not in allowed for name in declared):
985
+ raise ProtocolError("proposal changes paths outside the target surface")
986
+ with tempfile.TemporaryDirectory(prefix="instruction-candidate-") as temporary:
987
+ root = Path(temporary)
988
+ for name, row in parent.items():
989
+ destination = root / name
990
+ destination.parent.mkdir(parents=True, exist_ok=True)
991
+ destination.write_bytes(row["content"])
992
+ destination.chmod(row["mode"])
993
+ applied = subprocess.run(
994
+ [
995
+ "git",
996
+ "-c",
997
+ "core.hooksPath=/dev/null",
998
+ "-c",
999
+ "core.fsmonitor=false",
1000
+ "apply",
1001
+ "--binary",
1002
+ "-",
1003
+ ],
1004
+ cwd=root,
1005
+ input=patch,
1006
+ capture_output=True,
1007
+ )
1008
+ if applied.returncode:
1009
+ raise ProtocolError(
1010
+ "candidate patch cannot be applied safely to its parent"
1011
+ )
1012
+ candidate = {}
1013
+ for path in sorted(root.rglob("*")):
1014
+ if path.is_dir() and not path.is_symlink():
1015
+ continue
1016
+ name = path.relative_to(root).as_posix()
1017
+ candidate[name] = read_file(root, name)
1018
+ changed = sorted(
1019
+ name
1020
+ for name in parent.keys() | candidate.keys()
1021
+ if parent.get(name) != candidate.get(name)
1022
+ )
1023
+ if changed != sorted(declared):
1024
+ raise ProtocolError("proposal changed_paths differs from the actual patch")
1025
+ for rule in job.spec["target"]["protected_rules"]:
1026
+ if rule["verification"] == "exact" and rule[
1027
+ "text"
1028
+ ].encode() not in candidate.get(rule["path"], {}).get("content", b""):
1029
+ raise ProtocolError("candidate removes a protected text block")
1030
+ references = set()
1031
+ for views in job.case_files.values():
1032
+ for row in views["oracle_paths"].values():
1033
+ content = row["content"].strip()
1034
+ if len(content) >= 16:
1035
+ references.add(content)
1036
+ references.update(
1037
+ line[1:].strip()
1038
+ for line in content.splitlines()
1039
+ if line.startswith(b"+")
1040
+ and not line.startswith(b"+++")
1041
+ and len(line.strip()) >= 33
1042
+ )
1043
+ for name in changed:
1044
+ raw = candidate.get(name, {}).get("content", b"")
1045
+ original = parent.get(name, {}).get("content", b"")
1046
+ if any(
1047
+ reference in raw and reference not in original for reference in references
1048
+ ):
1049
+ raise ProtocolError("candidate contains known private reference content")
1050
+ for case in job.spec["cases"]:
1051
+ if len(case["case_id"]) >= 8 and case["case_id"].encode() in raw:
1052
+ raise ProtocolError("candidate contains restricted task identifiers")
1053
+ if Path(name).name == "SKILL.md" and name in parent:
1054
+ if skill_name(raw) != skill_name(parent[name]["content"]):
1055
+ raise ProtocolError("candidate changes the skill invocation name")
1056
+ return candidate
1057
+
1058
+
1059
+ @dataclass
1060
+ class PreparedJob:
1061
+ spec: dict
1062
+ bundles: dict
1063
+ case_files: dict
1064
+ method_files: dict
1065
+ deleted_paths: list
1066
+ differences: dict
1067
+ minimum_calls: int
1068
+ confirmation_reserve: int
1069
+ evaluation_files: dict = field(default_factory=dict)
1070
+ worker_files: dict = field(default_factory=dict)
1071
+ call_plan: dict = field(default_factory=dict)
1072
+
1073
+ @property
1074
+ def bundle_hashes(self):
1075
+ return {name: bundle_hash(files) for name, files in self.bundles.items()}
1076
+
1077
+ def inputs(self):
1078
+ result = {
1079
+ "bundles": {name: manifest(files) for name, files in self.bundles.items()},
1080
+ "cases": {
1081
+ name: {view: manifest(files) for view, files in views.items()}
1082
+ for name, views in self.case_files.items()
1083
+ },
1084
+ "method": manifest(self.method_files),
1085
+ "deleted_paths": self.deleted_paths,
1086
+ }
1087
+ if self.spec["schema_version"] == 2:
1088
+ result.update(evaluation=manifest(self.evaluation_files), workers=manifest(self.worker_files))
1089
+ return result
1090
+
1091
+ @property
1092
+ def protocol_hash(self):
1093
+ return sha256(canonical({"spec": self.spec, "inputs": self.inputs()}))
1094
+
1095
+ def summary(self):
1096
+ return {
1097
+ "schema_version": self.spec["schema_version"],
1098
+ "protocol_id": self.spec["protocol_id"],
1099
+ "protocol_hash": self.protocol_hash,
1100
+ "mode": self.spec["mode"],
1101
+ "configuration": deepcopy(self.spec),
1102
+ "export_files": sorted(self.bundles[self.spec["baseline_condition"]]),
1103
+ "condition_differences": self.differences,
1104
+ "bundle_hashes": self.bundle_hashes,
1105
+ "minimum_calls": self.minimum_calls,
1106
+ "confirmation_reserve": self.confirmation_reserve,
1107
+ "call_upper_bound": min(
1108
+ self.spec["budget"]["max_trials"],
1109
+ self.minimum_calls * (1 + self.spec["budget"]["max_retries"]),
1110
+ )
1111
+ if self.spec["mode"] == "smoke"
1112
+ else self.spec["budget"]["max_trials"],
1113
+ "effect_eligible": self.spec["mode"] not in {"smoke", "calibrate"},
1114
+ **({"call_plan": self.call_plan} if self.spec["schema_version"] == 2 else {}),
1115
+ }
1116
+
1117
+ def optimizer_view(self):
1118
+ cases = []
1119
+ for case in self.spec["cases"]:
1120
+ if case["split"] != "search":
1121
+ continue
1122
+ cases.append(
1123
+ {
1124
+ "case_id": case["case_id"],
1125
+ "group_id": case["group_id"],
1126
+ "repo_id": case["repo_id"],
1127
+ "observable_requirements": case["observable_requirements"],
1128
+ "files": {
1129
+ name: row["content"].decode("utf-8")
1130
+ for name, row in self.case_files[case["case_id"]][
1131
+ "public_paths"
1132
+ ].items()
1133
+ },
1134
+ }
1135
+ )
1136
+ return {"schema_version": 1, "cases": cases}
1137
+
1138
+
1139
+ def evaluation_files(spec, base):
1140
+ from quality import CONTINUOUS_SCORING, validate_calibration, validate_rubric, validate_auxiliary_rubric
1141
+
1142
+ evaluation = fields(spec.get("evaluation"), "evaluation", {
1143
+ "root", "paths", "rubrics", "calibration",
1144
+ }, {"auxiliary", "scoring"})
1145
+ if "scoring" in evaluation:
1146
+ choice(evaluation["scoring"], {CONTINUOUS_SCORING}, "evaluation.scoring")
1147
+ root = directory(evaluation["root"], base)
1148
+ authority_root = directory(spec["authority"].get("evaluation_root"), base)
1149
+ if root != authority_root:
1150
+ raise ProtocolError("evaluation root is outside explicit authority")
1151
+ evaluation["root"] = spec["authority"]["evaluation_root"] = str(root)
1152
+ files = {name: read_file(root, name) for name in path_list(evaluation["paths"], "evaluation.paths")}
1153
+
1154
+ def document(name):
1155
+ relative_path(name)
1156
+ if name not in files:
1157
+ raise ProtocolError("evaluation file is outside its allowlist")
1158
+ return parse_json(files[name]["content"])
1159
+
1160
+ ids = {case["case_id"] for case in spec["cases"]}
1161
+ if not isinstance(evaluation["rubrics"], dict) or evaluation["rubrics"].keys() != ids:
1162
+ raise ProtocolError("evaluation.rubrics must name every case exactly once")
1163
+ rubrics = {case_id: validate_rubric(document(name), case_id=case_id)
1164
+ for case_id, name in evaluation["rubrics"].items()}
1165
+ scoring = {r.get("scoring") for r in rubrics.values()}
1166
+ if len(scoring) != 1 or ("scoring" in evaluation and evaluation["scoring"] not in scoring):
1167
+ raise ProtocolError("quality rubrics use different scoring contracts")
1168
+ status_formats = {r.get("derive_assessment_status", False) for r in rubrics.values()
1169
+ if any(c["checker_kind"] == "judge" for c in r["criteria"])}
1170
+ if len(status_formats) > 1:
1171
+ raise ProtocolError("quality rubrics use different assessment status formats")
1172
+ if next(iter(scoring)) is not None:
1173
+ evaluation["scoring"] = next(iter(scoring))
1174
+ for case in spec["cases"]:
1175
+ public = {name: read_file(Path(case["task_path"]), name)["content"].decode("utf-8")
1176
+ for name in case["public_paths"]}
1177
+ if evaluation.get("scoring") == CONTINUOUS_SCORING:
1178
+ if "task-contract.md" in public:
1179
+ raise ProtocolError("task-contract.md is reserved for declared observable requirements")
1180
+ public["task-contract.md"] = task_contract(case).decode("utf-8")
1181
+ for criterion in rubrics[case["case_id"]]["criteria"]:
1182
+ name, separator, quote = criterion["public_requirement_ref"].partition(": ")
1183
+ if not separator or name not in public or not quote or quote not in public[name]:
1184
+ raise ProtocolError("quality criterion must reference an actual public requirement")
1185
+ calibration = validate_calibration(document(evaluation["calibration"]), files, rubrics)
1186
+ if any(next(c for c in spec["cases"] if c["case_id"] == a["case_id"])["split"] != "search"
1187
+ for a in calibration["artifacts"]):
1188
+ raise ProtocolError("calibration cannot consume heldout tasks")
1189
+ workers = {name: read_file(Path(__file__).parent, name) for name in ("quality.py", "remote.py")}
1190
+ if evaluation.get("scoring") == CONTINUOUS_SCORING:
1191
+ workers.update({name: read_file(Path(__file__).parent, name) for name in ("protocol.py", "evolution.py", "compare.py")})
1192
+ auxiliary = evaluation.get("auxiliary")
1193
+ if auxiliary is not None:
1194
+ fields(auxiliary, "evaluation.auxiliary", {
1195
+ "provider", "model", "criterion_ids", "rubric_path", "calibration_path", "authentication",
1196
+ }, {"long_context"})
1197
+ if "long_context" in auxiliary:
1198
+ boolean(auxiliary["long_context"], "auxiliary.long_context")
1199
+ choice(auxiliary["provider"], {"typesafe"}, "auxiliary provider")
1200
+ choice(auxiliary["model"], {"jev-1.14.0"}, "auxiliary model")
1201
+ authentication = fields(auxiliary["authentication"], "auxiliary authentication", {"source", "name"})
1202
+ if authentication != {"source": "controller_env", "name": "TYPESAFE_API_KEY"}:
1203
+ raise ProtocolError("auxiliary credential must come from TYPESAFE_API_KEY in the controller environment")
1204
+ if spec["authority"].get("allow_typesafe_auxiliary") is not True:
1205
+ raise ProtocolError("TypeSafe evidence export is not explicitly authorized")
1206
+ if "max_auxiliary_calls" not in spec["budget"]:
1207
+ raise ProtocolError("auxiliary scoring requires a finite sub-budget")
1208
+ if spec["budget"]["max_auxiliary_calls"] > spec["budget"]["max_trials"]:
1209
+ raise ProtocolError("auxiliary sub-budget exceeds the total call budget")
1210
+ validate_auxiliary_rubric(document(auxiliary["rubric_path"]), rubrics, auxiliary["criterion_ids"])
1211
+ auxiliary_calibration = validate_calibration(document(auxiliary["calibration_path"]), files, rubrics,
1212
+ auxiliary=True, criterion_ids=auxiliary["criterion_ids"])
1213
+ artifacts = {a["artifact_id"]: a for a in calibration["artifacts"]}
1214
+ for artifact in auxiliary_calibration["artifacts"]:
1215
+ if next(c for c in spec["cases"] if c["case_id"] == artifact["case_id"])["split"] != "search":
1216
+ raise ProtocolError("auxiliary calibration cannot consume heldout tasks")
1217
+ prior = artifacts.get(artifact["artifact_id"])
1218
+ if prior is not None and prior != artifact:
1219
+ raise ProtocolError("calibration artifact id aliases different frozen inputs")
1220
+ if any(artifact["expected_levels"][name] not in (0, 0.5, 1)
1221
+ for name in auxiliary["criterion_ids"] if name in artifact["expected_levels"]):
1222
+ raise ProtocolError("auxiliary calibration requires its own three semantic reference levels")
1223
+ workers["typesafe_worker.py"] = read_file(Path(__file__).parent, "typesafe_worker.py")
1224
+ elif spec["budget"].get("max_auxiliary_calls", 0):
1225
+ raise ProtocolError("auxiliary budget requires auxiliary configuration")
1226
+ return files, workers, rubrics, calibration
1227
+
1228
+
1229
+ def quality_case_calls(criteria):
1230
+ return 2 + sum(c["checker_kind"] == "regression_replay" for c in criteria) + 2 * any(
1231
+ c["checker_kind"] == "judge" for c in criteria)
1232
+
1233
+
1234
+ def quality_call_plan(spec, files, rubrics, calibration, bundles):
1235
+ def per_case(case):
1236
+ criteria = rubrics[case["case_id"]]["criteria"]
1237
+ return quality_case_calls(criteria)
1238
+
1239
+ repeats = spec["measurement"]["repeats"]
1240
+ search = sum(per_case(c) for c in spec["cases"] if c["split"] == "search") * repeats
1241
+ validation = sum(per_case(c) for c in spec["cases"] if c["split"] == "validation") * repeats
1242
+ confirmation = 2 * sum(per_case(c) for c in spec["cases"] if c["split"] == "confirmation") * repeats
1243
+ calibration_calls = 1 + 2 * len(spec["cases"])
1244
+ for artifact in calibration["artifacts"]:
1245
+ calibration_calls += per_case({"case_id": artifact["case_id"]}) - 1
1246
+ auxiliary = spec["evaluation"].get("auxiliary")
1247
+ if auxiliary is not None:
1248
+ primary_ids = {a["artifact_id"] for a in calibration["artifacts"]}
1249
+ auxiliary_calibration = parse_json(files[auxiliary["calibration_path"]]["content"])
1250
+ for artifact in auxiliary_calibration["artifacts"]:
1251
+ if artifact["artifact_id"] not in primary_ids:
1252
+ criteria = rubrics[artifact["case_id"]]["criteria"]
1253
+ calibration_calls += 1 + sum(c["checker_kind"] == "regression_replay" for c in criteria)
1254
+ plan = {"runtime_and_quality_calibration": calibration_calls, "baseline_aa": 2 * search,
1255
+ "initial_conditions": 0 if spec["mode"] == "calibrate" else len(bundles) * (search + validation),
1256
+ "optimizer_and_policy": 2 * spec["budget"]["max_candidates"] if spec["mode"] == "search" else 1 if spec["mode"] == "compare" else 0,
1257
+ "candidate_pairs": 2 * (search + validation) * spec["budget"]["max_candidates"] if spec["mode"] == "search" else 0,
1258
+ "confirmation_reserve": confirmation,
1259
+ "auxiliary_maximum": spec["budget"].get("max_auxiliary_calls", 0)}
1260
+ planned = sum(plan.values())
1261
+ optional_rounds = max(0, spec["budget"]["max_candidates"] - 1) if spec["mode"] == "search" else 0
1262
+ plan["minimum_calls"] = planned - optional_rounds * (2 + 2 * (search + validation))
1263
+ plan["finite_retry_allowance"] = (planned - plan["auxiliary_maximum"]) * spec["budget"]["max_retries"]
1264
+ plan["maximum_planned_calls"] = planned + plan["finite_retry_allowance"]
1265
+ return plan
1266
+
1267
+
1268
+ def prepare(path):
1269
+ path = Path(path).resolve(strict=True)
1270
+ spec = load_json(path)
1271
+ fields(
1272
+ spec,
1273
+ "JobSpec",
1274
+ {
1275
+ "schema_version",
1276
+ "protocol_id",
1277
+ "question",
1278
+ "mode",
1279
+ "target",
1280
+ "source",
1281
+ "runtime",
1282
+ "authority",
1283
+ "budget",
1284
+ "measurement",
1285
+ "guardrails",
1286
+ "cases",
1287
+ "conditions",
1288
+ "baseline_condition",
1289
+ },
1290
+ {"optimizer", "candidate_condition", "attribution", "evaluation"},
1291
+ )
1292
+ if type(spec["schema_version"]) is not int or spec["schema_version"] not in {1, 2}:
1293
+ raise ProtocolError("unsupported schema_version")
1294
+ text(spec["protocol_id"], "protocol_id")
1295
+ text(spec["question"], "question")
1296
+ choice(spec["mode"], {"calibrate", "compare", "search"} if spec["schema_version"] == 2 else {"smoke", "compare", "search"}, "mode")
1297
+ if spec["schema_version"] == 1 and "evaluation" in spec:
1298
+ raise ProtocolError("quality evaluation requires schema_version=2")
1299
+ validate_target(spec, path.parent)
1300
+ validate_runtime(spec)
1301
+ validate_measurement(spec)
1302
+ baseline, deleted = repository_files(spec)
1303
+ cases = task_files(spec, path.parent)
1304
+ evaluation, workers, rubrics, calibration = {}, {}, {}, None
1305
+ if spec["schema_version"] == 2:
1306
+ evaluation, workers, rubrics, calibration = evaluation_files(spec, path.parent)
1307
+ private_files = set()
1308
+ for case in spec["cases"]:
1309
+ root = Path(case["task_path"])
1310
+ for name in case["grader_paths"] + case["oracle_paths"]:
1311
+ info = (root / name).stat()
1312
+ private_files.add((info.st_dev, info.st_ino))
1313
+ for name in baseline:
1314
+ info = (Path(spec["target"]["repo"]) / name).stat()
1315
+ if (info.st_dev, info.st_ino) in private_files:
1316
+ raise ProtocolError(
1317
+ "repository export contains private grading or oracle material"
1318
+ )
1319
+ fixed_roots = spec["source"].get("fixed_skill_roots", [])
1320
+ target_roots = {str(PurePosixPath(path).parent) for path in spec["target"]["surfaces"]["skill"]
1321
+ if PurePosixPath(path).name == "SKILL.md"}
1322
+ skill_names = {skill_name(baseline[path]["content"]) for path in spec["target"]["surfaces"]["skill"]
1323
+ if PurePosixPath(path).name == "SKILL.md" and path in baseline}
1324
+ for root in fixed_roots:
1325
+ descriptor = root + "/SKILL.md"
1326
+ if descriptor not in baseline:
1327
+ raise ProtocolError("fixed skill descriptor must be in the source export")
1328
+ if any(covered(root, [target]) or covered(target, [root]) for target in target_roots) or any(
1329
+ covered(path, [root]) for path in spec["target"]["allowed_paths"]
1330
+ ):
1331
+ raise ProtocolError("fixed skill cannot overlap a candidate surface")
1332
+ name = skill_name(baseline[descriptor]["content"])
1333
+ if name is None or name in skill_names:
1334
+ raise ProtocolError("fixed skill identity is missing or duplicated")
1335
+ skill_names.add(name)
1336
+ bundles, differences = condition_bundles(spec, baseline)
1337
+ method = {}
1338
+ if spec["mode"] == "search":
1339
+ if "optimizer" not in spec:
1340
+ raise ProtocolError("search requires an optimizer")
1341
+ optimizer = fields(
1342
+ spec["optimizer"],
1343
+ "optimizer",
1344
+ {"model", "effort", "method_path", "method_sha256"},
1345
+ )
1346
+ text(optimizer["model"], "optimizer.model")
1347
+ choice(
1348
+ optimizer["effort"],
1349
+ {"minimal", "low", "medium", "high", "xhigh"},
1350
+ "optimizer.effort",
1351
+ )
1352
+ fingerprint(optimizer["method_sha256"], "optimizer.method_sha256")
1353
+ method_path = Path(optimizer["method_path"])
1354
+ if not method_path.is_absolute():
1355
+ method_path = path.parent / method_path
1356
+ method = {
1357
+ "method.md": read_file(
1358
+ method_path.parent.resolve(strict=True), method_path.name
1359
+ )
1360
+ }
1361
+ optimizer["method_path"] = str(method_path.absolute())
1362
+ if method["method.md"]["sha256"] != optimizer["method_sha256"]:
1363
+ raise ProtocolError("optimizer method hash mismatch")
1364
+ if spec["schema_version"] == 2 and (optimizer["model"], optimizer["effort"]) != ("gpt-6.1-sol", "high"):
1365
+ raise ProtocolError("v2 optimizer requires gpt-6.1-sol/high")
1366
+ elif "optimizer" in spec:
1367
+ raise ProtocolError("optimizer is only valid in search mode")
1368
+ if "attribution" in spec:
1369
+ choice(
1370
+ spec["attribution"],
1371
+ {"skill", "agents", "joint", "interaction"},
1372
+ "attribution",
1373
+ )
1374
+ if spec["attribution"] == "interaction":
1375
+ combinations = {(c["skill"], c["agents"]) for c in spec["conditions"]}
1376
+ required = {
1377
+ (s, a)
1378
+ for s in ["baseline", "candidate"]
1379
+ for a in ["baseline", "candidate"]
1380
+ }
1381
+ if not required.issubset(combinations):
1382
+ raise ProtocolError(
1383
+ "interaction attribution requires a frozen crossed design"
1384
+ )
1385
+ elif spec["attribution"] in {"skill", "agents"}:
1386
+ background = "agents" if spec["attribution"] == "skill" else "skill"
1387
+ if len({c[background] for c in spec["conditions"]}) != 1:
1388
+ raise ProtocolError(
1389
+ "single-factor attribution changes the other factor"
1390
+ )
1391
+ repeats = spec["measurement"]["repeats"]
1392
+ search_count = sum(case["split"] == "search" for case in spec["cases"])
1393
+ validation_count = sum(case["split"] == "validation" for case in spec["cases"])
1394
+ confirmation_count = sum(case["split"] == "confirmation" for case in spec["cases"])
1395
+ reserve = 0 if spec["mode"] == "smoke" else 4 * confirmation_count * repeats
1396
+ minimum = 1 + 2 * len(cases)
1397
+ if spec["mode"] != "smoke":
1398
+ minimum += (
1399
+ 4 * search_count * repeats
1400
+ + 2 * len(bundles) * (search_count + validation_count) * repeats
1401
+ + reserve
1402
+ )
1403
+ if spec["mode"] == "search":
1404
+ minimum += 2 + 4 * (search_count + validation_count) * repeats
1405
+ else:
1406
+ minimum += 1
1407
+ call_plan = {}
1408
+ if spec["schema_version"] == 2:
1409
+ call_plan = quality_call_plan(spec, evaluation, rubrics, calibration, bundles)
1410
+ minimum, reserve = call_plan["minimum_calls"], call_plan["confirmation_reserve"]
1411
+ if minimum > spec["budget"]["max_trials"]:
1412
+ raise ProtocolError(
1413
+ f"budget cannot fund calibration, baseline and final confirmation: requires {minimum}"
1414
+ )
1415
+ return PreparedJob(
1416
+ spec, bundles, cases, method, deleted, differences, minimum, reserve,
1417
+ evaluation, workers, call_plan,
1418
+ )
1419
+
1420
+
1421
+ def new_execution(
1422
+ job, role, idempotency_key, command_hash, runner_hash, *, now, run_deadline
1423
+ ):
1424
+ choice(role, ROLES, "role")
1425
+ budget = job.spec["budget"]
1426
+ command_deadline = min(
1427
+ now + budget["per_trial_timeout_sec"],
1428
+ run_deadline - budget["recovery_window_sec"],
1429
+ )
1430
+ if command_deadline <= now:
1431
+ raise ProtocolError(
1432
+ "insufficient time for command and reserved recovery window"
1433
+ )
1434
+ task_id = str(uuid.uuid4())
1435
+ result = {
1436
+ "schema_version": 1,
1437
+ "remote_task_id": task_id,
1438
+ "role": role,
1439
+ "idempotency_key": text(idempotency_key, "idempotency_key"),
1440
+ "input_hash": job.protocol_hash,
1441
+ "command_hash": command_hash,
1442
+ "runner_hash": runner_hash,
1443
+ "runner_version": 1,
1444
+ "ssh_target": job.spec["runtime"]["ssh_target"],
1445
+ "remote_root": job.spec["runtime"]["remote_root"],
1446
+ "sandbox_name": "evolve-" + task_id,
1447
+ "sandbox_id": None,
1448
+ "engine_id": None,
1449
+ "receipt_path": job.spec["runtime"]["remote_root"]
1450
+ + "/executions/"
1451
+ + task_id
1452
+ + "/control/receipt.json",
1453
+ "phase": "prepared",
1454
+ "submission_status": "not_submitted",
1455
+ "process": None,
1456
+ "exit_code": None,
1457
+ "termination_reason": None,
1458
+ "artifact_manifest": [],
1459
+ "export_status": "not_exported",
1460
+ "cleanup_status": "not_cleaned",
1461
+ "cancel_reason": None,
1462
+ "command_deadline": command_deadline,
1463
+ "resource_deadline": run_deadline,
1464
+ }
1465
+ validate_execution(result)
1466
+ return result
1467
+
1468
+
1469
+ def validate_execution(value):
1470
+ fields(
1471
+ value,
1472
+ "RemoteExecution",
1473
+ {
1474
+ "schema_version",
1475
+ "remote_task_id",
1476
+ "role",
1477
+ "idempotency_key",
1478
+ "input_hash",
1479
+ "command_hash",
1480
+ "runner_hash",
1481
+ "runner_version",
1482
+ "ssh_target",
1483
+ "remote_root",
1484
+ "sandbox_name",
1485
+ "sandbox_id",
1486
+ "engine_id",
1487
+ "receipt_path",
1488
+ "phase",
1489
+ "submission_status",
1490
+ "process",
1491
+ "exit_code",
1492
+ "termination_reason",
1493
+ "artifact_manifest",
1494
+ "export_status",
1495
+ "cleanup_status",
1496
+ "cancel_reason",
1497
+ "command_deadline",
1498
+ "resource_deadline",
1499
+ },
1500
+ )
1501
+ if (
1502
+ type(value["schema_version"]) is not int
1503
+ or value["schema_version"] != 1
1504
+ or type(value["runner_version"]) is not int
1505
+ or value["runner_version"] != 1
1506
+ ):
1507
+ raise ProtocolError("unsupported execution or runner schema")
1508
+ try:
1509
+ uuid.UUID(value["remote_task_id"])
1510
+ except (ValueError, TypeError, AttributeError):
1511
+ raise ProtocolError("invalid remote_task_id") from None
1512
+ choice(value["role"], ROLES, "role")
1513
+ choice(value["phase"], PHASES, "phase")
1514
+ for key in ["input_hash", "command_hash", "runner_hash"]:
1515
+ fingerprint(value[key], key)
1516
+ for key in [
1517
+ "ssh_target",
1518
+ "remote_root",
1519
+ "idempotency_key",
1520
+ "sandbox_name",
1521
+ "receipt_path",
1522
+ ]:
1523
+ text(value[key], key)
1524
+ expected_receipt = (
1525
+ remote_path(value["remote_root"])
1526
+ + "/executions/"
1527
+ + value["remote_task_id"]
1528
+ + "/control/receipt.json"
1529
+ )
1530
+ if (
1531
+ value["sandbox_name"] != "evolve-" + value["remote_task_id"]
1532
+ or value["receipt_path"] != expected_receipt
1533
+ ):
1534
+ raise ProtocolError("remote execution resource or receipt identity has drifted")
1535
+ if value["sandbox_id"] is not None:
1536
+ text(value["sandbox_id"], "sandbox_id")
1537
+ if value["engine_id"] is not None:
1538
+ text(value["engine_id"], "engine_id")
1539
+ choice(
1540
+ value["submission_status"],
1541
+ {
1542
+ "not_submitted",
1543
+ "intent_saved",
1544
+ "resource_created",
1545
+ "launch_intent_saved",
1546
+ "runner_submitted",
1547
+ "unresolved",
1548
+ },
1549
+ "submission_status",
1550
+ )
1551
+ choice(
1552
+ value["export_status"],
1553
+ {"not_exported", "partial", "exported", "unresolved"},
1554
+ "export_status",
1555
+ )
1556
+ choice(
1557
+ value["cleanup_status"],
1558
+ {"not_cleaned", "pending", "terminated", "unresolved"},
1559
+ "cleanup_status",
1560
+ )
1561
+ for key in ["command_deadline", "resource_deadline"]:
1562
+ number(value[key], key, minimum=1)
1563
+ if value["command_deadline"] >= value["resource_deadline"]:
1564
+ raise ProtocolError("command deadline must leave a recovery window")
1565
+ if value["exit_code"] is not None and type(value["exit_code"]) is not int:
1566
+ raise ProtocolError("exit_code must be integer or null")
1567
+ for key in ["termination_reason", "cancel_reason"]:
1568
+ if value[key] is not None:
1569
+ text(value[key], key)
1570
+ if value["phase"] == "running" and value["process"] is None:
1571
+ raise ProtocolError("running receipt must identify the original process")
1572
+ if value["process"] is not None:
1573
+ fields(value["process"], "process", {"pid", "pgid", "start_identity"})
1574
+ for key in ["pid", "pgid"]:
1575
+ number(value["process"][key], key, minimum=1, integer=True)
1576
+ text(value["process"]["start_identity"], "process.start_identity")
1577
+ paths = set()
1578
+ for artifact in rows(value["artifact_manifest"], "artifact_manifest", empty=True):
1579
+ fields(artifact, "artifact", {"path", "size", "sha256"})
1580
+ name = relative_path(artifact["path"])
1581
+ if name in paths:
1582
+ raise ProtocolError("duplicate artifact path")
1583
+ paths.add(name)
1584
+ fingerprint(artifact["sha256"], "artifact.sha256")
1585
+ number(artifact["size"], "artifact.size", integer=True)
1586
+ return value