@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,567 @@
1
+ /** Native adapter primitives. They create real Git worktree isolation and
2
+ * require a ledger authority record before a host integration can start work. */
3
+ import { execFile, spawn } from 'node:child_process';
4
+ import { mkdtemp, mkdir, open, readFile, readdir, realpath } from 'node:fs/promises';
5
+ import { constants } from 'node:fs';
6
+ import { tmpdir } from 'node:os';
7
+ import path from 'node:path';
8
+ import { promisify } from 'node:util';
9
+ import { createHash, randomUUID } from 'node:crypto';
10
+ import { capabilityReceiptHash, verifyCapabilityReceipt } from './gofer-host-capability.mjs';
11
+ import { codexIsolatedPermissionArgs, verifyLocalIsolationReport } from './gofer-local-isolation.mjs';
12
+
13
+ const execFileAsync = promisify(execFile);
14
+ const text = value => typeof value === 'string' && value.trim().length > 0;
15
+ const QUALIFIED_LOCAL_ISOLATION = 'git-worktree+local-os-sandbox';
16
+ function processGroupAlive(processGroupId) {
17
+ try { process.kill(-processGroupId, 0); return true; }
18
+ catch (error) { return error?.code !== 'ESRCH'; }
19
+ }
20
+ const sameScope = (left, right) => Array.isArray(left) && Array.isArray(right) &&
21
+ left.length === right.length && left.every((value, index) => value === right[index]);
22
+ const gitEnvironment = Object.fromEntries(Object.entries(process.env).filter(([key]) =>
23
+ !['GIT_DIR', 'GIT_WORK_TREE', 'GIT_INDEX_FILE', 'GIT_COMMON_DIR'].includes(key)));
24
+
25
+ async function git(directory, args) {
26
+ return execFileAsync('git', ['-C', directory, ...args], { encoding: 'utf8', env: gitEnvironment });
27
+ }
28
+
29
+ function safeScope(scope) {
30
+ return text(scope) && !/(^\/|\\|\0|(^|\/)\.\.?(?:\/|$))/.test(scope);
31
+ }
32
+
33
+ function boundedCollector(limit = 1024 * 1024) {
34
+ let value = '';
35
+ return {
36
+ add(chunk) { value = `${value}${chunk}`.slice(-limit); },
37
+ value: () => value,
38
+ };
39
+ }
40
+
41
+ function tokenUsage(value) {
42
+ if (!value || typeof value !== 'object') return null;
43
+ const inputTokens = value.input_tokens ?? value.inputTokens;
44
+ const cachedInputTokens = value.cached_input_tokens ?? value.cachedInputTokens ?? 0;
45
+ const outputTokens = value.output_tokens ?? value.outputTokens;
46
+ if (![inputTokens, cachedInputTokens, outputTokens].every(item => Number.isInteger(item) && item >= 0)) return null;
47
+ return Object.freeze({ inputTokens, cachedInputTokens, outputTokens });
48
+ }
49
+
50
+ function extractTokenUsage(jsonl) {
51
+ const findings = [];
52
+ const visit = value => {
53
+ if (!value || typeof value !== 'object') return;
54
+ const direct = tokenUsage(value);
55
+ if (direct) findings.push(direct);
56
+ for (const item of Object.values(value)) visit(item);
57
+ };
58
+ for (const line of jsonl.split(/\r?\n/)) {
59
+ try { visit(JSON.parse(line)); } catch { /* Non-JSON host diagnostics are not usage evidence. */ }
60
+ }
61
+ return findings.at(-1) ?? null;
62
+ }
63
+
64
+ /** The Codex host profile: what differs between hosts is only how a host is
65
+ * launched, how its sandbox is described, and how its result is read. The
66
+ * process-group evidence, Git baseline and scope checks are shared. */
67
+ export const CODEX_HOST = Object.freeze({
68
+ name: 'codex',
69
+ sandboxPolicy: workspace => codexIsolatedPermissionArgs(workspace),
70
+ buildArgs: ({ sandboxPolicy, outputPath, modelId, prompt }) => ['--ask-for-approval', 'never', 'exec',
71
+ '--ignore-user-config', ...sandboxPolicy.config.flatMap(value => ['-c', value]),
72
+ '--json', '--output-last-message', outputPath, '--model', modelId, prompt],
73
+ finalMessage: ({ outputPath }) => readFile(outputPath, 'utf8').catch(() => ''),
74
+ extractUsage: stdoutText => extractTokenUsage(stdoutText),
75
+ });
76
+
77
+ /**
78
+ * Start a real local host process in a pre-created isolated worktree. This
79
+ * primitive deliberately has no fallback host or cloud mode. Its receipt is
80
+ * only available after the child has exited, so a cancellation cannot be
81
+ * reported as confirmed while the host still owns the worktree.
82
+ */
83
+ export async function startLocalHostInvocation({ host, isolatedWorkspace, prompt, modelId,
84
+ capabilityReceiptHash, allowedWriteScope, command, spawnProcess = spawn,
85
+ receiptDirectory = tmpdir(), evidenceDirectory, objectiveRevision, leaseId,
86
+ worktreeReceipt, expectedHead, signalProcessGroup = (pid, signal) => process.kill(-pid, signal),
87
+ usageReporting = false, hostOptions = {} } = {}) {
88
+ if (!/^[a-z]{3,16}$/.test(host?.name ?? '') || typeof host.sandboxPolicy !== 'function' ||
89
+ typeof host.buildArgs !== 'function' || typeof host.finalMessage !== 'function' ||
90
+ typeof host.extractUsage !== 'function') throw new Error('INVALID_NATIVE_HOST');
91
+ if (!text(isolatedWorkspace) || !text(prompt) || !text(modelId) || !text(capabilityReceiptHash) ||
92
+ !Array.isArray(allowedWriteScope) || !allowedWriteScope.length ||
93
+ allowedWriteScope.some(scope => !safeScope(scope)) || !text(command) ||
94
+ (evidenceDirectory && (![objectiveRevision, leaseId, worktreeReceipt].every(text)))) throw new Error('INVALID_NATIVE_REQUEST');
95
+ const workspace = await realpath(isolatedWorkspace);
96
+ const sandboxPolicy = host.sandboxPolicy(workspace, hostOptions);
97
+ if (!sandboxPolicy) throw new Error('LOCAL_SANDBOX_REQUIRED');
98
+ const outputRoot = await realpath(receiptDirectory);
99
+ // A clean file-status result does not reveal a commit or a new branch made
100
+ // by the worker. Capture both HEAD and shared refs before native execution.
101
+ const gitBaseline = await Promise.all([
102
+ git(workspace, ['rev-parse', 'HEAD']),
103
+ git(workspace, ['for-each-ref', '--format=%(refname) %(objectname)']),
104
+ ]).then(([head, refs]) => ({ head: head.stdout.trim(), refs: refs.stdout })).catch(() => null);
105
+ if (expectedHead && gitBaseline?.head !== expectedHead) throw new Error('NATIVE_GIT_BASELINE_MISMATCH');
106
+ let evidenceRoot;
107
+ if (evidenceDirectory) {
108
+ if (process.platform === 'win32') throw new Error('NATIVE_PROCESS_GROUP_UNAVAILABLE');
109
+ const requested = path.join(await realpath(path.dirname(path.resolve(evidenceDirectory))),
110
+ path.basename(evidenceDirectory));
111
+ const requestedRelative = path.relative(workspace, requested);
112
+ if (requestedRelative === '' || (!requestedRelative.startsWith('..') && !path.isAbsolute(requestedRelative))) {
113
+ throw new Error('NATIVE_EVIDENCE_INSIDE_WORKTREE');
114
+ }
115
+ await mkdir(evidenceDirectory, { recursive: true, mode: 0o700 });
116
+ evidenceRoot = await realpath(evidenceDirectory);
117
+ const relative = path.relative(workspace, evidenceRoot);
118
+ if (relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative))) {
119
+ throw new Error('NATIVE_EVIDENCE_INSIDE_WORKTREE');
120
+ }
121
+ }
122
+ const outputPath = path.join(outputRoot, `gofer-${host.name}-${randomUUID()}.md`);
123
+ const args = host.buildArgs({ sandboxPolicy, outputPath, modelId, prompt, allowedWriteScope,
124
+ workspace, hostOptions });
125
+ const stdout = boundedCollector();
126
+ const stderr = boundedCollector();
127
+ let child;
128
+ let exit = null;
129
+ let cancelRequested = false;
130
+ let fatal = null;
131
+ let completion;
132
+ const invocationId = `${host.name}-${randomUUID()}`;
133
+ const evidencePath = evidenceRoot ? path.join(evidenceRoot, `native-worker-${invocationId}.jsonl`) : null;
134
+ const receiptFor = async () => {
135
+ const message = await host.finalMessage({ outputPath, stdout: stdout.value() });
136
+ return createHash('sha256').update(JSON.stringify({ invocationId, capabilityReceiptHash, modelId,
137
+ allowedWriteScope, exit, stdout: stdout.value(), stderr: stderr.value(), message })).digest('hex');
138
+ };
139
+ // A host may write a per-task policy file before it starts.
140
+ await host.beforeStart?.({ workspace, sandboxPolicy, hostOptions });
141
+ try {
142
+ child = spawnProcess(command, args, { cwd: workspace, shell: false, detached: Boolean(evidenceRoot),
143
+ stdio: ['ignore', 'pipe', 'pipe'], windowsHide: true,
144
+ ...(typeof host.env === 'function' ? { env: host.env(process.env) } : {}) });
145
+ } catch (error) {
146
+ throw new Error(`NATIVE_HOST_START_FAILED:${error.message}`);
147
+ }
148
+ if (!child || typeof child.once !== 'function' || typeof child.kill !== 'function') throw new Error('NATIVE_HOST_START_FAILED');
149
+ if (evidencePath && (!Number.isSafeInteger(child.pid) || child.pid <= 0)) {
150
+ child.kill('SIGTERM');
151
+ throw new Error('NATIVE_PROCESS_ID_REQUIRED');
152
+ }
153
+ const startEvidence = evidencePath ? (async () => {
154
+ const file = await open(evidencePath, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 0o600);
155
+ try {
156
+ await file.writeFile(`${JSON.stringify({ schemaVersion: 1, event: 'started', invocationId,
157
+ objectiveRevision, leaseId, worktreeReceipt, capabilityReceiptHash, modelId,
158
+ isolatedWorkspace: workspace, pid: child.pid, processGroupId: child.pid,
159
+ at: new Date().toISOString() })}\n`);
160
+ await file.sync();
161
+ } finally { await file.close(); }
162
+ })() : Promise.resolve();
163
+ child.stdout?.on('data', chunk => stdout.add(chunk));
164
+ child.stderr?.on('data', chunk => {
165
+ stderr.add(chunk);
166
+ // A sandbox that fails to apply must never be allowed to run unsandboxed.
167
+ if (!fatal && host.fatalStderr?.test(String(chunk))) {
168
+ fatal = 'NATIVE_HOST_SANDBOX_NOT_APPLIED';
169
+ // A single group signal can miss a child that was starting at that moment,
170
+ // so keep killing until the group is empty.
171
+ (async () => {
172
+ for (let attempt = 0; attempt < 30; attempt++) {
173
+ try { if (evidencePath) signalProcessGroup(child.pid, 'SIGKILL'); else child.kill('SIGKILL'); } catch { /* already gone */ }
174
+ await new Promise(resolve => setTimeout(resolve, 50));
175
+ if (evidencePath ? !processGroupAlive(child.pid) : exit !== null) return;
176
+ }
177
+ })();
178
+ }
179
+ });
180
+ completion = new Promise((resolve, reject) => {
181
+ child.once('error', error => reject(new Error(`NATIVE_HOST_START_FAILED:${error.message}`)));
182
+ child.once('close', async (code, signal) => {
183
+ exit = { code, signal };
184
+ // The host has stopped: remove anything it needed from the worktree.
185
+ try { await host.cleanup?.({ workspace, sandboxPolicy, hostOptions }); } catch { /* reported by the scope check */ }
186
+ try {
187
+ await startEvidence;
188
+ if (evidencePath) {
189
+ const file = await open(evidencePath, constants.O_WRONLY | constants.O_APPEND | constants.O_NOFOLLOW);
190
+ try {
191
+ await file.writeFile(`${JSON.stringify({ schemaVersion: 1, event: 'stopped', invocationId,
192
+ pid: child.pid, processGroupId: child.pid, cancelled: cancelRequested, exit, receipt: await receiptFor(),
193
+ at: new Date().toISOString() })}\n`);
194
+ await file.sync();
195
+ } finally { await file.close(); }
196
+ }
197
+ resolve();
198
+ } catch (error) { reject(error); }
199
+ });
200
+ });
201
+ await startEvidence.catch(error => {
202
+ if (evidencePath) signalProcessGroup(child.pid, 'SIGTERM');
203
+ else child.kill('SIGTERM');
204
+ throw new Error(`NATIVE_EVIDENCE_UNAVAILABLE:${error.message}`);
205
+ });
206
+ return Object.freeze({
207
+ invocationId,
208
+ evidencePath,
209
+ async cancel() {
210
+ if (exit !== null) throw new Error('CANCELLATION_ALREADY_EXITED');
211
+ cancelRequested = true;
212
+ if (exit === null) {
213
+ try {
214
+ if (evidencePath) signalProcessGroup(child.pid, 'SIGTERM');
215
+ else if (child.kill('SIGTERM') === false) throw new Error('CANCELLATION_DELIVERY_REQUIRED');
216
+ } catch { throw new Error('CANCELLATION_DELIVERY_REQUIRED'); }
217
+ }
218
+ await completion;
219
+ if (evidencePath) {
220
+ for (let attempt = 0; attempt < 20 && processGroupAlive(child.pid); attempt++) {
221
+ await new Promise(resolve => setTimeout(resolve, 100));
222
+ }
223
+ if (processGroupAlive(child.pid)) throw new Error('CANCELLATION_CONFIRMATION_REQUIRED');
224
+ }
225
+ },
226
+ async inspect() {
227
+ if (exit === null) return { invocationId, cancelled: false, receipt: null, state: 'running' };
228
+ await completion;
229
+ if (evidencePath && processGroupAlive(child.pid)) {
230
+ return { invocationId, cancelled: false, receipt: null, state: 'unresolved' };
231
+ }
232
+ return { invocationId, cancelled: cancelRequested, receipt: await receiptFor(), state: 'exited', exit: { ...exit } };
233
+ },
234
+ async wait() {
235
+ await completion;
236
+ const receipt = await receiptFor();
237
+ if (cancelRequested) {
238
+ if (evidencePath && processGroupAlive(child.pid)) throw new Error('CANCELLATION_CONFIRMATION_REQUIRED');
239
+ return { invocationId, capabilityReceiptHash, receipt, cancelled: true };
240
+ }
241
+ if (fatal) throw new Error(fatal);
242
+ if (exit?.code !== 0) throw new Error(`NATIVE_HOST_EXIT:${exit?.code ?? 'signal'}`);
243
+ host.assertSuccess?.(stdout.value(), stderr.value());
244
+ if (!gitBaseline) throw new Error('NATIVE_GIT_BASELINE_REQUIRED');
245
+ const [head, refs] = await Promise.all([
246
+ git(workspace, ['rev-parse', 'HEAD']),
247
+ git(workspace, ['for-each-ref', '--format=%(refname) %(objectname)']),
248
+ ]);
249
+ if (head.stdout.trim() !== gitBaseline.head || refs.stdout !== gitBaseline.refs) {
250
+ throw new Error('NATIVE_UNAUTHORIZED_GIT_CHANGE');
251
+ }
252
+ await host.afterExit?.({ workspace, sandboxPolicy, hostOptions });
253
+ const status = await git(workspace, ['-c', 'status.renames=false', 'status', '--porcelain=v1', '-z',
254
+ '--untracked-files=all', '--ignored=matching']);
255
+ const entries = status.stdout.split('\0').filter(Boolean);
256
+ if (entries.some(entry => entry.length < 4 || entry[2] !== ' ')) throw new Error('NATIVE_STATUS_UNAVAILABLE');
257
+ const changedFiles = [...new Set(entries.map(entry => entry.slice(3)))];
258
+ if (changedFiles.some(file => !allowedWriteScope.some(scope => file === scope.replace(/\/$/, '') || file.startsWith(`${scope.replace(/\/$/, '')}/`)))) {
259
+ throw new Error('NATIVE_SCOPE_VIOLATION');
260
+ }
261
+ return Object.freeze({ invocationId, capabilityReceiptHash, receipt, changedFiles,
262
+ outputPath, isolation: QUALIFIED_LOCAL_ISOLATION,
263
+ usage: usageReporting ? host.extractUsage(stdout.value()) : undefined });
264
+ },
265
+ });
266
+ }
267
+
268
+ /** Start a real local Codex process. Kept as the stable entry point. */
269
+ export function startLocalCodexInvocation(options = {}) {
270
+ return startLocalHostInvocation({ ...options, host: CODEX_HOST, command: options.command ?? 'codex' });
271
+ }
272
+
273
+ /** A missing, incomplete, or still-running process never becomes a stop proof. */
274
+ export async function inspectNativeWorkerEvidence({ evidenceDirectory, revision, journalHash,
275
+ authorizations, probeProcess = processGroupId => {
276
+ if (process.platform === 'win32') return true;
277
+ return processGroupAlive(processGroupId);
278
+ } } = {}) {
279
+ const denied = { allStopped: false, revision, journalHash, receipt: null };
280
+ if (![evidenceDirectory, revision, journalHash].every(text) || !Array.isArray(authorizations) ||
281
+ !authorizations.length || typeof probeProcess !== 'function') return denied;
282
+ let root;
283
+ try { root = await realpath(evidenceDirectory); } catch { return denied; }
284
+ const names = await readdir(root);
285
+ if (names.length > 1000 || names.some(name => !/^native-worker-(?:codex|claude|grok)-[0-9a-f-]+\.jsonl$/.test(name))) return denied;
286
+ const records = [];
287
+ for (const name of names) {
288
+ const file = await open(path.join(root, name), constants.O_RDONLY | constants.O_NOFOLLOW).catch(() => null);
289
+ if (!file) return denied;
290
+ let raw;
291
+ try {
292
+ const stat = await file.stat();
293
+ if (!stat.isFile() || stat.size > 65536) return denied;
294
+ raw = await file.readFile('utf8');
295
+ } finally { await file.close(); }
296
+ if (!raw.endsWith('\n')) return denied;
297
+ let events;
298
+ try { events = raw.trimEnd().split('\n').map(line => JSON.parse(line)); }
299
+ catch { return denied; }
300
+ if (events.length !== 2 || events[0]?.schemaVersion !== 1 || events[0].event !== 'started' ||
301
+ events[1]?.schemaVersion !== 1 || events[1].event !== 'stopped' ||
302
+ events[0].invocationId !== events[1].invocationId ||
303
+ events[0].pid !== events[1].pid || !Number.isSafeInteger(events[0].pid) || events[0].pid <= 0 ||
304
+ events[0].processGroupId !== events[0].pid || events[1].processGroupId !== events[0].pid ||
305
+ !text(events[1].receipt) || events[0].objectiveRevision !== revision) return denied;
306
+ if (await probeProcess(events[0].processGroupId) !== false) return denied;
307
+ records.push({ started: events[0], stopped: events[1] });
308
+ }
309
+ if (!records.length || authorizations.some(authority =>
310
+ !text(authority?.leaseId) || !text(authority?.worktreeReceipt) ||
311
+ records.filter(record => record.started.leaseId === authority.leaseId &&
312
+ record.started.capabilityReceiptHash === authority.capabilityReceiptHash &&
313
+ record.started.worktreeReceipt === authority.worktreeReceipt &&
314
+ (!authority.isolatedWorkspace || record.started.isolatedWorkspace === authority.isolatedWorkspace)).length !== 1)) return denied;
315
+ const receipt = `worker-stop:${createHash('sha256').update(JSON.stringify({ revision, journalHash,
316
+ records: records.map(record => ({ invocationId: record.started.invocationId,
317
+ leaseId: record.started.leaseId, pid: record.started.pid,
318
+ cancelled: record.stopped.cancelled, receipt: record.stopped.receipt }))
319
+ .sort((left, right) => left.invocationId.localeCompare(right.invocationId)) })).digest('hex')}`;
320
+ return { allStopped: true, revision, journalHash, receipt, workerCount: records.length,
321
+ cancelledLeases: records.filter(record => record.stopped.cancelled === true).map(record => record.started.leaseId) };
322
+ }
323
+
324
+ /** Bind benchmark capture to the controller-owned worker evidence directory.
325
+ * Workers cannot choose the directory or declare their own stopped state. */
326
+ export function createNativeBenchmarkCaptureVerifier({ evidenceDirectory } = {}) {
327
+ if (!text(evidenceDirectory) || !path.isAbsolute(evidenceDirectory)) {
328
+ throw new Error('BENCHMARK_CAPTURE_EVIDENCE_REQUIRED');
329
+ }
330
+ return request => inspectNativeWorkerEvidence({ evidenceDirectory,
331
+ revision: request?.revision, journalHash: request?.journalHash,
332
+ authorizations: request?.runs?.map(run => ({ leaseId: run.leaseId,
333
+ capabilityReceiptHash: run.capabilityReceiptHash,
334
+ worktreeReceipt: run.worktreeReceipt,
335
+ isolatedWorkspace: run.isolatedWorkspace })) });
336
+ }
337
+
338
+ /**
339
+ * Adapt the verified graph's `execute` seam to a real Codex invocation. The
340
+ * caller supplies the durable ledger assertion; this adapter refuses to run
341
+ * if it cannot reproduce the graph's just-issued authority receipt. This
342
+ * prevents a caller from substituting a safe-looking local launcher after
343
+ * the graph has authorised a different task, scope, lease, or approval.
344
+ */
345
+ export function createLedgerBoundCodexExecutor({ isolatedWorkspace, worktreeReceipt, expectedHead, capabilityReceipt, capabilityPublicKey,
346
+ requiredCapabilities, assertLedger, promptForRequest, start = startLocalCodexInvocation } = {}) {
347
+ if (!text(isolatedWorkspace) || !text(worktreeReceipt) || !capabilityReceipt || !capabilityPublicKey ||
348
+ typeof assertLedger !== 'function' || typeof promptForRequest !== 'function' || typeof start !== 'function') {
349
+ throw new Error('NATIVE_EXECUTOR_CONFIGURATION_REQUIRED');
350
+ }
351
+ return Object.freeze({
352
+ worktreeReceipt,
353
+ async execute(request) {
354
+ if (!request || !text(request.revision) || !text(request.taskId) || !text(request.ledgerAuthorityReceipt) ||
355
+ !text(request.selectedModel) || !Array.isArray(request.allowedEditScope) ||
356
+ request.worktreeReceipt !== worktreeReceipt) throw new Error('LEDGER_AUTHORITY_REQUIRED');
357
+ const prompt = await promptForRequest(Object.freeze({ ...request }));
358
+ if (!text(prompt)) throw new Error('NATIVE_PROMPT_REQUIRED');
359
+ return invokeLedgerBoundNative({
360
+ request: {
361
+ objectiveRevision: request.revision,
362
+ allowedWriteScope: request.allowedEditScope,
363
+ leaseId: request.leaseId,
364
+ budgetReservation: request.budgetReservation,
365
+ approvalReceipt: request.approvalReceipt,
366
+ worktreeReceipt,
367
+ usageReporting: request.usageReporting === true,
368
+ },
369
+ capabilityReceipt,
370
+ capabilityPublicKey,
371
+ requiredCapabilities,
372
+ assertLedger: async nativeRequest => {
373
+ const authority = await assertLedger(Object.freeze({ ...request, ...nativeRequest }));
374
+ if (authority?.receipt !== request.ledgerAuthorityReceipt) throw new Error('LEDGER_AUTHORITY_REQUIRED');
375
+ return authority;
376
+ },
377
+ start: nativeRequest => start({ isolatedWorkspace, expectedHead, prompt, modelId: request.selectedModel,
378
+ allowedWriteScope: request.allowedEditScope, ...nativeRequest }),
379
+ signal: request.signal,
380
+ });
381
+ },
382
+ });
383
+ }
384
+
385
+ export async function createVerifiedWorktree({ workspaceRoot, host, localIsolation, baseRef = 'HEAD', temporaryRoot = tmpdir() } = {}) {
386
+ if (!text(workspaceRoot) || !text(baseRef) || baseRef.startsWith('-')) throw new Error('INVALID_ISOLATION_REQUEST');
387
+ if (typeof localIsolation !== 'function') throw new Error('LOCAL_SANDBOX_REQUIRED');
388
+ const workspace = await realpath(workspaceRoot);
389
+ const temporary = await realpath(temporaryRoot);
390
+ const relativeTemporary = path.relative(workspace, temporary);
391
+ if (relativeTemporary === '' || (!relativeTemporary.startsWith('..') && !path.isAbsolute(relativeTemporary))) {
392
+ throw new Error('ISOLATION_ROOT_INSIDE_WORKSPACE');
393
+ }
394
+ const repository = (await git(workspace, ['rev-parse', '--is-inside-work-tree'])).stdout.trim();
395
+ if (repository !== 'true') throw new Error('WORKSPACE_IS_NOT_GIT');
396
+ const destination = await mkdtemp(path.join(temporary, 'gofer-isolated-worktree-'));
397
+ try {
398
+ await git(workspace, ['worktree', 'add', '--detach', destination, baseRef]);
399
+ const isolated = await realpath(destination);
400
+ if (isolated === workspace) throw new Error('ISOLATION_PATH_REUSED');
401
+ const [head, expected] = await Promise.all([
402
+ git(isolated, ['rev-parse', 'HEAD']), git(workspace, ['rev-parse', baseRef]),
403
+ ]);
404
+ if (head.stdout.trim() !== expected.stdout.trim()) throw new Error('ISOLATION_REVISION_MISMATCH');
405
+ const report = await localIsolation(Object.freeze({ host, workspaceRoot: isolated }));
406
+ if (!verifyLocalIsolationReport(report, { host, workspaceRoot: isolated }) ||
407
+ !text(report.nativeExecutable) || !path.isAbsolute(report.nativeExecutable)) {
408
+ throw new Error('LOCAL_SANDBOX_REQUIRED');
409
+ }
410
+ const status = await git(isolated, ['status', '--porcelain=v1', '--untracked-files=all', '--ignored=matching']);
411
+ if (status.stdout.trim() !== '') throw new Error('ISOLATION_PREFLIGHT_CHANGED_WORKTREE');
412
+ const receipt = worktreeReceipt(workspace, isolated, head.stdout.trim());
413
+ return Object.freeze({ isolationClass: 'git-worktree+local-os-sandbox', workspace, isolatedWorkspace: isolated,
414
+ nativeExecutable: report.nativeExecutable, revision: head.stdout.trim(), receipt });
415
+ } catch (error) {
416
+ await git(workspace, ['worktree', 'remove', '--force', destination]).catch(() => {});
417
+ throw error;
418
+ }
419
+ }
420
+
421
+ function worktreeReceipt(workspace, isolated, revision) {
422
+ return `git-worktree:${createHash('sha256').update(JSON.stringify({ workspace, isolated, revision })).digest('hex')}`;
423
+ }
424
+
425
+ /** Recheck a worktree before it is named in a cancellation reconciliation. */
426
+ export async function inspectVerifiedWorktree({ workspaceRoot, isolatedWorkspace, revision, receipt, requireClean = false } = {}) {
427
+ if (![workspaceRoot, isolatedWorkspace, revision, receipt].every(text)) return { valid: false };
428
+ const workspace = await realpath(workspaceRoot);
429
+ const isolated = await realpath(isolatedWorkspace);
430
+ if (workspace === isolated || worktreeReceipt(workspace, isolated, revision) !== receipt) return { valid: false };
431
+ const [head, listed, status] = await Promise.all([
432
+ git(isolated, ['rev-parse', 'HEAD']),
433
+ git(workspace, ['worktree', 'list', '--porcelain']),
434
+ git(isolated, ['status', '--porcelain=v1', '--untracked-files=all', '--ignored=matching']),
435
+ ]);
436
+ const comparablePath = value => process.platform === 'win32'
437
+ ? path.normalize(value.trim()).toLowerCase() : path.normalize(value.trim());
438
+ const registered = [...listed.stdout.matchAll(/^worktree (.+)$/gm)]
439
+ .some(match => comparablePath(match[1]) === comparablePath(isolated));
440
+ const clean = status.stdout.trim() === '';
441
+ if (!registered || head.stdout.trim() !== revision || (requireClean && !clean)) return { valid: false };
442
+ return Object.freeze({ valid: true, receipt, revision, isolatedWorkspace: isolated, clean,
443
+ statusHash: createHash('sha256').update(status.stdout).digest('hex') });
444
+ }
445
+
446
+ /** Remove only a matching, clean task worktree after its controller has closed. */
447
+ export async function disposeVerifiedWorktree({ workspaceRoot, isolatedWorkspace, revision, receipt } = {}) {
448
+ const inspection = await inspectVerifiedWorktree({ workspaceRoot, isolatedWorkspace,
449
+ revision, receipt, requireClean: true });
450
+ if (!inspection.valid) throw new Error('WORKTREE_DISPOSAL_REQUIRES_CLEAN_VERIFIED_STATE');
451
+ await git(workspaceRoot, ['worktree', 'remove', isolatedWorkspace]);
452
+ }
453
+
454
+ /** Bind ledger cancellation authority to independently inspected local state. */
455
+ export function createNativeCancellationVerifier({ workspaceRoot, abandonedWorkspace,
456
+ replacementWorkspace, worktreeRevision, evidenceDirectory, inspectInputRevision } = {}) {
457
+ if (![workspaceRoot, abandonedWorkspace, replacementWorkspace, worktreeRevision, evidenceDirectory].every(text) ||
458
+ typeof inspectInputRevision !== 'function') throw new Error('NATIVE_CANCELLATION_VERIFIER_CONFIGURATION_REQUIRED');
459
+ return async request => {
460
+ const denied = { valid: false };
461
+ if (![request?.taskId, request?.revision, request?.leaseId, request?.journalHash,
462
+ request?.workerStopReceipt, request?.abandonedWorktreeReceipt,
463
+ request?.replacementWorktreeReceipt, request?.capabilityReceiptHash,
464
+ request?.inputRevision].every(text)) return denied;
465
+ try {
466
+ const [oldWorktree, newWorktree, evidenceRoot] = await Promise.all([
467
+ inspectVerifiedWorktree({ workspaceRoot, isolatedWorkspace: abandonedWorkspace,
468
+ revision: worktreeRevision, receipt: request.abandonedWorktreeReceipt }),
469
+ inspectVerifiedWorktree({ workspaceRoot, isolatedWorkspace: replacementWorkspace,
470
+ revision: worktreeRevision, receipt: request.replacementWorktreeReceipt, requireClean: true }),
471
+ realpath(evidenceDirectory),
472
+ ]);
473
+ if (!oldWorktree.valid || !newWorktree.valid ||
474
+ oldWorktree.isolatedWorkspace === newWorktree.isolatedWorkspace ||
475
+ oldWorktree.receipt === newWorktree.receipt) return denied;
476
+ for (const worktree of [oldWorktree, newWorktree]) {
477
+ const relative = path.relative(worktree.isolatedWorkspace, evidenceRoot);
478
+ if (relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative))) return denied;
479
+ }
480
+ const workers = await inspectNativeWorkerEvidence({ evidenceDirectory: evidenceRoot,
481
+ revision: request.revision, journalHash: request.journalHash,
482
+ authorizations: [{ leaseId: request.leaseId,
483
+ capabilityReceiptHash: request.capabilityReceiptHash,
484
+ worktreeReceipt: request.abandonedWorktreeReceipt,
485
+ isolatedWorkspace: oldWorktree.isolatedWorkspace }] });
486
+ if (!workers.allStopped || workers.receipt !== request.workerStopReceipt ||
487
+ !workers.cancelledLeases.includes(request.leaseId)) return denied;
488
+ const currentInput = await inspectInputRevision(Object.freeze({ taskId: request.taskId,
489
+ revision: request.revision, isolatedWorkspace: newWorktree.isolatedWorkspace,
490
+ worktreeReceipt: newWorktree.receipt }));
491
+ if (currentInput !== request.inputRevision) return denied;
492
+ return { ...request, valid: true };
493
+ } catch { return denied; }
494
+ };
495
+ }
496
+
497
+ /**
498
+ * Execute only after a ledger service binds the exact objective revision,
499
+ * scope, receipt hash, lease, budget and approval state. Cancellation must be
500
+ * delivered and independently confirmed before an aborted invocation returns.
501
+ */
502
+ export async function invokeLedgerBoundNative({ request, capabilityReceipt, capabilityPublicKey,
503
+ requiredCapabilities, assertLedger, start, signal } = {}) {
504
+ if (!request || !capabilityReceipt || typeof assertLedger !== 'function' || typeof start !== 'function' ||
505
+ !text(request.objectiveRevision) || !Array.isArray(request.allowedWriteScope) || !text(request.leaseId) ||
506
+ !text(request.budgetReservation) || !text(request.approvalReceipt)) throw new Error('LEDGER_AUTHORITY_REQUIRED');
507
+ if (capabilityReceipt?.isolationClass !== QUALIFIED_LOCAL_ISOLATION ||
508
+ !verifyCapabilityReceipt(capabilityReceipt, { publicKey: capabilityPublicKey,
509
+ host: 'codex', requiredCapabilities })) {
510
+ throw new Error('CAPABILITY_RECEIPT_REQUIRED');
511
+ }
512
+ const receiptHash = capabilityReceiptHash(capabilityReceipt);
513
+ const authority = await assertLedger({ ...request, capabilityReceiptHash: receiptHash });
514
+ if (authority?.allowed !== true || authority.objectiveRevision !== request.objectiveRevision ||
515
+ authority.capabilityReceiptHash !== receiptHash || authority.leaseId !== request.leaseId ||
516
+ authority.budgetReservation !== request.budgetReservation || authority.approvalReceipt !== request.approvalReceipt ||
517
+ authority.worktreeReceipt !== request.worktreeReceipt ||
518
+ !sameScope(authority.allowedWriteScope, request.allowedWriteScope) ||
519
+ authority.isolation !== capabilityReceipt.isolationClass) {
520
+ throw new Error('LEDGER_AUTHORITY_REQUIRED');
521
+ }
522
+ const invocation = await start(Object.freeze({ ...request, capabilityReceiptHash: receiptHash }));
523
+ if (!text(invocation?.invocationId) || typeof invocation.wait !== 'function' || typeof invocation.cancel !== 'function' ||
524
+ typeof invocation.inspect !== 'function') {
525
+ if (typeof invocation?.cancel === 'function') await invocation.cancel();
526
+ if (typeof invocation?.inspect === 'function') {
527
+ const state = await invocation.inspect();
528
+ if (state?.invocationId !== invocation.invocationId || state?.cancelled !== true || !text(state?.receipt)) {
529
+ throw new Error('CANCELLATION_CONFIRMATION_REQUIRED');
530
+ }
531
+ } else if (invocation) {
532
+ throw new Error('CANCELLATION_CONFIRMATION_REQUIRED');
533
+ }
534
+ throw new Error('NATIVE_INVOCATION_REQUIRED');
535
+ }
536
+ let cancelPromise;
537
+ const cancel = () => {
538
+ if (!cancelPromise) {
539
+ cancelPromise = (async () => {
540
+ await invocation.cancel();
541
+ const state = await invocation.inspect();
542
+ if (state?.invocationId !== invocation.invocationId || state?.cancelled !== true || !text(state?.receipt)) {
543
+ throw new Error('CANCELLATION_CONFIRMATION_REQUIRED');
544
+ }
545
+ })();
546
+ }
547
+ return cancelPromise;
548
+ };
549
+ if (signal?.aborted) await cancel();
550
+ const listener = () => { cancel().catch(() => {}); };
551
+ signal?.addEventListener('abort', listener, { once: true });
552
+ try {
553
+ const result = await invocation.wait();
554
+ if (signal?.aborted) await cancel();
555
+ if (cancelPromise) {
556
+ await cancelPromise;
557
+ throw new Error('NATIVE_INVOCATION_CANCELLED');
558
+ }
559
+ if (result?.invocationId !== invocation.invocationId || result?.capabilityReceiptHash !== receiptHash || !text(result?.receipt)) {
560
+ throw new Error('NATIVE_INVOCATION_UNVERIFIED');
561
+ }
562
+ return Object.freeze({ ...result, capabilityReceiptHash: receiptHash, isolation: authority.isolation });
563
+ } finally {
564
+ signal?.removeEventListener('abort', listener);
565
+ if (cancelPromise) await cancelPromise;
566
+ }
567
+ }