@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
@@ -0,0 +1,22 @@
1
+ type Phase = "runtime-probe" | "calculation";
2
+ /** Local operational coordinates, deliberately excluded from portable records. */
3
+ export declare function investigationObserverRoute(root: string, projectId: string, key: string, phase: Phase, stagingDirectory: string): {
4
+ title: string;
5
+ onSpawn: (pid: number) => Promise<void>;
6
+ };
7
+ export declare function inspectInvestigationObserver(root: string, projectId: string, key: string): Promise<{
8
+ state: string;
9
+ localRoute: string;
10
+ automaticRetry: boolean;
11
+ supervisorPid?: never;
12
+ phase?: never;
13
+ stagingDirectoryName?: never;
14
+ } | {
15
+ state: string;
16
+ supervisorPid: number;
17
+ phase: Phase;
18
+ stagingDirectoryName: string;
19
+ localRoute: string;
20
+ automaticRetry: boolean;
21
+ }>;
22
+ export {};
@@ -0,0 +1,122 @@
1
+ import { execFile } from "node:child_process";
2
+ import { lstat, mkdir, readFile } from "node:fs/promises";
3
+ import { basename, join } from "node:path";
4
+ import { promisify } from "node:util";
5
+ import { CliError } from "../../errors.js";
6
+ import { sha256Text, workspacePaths, writeJsonAtomic } from "./storage.js";
7
+ const exec = promisify(execFile), HASH = /^[a-f0-9]{64}$/;
8
+ function titleFor(key, phase) {
9
+ return `tgr-${sha256Text(`${key}/${phase}`).slice(0, 32)}`;
10
+ }
11
+ async function location(root, projectId, key, create) {
12
+ if (!/^[a-z0-9][a-z0-9-]{2,63}$/.test(projectId) || !HASH.test(key))
13
+ throw new CliError("Observer routing identity is invalid.", {
14
+ code: "RESEARCH_INVESTIGATION_BINDING_INVALID",
15
+ exitCode: 3,
16
+ });
17
+ let path = workspacePaths(root).control;
18
+ for (const part of ["projects", projectId, "native", "calculation-observers"]) {
19
+ path = join(path, part);
20
+ if (create)
21
+ await mkdir(path, { mode: 0o700 }).catch((error) => {
22
+ if (error.code !== "EEXIST")
23
+ throw error;
24
+ });
25
+ const info = await lstat(path).catch(() => null);
26
+ if (!info) {
27
+ if (!create)
28
+ return null;
29
+ throw new Error("Missing observer route directory");
30
+ }
31
+ if (!info.isDirectory() || info.isSymbolicLink())
32
+ throw new CliError("Observer routing must use regular private directories.", {
33
+ code: "RESEARCH_INVESTIGATION_BINDING_INVALID",
34
+ exitCode: 3,
35
+ });
36
+ }
37
+ return join(path, `${key}.json`);
38
+ }
39
+ /** Local operational coordinates, deliberately excluded from portable records. */
40
+ export function investigationObserverRoute(root, projectId, key, phase, stagingDirectory) {
41
+ const title = titleFor(key, phase);
42
+ return {
43
+ title,
44
+ onSpawn: async (pid) => {
45
+ const path = await location(root, projectId, key, true);
46
+ const prior = await lstat(path).catch(() => null);
47
+ if (prior && (!prior.isFile() || prior.isSymbolicLink()))
48
+ throw new CliError("Observer route cannot replace a linked entry.", {
49
+ code: "RESEARCH_INVESTIGATION_BINDING_INVALID",
50
+ exitCode: 3,
51
+ });
52
+ const route = {
53
+ schemaVersion: 1,
54
+ projectId,
55
+ key,
56
+ pid,
57
+ title,
58
+ phase,
59
+ stagingDirectory,
60
+ updatedAt: new Date().toISOString(),
61
+ };
62
+ await writeJsonAtomic(path, route, 0o600);
63
+ },
64
+ };
65
+ }
66
+ export async function inspectInvestigationObserver(root, projectId, key) {
67
+ const localRoute = `projects/${projectId}/native/calculation-observers/${key}.json`;
68
+ const path = await location(root, projectId, key, false);
69
+ if (!path)
70
+ return { state: "unavailable", localRoute, automaticRetry: false };
71
+ const info = await lstat(path).catch(() => null);
72
+ if (!info?.isFile() || info.isSymbolicLink() || info.size > 16384)
73
+ return { state: "unavailable", localRoute, automaticRetry: false };
74
+ let route;
75
+ try {
76
+ route = JSON.parse(await readFile(path, "utf8"));
77
+ }
78
+ catch {
79
+ return { state: "unavailable", localRoute, automaticRetry: false };
80
+ }
81
+ if (route.schemaVersion !== 1 ||
82
+ route.projectId !== projectId ||
83
+ route.key !== key ||
84
+ !["runtime-probe", "calculation"].includes(route.phase) ||
85
+ route.title !== titleFor(key, route.phase) ||
86
+ !Number.isSafeInteger(route.pid) ||
87
+ route.pid < 2 ||
88
+ typeof route.stagingDirectory !== "string")
89
+ return { state: "unavailable", localRoute, automaticRetry: false };
90
+ let state = "unavailable";
91
+ try {
92
+ if (process.platform === "linux") {
93
+ const command = await readFile(`/proc/${route.pid}/cmdline`);
94
+ state =
95
+ command.toString("utf8").split("\0")[0] === route.title ? "observing" : "not-matching";
96
+ }
97
+ else if (process.platform === "darwin") {
98
+ const result = await exec("/bin/ps", ["-p", String(route.pid), "-o", "command="], {
99
+ env: { PATH: "/usr/bin:/bin", LANG: "C" },
100
+ timeout: 1000,
101
+ maxBuffer: 8192,
102
+ });
103
+ state = result.stdout.trim() === route.title ? "observing" : "not-matching";
104
+ }
105
+ }
106
+ catch (error) {
107
+ const code = error.code;
108
+ state =
109
+ code === "ENOENT" || (process.platform === "darwin" && code === 1)
110
+ ? "not-found"
111
+ : "unavailable";
112
+ }
113
+ return {
114
+ state,
115
+ supervisorPid: route.pid,
116
+ phase: route.phase,
117
+ stagingDirectoryName: basename(route.stagingDirectory),
118
+ localRoute,
119
+ automaticRetry: false,
120
+ };
121
+ }
122
+ //# sourceMappingURL=investigation-observer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"investigation-observer.js","sourceRoot":"","sources":["../../../src/research/workspace/investigation-observer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,129 @@
1
+ import { type InvestigationReadStore } from "./investigation-store.js";
2
+ import { type ScientificFulfillmentProjection } from "./scientific-fulfillment.js";
3
+ import type { JournalEvent, OutputRecord } from "./types.js";
4
+ export declare function investigationPromotionInputSchema(): {
5
+ type: string;
6
+ additionalProperties: boolean;
7
+ required: string[];
8
+ properties: {
9
+ schemaVersion: {
10
+ const: number;
11
+ };
12
+ promotionId: {
13
+ type: string;
14
+ pattern: string;
15
+ };
16
+ sourceProjectId: {
17
+ type: string;
18
+ pattern: string;
19
+ };
20
+ investigationId: {
21
+ type: string;
22
+ pattern: string;
23
+ };
24
+ candidateSha256: {
25
+ type: string;
26
+ pattern: string;
27
+ };
28
+ requirementId: {
29
+ type: string;
30
+ pattern: string;
31
+ };
32
+ requirementSha256: {
33
+ type: string;
34
+ pattern: string;
35
+ };
36
+ modelId: {
37
+ type: string;
38
+ pattern: string;
39
+ };
40
+ maxRunSeconds: {
41
+ type: string;
42
+ minimum: number;
43
+ maximum: number;
44
+ };
45
+ maxCostUsd: {
46
+ type: string;
47
+ minimum: number;
48
+ };
49
+ };
50
+ };
51
+ export declare function planInvestigationPromotion(root: string, projectId: string, value: unknown): Promise<{
52
+ schemaVersion: 1;
53
+ kind: "tiangong-investigation-promotion-plan";
54
+ projectId: string;
55
+ promotionId: string;
56
+ sourceProjectId: string;
57
+ investigationId: string;
58
+ candidateSha256: string;
59
+ definitionSha256: string;
60
+ recipeSha256: string;
61
+ recipe: {
62
+ programId: string;
63
+ runtime: {
64
+ kind: "node" | "python";
65
+ version: string;
66
+ binarySha256: string;
67
+ platform: string;
68
+ architecture: string;
69
+ };
70
+ script: OutputRecord;
71
+ environmentLock: OutputRecord;
72
+ inputs: (OutputRecord & {
73
+ id: string;
74
+ artifactId: string;
75
+ })[];
76
+ configuration: Record<string, string | number>;
77
+ arguments: string[];
78
+ outputs: {
79
+ id: string;
80
+ fileName: string;
81
+ mediaType: string;
82
+ }[];
83
+ diagnosticOutputId: string;
84
+ telemetry: {
85
+ requiredMetrics: string[];
86
+ requiredStatuses: string[];
87
+ };
88
+ maxOutputBytes: number;
89
+ };
90
+ requirementId: string;
91
+ requirementSha256: string;
92
+ modelId: string;
93
+ requestSha256: string;
94
+ route: "frozen-recipe" | "predeclared-fulfillment" | "successor-fulfillment";
95
+ questionSha256: string;
96
+ designSha256: string;
97
+ policySha256: string;
98
+ acquisitionSnapshotSha256: string;
99
+ beforeEffectiveDesignSha256: string;
100
+ expectedEffectiveDesignSha256: string;
101
+ parentFulfillmentSha256: string | null;
102
+ fulfillment: ScientificFulfillmentProjection;
103
+ certification: {
104
+ maxRuns: 1;
105
+ maxRunSeconds: number;
106
+ maxCostUsd: number;
107
+ maxOutputBytes: number;
108
+ };
109
+ purpose: "authorize-freezing-and-fresh-certification";
110
+ planSha256: string;
111
+ }>;
112
+ export type InvestigationPromotionPlan = Awaited<ReturnType<typeof planInvestigationPromotion>>;
113
+ export interface InvestigationPromotion {
114
+ schemaVersion: 1;
115
+ kind: "tiangong-investigation-promotion";
116
+ projectId: string;
117
+ promotionId: string;
118
+ plan: InvestigationPromotionPlan;
119
+ scopeAuthorization: {
120
+ kind: "operator-confirmation";
121
+ planSha256: string;
122
+ sourceSha256: string;
123
+ source: OutputRecord;
124
+ };
125
+ approvedAt: string;
126
+ recordSha256: string;
127
+ }
128
+ export declare function loadInvestigationPromotion(root: string, projectId: string, hash: string, knownEvents?: JournalEvent[], store?: InvestigationReadStore): Promise<InvestigationPromotion>;
129
+ export declare function approveInvestigationPromotion(root: string, projectId: string, value: unknown, confirmation: string | undefined, sourcePath: string | undefined): Promise<InvestigationPromotion>;
@@ -0,0 +1,316 @@
1
+ import { localInvestigationReadStore } from "./investigation-store.js";
2
+ import { Ajv2020 } from "ajv/dist/2020.js";
3
+ import { lstat, readFile } from "node:fs/promises";
4
+ import { isAbsolute } from "node:path";
5
+ import { CliError } from "../../errors.js";
6
+ import { loadCurrentEvidenceSnapshot } from "./acquisition.js";
7
+ import { investigationAttemptHistory } from "./investigation-attempt.js";
8
+ import { loadInvestigationCandidates } from "./investigation-candidate.js";
9
+ import { loadInvestigation } from "./investigation.js";
10
+ import { appendJournalEvent, readVerifiedJournal } from "./journal.js";
11
+ import { storeRunObject } from "./native-run.js";
12
+ import { assertProjectAuthority, projectAuthorityIndex } from "./project-authority.js";
13
+ import { remainingProjectCostUsd, reserveProjectCost } from "./project-budget.js";
14
+ import { beginProjectMutation, prepareProjectMutation, projectMutationBinding, settleProjectMutation, } from "./project-mutations.js";
15
+ import { loadProject } from "./projects.js";
16
+ import { assertResearchPolicyBinding } from "./research-policy.js";
17
+ import { configuredResearchSecrets, sanitizeResearchValue } from "./sanitization.js";
18
+ import { applyScientificFulfillmentRecord, loadScientificFulfillmentView, } from "./scientific-fulfillment.js";
19
+ import { canonicalJson, sha256Text, workspacePaths } from "./storage.js";
20
+ import { loadProjectTask, taskRequirementSha256, writeTaskObject } from "./task-contract.js";
21
+ import { loadWorkspaceConfig, withWorkspaceLock } from "./workspace.js";
22
+ const HASH = /^[a-f0-9]{64}$/;
23
+ const id = { type: "string", pattern: "^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$" };
24
+ const schema = {
25
+ type: "object",
26
+ additionalProperties: false,
27
+ required: [
28
+ "schemaVersion",
29
+ "promotionId",
30
+ "sourceProjectId",
31
+ "investigationId",
32
+ "candidateSha256",
33
+ "requirementId",
34
+ "requirementSha256",
35
+ "modelId",
36
+ "maxRunSeconds",
37
+ "maxCostUsd",
38
+ ],
39
+ properties: {
40
+ schemaVersion: { const: 1 },
41
+ promotionId: id,
42
+ sourceProjectId: { type: "string", pattern: "^[a-z0-9][a-z0-9-]{2,63}$" },
43
+ investigationId: id,
44
+ candidateSha256: { type: "string", pattern: HASH.source },
45
+ requirementId: id,
46
+ requirementSha256: { type: "string", pattern: HASH.source },
47
+ modelId: id,
48
+ maxRunSeconds: { type: "integer", minimum: 1, maximum: 172800 },
49
+ maxCostUsd: { type: "number", minimum: 0 },
50
+ },
51
+ };
52
+ const validate = new Ajv2020({ strict: false, allErrors: true }).compile(schema);
53
+ export function investigationPromotionInputSchema() {
54
+ return structuredClone(schema);
55
+ }
56
+ function failure(message, code = "RESEARCH_INVESTIGATION_PROMOTION_INVALID") {
57
+ return new CliError(message, { code, exitCode: 3 });
58
+ }
59
+ function parse(value) {
60
+ if (!validate(value) ||
61
+ canonicalJson(sanitizeResearchValue(value, configuredResearchSecrets(process.env))) !==
62
+ canonicalJson(value))
63
+ throw failure("Promotion must match the closed non-secret schema.");
64
+ return structuredClone(value);
65
+ }
66
+ export async function planInvestigationPromotion(root, projectId, value) {
67
+ const input = parse(value);
68
+ const project = await loadProject(root, projectId);
69
+ const source = projectId === input.sourceProjectId ? project : await loadProject(root, input.sourceProjectId);
70
+ const events = await readVerifiedJournal(workspacePaths(root).journal);
71
+ assertProjectAuthority(project, projectAuthorityIndex(events));
72
+ const definition = await loadInvestigation(root, input.sourceProjectId, input.investigationId, events);
73
+ const attempts = await investigationAttemptHistory(root, input.sourceProjectId, definition, events);
74
+ const candidates = await loadInvestigationCandidates(root, input.sourceProjectId, definition, events, attempts);
75
+ const candidate = candidates.at(-1);
76
+ if (!candidate ||
77
+ candidate.recordSha256 !== input.candidateSha256 ||
78
+ attempts.some((a) => !a.record))
79
+ throw failure("Promotion requires the current exact selected candidate and no unresolved attempt.");
80
+ const task = await loadProjectTask(root, projectId, events);
81
+ if (!task?.current.requirements.some((r) => r.id === input.requirementId &&
82
+ taskRequirementSha256(r) === input.requirementSha256 &&
83
+ r.checkKind === "computation"))
84
+ throw failure("Promotion must bind an active computational requirement.");
85
+ const analyze = project.packages.find((p) => p.stage === "analyze");
86
+ if (!project.publicationPolicy ||
87
+ !project.scientificDesign ||
88
+ project.handoff.state !== "agent-actionable" ||
89
+ project.status === "complete" ||
90
+ !analyze ||
91
+ analyze.attempts > 0 ||
92
+ analyze.startedAt ||
93
+ !["pending", "ready"].includes(analyze.status) ||
94
+ project.packages.find((p) => p.stage === "acquire")?.status !== "complete")
95
+ throw failure("Promote through the existing approved scientific design at an idle pre-analysis boundary; otherwise create the applicable reviewed successor.", "RESEARCH_INVESTIGATION_SUCCESSOR_REQUIRED");
96
+ if (projectId !== input.sourceProjectId &&
97
+ (project.lineage.derivedFrom !== input.sourceProjectId ||
98
+ source.lineage.supersededBy !== projectId))
99
+ throw failure("A changed scientific scope must use its actual authoritative successor relationship.", "RESEARCH_INVESTIGATION_SUCCESSOR_REQUIRED");
100
+ await assertResearchPolicyBinding(root, project.publicationPolicy);
101
+ const view = await loadScientificFulfillmentView(root, project, undefined, events);
102
+ const snapshot = await loadCurrentEvidenceSnapshot(root, projectId);
103
+ if (!candidate.recipe.inputs.every((i) => snapshot.artifacts.some((a) => a.artifactId === i.artifactId && a.sha256 === i.sha256 && a.bytes === i.bytes)))
104
+ throw failure("The target must freeze the candidate's exact canonical input bytes.");
105
+ if (projectId === input.sourceProjectId) {
106
+ if (definition.plan.requirementId !== input.requirementId ||
107
+ definition.plan.requirementSha256 !== input.requirementSha256 ||
108
+ definition.plan.questionSha256 !== sha256Text(project.question) ||
109
+ definition.plan.designSha256 !== project.scientificDesign.designSha256 ||
110
+ definition.plan.policySha256 !== project.publicationPolicy.resolvedPolicySha256 ||
111
+ definition.plan.acquisitionSnapshotSha256 !== snapshot.snapshotSha256)
112
+ throw failure("Changed question, requirement, Policy, design or acquisition needs an explicitly reviewed successor.", "RESEARCH_INVESTIGATION_SUCCESSOR_REQUIRED");
113
+ // Later fulfillment of predeclared slots is permitted. The same immutable
114
+ // declaration must still reproduce the investigation's earlier view.
115
+ const earlier = structuredClone(view.amendedBase);
116
+ let extendsInvestigation = sha256Text(canonicalJson(earlier)) === definition.plan.effectiveDesignSha256;
117
+ for (const record of view.records) {
118
+ applyScientificFulfillmentRecord(earlier, record);
119
+ extendsInvestigation ||=
120
+ sha256Text(canonicalJson(earlier)) === definition.plan.effectiveDesignSha256;
121
+ }
122
+ if (!extendsInvestigation)
123
+ throw failure("Scientific declaration changes require a new reviewed successor.", "RESEARCH_INVESTIGATION_SUCCESSOR_REQUIRED");
124
+ }
125
+ const model = view.contract.identity.modelStructures.find((m) => m.id === input.modelId);
126
+ if (!model)
127
+ throw failure("Promotion must name a model declared by the target design.");
128
+ const recipe = candidate.recipe;
129
+ const entrypoint = recipe.runtime.kind === "node" ? "program.mjs" : "program.py";
130
+ const fulfillment = {
131
+ modelImplementations: [],
132
+ environmentLocks: [],
133
+ parameterStates: [],
134
+ };
135
+ if (model.implementationStatus === "pending-source-acquisition" &&
136
+ model.implementationFreezeBeforeGate !== "research-design")
137
+ fulfillment.modelImplementations.push({
138
+ modelId: model.id,
139
+ sha256: recipe.script.sha256,
140
+ objectLocator: `lineage/objects/${recipe.script.sha256}/blob`,
141
+ entrypoint,
142
+ dueGate: model.implementationFreezeBeforeGate,
143
+ });
144
+ else if (model.implementationStatus !== "executable-frozen" ||
145
+ model.implementationArtifactSha256 !== recipe.script.sha256 ||
146
+ model.implementationEntrypoint !== entrypoint)
147
+ throw failure("Replacing a frozen model implementation requires a reviewed successor.", "RESEARCH_INVESTIGATION_SUCCESSOR_REQUIRED");
148
+ if (model.environmentLockStatus === "pending-runtime-lock" &&
149
+ model.environmentLockFreezeBeforeGate !== "research-design")
150
+ fulfillment.environmentLocks.push({
151
+ modelId: model.id,
152
+ sha256: recipe.environmentLock.sha256,
153
+ objectLocator: `lineage/objects/${recipe.environmentLock.sha256}/blob`,
154
+ dueGate: model.environmentLockFreezeBeforeGate,
155
+ });
156
+ else if (model.environmentLockStatus !== "exact-frozen" ||
157
+ model.environmentLockSha256 !== recipe.environmentLock.sha256)
158
+ throw failure("Replacing a frozen environment declaration requires a reviewed successor.", "RESEARCH_INVESTIGATION_SUCCESSOR_REQUIRED");
159
+ const projected = structuredClone(view.contract);
160
+ applyScientificFulfillmentRecord(projected, fulfillment);
161
+ const config = await loadWorkspaceConfig(root);
162
+ if (!project.budget ||
163
+ input.maxCostUsd > remainingProjectCostUsd(project, config) + 1e-9 ||
164
+ input.maxRunSeconds >
165
+ Math.min(config.budget.packageMaxWallSeconds.analyze, config.budget.maxWallSeconds - project.usage.wallSeconds))
166
+ throw failure("Configure a finite project budget that can admit the one separately authorized certification run.");
167
+ const core = {
168
+ schemaVersion: 1,
169
+ kind: "tiangong-investigation-promotion-plan",
170
+ projectId,
171
+ promotionId: input.promotionId,
172
+ sourceProjectId: input.sourceProjectId,
173
+ investigationId: input.investigationId,
174
+ candidateSha256: candidate.recordSha256,
175
+ definitionSha256: definition.recordSha256,
176
+ recipeSha256: candidate.recipeSha256,
177
+ recipe,
178
+ requirementId: input.requirementId,
179
+ requirementSha256: input.requirementSha256,
180
+ modelId: input.modelId,
181
+ requestSha256: sha256Text(canonicalJson(input)),
182
+ route: projectId !== input.sourceProjectId
183
+ ? "successor-fulfillment"
184
+ : fulfillment.modelImplementations.length || fulfillment.environmentLocks.length
185
+ ? "predeclared-fulfillment"
186
+ : "frozen-recipe",
187
+ questionSha256: sha256Text(project.question),
188
+ designSha256: project.scientificDesign.designSha256,
189
+ policySha256: project.publicationPolicy.resolvedPolicySha256,
190
+ acquisitionSnapshotSha256: snapshot.snapshotSha256,
191
+ beforeEffectiveDesignSha256: view.effectiveSha256,
192
+ expectedEffectiveDesignSha256: sha256Text(canonicalJson(projected)),
193
+ parentFulfillmentSha256: view.headSha256,
194
+ fulfillment,
195
+ certification: {
196
+ maxRuns: 1,
197
+ maxRunSeconds: input.maxRunSeconds,
198
+ maxCostUsd: input.maxCostUsd,
199
+ maxOutputBytes: candidate.recipe.maxOutputBytes,
200
+ },
201
+ purpose: "authorize-freezing-and-fresh-certification",
202
+ };
203
+ return { ...core, planSha256: sha256Text(canonicalJson(core)) };
204
+ }
205
+ export async function loadInvestigationPromotion(root, projectId, hash, knownEvents, store = localInvestigationReadStore(root)) {
206
+ const record = await store.readTask(projectId, "investigation-promotions", hash, "recordSha256");
207
+ const events = knownEvents ?? (await readVerifiedJournal(workspacePaths(root).journal));
208
+ const event = events.find((e) => e.scope === projectId &&
209
+ e.type === "investigation.promotion.approved" &&
210
+ e.payload.recordSha256 === hash);
211
+ if (!event ||
212
+ record.schemaVersion !== 1 ||
213
+ record.kind !== "tiangong-investigation-promotion" ||
214
+ record.projectId !== projectId ||
215
+ record.promotionId !== event.payload.promotionId ||
216
+ record.plan.projectId !== projectId ||
217
+ record.plan.promotionId !== record.promotionId ||
218
+ record.plan.planSha256 !== event.payload.planSha256 ||
219
+ record.scopeAuthorization.kind !== "operator-confirmation" ||
220
+ record.scopeAuthorization.planSha256 !== record.plan.planSha256 ||
221
+ record.scopeAuthorization.sourceSha256 !== record.scopeAuthorization.source.sha256 ||
222
+ record.scopeAuthorization.source.path !==
223
+ `task/run-objects/${record.scopeAuthorization.sourceSha256}`)
224
+ throw failure("Promotion does not match its committed authorization.");
225
+ const { planSha256, ...core } = record.plan;
226
+ if (planSha256 !== sha256Text(canonicalJson(core)))
227
+ throw failure("Promotion plan bytes changed.");
228
+ await store.verifyBlob(projectId, record.scopeAuthorization.source);
229
+ return record;
230
+ }
231
+ export async function approveInvestigationPromotion(root, projectId, value, confirmation, sourcePath) {
232
+ const input = parse(value);
233
+ if (!confirmation || !HASH.test(confirmation) || !sourcePath || !isAbsolute(sourcePath))
234
+ throw failure("Approve the exact promotion plan with --confirm and --authorization-source.", "RESEARCH_INVESTIGATION_CONFIRMATION_REQUIRED");
235
+ const info = await lstat(sourcePath);
236
+ if (!info.isFile() || info.isSymbolicLink() || info.size > 65536)
237
+ throw failure("Promotion authorization must be bounded regular UTF-8 text.");
238
+ let text;
239
+ try {
240
+ text = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(await readFile(sourcePath));
241
+ }
242
+ catch {
243
+ throw failure("Promotion authorization must be UTF-8 text.");
244
+ }
245
+ if (text.trim().length < 8 ||
246
+ sanitizeResearchValue(text, configuredResearchSecrets(process.env)) !== text)
247
+ throw failure("Promotion authorization must be bounded non-secret supplied text.");
248
+ return withWorkspaceLock(root, "research.investigation.promotion.approve", async () => {
249
+ const project = await loadProject(root, projectId);
250
+ const events = await readVerifiedJournal(workspacePaths(root).journal);
251
+ assertProjectAuthority(project, projectAuthorityIndex(events));
252
+ const existing = events.find((e) => e.scope === projectId &&
253
+ e.type === "investigation.promotion.approved" &&
254
+ e.payload.promotionId === input.promotionId);
255
+ if (existing) {
256
+ const record = await loadInvestigationPromotion(root, projectId, String(existing.payload.recordSha256), events);
257
+ if (record.plan.requestSha256 !== sha256Text(canonicalJson(input)) ||
258
+ record.plan.planSha256 !== confirmation ||
259
+ record.scopeAuthorization.sourceSha256 !== sha256Text(text))
260
+ throw failure("Promotion ID already belongs to another exact approval.");
261
+ return record;
262
+ }
263
+ const plan = await planInvestigationPromotion(root, projectId, input);
264
+ if (plan.planSha256 !== confirmation)
265
+ throw failure("Promotion plan changed; inspect the current exact plan before approving.");
266
+ const source = await storeRunObject(root, projectId, sourcePath);
267
+ if (source.sha256 !== sha256Text(text))
268
+ throw failure("Promotion approval source changed during storage.");
269
+ const core = {
270
+ schemaVersion: 1,
271
+ kind: "tiangong-investigation-promotion",
272
+ projectId,
273
+ promotionId: input.promotionId,
274
+ plan,
275
+ scopeAuthorization: {
276
+ kind: "operator-confirmation",
277
+ planSha256: plan.planSha256,
278
+ sourceSha256: source.sha256,
279
+ source,
280
+ },
281
+ approvedAt: new Date().toISOString(),
282
+ };
283
+ const record = {
284
+ ...core,
285
+ recordSha256: sha256Text(canonicalJson(core)),
286
+ };
287
+ await writeTaskObject(root, projectId, "investigation-promotions", record.recordSha256, record);
288
+ let mutation = await beginProjectMutation(root, "investigation-promotion", project, record.recordSha256);
289
+ try {
290
+ reserveProjectCost(project, await loadWorkspaceConfig(root), {
291
+ id: `investigation-certification-${record.recordSha256}`,
292
+ kind: "investigation",
293
+ reference: `promotion/${input.promotionId}`,
294
+ maxCostUsd: plan.certification.maxCostUsd,
295
+ });
296
+ project.updatedAt = new Date().toISOString();
297
+ mutation = await prepareProjectMutation(root, mutation, project);
298
+ await appendJournalEvent(workspacePaths(root).journal, "investigation.promotion.approved", projectId, {
299
+ projectId,
300
+ promotionId: input.promotionId,
301
+ investigationId: input.investigationId,
302
+ sourceProjectId: input.sourceProjectId,
303
+ recordSha256: record.recordSha256,
304
+ planSha256: plan.planSha256,
305
+ mutation: projectMutationBinding(mutation),
306
+ });
307
+ await settleProjectMutation(root, mutation);
308
+ }
309
+ catch (error) {
310
+ await settleProjectMutation(root, mutation);
311
+ throw error;
312
+ }
313
+ return record;
314
+ });
315
+ }
316
+ //# sourceMappingURL=investigation-promotion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"investigation-promotion.js","sourceRoot":"","sources":["../../../src/research/workspace/investigation-promotion.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { TaskObjectReader } from "./task-contract.js";
2
+ import type { JournalEvent } from "./types.js";
3
+ /** Lightweight derived index shared by intake, review context and portable audit.
4
+ * It never loads programs/results for requirements without investigation history. */
5
+ export declare function investigatedRequirementHashes(projectId: string, events: Array<Pick<JournalEvent, "scope" | "type" | "payload">>, readObject: TaskObjectReader): Promise<Set<string>>;