@enterpriseai/cli 3.19.0 → 3.19.1

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 (362) hide show
  1. package/package.json +1 -1
  2. package/resources/gofer/.gofer-version +4 -357
  3. package/resources/gofer/agents-skills/eai/SKILL.md +365 -0
  4. package/resources/gofer/agents-skills/eai-update/SKILL.md +56 -0
  5. package/resources/gofer/agents-skills/gofer-documentation/SKILL.md +93 -0
  6. package/resources/gofer/bash-scripts/create-new-feature.sh +3 -1
  7. package/resources/gofer/bash-scripts/sync-implementation-status.sh +4 -3
  8. package/resources/gofer/bash-scripts/update-agent-context.sh +7 -8
  9. package/resources/gofer/bash-scripts/validate-artifact.sh +10 -6
  10. package/resources/gofer/bash-scripts/verify-object-type-routing-workspace.sh +184 -0
  11. package/resources/gofer/claude-commands/eai-update.md +46 -0
  12. package/resources/gofer/claude-commands/eai.md +355 -0
  13. package/resources/gofer/claude-skills/eai/SKILL.md +365 -0
  14. package/resources/gofer/claude-skills/eai-update/SKILL.md +56 -0
  15. package/resources/gofer/claude-skills/gofer-documentation/SKILL.md +93 -0
  16. package/resources/gofer/commands/0_gofer_start.md +440 -99
  17. package/resources/gofer/commands/0a_problem_validation.md +187 -27
  18. package/resources/gofer/commands/10_gofer_cloud.md +183 -23
  19. package/resources/gofer/commands/1_gofer_research.md +239 -30
  20. package/resources/gofer/commands/2_gofer_specify.md +239 -35
  21. package/resources/gofer/commands/3_gofer_plan.md +259 -43
  22. package/resources/gofer/commands/4_gofer_tasks.md +401 -81
  23. package/resources/gofer/commands/5_gofer_implement.md +375 -84
  24. package/resources/gofer/commands/6_gofer_validate.md +284 -53
  25. package/resources/gofer/commands/7_gofer_save.md +187 -26
  26. package/resources/gofer/commands/7a_stakeholder_comms.md +183 -23
  27. package/resources/gofer/commands/8_gofer_branding.md +183 -23
  28. package/resources/gofer/commands/9_gofer_tests.md +212 -23
  29. package/resources/gofer/commands/gofer_bootstrap_workspace.md +121 -8
  30. package/resources/gofer/commands/gofer_check_workspace.md +123 -8
  31. package/resources/gofer/commands/gofer_constitution.md +183 -23
  32. package/resources/gofer/commands/gofer_diagnose.md +183 -23
  33. package/resources/gofer/commands/gofer_eai_first_run.md +254 -25
  34. package/resources/gofer/commands/gofer_hydrate.md +183 -23
  35. package/resources/gofer/commands/gofer_personality.md +117 -6
  36. package/resources/gofer/commands/gofer_plan.md +117 -6
  37. package/resources/gofer/commands/gofer_side.md +117 -6
  38. package/resources/gofer/commands/gofer_spec_summary.md +183 -23
  39. package/resources/gofer/commands/gofer_tdd.md +183 -23
  40. package/resources/gofer/commands/gofer_vocabulary.md +185 -25
  41. package/resources/gofer/commands/gofer_zoom_out.md +183 -23
  42. package/resources/gofer/config/typesafe-learning-review.json +16 -0
  43. package/resources/gofer/config/typesafe-semantic-review.json +9 -0
  44. package/resources/gofer/copilot-instructions/gofer-cost.instructions.md +15 -6
  45. package/resources/gofer/copilot-instructions/typescript.instructions.md +1 -1
  46. package/resources/gofer/copilot-prompts/eai-update.prompt.md +58 -0
  47. package/resources/gofer/copilot-prompts/eai.prompt.md +367 -0
  48. package/resources/gofer/gemini/commands/gofer/eai-update.md +22 -0
  49. package/resources/gofer/gemini/commands/gofer/eai-update.toml +2 -0
  50. package/resources/gofer/gemini/commands/gofer/eai.md +357 -0
  51. package/resources/gofer/gemini/commands/gofer/eai.toml +2 -0
  52. package/resources/gofer/gemini/commands/gofer/manifest.json +3 -27
  53. package/resources/gofer/gemini/extension.json +4 -4
  54. package/resources/gofer/github-agents/eai.agent.md +83 -0
  55. package/resources/gofer/github-agents/gofer-business.agent.md +73 -4
  56. package/resources/gofer/github-agents/gofer-implement.agent.md +71 -2
  57. package/resources/gofer/github-agents/gofer-plan.agent.md +72 -2
  58. package/resources/gofer/github-agents/gofer-research.agent.md +72 -2
  59. package/resources/gofer/github-agents/gofer-validate.agent.md +72 -2
  60. package/resources/gofer/github-skills/eai/SKILL.md +365 -0
  61. package/resources/gofer/github-skills/eai-update/SKILL.md +56 -0
  62. package/resources/gofer/github-skills/gofer-documentation/SKILL.md +93 -0
  63. package/resources/gofer/grok-skills/eai/SKILL.md +267 -14
  64. package/resources/gofer/grok-skills/eai-update/SKILL.md +56 -0
  65. package/resources/gofer/hook-scripts/user-prompt-submit.mjs +58 -13
  66. package/resources/gofer/instruction-templates/base/agents-base.md +8 -4
  67. package/resources/gofer/instruction-templates/gofer/gofer-claude.md +7 -5
  68. package/resources/gofer/instruction-templates/gofer/gofer-copilot.md +10 -8
  69. package/resources/gofer/memory/constitution.md +9 -7
  70. package/resources/gofer/memory/gofer-model-policy.yaml +23 -1
  71. package/resources/gofer/memory/lessons.md +0 -31
  72. package/resources/gofer/node-scripts/canonical-descriptions.mjs +1 -1
  73. package/resources/gofer/node-scripts/check-version-alignment.mjs +4 -7
  74. package/resources/gofer/node-scripts/delivery-lineage-corpus.mjs +156 -0
  75. package/resources/gofer/node-scripts/generate-commands.mjs +1073 -265
  76. package/resources/gofer/node-scripts/gofer-acceptance-check.mjs +143 -0
  77. package/resources/gofer/node-scripts/gofer-agent-catalog.mjs +271 -0
  78. package/resources/gofer/node-scripts/gofer-benchmark-executor.mjs +123 -0
  79. package/resources/gofer/node-scripts/gofer-benchmark-sign.mjs +62 -0
  80. package/resources/gofer/node-scripts/gofer-benchmark-signer.mjs +89 -0
  81. package/resources/gofer/node-scripts/gofer-benchmark.mjs +76 -0
  82. package/resources/gofer/node-scripts/gofer-blocker-control.mjs +274 -0
  83. package/resources/gofer/node-scripts/gofer-claude-adapter.mjs +154 -0
  84. package/resources/gofer/node-scripts/gofer-closed-loop-audit.mjs +19 -2
  85. package/resources/gofer/node-scripts/gofer-delivery-check.mjs +121 -0
  86. package/resources/gofer/node-scripts/gofer-encrypted-key.mjs +58 -0
  87. package/resources/gofer/node-scripts/gofer-execution-metrics.mjs +477 -0
  88. package/resources/gofer/node-scripts/gofer-execution-recovery.mjs +334 -0
  89. package/resources/gofer/node-scripts/gofer-grok-adapter.mjs +184 -0
  90. package/resources/gofer/node-scripts/gofer-heldout-corpus.mjs +73 -0
  91. package/resources/gofer/node-scripts/gofer-heldout-snapshot.mjs +286 -0
  92. package/resources/gofer/node-scripts/gofer-heldout-verifier.mjs +211 -0
  93. package/resources/gofer/node-scripts/gofer-host-capability.mjs +335 -0
  94. package/resources/gofer/node-scripts/gofer-independent-reviewer.mjs +130 -0
  95. package/resources/gofer/node-scripts/gofer-live-routing.mjs +109 -0
  96. package/resources/gofer/node-scripts/gofer-local-capability-issuer.mjs +71 -0
  97. package/resources/gofer/node-scripts/gofer-local-isolation.mjs +175 -0
  98. package/resources/gofer/node-scripts/gofer-local-settings-cleanup.mjs +388 -0
  99. package/resources/gofer/node-scripts/gofer-loop-audit.mjs +54 -3
  100. package/resources/gofer/node-scripts/gofer-native-adapter.mjs +567 -0
  101. package/resources/gofer/node-scripts/gofer-native-benchmark-dispatch.mjs +145 -0
  102. package/resources/gofer/node-scripts/gofer-native-runtime.mjs +169 -0
  103. package/resources/gofer/node-scripts/gofer-pre-edit-check.mjs +204 -0
  104. package/resources/gofer/node-scripts/gofer-priority-check.mjs +214 -0
  105. package/resources/gofer/node-scripts/gofer-response-check.mjs +56 -0
  106. package/resources/gofer/node-scripts/gofer-reviewed-learning.mjs +1232 -0
  107. package/resources/gofer/node-scripts/gofer-run-verified-task.mjs +330 -0
  108. package/resources/gofer/node-scripts/gofer-runtime-ledger.mjs +289 -0
  109. package/resources/gofer/node-scripts/gofer-semantic-drift.mjs +584 -0
  110. package/resources/gofer/node-scripts/gofer-surface-update.mjs +1178 -0
  111. package/resources/gofer/node-scripts/gofer-trust-bootstrap.mjs +77 -0
  112. package/resources/gofer/node-scripts/gofer-trusted-benchmark.mjs +102 -0
  113. package/resources/gofer/node-scripts/gofer-trusted-evaluator.mjs +274 -0
  114. package/resources/gofer/node-scripts/gofer-tty-prompt.mjs +34 -0
  115. package/resources/gofer/node-scripts/gofer-typesafe-credentials.mjs +435 -0
  116. package/resources/gofer/node-scripts/gofer-ui-preview.mjs +1212 -0
  117. package/resources/gofer/node-scripts/gofer-verified-execution.mjs +484 -0
  118. package/resources/gofer/node-scripts/gofer-verifier-key-ceremony.mjs +101 -0
  119. package/resources/gofer/node-scripts/gofer-worktree-layout.mjs +32 -0
  120. package/resources/gofer/node-scripts/object-type-routing-phase-bundle.mjs +360 -0
  121. package/resources/gofer/node-scripts/package-agent-plugin.mjs +574 -82
  122. package/resources/gofer/node-scripts/parse-stage-command.mjs +1 -1
  123. package/resources/gofer/node-scripts/render-delivery-lineage.mjs +178 -0
  124. package/resources/gofer/node-scripts/sync-extension-resources.mjs +78 -2
  125. package/resources/gofer/node-scripts/validate-object-type-identifiers.mjs +767 -0
  126. package/resources/gofer/node-scripts/validate-object-type-routing-workspace.mjs +1325 -0
  127. package/resources/gofer/node-scripts/validate-v4-resource-contract.d.mts +44 -0
  128. package/resources/gofer/node-scripts/validate-v4-resource-contract.mjs +957 -0
  129. package/resources/gofer/node-scripts/workspace-bootstrap-lib.mjs +685 -116
  130. package/resources/gofer/references/agent-catalog.json +126 -0
  131. package/resources/gofer/references/blocker-mediation.md +156 -0
  132. package/resources/gofer/references/business-updates-and-goal-checks.md +109 -0
  133. package/resources/gofer/references/delivery-lineage.md +48 -0
  134. package/resources/gofer/references/mvp-capability-validation.md +102 -0
  135. package/resources/gofer/references/platform/README.md +1 -1
  136. package/resources/gofer/references/platform/eai-app-template.md +15 -13
  137. package/resources/gofer/references/platform/eai-auth-access.md +104 -0
  138. package/resources/gofer/references/platform/eai-config-driven-ui.md +5 -5
  139. package/resources/gofer/references/platform/eai-error-catalog.yaml +77 -19
  140. package/resources/gofer/references/platform/eai-repo-contract.md +61 -23
  141. package/resources/gofer/references/platform/eai-service-patterns.md +102 -105
  142. package/resources/gofer/references/platform/eai.md +44 -8
  143. package/resources/gofer/references/platform/vertical-template.md +10 -9
  144. package/resources/gofer/references/priority-outcome-protection.md +152 -0
  145. package/resources/gofer/references/verified-agent-execution.md +179 -0
  146. package/resources/gofer/schemas/gofer-learning-trace-v1.json +70 -0
  147. package/resources/gofer/specify-commands/0_gofer_start.md +440 -99
  148. package/resources/gofer/specify-commands/0a_problem_validation.md +187 -27
  149. package/resources/gofer/specify-commands/10_gofer_cloud.md +183 -23
  150. package/resources/gofer/specify-commands/1_gofer_research.md +239 -30
  151. package/resources/gofer/specify-commands/2_gofer_specify.md +239 -35
  152. package/resources/gofer/specify-commands/3_gofer_plan.md +259 -43
  153. package/resources/gofer/specify-commands/4_gofer_tasks.md +401 -81
  154. package/resources/gofer/specify-commands/5_gofer_implement.md +375 -84
  155. package/resources/gofer/specify-commands/6_gofer_validate.md +284 -53
  156. package/resources/gofer/specify-commands/7_gofer_save.md +187 -26
  157. package/resources/gofer/specify-commands/7a_stakeholder_comms.md +183 -23
  158. package/resources/gofer/specify-commands/8_gofer_branding.md +183 -23
  159. package/resources/gofer/specify-commands/9_gofer_tests.md +212 -23
  160. package/resources/gofer/specify-commands/gofer_bootstrap_workspace.md +121 -8
  161. package/resources/gofer/specify-commands/gofer_check_workspace.md +123 -8
  162. package/resources/gofer/specify-commands/gofer_constitution.md +183 -23
  163. package/resources/gofer/specify-commands/gofer_diagnose.md +183 -23
  164. package/resources/gofer/specify-commands/gofer_eai_first_run.md +254 -25
  165. package/resources/gofer/specify-commands/gofer_hydrate.md +183 -23
  166. package/resources/gofer/specify-commands/gofer_personality.md +117 -6
  167. package/resources/gofer/specify-commands/gofer_plan.md +117 -6
  168. package/resources/gofer/specify-commands/gofer_side.md +117 -6
  169. package/resources/gofer/specify-commands/gofer_spec_summary.md +183 -23
  170. package/resources/gofer/specify-commands/gofer_tdd.md +183 -23
  171. package/resources/gofer/specify-commands/gofer_vocabulary.md +185 -25
  172. package/resources/gofer/specify-commands/gofer_zoom_out.md +183 -23
  173. package/resources/gofer/specify-config/object-type-routing.json +24 -0
  174. package/resources/gofer/specify-config/typesafe-learning-review.json +16 -0
  175. package/resources/gofer/specify-config/typesafe-semantic-review.json +9 -0
  176. package/resources/gofer/system-skills/eai/SKILL.md +365 -0
  177. package/resources/gofer/system-skills/eai-update/SKILL.md +56 -0
  178. package/resources/gofer/system-skills/gofer-documentation/SKILL.md +93 -0
  179. package/resources/gofer/templates/build-map-template.md +64 -0
  180. package/resources/gofer/templates/business-scenarios-template.json +14 -0
  181. package/resources/gofer/templates/ciso-security-summary-template.md +3 -3
  182. package/resources/gofer/templates/context-bundle-template.md +4 -3
  183. package/resources/gofer/templates/contract-pack-template.md +8 -8
  184. package/resources/gofer/templates/cto-architecture-summary-template.md +3 -3
  185. package/resources/gofer/templates/delivery-lineage-template.json +8 -0
  186. package/resources/gofer/templates/eai-preflight-template.md +109 -68
  187. package/resources/gofer/templates/goal-ledger-template.json +1 -1
  188. package/resources/gofer/templates/gofer-model-policy.yaml +28 -6
  189. package/resources/gofer/templates/loop-contract-template.json +3 -1
  190. package/resources/gofer/templates/plan-template.md +8 -7
  191. package/resources/gofer/templates/priority-plan-template.json +29 -0
  192. package/resources/gofer/templates/proposal-review-template.md +6 -3
  193. package/resources/gofer/templates/release-capability-ledger-template.md +24 -0
  194. package/resources/gofer/templates/research-template.md +7 -6
  195. package/resources/gofer/templates/spec-summary-template.md +1 -1
  196. package/resources/gofer/templates/spec-template.md +45 -6
  197. package/resources/gofer/templates/tasks-template.md +12 -3
  198. package/resources/gofer/templates/ui-preview-brief-template.md +55 -5
  199. package/resources/gofer/templates/ui-review-log-template.md +21 -3
  200. package/resources/gofer/templates/ui-show-and-tell-template.md +46 -0
  201. package/resources/gofer/templates/visuals/capability-heatmap-template.md +2 -2
  202. package/resources/gofer/templates/working-backwards-prfaq-template.md +9 -8
  203. package/resources/linked-sources.json +2 -2
  204. package/resources/gofer/agents-skills/0_gofer_start/SKILL.md +0 -1287
  205. package/resources/gofer/agents-skills/0a_problem_validation/SKILL.md +0 -429
  206. package/resources/gofer/agents-skills/10_gofer_cloud/SKILL.md +0 -635
  207. package/resources/gofer/agents-skills/1_gofer_research/SKILL.md +0 -1159
  208. package/resources/gofer/agents-skills/2_gofer_specify/SKILL.md +0 -860
  209. package/resources/gofer/agents-skills/3_gofer_plan/SKILL.md +0 -899
  210. package/resources/gofer/agents-skills/4_gofer_tasks/SKILL.md +0 -760
  211. package/resources/gofer/agents-skills/5_gofer_implement/SKILL.md +0 -944
  212. package/resources/gofer/agents-skills/6_gofer_validate/SKILL.md +0 -2302
  213. package/resources/gofer/agents-skills/7_gofer_save/SKILL.md +0 -423
  214. package/resources/gofer/agents-skills/7a_stakeholder_comms/SKILL.md +0 -508
  215. package/resources/gofer/agents-skills/8_gofer_branding/SKILL.md +0 -315
  216. package/resources/gofer/agents-skills/9_gofer_tests/SKILL.md +0 -558
  217. package/resources/gofer/agents-skills/gofer_bootstrap_workspace/SKILL.md +0 -148
  218. package/resources/gofer/agents-skills/gofer_check_workspace/SKILL.md +0 -119
  219. package/resources/gofer/agents-skills/gofer_constitution/SKILL.md +0 -612
  220. package/resources/gofer/agents-skills/gofer_diagnose/SKILL.md +0 -114
  221. package/resources/gofer/agents-skills/gofer_eai_first_run/SKILL.md +0 -397
  222. package/resources/gofer/agents-skills/gofer_hydrate/SKILL.md +0 -561
  223. package/resources/gofer/agents-skills/gofer_personality/SKILL.md +0 -44
  224. package/resources/gofer/agents-skills/gofer_plan/SKILL.md +0 -40
  225. package/resources/gofer/agents-skills/gofer_side/SKILL.md +0 -45
  226. package/resources/gofer/agents-skills/gofer_spec_summary/SKILL.md +0 -112
  227. package/resources/gofer/agents-skills/gofer_tdd/SKILL.md +0 -112
  228. package/resources/gofer/agents-skills/gofer_vocabulary/SKILL.md +0 -112
  229. package/resources/gofer/agents-skills/gofer_zoom_out/SKILL.md +0 -112
  230. package/resources/gofer/claude-commands/0_gofer_start.md +0 -1282
  231. package/resources/gofer/claude-commands/0a_problem_validation.md +0 -424
  232. package/resources/gofer/claude-commands/10_gofer_cloud.md +0 -630
  233. package/resources/gofer/claude-commands/1_gofer_research.md +0 -1154
  234. package/resources/gofer/claude-commands/2_gofer_specify.md +0 -855
  235. package/resources/gofer/claude-commands/3_gofer_plan.md +0 -894
  236. package/resources/gofer/claude-commands/4_gofer_tasks.md +0 -755
  237. package/resources/gofer/claude-commands/5_gofer_implement.md +0 -939
  238. package/resources/gofer/claude-commands/6_gofer_validate.md +0 -2297
  239. package/resources/gofer/claude-commands/7_gofer_save.md +0 -418
  240. package/resources/gofer/claude-commands/7a_stakeholder_comms.md +0 -503
  241. package/resources/gofer/claude-commands/8_gofer_branding.md +0 -310
  242. package/resources/gofer/claude-commands/9_gofer_tests.md +0 -553
  243. package/resources/gofer/claude-commands/gofer_bootstrap_workspace.md +0 -143
  244. package/resources/gofer/claude-commands/gofer_check_workspace.md +0 -114
  245. package/resources/gofer/claude-commands/gofer_constitution.md +0 -607
  246. package/resources/gofer/claude-commands/gofer_diagnose.md +0 -109
  247. package/resources/gofer/claude-commands/gofer_eai_first_run.md +0 -392
  248. package/resources/gofer/claude-commands/gofer_hydrate.md +0 -556
  249. package/resources/gofer/claude-commands/gofer_personality.md +0 -39
  250. package/resources/gofer/claude-commands/gofer_plan.md +0 -35
  251. package/resources/gofer/claude-commands/gofer_side.md +0 -40
  252. package/resources/gofer/claude-commands/gofer_spec_summary.md +0 -107
  253. package/resources/gofer/claude-commands/gofer_tdd.md +0 -107
  254. package/resources/gofer/claude-commands/gofer_vocabulary.md +0 -107
  255. package/resources/gofer/claude-commands/gofer_zoom_out.md +0 -107
  256. package/resources/gofer/claude-skills/eai-gofer/SKILL.md +0 -56
  257. package/resources/gofer/copilot-prompts/0_gofer_start.prompt.md +0 -1308
  258. package/resources/gofer/copilot-prompts/0a_problem_validation.prompt.md +0 -429
  259. package/resources/gofer/copilot-prompts/10_gofer_cloud.prompt.md +0 -644
  260. package/resources/gofer/copilot-prompts/1_gofer_research.prompt.md +0 -1177
  261. package/resources/gofer/copilot-prompts/2_gofer_specify.prompt.md +0 -878
  262. package/resources/gofer/copilot-prompts/3_gofer_plan.prompt.md +0 -917
  263. package/resources/gofer/copilot-prompts/4_gofer_tasks.prompt.md +0 -778
  264. package/resources/gofer/copilot-prompts/5_gofer_implement.prompt.md +0 -962
  265. package/resources/gofer/copilot-prompts/6_gofer_validate.prompt.md +0 -2310
  266. package/resources/gofer/copilot-prompts/7_gofer_save.prompt.md +0 -433
  267. package/resources/gofer/copilot-prompts/7a_stakeholder_comms.prompt.md +0 -516
  268. package/resources/gofer/copilot-prompts/8_gofer_branding.prompt.md +0 -323
  269. package/resources/gofer/copilot-prompts/9_gofer_tests.prompt.md +0 -566
  270. package/resources/gofer/copilot-prompts/gofer_bootstrap_workspace.prompt.md +0 -161
  271. package/resources/gofer/copilot-prompts/gofer_check_workspace.prompt.md +0 -132
  272. package/resources/gofer/copilot-prompts/gofer_constitution.prompt.md +0 -621
  273. package/resources/gofer/copilot-prompts/gofer_diagnose.prompt.md +0 -127
  274. package/resources/gofer/copilot-prompts/gofer_eai_first_run.prompt.md +0 -410
  275. package/resources/gofer/copilot-prompts/gofer_hydrate.prompt.md +0 -571
  276. package/resources/gofer/copilot-prompts/gofer_personality.prompt.md +0 -57
  277. package/resources/gofer/copilot-prompts/gofer_plan.prompt.md +0 -53
  278. package/resources/gofer/copilot-prompts/gofer_side.prompt.md +0 -58
  279. package/resources/gofer/copilot-prompts/gofer_spec_summary.prompt.md +0 -125
  280. package/resources/gofer/copilot-prompts/gofer_tdd.prompt.md +0 -125
  281. package/resources/gofer/copilot-prompts/gofer_vocabulary.prompt.md +0 -125
  282. package/resources/gofer/copilot-prompts/gofer_zoom_out.prompt.md +0 -125
  283. package/resources/gofer/gemini/commands/gofer/0_gofer_start.md +0 -1282
  284. package/resources/gofer/gemini/commands/gofer/0_gofer_start.toml +0 -2
  285. package/resources/gofer/gemini/commands/gofer/0a_problem_validation.md +0 -424
  286. package/resources/gofer/gemini/commands/gofer/0a_problem_validation.toml +0 -2
  287. package/resources/gofer/gemini/commands/gofer/10_gofer_cloud.md +0 -630
  288. package/resources/gofer/gemini/commands/gofer/10_gofer_cloud.toml +0 -2
  289. package/resources/gofer/gemini/commands/gofer/1_gofer_research.md +0 -1154
  290. package/resources/gofer/gemini/commands/gofer/1_gofer_research.toml +0 -2
  291. package/resources/gofer/gemini/commands/gofer/2_gofer_specify.md +0 -855
  292. package/resources/gofer/gemini/commands/gofer/2_gofer_specify.toml +0 -2
  293. package/resources/gofer/gemini/commands/gofer/3_gofer_plan.md +0 -894
  294. package/resources/gofer/gemini/commands/gofer/3_gofer_plan.toml +0 -2
  295. package/resources/gofer/gemini/commands/gofer/4_gofer_tasks.md +0 -755
  296. package/resources/gofer/gemini/commands/gofer/4_gofer_tasks.toml +0 -2
  297. package/resources/gofer/gemini/commands/gofer/5_gofer_implement.md +0 -939
  298. package/resources/gofer/gemini/commands/gofer/5_gofer_implement.toml +0 -2
  299. package/resources/gofer/gemini/commands/gofer/6_gofer_validate.md +0 -2297
  300. package/resources/gofer/gemini/commands/gofer/6_gofer_validate.toml +0 -2
  301. package/resources/gofer/gemini/commands/gofer/7_gofer_save.md +0 -418
  302. package/resources/gofer/gemini/commands/gofer/7_gofer_save.toml +0 -2
  303. package/resources/gofer/gemini/commands/gofer/7a_stakeholder_comms.md +0 -503
  304. package/resources/gofer/gemini/commands/gofer/7a_stakeholder_comms.toml +0 -2
  305. package/resources/gofer/gemini/commands/gofer/8_gofer_branding.md +0 -310
  306. package/resources/gofer/gemini/commands/gofer/8_gofer_branding.toml +0 -2
  307. package/resources/gofer/gemini/commands/gofer/9_gofer_tests.md +0 -553
  308. package/resources/gofer/gemini/commands/gofer/9_gofer_tests.toml +0 -2
  309. package/resources/gofer/gemini/commands/gofer/gofer_bootstrap_workspace.md +0 -143
  310. package/resources/gofer/gemini/commands/gofer/gofer_bootstrap_workspace.toml +0 -2
  311. package/resources/gofer/gemini/commands/gofer/gofer_check_workspace.md +0 -114
  312. package/resources/gofer/gemini/commands/gofer/gofer_check_workspace.toml +0 -2
  313. package/resources/gofer/gemini/commands/gofer/gofer_constitution.md +0 -607
  314. package/resources/gofer/gemini/commands/gofer/gofer_constitution.toml +0 -2
  315. package/resources/gofer/gemini/commands/gofer/gofer_diagnose.md +0 -109
  316. package/resources/gofer/gemini/commands/gofer/gofer_diagnose.toml +0 -2
  317. package/resources/gofer/gemini/commands/gofer/gofer_eai_first_run.md +0 -392
  318. package/resources/gofer/gemini/commands/gofer/gofer_eai_first_run.toml +0 -2
  319. package/resources/gofer/gemini/commands/gofer/gofer_hydrate.md +0 -556
  320. package/resources/gofer/gemini/commands/gofer/gofer_hydrate.toml +0 -2
  321. package/resources/gofer/gemini/commands/gofer/gofer_personality.md +0 -39
  322. package/resources/gofer/gemini/commands/gofer/gofer_personality.toml +0 -2
  323. package/resources/gofer/gemini/commands/gofer/gofer_plan.md +0 -35
  324. package/resources/gofer/gemini/commands/gofer/gofer_plan.toml +0 -2
  325. package/resources/gofer/gemini/commands/gofer/gofer_side.md +0 -40
  326. package/resources/gofer/gemini/commands/gofer/gofer_side.toml +0 -2
  327. package/resources/gofer/gemini/commands/gofer/gofer_spec_summary.md +0 -107
  328. package/resources/gofer/gemini/commands/gofer/gofer_spec_summary.toml +0 -2
  329. package/resources/gofer/gemini/commands/gofer/gofer_tdd.md +0 -107
  330. package/resources/gofer/gemini/commands/gofer/gofer_tdd.toml +0 -2
  331. package/resources/gofer/gemini/commands/gofer/gofer_vocabulary.md +0 -107
  332. package/resources/gofer/gemini/commands/gofer/gofer_vocabulary.toml +0 -2
  333. package/resources/gofer/gemini/commands/gofer/gofer_zoom_out.md +0 -107
  334. package/resources/gofer/gemini/commands/gofer/gofer_zoom_out.toml +0 -2
  335. package/resources/gofer/github-skills/eai-gofer/SKILL.md +0 -56
  336. package/resources/gofer/system-skills/0_gofer_start/SKILL.md +0 -1287
  337. package/resources/gofer/system-skills/0a_problem_validation/SKILL.md +0 -429
  338. package/resources/gofer/system-skills/10_gofer_cloud/SKILL.md +0 -635
  339. package/resources/gofer/system-skills/1_gofer_research/SKILL.md +0 -1159
  340. package/resources/gofer/system-skills/2_gofer_specify/SKILL.md +0 -860
  341. package/resources/gofer/system-skills/3_gofer_plan/SKILL.md +0 -899
  342. package/resources/gofer/system-skills/4_gofer_tasks/SKILL.md +0 -760
  343. package/resources/gofer/system-skills/5_gofer_implement/SKILL.md +0 -944
  344. package/resources/gofer/system-skills/6_gofer_validate/SKILL.md +0 -2302
  345. package/resources/gofer/system-skills/7_gofer_save/SKILL.md +0 -423
  346. package/resources/gofer/system-skills/7a_stakeholder_comms/SKILL.md +0 -508
  347. package/resources/gofer/system-skills/8_gofer_branding/SKILL.md +0 -315
  348. package/resources/gofer/system-skills/9_gofer_tests/SKILL.md +0 -558
  349. package/resources/gofer/system-skills/gofer_bootstrap_workspace/SKILL.md +0 -148
  350. package/resources/gofer/system-skills/gofer_check_workspace/SKILL.md +0 -119
  351. package/resources/gofer/system-skills/gofer_constitution/SKILL.md +0 -612
  352. package/resources/gofer/system-skills/gofer_diagnose/SKILL.md +0 -114
  353. package/resources/gofer/system-skills/gofer_eai_first_run/SKILL.md +0 -397
  354. package/resources/gofer/system-skills/gofer_hydrate/SKILL.md +0 -561
  355. package/resources/gofer/system-skills/gofer_personality/SKILL.md +0 -44
  356. package/resources/gofer/system-skills/gofer_plan/SKILL.md +0 -40
  357. package/resources/gofer/system-skills/gofer_side/SKILL.md +0 -45
  358. package/resources/gofer/system-skills/gofer_spec_summary/SKILL.md +0 -112
  359. package/resources/gofer/system-skills/gofer_tdd/SKILL.md +0 -112
  360. package/resources/gofer/system-skills/gofer_vocabulary/SKILL.md +0 -112
  361. package/resources/gofer/system-skills/gofer_zoom_out/SKILL.md +0 -112
  362. 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
+ }