@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,77 @@
1
+ #!/usr/bin/env node
2
+ /** Prepare the local capability identity without granting it runtime authority. */
3
+ import { execFileSync } from 'node:child_process';
4
+ import { generateKeyPairSync, randomUUID } from 'node:crypto';
5
+ import { constants } from 'node:fs';
6
+ import { lstat, mkdir, open, realpath } from 'node:fs/promises';
7
+ import path from 'node:path';
8
+ import { fileURLToPath } from 'node:url';
9
+
10
+ const denied = () => new Error('LOCAL_TRUST_SETUP_REQUIRES_REVIEW');
11
+
12
+ function accountHome() {
13
+ if (typeof process.getuid !== 'function') throw denied();
14
+ if (process.platform === 'darwin') {
15
+ const name = execFileSync('/usr/bin/id', ['-un'], { encoding: 'utf8', timeout: 3000 }).trim();
16
+ if (!/^[a-zA-Z0-9._-]+$/.test(name)) throw denied();
17
+ const record = execFileSync('/usr/bin/dscl', ['.', '-read', path.join(path.sep, 'Users', name), 'NFSHomeDirectory'],
18
+ { encoding: 'utf8', timeout: 3000 }).trim();
19
+ return /^NFSHomeDirectory: (\/[^\n]+)$/.exec(record)?.[1] ?? null;
20
+ }
21
+ if (process.platform === 'linux') {
22
+ const record = execFileSync('/usr/bin/getent', ['passwd', String(process.getuid())],
23
+ { encoding: 'utf8', timeout: 3000 }).trim().split(':');
24
+ return record.length === 7 && record[2] === String(process.getuid()) ? record[5] : null;
25
+ }
26
+ throw denied();
27
+ }
28
+
29
+ async function writeExclusive(filename, value) {
30
+ const file = await open(filename, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 0o600);
31
+ try { await file.writeFile(value, 'utf8'); }
32
+ finally { await file.close(); }
33
+ }
34
+
35
+ /** Used by trusted setup only. Existing material is never replaced or activated. */
36
+ export async function initializeStagedTrust(root) {
37
+ if (!path.isAbsolute(root)) throw denied();
38
+ const parent = await realpath(path.dirname(root));
39
+ const parentInfo = await lstat(parent);
40
+ if (!parentInfo.isDirectory() || ![0, process.getuid()].includes(parentInfo.uid) ||
41
+ (parentInfo.mode & 0o022) !== 0 || parent !== path.dirname(root)) throw denied();
42
+ await mkdir(root, { mode: 0o700 });
43
+ const rootInfo = await lstat(root);
44
+ if (!rootInfo.isDirectory() || rootInfo.uid !== process.getuid() ||
45
+ (rootInfo.mode & 0o077) !== 0) throw denied();
46
+ const staged = path.join(root, 'staged-keys');
47
+ await mkdir(staged, { mode: 0o700 });
48
+ // The benchmark verifier key is not staged here. A worker sandbox can read
49
+ // the account home, so a plaintext verifier key would be forgeable. It is
50
+ // created, encrypted, by the human-run gofer-verifier-key-ceremony.mjs.
51
+ const identities = [
52
+ { name: 'capability-evaluator', host: 'codex', evaluator: 'gofer-native-host-evaluator' },
53
+ ];
54
+ const records = [];
55
+ for (const identity of identities) {
56
+ const pair = generateKeyPairSync('ed25519');
57
+ const keyId = `${identity.name}-${randomUUID()}`;
58
+ await writeExclusive(path.join(staged, `${identity.name}.private.pem`),
59
+ pair.privateKey.export({ type: 'pkcs8', format: 'pem' }));
60
+ await writeExclusive(path.join(staged, `${identity.name}.public.pem`),
61
+ pair.publicKey.export({ type: 'spki', format: 'pem' }));
62
+ records.push({ ...identity, keyId });
63
+ }
64
+ await writeExclusive(path.join(root, 'trusted-evaluators.json'),
65
+ `${JSON.stringify({ schemaVersion: 1, evaluators: [] }, null, 2)}\n`);
66
+ await writeExclusive(path.join(staged, 'identities.json'), `${JSON.stringify(records, null, 2)}\n`);
67
+ return { root, identities: records.map(({ name, keyId }) => ({ name, keyId })), active: false };
68
+ }
69
+
70
+ if (process.argv[1] && fileURLToPath(import.meta.url) === path.resolve(process.argv[1])) {
71
+ if (process.argv.length !== 2) throw denied();
72
+ const home = accountHome();
73
+ if (!home || !path.isAbsolute(home)) throw denied();
74
+ initializeStagedTrust(path.join(home, '.eai-gofer-trust'))
75
+ .then(result => process.stdout.write(`${JSON.stringify(result)}\n`))
76
+ .catch(error => { process.stderr.write(`${error.message}\n`); process.exitCode = 1; });
77
+ }
@@ -0,0 +1,102 @@
1
+ /** Authenticate a held-out benchmark report before it can govern routing. */
2
+ import { createHash, createPublicKey, verify } from 'node:crypto';
3
+ import { resolveTrustedEvaluatorPublicKey } from './gofer-trusted-evaluator.mjs';
4
+
5
+ const text = value => typeof value === 'string' && value.trim().length > 0;
6
+ const sha256 = value => createHash('sha256').update(value).digest('hex');
7
+ const denied = () => new Error('TRUSTED_BENCHMARK_REQUIRED');
8
+ const VERIFIER = 'gofer-heldout-benchmark-verifier';
9
+ const digest = value => /^[a-f0-9]{64}$/.test(value ?? '');
10
+ const nonnegative = value => Number.isFinite(value) && value >= 0;
11
+ const wilson95 = (passes, total) => {
12
+ const z = 1.96;
13
+ const p = passes / total;
14
+ const denominator = 1 + z ** 2 / total;
15
+ const centre = (p + z ** 2 / (2 * total)) / denominator;
16
+ const spread = z * Math.sqrt((p * (1 - p) + z ** 2 / (4 * total)) / total) / denominator;
17
+ return { lower: Math.max(0, centre - spread), upper: Math.min(1, centre + spread) };
18
+ };
19
+
20
+ function validReport(report, receiptHash) {
21
+ if (report?.schemaVersion !== 2 || report.repetitions !== 3 ||
22
+ !Number.isInteger(report.caseCount) || report.caseCount < 4 ||
23
+ !Array.isArray(report.runs) || report.runs.length !== report.caseCount * 3 ||
24
+ !text(report.provenance?.harnessId) || !text(report.provenance?.modelId) ||
25
+ !digest(report.provenance?.corpusHash) ||
26
+ report.provenance?.capabilityReceiptHash !== receiptHash) return false;
27
+ const seen = new Set();
28
+ const executions = new Set();
29
+ const verifications = new Set();
30
+ let passes = 0;
31
+ let cost = 0;
32
+ let duration = 0;
33
+ for (const run of report.runs) {
34
+ const pair = `${run?.caseId}:${run?.run}`;
35
+ if (!text(run?.caseId) || !Number.isInteger(run.run) || run.run < 1 || run.run > 3 ||
36
+ seen.has(pair) || run.modelId !== report.provenance.modelId ||
37
+ !nonnegative(run.costUsd) || !nonnegative(run.durationMs) ||
38
+ !digest(run.receipt) || !digest(run.inputHash) || !digest(run.verifierReceipt) ||
39
+ !digest(run.reviewReceipt) || !text(run.verifierId) ||
40
+ !text(run.failureClassification) || typeof run.functionalVerified !== 'boolean' ||
41
+ executions.has(run.receipt) || verifications.has(run.verifierReceipt)) return false;
42
+ seen.add(pair);
43
+ executions.add(run.receipt);
44
+ verifications.add(run.verifierReceipt);
45
+ passes += Number(run.functionalVerified);
46
+ cost += run.costUsd;
47
+ duration += run.durationMs;
48
+ }
49
+ const cases = new Set(report.runs.map(run => run.caseId));
50
+ if (cases.size !== report.caseCount ||
51
+ [...cases].some(id => [1, 2, 3].some(run => !seen.has(`${id}:${run}`)))) return false;
52
+ const reliability = passes / report.runs.length;
53
+ const interval = report.confidenceInterval;
54
+ const expectedInterval = wilson95(passes, report.runs.length);
55
+ return report.functionalPasses === passes && report.functionalRuns === report.runs.length &&
56
+ Math.abs(report.reliability - reliability) < 1e-12 &&
57
+ Math.abs(report.costUsd - cost) < 1e-9 && report.durationMs === duration &&
58
+ report.status === (passes === report.runs.length ? 'pass' : 'fail') &&
59
+ interval?.level === 0.95 &&
60
+ Math.abs(interval.lower - expectedInterval.lower) < 1e-12 &&
61
+ Math.abs(interval.upper - expectedInterval.upper) < 1e-12;
62
+ }
63
+
64
+ /**
65
+ * A signed attestation binds all report fields, including every run verdict,
66
+ * cost, review receipt, and provenance field. Only a separately registered
67
+ * verifier key may authorize this evidence for the native runtime.
68
+ */
69
+ export async function verifyTrustedBenchmarkEvidence({ host, receiptHash, evidence,
70
+ attestation, capabilityKeyId, capabilityPublicKey, workspaceRoot, now = Date.now() } = {}) {
71
+ if (!text(host) || !/^[a-f0-9]{64}$/.test(receiptHash ?? '') || !text(capabilityKeyId) ||
72
+ !capabilityPublicKey || !text(workspaceRoot) || !Number.isFinite(now) || !attestation ||
73
+ attestation.schemaVersion !== 1 || attestation.host !== host ||
74
+ attestation.capabilityReceiptHash !== receiptHash ||
75
+ attestation.verification !== 'functional-tests+independent-review' ||
76
+ !text(attestation.verifierVersion) || attestation.provenance?.evaluator !== VERIFIER ||
77
+ !text(attestation.provenance?.keyId) || attestation.provenance.keyId === capabilityKeyId ||
78
+ !text(attestation.provenance?.source) || attestation.signature?.algorithm !== 'ed25519' ||
79
+ attestation.signature.keyId !== attestation.provenance.keyId ||
80
+ !/^[A-Za-z0-9_-]+$/.test(attestation.signature.value ?? '')) throw denied();
81
+ const verifiedAt = Date.parse(attestation.verifiedAt);
82
+ const expiresAt = Date.parse(attestation.expiresAt);
83
+ if (!Number.isFinite(verifiedAt) || !Number.isFinite(expiresAt) ||
84
+ verifiedAt > now || expiresAt <= now || expiresAt <= verifiedAt) throw denied();
85
+ let bytes;
86
+ try { bytes = JSON.stringify(evidence); } catch { throw denied(); }
87
+ const reports = Array.isArray(evidence) ? evidence : [evidence];
88
+ if (!reports.length || !reports.every(report => validReport(report, receiptHash)) ||
89
+ attestation.evidenceHash !== sha256(bytes)) throw denied();
90
+ const { signature, ...payload } = attestation;
91
+ const publicKey = await resolveTrustedEvaluatorPublicKey(attestation,
92
+ { workspaceRoot }).catch(() => { throw denied(); });
93
+ try {
94
+ const capabilityKey = capabilityPublicKey?.type === 'public'
95
+ ? capabilityPublicKey : createPublicKey(capabilityPublicKey);
96
+ if (publicKey.export({ type: 'spki', format: 'der' }).equals(
97
+ capabilityKey.export({ type: 'spki', format: 'der' }))) throw denied();
98
+ } catch { throw denied(); }
99
+ if (!verify(null, Buffer.from(JSON.stringify(payload)), publicKey,
100
+ Buffer.from(signature.value, 'base64url'))) throw denied();
101
+ return Object.freeze({ valid: true, receiptHash, receipt: `benchmark:${sha256(JSON.stringify(attestation))}` });
102
+ }
@@ -0,0 +1,274 @@
1
+ /** Read a locally provisioned evaluator key. The worker never chooses it. */
2
+ import { createHash, createPrivateKey, createPublicKey } from 'node:crypto';
3
+ import { execFileSync } from 'node:child_process';
4
+ import { constants } from 'node:fs';
5
+ import { lstat, open, realpath } from 'node:fs/promises';
6
+ import path from 'node:path';
7
+ import { loadHeldOutCorpus } from './gofer-heldout-corpus.mjs';
8
+ import { decryptSigningKey } from './gofer-encrypted-key.mjs';
9
+
10
+ const text = value => typeof value === 'string' && value.trim().length > 0;
11
+ const inside = (parent, child) => {
12
+ const relative = path.relative(parent, child);
13
+ return relative === '' || (relative !== '..' && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative));
14
+ };
15
+ const denied = () => new Error('TRUSTED_EVALUATOR_REQUIRED');
16
+
17
+ export function accountTrustRoot() {
18
+ // HOME is caller-controlled. Resolve the account record by effective UID.
19
+ if (process.platform === 'linux') {
20
+ const uid = process.getuid();
21
+ const record = execFileSync('/usr/bin/getent', ['passwd', String(uid)],
22
+ { encoding: 'utf8', timeout: 3000 }).trim();
23
+ const fields = record.split(':');
24
+ const home = fields.length === 7 && fields[2] === String(uid) ? fields[5] : null;
25
+ if (!home || !path.isAbsolute(home) || home.includes('\n')) throw denied();
26
+ return path.join(home, '.eai-gofer-trust');
27
+ }
28
+ if (process.platform !== 'darwin') throw denied();
29
+ const name = execFileSync('/usr/bin/id', ['-un'], { encoding: 'utf8', timeout: 3000 }).trim();
30
+ if (!/^[a-zA-Z0-9._-]+$/.test(name)) throw denied();
31
+ const record = execFileSync('/usr/bin/dscl', ['.', '-read', path.join(path.sep, 'Users', name), 'NFSHomeDirectory'],
32
+ { encoding: 'utf8', timeout: 3000 }).trim();
33
+ const home = /^NFSHomeDirectory: (\/[^\n]+)$/.exec(record)?.[1];
34
+ if (!home) throw denied();
35
+ return path.join(home, '.eai-gofer-trust');
36
+ }
37
+
38
+ // A directory handle stays bound to the inode it opened even if something
39
+ // later renames or replaces the path. Re-checking a path-based file open
40
+ // against the handle's device/inode closes the gap between validating a
41
+ // directory and reading a file inside it: a same-uid path substitution is
42
+ // detected instead of silently trusted.
43
+ async function assertSameDirectory(candidatePath, boundInfo) {
44
+ const current = await lstat(candidatePath).catch(() => null);
45
+ if (!current || current.dev !== boundInfo.dev || current.ino !== boundInfo.ino) throw denied();
46
+ }
47
+
48
+ async function inspectAccountTrustRoot(root, workspaceRoot) {
49
+ if (!path.isAbsolute(root)) throw denied();
50
+ const [workspace, parent] = await Promise.all([realpath(workspaceRoot), realpath(path.dirname(root))]);
51
+ const parentInfo = await lstat(parent);
52
+ const canonicalRoot = path.join(parent, path.basename(root));
53
+ if (!parentInfo.isDirectory() || ![0, process.getuid()].includes(parentInfo.uid) ||
54
+ (parentInfo.mode & 0o022) !== 0 || inside(workspace, canonicalRoot) ||
55
+ inside(canonicalRoot, workspace)) throw denied();
56
+ const handle = await open(canonicalRoot, constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW);
57
+ try {
58
+ const rootInfo = await handle.stat();
59
+ if (!rootInfo.isDirectory() || rootInfo.uid !== process.getuid() ||
60
+ (rootInfo.mode & 0o077) !== 0) throw denied();
61
+ return { canonicalRoot, handle, info: rootInfo };
62
+ } catch (err) { await handle.close(); throw err; }
63
+ }
64
+
65
+ // Open a file below a directory already validated by `inspectAccountTrustRoot`,
66
+ // re-confirming immediately beforehand that the directory path has not been
67
+ // substituted since that validation.
68
+ async function openVerifiedFile(directory, filename) {
69
+ const filePath = path.join(directory.canonicalRoot, filename);
70
+ const file = await open(filePath, constants.O_RDONLY | constants.O_NOFOLLOW);
71
+ try {
72
+ await assertSameDirectory(directory.canonicalRoot, directory.info);
73
+ return file;
74
+ } catch (err) { await file.close(); throw err; }
75
+ }
76
+
77
+ export const VERIFIER_EVALUATOR = 'gofer-heldout-benchmark-verifier';
78
+
79
+ /** Verifier keys are trusted only from a root-owned registry. Anything the
80
+ * account can write, an unsandboxed process in that account can also write. */
81
+ export function protectedVerifierRegistryPath() {
82
+ if (process.platform === 'darwin') return '/Library/Application Support/EAI Gofer/verifier-registry.json';
83
+ if (process.platform === 'linux') return '/etc/eai-gofer/verifier-registry.json';
84
+ throw denied();
85
+ }
86
+
87
+ async function loadProtectedVerifierKey(receipt, { path: registryPath = protectedVerifierRegistryPath(),
88
+ ownerUid = 0 } = {}) {
89
+ try {
90
+ if (!path.isAbsolute(registryPath) || !Number.isInteger(ownerUid)) throw denied();
91
+ const parent = await realpath(path.dirname(registryPath));
92
+ for (let current = parent; ;) {
93
+ const info = await lstat(current);
94
+ if (!info.isDirectory() || ![0, ownerUid].includes(info.uid) || (info.mode & 0o022) !== 0) throw denied();
95
+ const above = path.dirname(current);
96
+ if (above === current) break;
97
+ current = above;
98
+ }
99
+ let registry;
100
+ const file = await open(path.join(parent, path.basename(registryPath)),
101
+ constants.O_RDONLY | constants.O_NOFOLLOW);
102
+ try {
103
+ const info = await file.stat();
104
+ if (!info.isFile() || info.uid !== ownerUid || info.nlink !== 1 ||
105
+ (info.mode & 0o022) !== 0 || info.size < 2 || info.size > 65536) throw denied();
106
+ registry = JSON.parse(await file.readFile('utf8'));
107
+ } finally { await file.close(); }
108
+ if (registry?.schemaVersion !== 1 || !Array.isArray(registry.evaluators) ||
109
+ registry.evaluators.length < 1 || registry.evaluators.length > 32 ||
110
+ registry.evaluators.some(item => !text(item?.keyId) || !text(item?.host) ||
111
+ item.evaluator !== VERIFIER_EVALUATOR || !text(item?.publicKeyPem)) ||
112
+ new Set(registry.evaluators.map(item => item.keyId)).size !== registry.evaluators.length) throw denied();
113
+ const entry = registry.evaluators.find(item => item.keyId === receipt.provenance.keyId &&
114
+ item.host === receipt.host);
115
+ if (!entry) throw denied();
116
+ const key = createPublicKey(entry.publicKeyPem);
117
+ if (key.asymmetricKeyType !== 'ed25519') throw denied();
118
+ return key;
119
+ } catch { throw denied(); }
120
+ }
121
+
122
+ /**
123
+ * The default trust root is fixed outside the checkout. `trustRoot` exists for
124
+ * isolated tests; the production composition root never accepts an override.
125
+ */
126
+ export async function resolveTrustedEvaluatorPublicKey(receipt, { workspaceRoot, trustRoot, protectedRegistry } = {}) {
127
+ if (process.platform === 'win32' || typeof process.getuid !== 'function' ||
128
+ !text(workspaceRoot) || !text(receipt?.host) || !text(receipt?.provenance?.keyId) ||
129
+ !text(receipt?.provenance?.evaluator)) throw denied();
130
+ if (receipt.provenance.evaluator === VERIFIER_EVALUATOR) return loadProtectedVerifierKey(receipt, protectedRegistry);
131
+ const root = trustRoot ?? accountTrustRoot();
132
+ try {
133
+ const directory = await inspectAccountTrustRoot(root, workspaceRoot);
134
+ let registry;
135
+ try {
136
+ const file = await openVerifiedFile(directory, 'trusted-evaluators.json');
137
+ try {
138
+ const actual = await file.stat();
139
+ if (!actual.isFile() || actual.uid !== process.getuid() ||
140
+ (actual.mode & 0o077) !== 0 || actual.size < 2 || actual.size > 65536) throw denied();
141
+ registry = JSON.parse(await file.readFile('utf8'));
142
+ } finally { await file.close(); }
143
+ } finally { await directory.handle.close(); }
144
+ if (registry?.schemaVersion !== 1 || !Array.isArray(registry.evaluators) ||
145
+ registry.evaluators.length < 1 || registry.evaluators.length > 32 ||
146
+ registry.evaluators.some(item => !text(item?.keyId) || !text(item?.host) ||
147
+ !text(item?.evaluator) || !text(item?.publicKeyPem)) ||
148
+ new Set(registry.evaluators.map(item => item.keyId)).size !== registry.evaluators.length) throw denied();
149
+ const entry = registry.evaluators.find(item => item.keyId === receipt.provenance.keyId &&
150
+ item.host === receipt.host && item.evaluator === receipt.provenance.evaluator);
151
+ if (!entry) throw denied();
152
+ const key = createPublicKey(entry.publicKeyPem);
153
+ if (key.asymmetricKeyType !== 'ed25519') throw denied();
154
+ return key;
155
+ } catch { throw denied(); }
156
+ }
157
+
158
+ /** Only activated identities can sign. Production issuers never expose a
159
+ * caller-selected trust root; the override is for isolated tests. */
160
+ async function loadActiveEvaluatorKey({ workspaceRoot, trustRoot, identityName, evaluator,
161
+ getPassphrase, protectedRegistry } = {}) {
162
+ if (!text(workspaceRoot) || process.platform === 'win32' || typeof process.getuid !== 'function') throw denied();
163
+ const root = trustRoot ?? accountTrustRoot();
164
+ try {
165
+ const active = path.join(root, 'active-keys');
166
+ const handle = await open(active, constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW);
167
+ let identity, privateKey;
168
+ try {
169
+ const activeInfo = await handle.stat();
170
+ if (!activeInfo.isDirectory() || activeInfo.uid !== process.getuid() ||
171
+ (activeInfo.mode & 0o077) !== 0) throw denied();
172
+ const directory = { canonicalRoot: active, handle, info: activeInfo };
173
+ const identityFile = await openVerifiedFile(directory, `${identityName}.json`);
174
+ try {
175
+ const info = await identityFile.stat();
176
+ if (!info.isFile() || info.uid !== process.getuid() ||
177
+ (info.mode & 0o077) !== 0 || info.size < 2 || info.size > 4096) throw denied();
178
+ identity = JSON.parse(await identityFile.readFile('utf8'));
179
+ } finally { await identityFile.close(); }
180
+ if (identity?.schemaVersion !== 1 || identity.host !== 'codex' ||
181
+ identity.evaluator !== evaluator || !text(identity.keyId)) throw denied();
182
+ const publicKey = await resolveTrustedEvaluatorPublicKey({ host: identity.host,
183
+ provenance: { evaluator: identity.evaluator, keyId: identity.keyId } }, { workspaceRoot, trustRoot, protectedRegistry });
184
+ if (evaluator === VERIFIER_EVALUATOR) {
185
+ // A plaintext verifier key is readable by any worker. Only an
186
+ // encrypted envelope, opened with a passphrase a person types, loads.
187
+ if (typeof getPassphrase !== 'function') throw denied();
188
+ const envelopeFile = await openVerifiedFile(directory, `${identityName}.private.enc.json`);
189
+ let envelope;
190
+ try {
191
+ const info = await envelopeFile.stat();
192
+ if (!info.isFile() || info.uid !== process.getuid() || info.nlink !== 1 ||
193
+ (info.mode & 0o077) !== 0 || info.size < 100 || info.size > 8192) throw denied();
194
+ envelope = JSON.parse(await envelopeFile.readFile('utf8'));
195
+ } finally { await envelopeFile.close(); }
196
+ privateKey = await decryptSigningKey(envelope, await getPassphrase());
197
+ } else {
198
+ const privateFile = await openVerifiedFile(directory, `${identityName}.private.pem`);
199
+ try {
200
+ const info = await privateFile.stat();
201
+ if (!info.isFile() || info.uid !== process.getuid() ||
202
+ (info.mode & 0o077) !== 0 || info.size < 32 || info.size > 8192) throw denied();
203
+ privateKey = createPrivateKey(await privateFile.readFile('utf8'));
204
+ } finally { await privateFile.close(); }
205
+ }
206
+ if (privateKey.asymmetricKeyType !== 'ed25519' ||
207
+ !createPublicKey(privateKey).export({ type: 'spki', format: 'der' })
208
+ .equals(publicKey.export({ type: 'spki', format: 'der' }))) throw denied();
209
+ } finally { await handle.close(); }
210
+ return Object.freeze({ privateKey, keyId: identity.keyId });
211
+ } catch { throw denied(); }
212
+ }
213
+
214
+ export async function loadActiveCodexEvaluatorKey({ workspaceRoot, trustRoot } = {}) {
215
+ return loadActiveEvaluatorKey({ workspaceRoot, trustRoot,
216
+ identityName: 'codex-evaluator', evaluator: 'gofer-native-host-evaluator' });
217
+ }
218
+
219
+ export async function loadActiveBenchmarkVerifierKey({ workspaceRoot, trustRoot, getPassphrase,
220
+ protectedRegistry } = {}) {
221
+ return loadActiveEvaluatorKey({ workspaceRoot, trustRoot, getPassphrase, protectedRegistry,
222
+ identityName: 'heldout-verifier', evaluator: VERIFIER_EVALUATOR });
223
+ }
224
+
225
+ /** The controller pins one corpus inside its account-owned trust root.
226
+ * A worker cannot select a path or replace a pinned input through this API. */
227
+ export async function loadTrustedHeldOutCorpus({ workspaceRoot, trustRoot } = {}) {
228
+ if (!text(workspaceRoot) || process.platform === 'win32' ||
229
+ typeof process.getuid !== 'function') throw denied();
230
+ const root = trustRoot ?? accountTrustRoot();
231
+ try {
232
+ const trustDirectory = await inspectAccountTrustRoot(root, workspaceRoot);
233
+ let config;
234
+ try {
235
+ const configFile = await openVerifiedFile(trustDirectory, 'heldout-corpus.json');
236
+ try {
237
+ const info = await configFile.stat();
238
+ if (!info.isFile() || info.uid !== process.getuid() || info.nlink !== 1 ||
239
+ (info.mode & 0o077) !== 0 || info.size < 2 || info.size > 4096) throw denied();
240
+ config = JSON.parse(await configFile.readFile('utf8'));
241
+ } finally { await configFile.close(); }
242
+ } finally { await trustDirectory.handle.close(); }
243
+ if (config?.schemaVersion !== 1 || !/^[a-zA-Z0-9][a-zA-Z0-9._-]{0,63}$/.test(config.corpusId ?? '') ||
244
+ !/^[a-f0-9]{64}$/.test(config.corpusHash ?? '')) throw denied();
245
+ const corpora = path.join(trustDirectory.canonicalRoot, 'corpora');
246
+ const corpusRoot = path.join(corpora, config.corpusId);
247
+ for (const directory of [corpora, corpusRoot]) {
248
+ const info = await lstat(directory);
249
+ if (!info.isDirectory() || info.uid !== process.getuid() ||
250
+ (info.mode & 0o077) !== 0) throw denied();
251
+ }
252
+ const manifestFile = await open(path.join(corpusRoot, 'manifest.json'),
253
+ constants.O_RDONLY | constants.O_NOFOLLOW);
254
+ let manifest;
255
+ try {
256
+ const info = await manifestFile.stat();
257
+ if (!info.isFile() || info.uid !== process.getuid() || info.nlink !== 1 ||
258
+ (info.mode & 0o077) !== 0 || info.size < 2 || info.size > 65536) throw denied();
259
+ manifest = JSON.parse(await manifestFile.readFile('utf8'));
260
+ } finally { await manifestFile.close(); }
261
+ if (!Array.isArray(manifest?.cases) ||
262
+ createHash('sha256').update(JSON.stringify(manifest)).digest('hex') !== config.corpusHash) throw denied();
263
+ for (const name of manifest.cases.map(item => item?.inputFile)) {
264
+ if (!text(name) || name === '.' || name === '..' || name.includes('/') ||
265
+ name.includes('\\')) throw denied();
266
+ const info = await lstat(path.join(corpusRoot, name));
267
+ if (!info.isFile() || info.uid !== process.getuid() || info.nlink !== 1 ||
268
+ (info.mode & 0o077) !== 0) throw denied();
269
+ }
270
+ const corpus = await loadHeldOutCorpus({ corpusRoot, workspaceRoot });
271
+ if (corpus.corpusHash !== config.corpusHash) throw denied();
272
+ return Object.freeze({ ...corpus, corpusRoot });
273
+ } catch { throw denied(); }
274
+ }
@@ -0,0 +1,34 @@
1
+ /** Read a secret from a real terminal only. Never from a pipe, an argument,
2
+ * the environment, or a file: a person must be present to type it. */
3
+ import process from 'node:process';
4
+
5
+ const denied = () => new Error('INTERACTIVE_TERMINAL_REQUIRED');
6
+ const CANCEL = new Set([String.fromCharCode(3), String.fromCharCode(4)]);
7
+ const BACKSPACE = new Set([String.fromCharCode(127), String.fromCharCode(8)]);
8
+
9
+ export function promptHidden(label, { stdin = process.stdin, stdout = process.stdout } = {}) {
10
+ if (!stdin.isTTY || !stdout.isTTY || typeof stdin.setRawMode !== 'function') throw denied();
11
+ return new Promise((resolve, reject) => {
12
+ let value = '';
13
+ const finish = (error, result) => {
14
+ stdin.removeListener('data', onData);
15
+ stdin.setRawMode(false);
16
+ stdin.pause();
17
+ stdout.write('\n');
18
+ if (error) reject(error);
19
+ else resolve(result);
20
+ };
21
+ const onData = chunk => {
22
+ for (const character of chunk.toString('utf8')) {
23
+ if (character === '\r' || character === '\n') return finish(null, value);
24
+ if (CANCEL.has(character)) return finish(new Error('PASSPHRASE_ENTRY_CANCELLED'));
25
+ if (BACKSPACE.has(character)) value = value.slice(0, -1);
26
+ else if (character >= ' ') value += character;
27
+ }
28
+ };
29
+ stdout.write(label);
30
+ stdin.setRawMode(true);
31
+ stdin.resume();
32
+ stdin.on('data', onData);
33
+ });
34
+ }