@citeark/agent 0.3.20

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 (347) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +128 -0
  3. package/data/dataset-source-registry.v1.json +300 -0
  4. package/dist/arkgraph/boot.js +6 -0
  5. package/dist/arkgraph/index.html +1 -0
  6. package/dist/arkgraph/viewer.css +1 -0
  7. package/dist/arkgraph/viewer.en.css +1 -0
  8. package/dist/arkgraph/viewer.en.js +49 -0
  9. package/dist/arkgraph/viewer.en.js.LEGAL.txt +56 -0
  10. package/dist/arkgraph/viewer.js +49 -0
  11. package/dist/arkgraph/viewer.js.LEGAL.txt +56 -0
  12. package/docker/claude-code/Dockerfile +97 -0
  13. package/docker/claude-code/codex-pro-relay.mjs +466 -0
  14. package/docker/claude-code/runtime-contract-check.mjs +79 -0
  15. package/docs/arkgraph-reading.md +79 -0
  16. package/docs/configuration.md +100 -0
  17. package/docs/integration.md +92 -0
  18. package/docs/maturity-plan.md +27 -0
  19. package/docs/npm-release.md +44 -0
  20. package/docs/paper-reading.md +40 -0
  21. package/docs/research-plan-granularity.md +27 -0
  22. package/docs/terminal.md +49 -0
  23. package/examples/toy-evaluation/compile-task.json +27 -0
  24. package/examples/toy-evaluation/paper.md +5 -0
  25. package/examples/toy-evaluation/repository/README.md +9 -0
  26. package/examples/toy-evaluation/repository/checkpoint.json +4 -0
  27. package/examples/toy-evaluation/repository/evaluate.py +17 -0
  28. package/examples/toy-evaluation/task.json +81 -0
  29. package/package.json +59 -0
  30. package/prompts/compile-research.md +58 -0
  31. package/prompts/execute-contract.md +72 -0
  32. package/prompts/execute-workspace-simple.md +51 -0
  33. package/prompts/execute-workspace.md +34 -0
  34. package/prompts/prepare-reproduction.md +82 -0
  35. package/prompts/repair-research.md +45 -0
  36. package/protocol/CAP.md +129 -0
  37. package/protocol/LICENSE +12 -0
  38. package/protocol/MAPPINGS.md +72 -0
  39. package/protocol/README.md +38 -0
  40. package/protocol/conformance-v2.0-alpha.1.json +36 -0
  41. package/protocol/examples/arkgraph/checkpoint-evaluation.json +309 -0
  42. package/protocol/examples/arkgraph/fixtures.mjs +49 -0
  43. package/protocol/examples/arkgraph/paper-free.json +291 -0
  44. package/protocol/examples/arkgraph/partial-failure.json +344 -0
  45. package/protocol/examples/arkgraph/training-evaluation.json +443 -0
  46. package/protocol/profiles/agent-trace.md +16 -0
  47. package/protocol/profiles/computational-run.md +16 -0
  48. package/protocol/profiles/core.md +15 -0
  49. package/protocol/profiles/public-bundle.md +18 -0
  50. package/protocol/profiles/reproduction.md +29 -0
  51. package/protocol/profiles/research-compilation.md +44 -0
  52. package/protocol/profiles/research-plan.md +39 -0
  53. package/protocol/profiles/restricted-evidence.md +15 -0
  54. package/runtime/bootstrap-autodl-runtime.sh +314 -0
  55. package/runtime/create-runtime-venv.sh +41 -0
  56. package/runtime/install-local-cpu-runtime.sh +23 -0
  57. package/runtime/install-scientific-runtime.sh +153 -0
  58. package/runtime/mineru/parse.py +62 -0
  59. package/runtime/mineru/requirements.txt +4 -0
  60. package/runtime/requirements-baseline.txt +38 -0
  61. package/schemas/cap/v2/activity.schema.json +47 -0
  62. package/schemas/cap/v2/agent.schema.json +32 -0
  63. package/schemas/cap/v2/assertion.schema.json +110 -0
  64. package/schemas/cap/v2/descriptor.schema.json +243 -0
  65. package/schemas/cap/v2/entity.schema.json +64 -0
  66. package/schemas/cap/v2/manifest.schema.json +67 -0
  67. package/schemas/cap/v2/relation.schema.json +82 -0
  68. package/schemas/compute-catalog.schema.json +63 -0
  69. package/schemas/compute-decision.schema.json +27 -0
  70. package/schemas/execution-contract.schema.json +1024 -0
  71. package/schemas/research-card.schema.json +30 -0
  72. package/schemas/research-inventory-draft.schema.json +366 -0
  73. package/schemas/research.schema.json +1044 -0
  74. package/schemas/result.schema.json +173 -0
  75. package/schemas/verification-policy.schema.json +47 -0
  76. package/schemas/verified-conclusion.schema.json +58 -0
  77. package/schemas/workspace-summary.schema.json +24 -0
  78. package/scripts/build-arkgraph-view.mjs +12 -0
  79. package/scripts/check-execution-feasibility.mjs +24 -0
  80. package/scripts/check-syntax.mjs +15 -0
  81. package/scripts/deterministic-asset-preparation.py +438 -0
  82. package/scripts/package-cap.mjs +23 -0
  83. package/scripts/package-local-agent.mjs +23 -0
  84. package/scripts/preview-arkgraph.mjs +25 -0
  85. package/scripts/replay-research-compiler-candidate.mjs +134 -0
  86. package/scripts/review-compiler-sources.mjs +44 -0
  87. package/scripts/run-asset-preparation.sh +17 -0
  88. package/scripts/run-research-plan.mjs +98 -0
  89. package/scripts/validate-asset-preparation.py +290 -0
  90. package/scripts/verify-local-runtime.mjs +57 -0
  91. package/scripts/verify-npm-package.mjs +57 -0
  92. package/src/adapters/paper2agent.mjs +107 -0
  93. package/src/assets/cache.mjs +159 -0
  94. package/src/assets/compute.mjs +98 -0
  95. package/src/assets/executor.mjs +145 -0
  96. package/src/assets/lifecycle.mjs +213 -0
  97. package/src/assets/manifest.mjs +242 -0
  98. package/src/assets/opportunistic-preparation.mjs +81 -0
  99. package/src/assets/plan.mjs +411 -0
  100. package/src/assets/prompts.mjs +29 -0
  101. package/src/assets/public-asset-probe.mjs +525 -0
  102. package/src/assets/qualification.mjs +119 -0
  103. package/src/assets/readiness.mjs +130 -0
  104. package/src/assets/reproduction-admission.mjs +355 -0
  105. package/src/assets/requirements.mjs +152 -0
  106. package/src/assets/source-grounding.mjs +341 -0
  107. package/src/assets/source-policy.mjs +118 -0
  108. package/src/autodl/client.mjs +260 -0
  109. package/src/autodl/ssh.mjs +380 -0
  110. package/src/autodl/tools.mjs +129 -0
  111. package/src/cap/redaction.mjs +38 -0
  112. package/src/cap/v2/archive.mjs +152 -0
  113. package/src/cap/v2/attestation.mjs +204 -0
  114. package/src/cap/v2/canonical-json.mjs +114 -0
  115. package/src/cap/v2/compilation-artifact.mjs +240 -0
  116. package/src/cap/v2/core.mjs +282 -0
  117. package/src/cap/v2/measurement-assessment-records.mjs +23 -0
  118. package/src/cap/v2/pipeline-artifact.mjs +922 -0
  119. package/src/cap/v2/read.mjs +41 -0
  120. package/src/cap/v2/reassessment-artifact.mjs +383 -0
  121. package/src/cap/v2/research-artifact.mjs +231 -0
  122. package/src/cap/v2/research-map-records.mjs +46 -0
  123. package/src/cap/v2/research-object-records.mjs +163 -0
  124. package/src/cap/v2/research-records.mjs +187 -0
  125. package/src/cap/v2/verify.mjs +642 -0
  126. package/src/cli.mjs +1146 -0
  127. package/src/compute/autodl-pro-compiler.mjs +347 -0
  128. package/src/compute/autodl-pro-executor.mjs +459 -0
  129. package/src/compute/autodl-pro-job.mjs +843 -0
  130. package/src/compute/autodl-pro-network.mjs +295 -0
  131. package/src/compute/autodl-pro-remote.mjs +810 -0
  132. package/src/compute/autodl-pro-staging.mjs +117 -0
  133. package/src/compute/campaign.mjs +110 -0
  134. package/src/compute/catalog.mjs +123 -0
  135. package/src/compute/checkpoint-protocol.mjs +154 -0
  136. package/src/compute/codex-account-lock.mjs +111 -0
  137. package/src/compute/codex-account-session.mjs +107 -0
  138. package/src/compute/compiler-profile.mjs +38 -0
  139. package/src/compute/compiler-router.mjs +23 -0
  140. package/src/compute/coordinator-recovery.mjs +210 -0
  141. package/src/compute/executor-router.mjs +29 -0
  142. package/src/compute/gcp-batch-compiler.mjs +685 -0
  143. package/src/compute/gcp-batch-executor.mjs +1215 -0
  144. package/src/compute/gcp-batch-failure.mjs +92 -0
  145. package/src/compute/gcp-batch-job.mjs +527 -0
  146. package/src/compute/gcp-batch-lifecycle.mjs +81 -0
  147. package/src/compute/gcp-checkpoint-worker.mjs +1633 -0
  148. package/src/compute/local-codex-compiler.mjs +52 -0
  149. package/src/compute/measurement-hardware.mjs +128 -0
  150. package/src/compute/remote-attempt.mjs +226 -0
  151. package/src/compute/requirements.mjs +124 -0
  152. package/src/compute/research-phases.mjs +48 -0
  153. package/src/compute/scheduler.mjs +452 -0
  154. package/src/compute/shared-workloads.mjs +26 -0
  155. package/src/compute/stage-archive.mjs +79 -0
  156. package/src/contracts/campaign-contract.mjs +52 -0
  157. package/src/contracts/execution-contract.mjs +819 -0
  158. package/src/contracts/execution-mode.mjs +19 -0
  159. package/src/contracts/execution-timeouts.mjs +45 -0
  160. package/src/contracts/execution-workload.mjs +68 -0
  161. package/src/contracts/preflight-schema.mjs +25 -0
  162. package/src/contracts/public-contract.mjs +63 -0
  163. package/src/contracts/subject-tags.mjs +31 -0
  164. package/src/dashboard/data.mjs +898 -0
  165. package/src/dashboard/server.mjs +79 -0
  166. package/src/dashboard/static/dashboard.css +366 -0
  167. package/src/dashboard/static/dashboard.js +560 -0
  168. package/src/dashboard/static/index.html +85 -0
  169. package/src/deployment/community-policy.mjs +9 -0
  170. package/src/deployment/environment.mjs +112 -0
  171. package/src/deployment/guided.mjs +98 -0
  172. package/src/deployment/handoff.mjs +102 -0
  173. package/src/deployment/local-contract.mjs +31 -0
  174. package/src/deployment/local.mjs +100 -0
  175. package/src/deployment/prepare.mjs +46 -0
  176. package/src/deployment/recipe.mjs +108 -0
  177. package/src/deployment/supplement.mjs +51 -0
  178. package/src/deployment/terminal.mjs +43 -0
  179. package/src/diagnosis/renderer.mjs +75 -0
  180. package/src/diagnosis/target-failure.mjs +46 -0
  181. package/src/evidence/parser-registry.mjs +54 -0
  182. package/src/evidence/parsers/fasttext-classification.mjs +82 -0
  183. package/src/evidence/parsers/json-scalar.mjs +96 -0
  184. package/src/evidence/parsers/simcse-senteval.mjs +104 -0
  185. package/src/evidence/parsers/starspace-classification.mjs +78 -0
  186. package/src/evidence/registry.mjs +147 -0
  187. package/src/execution/runner-audit.mjs +473 -0
  188. package/src/gcp/auth.mjs +106 -0
  189. package/src/gcp/batch-client.mjs +120 -0
  190. package/src/gcp/resource-discovery.mjs +177 -0
  191. package/src/gcp/rest.mjs +82 -0
  192. package/src/gcp/secret-manager.mjs +34 -0
  193. package/src/gcp/signed-url.mjs +133 -0
  194. package/src/gcp/storage.mjs +220 -0
  195. package/src/graph/command.mjs +41 -0
  196. package/src/graph/execution.mjs +97 -0
  197. package/src/graph/model.mjs +37 -0
  198. package/src/graph/presentation.mjs +110 -0
  199. package/src/graph/query.mjs +159 -0
  200. package/src/graph/research-relations.mjs +69 -0
  201. package/src/graph/source-page.mjs +12 -0
  202. package/src/graph/source-preview.mjs +34 -0
  203. package/src/graph/validate.mjs +76 -0
  204. package/src/job.mjs +496 -0
  205. package/src/network/autodl-routing-proxy.mjs +462 -0
  206. package/src/network/egress-proxy.mjs +158 -0
  207. package/src/observability/event-contract.mjs +230 -0
  208. package/src/observability/pipeline-monitor.mjs +166 -0
  209. package/src/pipeline/orchestrator.mjs +1281 -0
  210. package/src/pipeline/recovery-error.mjs +11 -0
  211. package/src/pipeline/replay.mjs +304 -0
  212. package/src/pipeline/shared-execution.mjs +115 -0
  213. package/src/pipeline/stage-checkpoint.mjs +86 -0
  214. package/src/pipeline/stage-recovery.mjs +101 -0
  215. package/src/pipeline/targets.mjs +110 -0
  216. package/src/process.mjs +143 -0
  217. package/src/protocol.mjs +312 -0
  218. package/src/provider/codex-account.mjs +44 -0
  219. package/src/provider/codex-completion.mjs +49 -0
  220. package/src/provider/completion.mjs +292 -0
  221. package/src/provider/model-client.mjs +44 -0
  222. package/src/provider/model-route.mjs +29 -0
  223. package/src/provider/openrouter-readiness.mjs +189 -0
  224. package/src/provider/reader-bridge.mjs +35 -0
  225. package/src/provider/relay.mjs +263 -0
  226. package/src/provider/runtime-auth.mjs +40 -0
  227. package/src/public/cap.d.mts +90 -0
  228. package/src/public/cap.mjs +12 -0
  229. package/src/public/contracts.d.mts +2 -0
  230. package/src/public/host.mjs +171 -0
  231. package/src/public/operations.d.mts +11 -0
  232. package/src/public/presentation.d.mts +4 -0
  233. package/src/records/views.mjs +26 -0
  234. package/src/remote/command.mjs +178 -0
  235. package/src/remote/ssh.mjs +59 -0
  236. package/src/repository-origin.mjs +81 -0
  237. package/src/reproduction/evidence-feedback.mjs +96 -0
  238. package/src/reproduction/incomplete-initialization.mjs +25 -0
  239. package/src/reproduction/lifecycle.mjs +253 -0
  240. package/src/reproduction/plan.mjs +132 -0
  241. package/src/reproduction/prompts.mjs +70 -0
  242. package/src/reproduction/runner.mjs +188 -0
  243. package/src/reproduction/summary.mjs +130 -0
  244. package/src/reproduction/workspace-mode.mjs +7 -0
  245. package/src/research/automatic-admission.mjs +156 -0
  246. package/src/research/compiler-coverage.mjs +85 -0
  247. package/src/research/compiler-failure.mjs +24 -0
  248. package/src/research/compiler-normalization-guards.mjs +112 -0
  249. package/src/research/compiler-repair.mjs +3 -0
  250. package/src/research/compiler.mjs +853 -0
  251. package/src/research/continuation-selection.mjs +26 -0
  252. package/src/research/execution-graph-context.mjs +43 -0
  253. package/src/research/experiment-importance.mjs +15 -0
  254. package/src/research/inventory-handoff.mjs +104 -0
  255. package/src/research/inventory-revisions.mjs +32 -0
  256. package/src/research/mineru-local.mjs +73 -0
  257. package/src/research/paper-command.mjs +19 -0
  258. package/src/research/paper-markdown.mjs +180 -0
  259. package/src/research/paper-source-map.mjs +69 -0
  260. package/src/research/planning-policy.mjs +88 -0
  261. package/src/research/reference-materials.mjs +11 -0
  262. package/src/research/reproduction-scope.mjs +30 -0
  263. package/src/research/research-map.mjs +94 -0
  264. package/src/research/research-objects.mjs +88 -0
  265. package/src/research/source-discovery.mjs +646 -0
  266. package/src/research/source-observations.mjs +75 -0
  267. package/src/research/source-review-cli-mcp.mjs +26 -0
  268. package/src/research/source-review-input.mjs +209 -0
  269. package/src/research/source-review-local-codex.mjs +36 -0
  270. package/src/research/source-review-model.mjs +70 -0
  271. package/src/research/source-review.mjs +173 -0
  272. package/src/research/structure.mjs +3163 -0
  273. package/src/research-card/renderer.mjs +277 -0
  274. package/src/research-card/verified-conclusion.mjs +143 -0
  275. package/src/results/output-registry.mjs +183 -0
  276. package/src/runtime/claude-code.mjs +52 -0
  277. package/src/runtime/codex-capacity-retry.mjs +87 -0
  278. package/src/runtime/codex.mjs +64 -0
  279. package/src/runtime/config.mjs +157 -0
  280. package/src/runtime/final-output.mjs +40 -0
  281. package/src/runtime/index.mjs +21 -0
  282. package/src/runtime/local-codex.mjs +74 -0
  283. package/src/runtime/opencode.mjs +95 -0
  284. package/src/runtime/prompt.mjs +13 -0
  285. package/src/sandbox/docker.mjs +363 -0
  286. package/src/settings/command.mjs +297 -0
  287. package/src/settings/store.mjs +119 -0
  288. package/src/telemetry/pricing.mjs +68 -0
  289. package/src/telemetry/usage.mjs +265 -0
  290. package/src/terminal/events.mjs +97 -0
  291. package/src/terminal/input.mjs +40 -0
  292. package/src/terminal/plain.mjs +40 -0
  293. package/src/terminal/remote-stream.mjs +22 -0
  294. package/src/terminal/screen.mjs +214 -0
  295. package/src/terminal/transcript.mjs +69 -0
  296. package/src/util.mjs +107 -0
  297. package/src/verification/ai-assessor.mjs +534 -0
  298. package/src/verification/claim-evaluator.mjs +242 -0
  299. package/src/verification/evidence-context.mjs +165 -0
  300. package/src/verification/evidence-reader.mjs +95 -0
  301. package/src/verification/integrity.mjs +570 -0
  302. package/src/verification/tolerance.mjs +32 -0
  303. package/src/workloads/cpu-research-preparation.mjs +56 -0
  304. package/src/workloads/definition.mjs +74 -0
  305. package/src/workloads/phase-aware-reproduction.mjs +46 -0
  306. package/src/workloads/reproduction.mjs +85 -0
  307. package/src/workspace/command.mjs +242 -0
  308. package/src/workspace/control.mjs +49 -0
  309. package/src/workspace/entry.mjs +28 -0
  310. package/src/workspace/input.mjs +93 -0
  311. package/src/workspace/interactive.mjs +94 -0
  312. package/src/workspace/jobs.mjs +418 -0
  313. package/src/workspace/session.mjs +97 -0
  314. package/src/workspace/worker.mjs +137 -0
  315. package/ui/arkgraph/ambient-motion.mjs +10 -0
  316. package/ui/arkgraph/app.jsx +153 -0
  317. package/ui/arkgraph/boot.js +6 -0
  318. package/ui/arkgraph/camera-motion.mjs +20 -0
  319. package/ui/arkgraph/context-reveal.mjs +39 -0
  320. package/ui/arkgraph/details.css +3 -0
  321. package/ui/arkgraph/entry.jsx +28 -0
  322. package/ui/arkgraph/experiment-curves.mjs +17 -0
  323. package/ui/arkgraph/experiment-selection.mjs +15 -0
  324. package/ui/arkgraph/experiment-style.css +26 -0
  325. package/ui/arkgraph/experiment-ui.jsx +32 -0
  326. package/ui/arkgraph/frame.html +1 -0
  327. package/ui/arkgraph/graph-gestures.mjs +62 -0
  328. package/ui/arkgraph/label-layout.mjs +57 -0
  329. package/ui/arkgraph/locales/en.json +229 -0
  330. package/ui/arkgraph/locales/source-types.json +15 -0
  331. package/ui/arkgraph/localization-build.mjs +27 -0
  332. package/ui/arkgraph/material-build.mjs +23 -0
  333. package/ui/arkgraph/material-colors.mjs +39 -0
  334. package/ui/arkgraph/material-style.css +15 -0
  335. package/ui/arkgraph/open-graph.jsx +326 -0
  336. package/ui/arkgraph/outline.jsx +49 -0
  337. package/ui/arkgraph/package-lock.json +888 -0
  338. package/ui/arkgraph/package.json +17 -0
  339. package/ui/arkgraph/reading-layout.mjs +130 -0
  340. package/ui/arkgraph/reading-presentation.mjs +73 -0
  341. package/ui/arkgraph/record-detail.css +51 -0
  342. package/ui/arkgraph/record-details.jsx +29 -0
  343. package/ui/arkgraph/research-types.mjs +31 -0
  344. package/ui/arkgraph/selection-mark.jsx +6 -0
  345. package/ui/arkgraph/soft-spine.mjs +26 -0
  346. package/ui/arkgraph/steering-style.css +187 -0
  347. package/ui/arkgraph/style.css +272 -0
@@ -0,0 +1,107 @@
1
+ import { readFile, writeFile, mkdir, chmod, unlink } from "node:fs/promises";
2
+ import { createHash } from "node:crypto";
3
+ import { pathToFileURL } from "node:url";
4
+
5
+ export function validateCodexLogin(text) {
6
+ let value;
7
+ try { value = JSON.parse(text); } catch { throw new Error("codex.account_invalid_login"); }
8
+ if (value.auth_mode !== "chatgpt" || !value.tokens?.access_token || !value.tokens?.refresh_token || !value.tokens?.account_id
9
+ || value.OPENAI_API_KEY) throw new Error("codex.account_invalid_login");
10
+ return value;
11
+ }
12
+
13
+ // This file runs as the existing Batch supervisor, never as a model API proxy.
14
+ // The lock has no automatic expiry: a dead VM must be verified before an operator
15
+ // removes its lock, so a delayed worker cannot overwrite another login refresh.
16
+ export async function accountSession(action, { env = process.env, fetchImpl = fetch } = {}) {
17
+ const id = env.CITEARK_CODEX_ACCOUNT_ID;
18
+ if (!id) return;
19
+ if (!/^[a-z0-9][a-z0-9-]{0,47}$/.test(id)) throw new Error("codex.account_invalid_id");
20
+ const secret = env.CITEARK_CODEX_AUTH_SECRET;
21
+ if (!/^projects\/[^/]+\/secrets\/citeark-codex-[a-z0-9-]+\/versions\/latest$/.test(secret ?? "")) throw new Error("codex.account_invalid_secret");
22
+ const bucket = env.CITEARK_CODEX_ACCOUNT_BUCKET;
23
+ const owner = env.CITEARK_CODEX_ACCOUNT_OWNER;
24
+ if (!bucket || !owner) throw new Error("codex.account_missing_binding");
25
+ const home = env.CODEX_HOME;
26
+ if (!home) throw new Error("codex.account_missing_home");
27
+ const statePath = env.CITEARK_CODEX_ACCOUNT_STATE ?? `/tmp/citeark-codex-${id}-session.json`;
28
+ const authPath = `${home}/auth.json`;
29
+ const coordinatorManaged = env.CITEARK_CODEX_ACCOUNT_LOCK_MODE === "coordinator";
30
+ const digest = (text) => createHash("sha256").update(text).digest("hex");
31
+ const response = await fetchImpl("http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token", {
32
+ headers: { "Metadata-Flavor": "Google" }, signal: AbortSignal.timeout(10000),
33
+ });
34
+ if (!response.ok) throw new Error("codex.account_metadata_unavailable");
35
+ const { access_token: token } = await response.json();
36
+ if (!token) throw new Error("codex.account_metadata_unavailable");
37
+ const request = (url, options = {}) => fetchImpl(url, { ...options,
38
+ headers: { authorization: `Bearer ${token}`, "content-type": "application/json", ...options.headers }, signal: AbortSignal.timeout(20000) });
39
+ const object = `codex-accounts/${id}/active.json`;
40
+ const objectUrl = `https://storage.googleapis.com/storage/v1/b/${encodeURIComponent(bucket)}/o/${encodeURIComponent(object)}`;
41
+ if (action === "open") {
42
+ let generation;
43
+ if (coordinatorManaged) {
44
+ const lock = await request(`${objectUrl}?alt=media`);
45
+ if (!lock.ok) throw new Error("codex.account_lock_lost");
46
+ const current = await lock.json();
47
+ generation = lock.headers.get("x-goog-generation");
48
+ if (current?.owner !== owner || !/^\d+$/.test(generation ?? "")) {
49
+ throw new Error("codex.account_owner_mismatch");
50
+ }
51
+ } else {
52
+ const lock = await request(`https://storage.googleapis.com/upload/storage/v1/b/${encodeURIComponent(bucket)}/o?uploadType=media&name=${encodeURIComponent(object)}&ifGenerationMatch=0`, {
53
+ method: "POST", body: JSON.stringify({ owner, createdAt: new Date().toISOString() }),
54
+ });
55
+ if (!lock.ok) throw new Error(lock.status === 412 ? "codex.account_busy" : "codex.account_lock_failed");
56
+ ({ generation } = await lock.json());
57
+ }
58
+ const state = { owner, generation, digest: null };
59
+ await writeFile(statePath, JSON.stringify(state), { mode: 0o600 });
60
+ try {
61
+ const login = await request(`https://secretmanager.googleapis.com/v1/${secret}:access`);
62
+ if (!login.ok) throw new Error("codex.account_login_required");
63
+ const text = Buffer.from((await login.json()).payload.data, "base64").toString("utf8");
64
+ validateCodexLogin(text);
65
+ await mkdir(home, { recursive: true });
66
+ await writeFile(authPath, text, { mode: 0o600 });
67
+ await chmod(authPath, 0o600);
68
+ state.digest = digest(text);
69
+ await writeFile(statePath, JSON.stringify(state), { mode: 0o600 });
70
+ } catch (error) {
71
+ if (!coordinatorManaged) {
72
+ await request(`${objectUrl}?ifGenerationMatch=${generation}`, { method: "DELETE" });
73
+ }
74
+ await unlink(statePath).catch(() => {});
75
+ throw error;
76
+ }
77
+ return;
78
+ }
79
+ if (!new Set(["save", "close"]).has(action)) throw new Error("codex.account_invalid_action");
80
+ let state;
81
+ try { state = JSON.parse(await readFile(statePath, "utf8")); } catch (error) {
82
+ if (action === "close" && error.code === "ENOENT") return;
83
+ throw new Error("codex.account_state_missing");
84
+ }
85
+ if (state.owner !== owner) throw new Error("codex.account_owner_mismatch");
86
+ const lock = await request(objectUrl);
87
+ if (!lock.ok || String((await lock.json()).generation) !== String(state.generation)) throw new Error("codex.account_lock_lost");
88
+ const text = await readFile(authPath, "utf8");
89
+ validateCodexLogin(text);
90
+ if (digest(text) !== state.digest) {
91
+ const saved = await request(`https://secretmanager.googleapis.com/v1/${secret.replace(/\/versions\/latest$/, "")}:addVersion`, {
92
+ method: "POST", body: JSON.stringify({ payload: { data: Buffer.from(text).toString("base64") } }),
93
+ });
94
+ if (!saved.ok) throw new Error("codex.account_refresh_save_failed");
95
+ state.digest = digest(text);
96
+ await writeFile(statePath, JSON.stringify(state), { mode: 0o600 });
97
+ }
98
+ if (action === "close" && !coordinatorManaged) {
99
+ const released = await request(`${objectUrl}?ifGenerationMatch=${state.generation}`, { method: "DELETE" });
100
+ if (!released.ok) throw new Error("codex.account_release_failed");
101
+ }
102
+ if (action === "close") await unlink(statePath);
103
+ }
104
+
105
+ if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
106
+ accountSession(process.argv[2]).catch((error) => { console.error(/^codex\.account_[a-z_]+$/.test(error.message) ? error.message : "codex.account_session_failed"); process.exitCode = 1; });
107
+ }
@@ -0,0 +1,38 @@
1
+ export const MINIMUM_COMPILER_BOOT_DISK_GB = 30;
2
+
3
+ /**
4
+ * Research Compiler only needs the immutable runtime, fixed paper/repository
5
+ * snapshot and small audit outputs. It may enlarge a selected profile, but it
6
+ * must never shrink the boot disk below the immutable image/profile minimum.
7
+ */
8
+ export function compilerExecutionProfile(profile, {
9
+ bootDiskGb,
10
+ } = {}) {
11
+ if (!profile || typeof profile !== "object" || Array.isArray(profile)) {
12
+ throw new TypeError("Research Compiler 资源规格无效");
13
+ }
14
+ const profileDisk = Number(profile.executorConfig?.bootDiskGb);
15
+ if (
16
+ !Number.isInteger(profileDisk)
17
+ || profileDisk < MINIMUM_COMPILER_BOOT_DISK_GB
18
+ || profileDisk > 500
19
+ ) {
20
+ throw new TypeError("Research Compiler 资源规格必须声明 30–500 GiB 的启动盘");
21
+ }
22
+ const disk = bootDiskGb === undefined ? profileDisk : Number(bootDiskGb);
23
+ if (!Number.isInteger(disk) || disk < MINIMUM_COMPILER_BOOT_DISK_GB || disk > 500) {
24
+ throw new TypeError("Research Compiler 启动盘必须是 30–500 GiB 的整数");
25
+ }
26
+ if (disk < profileDisk) {
27
+ throw new TypeError(
28
+ `Research Compiler 启动盘 ${disk} GiB 不能小于所选镜像规格 ${profileDisk} GiB`,
29
+ );
30
+ }
31
+ return {
32
+ ...structuredClone(profile),
33
+ executorConfig: {
34
+ ...structuredClone(profile.executorConfig ?? {}),
35
+ bootDiskGb: disk,
36
+ },
37
+ };
38
+ }
@@ -0,0 +1,23 @@
1
+ import { CiteArkError } from "../util.mjs";
2
+ import { executeAutoDlProCompilation } from "./autodl-pro-compiler.mjs";
3
+ import { executeGcpBatchCompilation } from "./gcp-batch-compiler.mjs";
4
+
5
+ const COMPILER_ADAPTERS = new Map([
6
+ ["gcp-batch", executeGcpBatchCompilation],
7
+ ["autodl-pro", executeAutoDlProCompilation],
8
+ ]);
9
+
10
+ export function listCompilerExecutors() {
11
+ return [...COMPILER_ADAPTERS.keys()].sort();
12
+ }
13
+
14
+ export async function executeScheduledCompilation(options) {
15
+ const executor = options.computeProfile?.executor;
16
+ const adapter = COMPILER_ADAPTERS.get(executor);
17
+ if (!adapter) {
18
+ throw new CiteArkError(
19
+ `Research Compiler 选择了尚未注册的 executor:${executor ?? "未指定"}。当前可用:${listCompilerExecutors().join("、")}`,
20
+ );
21
+ }
22
+ return await adapter(options);
23
+ }
@@ -0,0 +1,210 @@
1
+ import { mkdir } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { pathExists, readJson, sha256File, writeJson } from "../util.mjs";
4
+ import { relocateStageValue } from "../pipeline/stage-checkpoint.mjs";
5
+
6
+ export async function saveRunRecovery(bundle, persist) {
7
+ if (typeof persist !== "function") return;
8
+ const value = Object.fromEntries(
9
+ [
10
+ "runId",
11
+ "sessionId",
12
+ "task",
13
+ "runtimeTask",
14
+ "directories",
15
+ "state",
16
+ "beforeSnapshot",
17
+ "repositoryProvenance",
18
+ "repositoryIdentity",
19
+ "repairBaselineResearch",
20
+ "sourceInventory",
21
+ "attempts",
22
+ "computeDecision",
23
+ "executionEnvironment",
24
+ "sandboxProvider",
25
+ "sandboxImageIdentity",
26
+ ]
27
+ .filter((key) => bundle[key] !== undefined)
28
+ .map((key) => [key, bundle[key]]),
29
+ );
30
+ await writeJson(path.join(bundle.directories.run, "run.json"), bundle.state);
31
+ await writeJson(path.join(bundle.directories.run, "recovery-bundle.json"), {
32
+ schemaVersion: "1.0",
33
+ root: bundle.directories.run,
34
+ value,
35
+ });
36
+ await persist();
37
+ }
38
+
39
+ export async function restoreRunRecovery({ runsDirectory, runId, task }) {
40
+ if (!runId) return null;
41
+ const root = path.resolve(runsDirectory, runId);
42
+ const filename = path.join(root, "recovery-bundle.json");
43
+ if (!(await pathExists(filename))) return null;
44
+ const saved = await readJson(filename);
45
+ const bundle = relocateStageValue(saved.value, saved.root, root);
46
+ if (
47
+ task?.contractDigest &&
48
+ task.contractDigest !== bundle.task?.contractDigest
49
+ )
50
+ throw new Error("Restored run has a different execution contract");
51
+ bundle.state = await readJson(path.join(root, "run.json"));
52
+ for (const directory of Object.values(bundle.directories))
53
+ await mkdir(directory, { recursive: true });
54
+ bundle.restored = true;
55
+ return bundle;
56
+ }
57
+
58
+ // Copy the latest complete remote checkpoint into the coordinator's private
59
+ // content-addressed recovery store. GCS expiry must not erase the only resume
60
+ // path after a worker exits. Its bytes are never public evidence.
61
+ export async function saveRemoteRecovery({
62
+ bundle,
63
+ storage,
64
+ bucket,
65
+ record,
66
+ persist,
67
+ recoveryBucket,
68
+ recoveryNamespace,
69
+ }) {
70
+ if (typeof persist !== "function") return;
71
+ const checkpoint = record.checkpoint;
72
+ if (
73
+ checkpoint?.object &&
74
+ checkpoint.sha256 &&
75
+ checkpoint.sequence !== bundle.state.durableRemoteCheckpoint?.sequence
76
+ ) {
77
+ if (recoveryBucket) {
78
+ if (typeof storage.copyObject !== "function")
79
+ throw new Error("Durable cloud recovery copy is unavailable");
80
+ const sourcePrefix = record.checkpointPrefix;
81
+ if (!sourcePrefix || !checkpoint.object.startsWith(`${sourcePrefix}-`))
82
+ throw new Error("Recovery checkpoint prefix mismatch");
83
+ const namespace = recoveryNamespace ? `${recoveryNamespace}-` : "";
84
+ if (recoveryNamespace && !/^[a-zA-Z0-9-]{1,200}$/.test(recoveryNamespace))
85
+ throw new Error("Invalid recovery namespace");
86
+ const checkpointPrefix = `recovery-${namespace}${sourcePrefix}`;
87
+ const object =
88
+ checkpointPrefix + checkpoint.object.slice(sourcePrefix.length);
89
+ const copied = await storage.copyObject({
90
+ sourceBucket: bucket,
91
+ sourceObject: checkpoint.object,
92
+ destinationBucket: recoveryBucket,
93
+ destinationObject: object,
94
+ });
95
+ if (
96
+ checkpoint.bytes != null &&
97
+ Number(copied?.size) !== Number(checkpoint.bytes)
98
+ )
99
+ throw new Error("Cloud recovery copy size mismatch");
100
+ const saved = {
101
+ ...checkpoint,
102
+ bucket: recoveryBucket,
103
+ object,
104
+ checkpointPrefix,
105
+ checkpointStatus: `${checkpointPrefix}-status.json`,
106
+ durable: true,
107
+ };
108
+ await storage.writeJsonObject({
109
+ bucket: recoveryBucket,
110
+ object: saved.checkpointStatus,
111
+ value: saved,
112
+ });
113
+ bundle.state.durableRemoteCheckpoint = saved;
114
+ bundle.state.durableRemoteCheckpoints = {
115
+ ...bundle.state.durableRemoteCheckpoints,
116
+ [checkpoint.kind === "full" ? "full" : "critical"]: saved,
117
+ };
118
+ await saveRunRecovery(bundle, persist);
119
+ return;
120
+ }
121
+ const filename = path.join(
122
+ bundle.directories.run,
123
+ "recovery",
124
+ `remote-recovery-${checkpoint.kind === "full" ? "full" : "critical"}.tar.gz`,
125
+ );
126
+ await mkdir(path.dirname(filename), { recursive: true });
127
+ await storage.downloadFile({
128
+ bucket,
129
+ object: checkpoint.object,
130
+ filePath: filename,
131
+ });
132
+ const observed = await sha256File(filename);
133
+ if (observed !== checkpoint.sha256.replace(/^sha256:/, ""))
134
+ throw new Error("Remote recovery checkpoint digest mismatch");
135
+ bundle.state.durableRemoteCheckpoint = {
136
+ ...checkpoint,
137
+ bucket,
138
+ checkpointPrefix: record.checkpointPrefix,
139
+ checkpointStatus: record.checkpointStatus,
140
+ localPath: filename,
141
+ };
142
+ bundle.state.durableRemoteCheckpoints = {
143
+ ...bundle.state.durableRemoteCheckpoints,
144
+ [checkpoint.kind === "full" ? "full" : "critical"]:
145
+ bundle.state.durableRemoteCheckpoint,
146
+ };
147
+ await writeJson(
148
+ path.join(bundle.directories.run, "run.json"),
149
+ bundle.state,
150
+ );
151
+ }
152
+ await saveRunRecovery(bundle, persist);
153
+ }
154
+
155
+ export async function restoreRemoteRecovery({ bundle, storage, bucket }) {
156
+ const checkpoint = bundle.state.durableRemoteCheckpoint;
157
+ if (checkpoint?.durable === true)
158
+ return {
159
+ bucket: checkpoint.bucket,
160
+ checkpointPrefix: checkpoint.checkpointPrefix,
161
+ };
162
+ if (!checkpoint?.localPath) return null;
163
+ const generations = bundle.state.durableRemoteCheckpoints ?? {
164
+ [checkpoint.kind === "full" ? "full" : "critical"]: checkpoint,
165
+ };
166
+ const selected = [generations.full, generations.critical].filter(
167
+ (item) =>
168
+ item &&
169
+ (item.kind !== "critical" ||
170
+ !generations.full ||
171
+ item.createdAt >= generations.full.createdAt),
172
+ );
173
+ for (const item of selected) {
174
+ const filename = path.join(
175
+ bundle.directories.run,
176
+ "recovery",
177
+ `remote-recovery-${item.kind === "full" ? "full" : "critical"}.tar.gz`,
178
+ );
179
+ if (
180
+ `sha256:${await sha256File(filename)}` !==
181
+ `sha256:${item.sha256.replace(/^sha256:/, "")}`
182
+ )
183
+ throw new Error("Stored remote checkpoint digest mismatch");
184
+ await storage.uploadFile({
185
+ bucket,
186
+ object: item.object,
187
+ filePath: filename,
188
+ });
189
+ }
190
+ const statusPath = path.join(
191
+ bundle.directories.run,
192
+ "recovery",
193
+ "remote-recovery-status.json",
194
+ );
195
+ const {
196
+ localPath: _path,
197
+ bucket: _bucket,
198
+ checkpointPrefix: _prefix,
199
+ checkpointStatus: _status,
200
+ ...status
201
+ } = checkpoint;
202
+ await writeJson(statusPath, status);
203
+ await storage.uploadFile({
204
+ bucket,
205
+ object: checkpoint.checkpointStatus,
206
+ filePath: statusPath,
207
+ contentType: "application/json",
208
+ });
209
+ return { bucket, checkpointPrefix: checkpoint.checkpointPrefix };
210
+ }
@@ -0,0 +1,29 @@
1
+ import { executeReproduction } from "../reproduction/runner.mjs";
2
+ import { executeResearchPhases } from "./research-phases.mjs";
3
+ import { executeAutoDlProReproduction } from "./autodl-pro-executor.mjs";
4
+ import { CiteArkError } from "../util.mjs";
5
+
6
+ const EXECUTOR_ADAPTERS = new Map([
7
+ ["local-docker", executeLocalDocker],
8
+ ["gcp-batch", executeResearchPhases],
9
+ ["autodl-pro", executeAutoDlProReproduction],
10
+ ]);
11
+
12
+ export function listComputeExecutors() {
13
+ return [...EXECUTOR_ADAPTERS.keys()].sort();
14
+ }
15
+
16
+ export async function executeScheduledReproduction(options) {
17
+ const executor = options.computeDecision?.selectedProfile?.executor ?? "local-docker";
18
+ const adapter = EXECUTOR_ADAPTERS.get(executor);
19
+ if (!adapter) {
20
+ throw new CiteArkError(
21
+ `计算调度选择了尚未注册执行适配器的 executor:${executor}。当前可用:${listComputeExecutors().join("、")}`,
22
+ );
23
+ }
24
+ return await adapter(options);
25
+ }
26
+
27
+ async function executeLocalDocker(options) {
28
+ return await executeReproduction(options);
29
+ }