@tiangong-ai/cli 0.0.57 → 0.0.58
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.
- package/AGENTS.md +2 -2
- package/README.md +106 -3
- package/dist/research/orchestration.js +96 -26
- package/dist/research/orchestration.js.map +1 -1
- package/dist/research/workspace/acquisition-forecast.d.ts +18 -0
- package/dist/research/workspace/acquisition-forecast.js +116 -0
- package/dist/research/workspace/acquisition-forecast.js.map +1 -0
- package/dist/research/workspace/acquisition.d.ts +13 -1
- package/dist/research/workspace/acquisition.js +71 -62
- package/dist/research/workspace/acquisition.js.map +1 -1
- package/dist/research/workspace/artifacts.d.ts +18 -0
- package/dist/research/workspace/artifacts.js +40 -2
- package/dist/research/workspace/artifacts.js.map +1 -1
- package/dist/research/workspace/content-evidence.d.ts +37 -0
- package/dist/research/workspace/content-evidence.js +287 -137
- package/dist/research/workspace/content-evidence.js.map +1 -1
- package/dist/research/workspace/downloads.js +2 -2
- package/dist/research/workspace/downloads.js.map +1 -1
- package/dist/research/workspace/evidence-content-schema.d.ts +14 -0
- package/dist/research/workspace/evidence-content-schema.js +123 -0
- package/dist/research/workspace/evidence-content-schema.js.map +1 -0
- package/dist/research/workspace/evidence-ledger.d.ts +1 -1
- package/dist/research/workspace/evidence-ledger.js.map +1 -1
- package/dist/research/workspace/evidence-role-coverage.d.ts +35 -0
- package/dist/research/workspace/evidence-role-coverage.js +81 -0
- package/dist/research/workspace/evidence-role-coverage.js.map +1 -0
- package/dist/research/workspace/journal.d.ts +2 -0
- package/dist/research/workspace/journal.js +6 -0
- package/dist/research/workspace/journal.js.map +1 -1
- package/dist/research/workspace/preflight.d.ts +2 -0
- package/dist/research/workspace/preflight.js +14 -5
- package/dist/research/workspace/preflight.js.map +1 -1
- package/dist/research/workspace/projects.d.ts +7 -0
- package/dist/research/workspace/projects.js +65 -19
- package/dist/research/workspace/projects.js.map +1 -1
- package/dist/research/workspace/review-executor.d.ts +2 -0
- package/dist/research/workspace/review-executor.js +69 -1
- package/dist/research/workspace/review-executor.js.map +1 -1
- package/dist/research/workspace/runtime.d.ts +8 -1
- package/dist/research/workspace/runtime.js +54 -28
- package/dist/research/workspace/runtime.js.map +1 -1
- package/dist/research/workspace/schemas.js +10 -2
- package/dist/research/workspace/schemas.js.map +1 -1
- package/dist/research/workspace/scientific-design.d.ts +2 -1
- package/dist/research/workspace/scientific-design.js +39 -2
- package/dist/research/workspace/scientific-design.js.map +1 -1
- package/dist/research/workspace/scientific-review-execution.d.ts +19 -0
- package/dist/research/workspace/scientific-review-execution.js +445 -0
- package/dist/research/workspace/scientific-review-execution.js.map +1 -0
- package/dist/research/workspace/scientific-review.d.ts +110 -3
- package/dist/research/workspace/scientific-review.js +113 -20
- package/dist/research/workspace/scientific-review.js.map +1 -1
- package/dist/research/workspace/setup-catalog.js +2 -2
- package/dist/research/workspace/types.d.ts +4 -1
- package/dist/research/workspace/types.js +14 -1
- package/dist/research/workspace/types.js.map +1 -1
- package/dist/research/workspace/workspace.js +13 -1
- package/dist/research/workspace/workspace.js.map +1 -1
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -17,8 +17,8 @@ checkPaths:
|
|
|
17
17
|
- .docpact/config.yaml
|
|
18
18
|
- docs/agents/**
|
|
19
19
|
- src/**
|
|
20
|
-
lastReviewedAt: 2026-09-
|
|
21
|
-
lastReviewedCommit:
|
|
20
|
+
lastReviewedAt: 2026-09-02
|
|
21
|
+
lastReviewedCommit: 8a18ba69f432d2c639517549157ef29545722cff
|
|
22
22
|
---
|
|
23
23
|
|
|
24
24
|
# Tiangong AI CLI Contract
|
package/README.md
CHANGED
|
@@ -12,8 +12,8 @@ checkPaths:
|
|
|
12
12
|
- package.json
|
|
13
13
|
- bin/**
|
|
14
14
|
- src/**
|
|
15
|
-
lastReviewedAt: 2026-09-
|
|
16
|
-
lastReviewedCommit:
|
|
15
|
+
lastReviewedAt: 2026-09-02
|
|
16
|
+
lastReviewedCommit: 8a18ba69f432d2c639517549157ef29545722cff
|
|
17
17
|
---
|
|
18
18
|
|
|
19
19
|
# Tiangong AI CLI
|
|
@@ -650,7 +650,33 @@ tiangong-ai research project scientific review submit top-journal-paper \
|
|
|
650
650
|
--workspace /absolute/path/to/workspace --json
|
|
651
651
|
```
|
|
652
652
|
|
|
653
|
-
|
|
653
|
+
For a prepared packet, use explicit isolated execution instead of writing a
|
|
654
|
+
custom reviewer runner:
|
|
655
|
+
|
|
656
|
+
```bash
|
|
657
|
+
tiangong-ai research reviewer status --workspace /absolute/path/to/workspace --json
|
|
658
|
+
tiangong-ai research project scientific review execute top-journal-paper \
|
|
659
|
+
--role research-design --confirm-review-cost \
|
|
660
|
+
--workspace /absolute/path/to/workspace --json
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
Confirm the bounded cost before execution. The command uses the configured
|
|
664
|
+
`native-direct` or `sandbox-bridge` reviewer, copies exact hash-verified packet
|
|
665
|
+
inputs and human Policy documents into its capsule, and submits only a
|
|
666
|
+
schema-valid, packet/session-bound review. A saved successful execution is
|
|
667
|
+
replayed without another model call after revalidating its immutable proof.
|
|
668
|
+
Failures require explicit `--retry` and remain bounded by the attempt budget;
|
|
669
|
+
unreported usage and interrupted wall time retain conservative reservations.
|
|
670
|
+
A nonpassing mechanical packet can receive an independent stop verdict, never
|
|
671
|
+
an override. The existing manual submit command remains available for an exact
|
|
672
|
+
independent review.
|
|
673
|
+
|
|
674
|
+
Reviewer status is read-only and transport-aware. Native-direct does not
|
|
675
|
+
require a bridge connection. Smoke configuration readiness is explicitly not
|
|
676
|
+
production readiness and does not demand an attestation that smoke mode never
|
|
677
|
+
writes. Production still requires its current reviewer doctor attestation.
|
|
678
|
+
|
|
679
|
+
Repeat the same prepare/execute route for `evidence-construct`, adding an
|
|
654
680
|
owner-reviewed JSON array of absolute canonical canary paths with
|
|
655
681
|
`--canary-artifacts /absolute/path/to/canary-paths.json`, and then for
|
|
656
682
|
`pilot-methods` at its stage boundary. A top-journal fork or addendum is a
|
|
@@ -966,6 +992,25 @@ resume criteria. Research then stops; it does not spend more budget on
|
|
|
966
992
|
low-yield substitutes. If no lawful remaining route exists, the user must narrow
|
|
967
993
|
or abandon the unsupported scope before a new reviewed generation can resume.
|
|
968
994
|
|
|
995
|
+
Before submitting an acquisition audit, inspect its exact current eligibility:
|
|
996
|
+
|
|
997
|
+
```bash
|
|
998
|
+
tiangong-ai research project evidence content forecast PROJECT \
|
|
999
|
+
--input /absolute/path/acquisition-audit.json --workspace /absolute/workspace --json
|
|
1000
|
+
```
|
|
1001
|
+
|
|
1002
|
+
This read-only check uses the freeze path's source projection and coverage
|
|
1003
|
+
rules, checks registered artifact bytes and provenance, and forecasts required
|
|
1004
|
+
roles from potentially assignable source dimensions. Exit `3` identifies known
|
|
1005
|
+
deficits; exit `0` means only potential eligibility, never successful atom
|
|
1006
|
+
registration, content freeze, independence certification, or review. Pending
|
|
1007
|
+
input materialization, decomposition, and exact atom assignments remain
|
|
1008
|
+
explicit. Re-run after material acquisition changes, not after every atom.
|
|
1009
|
+
Flat `sourceTypeRequirements` arrays mean **all-of**. A design may instead use
|
|
1010
|
+
`{"allOf":["academic-paper"],"anyOf":["government","industry"],"atLeast":{"count":2,"from":["academic-paper","government","industry"]}}`;
|
|
1011
|
+
every present group applies, and counts use distinct types. Forecast, typed
|
|
1012
|
+
content, and scientific review use the same source-type evaluator.
|
|
1013
|
+
|
|
969
1014
|
Acquisition freezes an immutable evidence snapshot even when lawful retrieval
|
|
970
1015
|
ends with explicit gaps. Before inference, decompose every acquired PDF,
|
|
971
1016
|
spreadsheet, archive, or structured file into exact lineage-bound producer-
|
|
@@ -984,6 +1029,46 @@ closure remains unchanged, the child snapshot records a mechanical delta, and
|
|
|
984
1029
|
default status hides the superseded project (`research status --all` shows full
|
|
985
1030
|
lineage).
|
|
986
1031
|
|
|
1032
|
+
For many content records, use `research project evidence decomposition batch
|
|
1033
|
+
<project-id> --record <absolute-json>` or `research project evidence atom batch
|
|
1034
|
+
<project-id> --record <absolute-json>`, with `--workspace` and `--json` as needed.
|
|
1035
|
+
The input is `{"schemaVersion":1,"records":[...]}`; each item has exactly the same
|
|
1036
|
+
schema and validation as the corresponding single-record command. A batch is
|
|
1037
|
+
bounded to 500 records and 4 MiB of input. The CLI verifies acquisition/artifact
|
|
1038
|
+
bindings once per batch, groups atoms by artifact to read and parse each referenced
|
|
1039
|
+
document once without retaining all files in memory, and commits one hash-bound
|
|
1040
|
+
immutable envelope through one ledger event. A bad item commits nothing; identical
|
|
1041
|
+
replay is idempotent and a changed ID is rejected. Uncommitted envelopes are never
|
|
1042
|
+
visible and a retry can safely complete their commit. `work` reports deterministic
|
|
1043
|
+
verification, read, and append counts; no persistent verification cache is trusted.
|
|
1044
|
+
|
|
1045
|
+
Retrieve these CLI-owned input schemas with `research schema show evidence-atom`,
|
|
1046
|
+
`artifact-decomposition`, `evidence-atom-batch`, or `artifact-decomposition-batch`
|
|
1047
|
+
and `--json`. Help and command intake share the batch-limit constants. Schemas
|
|
1048
|
+
validate structure; execution still checks exact artifact/lineage bindings,
|
|
1049
|
+
locator semantics, stage, and sensitive content. A schema pass is not admission.
|
|
1050
|
+
|
|
1051
|
+
Before a potentially large download, use the offline command
|
|
1052
|
+
`research project evidence artifact preflight --bytes <known-bytes> --workspace
|
|
1053
|
+
<path> --json`, or replace `--bytes` with `--path <exact-local-file>` for a stat-only
|
|
1054
|
+
check. `budget.maxBytesPerArtifact` bounds one acquired/downloaded file;
|
|
1055
|
+
`budget.maxBytesPerPackage` separately bounds aggregate generated stage outputs.
|
|
1056
|
+
Both are exposed in preflight, and native packets expose `maxArtifactBytes` beside
|
|
1057
|
+
`maxOutputBytes`. Their defaults remain 20 MiB in smoke mode and 512 MiB in
|
|
1058
|
+
production. A missing artifact field in an existing configuration retains its
|
|
1059
|
+
existing package limit in memory without rewriting the owner's file; an explicit
|
|
1060
|
+
invalid limit is rejected. Preflight exit 3 means stop and request a provider-side
|
|
1061
|
+
subset/filter or smaller official export preserving required variables/provenance.
|
|
1062
|
+
A size pass is not content acceptance: download binding, format, archive-expansion,
|
|
1063
|
+
SHA-256, and snapshot checks still apply. This is not a large-file streaming or
|
|
1064
|
+
external-reference bypass.
|
|
1065
|
+
|
|
1066
|
+
Use acquisition `gaps` only for unresolved blocking evidence deficiencies;
|
|
1067
|
+
`limitations` holds non-blocking scope constraints and intentionally sealed
|
|
1068
|
+
outcomes. Future Policy obligations stay in the scientific design and appear
|
|
1069
|
+
in `futureGateObligations`, including ordinary planned rules without pending
|
|
1070
|
+
model/uncertainty objects. Their declared gate remains authoritative.
|
|
1071
|
+
|
|
987
1072
|
Accepted local inputs are normalized into immutable input-backed artifacts while
|
|
988
1073
|
the acquire package is still active. JSON, CSV, Markdown, and plain-text inputs
|
|
989
1074
|
therefore have an atom-capable identity even when the producer omitted an
|
|
@@ -1001,6 +1086,12 @@ JSON/JSONL `projectId`, so historical blocked siblings do not alter its exit
|
|
|
1001
1086
|
status. Omit `--project` and use `--max-parallel` only for an intentional
|
|
1002
1087
|
workspace-wide run.
|
|
1003
1088
|
|
|
1089
|
+
Run/status share the same due scientific-gate decision: pending/prepared review,
|
|
1090
|
+
revision-required, and stopped are distinct from a runnable native stage.
|
|
1091
|
+
Future gates do not prevent earlier discovery or acquisition. Legitimate
|
|
1092
|
+
historical and user/external-wait project states remain doctor-readable;
|
|
1093
|
+
unknown states and broken evidence bindings still block readiness.
|
|
1094
|
+
|
|
1004
1095
|
Inputs are admitted by SHA-256. Native producer preparation creates an
|
|
1005
1096
|
ephemeral, hash-bound packet directory but does not copy agent authentication
|
|
1006
1097
|
or start an agent. The independent reviewer runs with a dedicated capsule HOME
|
|
@@ -1279,6 +1370,18 @@ pilot-methods reviews before analysis. `research status --all` marks any legacy
|
|
|
1279
1370
|
fork directory without a `project.forked` commit marker as
|
|
1280
1371
|
`authority.state = "invalid"` rather than authoritative.
|
|
1281
1372
|
|
|
1373
|
+
To repair completed acquisition before analysis, use
|
|
1374
|
+
`research project fork SOURCE --to TARGET --resume-through discover`. This
|
|
1375
|
+
preserves the original frozen audit, inherits verified discovery/receipts and
|
|
1376
|
+
exact acquired artifacts, and opens TARGET's acquire stage. Reuse the returned
|
|
1377
|
+
artifact IDs from the source acquisition audit, run
|
|
1378
|
+
`project evidence content forecast TARGET --input AUDIT`,
|
|
1379
|
+
then prepare/submit TARGET's acquire stage and rebuild typed content. There is
|
|
1380
|
+
no need to repeat paid searches or download unchanged files. Top-journal
|
|
1381
|
+
recovery additionally requires a Policy approved for TARGET and `--design`,
|
|
1382
|
+
`--design-producer-agent`, and `--design-producer-session`; new generation
|
|
1383
|
+
reviews cannot inherit the source generation's scientific approval.
|
|
1384
|
+
|
|
1282
1385
|
## Research Search
|
|
1283
1386
|
|
|
1284
1387
|
Forward research-oriented search requests to SCI, report, patent, and ESG edge
|
|
@@ -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 {
|
|
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 {
|
|
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
|
-
|
|
215
|
-
|
|
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
|
|
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", () =>
|
|
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", () =>
|
|
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,
|
|
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,
|
|
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
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
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 >
|
|
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,
|