@tiangong-ai/cli 0.0.60 → 0.0.61

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 (73) hide show
  1. package/AGENTS.md +2 -2
  2. package/README.md +167 -26
  3. package/dist/research/orchestration.js +108 -18
  4. package/dist/research/orchestration.js.map +1 -1
  5. package/dist/research/workspace/acquisition-routes.d.ts +1 -1
  6. package/dist/research/workspace/acquisition-routes.js +2 -11
  7. package/dist/research/workspace/acquisition-routes.js.map +1 -1
  8. package/dist/research/workspace/artifact-read-audit.d.ts +16 -0
  9. package/dist/research/workspace/artifact-read-audit.js +176 -0
  10. package/dist/research/workspace/artifact-read-audit.js.map +1 -0
  11. package/dist/research/workspace/artifact-trace.d.ts +12 -0
  12. package/dist/research/workspace/artifact-trace.js +109 -0
  13. package/dist/research/workspace/artifact-trace.js.map +1 -0
  14. package/dist/research/workspace/artifact-view-mcp.d.ts +75 -0
  15. package/dist/research/workspace/artifact-view-mcp.js +214 -0
  16. package/dist/research/workspace/artifact-view-mcp.js.map +1 -0
  17. package/dist/research/workspace/artifact-views.d.ts +100 -0
  18. package/dist/research/workspace/artifact-views.js +395 -0
  19. package/dist/research/workspace/artifact-views.js.map +1 -0
  20. package/dist/research/workspace/audit-bundle.d.ts +4 -0
  21. package/dist/research/workspace/audit-bundle.js +107 -8
  22. package/dist/research/workspace/audit-bundle.js.map +1 -1
  23. package/dist/research/workspace/executor.d.ts +5 -1
  24. package/dist/research/workspace/executor.js +106 -22
  25. package/dist/research/workspace/executor.js.map +1 -1
  26. package/dist/research/workspace/native-run.d.ts +77 -0
  27. package/dist/research/workspace/native-run.js +637 -0
  28. package/dist/research/workspace/native-run.js.map +1 -0
  29. package/dist/research/workspace/preflight.d.ts +8 -2
  30. package/dist/research/workspace/preflight.js +17 -14
  31. package/dist/research/workspace/preflight.js.map +1 -1
  32. package/dist/research/workspace/project-mutations.d.ts +1 -1
  33. package/dist/research/workspace/project-mutations.js +5 -3
  34. package/dist/research/workspace/project-mutations.js.map +1 -1
  35. package/dist/research/workspace/projects.js +1 -0
  36. package/dist/research/workspace/projects.js.map +1 -1
  37. package/dist/research/workspace/request-provenance.d.ts +67 -0
  38. package/dist/research/workspace/request-provenance.js +115 -0
  39. package/dist/research/workspace/request-provenance.js.map +1 -0
  40. package/dist/research/workspace/review-executor.js +22 -11
  41. package/dist/research/workspace/review-executor.js.map +1 -1
  42. package/dist/research/workspace/runtime.d.ts +52 -0
  43. package/dist/research/workspace/runtime.js +221 -98
  44. package/dist/research/workspace/runtime.js.map +1 -1
  45. package/dist/research/workspace/sanitization.js +1 -1
  46. package/dist/research/workspace/sanitization.js.map +1 -1
  47. package/dist/research/workspace/schema-compatibility.d.ts +5 -0
  48. package/dist/research/workspace/schema-compatibility.js +55 -0
  49. package/dist/research/workspace/schema-compatibility.js.map +1 -0
  50. package/dist/research/workspace/scientific-design.js +8 -17
  51. package/dist/research/workspace/scientific-design.js.map +1 -1
  52. package/dist/research/workspace/scientific-fulfillment-audit.d.ts +3 -0
  53. package/dist/research/workspace/scientific-fulfillment-audit.js +137 -0
  54. package/dist/research/workspace/scientific-fulfillment-audit.js.map +1 -0
  55. package/dist/research/workspace/scientific-fulfillment.d.ts +121 -0
  56. package/dist/research/workspace/scientific-fulfillment.js +539 -0
  57. package/dist/research/workspace/scientific-fulfillment.js.map +1 -0
  58. package/dist/research/workspace/scientific-review-execution.js +82 -61
  59. package/dist/research/workspace/scientific-review-execution.js.map +1 -1
  60. package/dist/research/workspace/scientific-review.d.ts +5 -1
  61. package/dist/research/workspace/scientific-review.js +197 -52
  62. package/dist/research/workspace/scientific-review.js.map +1 -1
  63. package/dist/research/workspace/setup-catalog.js +2 -2
  64. package/dist/research/workspace/task-acceptance.d.ts +10 -2
  65. package/dist/research/workspace/task-acceptance.js +72 -8
  66. package/dist/research/workspace/task-acceptance.js.map +1 -1
  67. package/dist/research/workspace/task-audit.js +52 -2
  68. package/dist/research/workspace/task-audit.js.map +1 -1
  69. package/dist/research/workspace/task-contract.d.ts +4 -1
  70. package/dist/research/workspace/task-contract.js +26 -5
  71. package/dist/research/workspace/task-contract.js.map +1 -1
  72. package/dist/research/workspace/types.d.ts +6 -3
  73. 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-03
21
- lastReviewedCommit: 06dadef170ab79c19eef9a35663e86fdee22479b
20
+ lastReviewedAt: 2026-09-04
21
+ lastReviewedCommit: 4cb45f23331677a7c713f20f3aa3cbb65afe9358
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-03
16
- lastReviewedCommit: 06dadef170ab79c19eef9a35663e86fdee22479b
15
+ lastReviewedAt: 2026-09-04
16
+ lastReviewedCommit: 25b236a15c846c0168ffb84f8afa390d71985f4b
17
17
  ---
18
18
 
19
19
  # Tiangong AI CLI
@@ -607,8 +607,9 @@ owns the same due gate. Pending implementations use `null` for implementation
607
607
  SHA-256, locator, and entrypoint; pending environments use `null` for lock
608
608
  SHA-256 and locator. They are exposed in every earlier review packet as
609
609
  `futureGateObligations` and become blocking mechanical errors at that gate.
610
- Freezing them requires a new authoritative generation; it never upgrades the
611
- old object in place.
610
+ Their predeclared slots may be fulfilled through the append-only same-project
611
+ command below. The original design bytes never change; a material assumption,
612
+ question, policy or already-frozen value still requires a reviewed successor.
612
613
 
613
614
  Use the same Policy project ID and exact design when preflighting and admitting
614
615
  the research project:
@@ -677,6 +678,16 @@ schema-valid, packet/session-bound review. A saved successful execution is
677
678
  replayed without another model call after revalidating its immutable proof.
678
679
  Failures require explicit `--retry` and remain bounded by the attempt budget;
679
680
  unreported usage and interrupted wall time retain conservative reservations.
681
+ Failed processes return a bounded, sanitized exit diagnostic and record it in
682
+ the journal; no full prompt or raw authentication output is persisted. Automatic
683
+ Claude invocation uses the same dialect-annotation conversion as
684
+ `research schema show NAME --compatibility claude-code`; canonical controller
685
+ validation and its scientific constraints remain unchanged.
686
+ The provider view explicitly types scalar constants/enums; returned values are
687
+ never coerced to satisfy the canonical schema.
688
+ Claude's structured result is used instead of any accompanying narrative;
689
+ declared error results remain failures, with their safe diagnostic ahead of
690
+ incidental stderr warnings.
680
691
  A nonpassing mechanical packet can receive an independent stop verdict, never
681
692
  an override. The existing manual submit command remains available for an exact
682
693
  independent review.
@@ -685,6 +696,8 @@ Reviewer status is read-only and transport-aware. Native-direct does not
685
696
  require a bridge connection. Smoke configuration readiness is explicitly not
686
697
  production readiness and does not demand an attestation that smoke mode never
687
698
  writes. Production still requires its current reviewer doctor attestation.
699
+ Packet read responses carry their actual content and receipt together; a
700
+ receipt alone does not establish that the host displayed the content to its model.
688
701
 
689
702
  Repeat the same prepare/execute route for `evidence-construct`, adding an
690
703
  owner-reviewed JSON array of absolute canonical canary paths with
@@ -759,6 +772,12 @@ derivatives. Credentials, setup
759
772
  sources, browser profiles, native active state, capsules, unrelated projects,
760
773
  and host-specific absolute paths are excluded.
761
774
 
775
+ Text inspection distinguishes internal identifiers such as `interruptedSessionId`
776
+ from credential fields. It checks raw text and read-only decoded JSON/JSONL,
777
+ including escaped keys and nested string payloads, while retaining the exact
778
+ evidence and ledger bytes. Authentication values remain blocked even when wrapped
779
+ in arrays or objects; an identifier's UUID shape is never a credential exemption.
780
+
762
781
  ```bash
763
782
  tiangong-ai research project audit export top-journal-paper \
764
783
  --output /absolute/path/to/new-audit-directory \
@@ -859,8 +878,10 @@ For large local sources, pass an immutable `--input-plan` to both preflight and
859
878
  project initialization. Each plan entry may expose either a separate
860
879
  `contextPath` or non-overlapping, one-based `contextRanges`; the producer sees
861
880
  only that bounded context, while independent review receives the hash-verified
862
- full source. Symlinks, duplicate content, changed hashes, and context above
863
- `maxInputContextTokens` are rejected.
881
+ full source. Symlinks, duplicate content and changed hashes are rejected.
882
+ There is no total stage-context length gate: large admitted objects remain complete
883
+ and are read through the packet's artifact directory instead of being forced into
884
+ the initial prompt. This does not expose files deliberately withheld by an input plan.
864
885
 
865
886
  The workspace stores its current protocol state under `.tiangong-research/`.
866
887
  Each project follows the evidence-first sequence: broad discovery, strict
@@ -871,6 +892,13 @@ CodeBuddy session. The CLI never launches a nested producer process. Independent
871
892
  runs through the other configured agent family's CLI, and execution is blocked
872
893
  when the two roles use the same family.
873
894
 
895
+ Native packets direct the host to save one new JSON submission file, not to write
896
+ admitted output paths. Acquire may retrieve files and readable derivatives for
897
+ provisionally admitted sources through the packet's binding/registration commands;
898
+ it may not reopen discovery. Analyze, synthesize and the isolated reviewer retain
899
+ their no-new-evidence boundary. Headless reviewer prompts remain capsule-scoped
900
+ and return JSON rather than saving native submission files.
901
+
874
902
  Every workspace mutation is serialized by an owner-recorded directory lease
875
903
  with a heartbeat. A later command immediately reclaims a lease whose same-host
876
904
  owner process is definitely dead; an unverifiable cross-host lease is reclaimed
@@ -1165,7 +1193,8 @@ total tokens, USD 5,000, 30 days, and package ceilings of 12,000,000 for discove
1165
1193
  acquisition, 1,500,000 each for analysis and synthesis, and 2,500,000 for
1166
1194
  review. Primary output is bounded at 32,000 tokens and a separately invoked
1167
1195
  repair at 16,000. The production broker hard ceiling is 256 bounded views with
1168
- 32,000 context tokens per view; input context is bounded at 128,000 tokens.
1196
+ 32,000 context tokens per broker view. The legacy `maxInputContextTokens` setting
1197
+ is an embedding/planning hint, not an input admission or artifact-read ceiling.
1169
1198
  Top-journal admission additionally reserves three early scientific reviews at
1170
1199
  500,000 tokens each, four final publication reviews at 750,000 each, and one
1171
1200
  4,000,000-token revision cycle, including their finite wall-time allowances.
@@ -1174,7 +1203,7 @@ stop control ordinary use, while the finite ceilings, three attempts per
1174
1203
  package, and explicit confirmation above the cost threshold stop runaway work.
1175
1204
  Smoke-test workspaces retain their smaller low-cost defaults.
1176
1205
  Before project initialization and every executable package, the control plane
1177
- requires the complete token and conservative price reservation to fit. Native
1206
+ requires a token and conservative price estimate to fit the finite execution budget. Native
1178
1207
  producer stages reserve prompt, schema, admitted context, bounded broker
1179
1208
  context, and output allowance, but the host app does not expose trusted
1180
1209
  per-stage usage telemetry to this CLI. A successful native submit therefore
@@ -1184,9 +1213,14 @@ output bytes/tokens, provenance, coverage, hashes, and remaining project budget.
1184
1213
  It does not claim a provider-side turn or output-token cap for the host app.
1185
1214
 
1186
1215
  Independent review uses the pre-call reservation calculator and the reviewer's
1187
- provider-side structured-output/turn controls where available. Review admission
1188
- reserves three maximum-size generated artifacts plus one globally bounded
1189
- evidence-excerpt bundle, and formatting repair remains one separately budgeted,
1216
+ provider-side structured-output/turn controls where available. Claude packet-only
1217
+ review has a 64-turn provider guard; Codex uses the existing finite wall-time and
1218
+ token/cost guards because its CLI has no equivalent turn flag. Planning uses a
1219
+ small initial-context estimate and expected reads, not the entire corpus or an
1220
+ unbounded legacy context hint. Preflight reports `inputContextTokenLimit=null`.
1221
+ These are approximate estimates, not precise billing; scientific review keeps
1222
+ the approved remaining cost ceiling separate from its rough read-cost estimate.
1223
+ Formatting repair remains one separately budgeted,
1190
1224
  tool-free JSON correction. Production workspaces enforce a finite 256-view
1191
1225
  broker ceiling mechanically, while each project derives a much smaller working
1192
1226
  budget from its reviewed coverage requirements and stops early when they are
@@ -1211,8 +1245,9 @@ context, evidence objects, and registered local input hashes before recording
1211
1245
  their safe locators. Capsule deletion therefore does not delete the durable
1212
1246
  review chain.
1213
1247
 
1214
- Native discovery preparation embeds the exact staged capability manifest and
1215
- each external Skill's top-level `SKILL.md`. It also projects every built-in data
1248
+ Native discovery preparation supplies the exact staged capability manifest and
1249
+ each external Skill's top-level `SKILL.md` inline or by an exact artifact reference.
1250
+ It also projects every built-in data
1216
1251
  operation dynamically, with no per-provider Research adapter. The current host
1217
1252
  may fetch generic broker evidence with `research project evidence fetch`, whose bounded request file
1218
1253
  contains logical IDs but no credential values. The manifest includes the locked,
@@ -1240,19 +1275,37 @@ credentialed operation must resolve its namespaced logical credential from the
1240
1275
  workspace's owner-only store or it is blocked before any provider request.
1241
1276
  Standalone `tiangong-ai data run` keeps its separate manifest-declared
1242
1277
  environment-variable policy. A blocked data result is not promoted to evidence.
1243
- Analyze and synthesize packets contain bounded, hash-verified prior-stage
1244
- artifacts and require no external evidence calls. Review is tool-free and uses the
1245
- reviewer's route-specific structured-output turn cap:
1246
- its prompt embeds the complete generated artifacts and a deterministic,
1247
- globally bounded set of excerpts distributed across registered local contexts
1248
- and broker receipts. Broker excerpts prioritize deterministic, sanitized
1278
+ Analyze and synthesize packets contain hash-verified prior-stage artifacts and
1279
+ require no external evidence calls. Base and scientific review use only the
1280
+ packet-bound `research_list_artifacts` and `research_read_artifact` tools; shell,
1281
+ general filesystem, browser, broker and undeclared integrations remain disabled.
1282
+ The same surface works through native-direct and the signed sandbox-bridge.
1283
+ Small objects/excerpts are included initially; large objects are referenced without
1284
+ rejecting the stage. Broker excerpts prioritize deterministic, sanitized
1249
1285
  projections of the exact raw-response items selected by admitted evidence JSON
1250
1286
  Pointers; uncited receipts retain metadata-only bindings, and unresolved
1251
1287
  pointers receive a bounded-context fallback. The packet hash is schema-bound, but complete packet
1252
1288
  metadata is not redundantly copied into model context. Full local files,
1253
- original per-receipt bounded contexts, raw broker objects, and the complete
1254
- packet remain hash-bound for durable human/mechanical audit; the model must not
1255
- claim to have read beyond the embedded excerpts.
1289
+ original per-receipt contexts, raw broker objects, checks and counterevidence stay
1290
+ discoverable in the exact directory. Reads use opaque object IDs and byte offsets;
1291
+ UTF-8 pages preserve character boundaries. Omit `length` for a 16 KiB page or use
1292
+ `length: null` for the whole object, without a CLI read-length ceiling. Objects
1293
+ actually read are preserved under `reads/objects/`, with exact directory and
1294
+ packet/object/view hash receipts. Receipts prove bytes delivered, not comprehension
1295
+ or scientific truth; actual provider/model capacity remains a limitation.
1296
+
1297
+ Native hosts can use the same primitives without adding an IDE integration:
1298
+
1299
+ ```bash
1300
+ tiangong-ai research project stage artifacts PROJECT --session SESSION --workspace /absolute/workspace --json
1301
+ tiangong-ai research project stage read PROJECT --session SESSION --artifact OBJECT_ID --offset 0 --length 16384 --workspace /absolute/workspace --json
1302
+ tiangong-ai research project stage read PROJECT --session SESSION --artifact OBJECT_ID --length all --workspace /absolute/workspace --json
1303
+ ```
1304
+
1305
+ Follow `nextOffset` for subsequent pages. `--encoding base64` explicitly requests
1306
+ binary bytes; prefer a registered text derivative for interpretation. The channel
1307
+ does not scan arbitrary host paths or discover files created after the snapshot.
1308
+ Stopped, changed or expired native sessions cannot read through it.
1256
1309
  The CLI mechanically derives local full-text availability, source types,
1257
1310
  counts, date coverage, source IDs, and the coverage decision. A `partial`
1258
1311
  dimension is usable but incomplete; a missing dimension or unmet declared
@@ -1444,6 +1497,43 @@ start a new generation. There is no automatic migration. A top-journal successor
1444
1497
  requires a Policy approved for TARGET and `--design`, `--design-producer-agent`,
1445
1498
  and `--design-producer-session`; it cannot inherit scientific approval.
1446
1499
 
1500
+ ### Fulfill predeclared scientific objects
1501
+
1502
+ At an idle boundary before analysis, register the exact code/environment files
1503
+ as scientific objects, then supply only the pending slots already named in the
1504
+ frozen design:
1505
+
1506
+ ```bash
1507
+ tiangong-ai research schema show scientific-fulfillment --json
1508
+ tiangong-ai research scientific fulfillment status PROJECT --workspace /absolute/workspace --json
1509
+ tiangong-ai research scientific fulfillment record PROJECT \
1510
+ --input /absolute/fulfillment.json --workspace /absolute/workspace --json
1511
+ ```
1512
+
1513
+ The closed input names `designSha256`, the exact `parentFulfillmentSha256`
1514
+ (`null` initially), a non-sensitive reason, and arrays `modelImplementations`,
1515
+ `environmentLocks`, and `parameterStates`. Model entries bind the registered
1516
+ `objectLocator`, raw `sha256`, registration `recordSha256`, and the declared
1517
+ `modelId`; implementations additionally supply `entrypoint`. Parameter entries
1518
+ name the existing `parameterId` and every exact `stateId`, its source-derived
1519
+ `value`, and admitted `evidenceAtomIds` from the frozen typed-content snapshot.
1520
+ Units, state sets, ranges, factors, composition, claims, thresholds and Policy
1521
+ cannot be changed through this intake. At least one pending slot is required.
1522
+
1523
+ Identical replay returns the same immutable record. Replacing an already-frozen
1524
+ slot, guessing a parent, an active native session, or analysis/inference already
1525
+ started is refused. The journal is the commit point; interrupted state projection
1526
+ uses the same narrow recovery mechanism as acquisition/scope revisions.
1527
+
1528
+ Only the fulfillment's due gate and later scientific gates are reset; earlier
1529
+ reviews remain bound to their unchanged deadline-specific design view. New review
1530
+ packets include the original design, the exact fulfillment chain, the effective
1531
+ view and registered code/environment bytes. Filing objects does **not** mark the
1532
+ original Policy rule scientifically satisfied or certify code execution. The
1533
+ existing independent reviewer must assess the actual objects and rule. Portable
1534
+ audits retain the raw objects and registration metadata and verify the committed
1535
+ fulfillment head, slot semantics and current review view after relocation.
1536
+
1447
1537
  ### Original task, current scope, and actual checks
1448
1538
 
1449
1539
  For a new research project, record a small original-requirement checklist after
@@ -1462,6 +1552,17 @@ Each requirement has a stable ID, acceptance condition, `checkKind` (`evidence`,
1462
1552
  coverage dimensions. Original wording cannot be overwritten. Old projects without
1463
1553
  a task remain explicitly unassessed rather than retrospectively accepted.
1464
1554
 
1555
+ Optional `requestProvenance` supplies `mode` (`verbatim`, `interpreted`, or
1556
+ `reconstructed`), `source` (`kind: user-message|user-file`, exact `text`, `locator`
1557
+ or null), and `explanation`. A null source is valid only for reconstruction.
1558
+ Verbatim source text must equal `originalRequest` exactly, including BOM and line
1559
+ endings. Source bytes are immutable; locator values are retained only by hash.
1560
+ Missing provenance is explicitly `unrecorded`, never inferred retroactively.
1561
+ Scope changes and forks preserve it. Declared origin is not authenticated authorship;
1562
+ secrets are rejected before admission.
1563
+ Scientific review also stages the exact supplied request-source object, so its
1564
+ original bytes are available through the same packet-only read channel as its hash.
1565
+
1465
1566
  Before analysis, use `research schema show task-scope-change` and
1466
1567
  `project task scope propose PROJECT --input FILE --expected-contract SHA` to
1467
1568
  propose a change. Review the returned `changes.details` before/after values, then
@@ -1479,17 +1580,57 @@ between native stages. Records bind the exact requirement version, source/atom/
1479
1580
  finding IDs, and explicitly selected bounded UTF-8 result files. The declared
1480
1581
  command is stored only by hash and is **not executed by this command**. Raw result
1481
1582
  bytes are copied into immutable hash-addressed objects; secrets and control-store
1482
- sources are rejected. Positive/negative computational outcomes need a command and
1483
- results; failed, inconclusive, and not-run checks remain honest without invented
1484
- results. All records say `trust=native-observation`, `executionCertified=false`.
1583
+ sources are rejected. A reported computation without an observed run remains
1584
+ `unverified-execution`, not an answered computational requirement. Failed,
1585
+ inconclusive and not-run checks remain honest without invented results. Evidence
1586
+ and proof checks need no fabricated computation. All records say
1587
+ `trust=native-observation`, `executionCertified=false`.
1588
+
1589
+ For an actual calculation, the native host authors and reviews one ordinary
1590
+ Node/Python program and explicitly requests observation:
1591
+
1592
+ ```bash
1593
+ tiangong-ai research schema show task-native-run --json
1594
+ tiangong-ai research project task run observe PROJECT \
1595
+ --input /absolute/native-run.json --confirm-execution --workspace /absolute/workspace --json
1596
+ tiangong-ai research project task run inspect PROJECT --run RUN_ID \
1597
+ --workspace /absolute/workspace --json
1598
+ ```
1485
1599
 
1486
- One unchanged result blob is stored and included once per reviewer context. The
1600
+ The closed request binds the computational requirement version, explicit
1601
+ interpreter, script, environment-lock declaration, current acquisition artifact
1602
+ IDs/hashes, unique output filenames, non-secret arguments and finite timeout.
1603
+ Use `{input:ID}` / `{output:ID}` placeholders rather than host paths in arguments,
1604
+ and name `nativeSessionId` when a producer stage is active. The CLI snapshots
1605
+ inputs and plans exact output paths before invoking the ordinary program. It
1606
+ adds no permission bypass or dependency installation, forwards no provider
1607
+ credentials and launches no reasoning agent. The workspace lease is released
1608
+ during computation. Program authoring and scientific decisions remain native.
1609
+
1610
+ The returned record binds runtime/code/input/output bytes, process exit/signal
1611
+ and time. Use `nativeRunSha256` at acceptance; those results come only from that
1612
+ run, not a directory scan or unrelated external files. Success requires a zero
1613
+ exit, stable inputs and every declared output; failure/timeout/cancellation and
1614
+ missing or changed outputs remain nonpassing records. Committed replay does not
1615
+ run again. An incomplete interrupted run requires inspection and an explicitly
1616
+ new run ID, not automatic retry. `stagingDirectoryName` is only a safe relative
1617
+ local-inspection hint; permanent hash-bound objects carry audit authority.
1618
+ `observation=cli-observed-native-process` is not mathematical correctness or an
1619
+ authenticated execution certificate. The dependency lock is explicitly
1620
+ `declared-lock-not-attested`; no hermetic-environment claim is inferred.
1621
+
1622
+ One unchanged result blob is stored once and appears once in the reviewer directory. The
1487
1623
  existing independent review receives the original request, original/current
1488
1624
  requirements, exact checks and results, and returns a bound `taskAssessment`;
1489
1625
  there is no additional default paid review round. Missing current checks stop
1490
1626
  before review, and stale/failed/inconclusive checks cannot be promoted to answered.
1491
1627
  Publication packets and portable audit verification retain these relationships;
1492
1628
  hash integrity does not prove execution, scientific validity, or editorial acceptance.
1629
+ Native and scientific packets stage observed programs, locks, inputs and outputs
1630
+ for exact on-demand inspection. Portable audit checks native start/completion
1631
+ events, requirement versions and all run objects. It also replays read selectors
1632
+ against the exact stored object, directory and packet/delivery records; a rehashed
1633
+ outer inventory cannot hide missing program bytes or a changed read receipt.
1493
1634
 
1494
1635
  `project task status` and each `research run` project summary report original and
1495
1636
  current task completion separately from workflow completion and publication verdict.
@@ -31,16 +31,19 @@ import { recordNativeResearchActivity } from "./workspace/native-activity.js";
31
31
  import { inspectReviewerStatus, startReviewerBridgeSidecar } from "./workspace/review-executor.js";
32
32
  import { readAndVerifyProjectInputPlan } from "./workspace/input-plan.js";
33
33
  import { executeScientificReview } from "./workspace/scientific-review-execution.js";
34
+ import { claudeCodeCompatibleSchema } from "./workspace/schema-compatibility.js";
34
35
  import { loadCurrentClaimEvidenceGraph, loadCurrentInferenceSnapshot, } from "./workspace/inference.js";
35
36
  import { addProjectInput, createProjectAddendum, initializeProject, forkProject, listProjects, loadProject, nextReadyPackage, normalizeEvidenceRequirements, refreshProject, retryProjectPackage, setProjectDisposition, scientificGateRecommendedAction, } from "./workspace/projects.js";
36
37
  import { evaluateProjectPreflight } from "./workspace/preflight.js";
37
38
  import { closePublication, freezePublicationManuscript, inspectPublicationStatus, preparePublicationReview, publicationAssessmentSchema, publicationReviewSchema, submitPublicationReview, } from "./workspace/publication-workflow.js";
38
39
  import { approveResearchPolicy, initializeResearchPolicy, inspectResearchPolicyCatalog, inspectResearchPolicyStatus, loadApprovedResearchPolicy, } from "./workspace/research-policy.js";
39
40
  import { resolveInstalledResearchPolicySource, runInteractiveResearchPolicyWizard, } from "./workspace/research-policy-wizard.js";
40
- import { abortNativeResearchStage, inspectNativeResearchStage, prepareNativeResearchStage, requestResearchHandoff, resolveResearchHandoff, runResearchWorkspace, submitNativeResearchStage, } from "./workspace/runtime.js";
41
+ import { abortNativeResearchStage, inspectNativeResearchStage, prepareNativeResearchStage, readNativeStageArtifact, requestResearchHandoff, resolveResearchHandoff, runResearchWorkspace, submitNativeResearchStage, } from "./workspace/runtime.js";
41
42
  import { schemaForStage } from "./workspace/schemas.js";
42
43
  import { readAndVerifyScientificDesign, scientificDesignSchema, } from "./workspace/scientific-design.js";
43
44
  import { inspectScientificObject, parseScientificObjectKind, registerScientificObject, } from "./workspace/scientific-objects.js";
45
+ import { inspectScientificFulfillment, recordScientificFulfillment, scientificFulfillmentSchema, } from "./workspace/scientific-fulfillment.js";
46
+ import { inspectNativeRun, nativeRunInputSchema, observeNativeRun, } from "./workspace/native-run.js";
44
47
  import { inspectScientificReviewStatus, prepareScientificReview, scientificGateAssessmentSchema, scientificReviewSchema, submitScientificReview, } from "./workspace/scientific-review.js";
45
48
  import { isObject, pathExists, sha256Text, workspacePaths } from "./workspace/storage.js";
46
49
  import { doctorResearchWorkspace, initializeResearchWorkspace, loadWorkspaceConfig, requireResearchWorkspace, withWorkspaceLock, } from "./workspace/workspace.js";
@@ -104,6 +107,10 @@ export function researchOrchestrationHelp() {
104
107
  tiangong-ai research publication close <project-id> [--workspace <path>] [--json]
105
108
  tiangong-ai research scientific object register --kind model-implementation|environment-lock --path <absolute-file> [--media-type <type>] [--workspace <path>] [--json]
106
109
  tiangong-ai research scientific object inspect --kind model-implementation|environment-lock --locator <control-relative-locator> [--workspace <path>] [--json]
110
+ tiangong-ai research scientific fulfillment record <project> --input <json-file> [--workspace <path>] [--json]
111
+ tiangong-ai research scientific fulfillment status <project> [--workspace <path>] [--json]
112
+ tiangong-ai research project task run observe <project> --input <json-file> --confirm-execution [--workspace <path>] [--json]
113
+ tiangong-ai research project task run inspect <project> --run <run-id> [--workspace <path>] [--json]
107
114
  tiangong-ai research project init <project-id> --question <question> [--goal evidence-report|top-journal] [--design <absolute-json> --design-producer-agent codex|claude --design-producer-session <opaque-id>] [--requirements <absolute-json>] [--input-plan <absolute-json>] [--confirm-budget] [--workspace <path>] [--json]
108
115
  tiangong-ai research project preflight --question <question> [--goal evidence-report|top-journal] [--policy-project <project-id> --design <absolute-json>] [--requirements <absolute-json>] [--input-plan <absolute-json>] [--workspace <path>] [--json]
109
116
  tiangong-ai research project input add <project-id> --path <absolute-file> [--role primary|reference|replication] [--trust-status verified-owner-input|unverified-owner-input|reference-only|replication-candidate] [--independently-reproduced] [--workspace <path>] [--json]
@@ -129,6 +136,8 @@ export function researchOrchestrationHelp() {
129
136
  tiangong-ai research project stage prepare <project-id> --stage discover|acquire|analyze|synthesize --host-agent codex|claude|workbuddy|codebuddy [--workspace <path>] [--json]
130
137
  tiangong-ai research project stage submit <project-id> --session <id> --output <absolute-json> [--confirm-model <id>] [--workspace <path>] [--json]
131
138
  tiangong-ai research project stage abort <project-id> --session <id> [--workspace <path>] [--json]
139
+ tiangong-ai research project stage artifacts <project-id> --session <id> [--offset <n>] [--limit <n>] [--path-prefix <prefix>] [--workspace <path>] [--json]
140
+ tiangong-ai research project stage read <project-id> --session <id> --artifact <object-id> [--offset <bytes>] [--length <bytes|all>] [--encoding utf8|base64] [--workspace <path>] [--json]
132
141
  tiangong-ai research project evidence fetch <project-id> --request <absolute-json> [--workspace <path>] [--json]
133
142
  tiangong-ai research project evidence data run <project-id> --request <absolute-data-run-request.json> [--workspace <path>] [--json]
134
143
  tiangong-ai research project evidence activity record <project-id> --record <absolute-json> [--workspace <path>] [--json]
@@ -160,6 +169,28 @@ async function runScientific(argv, io) {
160
169
  const [action, ...rest] = argv;
161
170
  if (!action || action === "--help" || action === "-h")
162
171
  return writeHelp(io);
172
+ if (action === "fulfillment") {
173
+ const [operation, ...arguments_] = rest;
174
+ if (operation !== "record" && operation !== "status")
175
+ throw unknownAction("research scientific fulfillment", operation ?? "");
176
+ const args = parseStrictArgs(arguments_, { ...WORKSPACE_OPTIONS, ...(operation === "record" ? { input: "string" } : {}) }, `research scientific fulfillment ${operation}`);
177
+ if (strictBoolean(args, "help"))
178
+ return writeHelp(io);
179
+ const projectId = onePositional(args.positionals, `research scientific fulfillment ${operation}`);
180
+ const root = await workspaceFromArgs(args);
181
+ if (operation === "status")
182
+ writeJson(io, await inspectScientificFulfillment(root, projectId), args);
183
+ else {
184
+ const path = strictString(args, "input");
185
+ if (!path)
186
+ throw new CliError("Fulfillment record requires --input.", {
187
+ code: "RESEARCH_SCIENTIFIC_FULFILLMENT_INVALID",
188
+ exitCode: 2,
189
+ });
190
+ writeJson(io, await recordScientificFulfillment(root, projectId, await readBoundedJsonRecord(path, "--input", "RESEARCH_SCIENTIFIC_FULFILLMENT_INVALID")), args);
191
+ }
192
+ return 0;
193
+ }
163
194
  if (action !== "object")
164
195
  throw unknownAction("research scientific", action);
165
196
  const [objectAction, ...objectRest] = rest;
@@ -519,6 +550,9 @@ async function runSchema(argv, io) {
519
550
  if (stage === "task-acceptance") {
520
551
  schema = taskAcceptanceInputSchema();
521
552
  }
553
+ else if (stage === "task-native-run") {
554
+ schema = nativeRunInputSchema();
555
+ }
522
556
  else if (isTaskSchemaName(stage)) {
523
557
  schema = taskInputSchema(stage);
524
558
  }
@@ -528,6 +562,9 @@ async function runSchema(argv, io) {
528
562
  else if (stage === "scientific-design") {
529
563
  schema = scientificDesignSchema();
530
564
  }
565
+ else if (stage === "scientific-fulfillment") {
566
+ schema = scientificFulfillmentSchema();
567
+ }
531
568
  else if (stage.startsWith("scientific-assessment-")) {
532
569
  const role = scientificReviewRole(stage.slice("scientific-assessment-".length));
533
570
  schema = scientificGateAssessmentSchema(role);
@@ -570,23 +607,7 @@ function compatibleSchema(schema, compatibility) {
570
607
  details: { supported: ["claude-code"] },
571
608
  });
572
609
  }
573
- const compatible = structuredClone(schema);
574
- const stripMetadata = (value) => {
575
- if (Array.isArray(value)) {
576
- for (const item of value)
577
- stripMetadata(item);
578
- return;
579
- }
580
- if (!value || typeof value !== "object")
581
- return;
582
- const record = value;
583
- delete record.$schema;
584
- delete record.$id;
585
- for (const item of Object.values(record))
586
- stripMetadata(item);
587
- };
588
- stripMetadata(compatible);
589
- return compatible;
610
+ return claudeCodeCompatibleSchema(schema);
590
611
  }
591
612
  async function runContext(argv, io) {
592
613
  const [action, ...rest] = argv;
@@ -981,6 +1002,60 @@ async function runProject(argv, io) {
981
1002
  }
982
1003
  if (action === "stage") {
983
1004
  const [stageAction, ...stageRest] = rest;
1005
+ if (stageAction === "artifacts" || stageAction === "read") {
1006
+ const args = parseStrictArgs(stageRest, {
1007
+ ...WORKSPACE_OPTIONS,
1008
+ session: "string",
1009
+ artifact: "string",
1010
+ offset: "string",
1011
+ limit: "string",
1012
+ length: "string",
1013
+ encoding: "string",
1014
+ "path-prefix": "string",
1015
+ }, `research project stage ${stageAction}`);
1016
+ if (strictBoolean(args, "help"))
1017
+ return writeHelp(io);
1018
+ const sessionId = strictString(args, "session");
1019
+ const objectId = strictString(args, "artifact");
1020
+ if (!sessionId || (stageAction === "read" && !objectId))
1021
+ throw new CliError("Stage artifact reads require --session and an exact --artifact for read.", { code: "RESEARCH_NATIVE_STAGE_SESSION_REQUIRED", exitCode: 3 });
1022
+ const offset = strictString(args, "offset");
1023
+ const limit = strictString(args, "limit");
1024
+ const length = strictString(args, "length");
1025
+ const encoding = strictString(args, "encoding");
1026
+ if (encoding && encoding !== "utf8" && encoding !== "base64")
1027
+ throw new CliError("Artifact encoding must be utf8 or base64.", {
1028
+ code: "RESEARCH_ARTIFACT_VIEW_INVALID",
1029
+ exitCode: 3,
1030
+ });
1031
+ const projectId = onePositional(args.positionals, `research project stage ${stageAction}`);
1032
+ writeJson(io, await readNativeStageArtifact({
1033
+ root: await workspaceFromArgs(args),
1034
+ projectId,
1035
+ sessionId,
1036
+ ...(stageAction === "read"
1037
+ ? {
1038
+ selection: {
1039
+ objectId: objectId,
1040
+ ...(offset === undefined ? {} : { offset: Number(offset) }),
1041
+ ...(length === undefined
1042
+ ? {}
1043
+ : { length: length === "all" ? null : Number(length) }),
1044
+ ...(encoding ? { encoding: encoding } : {}),
1045
+ },
1046
+ }
1047
+ : {
1048
+ listing: {
1049
+ ...(offset === undefined ? {} : { offset: Number(offset) }),
1050
+ ...(limit === undefined ? {} : { limit: Number(limit) }),
1051
+ ...(strictString(args, "path-prefix")
1052
+ ? { pathPrefix: strictString(args, "path-prefix") }
1053
+ : {}),
1054
+ },
1055
+ }),
1056
+ }), args);
1057
+ return 0;
1058
+ }
984
1059
  if (stageAction === "prepare") {
985
1060
  const args = parseStrictArgs(stageRest, { ...WORKSPACE_OPTIONS, stage: "string", "host-agent": "string" }, "research project stage prepare");
986
1061
  if (strictBoolean(args, "help"))
@@ -1043,6 +1118,21 @@ async function runProject(argv, io) {
1043
1118
  }
1044
1119
  if (action === "task") {
1045
1120
  const [taskAction, ...taskRest] = rest;
1121
+ if (taskAction === "run") {
1122
+ const [runAction, ...runRest] = taskRest;
1123
+ if (runAction !== "observe" && runAction !== "inspect")
1124
+ throw unknownAction("research project task run", runAction ?? "");
1125
+ const args = parseStrictArgs(runRest, { ...WORKSPACE_OPTIONS, input: "string", run: "string", "confirm-execution": "boolean" }, `research project task run ${runAction}`);
1126
+ if (strictBoolean(args, "help"))
1127
+ return writeHelp(io);
1128
+ const projectId = onePositional(args.positionals, `research project task run ${runAction}`);
1129
+ const root = await workspaceFromArgs(args);
1130
+ const result = runAction === "inspect"
1131
+ ? await inspectNativeRun(root, projectId, strictString(args, "run") ?? "")
1132
+ : await observeNativeRun(root, projectId, await readBoundedJsonRecord(strictString(args, "input") ?? "", "--input", "RESEARCH_NATIVE_RUN_INVALID"), strictBoolean(args, "confirm-execution"));
1133
+ writeJson(io, result, args);
1134
+ return "record" in result && result.record && result.record.status !== "succeeded" ? 3 : 0;
1135
+ }
1046
1136
  if (taskAction === "acceptance") {
1047
1137
  const [acceptanceAction, ...acceptanceRest] = taskRest;
1048
1138
  if (acceptanceAction !== "record")