@tiangong-ai/cli 0.0.57 → 0.0.59

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 (62) hide show
  1. package/AGENTS.md +8 -2
  2. package/CONTRIBUTING.md +79 -0
  3. package/README.md +116 -3
  4. package/dist/cli.js +5 -0
  5. package/dist/cli.js.map +1 -1
  6. package/dist/research/orchestration.js +96 -26
  7. package/dist/research/orchestration.js.map +1 -1
  8. package/dist/research/workspace/acquisition-forecast.d.ts +18 -0
  9. package/dist/research/workspace/acquisition-forecast.js +116 -0
  10. package/dist/research/workspace/acquisition-forecast.js.map +1 -0
  11. package/dist/research/workspace/acquisition.d.ts +13 -1
  12. package/dist/research/workspace/acquisition.js +71 -62
  13. package/dist/research/workspace/acquisition.js.map +1 -1
  14. package/dist/research/workspace/artifacts.d.ts +18 -0
  15. package/dist/research/workspace/artifacts.js +40 -2
  16. package/dist/research/workspace/artifacts.js.map +1 -1
  17. package/dist/research/workspace/content-evidence.d.ts +37 -0
  18. package/dist/research/workspace/content-evidence.js +287 -137
  19. package/dist/research/workspace/content-evidence.js.map +1 -1
  20. package/dist/research/workspace/downloads.js +2 -2
  21. package/dist/research/workspace/downloads.js.map +1 -1
  22. package/dist/research/workspace/evidence-content-schema.d.ts +14 -0
  23. package/dist/research/workspace/evidence-content-schema.js +123 -0
  24. package/dist/research/workspace/evidence-content-schema.js.map +1 -0
  25. package/dist/research/workspace/evidence-ledger.d.ts +1 -1
  26. package/dist/research/workspace/evidence-ledger.js.map +1 -1
  27. package/dist/research/workspace/evidence-role-coverage.d.ts +35 -0
  28. package/dist/research/workspace/evidence-role-coverage.js +81 -0
  29. package/dist/research/workspace/evidence-role-coverage.js.map +1 -0
  30. package/dist/research/workspace/journal.d.ts +2 -0
  31. package/dist/research/workspace/journal.js +6 -0
  32. package/dist/research/workspace/journal.js.map +1 -1
  33. package/dist/research/workspace/preflight.d.ts +2 -0
  34. package/dist/research/workspace/preflight.js +14 -5
  35. package/dist/research/workspace/preflight.js.map +1 -1
  36. package/dist/research/workspace/projects.d.ts +7 -0
  37. package/dist/research/workspace/projects.js +65 -19
  38. package/dist/research/workspace/projects.js.map +1 -1
  39. package/dist/research/workspace/review-executor.d.ts +2 -0
  40. package/dist/research/workspace/review-executor.js +69 -1
  41. package/dist/research/workspace/review-executor.js.map +1 -1
  42. package/dist/research/workspace/runtime.d.ts +8 -1
  43. package/dist/research/workspace/runtime.js +54 -28
  44. package/dist/research/workspace/runtime.js.map +1 -1
  45. package/dist/research/workspace/schemas.js +10 -2
  46. package/dist/research/workspace/schemas.js.map +1 -1
  47. package/dist/research/workspace/scientific-design.d.ts +2 -1
  48. package/dist/research/workspace/scientific-design.js +39 -2
  49. package/dist/research/workspace/scientific-design.js.map +1 -1
  50. package/dist/research/workspace/scientific-review-execution.d.ts +19 -0
  51. package/dist/research/workspace/scientific-review-execution.js +445 -0
  52. package/dist/research/workspace/scientific-review-execution.js.map +1 -0
  53. package/dist/research/workspace/scientific-review.d.ts +110 -3
  54. package/dist/research/workspace/scientific-review.js +113 -20
  55. package/dist/research/workspace/scientific-review.js.map +1 -1
  56. package/dist/research/workspace/setup-catalog.js +3 -3
  57. package/dist/research/workspace/types.d.ts +4 -1
  58. package/dist/research/workspace/types.js +14 -1
  59. package/dist/research/workspace/types.js.map +1 -1
  60. package/dist/research/workspace/workspace.js +13 -1
  61. package/dist/research/workspace/workspace.js.map +1 -1
  62. package/package.json +2 -1
@@ -11,21 +11,24 @@ import { researchDataCredentialIds, setCapabilityCredentialValue, } from "./work
11
11
  import { configureExternalSkillProfile, doctorExternalCapabilities, EXTERNAL_SKILL_CONTEXT_PROFILE, EXTERNAL_SKILL_MEDIA_PROFILE, EXTERNAL_SKILL_PROFILE, importExternalCapability, inspectExternalSkillCatalog, } from "./workspace/external-skills.js";
12
12
  import { appendJournalEvent, readJournal } from "./workspace/journal.js";
13
13
  import { fetchNativeCandidateSource } from "./workspace/broker.js";
14
- import { registerEvidenceArtifact } from "./workspace/artifacts.js";
14
+ import { preflightEvidenceArtifact, registerEvidenceArtifact } from "./workspace/artifacts.js";
15
15
  import { executeResearchDataCapability } from "./workspace/data-evidence-adapter.js";
16
16
  import { exportProjectAuditBundle, verifyProjectAuditBundle } from "./workspace/audit-bundle.js";
17
17
  import { loadCurrentEvidenceSnapshot } from "./workspace/acquisition.js";
18
- import { freezeEvidenceContentSnapshot, loadCurrentEvidenceContentSnapshot, recordArtifactDecomposition, registerEvidenceAtom, } from "./workspace/content-evidence.js";
18
+ import { inspectAcquisitionForecast } from "./workspace/acquisition-forecast.js";
19
+ import { freezeEvidenceContentSnapshot, loadCurrentEvidenceContentSnapshot, recordArtifactDecomposition, registerEvidenceAtom, registerEvidenceContentBatch, } from "./workspace/content-evidence.js";
19
20
  import { inspectDiscoveryProgress } from "./workspace/discovery-status.js";
21
+ import { EVIDENCE_CONTENT_LIMITS, EVIDENCE_CONTENT_SCHEMA_NAMES, evidenceContentInputSchema, isEvidenceContentSchemaName, } from "./workspace/evidence-content-schema.js";
20
22
  import { inspectEvidenceAccessStatus } from "./workspace/evidence-exhaustion.js";
21
23
  import { recordDiscoveryAssessmentBatch } from "./workspace/discovery.js";
22
24
  import { bindEvidenceDownload } from "./workspace/downloads.js";
23
25
  import { registerNativeDiscoveryCandidate } from "./workspace/evidence-ledger.js";
24
26
  import { recordNativeResearchActivity } from "./workspace/native-activity.js";
25
- import { inspectReviewerBridgeStatus, startReviewerBridgeSidecar, } from "./workspace/review-executor.js";
27
+ import { inspectReviewerStatus, startReviewerBridgeSidecar } from "./workspace/review-executor.js";
26
28
  import { readAndVerifyProjectInputPlan } from "./workspace/input-plan.js";
29
+ import { executeScientificReview } from "./workspace/scientific-review-execution.js";
27
30
  import { loadCurrentClaimEvidenceGraph, loadCurrentInferenceSnapshot, } from "./workspace/inference.js";
28
- import { addProjectInput, createProjectAddendum, initializeProject, forkProject, listProjects, loadProject, nextReadyPackage, normalizeEvidenceRequirements, refreshProject, retryProjectPackage, setProjectDisposition, } from "./workspace/projects.js";
31
+ import { addProjectInput, createProjectAddendum, initializeProject, forkProject, listProjects, loadProject, nextReadyPackage, normalizeEvidenceRequirements, refreshProject, retryProjectPackage, setProjectDisposition, scientificGateRecommendedAction, } from "./workspace/projects.js";
29
32
  import { evaluateProjectPreflight } from "./workspace/preflight.js";
30
33
  import { closePublication, freezePublicationManuscript, inspectPublicationStatus, preparePublicationReview, publicationAssessmentSchema, publicationReviewSchema, submitPublicationReview, } from "./workspace/publication-workflow.js";
31
34
  import { approveResearchPolicy, initializeResearchPolicy, inspectResearchPolicyCatalog, inspectResearchPolicyStatus, loadApprovedResearchPolicy, } from "./workspace/research-policy.js";
@@ -110,6 +113,7 @@ export function researchOrchestrationHelp() {
110
113
  tiangong-ai research project access status <project-id> [--workspace <path>] [--json]
111
114
  tiangong-ai research project scientific review prepare <project-id> --role research-design|evidence-construct|pilot-methods --assessment <absolute-json> [--canary-artifacts <absolute-json-array>] --reviewer-agent codex|claude --reviewer-session <opaque-id> [--workspace <path>] [--json]
112
115
  tiangong-ai research project scientific review submit <project-id> --role research-design|evidence-construct|pilot-methods --review <absolute-json> [--workspace <path>] [--json]
116
+ tiangong-ai research project scientific review execute <project-id> --role research-design|evidence-construct|pilot-methods --confirm-review-cost [--retry] [--workspace <path>] [--json]
113
117
  tiangong-ai research project scientific status <project-id> [--workspace <path>] [--json]
114
118
  tiangong-ai research project audit export <project-id> --output <absolute-new-directory> [--workspace <path>] [--json]
115
119
  tiangong-ai research project audit verify --bundle <absolute-directory> [--json]
@@ -124,13 +128,21 @@ export function researchOrchestrationHelp() {
124
128
  tiangong-ai research project evidence download bind <project-id> --candidate <id> --record <absolute-json> [--workspace <path>] [--json]
125
129
  tiangong-ai research project evidence artifact register <project-id> --candidate <id> --path <absolute-file> [--download-binding <id> | --derived-from-artifact <id>] [--media-type <type>] [--source-url <https-url>] [--license <declared-license>] [--license-url <https-url>] [--host-type <type>] [--article-version <version>] [--workspace <path>] [--json]
126
130
  tiangong-ai research project evidence decomposition record <project-id> --record <absolute-json> [--workspace <path>] [--json]
131
+ tiangong-ai research project evidence decomposition batch <project-id> --record <absolute-json> [--workspace <path>] [--json]
132
+ tiangong-ai research project evidence atom batch <project-id> --record <absolute-json> [--workspace <path>] [--json]
133
+ tiangong-ai research project evidence artifact preflight (--bytes <known-bytes> | --path <absolute-file>) [--workspace <path>] [--json]
127
134
  tiangong-ai research project evidence atom register <project-id> --record <absolute-json> [--workspace <path>] [--json]
128
135
  tiangong-ai research project evidence content freeze <project-id> [--workspace <path>] [--json]
136
+ tiangong-ai research project evidence content forecast <project-id> --input <absolute-acquisition-audit.json> [--workspace <path>] [--json]
129
137
  tiangong-ai research project evidence content status <project-id> [--workspace <path>] [--json]
130
138
  tiangong-ai research schema show <discover|acquire|analyze|synthesize|review|doctor|scientific-design|scientific-assessment-research-design|scientific-assessment-evidence-construct|scientific-assessment-pilot-methods|scientific-review-research-design|scientific-review-evidence-construct|scientific-review-pilot-methods|publication-assessment|publication-review-evidence|publication-review-methods-reproducibility|publication-review-domain-novelty|publication-review-journal-editor> [--compatibility claude-code] [--json]
131
139
  tiangong-ai research status [--project <project-id>] [--all] [--workspace <absolute-path>] [--json]
132
140
  tiangong-ai research run [--project <project-id>] [--max-parallel <1-8>] [--max-cycles <1-100>] [--dry-run] [--progress-jsonl] [--workspace <absolute-path>] [--json]
133
141
 
142
+ Evidence input schemas: ${EVIDENCE_CONTENT_SCHEMA_NAMES.join(", ")}.
143
+ Evidence batches: at most ${EVIDENCE_CONTENT_LIMITS.maxBatchRecords} records and ${EVIDENCE_CONTENT_LIMITS.maxBatchInputBytes} bytes (${EVIDENCE_CONTENT_LIMITS.maxBatchInputBytes / (1024 * 1024)} MiB) of UTF-8 input.
144
+ Use research schema show <name> --json; schemas validate shape only, not exact artifact/lineage/locator semantics.
145
+
134
146
  ${researchSetupHelp()}
135
147
  `;
136
148
  }
@@ -211,8 +223,9 @@ async function runReviewer(argv, io) {
211
223
  if (args.positionals.length)
212
224
  throw unknownAction("research reviewer status", args.positionals[0]);
213
225
  const root = await workspaceFromArgs(args);
214
- writeJson(io, await inspectReviewerBridgeStatus(root), args);
215
- return 0;
226
+ const result = await inspectReviewerStatus(root, io.env);
227
+ writeJson(io, result, args);
228
+ return isObject(result) && result.status === "ready" ? 0 : 3;
216
229
  }
217
230
  if (action === "doctor") {
218
231
  const args = parseStrictArgs(rest, { ...WORKSPACE_OPTIONS, "confirm-agent-smoke-cost": "boolean" }, "research reviewer doctor");
@@ -493,7 +506,10 @@ async function runSchema(argv, io) {
493
506
  return writeHelp(io);
494
507
  const stage = onePositional(args.positionals, "research schema show");
495
508
  let schema;
496
- if (stage === "scientific-design") {
509
+ if (isEvidenceContentSchemaName(stage)) {
510
+ schema = evidenceContentInputSchema(stage);
511
+ }
512
+ else if (stage === "scientific-design") {
497
513
  schema = scientificDesignSchema();
498
514
  }
499
515
  else if (stage.startsWith("scientific-assessment-")) {
@@ -863,6 +879,28 @@ async function runProject(argv, io) {
863
879
  throw unknownAction("research project scientific", scientificAction ?? "");
864
880
  }
865
881
  const [reviewAction, ...reviewRest] = scientificRest;
882
+ if (reviewAction === "execute") {
883
+ const args = parseStrictArgs(reviewRest, {
884
+ ...WORKSPACE_OPTIONS,
885
+ role: "string",
886
+ "confirm-review-cost": "boolean",
887
+ retry: "boolean",
888
+ }, "research project scientific review execute");
889
+ if (strictBoolean(args, "help"))
890
+ return writeHelp(io);
891
+ const projectId = onePositional(args.positionals, "research project scientific review execute");
892
+ const root = await workspaceFromArgs(args);
893
+ const result = await executeScientificReview({
894
+ root,
895
+ projectId,
896
+ role: scientificReviewRole(strictString(args, "role")),
897
+ confirmCost: strictBoolean(args, "confirm-review-cost"),
898
+ retry: strictBoolean(args, "retry"),
899
+ environment: io.env,
900
+ });
901
+ writeJson(io, result, args);
902
+ return result.status === "passed" ? 0 : 3;
903
+ }
866
904
  if (reviewAction === "prepare") {
867
905
  const args = parseStrictArgs(reviewRest, {
868
906
  ...WORKSPACE_OPTIONS,
@@ -1110,6 +1148,24 @@ async function runProject(argv, io) {
1110
1148
  }
1111
1149
  if (evidenceAction === "artifact") {
1112
1150
  const [artifactAction, ...artifactRest] = evidenceRest;
1151
+ if (artifactAction === "preflight") {
1152
+ const args = parseStrictArgs(artifactRest, { ...WORKSPACE_OPTIONS, bytes: "string", path: "string" }, "research project evidence artifact preflight");
1153
+ if (strictBoolean(args, "help"))
1154
+ return writeHelp(io);
1155
+ if (args.positionals.length)
1156
+ throw unknownAction("research project evidence artifact preflight", args.positionals[0]);
1157
+ const bytes = strictString(args, "bytes");
1158
+ const path = strictString(args, "path");
1159
+ const result = await preflightEvidenceArtifact({
1160
+ root: await workspaceFromArgs(args),
1161
+ ...(bytes === undefined
1162
+ ? {}
1163
+ : { bytes: /^\d+$/u.test(bytes) ? Number(bytes) : Number.NaN }),
1164
+ ...(path === undefined ? {} : { path }),
1165
+ });
1166
+ writeJson(io, result, args);
1167
+ return result.decision === "pass" ? 0 : 3;
1168
+ }
1113
1169
  if (artifactAction !== "register") {
1114
1170
  throw unknownAction("research project evidence artifact", artifactAction ?? "");
1115
1171
  }
@@ -1171,7 +1227,7 @@ async function runProject(argv, io) {
1171
1227
  }
1172
1228
  if (evidenceAction === "decomposition") {
1173
1229
  const [decompositionAction, ...decompositionRest] = evidenceRest;
1174
- if (decompositionAction !== "record") {
1230
+ if (decompositionAction !== "record" && decompositionAction !== "batch") {
1175
1231
  throw unknownAction("research project evidence decomposition", decompositionAction ?? "");
1176
1232
  }
1177
1233
  const args = parseStrictArgs(decompositionRest, { ...WORKSPACE_OPTIONS, record: "string" }, "research project evidence decomposition record");
@@ -1186,14 +1242,16 @@ async function runProject(argv, io) {
1186
1242
  });
1187
1243
  }
1188
1244
  const root = await workspaceFromArgs(args);
1189
- const record = await readBoundedJsonRecord(recordPath, "--record", "RESEARCH_DECOMPOSITION_INVALID");
1190
- const result = await withWorkspaceLock(root, "research.decomposition.record", () => recordArtifactDecomposition({ root, projectId, value: record }));
1245
+ const record = await readBoundedJsonRecord(recordPath, "--record", "RESEARCH_DECOMPOSITION_INVALID", decompositionAction === "batch" ? EVIDENCE_CONTENT_LIMITS.maxBatchInputBytes : undefined);
1246
+ const result = await withWorkspaceLock(root, "research.decomposition.record", async () => decompositionAction === "batch"
1247
+ ? registerEvidenceContentBatch({ root, projectId, kind: "decomposition", value: record })
1248
+ : recordArtifactDecomposition({ root, projectId, value: record }));
1191
1249
  writeJson(io, result, args);
1192
1250
  return 0;
1193
1251
  }
1194
1252
  if (evidenceAction === "atom") {
1195
1253
  const [atomAction, ...atomRest] = evidenceRest;
1196
- if (atomAction !== "register") {
1254
+ if (atomAction !== "register" && atomAction !== "batch") {
1197
1255
  throw unknownAction("research project evidence atom", atomAction ?? "");
1198
1256
  }
1199
1257
  const args = parseStrictArgs(atomRest, { ...WORKSPACE_OPTIONS, record: "string" }, "research project evidence atom register");
@@ -1208,13 +1266,31 @@ async function runProject(argv, io) {
1208
1266
  });
1209
1267
  }
1210
1268
  const root = await workspaceFromArgs(args);
1211
- const record = await readBoundedJsonRecord(recordPath, "--record", "RESEARCH_EVIDENCE_ATOM_INVALID");
1212
- const result = await withWorkspaceLock(root, "research.evidence-atom.register", () => registerEvidenceAtom({ root, projectId, value: record }));
1269
+ const record = await readBoundedJsonRecord(recordPath, "--record", "RESEARCH_EVIDENCE_ATOM_INVALID", atomAction === "batch" ? EVIDENCE_CONTENT_LIMITS.maxBatchInputBytes : undefined);
1270
+ const result = await withWorkspaceLock(root, "research.evidence-atom.register", async () => atomAction === "batch"
1271
+ ? registerEvidenceContentBatch({ root, projectId, kind: "atom", value: record })
1272
+ : registerEvidenceAtom({ root, projectId, value: record }));
1213
1273
  writeJson(io, result, args);
1214
1274
  return 0;
1215
1275
  }
1216
1276
  if (evidenceAction === "content") {
1217
1277
  const [contentAction, ...contentRest] = evidenceRest;
1278
+ if (contentAction === "forecast") {
1279
+ const args = parseStrictArgs(contentRest, { ...WORKSPACE_OPTIONS, input: "string" }, "research project evidence content forecast");
1280
+ if (strictBoolean(args, "help"))
1281
+ return writeHelp(io);
1282
+ const projectId = onePositional(args.positionals, "research project evidence content forecast");
1283
+ const inputPath = strictString(args, "input");
1284
+ if (!inputPath)
1285
+ throw new CliError("content forecast requires --input with a proposed acquisition audit.", { code: "RESEARCH_ACQUISITION_FORECAST_INVALID", exitCode: 2 });
1286
+ const root = await workspaceFromArgs(args);
1287
+ const value = await readBoundedJsonRecord(inputPath, "--input", "RESEARCH_ACQUISITION_FORECAST_INVALID");
1288
+ const result = await inspectAcquisitionForecast(root, projectId, value);
1289
+ writeJson(io, result, args);
1290
+ return result.acquisitionGate.decision === "pass" && !result.knownRoleDeficits.length
1291
+ ? 0
1292
+ : 3;
1293
+ }
1218
1294
  if (contentAction !== "freeze" && contentAction !== "status") {
1219
1295
  throw unknownAction("research project evidence content", contentAction ?? "");
1220
1296
  }
@@ -1600,7 +1676,7 @@ async function runStatus(argv, io) {
1600
1676
  readyPackage,
1601
1677
  recommendedAction: authority.state === "invalid"
1602
1678
  ? "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."
1603
- : projectRecommendedAction(root, current, readyPackage, nativeStage, scientificReview, evidencePipeline, publication),
1679
+ : projectRecommendedAction(root, current, readyPackage, nativeStage, evidencePipeline, publication),
1604
1680
  usage: current.usage,
1605
1681
  inputs: current.inputs,
1606
1682
  packages: current.packages,
@@ -1774,7 +1850,7 @@ async function inspectPublicationForStatus(root, projectId) {
1774
1850
  };
1775
1851
  }
1776
1852
  }
1777
- function projectRecommendedAction(root, project, readyPackage, nativeStage, scientificReview, evidencePipeline, publication) {
1853
+ function projectRecommendedAction(root, project, readyPackage, nativeStage, evidencePipeline, publication) {
1778
1854
  if (project.lineage.supersededBy) {
1779
1855
  return `Continue with superseding project ${project.lineage.supersededBy}.`;
1780
1856
  }
@@ -1815,15 +1891,9 @@ function projectRecommendedAction(root, project, readyPackage, nativeStage, scie
1815
1891
  return `Inference snapshot is invalid (${evidencePipeline.inference.code ?? "unknown"}); repair its frozen upstream bindings before analysis.`;
1816
1892
  }
1817
1893
  }
1818
- if (scientificReview.nextGate) {
1819
- const gate = scientificReview.nextGate;
1820
- if (gate.status === "stopped") {
1821
- return `Scientific ${gate.role} review stopped the project; inspect the frozen review and request user or external action instead of continuing.`;
1822
- }
1823
- const schema = `scientific-assessment-${gate.role}`;
1824
- const canaryOption = gate.role === "evidence-construct" ? " --canary-artifacts <absolute-json-array>" : "";
1825
- return `Use the native producer App to create a bounded ${gate.role} assessment from schema ${schema}, then prepare an independent review: tiangong-ai research project scientific review prepare ${project.id} --role ${gate.role} --assessment <absolute-json>${canaryOption} --reviewer-agent <codex|claude> --reviewer-session <fresh-opaque-id> --workspace ${root}`;
1826
- }
1894
+ const scientificAction = scientificGateRecommendedAction(root, project);
1895
+ if (scientificAction)
1896
+ return scientificAction;
1827
1897
  if (project.status === "complete") {
1828
1898
  if (project.publicationPolicy) {
1829
1899
  if (publication && "code" in publication) {
@@ -1981,7 +2051,7 @@ function nativeHostAgent(value) {
1981
2051
  async function readNativeEvidenceRequest(path) {
1982
2052
  return readBoundedJsonRecord(path, "--request", "RESEARCH_BROKER_REQUEST_INVALID");
1983
2053
  }
1984
- async function readBoundedJsonRecord(path, label, code) {
2054
+ async function readBoundedJsonRecord(path, label, code, maxBytes = 1024 * 1024) {
1985
2055
  if (!isAbsolute(path)) {
1986
2056
  throw new CliError(`${label} must be an absolute JSON file path.`, {
1987
2057
  code,
@@ -1990,7 +2060,7 @@ async function readBoundedJsonRecord(path, label, code) {
1990
2060
  }
1991
2061
  const selected = resolve(path);
1992
2062
  const info = await lstat(selected).catch(() => undefined);
1993
- if (!info?.isFile() || info.isSymbolicLink() || info.size > 1024 * 1024) {
2063
+ if (!info?.isFile() || info.isSymbolicLink() || info.size > maxBytes) {
1994
2064
  throw new CliError(`${label} must be a bounded regular non-symlink JSON file.`, {
1995
2065
  code,
1996
2066
  exitCode: 2,