@tiangong-ai/cli 0.0.60 → 0.0.62

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 (239) hide show
  1. package/AGENTS.md +17 -6
  2. package/README.md +577 -55
  3. package/dist/data/builtins.js +33 -5
  4. package/dist/data/builtins.js.map +1 -1
  5. package/dist/data/catalog.js +46 -0
  6. package/dist/data/catalog.js.map +1 -1
  7. package/dist/data/commands.js +15 -1
  8. package/dist/data/commands.js.map +1 -1
  9. package/dist/data/connectors/airnow-hourly-observations.js +60 -10
  10. package/dist/data/connectors/airnow-hourly-observations.js.map +1 -1
  11. package/dist/data/connectors/epa-eis-records.js +16 -2
  12. package/dist/data/connectors/epa-eis-records.js.map +1 -1
  13. package/dist/data/connectors/gdelt-doc-search.js +54 -18
  14. package/dist/data/connectors/gdelt-doc-search.js.map +1 -1
  15. package/dist/data/connectors/gdelt-file-feeds.js +20 -11
  16. package/dist/data/connectors/gdelt-file-feeds.js.map +1 -1
  17. package/dist/data/connectors/gdelt-web-ngrams.d.ts +2 -0
  18. package/dist/data/connectors/gdelt-web-ngrams.js +350 -0
  19. package/dist/data/connectors/gdelt-web-ngrams.js.map +1 -0
  20. package/dist/data/connectors/gdelt-web-ngrams.schemas.d.ts +188 -0
  21. package/dist/data/connectors/gdelt-web-ngrams.schemas.js +138 -0
  22. package/dist/data/connectors/gdelt-web-ngrams.schemas.js.map +1 -0
  23. package/dist/data/connectors/nasa-firms-fire.js +4 -0
  24. package/dist/data/connectors/nasa-firms-fire.js.map +1 -1
  25. package/dist/data/connectors/open-meteo-air-quality.js +27 -22
  26. package/dist/data/connectors/open-meteo-air-quality.js.map +1 -1
  27. package/dist/data/connectors/open-meteo-air-quality.schemas.d.ts +4 -1
  28. package/dist/data/connectors/open-meteo-air-quality.schemas.js +21 -1
  29. package/dist/data/connectors/open-meteo-air-quality.schemas.js.map +1 -1
  30. package/dist/data/connectors/open-meteo-flood.js +28 -23
  31. package/dist/data/connectors/open-meteo-flood.js.map +1 -1
  32. package/dist/data/connectors/open-meteo-flood.schemas.d.ts +4 -1
  33. package/dist/data/connectors/open-meteo-flood.schemas.js +21 -1
  34. package/dist/data/connectors/open-meteo-flood.schemas.js.map +1 -1
  35. package/dist/data/connectors/open-meteo-historical-weather.js +26 -21
  36. package/dist/data/connectors/open-meteo-historical-weather.js.map +1 -1
  37. package/dist/data/connectors/open-meteo-historical-weather.schemas.d.ts +4 -1
  38. package/dist/data/connectors/open-meteo-historical-weather.schemas.js +21 -1
  39. package/dist/data/connectors/open-meteo-historical-weather.schemas.js.map +1 -1
  40. package/dist/data/connectors/openaq-air-quality.js +50 -12
  41. package/dist/data/connectors/openaq-air-quality.js.map +1 -1
  42. package/dist/data/connectors/openaq-air-quality.schemas.d.ts +0 -4
  43. package/dist/data/connectors/openaq-air-quality.schemas.js +2 -2
  44. package/dist/data/connectors/openaq-air-quality.schemas.js.map +1 -1
  45. package/dist/data/connectors/youtube-public-content.js +76 -6
  46. package/dist/data/connectors/youtube-public-content.js.map +1 -1
  47. package/dist/data/connectors/youtube-public-content.schemas.d.ts +63 -3
  48. package/dist/data/connectors/youtube-public-content.schemas.js +56 -2
  49. package/dist/data/connectors/youtube-public-content.schemas.js.map +1 -1
  50. package/dist/data/contracts.d.ts +22 -1
  51. package/dist/data/runtime/bounded-http.d.ts +2 -0
  52. package/dist/data/runtime/bounded-http.js +221 -59
  53. package/dist/data/runtime/bounded-http.js.map +1 -1
  54. package/dist/data/runtime/execute.d.ts +2 -0
  55. package/dist/data/runtime/execute.js +82 -60
  56. package/dist/data/runtime/execute.js.map +1 -1
  57. package/dist/data/runtime/http-timing.d.ts +15 -0
  58. package/dist/data/runtime/http-timing.js +59 -0
  59. package/dist/data/runtime/http-timing.js.map +1 -0
  60. package/dist/data/runtime/http-transport.d.ts +1 -0
  61. package/dist/data/runtime/http-transport.js +27 -0
  62. package/dist/data/runtime/http-transport.js.map +1 -0
  63. package/dist/data/schemas/catalog.v1.json +46 -0
  64. package/dist/data/schemas/discovery.v1.json +12 -0
  65. package/dist/data/schemas/error.v1.json +1 -0
  66. package/dist/data/schemas/manifest.v1.json +19 -1
  67. package/dist/research/orchestration.js +341 -28
  68. package/dist/research/orchestration.js.map +1 -1
  69. package/dist/research/setup-command.js +37 -6
  70. package/dist/research/setup-command.js.map +1 -1
  71. package/dist/research/workspace/acquisition-routes.d.ts +1 -1
  72. package/dist/research/workspace/acquisition-routes.js +2 -11
  73. package/dist/research/workspace/acquisition-routes.js.map +1 -1
  74. package/dist/research/workspace/artifact-read-audit.d.ts +16 -0
  75. package/dist/research/workspace/artifact-read-audit.js +176 -0
  76. package/dist/research/workspace/artifact-read-audit.js.map +1 -0
  77. package/dist/research/workspace/artifact-trace.d.ts +12 -0
  78. package/dist/research/workspace/artifact-trace.js +109 -0
  79. package/dist/research/workspace/artifact-trace.js.map +1 -0
  80. package/dist/research/workspace/artifact-view-mcp.d.ts +75 -0
  81. package/dist/research/workspace/artifact-view-mcp.js +214 -0
  82. package/dist/research/workspace/artifact-view-mcp.js.map +1 -0
  83. package/dist/research/workspace/artifact-views.d.ts +100 -0
  84. package/dist/research/workspace/artifact-views.js +395 -0
  85. package/dist/research/workspace/artifact-views.js.map +1 -0
  86. package/dist/research/workspace/audit-bundle.d.ts +4 -0
  87. package/dist/research/workspace/audit-bundle.js +130 -11
  88. package/dist/research/workspace/audit-bundle.js.map +1 -1
  89. package/dist/research/workspace/broker.js +25 -4
  90. package/dist/research/workspace/broker.js.map +1 -1
  91. package/dist/research/workspace/constants.d.ts +1 -0
  92. package/dist/research/workspace/constants.js +1 -0
  93. package/dist/research/workspace/constants.js.map +1 -1
  94. package/dist/research/workspace/content-evidence.d.ts +1 -0
  95. package/dist/research/workspace/content-evidence.js +1 -1
  96. package/dist/research/workspace/content-evidence.js.map +1 -1
  97. package/dist/research/workspace/credentials.js +2 -1
  98. package/dist/research/workspace/credentials.js.map +1 -1
  99. package/dist/research/workspace/data-evidence-adapter.d.ts +71 -0
  100. package/dist/research/workspace/data-evidence-adapter.js +269 -59
  101. package/dist/research/workspace/data-evidence-adapter.js.map +1 -1
  102. package/dist/research/workspace/data-evidence-view.d.ts +58 -0
  103. package/dist/research/workspace/data-evidence-view.js +411 -0
  104. package/dist/research/workspace/data-evidence-view.js.map +1 -0
  105. package/dist/research/workspace/evidence-ledger.js +32 -29
  106. package/dist/research/workspace/evidence-ledger.js.map +1 -1
  107. package/dist/research/workspace/evidence.d.ts +28 -0
  108. package/dist/research/workspace/evidence.js +48 -0
  109. package/dist/research/workspace/evidence.js.map +1 -1
  110. package/dist/research/workspace/executor.d.ts +32 -2
  111. package/dist/research/workspace/executor.js +286 -42
  112. package/dist/research/workspace/executor.js.map +1 -1
  113. package/dist/research/workspace/investigation-attempt.d.ts +159 -0
  114. package/dist/research/workspace/investigation-attempt.js +619 -0
  115. package/dist/research/workspace/investigation-attempt.js.map +1 -0
  116. package/dist/research/workspace/investigation-audit.d.ts +20 -0
  117. package/dist/research/workspace/investigation-audit.js +306 -0
  118. package/dist/research/workspace/investigation-audit.js.map +1 -0
  119. package/dist/research/workspace/investigation-candidate.d.ts +84 -0
  120. package/dist/research/workspace/investigation-candidate.js +156 -0
  121. package/dist/research/workspace/investigation-candidate.js.map +1 -0
  122. package/dist/research/workspace/investigation-certification.d.ts +39 -0
  123. package/dist/research/workspace/investigation-certification.js +152 -0
  124. package/dist/research/workspace/investigation-certification.js.map +1 -0
  125. package/dist/research/workspace/investigation-close.d.ts +47 -0
  126. package/dist/research/workspace/investigation-close.js +153 -0
  127. package/dist/research/workspace/investigation-close.js.map +1 -0
  128. package/dist/research/workspace/investigation-lineage.d.ts +8 -0
  129. package/dist/research/workspace/investigation-lineage.js +10 -0
  130. package/dist/research/workspace/investigation-lineage.js.map +1 -0
  131. package/dist/research/workspace/investigation-observer.d.ts +22 -0
  132. package/dist/research/workspace/investigation-observer.js +122 -0
  133. package/dist/research/workspace/investigation-observer.js.map +1 -0
  134. package/dist/research/workspace/investigation-promotion.d.ts +129 -0
  135. package/dist/research/workspace/investigation-promotion.js +316 -0
  136. package/dist/research/workspace/investigation-promotion.js.map +1 -0
  137. package/dist/research/workspace/investigation-requirements.d.ts +5 -0
  138. package/dist/research/workspace/investigation-requirements.js +32 -0
  139. package/dist/research/workspace/investigation-requirements.js.map +1 -0
  140. package/dist/research/workspace/investigation-resources.d.ts +12 -0
  141. package/dist/research/workspace/investigation-resources.js +78 -0
  142. package/dist/research/workspace/investigation-resources.js.map +1 -0
  143. package/dist/research/workspace/investigation-source-export.d.ts +6 -0
  144. package/dist/research/workspace/investigation-source-export.js +68 -0
  145. package/dist/research/workspace/investigation-source-export.js.map +1 -0
  146. package/dist/research/workspace/investigation-store.d.ts +9 -0
  147. package/dist/research/workspace/investigation-store.js +55 -0
  148. package/dist/research/workspace/investigation-store.js.map +1 -0
  149. package/dist/research/workspace/investigation.d.ts +424 -0
  150. package/dist/research/workspace/investigation.js +716 -0
  151. package/dist/research/workspace/investigation.js.map +1 -0
  152. package/dist/research/workspace/native-process-supervisor.d.ts +1 -0
  153. package/dist/research/workspace/native-process-supervisor.js +97 -0
  154. package/dist/research/workspace/native-process-supervisor.js.map +1 -0
  155. package/dist/research/workspace/native-run.d.ts +150 -0
  156. package/dist/research/workspace/native-run.js +879 -0
  157. package/dist/research/workspace/native-run.js.map +1 -0
  158. package/dist/research/workspace/preflight.d.ts +11 -2
  159. package/dist/research/workspace/preflight.js +28 -20
  160. package/dist/research/workspace/preflight.js.map +1 -1
  161. package/dist/research/workspace/project-authority.js +2 -0
  162. package/dist/research/workspace/project-authority.js.map +1 -1
  163. package/dist/research/workspace/project-budget.d.ts +41 -0
  164. package/dist/research/workspace/project-budget.js +265 -0
  165. package/dist/research/workspace/project-budget.js.map +1 -0
  166. package/dist/research/workspace/project-mutations.d.ts +1 -1
  167. package/dist/research/workspace/project-mutations.js +29 -3
  168. package/dist/research/workspace/project-mutations.js.map +1 -1
  169. package/dist/research/workspace/projects.d.ts +66 -0
  170. package/dist/research/workspace/projects.js +182 -3
  171. package/dist/research/workspace/projects.js.map +1 -1
  172. package/dist/research/workspace/provider-budget.d.ts +3 -0
  173. package/dist/research/workspace/provider-budget.js +45 -0
  174. package/dist/research/workspace/provider-budget.js.map +1 -0
  175. package/dist/research/workspace/provider-state.d.ts +1 -0
  176. package/dist/research/workspace/provider-state.js +20 -0
  177. package/dist/research/workspace/provider-state.js.map +1 -0
  178. package/dist/research/workspace/publication-lineage.d.ts +34 -0
  179. package/dist/research/workspace/publication-lineage.js +165 -0
  180. package/dist/research/workspace/publication-lineage.js.map +1 -0
  181. package/dist/research/workspace/publication-workflow.d.ts +24 -0
  182. package/dist/research/workspace/publication-workflow.js +118 -14
  183. package/dist/research/workspace/publication-workflow.js.map +1 -1
  184. package/dist/research/workspace/request-provenance.d.ts +67 -0
  185. package/dist/research/workspace/request-provenance.js +115 -0
  186. package/dist/research/workspace/request-provenance.js.map +1 -0
  187. package/dist/research/workspace/review-executor.d.ts +6 -1
  188. package/dist/research/workspace/review-executor.js +39 -14
  189. package/dist/research/workspace/review-executor.js.map +1 -1
  190. package/dist/research/workspace/runtime.d.ts +64 -1
  191. package/dist/research/workspace/runtime.js +359 -112
  192. package/dist/research/workspace/runtime.js.map +1 -1
  193. package/dist/research/workspace/sanitization.js +1 -1
  194. package/dist/research/workspace/sanitization.js.map +1 -1
  195. package/dist/research/workspace/schema-compatibility.d.ts +5 -0
  196. package/dist/research/workspace/schema-compatibility.js +55 -0
  197. package/dist/research/workspace/schema-compatibility.js.map +1 -0
  198. package/dist/research/workspace/scientific-amendment.d.ts +103 -0
  199. package/dist/research/workspace/scientific-amendment.js +537 -0
  200. package/dist/research/workspace/scientific-amendment.js.map +1 -0
  201. package/dist/research/workspace/scientific-design.js +8 -17
  202. package/dist/research/workspace/scientific-design.js.map +1 -1
  203. package/dist/research/workspace/scientific-fulfillment-audit.d.ts +21 -0
  204. package/dist/research/workspace/scientific-fulfillment-audit.js +217 -0
  205. package/dist/research/workspace/scientific-fulfillment-audit.js.map +1 -0
  206. package/dist/research/workspace/scientific-fulfillment.d.ts +130 -0
  207. package/dist/research/workspace/scientific-fulfillment.js +553 -0
  208. package/dist/research/workspace/scientific-fulfillment.js.map +1 -0
  209. package/dist/research/workspace/scientific-review-execution.js +236 -75
  210. package/dist/research/workspace/scientific-review-execution.js.map +1 -1
  211. package/dist/research/workspace/scientific-review.d.ts +6 -1
  212. package/dist/research/workspace/scientific-review.js +228 -52
  213. package/dist/research/workspace/scientific-review.js.map +1 -1
  214. package/dist/research/workspace/setup-catalog.js +3 -3
  215. package/dist/research/workspace/setup-release.d.ts +22 -0
  216. package/dist/research/workspace/setup-release.js +426 -0
  217. package/dist/research/workspace/setup-release.js.map +1 -0
  218. package/dist/research/workspace/setup-runtime-integrity.d.ts +2 -0
  219. package/dist/research/workspace/setup-runtime-integrity.js +31 -0
  220. package/dist/research/workspace/setup-runtime-integrity.js.map +1 -0
  221. package/dist/research/workspace/setup-upgrade.d.ts +17 -0
  222. package/dist/research/workspace/setup-upgrade.js +784 -0
  223. package/dist/research/workspace/setup-upgrade.js.map +1 -0
  224. package/dist/research/workspace/setup.d.ts +31 -39
  225. package/dist/research/workspace/setup.js +220 -17
  226. package/dist/research/workspace/setup.js.map +1 -1
  227. package/dist/research/workspace/task-acceptance.d.ts +17 -2
  228. package/dist/research/workspace/task-acceptance.js +106 -10
  229. package/dist/research/workspace/task-acceptance.js.map +1 -1
  230. package/dist/research/workspace/task-audit.d.ts +5 -1
  231. package/dist/research/workspace/task-audit.js +70 -5
  232. package/dist/research/workspace/task-audit.js.map +1 -1
  233. package/dist/research/workspace/task-contract.d.ts +4 -1
  234. package/dist/research/workspace/task-contract.js +26 -5
  235. package/dist/research/workspace/task-contract.js.map +1 -1
  236. package/dist/research/workspace/types.d.ts +50 -3
  237. package/dist/research/workspace/workspace.js +34 -4
  238. package/dist/research/workspace/workspace.js.map +1 -1
  239. package/package.json +2 -1
@@ -1,3 +1,9 @@
1
+ import { closeInvestigation, investigationCloseInputSchema, } from "./workspace/investigation-close.js";
2
+ import { planInvestigationPromotion, approveInvestigationPromotion, investigationPromotionInputSchema, } from "./workspace/investigation-promotion.js";
3
+ import { selectInvestigationCandidate, investigationCandidateInputSchema, } from "./workspace/investigation-candidate.js";
4
+ import { observeInvestigationAttempt, investigationAttemptInputSchema, } from "./workspace/investigation-attempt.js";
5
+ import { planInvestigation, approveInvestigation, inspectInvestigation, investigationInputSchema, } from "./workspace/investigation.js";
6
+ import { projectBudgetAmount, projectBudgetView, providerCostLimits, } from "./workspace/project-budget.js";
1
7
  import { lstat, readFile } from "node:fs/promises";
2
8
  import { isAbsolute, join, resolve } from "node:path";
3
9
  import { CliError } from "../errors.js";
@@ -13,7 +19,7 @@ import { configureExternalSkillProfile, doctorExternalCapabilities, EXTERNAL_SKI
13
19
  import { appendJournalEvent } from "./workspace/journal.js";
14
20
  import { fetchNativeCandidateSource } from "./workspace/broker.js";
15
21
  import { preflightEvidenceArtifact, registerEvidenceArtifact } from "./workspace/artifacts.js";
16
- import { executeResearchDataCapability } from "./workspace/data-evidence-adapter.js";
22
+ import { executeResearchDataCapability, projectResearchDataEvidenceViewResult, projectResearchDataExecutionResult, readResearchDataEvidence, } from "./workspace/data-evidence-adapter.js";
17
23
  import { exportProjectAuditBundle, verifyProjectAuditBundle } from "./workspace/audit-bundle.js";
18
24
  import { loadCurrentEvidenceSnapshot } from "./workspace/acquisition.js";
19
25
  import { inspectAcquisitionForecast } from "./workspace/acquisition-forecast.js";
@@ -31,16 +37,21 @@ import { recordNativeResearchActivity } from "./workspace/native-activity.js";
31
37
  import { inspectReviewerStatus, startReviewerBridgeSidecar } from "./workspace/review-executor.js";
32
38
  import { readAndVerifyProjectInputPlan } from "./workspace/input-plan.js";
33
39
  import { executeScientificReview } from "./workspace/scientific-review-execution.js";
40
+ import { claudeCodeCompatibleSchema } from "./workspace/schema-compatibility.js";
34
41
  import { loadCurrentClaimEvidenceGraph, loadCurrentInferenceSnapshot, } from "./workspace/inference.js";
35
- import { addProjectInput, createProjectAddendum, initializeProject, forkProject, listProjects, loadProject, nextReadyPackage, normalizeEvidenceRequirements, refreshProject, retryProjectPackage, setProjectDisposition, scientificGateRecommendedAction, } from "./workspace/projects.js";
42
+ import { addProjectInput, createProjectAddendum, initializeProject, setProjectBudget, resolveProjectBudgetReservation, forkProject, listProjects, loadProject, nextReadyPackage, normalizeEvidenceRequirements, refreshProject, retryProjectPackage, setProjectDisposition, scientificGateRecommendedAction, } from "./workspace/projects.js";
36
43
  import { evaluateProjectPreflight } from "./workspace/preflight.js";
37
- import { closePublication, freezePublicationManuscript, inspectPublicationStatus, preparePublicationReview, publicationAssessmentSchema, publicationReviewSchema, submitPublicationReview, } from "./workspace/publication-workflow.js";
44
+ import { closePublication, freezePublicationManuscript, inspectPublicationStatus, inspectPublicationLineage, preparePublicationReview, publicationAssessmentSchema, publicationReviewSchema, submitPublicationReview, } from "./workspace/publication-workflow.js";
45
+ import { publicationResultLineageSchema } from "./workspace/publication-lineage.js";
38
46
  import { approveResearchPolicy, initializeResearchPolicy, inspectResearchPolicyCatalog, inspectResearchPolicyStatus, loadApprovedResearchPolicy, } from "./workspace/research-policy.js";
39
47
  import { resolveInstalledResearchPolicySource, runInteractiveResearchPolicyWizard, } from "./workspace/research-policy-wizard.js";
40
- import { abortNativeResearchStage, inspectNativeResearchStage, prepareNativeResearchStage, requestResearchHandoff, resolveResearchHandoff, runResearchWorkspace, submitNativeResearchStage, } from "./workspace/runtime.js";
48
+ import { abortNativeResearchStage, inspectNativeResearchStage, prepareNativeResearchStage, readNativeStageArtifact, requestResearchHandoff, resolveResearchHandoff, runResearchWorkspace, submitNativeResearchStage, } from "./workspace/runtime.js";
41
49
  import { schemaForStage } from "./workspace/schemas.js";
42
50
  import { readAndVerifyScientificDesign, scientificDesignSchema, } from "./workspace/scientific-design.js";
43
51
  import { inspectScientificObject, parseScientificObjectKind, registerScientificObject, } from "./workspace/scientific-objects.js";
52
+ import { inspectScientificFulfillment, recordScientificFulfillment, scientificFulfillmentSchema, } from "./workspace/scientific-fulfillment.js";
53
+ import { applyScientificAmendment, inspectScientificAmendment, planScientificAmendment, scientificAmendmentSchema, } from "./workspace/scientific-amendment.js";
54
+ import { inspectNativeRun, nativeRunInputSchema, observeNativeRun, } from "./workspace/native-run.js";
44
55
  import { inspectScientificReviewStatus, prepareScientificReview, scientificGateAssessmentSchema, scientificReviewSchema, submitScientificReview, } from "./workspace/scientific-review.js";
45
56
  import { isObject, pathExists, sha256Text, workspacePaths } from "./workspace/storage.js";
46
57
  import { doctorResearchWorkspace, initializeResearchWorkspace, loadWorkspaceConfig, requireResearchWorkspace, withWorkspaceLock, } from "./workspace/workspace.js";
@@ -98,14 +109,32 @@ export function researchOrchestrationHelp() {
98
109
  tiangong-ai research policy approve <project-id> --confirm [--acknowledge-defaults] [--workspace <path>] [--json]
99
110
  tiangong-ai research policy resolve <project-id> [--workspace <path>] [--json]
100
111
  tiangong-ai research publication freeze <project-id> --manuscript <absolute-file> --assessment <absolute-json> --submission <absolute-json> --producer-agent codex|claude|workbuddy|codebuddy --producer-session <opaque-id> [--supplements <absolute-json-array>] [--workspace <path>] [--json]
112
+ tiangong-ai research publication lineage <project-id> [--workspace <path>] [--json]
101
113
  tiangong-ai research publication review prepare <project-id> --role evidence|methods-reproducibility|domain-novelty|journal-editor --reviewer-agent codex|claude --reviewer-session <opaque-id> [--workspace <path>] [--json]
102
114
  tiangong-ai research publication review submit <project-id> --role evidence|methods-reproducibility|domain-novelty|journal-editor --review <absolute-json> [--workspace <path>] [--json]
103
115
  tiangong-ai research publication status <project-id> [--workspace <path>] [--json]
104
116
  tiangong-ai research publication close <project-id> [--workspace <path>] [--json]
105
117
  tiangong-ai research scientific object register --kind model-implementation|environment-lock --path <absolute-file> [--media-type <type>] [--workspace <path>] [--json]
106
118
  tiangong-ai research scientific object inspect --kind model-implementation|environment-lock --locator <control-relative-locator> [--workspace <path>] [--json]
107
- tiangong-ai research project init <project-id> --question <question> [--goal evidence-report|top-journal] [--design <absolute-json> --design-producer-agent codex|claude --design-producer-session <opaque-id>] [--requirements <absolute-json>] [--input-plan <absolute-json>] [--confirm-budget] [--workspace <path>] [--json]
108
- tiangong-ai research project preflight --question <question> [--goal evidence-report|top-journal] [--policy-project <project-id> --design <absolute-json>] [--requirements <absolute-json>] [--input-plan <absolute-json>] [--workspace <path>] [--json]
119
+ tiangong-ai research scientific fulfillment record <project> --input <json-file> [--workspace <path>] [--json]
120
+ tiangong-ai research scientific fulfillment status <project> [--workspace <path>] [--json]
121
+ tiangong-ai research scientific amendment plan <project> --input <json-file> [--workspace <path>] [--json]
122
+ tiangong-ai research scientific amendment apply <project> --plan <json-file> --confirm <plan-sha256> --authorization-source <text-file> [--workspace <path>] [--json]
123
+ tiangong-ai research project investigation plan <project> --input <json-file> [--workspace <path>] [--json]
124
+ tiangong-ai research project investigation approve <project> --input <json-file> --confirm <plan-sha256> --authorization-source <text-file> [--workspace <path>] [--json]
125
+ tiangong-ai research project investigation attempt <project> --input <json-file> [--workspace <path>] [--json]
126
+ tiangong-ai research project investigation select <project> --input <json-file> [--workspace <path>] [--json]
127
+ tiangong-ai research project investigation promotion plan <project> --input <json-file> [--workspace <path>] [--json]
128
+ tiangong-ai research project investigation promotion approve <project> --input <json-file> --confirm <plan-sha256> --authorization-source <text-file> [--workspace <path>] [--json]
129
+ tiangong-ai research project investigation close <project> --input <json-file> [--workspace <path>] [--json]
130
+ tiangong-ai research project investigation status <project> --investigation <id> [--workspace <path>] [--json]
131
+ tiangong-ai research scientific amendment status <project> [--workspace <path>] [--json]
132
+ tiangong-ai research project task run observe <project> --input <json-file> --confirm-execution [--workspace <path>] [--json]
133
+ tiangong-ai research project task run inspect <project> --run <run-id> [--workspace <path>] [--json]
134
+ tiangong-ai research project budget resolve <project-id> --reservation <id> --accounted-cost-usd <estimate> --reason <text> --confirm-budget [--workspace <path>] [--json]
135
+ tiangong-ai research project budget set <project-id> --max-cost-usd <amount> [--provider-costs <absolute-json>] [--confirm-budget] [--workspace <path>] [--json]
136
+ tiangong-ai research project init <project-id> --question <question> [--goal evidence-report|top-journal] [--design <absolute-json> --design-producer-agent codex|claude --design-producer-session <opaque-id>] [--requirements <absolute-json>] [--input-plan <absolute-json>] [--max-cost-usd <amount>] [--confirm-budget] [--workspace <path>] [--json]
137
+ tiangong-ai research project preflight --question <question> [--goal evidence-report|top-journal] [--policy-project <project-id> --design <absolute-json>] [--requirements <absolute-json>] [--input-plan <absolute-json>] [--max-cost-usd <amount>] [--workspace <path>] [--json]
109
138
  tiangong-ai research project input add <project-id> --path <absolute-file> [--role primary|reference|replication] [--trust-status verified-owner-input|unverified-owner-input|reference-only|replication-candidate] [--independently-reproduced] [--workspace <path>] [--json]
110
139
  tiangong-ai research project retry <project-id> [--package <package-id>] [--workspace <path>] [--json]
111
140
  tiangong-ai research project task define <project-id> --input <absolute-json> [--workspace <path>] [--json]
@@ -129,8 +158,11 @@ export function researchOrchestrationHelp() {
129
158
  tiangong-ai research project stage prepare <project-id> --stage discover|acquire|analyze|synthesize --host-agent codex|claude|workbuddy|codebuddy [--workspace <path>] [--json]
130
159
  tiangong-ai research project stage submit <project-id> --session <id> --output <absolute-json> [--confirm-model <id>] [--workspace <path>] [--json]
131
160
  tiangong-ai research project stage abort <project-id> --session <id> [--workspace <path>] [--json]
161
+ tiangong-ai research project stage artifacts <project-id> --session <id> [--offset <n>] [--limit <n>] [--path-prefix <prefix>] [--workspace <path>] [--json]
162
+ tiangong-ai research project stage read <project-id> --session <id> --artifact <object-id> [--offset <bytes>] [--length <bytes|all>] [--encoding utf8|base64] [--workspace <path>] [--json]
132
163
  tiangong-ai research project evidence fetch <project-id> --request <absolute-json> [--workspace <path>] [--json]
133
164
  tiangong-ai research project evidence data run <project-id> --request <absolute-data-run-request.json> [--workspace <path>] [--json]
165
+ tiangong-ai research project evidence data read <project-id> --receipt <attempt-id> --cursor <opaque-cursor> [--workspace <path>] [--json]
134
166
  tiangong-ai research project evidence activity record <project-id> --record <absolute-json> [--workspace <path>] [--json]
135
167
  tiangong-ai research project evidence candidate register <project-id> --record <absolute-json> [--workspace <path>] [--json]
136
168
  tiangong-ai research project evidence assessment record <project-id> --record <absolute-json> [--workspace <path>] [--json]
@@ -160,6 +192,64 @@ async function runScientific(argv, io) {
160
192
  const [action, ...rest] = argv;
161
193
  if (!action || action === "--help" || action === "-h")
162
194
  return writeHelp(io);
195
+ if (action === "amendment") {
196
+ const [operation, ...arguments_] = rest;
197
+ if (!["plan", "apply", "status"].includes(operation ?? ""))
198
+ throw unknownAction("research scientific amendment", operation ?? "");
199
+ const args = parseStrictArgs(arguments_, {
200
+ ...WORKSPACE_OPTIONS,
201
+ ...(operation === "plan" ? { input: "string" } : {}),
202
+ ...(operation === "apply"
203
+ ? {
204
+ plan: "string",
205
+ confirm: "string",
206
+ "authorization-source": "string",
207
+ }
208
+ : {}),
209
+ }, `research scientific amendment ${operation}`);
210
+ if (strictBoolean(args, "help"))
211
+ return writeHelp(io);
212
+ const projectId = onePositional(args.positionals, `research scientific amendment ${operation}`);
213
+ const root = await workspaceFromArgs(args);
214
+ if (operation === "status")
215
+ writeJson(io, await inspectScientificAmendment(root, projectId), args);
216
+ else {
217
+ const field = operation === "plan" ? "input" : "plan";
218
+ const path = strictString(args, field);
219
+ if (!path)
220
+ throw new CliError(`Amendment ${operation} requires --${field}.`, {
221
+ code: "RESEARCH_SCIENTIFIC_AMENDMENT_INVALID",
222
+ exitCode: 2,
223
+ });
224
+ const value = await readBoundedJsonRecord(path, `--${field}`, "RESEARCH_SCIENTIFIC_AMENDMENT_INVALID");
225
+ writeJson(io, operation === "plan"
226
+ ? await planScientificAmendment(root, projectId, value)
227
+ : await applyScientificAmendment(root, projectId, value, strictString(args, "confirm"), strictString(args, "authorization-source")), args);
228
+ }
229
+ return 0;
230
+ }
231
+ if (action === "fulfillment") {
232
+ const [operation, ...arguments_] = rest;
233
+ if (operation !== "record" && operation !== "status")
234
+ throw unknownAction("research scientific fulfillment", operation ?? "");
235
+ const args = parseStrictArgs(arguments_, { ...WORKSPACE_OPTIONS, ...(operation === "record" ? { input: "string" } : {}) }, `research scientific fulfillment ${operation}`);
236
+ if (strictBoolean(args, "help"))
237
+ return writeHelp(io);
238
+ const projectId = onePositional(args.positionals, `research scientific fulfillment ${operation}`);
239
+ const root = await workspaceFromArgs(args);
240
+ if (operation === "status")
241
+ writeJson(io, await inspectScientificFulfillment(root, projectId), args);
242
+ else {
243
+ const path = strictString(args, "input");
244
+ if (!path)
245
+ throw new CliError("Fulfillment record requires --input.", {
246
+ code: "RESEARCH_SCIENTIFIC_FULFILLMENT_INVALID",
247
+ exitCode: 2,
248
+ });
249
+ writeJson(io, await recordScientificFulfillment(root, projectId, await readBoundedJsonRecord(path, "--input", "RESEARCH_SCIENTIFIC_FULFILLMENT_INVALID")), args);
250
+ }
251
+ return 0;
252
+ }
163
253
  if (action !== "object")
164
254
  throw unknownAction("research scientific", action);
165
255
  const [objectAction, ...objectRest] = rest;
@@ -313,6 +403,13 @@ async function runPublication(argv, io) {
313
403
  const [action, ...rest] = argv;
314
404
  if (!action || action === "--help" || action === "-h")
315
405
  return writeHelp(io);
406
+ if (action === "lineage") {
407
+ const args = parseStrictArgs(rest, { ...WORKSPACE_OPTIONS }, "research publication lineage");
408
+ if (strictBoolean(args, "help"))
409
+ return writeHelp(io);
410
+ writeJson(io, await inspectPublicationLineage(await workspaceFromArgs(args), onePositional(args.positionals, "research publication lineage")), args);
411
+ return 0;
412
+ }
316
413
  if (action === "freeze") {
317
414
  const args = parseStrictArgs(rest, {
318
415
  ...WORKSPACE_OPTIONS,
@@ -335,13 +432,15 @@ async function runPublication(argv, io) {
335
432
  }
336
433
  const root = await workspaceFromArgs(args);
337
434
  const supplementsPath = strictString(args, "supplements");
435
+ const submission = await readSubmissionFiles(submissionPath);
338
436
  writeJson(io, await freezePublicationManuscript({
339
437
  root,
340
438
  projectId,
341
439
  manuscriptPath,
342
440
  assessmentPath,
343
441
  supplementPaths: supplementsPath ? await readAbsolutePathArray(supplementsPath) : [],
344
- submissionFiles: await readSubmissionFiles(submissionPath),
442
+ submissionFiles: submission.files,
443
+ resultLineage: submission.resultLineage,
345
444
  producerAgent: publicationAgent(strictString(args, "producer-agent"), "producer"),
346
445
  producerSessionId,
347
446
  }), args);
@@ -519,6 +618,9 @@ async function runSchema(argv, io) {
519
618
  if (stage === "task-acceptance") {
520
619
  schema = taskAcceptanceInputSchema();
521
620
  }
621
+ else if (stage === "task-native-run") {
622
+ schema = nativeRunInputSchema();
623
+ }
522
624
  else if (isTaskSchemaName(stage)) {
523
625
  schema = taskInputSchema(stage);
524
626
  }
@@ -528,6 +630,27 @@ async function runSchema(argv, io) {
528
630
  else if (stage === "scientific-design") {
529
631
  schema = scientificDesignSchema();
530
632
  }
633
+ else if (stage === "scientific-fulfillment") {
634
+ schema = scientificFulfillmentSchema();
635
+ }
636
+ else if (stage === "investigation-close") {
637
+ schema = investigationCloseInputSchema();
638
+ }
639
+ else if (stage === "investigation-promotion") {
640
+ schema = investigationPromotionInputSchema();
641
+ }
642
+ else if (stage === "investigation-candidate") {
643
+ schema = investigationCandidateInputSchema();
644
+ }
645
+ else if (stage === "investigation-attempt") {
646
+ schema = investigationAttemptInputSchema();
647
+ }
648
+ else if (stage === "investigation") {
649
+ schema = investigationInputSchema();
650
+ }
651
+ else if (stage === "scientific-amendment") {
652
+ schema = scientificAmendmentSchema();
653
+ }
531
654
  else if (stage.startsWith("scientific-assessment-")) {
532
655
  const role = scientificReviewRole(stage.slice("scientific-assessment-".length));
533
656
  schema = scientificGateAssessmentSchema(role);
@@ -539,6 +662,9 @@ async function runSchema(argv, io) {
539
662
  else if (stage === "publication-assessment") {
540
663
  schema = publicationAssessmentSchema();
541
664
  }
665
+ else if (stage === "publication-result-lineage") {
666
+ schema = publicationResultLineageSchema();
667
+ }
542
668
  else if (stage.startsWith("publication-review-")) {
543
669
  const role = publicationReviewRole(stage.slice("publication-review-".length));
544
670
  schema = publicationReviewSchema(role);
@@ -570,23 +696,7 @@ function compatibleSchema(schema, compatibility) {
570
696
  details: { supported: ["claude-code"] },
571
697
  });
572
698
  }
573
- const compatible = structuredClone(schema);
574
- const stripMetadata = (value) => {
575
- if (Array.isArray(value)) {
576
- for (const item of value)
577
- stripMetadata(item);
578
- return;
579
- }
580
- if (!value || typeof value !== "object")
581
- return;
582
- const record = value;
583
- delete record.$schema;
584
- delete record.$id;
585
- for (const item of Object.values(record))
586
- stripMetadata(item);
587
- };
588
- stripMetadata(compatible);
589
- return compatible;
699
+ return claudeCodeCompatibleSchema(schema);
590
700
  }
591
701
  async function runContext(argv, io) {
592
702
  const [action, ...rest] = argv;
@@ -793,6 +903,67 @@ async function runProject(argv, io) {
793
903
  const [action, ...rest] = argv;
794
904
  if (!action || action === "--help" || action === "-h")
795
905
  return writeHelp(io);
906
+ if (action === "investigation") {
907
+ const [firstOperation, ...firstArguments] = rest;
908
+ const operation = firstOperation === "promotion" ? `promotion-${firstArguments[0] ?? ""}` : firstOperation;
909
+ const arguments_ = firstOperation === "promotion" ? firstArguments.slice(1) : firstArguments;
910
+ if (![
911
+ "plan",
912
+ "approve",
913
+ "status",
914
+ "attempt",
915
+ "select",
916
+ "close",
917
+ "promotion-plan",
918
+ "promotion-approve",
919
+ ].includes(operation ?? ""))
920
+ throw unknownAction("research project investigation", operation ?? "");
921
+ const args = parseStrictArgs(arguments_, {
922
+ ...WORKSPACE_OPTIONS,
923
+ ...(operation === "status"
924
+ ? { investigation: "string" }
925
+ : { input: "string" }),
926
+ ...(["approve", "promotion-approve"].includes(operation)
927
+ ? { confirm: "string", "authorization-source": "string" }
928
+ : {}),
929
+ }, `research project investigation ${operation}`);
930
+ if (strictBoolean(args, "help"))
931
+ return writeHelp(io);
932
+ const projectId = onePositional(args.positionals, `research project investigation ${operation}`);
933
+ const root = await workspaceFromArgs(args);
934
+ if (operation === "status") {
935
+ const id = strictString(args, "investigation");
936
+ if (!id)
937
+ throw new CliError("Investigation status requires --investigation.", {
938
+ code: "RESEARCH_INVESTIGATION_INVALID",
939
+ exitCode: 2,
940
+ });
941
+ writeJson(io, await inspectInvestigation(root, projectId, id), args);
942
+ }
943
+ else {
944
+ const path = strictString(args, "input");
945
+ if (!path)
946
+ throw new CliError("Investigation plan/approve requires --input.", {
947
+ code: "RESEARCH_INVESTIGATION_INVALID",
948
+ exitCode: 2,
949
+ });
950
+ const value = await readBoundedJsonRecord(path, "--input", "RESEARCH_INVESTIGATION_INVALID");
951
+ writeJson(io, operation === "plan"
952
+ ? await planInvestigation(root, projectId, value)
953
+ : operation === "attempt"
954
+ ? await observeInvestigationAttempt(root, projectId, value)
955
+ : operation === "select"
956
+ ? await selectInvestigationCandidate(root, projectId, value)
957
+ : operation === "close"
958
+ ? await closeInvestigation(root, projectId, value)
959
+ : operation === "promotion-plan"
960
+ ? await planInvestigationPromotion(root, projectId, value)
961
+ : operation === "promotion-approve"
962
+ ? await approveInvestigationPromotion(root, projectId, value, strictString(args, "confirm"), strictString(args, "authorization-source"))
963
+ : await approveInvestigation(root, projectId, value, strictString(args, "confirm"), strictString(args, "authorization-source")), args);
964
+ }
965
+ return 0;
966
+ }
796
967
  if (action === "audit") {
797
968
  const [auditAction, ...auditRest] = rest;
798
969
  if (auditAction === "export") {
@@ -981,6 +1152,60 @@ async function runProject(argv, io) {
981
1152
  }
982
1153
  if (action === "stage") {
983
1154
  const [stageAction, ...stageRest] = rest;
1155
+ if (stageAction === "artifacts" || stageAction === "read") {
1156
+ const args = parseStrictArgs(stageRest, {
1157
+ ...WORKSPACE_OPTIONS,
1158
+ session: "string",
1159
+ artifact: "string",
1160
+ offset: "string",
1161
+ limit: "string",
1162
+ length: "string",
1163
+ encoding: "string",
1164
+ "path-prefix": "string",
1165
+ }, `research project stage ${stageAction}`);
1166
+ if (strictBoolean(args, "help"))
1167
+ return writeHelp(io);
1168
+ const sessionId = strictString(args, "session");
1169
+ const objectId = strictString(args, "artifact");
1170
+ if (!sessionId || (stageAction === "read" && !objectId))
1171
+ throw new CliError("Stage artifact reads require --session and an exact --artifact for read.", { code: "RESEARCH_NATIVE_STAGE_SESSION_REQUIRED", exitCode: 3 });
1172
+ const offset = strictString(args, "offset");
1173
+ const limit = strictString(args, "limit");
1174
+ const length = strictString(args, "length");
1175
+ const encoding = strictString(args, "encoding");
1176
+ if (encoding && encoding !== "utf8" && encoding !== "base64")
1177
+ throw new CliError("Artifact encoding must be utf8 or base64.", {
1178
+ code: "RESEARCH_ARTIFACT_VIEW_INVALID",
1179
+ exitCode: 3,
1180
+ });
1181
+ const projectId = onePositional(args.positionals, `research project stage ${stageAction}`);
1182
+ writeJson(io, await readNativeStageArtifact({
1183
+ root: await workspaceFromArgs(args),
1184
+ projectId,
1185
+ sessionId,
1186
+ ...(stageAction === "read"
1187
+ ? {
1188
+ selection: {
1189
+ objectId: objectId,
1190
+ ...(offset === undefined ? {} : { offset: Number(offset) }),
1191
+ ...(length === undefined
1192
+ ? {}
1193
+ : { length: length === "all" ? null : Number(length) }),
1194
+ ...(encoding ? { encoding: encoding } : {}),
1195
+ },
1196
+ }
1197
+ : {
1198
+ listing: {
1199
+ ...(offset === undefined ? {} : { offset: Number(offset) }),
1200
+ ...(limit === undefined ? {} : { limit: Number(limit) }),
1201
+ ...(strictString(args, "path-prefix")
1202
+ ? { pathPrefix: strictString(args, "path-prefix") }
1203
+ : {}),
1204
+ },
1205
+ }),
1206
+ }), args);
1207
+ return 0;
1208
+ }
984
1209
  if (stageAction === "prepare") {
985
1210
  const args = parseStrictArgs(stageRest, { ...WORKSPACE_OPTIONS, stage: "string", "host-agent": "string" }, "research project stage prepare");
986
1211
  if (strictBoolean(args, "help"))
@@ -1043,6 +1268,21 @@ async function runProject(argv, io) {
1043
1268
  }
1044
1269
  if (action === "task") {
1045
1270
  const [taskAction, ...taskRest] = rest;
1271
+ if (taskAction === "run") {
1272
+ const [runAction, ...runRest] = taskRest;
1273
+ if (runAction !== "observe" && runAction !== "inspect")
1274
+ throw unknownAction("research project task run", runAction ?? "");
1275
+ const args = parseStrictArgs(runRest, { ...WORKSPACE_OPTIONS, input: "string", run: "string", "confirm-execution": "boolean" }, `research project task run ${runAction}`);
1276
+ if (strictBoolean(args, "help"))
1277
+ return writeHelp(io);
1278
+ const projectId = onePositional(args.positionals, `research project task run ${runAction}`);
1279
+ const root = await workspaceFromArgs(args);
1280
+ const result = runAction === "inspect"
1281
+ ? await inspectNativeRun(root, projectId, strictString(args, "run") ?? "")
1282
+ : await observeNativeRun(root, projectId, await readBoundedJsonRecord(strictString(args, "input") ?? "", "--input", "RESEARCH_NATIVE_RUN_INVALID"), strictBoolean(args, "confirm-execution"));
1283
+ writeJson(io, result, args);
1284
+ return "record" in result && result.record && result.record.status !== "succeeded" ? 3 : 0;
1285
+ }
1046
1286
  if (taskAction === "acceptance") {
1047
1287
  const [acceptanceAction, ...acceptanceRest] = taskRest;
1048
1288
  if (acceptanceAction !== "record")
@@ -1116,9 +1356,27 @@ async function runProject(argv, io) {
1116
1356
  }
1117
1357
  if (evidenceAction === "data") {
1118
1358
  const [dataAction, ...dataRest] = evidenceRest;
1119
- if (dataAction !== "run") {
1359
+ if (dataAction !== "run" && dataAction !== "read") {
1120
1360
  throw unknownAction("research project evidence data", dataAction ?? "");
1121
1361
  }
1362
+ if (dataAction === "read") {
1363
+ const args = parseStrictArgs(dataRest, { ...WORKSPACE_OPTIONS, receipt: "string", cursor: "string" }, "research project evidence data read");
1364
+ if (strictBoolean(args, "help"))
1365
+ return writeHelp(io);
1366
+ const projectId = onePositional(args.positionals, "research project evidence data read");
1367
+ const receiptId = strictString(args, "receipt");
1368
+ const cursor = strictString(args, "cursor");
1369
+ if (!receiptId || !cursor) {
1370
+ throw new CliError("evidence data read requires --receipt and --cursor.", {
1371
+ code: "RESEARCH_DATA_EVIDENCE_CURSOR_INVALID",
1372
+ exitCode: 2,
1373
+ });
1374
+ }
1375
+ const root = await workspaceFromArgs(args);
1376
+ const result = await withWorkspaceLock(root, "research.data-evidence.read", () => readResearchDataEvidence({ root, projectId, receiptId, cursor }));
1377
+ writeJson(io, projectResearchDataEvidenceViewResult(result), args);
1378
+ return 0;
1379
+ }
1122
1380
  const args = parseStrictArgs(dataRest, { ...WORKSPACE_OPTIONS, request: "string" }, "research project evidence data run");
1123
1381
  if (strictBoolean(args, "help"))
1124
1382
  return writeHelp(io);
@@ -1137,7 +1395,7 @@ async function runProject(argv, io) {
1137
1395
  projectId,
1138
1396
  request,
1139
1397
  }));
1140
- writeJson(io, result, args);
1398
+ writeJson(io, projectResearchDataExecutionResult(result), args);
1141
1399
  return result.coreResult.status === "success"
1142
1400
  ? 0
1143
1401
  : result.coreResult.status === "partial"
@@ -1414,10 +1672,54 @@ async function runProject(argv, io) {
1414
1672
  writeJson(io, result, args);
1415
1673
  return 0;
1416
1674
  }
1675
+ if (action === "budget") {
1676
+ const [budgetAction, ...budgetRest] = rest;
1677
+ if (budgetAction === "resolve") {
1678
+ const args = parseStrictArgs(budgetRest, {
1679
+ ...WORKSPACE_OPTIONS,
1680
+ reservation: "string",
1681
+ "accounted-cost-usd": "string",
1682
+ reason: "string",
1683
+ "confirm-budget": "boolean",
1684
+ }, "research project budget resolve");
1685
+ if (strictBoolean(args, "help"))
1686
+ return writeHelp(io);
1687
+ const projectId = onePositional(args.positionals, "research project budget resolve");
1688
+ const reservation = strictString(args, "reservation"), amount = strictString(args, "accounted-cost-usd"), reason = strictString(args, "reason");
1689
+ if (!reservation || amount === undefined || !reason)
1690
+ throw new CliError("Budget resolution requires --reservation, --accounted-cost-usd and --reason.", { code: "INVALID_ARGS", exitCode: 2 });
1691
+ const root = await workspaceFromArgs(args);
1692
+ writeJson(io, await resolveProjectBudgetReservation(root, projectId, reservation, Number(amount), reason, strictBoolean(args, "confirm-budget")), args);
1693
+ return 0;
1694
+ }
1695
+ if (budgetAction !== "set")
1696
+ throw unknownAction("research project budget", budgetAction ?? "");
1697
+ const args = parseStrictArgs(budgetRest, {
1698
+ ...WORKSPACE_OPTIONS,
1699
+ "max-cost-usd": "string",
1700
+ "confirm-budget": "boolean",
1701
+ "provider-costs": "string",
1702
+ }, "research project budget set");
1703
+ if (strictBoolean(args, "help"))
1704
+ return writeHelp(io);
1705
+ const projectId = onePositional(args.positionals, "research project budget set");
1706
+ const amount = projectBudgetAmount(strictString(args, "max-cost-usd"));
1707
+ if (amount === undefined)
1708
+ throw new CliError("project budget set requires --max-cost-usd.", {
1709
+ code: "INVALID_ARGS",
1710
+ exitCode: 2,
1711
+ });
1712
+ const root = await workspaceFromArgs(args);
1713
+ writeJson(io, await setProjectBudget(root, projectId, amount, strictBoolean(args, "confirm-budget"), strictString(args, "provider-costs")
1714
+ ? providerCostLimits(await readBoundedJsonRecord(strictString(args, "provider-costs"), "--provider-costs", "RESEARCH_BUDGET_INVALID"))
1715
+ : undefined), args);
1716
+ return 0;
1717
+ }
1417
1718
  if (action === "init") {
1418
1719
  const args = parseStrictArgs(rest, {
1419
1720
  ...WORKSPACE_OPTIONS,
1420
1721
  question: "string",
1722
+ "max-cost-usd": "string",
1421
1723
  goal: "string",
1422
1724
  requirements: "string",
1423
1725
  "input-plan": "string",
@@ -1453,13 +1755,14 @@ async function runProject(argv, io) {
1453
1755
  exitCode: 2,
1454
1756
  });
1455
1757
  }
1758
+ const projectMaxCostUsd = projectBudgetAmount(strictString(args, "max-cost-usd"));
1456
1759
  const project = await initializeProject(root, projectId, question, requirementsPath ? await readEvidenceRequirements(requirementsPath) : undefined, strictBoolean(args, "confirm-budget"), inputPlanPath ? await readAndVerifyProjectInputPlan(inputPlanPath) : undefined, publicationPolicy, designPath && designProducerAgent && designProducerSession
1457
1760
  ? {
1458
1761
  design: await readAndVerifyScientificDesign(designPath, projectId),
1459
1762
  producerAgent: publicationAgent(designProducerAgent, "design producer"),
1460
1763
  producerSessionId: designProducerSession,
1461
1764
  }
1462
- : undefined);
1765
+ : undefined, projectMaxCostUsd === undefined ? undefined : { maxCostUsd: projectMaxCostUsd });
1463
1766
  writeJson(io, project, args);
1464
1767
  return 0;
1465
1768
  }
@@ -1467,6 +1770,7 @@ async function runProject(argv, io) {
1467
1770
  const args = parseStrictArgs(rest, {
1468
1771
  ...WORKSPACE_OPTIONS,
1469
1772
  question: "string",
1773
+ "max-cost-usd": "string",
1470
1774
  goal: "string",
1471
1775
  "policy-project": "string",
1472
1776
  requirements: "string",
@@ -1522,9 +1826,11 @@ async function runProject(argv, io) {
1522
1826
  const scientificDesign = designPath
1523
1827
  ? await readAndVerifyScientificDesign(designPath, policyProject)
1524
1828
  : null;
1829
+ const projectMaxCostUsd = projectBudgetAmount(strictString(args, "max-cost-usd"));
1525
1830
  const result = await evaluateProjectPreflight(root, question, requirements, inputPlan, {
1526
1831
  publicationPolicy,
1527
1832
  scientificDesign,
1833
+ ...(projectMaxCostUsd === undefined ? {} : { projectMaxCostUsd }),
1528
1834
  });
1529
1835
  writeJson(io, result, args);
1530
1836
  return result.readyToInitialize ? 0 : 3;
@@ -1762,6 +2068,7 @@ async function runStatus(argv, io) {
1762
2068
  ? "This recovery target has no project.forked commit marker. Do not execute it; inspect and remove or repair the incomplete fork while retaining source authority."
1763
2069
  : projectRecommendedAction(root, current, readyPackage, nativeStage, evidencePipeline, publication),
1764
2070
  usage: current.usage,
2071
+ budget: projectBudgetView(current, config),
1765
2072
  inputs: current.inputs,
1766
2073
  packages: current.packages,
1767
2074
  discovery: await inspectDiscoveryProgress(root, current),
@@ -1904,6 +2211,7 @@ async function inspectPublicationForStatus(root, projectId) {
1904
2211
  return {
1905
2212
  generationStatus: "invalid",
1906
2213
  code: error instanceof CliError ? error.code : "RESEARCH_PUBLICATION_STATE_INVALID",
2214
+ ...(error instanceof CliError && error.details ? { details: error.details } : {}),
1907
2215
  };
1908
2216
  }
1909
2217
  }
@@ -2264,15 +2572,20 @@ async function readAbsolutePathArray(path, option = "supplements") {
2264
2572
  async function readSubmissionFiles(path) {
2265
2573
  const value = await readBoundedJsonRecord(path, "--submission", "RESEARCH_PUBLICATION_SUBMISSION_PACKAGE_INVALID");
2266
2574
  if (value.schemaVersion !== 1 ||
2575
+ Object.keys(value).some((key) => !["schemaVersion", "files", "resultLineage"].includes(key)) ||
2267
2576
  !Array.isArray(value.files) ||
2268
2577
  value.files.some((file) => !isObject(file) ||
2578
+ Object.keys(file).some((key) => !["role", "path"].includes(key)) ||
2269
2579
  typeof file.role !== "string" ||
2270
2580
  typeof file.path !== "string" ||
2271
2581
  !isAbsolute(file.path) ||
2272
2582
  resolve(file.path) !== file.path)) {
2273
2583
  throw new CliError("--submission must declare schemaVersion 1 and role/path entries with absolute canonical paths.", { code: "RESEARCH_PUBLICATION_SUBMISSION_PACKAGE_INVALID", exitCode: 2 });
2274
2584
  }
2275
- return value.files;
2585
+ return {
2586
+ files: value.files,
2587
+ resultLineage: value.resultLineage,
2588
+ };
2276
2589
  }
2277
2590
  function integerOption(value, fallback, label) {
2278
2591
  if (!value)