@enterpriseai/cli 3.19.0 → 3.19.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (364) hide show
  1. package/package.json +3 -3
  2. package/resources/deploy/eai-app-template/producer-pin.json +5 -5
  3. package/resources/deploy/eai-app-template/tests/source-unknown-deployment-evidence.test.mjs +2141 -1
  4. package/resources/gofer/.gofer-version +4 -357
  5. package/resources/gofer/agents-skills/eai/SKILL.md +365 -0
  6. package/resources/gofer/agents-skills/eai-update/SKILL.md +56 -0
  7. package/resources/gofer/agents-skills/gofer-documentation/SKILL.md +93 -0
  8. package/resources/gofer/bash-scripts/create-new-feature.sh +3 -1
  9. package/resources/gofer/bash-scripts/sync-implementation-status.sh +4 -3
  10. package/resources/gofer/bash-scripts/update-agent-context.sh +7 -8
  11. package/resources/gofer/bash-scripts/validate-artifact.sh +10 -6
  12. package/resources/gofer/bash-scripts/verify-object-type-routing-workspace.sh +184 -0
  13. package/resources/gofer/claude-commands/eai-update.md +46 -0
  14. package/resources/gofer/claude-commands/eai.md +355 -0
  15. package/resources/gofer/claude-skills/eai/SKILL.md +365 -0
  16. package/resources/gofer/claude-skills/eai-update/SKILL.md +56 -0
  17. package/resources/gofer/claude-skills/gofer-documentation/SKILL.md +93 -0
  18. package/resources/gofer/commands/0_gofer_start.md +440 -99
  19. package/resources/gofer/commands/0a_problem_validation.md +187 -27
  20. package/resources/gofer/commands/10_gofer_cloud.md +183 -23
  21. package/resources/gofer/commands/1_gofer_research.md +239 -30
  22. package/resources/gofer/commands/2_gofer_specify.md +239 -35
  23. package/resources/gofer/commands/3_gofer_plan.md +259 -43
  24. package/resources/gofer/commands/4_gofer_tasks.md +401 -81
  25. package/resources/gofer/commands/5_gofer_implement.md +375 -84
  26. package/resources/gofer/commands/6_gofer_validate.md +284 -53
  27. package/resources/gofer/commands/7_gofer_save.md +187 -26
  28. package/resources/gofer/commands/7a_stakeholder_comms.md +183 -23
  29. package/resources/gofer/commands/8_gofer_branding.md +183 -23
  30. package/resources/gofer/commands/9_gofer_tests.md +212 -23
  31. package/resources/gofer/commands/gofer_bootstrap_workspace.md +121 -8
  32. package/resources/gofer/commands/gofer_check_workspace.md +123 -8
  33. package/resources/gofer/commands/gofer_constitution.md +183 -23
  34. package/resources/gofer/commands/gofer_diagnose.md +183 -23
  35. package/resources/gofer/commands/gofer_eai_first_run.md +254 -25
  36. package/resources/gofer/commands/gofer_hydrate.md +183 -23
  37. package/resources/gofer/commands/gofer_personality.md +117 -6
  38. package/resources/gofer/commands/gofer_plan.md +117 -6
  39. package/resources/gofer/commands/gofer_side.md +117 -6
  40. package/resources/gofer/commands/gofer_spec_summary.md +183 -23
  41. package/resources/gofer/commands/gofer_tdd.md +183 -23
  42. package/resources/gofer/commands/gofer_vocabulary.md +185 -25
  43. package/resources/gofer/commands/gofer_zoom_out.md +183 -23
  44. package/resources/gofer/config/typesafe-learning-review.json +16 -0
  45. package/resources/gofer/config/typesafe-semantic-review.json +9 -0
  46. package/resources/gofer/copilot-instructions/gofer-cost.instructions.md +15 -6
  47. package/resources/gofer/copilot-instructions/typescript.instructions.md +1 -1
  48. package/resources/gofer/copilot-prompts/eai-update.prompt.md +58 -0
  49. package/resources/gofer/copilot-prompts/eai.prompt.md +367 -0
  50. package/resources/gofer/gemini/commands/gofer/eai-update.md +22 -0
  51. package/resources/gofer/gemini/commands/gofer/eai-update.toml +2 -0
  52. package/resources/gofer/gemini/commands/gofer/eai.md +357 -0
  53. package/resources/gofer/gemini/commands/gofer/eai.toml +2 -0
  54. package/resources/gofer/gemini/commands/gofer/manifest.json +3 -27
  55. package/resources/gofer/gemini/extension.json +4 -4
  56. package/resources/gofer/github-agents/eai.agent.md +83 -0
  57. package/resources/gofer/github-agents/gofer-business.agent.md +73 -4
  58. package/resources/gofer/github-agents/gofer-implement.agent.md +71 -2
  59. package/resources/gofer/github-agents/gofer-plan.agent.md +72 -2
  60. package/resources/gofer/github-agents/gofer-research.agent.md +72 -2
  61. package/resources/gofer/github-agents/gofer-validate.agent.md +72 -2
  62. package/resources/gofer/github-skills/eai/SKILL.md +365 -0
  63. package/resources/gofer/github-skills/eai-update/SKILL.md +56 -0
  64. package/resources/gofer/github-skills/gofer-documentation/SKILL.md +93 -0
  65. package/resources/gofer/grok-skills/eai/SKILL.md +267 -14
  66. package/resources/gofer/grok-skills/eai-update/SKILL.md +56 -0
  67. package/resources/gofer/hook-scripts/user-prompt-submit.mjs +58 -13
  68. package/resources/gofer/instruction-templates/base/agents-base.md +8 -4
  69. package/resources/gofer/instruction-templates/gofer/gofer-claude.md +7 -5
  70. package/resources/gofer/instruction-templates/gofer/gofer-copilot.md +10 -8
  71. package/resources/gofer/memory/constitution.md +9 -7
  72. package/resources/gofer/memory/gofer-model-policy.yaml +23 -1
  73. package/resources/gofer/memory/lessons.md +0 -31
  74. package/resources/gofer/node-scripts/canonical-descriptions.mjs +1 -1
  75. package/resources/gofer/node-scripts/check-version-alignment.mjs +4 -7
  76. package/resources/gofer/node-scripts/delivery-lineage-corpus.mjs +156 -0
  77. package/resources/gofer/node-scripts/generate-commands.mjs +1073 -265
  78. package/resources/gofer/node-scripts/gofer-acceptance-check.mjs +143 -0
  79. package/resources/gofer/node-scripts/gofer-agent-catalog.mjs +271 -0
  80. package/resources/gofer/node-scripts/gofer-benchmark-executor.mjs +123 -0
  81. package/resources/gofer/node-scripts/gofer-benchmark-sign.mjs +62 -0
  82. package/resources/gofer/node-scripts/gofer-benchmark-signer.mjs +89 -0
  83. package/resources/gofer/node-scripts/gofer-benchmark.mjs +76 -0
  84. package/resources/gofer/node-scripts/gofer-blocker-control.mjs +274 -0
  85. package/resources/gofer/node-scripts/gofer-claude-adapter.mjs +154 -0
  86. package/resources/gofer/node-scripts/gofer-closed-loop-audit.mjs +19 -2
  87. package/resources/gofer/node-scripts/gofer-delivery-check.mjs +121 -0
  88. package/resources/gofer/node-scripts/gofer-encrypted-key.mjs +58 -0
  89. package/resources/gofer/node-scripts/gofer-execution-metrics.mjs +477 -0
  90. package/resources/gofer/node-scripts/gofer-execution-recovery.mjs +334 -0
  91. package/resources/gofer/node-scripts/gofer-grok-adapter.mjs +184 -0
  92. package/resources/gofer/node-scripts/gofer-heldout-corpus.mjs +73 -0
  93. package/resources/gofer/node-scripts/gofer-heldout-snapshot.mjs +286 -0
  94. package/resources/gofer/node-scripts/gofer-heldout-verifier.mjs +211 -0
  95. package/resources/gofer/node-scripts/gofer-host-capability.mjs +335 -0
  96. package/resources/gofer/node-scripts/gofer-independent-reviewer.mjs +130 -0
  97. package/resources/gofer/node-scripts/gofer-live-routing.mjs +109 -0
  98. package/resources/gofer/node-scripts/gofer-local-capability-issuer.mjs +71 -0
  99. package/resources/gofer/node-scripts/gofer-local-isolation.mjs +175 -0
  100. package/resources/gofer/node-scripts/gofer-local-settings-cleanup.mjs +388 -0
  101. package/resources/gofer/node-scripts/gofer-loop-audit.mjs +54 -3
  102. package/resources/gofer/node-scripts/gofer-native-adapter.mjs +567 -0
  103. package/resources/gofer/node-scripts/gofer-native-benchmark-dispatch.mjs +145 -0
  104. package/resources/gofer/node-scripts/gofer-native-runtime.mjs +169 -0
  105. package/resources/gofer/node-scripts/gofer-pre-edit-check.mjs +204 -0
  106. package/resources/gofer/node-scripts/gofer-priority-check.mjs +214 -0
  107. package/resources/gofer/node-scripts/gofer-response-check.mjs +56 -0
  108. package/resources/gofer/node-scripts/gofer-reviewed-learning.mjs +1232 -0
  109. package/resources/gofer/node-scripts/gofer-run-verified-task.mjs +330 -0
  110. package/resources/gofer/node-scripts/gofer-runtime-ledger.mjs +289 -0
  111. package/resources/gofer/node-scripts/gofer-semantic-drift.mjs +584 -0
  112. package/resources/gofer/node-scripts/gofer-surface-update.mjs +1178 -0
  113. package/resources/gofer/node-scripts/gofer-trust-bootstrap.mjs +77 -0
  114. package/resources/gofer/node-scripts/gofer-trusted-benchmark.mjs +102 -0
  115. package/resources/gofer/node-scripts/gofer-trusted-evaluator.mjs +274 -0
  116. package/resources/gofer/node-scripts/gofer-tty-prompt.mjs +34 -0
  117. package/resources/gofer/node-scripts/gofer-typesafe-credentials.mjs +435 -0
  118. package/resources/gofer/node-scripts/gofer-ui-preview.mjs +1212 -0
  119. package/resources/gofer/node-scripts/gofer-verified-execution.mjs +484 -0
  120. package/resources/gofer/node-scripts/gofer-verifier-key-ceremony.mjs +101 -0
  121. package/resources/gofer/node-scripts/gofer-worktree-layout.mjs +32 -0
  122. package/resources/gofer/node-scripts/object-type-routing-phase-bundle.mjs +360 -0
  123. package/resources/gofer/node-scripts/package-agent-plugin.mjs +574 -82
  124. package/resources/gofer/node-scripts/parse-stage-command.mjs +1 -1
  125. package/resources/gofer/node-scripts/render-delivery-lineage.mjs +178 -0
  126. package/resources/gofer/node-scripts/sync-extension-resources.mjs +78 -2
  127. package/resources/gofer/node-scripts/validate-object-type-identifiers.mjs +767 -0
  128. package/resources/gofer/node-scripts/validate-object-type-routing-workspace.mjs +1325 -0
  129. package/resources/gofer/node-scripts/validate-v4-resource-contract.d.mts +44 -0
  130. package/resources/gofer/node-scripts/validate-v4-resource-contract.mjs +957 -0
  131. package/resources/gofer/node-scripts/workspace-bootstrap-lib.mjs +685 -116
  132. package/resources/gofer/references/agent-catalog.json +126 -0
  133. package/resources/gofer/references/blocker-mediation.md +156 -0
  134. package/resources/gofer/references/business-updates-and-goal-checks.md +109 -0
  135. package/resources/gofer/references/delivery-lineage.md +48 -0
  136. package/resources/gofer/references/mvp-capability-validation.md +102 -0
  137. package/resources/gofer/references/platform/README.md +1 -1
  138. package/resources/gofer/references/platform/eai-app-template.md +15 -13
  139. package/resources/gofer/references/platform/eai-auth-access.md +104 -0
  140. package/resources/gofer/references/platform/eai-config-driven-ui.md +5 -5
  141. package/resources/gofer/references/platform/eai-error-catalog.yaml +77 -19
  142. package/resources/gofer/references/platform/eai-repo-contract.md +61 -23
  143. package/resources/gofer/references/platform/eai-service-patterns.md +102 -105
  144. package/resources/gofer/references/platform/eai.md +44 -8
  145. package/resources/gofer/references/platform/vertical-template.md +10 -9
  146. package/resources/gofer/references/priority-outcome-protection.md +152 -0
  147. package/resources/gofer/references/verified-agent-execution.md +179 -0
  148. package/resources/gofer/schemas/gofer-learning-trace-v1.json +70 -0
  149. package/resources/gofer/specify-commands/0_gofer_start.md +440 -99
  150. package/resources/gofer/specify-commands/0a_problem_validation.md +187 -27
  151. package/resources/gofer/specify-commands/10_gofer_cloud.md +183 -23
  152. package/resources/gofer/specify-commands/1_gofer_research.md +239 -30
  153. package/resources/gofer/specify-commands/2_gofer_specify.md +239 -35
  154. package/resources/gofer/specify-commands/3_gofer_plan.md +259 -43
  155. package/resources/gofer/specify-commands/4_gofer_tasks.md +401 -81
  156. package/resources/gofer/specify-commands/5_gofer_implement.md +375 -84
  157. package/resources/gofer/specify-commands/6_gofer_validate.md +284 -53
  158. package/resources/gofer/specify-commands/7_gofer_save.md +187 -26
  159. package/resources/gofer/specify-commands/7a_stakeholder_comms.md +183 -23
  160. package/resources/gofer/specify-commands/8_gofer_branding.md +183 -23
  161. package/resources/gofer/specify-commands/9_gofer_tests.md +212 -23
  162. package/resources/gofer/specify-commands/gofer_bootstrap_workspace.md +121 -8
  163. package/resources/gofer/specify-commands/gofer_check_workspace.md +123 -8
  164. package/resources/gofer/specify-commands/gofer_constitution.md +183 -23
  165. package/resources/gofer/specify-commands/gofer_diagnose.md +183 -23
  166. package/resources/gofer/specify-commands/gofer_eai_first_run.md +254 -25
  167. package/resources/gofer/specify-commands/gofer_hydrate.md +183 -23
  168. package/resources/gofer/specify-commands/gofer_personality.md +117 -6
  169. package/resources/gofer/specify-commands/gofer_plan.md +117 -6
  170. package/resources/gofer/specify-commands/gofer_side.md +117 -6
  171. package/resources/gofer/specify-commands/gofer_spec_summary.md +183 -23
  172. package/resources/gofer/specify-commands/gofer_tdd.md +183 -23
  173. package/resources/gofer/specify-commands/gofer_vocabulary.md +185 -25
  174. package/resources/gofer/specify-commands/gofer_zoom_out.md +183 -23
  175. package/resources/gofer/specify-config/object-type-routing.json +24 -0
  176. package/resources/gofer/specify-config/typesafe-learning-review.json +16 -0
  177. package/resources/gofer/specify-config/typesafe-semantic-review.json +9 -0
  178. package/resources/gofer/system-skills/eai/SKILL.md +365 -0
  179. package/resources/gofer/system-skills/eai-update/SKILL.md +56 -0
  180. package/resources/gofer/system-skills/gofer-documentation/SKILL.md +93 -0
  181. package/resources/gofer/templates/build-map-template.md +64 -0
  182. package/resources/gofer/templates/business-scenarios-template.json +14 -0
  183. package/resources/gofer/templates/ciso-security-summary-template.md +3 -3
  184. package/resources/gofer/templates/context-bundle-template.md +4 -3
  185. package/resources/gofer/templates/contract-pack-template.md +8 -8
  186. package/resources/gofer/templates/cto-architecture-summary-template.md +3 -3
  187. package/resources/gofer/templates/delivery-lineage-template.json +8 -0
  188. package/resources/gofer/templates/eai-preflight-template.md +109 -68
  189. package/resources/gofer/templates/goal-ledger-template.json +1 -1
  190. package/resources/gofer/templates/gofer-model-policy.yaml +28 -6
  191. package/resources/gofer/templates/loop-contract-template.json +3 -1
  192. package/resources/gofer/templates/plan-template.md +8 -7
  193. package/resources/gofer/templates/priority-plan-template.json +29 -0
  194. package/resources/gofer/templates/proposal-review-template.md +6 -3
  195. package/resources/gofer/templates/release-capability-ledger-template.md +24 -0
  196. package/resources/gofer/templates/research-template.md +7 -6
  197. package/resources/gofer/templates/spec-summary-template.md +1 -1
  198. package/resources/gofer/templates/spec-template.md +45 -6
  199. package/resources/gofer/templates/tasks-template.md +12 -3
  200. package/resources/gofer/templates/ui-preview-brief-template.md +55 -5
  201. package/resources/gofer/templates/ui-review-log-template.md +21 -3
  202. package/resources/gofer/templates/ui-show-and-tell-template.md +46 -0
  203. package/resources/gofer/templates/visuals/capability-heatmap-template.md +2 -2
  204. package/resources/gofer/templates/working-backwards-prfaq-template.md +9 -8
  205. package/resources/linked-sources.json +4 -4
  206. package/resources/gofer/agents-skills/0_gofer_start/SKILL.md +0 -1287
  207. package/resources/gofer/agents-skills/0a_problem_validation/SKILL.md +0 -429
  208. package/resources/gofer/agents-skills/10_gofer_cloud/SKILL.md +0 -635
  209. package/resources/gofer/agents-skills/1_gofer_research/SKILL.md +0 -1159
  210. package/resources/gofer/agents-skills/2_gofer_specify/SKILL.md +0 -860
  211. package/resources/gofer/agents-skills/3_gofer_plan/SKILL.md +0 -899
  212. package/resources/gofer/agents-skills/4_gofer_tasks/SKILL.md +0 -760
  213. package/resources/gofer/agents-skills/5_gofer_implement/SKILL.md +0 -944
  214. package/resources/gofer/agents-skills/6_gofer_validate/SKILL.md +0 -2302
  215. package/resources/gofer/agents-skills/7_gofer_save/SKILL.md +0 -423
  216. package/resources/gofer/agents-skills/7a_stakeholder_comms/SKILL.md +0 -508
  217. package/resources/gofer/agents-skills/8_gofer_branding/SKILL.md +0 -315
  218. package/resources/gofer/agents-skills/9_gofer_tests/SKILL.md +0 -558
  219. package/resources/gofer/agents-skills/gofer_bootstrap_workspace/SKILL.md +0 -148
  220. package/resources/gofer/agents-skills/gofer_check_workspace/SKILL.md +0 -119
  221. package/resources/gofer/agents-skills/gofer_constitution/SKILL.md +0 -612
  222. package/resources/gofer/agents-skills/gofer_diagnose/SKILL.md +0 -114
  223. package/resources/gofer/agents-skills/gofer_eai_first_run/SKILL.md +0 -397
  224. package/resources/gofer/agents-skills/gofer_hydrate/SKILL.md +0 -561
  225. package/resources/gofer/agents-skills/gofer_personality/SKILL.md +0 -44
  226. package/resources/gofer/agents-skills/gofer_plan/SKILL.md +0 -40
  227. package/resources/gofer/agents-skills/gofer_side/SKILL.md +0 -45
  228. package/resources/gofer/agents-skills/gofer_spec_summary/SKILL.md +0 -112
  229. package/resources/gofer/agents-skills/gofer_tdd/SKILL.md +0 -112
  230. package/resources/gofer/agents-skills/gofer_vocabulary/SKILL.md +0 -112
  231. package/resources/gofer/agents-skills/gofer_zoom_out/SKILL.md +0 -112
  232. package/resources/gofer/claude-commands/0_gofer_start.md +0 -1282
  233. package/resources/gofer/claude-commands/0a_problem_validation.md +0 -424
  234. package/resources/gofer/claude-commands/10_gofer_cloud.md +0 -630
  235. package/resources/gofer/claude-commands/1_gofer_research.md +0 -1154
  236. package/resources/gofer/claude-commands/2_gofer_specify.md +0 -855
  237. package/resources/gofer/claude-commands/3_gofer_plan.md +0 -894
  238. package/resources/gofer/claude-commands/4_gofer_tasks.md +0 -755
  239. package/resources/gofer/claude-commands/5_gofer_implement.md +0 -939
  240. package/resources/gofer/claude-commands/6_gofer_validate.md +0 -2297
  241. package/resources/gofer/claude-commands/7_gofer_save.md +0 -418
  242. package/resources/gofer/claude-commands/7a_stakeholder_comms.md +0 -503
  243. package/resources/gofer/claude-commands/8_gofer_branding.md +0 -310
  244. package/resources/gofer/claude-commands/9_gofer_tests.md +0 -553
  245. package/resources/gofer/claude-commands/gofer_bootstrap_workspace.md +0 -143
  246. package/resources/gofer/claude-commands/gofer_check_workspace.md +0 -114
  247. package/resources/gofer/claude-commands/gofer_constitution.md +0 -607
  248. package/resources/gofer/claude-commands/gofer_diagnose.md +0 -109
  249. package/resources/gofer/claude-commands/gofer_eai_first_run.md +0 -392
  250. package/resources/gofer/claude-commands/gofer_hydrate.md +0 -556
  251. package/resources/gofer/claude-commands/gofer_personality.md +0 -39
  252. package/resources/gofer/claude-commands/gofer_plan.md +0 -35
  253. package/resources/gofer/claude-commands/gofer_side.md +0 -40
  254. package/resources/gofer/claude-commands/gofer_spec_summary.md +0 -107
  255. package/resources/gofer/claude-commands/gofer_tdd.md +0 -107
  256. package/resources/gofer/claude-commands/gofer_vocabulary.md +0 -107
  257. package/resources/gofer/claude-commands/gofer_zoom_out.md +0 -107
  258. package/resources/gofer/claude-skills/eai-gofer/SKILL.md +0 -56
  259. package/resources/gofer/copilot-prompts/0_gofer_start.prompt.md +0 -1308
  260. package/resources/gofer/copilot-prompts/0a_problem_validation.prompt.md +0 -429
  261. package/resources/gofer/copilot-prompts/10_gofer_cloud.prompt.md +0 -644
  262. package/resources/gofer/copilot-prompts/1_gofer_research.prompt.md +0 -1177
  263. package/resources/gofer/copilot-prompts/2_gofer_specify.prompt.md +0 -878
  264. package/resources/gofer/copilot-prompts/3_gofer_plan.prompt.md +0 -917
  265. package/resources/gofer/copilot-prompts/4_gofer_tasks.prompt.md +0 -778
  266. package/resources/gofer/copilot-prompts/5_gofer_implement.prompt.md +0 -962
  267. package/resources/gofer/copilot-prompts/6_gofer_validate.prompt.md +0 -2310
  268. package/resources/gofer/copilot-prompts/7_gofer_save.prompt.md +0 -433
  269. package/resources/gofer/copilot-prompts/7a_stakeholder_comms.prompt.md +0 -516
  270. package/resources/gofer/copilot-prompts/8_gofer_branding.prompt.md +0 -323
  271. package/resources/gofer/copilot-prompts/9_gofer_tests.prompt.md +0 -566
  272. package/resources/gofer/copilot-prompts/gofer_bootstrap_workspace.prompt.md +0 -161
  273. package/resources/gofer/copilot-prompts/gofer_check_workspace.prompt.md +0 -132
  274. package/resources/gofer/copilot-prompts/gofer_constitution.prompt.md +0 -621
  275. package/resources/gofer/copilot-prompts/gofer_diagnose.prompt.md +0 -127
  276. package/resources/gofer/copilot-prompts/gofer_eai_first_run.prompt.md +0 -410
  277. package/resources/gofer/copilot-prompts/gofer_hydrate.prompt.md +0 -571
  278. package/resources/gofer/copilot-prompts/gofer_personality.prompt.md +0 -57
  279. package/resources/gofer/copilot-prompts/gofer_plan.prompt.md +0 -53
  280. package/resources/gofer/copilot-prompts/gofer_side.prompt.md +0 -58
  281. package/resources/gofer/copilot-prompts/gofer_spec_summary.prompt.md +0 -125
  282. package/resources/gofer/copilot-prompts/gofer_tdd.prompt.md +0 -125
  283. package/resources/gofer/copilot-prompts/gofer_vocabulary.prompt.md +0 -125
  284. package/resources/gofer/copilot-prompts/gofer_zoom_out.prompt.md +0 -125
  285. package/resources/gofer/gemini/commands/gofer/0_gofer_start.md +0 -1282
  286. package/resources/gofer/gemini/commands/gofer/0_gofer_start.toml +0 -2
  287. package/resources/gofer/gemini/commands/gofer/0a_problem_validation.md +0 -424
  288. package/resources/gofer/gemini/commands/gofer/0a_problem_validation.toml +0 -2
  289. package/resources/gofer/gemini/commands/gofer/10_gofer_cloud.md +0 -630
  290. package/resources/gofer/gemini/commands/gofer/10_gofer_cloud.toml +0 -2
  291. package/resources/gofer/gemini/commands/gofer/1_gofer_research.md +0 -1154
  292. package/resources/gofer/gemini/commands/gofer/1_gofer_research.toml +0 -2
  293. package/resources/gofer/gemini/commands/gofer/2_gofer_specify.md +0 -855
  294. package/resources/gofer/gemini/commands/gofer/2_gofer_specify.toml +0 -2
  295. package/resources/gofer/gemini/commands/gofer/3_gofer_plan.md +0 -894
  296. package/resources/gofer/gemini/commands/gofer/3_gofer_plan.toml +0 -2
  297. package/resources/gofer/gemini/commands/gofer/4_gofer_tasks.md +0 -755
  298. package/resources/gofer/gemini/commands/gofer/4_gofer_tasks.toml +0 -2
  299. package/resources/gofer/gemini/commands/gofer/5_gofer_implement.md +0 -939
  300. package/resources/gofer/gemini/commands/gofer/5_gofer_implement.toml +0 -2
  301. package/resources/gofer/gemini/commands/gofer/6_gofer_validate.md +0 -2297
  302. package/resources/gofer/gemini/commands/gofer/6_gofer_validate.toml +0 -2
  303. package/resources/gofer/gemini/commands/gofer/7_gofer_save.md +0 -418
  304. package/resources/gofer/gemini/commands/gofer/7_gofer_save.toml +0 -2
  305. package/resources/gofer/gemini/commands/gofer/7a_stakeholder_comms.md +0 -503
  306. package/resources/gofer/gemini/commands/gofer/7a_stakeholder_comms.toml +0 -2
  307. package/resources/gofer/gemini/commands/gofer/8_gofer_branding.md +0 -310
  308. package/resources/gofer/gemini/commands/gofer/8_gofer_branding.toml +0 -2
  309. package/resources/gofer/gemini/commands/gofer/9_gofer_tests.md +0 -553
  310. package/resources/gofer/gemini/commands/gofer/9_gofer_tests.toml +0 -2
  311. package/resources/gofer/gemini/commands/gofer/gofer_bootstrap_workspace.md +0 -143
  312. package/resources/gofer/gemini/commands/gofer/gofer_bootstrap_workspace.toml +0 -2
  313. package/resources/gofer/gemini/commands/gofer/gofer_check_workspace.md +0 -114
  314. package/resources/gofer/gemini/commands/gofer/gofer_check_workspace.toml +0 -2
  315. package/resources/gofer/gemini/commands/gofer/gofer_constitution.md +0 -607
  316. package/resources/gofer/gemini/commands/gofer/gofer_constitution.toml +0 -2
  317. package/resources/gofer/gemini/commands/gofer/gofer_diagnose.md +0 -109
  318. package/resources/gofer/gemini/commands/gofer/gofer_diagnose.toml +0 -2
  319. package/resources/gofer/gemini/commands/gofer/gofer_eai_first_run.md +0 -392
  320. package/resources/gofer/gemini/commands/gofer/gofer_eai_first_run.toml +0 -2
  321. package/resources/gofer/gemini/commands/gofer/gofer_hydrate.md +0 -556
  322. package/resources/gofer/gemini/commands/gofer/gofer_hydrate.toml +0 -2
  323. package/resources/gofer/gemini/commands/gofer/gofer_personality.md +0 -39
  324. package/resources/gofer/gemini/commands/gofer/gofer_personality.toml +0 -2
  325. package/resources/gofer/gemini/commands/gofer/gofer_plan.md +0 -35
  326. package/resources/gofer/gemini/commands/gofer/gofer_plan.toml +0 -2
  327. package/resources/gofer/gemini/commands/gofer/gofer_side.md +0 -40
  328. package/resources/gofer/gemini/commands/gofer/gofer_side.toml +0 -2
  329. package/resources/gofer/gemini/commands/gofer/gofer_spec_summary.md +0 -107
  330. package/resources/gofer/gemini/commands/gofer/gofer_spec_summary.toml +0 -2
  331. package/resources/gofer/gemini/commands/gofer/gofer_tdd.md +0 -107
  332. package/resources/gofer/gemini/commands/gofer/gofer_tdd.toml +0 -2
  333. package/resources/gofer/gemini/commands/gofer/gofer_vocabulary.md +0 -107
  334. package/resources/gofer/gemini/commands/gofer/gofer_vocabulary.toml +0 -2
  335. package/resources/gofer/gemini/commands/gofer/gofer_zoom_out.md +0 -107
  336. package/resources/gofer/gemini/commands/gofer/gofer_zoom_out.toml +0 -2
  337. package/resources/gofer/github-skills/eai-gofer/SKILL.md +0 -56
  338. package/resources/gofer/system-skills/0_gofer_start/SKILL.md +0 -1287
  339. package/resources/gofer/system-skills/0a_problem_validation/SKILL.md +0 -429
  340. package/resources/gofer/system-skills/10_gofer_cloud/SKILL.md +0 -635
  341. package/resources/gofer/system-skills/1_gofer_research/SKILL.md +0 -1159
  342. package/resources/gofer/system-skills/2_gofer_specify/SKILL.md +0 -860
  343. package/resources/gofer/system-skills/3_gofer_plan/SKILL.md +0 -899
  344. package/resources/gofer/system-skills/4_gofer_tasks/SKILL.md +0 -760
  345. package/resources/gofer/system-skills/5_gofer_implement/SKILL.md +0 -944
  346. package/resources/gofer/system-skills/6_gofer_validate/SKILL.md +0 -2302
  347. package/resources/gofer/system-skills/7_gofer_save/SKILL.md +0 -423
  348. package/resources/gofer/system-skills/7a_stakeholder_comms/SKILL.md +0 -508
  349. package/resources/gofer/system-skills/8_gofer_branding/SKILL.md +0 -315
  350. package/resources/gofer/system-skills/9_gofer_tests/SKILL.md +0 -558
  351. package/resources/gofer/system-skills/gofer_bootstrap_workspace/SKILL.md +0 -148
  352. package/resources/gofer/system-skills/gofer_check_workspace/SKILL.md +0 -119
  353. package/resources/gofer/system-skills/gofer_constitution/SKILL.md +0 -612
  354. package/resources/gofer/system-skills/gofer_diagnose/SKILL.md +0 -114
  355. package/resources/gofer/system-skills/gofer_eai_first_run/SKILL.md +0 -397
  356. package/resources/gofer/system-skills/gofer_hydrate/SKILL.md +0 -561
  357. package/resources/gofer/system-skills/gofer_personality/SKILL.md +0 -44
  358. package/resources/gofer/system-skills/gofer_plan/SKILL.md +0 -40
  359. package/resources/gofer/system-skills/gofer_side/SKILL.md +0 -45
  360. package/resources/gofer/system-skills/gofer_spec_summary/SKILL.md +0 -112
  361. package/resources/gofer/system-skills/gofer_tdd/SKILL.md +0 -112
  362. package/resources/gofer/system-skills/gofer_vocabulary/SKILL.md +0 -112
  363. package/resources/gofer/system-skills/gofer_zoom_out/SKILL.md +0 -112
  364. package/resources/gofer/templates/ui-approval-template.md +0 -32
@@ -0,0 +1,484 @@
1
+ /**
2
+ * Host-neutral execution kernel. Adapters are trusted application code, never
3
+ * commands or capability declarations received from a worker or a document.
4
+ */
5
+ import { constants } from 'node:fs';
6
+ import { open, readFile, realpath, lstat, rename, writeFile } from 'node:fs/promises';
7
+ import path from 'node:path';
8
+ import { createHash } from 'node:crypto';
9
+ import { reviewPriority } from './gofer-priority-check.mjs';
10
+ import { inspectBlockers } from './gofer-blocker-control.mjs';
11
+ import { capabilityReceiptHash, verifyCapabilityReceipt } from './gofer-host-capability.mjs';
12
+ import { selectCapabilityRoute } from './gofer-live-routing.mjs';
13
+ import { acquireLedgerLock } from './gofer-runtime-ledger.mjs';
14
+
15
+ const contractFiles = ['spec.md', 'plan.md', 'decisions.md', 'priority-plan.json', 'loop-contract.json'];
16
+ const MAX_CONTRACT_FILE_BYTES = 1024 * 1024;
17
+ const positive = value => Number.isSafeInteger(value) && value > 0;
18
+ const text = value => typeof value === 'string' && value.trim().length > 0;
19
+ function releaseResumeLock(lock) {
20
+ try { lock.exec('ROLLBACK'); } finally { lock.close(); }
21
+ }
22
+
23
+ export async function executionRevision(featureDir) {
24
+ return (await snapshot(featureDir)).revision;
25
+ }
26
+
27
+ async function snapshot(featureDir) {
28
+ const hash = createHash('sha256');
29
+ const files = {};
30
+ for (const file of contractFiles) {
31
+ files[file] = await readContractFile(featureDir, file);
32
+ hash.update(file).update(files[file]);
33
+ }
34
+ return { files, revision: hash.digest('hex') };
35
+ }
36
+
37
+ async function readContractFile(featureDir, name) {
38
+ const root = await realpath(featureDir);
39
+ const target = path.join(root, name);
40
+ // Resolve before opening. A different canonical path proves a supplied link.
41
+ const canonical = await realpath(target);
42
+ if (canonical !== target) throw new Error('UNSAFE_CONTRACT_FILE');
43
+ // Do not follow a link introduced after canonical-path validation on POSIX.
44
+ const flags = constants.O_RDONLY | (process.platform === 'win32' ? 0 : constants.O_NOFOLLOW);
45
+ const file = await open(canonical, flags);
46
+ try {
47
+ const stat = await file.stat();
48
+ if (!stat.isFile() || stat.size > MAX_CONTRACT_FILE_BYTES) throw new Error('UNSAFE_CONTRACT_FILE');
49
+ return await file.readFile({ encoding: 'utf8' });
50
+ } finally {
51
+ await file.close();
52
+ }
53
+ }
54
+
55
+ function freeze(value) {
56
+ if (value && typeof value === 'object') { Object.values(value).forEach(freeze); Object.freeze(value); }
57
+ return value;
58
+ }
59
+
60
+ async function canonicalScopes(workspace, scopes) {
61
+ const root = await realpath(workspace);
62
+ return Promise.all(scopes.map(async scope => {
63
+ const segments = scope.replace(/\/$/, '').split('/');
64
+ let current = root;
65
+ for (const segment of segments) {
66
+ current = path.join(current, segment);
67
+ try { if ((await lstat(current)).isSymbolicLink()) throw new Error('SYMLINK_SCOPE_UNQUALIFIED'); }
68
+ catch (error) { if (error.code !== 'ENOENT') throw error; }
69
+ }
70
+ return path.relative(root, current).split(path.sep).join('/');
71
+ }));
72
+ }
73
+
74
+ export function validateWorkGraph(plan, checks) {
75
+ if (![1, 2].includes(plan?.schemaVersion) || !text(plan.revision) || !plan.tasks ||
76
+ !Array.isArray(plan.criticalPath) || !plan.criticalPath.length) throw new Error('INVALID_GRAPH');
77
+ const ids = Object.keys(plan.tasks);
78
+ if (!ids.length || ids.length > 1000 || new Set(plan.criticalPath).size !== plan.criticalPath.length ||
79
+ plan.criticalPath.some(id => !ids.includes(id))) throw new Error('INVALID_GRAPH');
80
+ let edgeCount = 0;
81
+ let scopeCount = 0;
82
+ for (const id of ids) {
83
+ const task = plan.tasks[id];
84
+ if (!/^T\d+$/.test(id) || !task || !Array.isArray(task.dependsOn) ||
85
+ task.dependsOn.length > 256 || task.dependsOn.some(dep => !ids.includes(dep)) || !Array.isArray(task.allowedEditScope) ||
86
+ task.allowedEditScope.length > 256 ||
87
+ task.allowedEditScope.some(scope => !text(scope) || /(^\/|\/\/|\\|:|\0|[*?\[\]]|(^|\/)\.\.?($|\/))/.test(scope)) ||
88
+ !Array.isArray(checks[id]) || !checks[id].length || checks[id].length > 256 || checks[id].some(c => !text(c) || c.length > 1024) ||
89
+ new Set(checks[id]).size !== checks[id].length) throw new Error('INVALID_WORK_ORDER');
90
+ edgeCount += task.dependsOn.length;
91
+ scopeCount += task.allowedEditScope.length;
92
+ if (edgeCount > 10000 || scopeCount > 10000) throw new Error('INVALID_WORK_ORDER');
93
+ }
94
+ const states = new Map(ids.map(id => [id, 0]));
95
+ const visit = id => {
96
+ const state = states.get(id);
97
+ if (state === 1) throw new Error('CYCLIC_GRAPH');
98
+ if (state === 2) return;
99
+ states.set(id, 1);
100
+ for (const dependency of plan.tasks[id].dependsOn) visit(dependency);
101
+ states.set(id, 2);
102
+ };
103
+ ids.forEach(visit);
104
+ return ids;
105
+ }
106
+
107
+ function overlaps(a, b) {
108
+ // Conservative on case-insensitive hosts and on parent/child directory edits.
109
+ return a.some(left => b.some(right => {
110
+ const x = left.toLowerCase().replace(/\/$/, '');
111
+ const y = right.toLowerCase().replace(/\/$/, '');
112
+ return x === y || x.startsWith(`${y}/`) || y.startsWith(`${x}/`);
113
+ }));
114
+ }
115
+
116
+ /**
117
+ * Run a trusted adapter against the existing priority plan. Each required check
118
+ * runs separately from worker output. This library does not provide a sandbox.
119
+ * An existing journal is a reconciliation gate, not permission to replay work.
120
+ */
121
+ export async function runVerifiedGraph({ featureDir, workspaceRoot, checks, adapter,
122
+ ledger, capabilityReceipt, capabilityPublicKey, requiredCapabilities, benchmarkEvidence, verifyBenchmark,
123
+ advisoryConstraints, approvalReceipt, maxCalls, maxConcurrent = 1, deadlineMs, signal, recovery,
124
+ adapterDrainMs = 5000 }) {
125
+ // Copy before any await: a caller or worker must not remove required checks.
126
+ checks = freeze(structuredClone(checks));
127
+ const journalName = 'verified-execution.jsonl';
128
+ if (!positive(maxCalls) || !positive(maxConcurrent) || maxConcurrent > 8 ||
129
+ !positive(adapterDrainMs) || adapterDrainMs > 10000 ||
130
+ !Number.isFinite(deadlineMs) || deadlineMs <= Date.now()) throw new Error('FINITE_LIMITS_REQUIRED');
131
+ if (!text(approvalReceipt)) throw new Error('APPROVAL_RECEIPT_REQUIRED');
132
+ for (const method of ['execute', 'check', 'inputRevision', 'reserve', 'lease', 'verified']) {
133
+ if (typeof adapter?.[method] !== 'function') throw new Error(`TRUSTED_ADAPTER_REQUIRED:${method}`);
134
+ }
135
+ if (capabilityReceipt?.isolationClass !== 'git-worktree+local-os-sandbox' ||
136
+ typeof ledger?.authorize !== 'function' || typeof ledger?.authorizeCommit !== 'function' || !verifyCapabilityReceipt(capabilityReceipt, {
137
+ publicKey: capabilityPublicKey, requiredCapabilities,
138
+ })) throw new Error('LEDGER_CAPABILITY_AUTHORITY_REQUIRED');
139
+ const route = await selectCapabilityRoute({ receipt: capabilityReceipt, publicKey: capabilityPublicKey,
140
+ host: capabilityReceipt.host, requiredCapabilities, benchmarkEvidence, verifyBenchmark, advisoryConstraints });
141
+ const root = await realpath(featureDir);
142
+ const captured = await snapshot(root);
143
+ const plan = freeze(JSON.parse(captured.files['priority-plan.json']));
144
+ const loop = freeze(JSON.parse(captured.files['loop-contract.json']));
145
+ if (!positive(loop.maxIterations)) throw new Error('FINITE_ATTEMPTS_REQUIRED');
146
+ if (loop.budget?.maxModelSpendUsd != null) throw new Error('SPEND_RESERVATION_NOT_IMPLEMENTED');
147
+ if (loop.budget?.maxWallClockMinutes != null) {
148
+ if (!(loop.budget.maxWallClockMinutes > 0)) throw new Error('INVALID_DEADLINE');
149
+ deadlineMs = Math.min(deadlineMs, Date.now() + loop.budget.maxWallClockMinutes * 60000);
150
+ }
151
+ const ids = validateWorkGraph(plan, checks);
152
+ const initial = await reviewPriority(root);
153
+ if (initial.status !== 'pass') throw new Error(`PRIORITY_BLOCKED:${initial.findings.join(',')}`);
154
+ const revision = captured.revision;
155
+ const receiptHash = capabilityReceiptHash(capabilityReceipt);
156
+ if (await executionRevision(root) !== revision) throw new Error('STALE_DIRECTION');
157
+ const tasksText = await readFile(path.join(root, 'tasks.md'), 'utf8');
158
+ const previouslyComplete = new Set([...tasksText.matchAll(/^\s*-\s+\[[xX]\]\s+(?:\*\*)?(T\d+)\b/gm)].map(m => m[1]));
159
+ const scopes = {};
160
+ for (const id of ids) scopes[id] = await canonicalScopes(workspaceRoot, plan.tasks[id].allowedEditScope);
161
+ let resumeReport;
162
+ let resumeLock;
163
+ const lockPath = path.join(root, 'verified-execution.resume.lock');
164
+ if (recovery) {
165
+ // The transaction excludes other controllers and the operating system
166
+ // releases it if this controller exits before reconciliation finishes.
167
+ resumeLock = await acquireLedgerLock(lockPath).catch(() => { throw new Error('RESUME_LOCKED'); });
168
+ try {
169
+ const { inspectExecutionRecovery } = await import('./gofer-execution-recovery.mjs');
170
+ resumeReport = await inspectExecutionRecovery({ ...recovery, featureDir: root });
171
+ const run = resumeReport.run;
172
+ if (resumeReport.status !== 'reconciled' || !resumeReport.resumeAllowed ||
173
+ resumeReport.uncertainTasks.length || !run ||
174
+ run.revision !== revision || run.maxCalls !== maxCalls || run.maxConcurrent !== maxConcurrent ||
175
+ run.maxIterations !== loop.maxIterations || deadlineMs !== run.deadlineMs ||
176
+ run.capabilityReceiptHash !== receiptHash || run.selectedModel !== route.model.id ||
177
+ run.benchmarkReceipt !== route.benchmarkReceipt || run.approvalReceipt !== approvalReceipt ||
178
+ JSON.stringify(run.requiredChecks) !== JSON.stringify(checks) ||
179
+ (resumeReport.restartableTasks.length > 0 &&
180
+ (resumeReport.restartableTasks.length !== 1 ||
181
+ resumeReport.replacementWorktreeReceipt !== adapter.worktreeReceipt)) ||
182
+ previouslyComplete.size !== resumeReport.reusableTasks.length ||
183
+ [...previouslyComplete].some(id => !resumeReport.reusableTasks.includes(id)) ||
184
+ resumeReport.reusableTasks.length === ids.length) throw new Error('RESUME_RECONCILIATION_REQUIRED');
185
+ for (const taskId of resumeReport.reusableTasks) {
186
+ const input = await adapter.inputRevision({ taskId, revision,
187
+ allowedEditScope: plan.tasks[taskId].allowedEditScope, requiredChecks: checks[taskId] });
188
+ if (input !== resumeReport.verifiedInputs[taskId]) throw new Error('STALE_PREREQUISITE_EVIDENCE');
189
+ }
190
+ } catch (error) {
191
+ releaseResumeLock(resumeLock);
192
+ throw error;
193
+ }
194
+ } else if (previouslyComplete.size) throw new Error('BASELINE_EVIDENCE_RECONCILIATION_REQUIRED');
195
+ const states = Object.fromEntries(ids.map(id => [id, resumeReport?.reusableTasks.includes(id) ? 'verified' : 'pending']));
196
+ const attempts = Object.fromEntries(ids.map(id => [id, resumeReport?.attemptsConsumed[id] || 0]));
197
+ const verifiedInputs = new Map(Object.entries(resumeReport?.verifiedInputs || {}));
198
+ const controller = new AbortController();
199
+ const cancel = () => controller.abort(new Error('CANCELLED'));
200
+ if (signal?.aborted) cancel();
201
+ signal?.addEventListener('abort', cancel, { once: true });
202
+ const timer = setTimeout(() => controller.abort(new Error('DEADLINE')), Math.min(deadlineMs - Date.now(), 2147483647));
203
+ const file = await open(path.join(root, journalName), recovery ? constants.O_RDWR | constants.O_APPEND | constants.O_NOFOLLOW : 'wx', 0o600).catch(async error => {
204
+ clearTimeout(timer); signal?.removeEventListener('abort', cancel);
205
+ if (resumeLock) releaseResumeLock(resumeLock);
206
+ throw new Error(error.code === 'EEXIST' ? 'RECONCILIATION_REQUIRED' : 'JOURNAL_UNAVAILABLE');
207
+ });
208
+ let calls = resumeReport?.callsConsumed || 0;
209
+ let write = Promise.resolve();
210
+ let checkpointWrite = Promise.resolve();
211
+ let checkpointSequence = 0;
212
+ const pendingAdapterCalls = new Set();
213
+ let drainAttempted = false;
214
+ async function drainAdapterCalls() {
215
+ drainAttempted = true;
216
+ if (!pendingAdapterCalls.size) return true;
217
+ let drainTimer;
218
+ const settled = await Promise.race([
219
+ Promise.allSettled([...pendingAdapterCalls]).then(() => true),
220
+ new Promise(resolve => { drainTimer = setTimeout(() => resolve(false), adapterDrainMs); }),
221
+ ]);
222
+ clearTimeout(drainTimer);
223
+ return settled;
224
+ }
225
+ const record = event => {
226
+ write = write.then(async () => { await file.writeFile(`${JSON.stringify({ schemaVersion: 1, revision, time: new Date().toISOString(), ...event })}\n`); await file.sync(); })
227
+ .catch(() => { controller.abort(new Error('JOURNAL_FAILURE')); throw new Error('JOURNAL_FAILURE'); });
228
+ return write;
229
+ };
230
+ const abortCheck = () => {
231
+ if (Date.now() >= deadlineMs && !controller.signal.aborted) controller.abort(new Error('DEADLINE'));
232
+ if (controller.signal.aborted) throw controller.signal.reason;
233
+ };
234
+ // The checkpoint contains only current graph state plus the latest delta.
235
+ // It avoids replaying the entire append-only ledger during operator recovery.
236
+ async function checkpoint(event, taskId = null) {
237
+ // Serialize snapshots so concurrent tasks cannot race the replacement file.
238
+ checkpointWrite = checkpointWrite.then(async () => {
239
+ const payload = JSON.stringify({ schemaVersion: 1, revision, updatedAt: new Date().toISOString(),
240
+ delta: { event, taskId }, states, attempts, calls,
241
+ verifiedInputs: Object.fromEntries(verifiedInputs) });
242
+ const target = path.join(root, 'verified-execution.checkpoint.json');
243
+ const temporary = `${target}.${process.pid}.${++checkpointSequence}.tmp`;
244
+ try {
245
+ await writeFile(temporary, payload, { encoding: 'utf8', mode: 0o600, flag: 'wx' });
246
+ await rename(temporary, target);
247
+ } catch {
248
+ controller.abort(new Error('CHECKPOINT_UNAVAILABLE'));
249
+ throw controller.signal.reason;
250
+ }
251
+ });
252
+ return checkpointWrite;
253
+ }
254
+ async function current() {
255
+ abortCheck();
256
+ if (await executionRevision(root) !== revision) {
257
+ controller.abort(new Error('STALE_DIRECTION'));
258
+ throw controller.signal.reason;
259
+ }
260
+ abortCheck();
261
+ }
262
+ async function invoke(method, request) {
263
+ await current();
264
+ const blockers = await inspectBlockers(root, { taskId: request.taskId });
265
+ if (blockers.blockers.some(b => b.state !== 'ready')) throw new Error('RECORDED_BLOCKER_WAIT');
266
+ if (calls >= maxCalls) throw new Error('CALL_LIMIT');
267
+ // Reserve globally before yielding, so parallel calls cannot overdraw.
268
+ calls++;
269
+ await record({ event: 'call_reserved', task: request.taskId, method, call: calls });
270
+ let listener;
271
+ try {
272
+ await current();
273
+ const operation = Promise.resolve().then(() => { abortCheck(); return adapter[method]({ ...request, signal: controller.signal }); });
274
+ const settled = operation.then(() => {}, () => {}).finally(() => pendingAdapterCalls.delete(settled));
275
+ pendingAdapterCalls.add(settled);
276
+ return await Promise.race([
277
+ operation,
278
+ new Promise((_, reject) => {
279
+ listener = () => reject(controller.signal.reason);
280
+ controller.signal.addEventListener('abort', listener, { once: true });
281
+ if (controller.signal.aborted) listener();
282
+ }),
283
+ ]);
284
+ } finally {
285
+ if (listener) controller.signal.removeEventListener('abort', listener);
286
+ }
287
+ }
288
+ async function runTask(taskId) {
289
+ const task = plan.tasks[taskId];
290
+ const dependencies = task.dependsOn.map(dependency => ({ taskId: dependency,
291
+ inputRevision: verifiedInputs.get(dependency) ?? null }));
292
+ if (dependencies.some(dependency => !text(dependency.inputRevision))) throw new Error('DEPENDENCY_INPUT_REQUIRED');
293
+ const request = { taskId, revision, dependencies, allowedEditScope: task.allowedEditScope, requiredChecks: checks[taskId], approvalReceipt,
294
+ ...(text(adapter.worktreeReceipt) ? { worktreeReceipt: adapter.worktreeReceipt } : {}),
295
+ capabilityReceiptHash: receiptHash, selectedModel: route.model.id, benchmarkReceipt: route.benchmarkReceipt };
296
+ let previousChecks = [];
297
+ try {
298
+ while (attempts[taskId] < loop.maxIterations) {
299
+ await current();
300
+ const blockers = await inspectBlockers(root, { taskId });
301
+ if (blockers.blockers.some(b => b.state !== 'ready')) throw new Error('RECORDED_BLOCKER_WAIT');
302
+ const priority = await reviewPriority(root, { task: taskId });
303
+ if (priority.status !== 'pass') throw new Error('PRIORITY_BLOCKED');
304
+ await canonicalScopes(workspaceRoot, task.allowedEditScope);
305
+ const attempt = ++attempts[taskId];
306
+ await record({ event: 'attempt_reserved', task: taskId, attempt });
307
+ const reservation = await invoke('reserve', { ...request, attempt });
308
+ if (reservation?.allowed !== true || !text(reservation.budgetReservation)) throw new Error('BLOCKER_OR_BUDGET_DENIED');
309
+ const lease = await invoke('lease', { ...request, attempt });
310
+ const leaseExpiry = Date.parse(lease?.expiresAt);
311
+ if (!text(lease?.leaseId) || !Number.isFinite(leaseExpiry) || leaseExpiry <= Date.now()) {
312
+ throw new Error('TASK_LEASE_REQUIRED');
313
+ }
314
+ await record({ event: 'lease_granted', task: taskId, attempt, leaseId: lease.leaseId, expiresAt: lease.expiresAt });
315
+ const leasedRequest = { ...request, attempt, budgetReservation: reservation.budgetReservation,
316
+ leaseId: lease.leaseId, leaseExpiresAt: lease.expiresAt };
317
+ const authority = await ledger.authorize(leasedRequest);
318
+ if (authority?.allowed !== true || authority.taskId !== taskId || authority.revision !== revision ||
319
+ authority.attempt !== attempt || authority.capabilityReceiptHash !== receiptHash ||
320
+ authority.budgetReservation !== reservation.budgetReservation || authority.leaseId !== lease.leaseId ||
321
+ authority.worktreeReceipt !== request.worktreeReceipt ||
322
+ authority.leaseExpiresAt !== lease.expiresAt || authority.allowedEditScope?.join('\0') !== request.allowedEditScope.join('\0') ||
323
+ authority.requiredChecks?.join('\0') !== request.requiredChecks.join('\0') || authority.approvalReceipt !== approvalReceipt ||
324
+ !text(authority.receipt)) throw new Error('LEDGER_AUTHORITY_REQUIRED');
325
+ await record({ event: 'ledger_authorized', task: taskId, attempt, leaseId: lease.leaseId,
326
+ budgetReservation: reservation.budgetReservation, receipt: authority.receipt, capabilityReceiptHash: receiptHash,
327
+ worktreeReceipt: request.worktreeReceipt ?? null });
328
+ states[taskId] = 'running';
329
+ await checkpoint('running', taskId);
330
+ // Repair sees measured failures, never just "try again" or prior reasoning.
331
+ const result = await invoke('execute', { ...leasedRequest, ledgerAuthorityReceipt: authority.receipt,
332
+ previousChecks: freeze(structuredClone(previousChecks)) });
333
+ await current();
334
+ if (!result || !Array.isArray(result.changedFiles) || result.changedFiles.some(f => !text(f))) throw new Error('INVALID_WORKER_RESULT');
335
+ const scope = await reviewPriority(root, { task: taskId, changedFiles: result.changedFiles, workspaceRoot });
336
+ if (scope.status !== 'pass') throw new Error('SCOPE_VIOLATION');
337
+ const inputRevision = await invoke('inputRevision', request);
338
+ if (!text(inputRevision)) throw new Error('INPUT_REVISION_REQUIRED');
339
+ states[taskId] = 'awaiting-check';
340
+ let passed = true;
341
+ previousChecks = [];
342
+ for (const check of checks[taskId]) {
343
+ let evidence;
344
+ try {
345
+ evidence = await invoke('check', { ...leasedRequest, check, inputRevision });
346
+ } catch {
347
+ // A failed check can leave local or remote work in an unknown state.
348
+ controller.abort(new Error('CHECK_RECONCILIATION_REQUIRED'));
349
+ throw controller.signal.reason;
350
+ }
351
+ await current();
352
+ const valid = evidence?.taskId === taskId && evidence.revision === revision &&
353
+ evidence.inputRevision === inputRevision && evidence.check === check &&
354
+ evidence.exitCode === 0 && evidence.executed === true && text(evidence.receipt);
355
+ await record({ event: 'check', task: taskId, attempt, check, inputRevision,
356
+ passed: valid, receipt: text(evidence?.receipt) ? evidence.receipt : null });
357
+ if (evidence?.cleanupVerified === false) {
358
+ controller.abort(new Error('CLEANUP_RECONCILIATION_REQUIRED'));
359
+ throw controller.signal.reason;
360
+ }
361
+ previousChecks.push({ check, passed: valid, inputRevision,
362
+ receipt: text(evidence?.receipt) ? evidence.receipt : null });
363
+ passed &&= valid;
364
+ }
365
+ if (await invoke('inputRevision', request) !== inputRevision) throw new Error('STALE_INPUT');
366
+ if (passed) {
367
+ await current();
368
+ const assertCurrent = async () => {
369
+ await current();
370
+ const blockers = await inspectBlockers(root, { taskId });
371
+ if (blockers.blockers.some(b => b.state !== 'ready')) throw new Error('RECORDED_BLOCKER_WAIT');
372
+ if (await invoke('inputRevision', request) !== inputRevision) throw new Error('STALE_INPUT');
373
+ await current();
374
+ };
375
+ await assertCurrent();
376
+ const commitAuthority = await ledger.authorizeCommit({ ...leasedRequest, inputRevision,
377
+ validation: freeze(structuredClone(previousChecks)) });
378
+ if (commitAuthority?.allowed !== true || commitAuthority.taskId !== taskId ||
379
+ commitAuthority.revision !== revision || commitAuthority.inputRevision !== inputRevision ||
380
+ commitAuthority.leaseId !== lease.leaseId || commitAuthority.capabilityReceiptHash !== receiptHash ||
381
+ !text(commitAuthority.receipt)) throw new Error('LEDGER_COMMIT_AUTHORITY_REQUIRED');
382
+ await record({ event: 'commit_authorized', task: taskId, attempt, leaseId: lease.leaseId,
383
+ inputRevision, receipt: commitAuthority.receipt, capabilityReceiptHash: receiptHash });
384
+ // The trusted adapter must compare-and-set, not unconditionally tick tasks.
385
+ const commit = await invoke('verified', { ...leasedRequest, inputRevision,
386
+ commitAuthorityReceipt: commitAuthority.receipt, assertCurrent });
387
+ if (commit?.committed !== true || commit.taskId !== taskId || commit.revision !== revision ||
388
+ commit.inputRevision !== inputRevision || !text(commit.receipt)) throw new Error('COMMIT_RECONCILIATION_REQUIRED');
389
+ await assertCurrent();
390
+ await current();
391
+ states[taskId] = 'verified';
392
+ verifiedInputs.set(taskId, inputRevision);
393
+ await record({ event: 'verified', task: taskId, inputRevision, receipt: commit.receipt });
394
+ await checkpoint('verified', taskId);
395
+ return;
396
+ }
397
+ await record({ event: 'repair_required', task: taskId, attempt });
398
+ }
399
+ throw new Error('ATTEMPT_LIMIT');
400
+ } catch (error) {
401
+ const reason = controller.signal.aborted ? controller.signal.reason.message : error.message;
402
+ states[taskId] = reason.startsWith('STALE') ? 'stale' : reason === 'CLEANUP_RECONCILIATION_REQUIRED' ? 'blocked' : controller.signal.aborted ? 'cancelled' : 'blocked';
403
+ await record({ event: states[taskId], task: taskId, reason, reconciliationRequired: true }).catch(() => {});
404
+ await checkpoint(states[taskId], taskId).catch(() => {});
405
+ }
406
+ }
407
+ try {
408
+ if (resumeReport) {
409
+ const contents = await file.readFile('utf8');
410
+ if (createHash('sha256').update(contents).digest('hex') !== resumeReport.journalHash) throw new Error('RECOVERY_INPUT_CHANGED');
411
+ await record({ event: 'resumed', previousJournalHash: resumeReport.journalHash,
412
+ callsConsumed: calls, attemptsConsumed: resumeReport.attemptsConsumed });
413
+ await checkpoint('resumed');
414
+ } else {
415
+ await record({ event: 'started', maxCalls, maxConcurrent, maxIterations: loop.maxIterations, capabilityReceiptHash: receiptHash,
416
+ selectedModel: route.model.id, benchmarkReceipt: route.benchmarkReceipt, approvalReceipt,
417
+ requiredChecks: checks, deadlineMs, baselineTasks: [...previouslyComplete],
418
+ worktreeReceipt: adapter.worktreeReceipt ?? null });
419
+ await checkpoint('started');
420
+ }
421
+ const active = new Map();
422
+ while (!controller.signal.aborted) {
423
+ let scheduled = false;
424
+ for (const id of ids) {
425
+ if (active.size === maxConcurrent || states[id] !== 'pending') continue;
426
+ if (!plan.tasks[id].dependsOn.every(dep => states[dep] === 'verified')) continue;
427
+ if ([...active.keys()].some(other => overlaps(scopes[id], scopes[other]))) continue;
428
+ for (const dependency of plan.tasks[id].dependsOn) {
429
+ const expected = verifiedInputs.get(dependency);
430
+ const currentInput = await invoke('inputRevision', {
431
+ taskId: dependency,
432
+ revision,
433
+ allowedEditScope: plan.tasks[dependency].allowedEditScope,
434
+ requiredChecks: checks[dependency],
435
+ });
436
+ if (currentInput !== expected) {
437
+ controller.abort(new Error('STALE_PREREQUISITE_EVIDENCE'));
438
+ break;
439
+ }
440
+ }
441
+ if (controller.signal.aborted) break;
442
+ if ((await reviewPriority(root, { task: id })).status !== 'pass') continue;
443
+ active.set(id, runTask(id).then(() => id));
444
+ scheduled = true;
445
+ }
446
+ if (active.size) {
447
+ const completed = await Promise.race(active.values());
448
+ active.delete(completed);
449
+ continue;
450
+ }
451
+ if (!scheduled) break;
452
+ }
453
+ // Cancellation stops new scheduling, but active work may still be draining
454
+ // its journal and checkpoint operations. Do not close the runtime ledger
455
+ // or return while a sibling can still write into the feature directory.
456
+ if (active.size) await Promise.allSettled([...active.values()]);
457
+ // The abort race stops scheduling promptly, but a trusted adapter may
458
+ // still be delivering cancellation. Give it a bounded drain window and
459
+ // report when it has not settled; recovery must then inspect the worker.
460
+ const adapterCallsSettled = await drainAdapterCalls();
461
+ const verified = ids.filter(id => states[id] === 'verified');
462
+ const status = !controller.signal.aborted && ids.every(id => states[id] === 'verified') ? 'verified' : 'incomplete';
463
+ // Task verification is not the feature/release outcome gate.
464
+ const result = { status, states, verified, calls, attempts, revision, cost: null, adapterCallsSettled,
465
+ nativeQualification: 'not-established', featureComplete: false };
466
+ await record({ event: 'finished', ...result });
467
+ await checkpoint('finished');
468
+ return result;
469
+ } finally {
470
+ controller.abort(new Error('RUN_CLOSED'));
471
+ if (!drainAttempted) await drainAdapterCalls();
472
+ clearTimeout(timer);
473
+ signal?.removeEventListener('abort', cancel);
474
+ // A journal failure must still drain checkpoint writes before callers or
475
+ // tests can remove the feature directory. Preserve the journal failure
476
+ // while ensuring no asynchronous checkpoint writer survives teardown.
477
+ try { await write; } finally {
478
+ try { await checkpointWrite; } finally {
479
+ await file.close();
480
+ if (resumeLock) releaseResumeLock(resumeLock);
481
+ }
482
+ }
483
+ }
484
+ }
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Human-run ceremony that creates the benchmark verifier's signing key.
4
+ *
5
+ * It generates a fresh Ed25519 key, encrypts it with a passphrase you type,
6
+ * and stores only the encrypted envelope. It never registers the key: trust
7
+ * comes from a root-owned registry file that only an administrator can write,
8
+ * so this tool prints the exact commands and changes nothing outside your
9
+ * trust folder. Run it in a terminal yourself. Do not run it through an agent.
10
+ */
11
+ import { createHash, generateKeyPairSync, randomUUID } from 'node:crypto';
12
+ import { constants } from 'node:fs';
13
+ import { lstat, mkdir, open } from 'node:fs/promises';
14
+ import path from 'node:path';
15
+ import { fileURLToPath } from 'node:url';
16
+ import { assertStrongPassphrase, encryptSigningKey } from './gofer-encrypted-key.mjs';
17
+ import { VERIFIER_EVALUATOR, accountTrustRoot, protectedVerifierRegistryPath } from './gofer-trusted-evaluator.mjs';
18
+ import { promptHidden } from './gofer-tty-prompt.mjs';
19
+
20
+ const denied = () => new Error('VERIFIER_KEY_CEREMONY_REQUIRES_REVIEW');
21
+ const shellQuote = value => `'${value.replaceAll("'", "'\"'\"'")}'`;
22
+
23
+ async function writeExclusive(filename, value) {
24
+ const file = await open(filename, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL |
25
+ constants.O_NOFOLLOW, 0o600);
26
+ try { await file.writeFile(value, 'utf8'); await file.sync(); } finally { await file.close(); }
27
+ }
28
+
29
+ async function requireUninitializedRegistry(registryPath) {
30
+ try {
31
+ await lstat(registryPath);
32
+ } catch (error) {
33
+ if (error?.code === 'ENOENT') return;
34
+ throw denied();
35
+ }
36
+ throw denied();
37
+ }
38
+
39
+ /** First-key setup only: an installed registry requires reviewed rotation. */
40
+ export async function runVerifierKeyCeremony({ trustRoot, getPassphrase, existingEntries,
41
+ keyId = `heldout-verifier-${randomUUID()}`, registryPath = protectedVerifierRegistryPath() } = {}) {
42
+ if (!path.isAbsolute(trustRoot ?? '') || typeof getPassphrase !== 'function' ||
43
+ !path.isAbsolute(registryPath) || !/^[a-zA-Z0-9._-]{8,80}$/.test(keyId) ||
44
+ existingEntries !== undefined) throw denied();
45
+ await requireUninitializedRegistry(registryPath);
46
+ const rootInfo = await lstat(trustRoot);
47
+ if (!rootInfo.isDirectory() || rootInfo.uid !== process.getuid() || (rootInfo.mode & 0o077) !== 0) throw denied();
48
+ const active = path.join(trustRoot, 'active-keys');
49
+ await mkdir(active, { mode: 0o700, recursive: true });
50
+ const activeInfo = await lstat(active);
51
+ if (!activeInfo.isDirectory() || activeInfo.uid !== process.getuid() || (activeInfo.mode & 0o077) !== 0) throw denied();
52
+
53
+ const passphrase = await getPassphrase('New verifier passphrase (12+ characters): ');
54
+ assertStrongPassphrase(passphrase);
55
+ if (passphrase !== await getPassphrase('Repeat the passphrase: ')) throw denied();
56
+ await requireUninitializedRegistry(registryPath);
57
+
58
+ const pair = generateKeyPairSync('ed25519');
59
+ const publicKeyPem = pair.publicKey.export({ type: 'spki', format: 'pem' }).toString();
60
+ const envelope = await encryptSigningKey(pair.privateKey, passphrase);
61
+ // O_EXCL: an existing verifier identity is never replaced.
62
+ await writeExclusive(path.join(active, 'heldout-verifier.private.enc.json'), `${JSON.stringify(envelope)}\n`);
63
+ await writeExclusive(path.join(active, 'heldout-verifier.json'), `${JSON.stringify({ schemaVersion: 1,
64
+ host: 'codex', evaluator: VERIFIER_EVALUATOR, keyId })}\n`);
65
+ const pendingPath = path.join(trustRoot, 'verifier-registry.pending.json');
66
+ const pendingBytes = `${JSON.stringify({ schemaVersion: 1, evaluators: [
67
+ { keyId, host: 'codex', evaluator: VERIFIER_EVALUATOR, publicKeyPem }] }, null, 2)}\n`;
68
+ await writeExclusive(pendingPath, pendingBytes);
69
+ const pendingSha256 = createHash('sha256').update(pendingBytes, 'utf8').digest('hex');
70
+ const directory = path.dirname(registryPath);
71
+ const stageTemplate = path.join(directory, `${path.basename(registryPath)}.${keyId}.XXXXXX`);
72
+ const installScript = [
73
+ 'set -eu',
74
+ 'PATH=/usr/bin:/bin; export PATH',
75
+ `stage=$(mktemp ${shellQuote(stageTemplate)})`,
76
+ `trap 'rm -f -- "$stage"' EXIT`,
77
+ `install -o root -m 0600 ${shellQuote(pendingPath)} "$stage"`,
78
+ // SECURITY: Check the root-owned copy against ceremony bytes, not the mutable pending file.
79
+ 'if command -v sha256sum >/dev/null 2>&1; then staged_hash=$(sha256sum < "$stage"); elif command -v shasum >/dev/null 2>&1; then staged_hash=$(shasum -a 256 < "$stage"); else exit 1; fi',
80
+ `[ "\${staged_hash%% *}" = ${shellQuote(pendingSha256)} ]`,
81
+ 'chmod 0644 "$stage"',
82
+ `link "$stage" ${shellQuote(registryPath)}`,
83
+ ].join('; ');
84
+ return Object.freeze({ keyId, publicKeyPem, pendingPath, installCommands: Object.freeze([
85
+ `sudo /bin/mkdir -p ${shellQuote(directory)}`,
86
+ `sudo /bin/sh -c ${shellQuote(installScript)}`,
87
+ ]) });
88
+ }
89
+
90
+ if (process.argv[1] && fileURLToPath(import.meta.url) === path.resolve(process.argv[1])) {
91
+ if (process.argv.length !== 2) throw denied();
92
+ runVerifierKeyCeremony({ trustRoot: accountTrustRoot(), getPassphrase: promptHidden })
93
+ .then(result => {
94
+ process.stdout.write(`\nVerifier key created (encrypted). Key id: ${result.keyId}\n\n` +
95
+ 'It is NOT trusted yet. An administrator must install the registry:\n\n' +
96
+ `${result.installCommands.map(command => ` ${command}`).join('\n')}\n\n` +
97
+ 'Then delete the old plaintext verifier key, which a worker can read:\n\n' +
98
+ ' rm ~/.eai-gofer-trust/staged-keys/heldout-verifier.private.pem\n');
99
+ })
100
+ .catch(error => { process.stderr.write(`${error.message}\n`); process.exitCode = 1; });
101
+ }
@@ -0,0 +1,32 @@
1
+ /** Shared checks about where a task worktree and its Git store live. */
2
+ import { spawnSync } from 'node:child_process';
3
+ import { realpathSync } from 'node:fs';
4
+ import path from 'node:path';
5
+
6
+ const text = value => typeof value === 'string' && value.trim().length > 0;
7
+ const gitEnvironment = Object.fromEntries(Object.entries(process.env)
8
+ .filter(([key]) => !key.startsWith('GIT_')));
9
+
10
+ export const insideDirectory = (parent, child) => {
11
+ const relative = path.relative(parent, child);
12
+ return relative === '' || (relative !== '..' && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative));
13
+ };
14
+
15
+ /** The shared Git store of a linked worktree, or null. A plain repository is
16
+ * refused: its Git store lies inside the workspace, so it cannot be protected. */
17
+ export function sharedGitDirectory(workspaceRoot) {
18
+ if (!text(workspaceRoot)) return null;
19
+ const result = spawnSync('/usr/bin/git', ['-C', workspaceRoot, 'rev-parse', '--path-format=absolute',
20
+ '--show-toplevel', '--git-dir', '--git-common-dir'],
21
+ { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], timeout: 5000, env: gitEnvironment });
22
+ if (result.status !== 0 || !result.stdout?.trim()) return null;
23
+ const [topLevel, gitDirectory, commonDirectory] = result.stdout.trim().split('\n');
24
+ if (!topLevel || !gitDirectory || !commonDirectory) return null;
25
+ try {
26
+ const workspace = realpathSync(workspaceRoot);
27
+ const common = realpathSync(commonDirectory);
28
+ if (realpathSync(topLevel) !== workspace || realpathSync(gitDirectory) === common ||
29
+ insideDirectory(workspace, common)) return null;
30
+ return common;
31
+ } catch { return null; }
32
+ }