@tiangong-lca/cli 0.0.25 → 0.0.27
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/README.md +37 -8
- package/dist/src/cli.js +292 -3
- package/dist/src/cli.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-protected-artifacts.js +100 -0
- package/dist/src/lib/dataset-maintenance-protected-artifacts.js.map +1 -0
- package/dist/src/lib/dataset-maintenance-protected-before.js +284 -0
- package/dist/src/lib/dataset-maintenance-protected-before.js.map +1 -0
- package/dist/src/lib/dataset-maintenance-protected-contract.js +25 -3
- package/dist/src/lib/dataset-maintenance-protected-contract.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-protected-freeze.js +230 -0
- package/dist/src/lib/dataset-maintenance-protected-freeze.js.map +1 -0
- package/dist/src/lib/dataset-maintenance-protected-preparation.js +524 -0
- package/dist/src/lib/dataset-maintenance-protected-preparation.js.map +1 -0
- package/dist/src/lib/dataset-maintenance-protected-run.js +54 -158
- package/dist/src/lib/dataset-maintenance-protected-run.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-protected-seal.js +160 -0
- package/dist/src/lib/dataset-maintenance-protected-seal.js.map +1 -0
- package/dist/src/lib/dataset-maintenance-protected-toolchain.js +86 -0
- package/dist/src/lib/dataset-maintenance-protected-toolchain.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@ checkPaths:
|
|
|
18
18
|
- src/cli.ts
|
|
19
19
|
- src/main.ts
|
|
20
20
|
lastReviewedAt: 2026-07-15
|
|
21
|
-
lastReviewedCommit:
|
|
21
|
+
lastReviewedCommit: bd145f692b3fd11e398302dd6a1d2831e058883a
|
|
22
22
|
---
|
|
23
23
|
|
|
24
24
|
# TianGong LCA CLI
|
|
@@ -33,6 +33,8 @@ Review note, 2026-07-14: maintenance now includes the protected derivative-only
|
|
|
33
33
|
|
|
34
34
|
Review note, 2026-07-15: `dataset maintenance run-protected` adds a production-only path for one sealed private alias execution and its exact 50-target derivative closure. The protected executor is server-dispatched and fenced by the authenticated owner plus exact actor/user_id/state_code=0 and plan-closure checks; RLS remains a defense on public and independent-read surfaces. It performs one server preflight, writes an immutable local attempt marker before one admission POST, and requires status-only recovery after any marker or ambiguous response. It has no dev, legacy-alias, publication, or state-code fallback.
|
|
35
35
|
|
|
36
|
+
Review note, 2026-07-15: `dataset maintenance freeze-protected` and `seal-protected-approval` close the preparation gap without adding a second execution path. Freeze preparation authenticates directly to the explicitly confirmed production project, performs only complete account/support reads plus the 50 derivative snapshot RPCs, and writes an unapproved canonical request. Approval sealing is entirely local and requires the exact human-returned UTF-8 bytes plus explicit freeze/request/text hashes and account confirmation. Only the later `run-protected` command can preflight or admit work.
|
|
37
|
+
|
|
36
38
|
## Run
|
|
37
39
|
|
|
38
40
|
One-off published run:
|
|
@@ -285,7 +287,7 @@ tiangong-lca dataset maintenance plan --scope ./maintenance-scope.json --operati
|
|
|
285
287
|
tiangong-lca dataset maintenance plan --scope ./derivative-rebuild-scope.json --operation rebuild-derivatives --out-dir /abs/path/to/derivative-rebuild --json
|
|
286
288
|
tiangong-lca dataset maintenance apply --plan /abs/path/to/dataset-maintenance/maintenance-plan.json --commit --approve-plan <sha256> --confirm <current-account-email> --timeout-ms 10000 --json
|
|
287
289
|
tiangong-lca dataset maintenance verify --plan /abs/path/to/dataset-maintenance/maintenance-plan.json --out-dir /abs/path/to/dataset-maintenance/verify --page-size 1000 --timeout-ms 10000 --json
|
|
288
|
-
tiangong-lca dataset maintenance run-protected --plan /abs/path/to/maintenance-plan.json --freeze /abs/path/to/protected-execution-
|
|
290
|
+
tiangong-lca dataset maintenance run-protected --plan /abs/path/to/maintenance-plan.json --freeze /abs/path/to/protected-execution-freeze.json --approval /abs/path/to/protected-approval.json --out-dir /abs/path/to/protected-run --status-only --json
|
|
289
291
|
tiangong-lca lifecyclemodel auto-build --input ./examples/lifecyclemodel-auto-build.request.json --out-dir /abs/path/to/lifecyclemodel-run --json
|
|
290
292
|
tiangong-lca lifecyclemodel validate-build --run-dir /abs/path/to/lifecyclemodel-run --json
|
|
291
293
|
tiangong-lca lifecyclemodel publish-build --run-dir /abs/path/to/lifecyclemodel-run --json
|
|
@@ -330,7 +332,7 @@ For `dataset references rewrite`, `--commit` executes the state-aware save-draft
|
|
|
330
332
|
|
|
331
333
|
## Dataset Maintenance
|
|
332
334
|
|
|
333
|
-
`dataset maintenance plan/apply/run-protected/verify` is the row-level cleanup surface for bad imports, the fixed BAFU private alias rewrite, and protected derivative rebuilds. Ordinary planning, apply, and independent verification use the authenticated account and RLS. The protected executor is server-dispatched and additionally enforces the sealed actor, user_id, state_code=0, exact target set, and closure hashes on every write.
|
|
335
|
+
`dataset maintenance plan/apply/freeze-protected/seal-protected-approval/run-protected/verify` is the row-level cleanup surface for bad imports, the fixed BAFU private alias rewrite, and protected derivative rebuilds. Ordinary planning, apply, and independent verification use the authenticated account and RLS. Protected freeze preparation reads the live production owner-draft scope directly with no Dev data replay, while approval sealing is offline. The protected executor is server-dispatched and additionally enforces the sealed actor, user_id, state_code=0, exact target set, and closure hashes on every write.
|
|
334
336
|
|
|
335
337
|
```bash
|
|
336
338
|
tiangong-lca dataset maintenance plan \
|
|
@@ -356,10 +358,33 @@ tiangong-lca dataset maintenance verify \
|
|
|
356
358
|
--timeout-ms 10000 \
|
|
357
359
|
--json
|
|
358
360
|
|
|
361
|
+
tiangong-lca dataset maintenance freeze-protected \
|
|
362
|
+
--plan ./protected-step2/maintenance-plan.json \
|
|
363
|
+
--toolchain-evidence ./protected-step2/toolchain-evidence.json \
|
|
364
|
+
--expected-project-ref <production-project-ref> \
|
|
365
|
+
--confirm <current-account-email> \
|
|
366
|
+
--out-dir ./protected-step2/freeze \
|
|
367
|
+
--page-size 1000 \
|
|
368
|
+
--timeout-ms 10000 \
|
|
369
|
+
--json
|
|
370
|
+
|
|
371
|
+
# After a human returns protected-approval-request.txt byte-for-byte as human-approval.txt:
|
|
372
|
+
tiangong-lca dataset maintenance seal-protected-approval \
|
|
373
|
+
--freeze ./protected-step2/freeze/protected-execution-freeze.json \
|
|
374
|
+
--approval-request ./protected-step2/freeze/protected-approval-request.json \
|
|
375
|
+
--human-approval ./protected-step2/human-approval.txt \
|
|
376
|
+
--approve-freeze-file <freeze-file-sha256> \
|
|
377
|
+
--approve-request <approval-request-sha256> \
|
|
378
|
+
--approve-text <approval-text-sha256> \
|
|
379
|
+
--confirm <current-account-email> \
|
|
380
|
+
--approved-at <approved-at-utc-from-request> \
|
|
381
|
+
--out-dir ./protected-step2/approval \
|
|
382
|
+
--json
|
|
383
|
+
|
|
359
384
|
tiangong-lca dataset maintenance run-protected \
|
|
360
385
|
--plan ./protected-step2/maintenance-plan.json \
|
|
361
|
-
--freeze ./protected-step2/protected-execution-
|
|
362
|
-
--approval ./protected-step2/protected-approval.json \
|
|
386
|
+
--freeze ./protected-step2/freeze/protected-execution-freeze.json \
|
|
387
|
+
--approval ./protected-step2/approval/protected-approval.json \
|
|
363
388
|
--out-dir ./protected-step2/run \
|
|
364
389
|
--commit \
|
|
365
390
|
--approve-execution <approved-execution-sha256> \
|
|
@@ -372,15 +397,19 @@ tiangong-lca dataset maintenance run-protected \
|
|
|
372
397
|
|
|
373
398
|
tiangong-lca dataset maintenance run-protected \
|
|
374
399
|
--plan ./protected-step2/maintenance-plan.json \
|
|
375
|
-
--freeze ./protected-step2/protected-execution-
|
|
376
|
-
--approval ./protected-step2/protected-approval.json \
|
|
400
|
+
--freeze ./protected-step2/freeze/protected-execution-freeze.json \
|
|
401
|
+
--approval ./protected-step2/approval/protected-approval.json \
|
|
377
402
|
--out-dir ./protected-step2/run \
|
|
378
403
|
--status-only \
|
|
379
404
|
--wait-seconds 60 \
|
|
380
405
|
--json
|
|
381
406
|
```
|
|
382
407
|
|
|
383
|
-
`run-protected` is a separate one-shot path for an already reviewed and sealed production execution; it does not replace ordinary planning. Both modes require the exact plan, freeze
|
|
408
|
+
`run-protected` is a separate one-shot path for an already reviewed and sealed production execution; it does not replace ordinary planning. Both modes require the exact plan, freeze artifact, approval artifact, and private output directory. Commit mode additionally requires `--commit`, the exact approved execution identity through `--approve-execution`, and the authenticated account email through `--confirm`. `--status-only` is mutually exclusive with `--commit` and performs no preflight or admission.
|
|
409
|
+
|
|
410
|
+
`freeze-protected` is the only supported generator for this fixed protected profile. Its toolchain evidence must be canonical JSON with schema `dataset-alias-protected-toolchain-evidence.v1`, production project ref, released-and-read-back database commit/evidence, the currently running published CLI version/commit/evidence, and the merged root-workspace integration commit/Issue. The fixed BAFU profile also has a compiled production project allowlist; the CLI rejects a Dev or arbitrary project even if the operator supplies matching flag/evidence values. The command verifies the exact 52 actions, two batches, six support snapshots, projected reference closure, and stable 23-flow + 27-process derivative snapshots; every derivative snapshot must have the same primary-row `modified_at` as the immediately preceding complete account census. It writes the entire private immutable alias-request, full baseline, freeze, unapproved request JSON/TXT, and final report into a sibling staging directory and atomically exposes the new output directory only after every file succeeds; preflight, gate, admission, mutation, and approval-artifact counts are all zero.
|
|
411
|
+
|
|
412
|
+
`seal-protected-approval` receives no environment or HTTP client. The freeze command puts one canonical approval-authority `approved_at_utc` into the request JSON, request hash, and human-visible approval text before review; seal requires `--approved-at` to equal that already approved value. The same text therefore cannot be resealed with another timestamp to mint a second database admission identity. The seal report records its actual generation time separately from this pre-authorized identity timestamp. Both commands hash raw file bytes, reject invalid UTF-8, publish their completed output directories atomically, and reject non-canonical freeze/request files, any changed whitespace or final newline, mismatched explicit hash/account/time bindings, and all three superseded historical Step-2 plan identities. Commit-mode `run-protected` rejects the same historical identities, so an old freeze/approval cannot bypass the fresh preparation chain; status-only remains read-only and available for recovery. Seal writes the canonical approval plus a local report, but does not submit execution. Human approval, sealing, and later execution remain separate events.
|
|
384
413
|
|
|
385
414
|
Before requesting preflight, the command validates the sealed production project, full current-user RLS before-state, support closure, and exact derivative baseline. The server then returns the three expected gate digests and a token valid for at most 180 seconds; the CLI captures and compares the live gate receipts before admission. The server-dispatched write remains fenced to the authenticated actor's exact `user_id`, `state_code=0` rows and sealed plan/closure; independent readback still uses RLS. The CLI writes an immutable local submission marker and sends at most one admission POST. A marker, admission timeout, connection loss, or ambiguous admission response permanently switches that local run to status-only recovery; status-read failures may be polled only within the configured wait window and never cause a second admission or fallback to dev or the legacy whole-plan RPC. The default status polling interval is 10 seconds.
|
|
386
415
|
|
package/dist/src/cli.js
CHANGED
|
@@ -56,7 +56,9 @@ import { runDatasetClassificationApply, runDatasetClassificationAudit, runDatase
|
|
|
56
56
|
import { runDatasetMaintenanceClearAccount, } from './lib/dataset-maintenance-clear-account.js';
|
|
57
57
|
import { runDatasetMaintenancePlan } from './lib/dataset-maintenance-plan.js';
|
|
58
58
|
import { runDatasetMaintenanceApply } from './lib/dataset-maintenance-apply.js';
|
|
59
|
+
import { freezeDatasetMaintenanceProtected } from './lib/dataset-maintenance-protected-freeze.js';
|
|
59
60
|
import { runDatasetMaintenanceProtected } from './lib/dataset-maintenance-protected-run.js';
|
|
61
|
+
import { sealDatasetMaintenanceProtectedApproval } from './lib/dataset-maintenance-protected-seal.js';
|
|
60
62
|
import { runDatasetMaintenanceVerify } from './lib/dataset-maintenance-verify.js';
|
|
61
63
|
import { runDatasetSourceUploadAttachments, } from './lib/dataset-source-upload-attachments.js';
|
|
62
64
|
function renderMainHelp(dotEnvStatus) {
|
|
@@ -132,6 +134,7 @@ Examples:
|
|
|
132
134
|
tiangong-lca dataset references rewrite --input ./rows.jsonl --from flow:<old-id>@<old-version> --to flow:<new-id>@<new-version> --out-dir /abs/path/to/dataset-rewrite
|
|
133
135
|
tiangong-lca dataset maintenance clear-account --out-dir /abs/path/to/account-clear --json
|
|
134
136
|
tiangong-lca dataset maintenance plan --scope ./maintenance-scope.json --operation merge-support-aliases --out-dir /abs/path/to/dataset-maintenance
|
|
137
|
+
tiangong-lca dataset maintenance freeze-protected --plan ./maintenance-plan.json --toolchain-evidence ./toolchain.json --expected-project-ref <production-ref> --confirm bafudata@126.com --out-dir /abs/path/to/protected-freeze
|
|
135
138
|
tiangong-lca dataset maintenance run-protected --plan ./maintenance-plan.json --freeze ./protected-execution-seal.json --approval ./protected-approval.json --out-dir /abs/path/to/protected-run --status-only
|
|
136
139
|
tiangong-lca lifecyclemodel auto-build --input ./lifecyclemodel-auto-build.request.json --out-dir /abs/path/to/lifecyclemodel-run
|
|
137
140
|
tiangong-lca lifecyclemodel validate-build --run-dir /abs/path/to/lifecyclemodel-run
|
|
@@ -285,6 +288,8 @@ Implemented Subcommands:
|
|
|
285
288
|
maintenance clear-account Dry-run or clear current authenticated account-owned dataset rows through RLS
|
|
286
289
|
maintenance plan Build an immutable, RLS-visible row-level maintenance plan
|
|
287
290
|
maintenance apply Execute an explicitly approved maintenance plan through current-user RLS
|
|
291
|
+
maintenance freeze-protected Read and freeze one exact production owner-draft plan without admitting or mutating it
|
|
292
|
+
maintenance seal-protected-approval Record byte-exact human approval entirely offline
|
|
288
293
|
maintenance run-protected Run or inspect one sealed, one-shot production maintenance execution
|
|
289
294
|
maintenance verify Read back affected rows and references against the immutable plan
|
|
290
295
|
|
|
@@ -313,24 +318,30 @@ Examples:
|
|
|
313
318
|
tiangong-lca dataset references refresh-remote --input ./rows.jsonl --out ./rows.refreshed.jsonl --out-dir ./dataset-reference-refresh --help
|
|
314
319
|
tiangong-lca dataset maintenance clear-account --out-dir ./account-clear --json --help
|
|
315
320
|
tiangong-lca dataset maintenance plan --scope ./maintenance-scope.json --operation merge-support-aliases --out-dir ./dataset-maintenance --help
|
|
321
|
+
tiangong-lca dataset maintenance freeze-protected --help
|
|
322
|
+
tiangong-lca dataset maintenance seal-protected-approval --help
|
|
316
323
|
tiangong-lca dataset maintenance run-protected --help
|
|
317
324
|
`.trim();
|
|
318
325
|
}
|
|
319
326
|
function renderDatasetMaintenanceHelp() {
|
|
320
327
|
return `Usage:
|
|
321
|
-
tiangong-lca dataset maintenance <clear-account|plan|apply|run-protected|verify> [options]
|
|
328
|
+
tiangong-lca dataset maintenance <clear-account|plan|apply|freeze-protected|seal-protected-approval|run-protected|verify> [options]
|
|
322
329
|
|
|
323
330
|
Actions:
|
|
324
331
|
clear-account Dry-run or delete current authenticated account-owned lifecyclemodels, processes, flows, sources, and contacts.
|
|
325
332
|
plan Build an immutable maintenance plan from a scope manifest, visible remote snapshot, dependency impact report, and intended operation.
|
|
326
333
|
apply Execute or durably admit an ordinary approved plan through current-user RLS and platform dataset command paths.
|
|
334
|
+
freeze-protected Re-read the exact production owner-draft census/support/50 derivatives and generate an unapproved freeze request.
|
|
335
|
+
seal-protected-approval Record a byte-exact human response into an approval artifact with no authentication or network access.
|
|
327
336
|
run-protected Run or inspect one sealed production execution with one-shot admission and terminal derivative proof.
|
|
328
337
|
verify Re-fetch rows, references, or derivative request state and report passed, pending, or failed independently of apply.
|
|
329
338
|
|
|
330
339
|
Safety:
|
|
331
|
-
plan and
|
|
340
|
+
plan, verify, and freeze-protected are read-only; seal-protected-approval is local-only.
|
|
332
341
|
apply is commit-only and requires --commit, the exact plan SHA-256 via --approve-plan, and the current account email via --confirm.
|
|
333
342
|
A sealed production merge-support-aliases execution must use run-protected; apply is not its fallback.
|
|
343
|
+
freeze-protected is production-only and never calls preflight, gate, admission, execution, or mutation RPCs.
|
|
344
|
+
seal-protected-approval only records the exact human-approved bytes; it never authenticates, connects, or submits execution.
|
|
334
345
|
run-protected is production-only: authenticated owner context plus server-side actor/user_id/state_code=0 and exact-plan closure fences protect writes; RLS remains a defense on public and independent-read surfaces. It never falls back to dev, a legacy alias RPC, or a second admission POST.
|
|
335
346
|
|
|
336
347
|
Required Artifact Contract:
|
|
@@ -349,6 +360,8 @@ Examples:
|
|
|
349
360
|
tiangong-lca dataset maintenance plan --scope ./maintenance-scope.json --operation repair-references --out-dir ./dataset-maintenance
|
|
350
361
|
tiangong-lca dataset maintenance plan --scope ./derivative-rebuild-scope.json --operation rebuild-derivatives --out-dir ./derivative-rebuild
|
|
351
362
|
tiangong-lca dataset maintenance apply --plan ./dataset-maintenance/maintenance-plan.json --commit --approve-plan <sha256> --confirm user@example.com
|
|
363
|
+
tiangong-lca dataset maintenance freeze-protected --plan ./maintenance-plan.json --toolchain-evidence ./toolchain.json --expected-project-ref <production-ref> --confirm bafudata@126.com --out-dir ./protected-freeze
|
|
364
|
+
tiangong-lca dataset maintenance seal-protected-approval --freeze ./protected-freeze/protected-execution-freeze.json --approval-request ./protected-freeze/protected-approval-request.json --human-approval ./human-approval.txt --approve-freeze-file <sha256> --approve-request <sha256> --approve-text <sha256> --confirm bafudata@126.com --approved-at <iso> --out-dir ./protected-approval
|
|
352
365
|
tiangong-lca dataset maintenance run-protected --plan ./maintenance-plan.json --freeze ./protected-execution-seal.json --approval ./protected-approval.json --out-dir ./protected-run --status-only
|
|
353
366
|
tiangong-lca dataset maintenance verify --plan ./dataset-maintenance/maintenance-plan.json --out-dir ./dataset-maintenance/verify
|
|
354
367
|
`.trim();
|
|
@@ -396,6 +409,63 @@ Options:
|
|
|
396
409
|
Outputs include approval-record.json and commit-report.json alongside an append-only action or admission ledger.
|
|
397
410
|
`.trim();
|
|
398
411
|
}
|
|
412
|
+
function renderDatasetMaintenanceFreezeProtectedHelp() {
|
|
413
|
+
return `Usage:
|
|
414
|
+
tiangong-lca dataset maintenance freeze-protected --plan <file> --toolchain-evidence <file> --expected-project-ref <ref> --confirm <email> --out-dir <dir> [options]
|
|
415
|
+
|
|
416
|
+
Behavior:
|
|
417
|
+
Authenticates directly to the explicitly confirmed production project and re-reads the complete
|
|
418
|
+
owner-draft account census, six support snapshots, projected reference closure, and the stable
|
|
419
|
+
23-flow + 27-process derivative snapshot set. It writes a canonical protected freeze and an
|
|
420
|
+
unapproved byte-exact human approval request. It never emits an approval artifact.
|
|
421
|
+
|
|
422
|
+
Required:
|
|
423
|
+
--plan <file> Ready owner-draft merge-support-aliases maintenance plan
|
|
424
|
+
--toolchain-evidence <file> Canonical released DB/CLI/root-integration evidence
|
|
425
|
+
--expected-project-ref <ref> Explicit production Supabase project ref
|
|
426
|
+
--confirm <email> Exact authenticated owner email
|
|
427
|
+
--out-dir <dir> New private immutable artifact directory
|
|
428
|
+
|
|
429
|
+
Options:
|
|
430
|
+
--page-size <n> Complete account scan page size, 1-5000
|
|
431
|
+
--timeout-ms <n> Positive authentication/read timeout in milliseconds
|
|
432
|
+
--json Print compact JSON
|
|
433
|
+
-h, --help
|
|
434
|
+
|
|
435
|
+
Remote safety:
|
|
436
|
+
This command uses only authenticated table reads and cmd_dataset_derivative_rebuild_snapshot.
|
|
437
|
+
Preflight, gate, admission, execution, save-draft, delete, state change, and all mutation calls are zero.
|
|
438
|
+
`.trim();
|
|
439
|
+
}
|
|
440
|
+
function renderDatasetMaintenanceSealProtectedApprovalHelp() {
|
|
441
|
+
return `Usage:
|
|
442
|
+
tiangong-lca dataset maintenance seal-protected-approval --freeze <file> --approval-request <file> --human-approval <file> --approve-freeze-file <sha256> --approve-request <sha256> --approve-text <sha256> --confirm <email> --approved-at <iso> --out-dir <dir> [options]
|
|
443
|
+
|
|
444
|
+
Behavior:
|
|
445
|
+
Records a human-provided approval text only when every UTF-8 byte, freeze-file hash, request hash,
|
|
446
|
+
text hash, account, and canonical timestamp matches the unapproved request. It writes the approval
|
|
447
|
+
artifact needed by a later, separate run-protected command; it does not submit that execution.
|
|
448
|
+
|
|
449
|
+
Required:
|
|
450
|
+
--freeze <file> Canonical protected freeze generated by freeze-protected
|
|
451
|
+
--approval-request <file> Canonical unapproved approval request JSON
|
|
452
|
+
--human-approval <file> Human-returned text, read byte-for-byte without trimming
|
|
453
|
+
--approve-freeze-file <sha256> Explicit SHA-256 of the exact freeze file bytes
|
|
454
|
+
--approve-request <sha256> Explicit request identity SHA-256
|
|
455
|
+
--approve-text <sha256> Explicit byte-exact approval text SHA-256
|
|
456
|
+
--confirm <email> Exact frozen account email
|
|
457
|
+
--approved-at <iso> Exact approval-authority timestamp already embedded in the request
|
|
458
|
+
--out-dir <dir> New private immutable artifact directory
|
|
459
|
+
|
|
460
|
+
Options:
|
|
461
|
+
--json Print compact JSON
|
|
462
|
+
-h, --help
|
|
463
|
+
|
|
464
|
+
Offline safety:
|
|
465
|
+
This command receives no environment or HTTP client and performs zero authentication, network,
|
|
466
|
+
database, preflight, gate, admission, execution, or mutation calls.
|
|
467
|
+
`.trim();
|
|
468
|
+
}
|
|
399
469
|
function renderDatasetMaintenanceRunProtectedHelp() {
|
|
400
470
|
return `Usage:
|
|
401
471
|
tiangong-lca dataset maintenance run-protected --plan <file> --freeze <file> --approval <file> --out-dir <dir> --commit --approve-execution <sha256> --confirm <email> [options]
|
|
@@ -3188,6 +3258,86 @@ function parseDatasetMaintenanceApplyFlags(args) {
|
|
|
3188
3258
|
dryRun: Boolean(values['dry-run']),
|
|
3189
3259
|
};
|
|
3190
3260
|
}
|
|
3261
|
+
function parseDatasetMaintenanceFreezeProtectedFlags(args) {
|
|
3262
|
+
let values;
|
|
3263
|
+
try {
|
|
3264
|
+
({ values } = parseArgs({
|
|
3265
|
+
args,
|
|
3266
|
+
allowPositionals: false,
|
|
3267
|
+
strict: true,
|
|
3268
|
+
options: {
|
|
3269
|
+
help: { type: 'boolean', short: 'h' },
|
|
3270
|
+
json: { type: 'boolean' },
|
|
3271
|
+
plan: { type: 'string' },
|
|
3272
|
+
'toolchain-evidence': { type: 'string' },
|
|
3273
|
+
'out-dir': { type: 'string' },
|
|
3274
|
+
'expected-project-ref': { type: 'string' },
|
|
3275
|
+
confirm: { type: 'string' },
|
|
3276
|
+
'page-size': { type: 'string' },
|
|
3277
|
+
'timeout-ms': { type: 'string' },
|
|
3278
|
+
},
|
|
3279
|
+
}));
|
|
3280
|
+
}
|
|
3281
|
+
catch (error) {
|
|
3282
|
+
throw new CliError(String(error), {
|
|
3283
|
+
code: 'INVALID_ARGS',
|
|
3284
|
+
exitCode: 2,
|
|
3285
|
+
});
|
|
3286
|
+
}
|
|
3287
|
+
return {
|
|
3288
|
+
help: Boolean(values.help),
|
|
3289
|
+
json: Boolean(values.json),
|
|
3290
|
+
planPath: typeof values.plan === 'string' ? values.plan : '',
|
|
3291
|
+
toolchainEvidencePath: typeof values['toolchain-evidence'] === 'string' ? values['toolchain-evidence'] : '',
|
|
3292
|
+
outDir: typeof values['out-dir'] === 'string' ? values['out-dir'] : '',
|
|
3293
|
+
expectedProjectRef: typeof values['expected-project-ref'] === 'string' ? values['expected-project-ref'] : '',
|
|
3294
|
+
confirm: typeof values.confirm === 'string' ? values.confirm : '',
|
|
3295
|
+
pageSize: parseDatasetMaintenancePositiveInteger(values['page-size'], '--page-size'),
|
|
3296
|
+
timeoutMs: parseDatasetMaintenancePositiveInteger(values['timeout-ms'], '--timeout-ms'),
|
|
3297
|
+
};
|
|
3298
|
+
}
|
|
3299
|
+
function parseDatasetMaintenanceSealProtectedApprovalFlags(args) {
|
|
3300
|
+
let values;
|
|
3301
|
+
try {
|
|
3302
|
+
({ values } = parseArgs({
|
|
3303
|
+
args,
|
|
3304
|
+
allowPositionals: false,
|
|
3305
|
+
strict: true,
|
|
3306
|
+
options: {
|
|
3307
|
+
help: { type: 'boolean', short: 'h' },
|
|
3308
|
+
json: { type: 'boolean' },
|
|
3309
|
+
freeze: { type: 'string' },
|
|
3310
|
+
'approval-request': { type: 'string' },
|
|
3311
|
+
'human-approval': { type: 'string' },
|
|
3312
|
+
'out-dir': { type: 'string' },
|
|
3313
|
+
'approve-freeze-file': { type: 'string' },
|
|
3314
|
+
'approve-request': { type: 'string' },
|
|
3315
|
+
'approve-text': { type: 'string' },
|
|
3316
|
+
confirm: { type: 'string' },
|
|
3317
|
+
'approved-at': { type: 'string' },
|
|
3318
|
+
},
|
|
3319
|
+
}));
|
|
3320
|
+
}
|
|
3321
|
+
catch (error) {
|
|
3322
|
+
throw new CliError(String(error), {
|
|
3323
|
+
code: 'INVALID_ARGS',
|
|
3324
|
+
exitCode: 2,
|
|
3325
|
+
});
|
|
3326
|
+
}
|
|
3327
|
+
return {
|
|
3328
|
+
help: Boolean(values.help),
|
|
3329
|
+
json: Boolean(values.json),
|
|
3330
|
+
freezePath: typeof values.freeze === 'string' ? values.freeze : '',
|
|
3331
|
+
approvalRequestPath: typeof values['approval-request'] === 'string' ? values['approval-request'] : '',
|
|
3332
|
+
humanApprovalPath: typeof values['human-approval'] === 'string' ? values['human-approval'] : '',
|
|
3333
|
+
outDir: typeof values['out-dir'] === 'string' ? values['out-dir'] : '',
|
|
3334
|
+
approveFreezeFile: typeof values['approve-freeze-file'] === 'string' ? values['approve-freeze-file'] : '',
|
|
3335
|
+
approveRequest: typeof values['approve-request'] === 'string' ? values['approve-request'] : '',
|
|
3336
|
+
approveText: typeof values['approve-text'] === 'string' ? values['approve-text'] : '',
|
|
3337
|
+
confirm: typeof values.confirm === 'string' ? values.confirm : '',
|
|
3338
|
+
approvedAtUtc: typeof values['approved-at'] === 'string' ? values['approved-at'] : '',
|
|
3339
|
+
};
|
|
3340
|
+
}
|
|
3191
3341
|
function parseDatasetMaintenanceProtectedFlags(args) {
|
|
3192
3342
|
let values;
|
|
3193
3343
|
try {
|
|
@@ -5015,7 +5165,9 @@ export async function executeCli(argv, deps) {
|
|
|
5015
5165
|
const datasetMaintenanceClearAccountImpl = deps.runDatasetMaintenanceClearAccountImpl ?? runDatasetMaintenanceClearAccount;
|
|
5016
5166
|
const datasetMaintenancePlanImpl = deps.runDatasetMaintenancePlanImpl ?? runDatasetMaintenancePlan;
|
|
5017
5167
|
const datasetMaintenanceApplyImpl = deps.runDatasetMaintenanceApplyImpl ?? runDatasetMaintenanceApply;
|
|
5168
|
+
const datasetMaintenanceProtectedFreezeImpl = deps.freezeDatasetMaintenanceProtectedImpl ?? freezeDatasetMaintenanceProtected;
|
|
5018
5169
|
const datasetMaintenanceProtectedImpl = deps.runDatasetMaintenanceProtectedImpl ?? runDatasetMaintenanceProtected;
|
|
5170
|
+
const datasetMaintenanceProtectedApprovalSealImpl = deps.sealDatasetMaintenanceProtectedApprovalImpl ?? sealDatasetMaintenanceProtectedApproval;
|
|
5019
5171
|
const datasetMaintenanceVerifyImpl = deps.runDatasetMaintenanceVerifyImpl ?? runDatasetMaintenanceVerify;
|
|
5020
5172
|
const datasetSourceUploadAttachmentsImpl = deps.runDatasetSourceUploadAttachmentsImpl ?? runDatasetSourceUploadAttachments;
|
|
5021
5173
|
if (flags.version) {
|
|
@@ -5728,6 +5880,143 @@ export async function executeCli(argv, deps) {
|
|
|
5728
5880
|
stderr: '',
|
|
5729
5881
|
};
|
|
5730
5882
|
}
|
|
5883
|
+
if (action === 'freeze-protected') {
|
|
5884
|
+
const datasetFlags = parseDatasetMaintenanceFreezeProtectedFlags(commandArgs.slice(1));
|
|
5885
|
+
if (datasetFlags.help) {
|
|
5886
|
+
return {
|
|
5887
|
+
exitCode: 0,
|
|
5888
|
+
stdout: `${renderDatasetMaintenanceFreezeProtectedHelp()}\n`,
|
|
5889
|
+
stderr: '',
|
|
5890
|
+
};
|
|
5891
|
+
}
|
|
5892
|
+
if (!datasetFlags.planPath) {
|
|
5893
|
+
throw new CliError('dataset maintenance freeze-protected requires --plan.', {
|
|
5894
|
+
code: 'DATASET_MAINTENANCE_PROTECTED_PLAN_REQUIRED',
|
|
5895
|
+
exitCode: 2,
|
|
5896
|
+
});
|
|
5897
|
+
}
|
|
5898
|
+
if (!datasetFlags.toolchainEvidencePath) {
|
|
5899
|
+
throw new CliError('dataset maintenance freeze-protected requires --toolchain-evidence.', {
|
|
5900
|
+
code: 'DATASET_MAINTENANCE_PROTECTED_TOOLCHAIN_REQUIRED',
|
|
5901
|
+
exitCode: 2,
|
|
5902
|
+
});
|
|
5903
|
+
}
|
|
5904
|
+
if (!datasetFlags.expectedProjectRef) {
|
|
5905
|
+
throw new CliError('dataset maintenance freeze-protected requires --expected-project-ref.', {
|
|
5906
|
+
code: 'DATASET_MAINTENANCE_PROTECTED_PROJECT_REF_REQUIRED',
|
|
5907
|
+
exitCode: 2,
|
|
5908
|
+
});
|
|
5909
|
+
}
|
|
5910
|
+
if (!datasetFlags.confirm) {
|
|
5911
|
+
throw new CliError('dataset maintenance freeze-protected requires --confirm.', {
|
|
5912
|
+
code: 'DATASET_MAINTENANCE_PROTECTED_CONFIRM_REQUIRED',
|
|
5913
|
+
exitCode: 2,
|
|
5914
|
+
});
|
|
5915
|
+
}
|
|
5916
|
+
if (!datasetFlags.outDir) {
|
|
5917
|
+
throw new CliError('dataset maintenance freeze-protected requires --out-dir.', {
|
|
5918
|
+
code: 'DATASET_MAINTENANCE_PROTECTED_OUT_DIR_REQUIRED',
|
|
5919
|
+
exitCode: 2,
|
|
5920
|
+
});
|
|
5921
|
+
}
|
|
5922
|
+
const report = await datasetMaintenanceProtectedFreezeImpl({
|
|
5923
|
+
planPath: datasetFlags.planPath,
|
|
5924
|
+
toolchainEvidencePath: datasetFlags.toolchainEvidencePath,
|
|
5925
|
+
outDir: datasetFlags.outDir,
|
|
5926
|
+
expectedProjectRef: datasetFlags.expectedProjectRef,
|
|
5927
|
+
confirm: datasetFlags.confirm,
|
|
5928
|
+
cliVersion: loadCliPackageVersion(import.meta.url),
|
|
5929
|
+
pageSize: datasetFlags.pageSize,
|
|
5930
|
+
timeoutMs: datasetFlags.timeoutMs,
|
|
5931
|
+
env: deps.env,
|
|
5932
|
+
fetchImpl: deps.fetchImpl,
|
|
5933
|
+
});
|
|
5934
|
+
return {
|
|
5935
|
+
exitCode: 0,
|
|
5936
|
+
stdout: stringifyJson(report, datasetFlags.json),
|
|
5937
|
+
stderr: '',
|
|
5938
|
+
};
|
|
5939
|
+
}
|
|
5940
|
+
if (action === 'seal-protected-approval') {
|
|
5941
|
+
const datasetFlags = parseDatasetMaintenanceSealProtectedApprovalFlags(commandArgs.slice(1));
|
|
5942
|
+
if (datasetFlags.help) {
|
|
5943
|
+
return {
|
|
5944
|
+
exitCode: 0,
|
|
5945
|
+
stdout: `${renderDatasetMaintenanceSealProtectedApprovalHelp()}\n`,
|
|
5946
|
+
stderr: '',
|
|
5947
|
+
};
|
|
5948
|
+
}
|
|
5949
|
+
if (!datasetFlags.freezePath) {
|
|
5950
|
+
throw new CliError('dataset maintenance seal-protected-approval requires --freeze.', {
|
|
5951
|
+
code: 'DATASET_MAINTENANCE_PROTECTED_FREEZE_REQUIRED',
|
|
5952
|
+
exitCode: 2,
|
|
5953
|
+
});
|
|
5954
|
+
}
|
|
5955
|
+
if (!datasetFlags.approvalRequestPath) {
|
|
5956
|
+
throw new CliError('dataset maintenance seal-protected-approval requires --approval-request.', {
|
|
5957
|
+
code: 'DATASET_MAINTENANCE_PROTECTED_APPROVAL_REQUEST_REQUIRED',
|
|
5958
|
+
exitCode: 2,
|
|
5959
|
+
});
|
|
5960
|
+
}
|
|
5961
|
+
if (!datasetFlags.humanApprovalPath) {
|
|
5962
|
+
throw new CliError('dataset maintenance seal-protected-approval requires --human-approval.', {
|
|
5963
|
+
code: 'DATASET_MAINTENANCE_PROTECTED_HUMAN_APPROVAL_REQUIRED',
|
|
5964
|
+
exitCode: 2,
|
|
5965
|
+
});
|
|
5966
|
+
}
|
|
5967
|
+
if (!datasetFlags.approveFreezeFile) {
|
|
5968
|
+
throw new CliError('dataset maintenance seal-protected-approval requires --approve-freeze-file.', {
|
|
5969
|
+
code: 'DATASET_MAINTENANCE_PROTECTED_FREEZE_CONFIRMATION_REQUIRED',
|
|
5970
|
+
exitCode: 2,
|
|
5971
|
+
});
|
|
5972
|
+
}
|
|
5973
|
+
if (!datasetFlags.approveRequest) {
|
|
5974
|
+
throw new CliError('dataset maintenance seal-protected-approval requires --approve-request.', {
|
|
5975
|
+
code: 'DATASET_MAINTENANCE_PROTECTED_REQUEST_CONFIRMATION_REQUIRED',
|
|
5976
|
+
exitCode: 2,
|
|
5977
|
+
});
|
|
5978
|
+
}
|
|
5979
|
+
if (!datasetFlags.approveText) {
|
|
5980
|
+
throw new CliError('dataset maintenance seal-protected-approval requires --approve-text.', {
|
|
5981
|
+
code: 'DATASET_MAINTENANCE_PROTECTED_TEXT_CONFIRMATION_REQUIRED',
|
|
5982
|
+
exitCode: 2,
|
|
5983
|
+
});
|
|
5984
|
+
}
|
|
5985
|
+
if (!datasetFlags.confirm) {
|
|
5986
|
+
throw new CliError('dataset maintenance seal-protected-approval requires --confirm.', {
|
|
5987
|
+
code: 'DATASET_MAINTENANCE_PROTECTED_CONFIRM_REQUIRED',
|
|
5988
|
+
exitCode: 2,
|
|
5989
|
+
});
|
|
5990
|
+
}
|
|
5991
|
+
if (!datasetFlags.approvedAtUtc) {
|
|
5992
|
+
throw new CliError('dataset maintenance seal-protected-approval requires --approved-at.', {
|
|
5993
|
+
code: 'DATASET_MAINTENANCE_PROTECTED_APPROVED_AT_REQUIRED',
|
|
5994
|
+
exitCode: 2,
|
|
5995
|
+
});
|
|
5996
|
+
}
|
|
5997
|
+
if (!datasetFlags.outDir) {
|
|
5998
|
+
throw new CliError('dataset maintenance seal-protected-approval requires --out-dir.', {
|
|
5999
|
+
code: 'DATASET_MAINTENANCE_PROTECTED_OUT_DIR_REQUIRED',
|
|
6000
|
+
exitCode: 2,
|
|
6001
|
+
});
|
|
6002
|
+
}
|
|
6003
|
+
const report = await datasetMaintenanceProtectedApprovalSealImpl({
|
|
6004
|
+
freezePath: datasetFlags.freezePath,
|
|
6005
|
+
approvalRequestPath: datasetFlags.approvalRequestPath,
|
|
6006
|
+
humanApprovalPath: datasetFlags.humanApprovalPath,
|
|
6007
|
+
outDir: datasetFlags.outDir,
|
|
6008
|
+
approveFreezeFile: datasetFlags.approveFreezeFile,
|
|
6009
|
+
approveRequest: datasetFlags.approveRequest,
|
|
6010
|
+
approveText: datasetFlags.approveText,
|
|
6011
|
+
confirm: datasetFlags.confirm,
|
|
6012
|
+
approvedAtUtc: datasetFlags.approvedAtUtc,
|
|
6013
|
+
});
|
|
6014
|
+
return {
|
|
6015
|
+
exitCode: 0,
|
|
6016
|
+
stdout: stringifyJson(report, datasetFlags.json),
|
|
6017
|
+
stderr: '',
|
|
6018
|
+
};
|
|
6019
|
+
}
|
|
5731
6020
|
if (action === 'run-protected') {
|
|
5732
6021
|
const datasetFlags = parseDatasetMaintenanceProtectedFlags(commandArgs.slice(1));
|
|
5733
6022
|
if (datasetFlags.help) {
|
|
@@ -5836,7 +6125,7 @@ export async function executeCli(argv, deps) {
|
|
|
5836
6125
|
stderr: '',
|
|
5837
6126
|
};
|
|
5838
6127
|
}
|
|
5839
|
-
throw new CliError("dataset maintenance action must be 'clear-account', 'plan', 'apply', 'run-protected', or 'verify'.", {
|
|
6128
|
+
throw new CliError("dataset maintenance action must be 'clear-account', 'plan', 'apply', 'freeze-protected', 'seal-protected-approval', 'run-protected', or 'verify'.", {
|
|
5840
6129
|
code: 'DATASET_MAINTENANCE_ACTION_INVALID',
|
|
5841
6130
|
exitCode: 2,
|
|
5842
6131
|
});
|