@tiangong-lca/cli 0.0.31 → 0.0.33

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 CHANGED
@@ -43,6 +43,10 @@ Review note, 2026-07-17: `dataset maintenance flow-identity capture|plan|freeze|
43
43
 
44
44
  Review note, 2026-07-23: `dataset save-draft --execution-contract` adds an opt-in crash-safe ordered owner-draft batch. The contract binds the authenticated project/owner, state 0, exact input order and payloads, before hashes, expected insert/update operations, and dependencies. A stable per-owner/project `action_id@desired_sha256` ledger prevents replay even if the contract or output directory is copied; ambiguous attempts are recovered only by exact owner/state/payload readback. The ordinary save-draft mode is unchanged.
45
45
 
46
+ Review note, 2026-07-24: CLI 0.0.32 adds bounded execution-contract concurrency without changing the sealed payload or replay model. `--max-parallel 1..8` keeps the complete dependency prefix serial and exact-read-back, then overlaps only the unique-target suffix. The current owner token is renewed and revalidated before each DML dispatch so long batches do not turn token expiry into an avoidable UNKNOWN.
47
+
48
+ Review note, 2026-07-24: CLI 0.0.33 adds an explicit `dataset maintenance apply --max-parallel 1..8` profile for large owner-draft flow convergence. It accepts only unique flow delete-only plans with zero frozen and fresh visible-process inbound references, persists `PREPARED` and `DISPATCHED` before each protected RPC, requires exact absent readback for `COMMITTED`, never automatically replays success or UNKNOWN, and continues independent rows.
49
+
46
50
  ## Run
47
51
 
48
52
  One-off published run:
@@ -365,13 +369,14 @@ tiangong-lca dataset classification apply --type location --input ./rows/process
365
369
  tiangong-lca dataset curation-queue build --processes ./rows/processes.jsonl --flows ./rows/flows.jsonl --support ./rows/sources.jsonl --out-dir /abs/path/to/curation-queue --json
366
370
  tiangong-lca dataset curation-queue next --queue-dir /abs/path/to/curation-queue --type support --json
367
371
  tiangong-lca dataset curation-queue verify --queue-dir /abs/path/to/curation-queue --type process --json
368
- tiangong-lca dataset save-draft --input ./rows.jsonl --type auto --execution-contract ./execution-contract.json --out-dir /abs/path/to/dataset-save-draft --commit --json
372
+ tiangong-lca dataset save-draft --input ./rows.jsonl --type auto --execution-contract ./execution-contract.json --max-parallel 8 --out-dir /abs/path/to/dataset-save-draft --commit --json
369
373
  tiangong-lca dataset evidence-search plan --query "中国2026年电力结构数据" --out-dir /abs/path/to/evidence-search --json
370
374
  tiangong-lca dataset evidence-search run --input ./evidence-search.request.json --results ./search-results.json --out-dir /abs/path/to/evidence-search --json
371
375
  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 --json
372
376
  tiangong-lca dataset maintenance plan --scope ./maintenance-scope.json --operation redo-import --out-dir /abs/path/to/dataset-maintenance --page-size 1000 --timeout-ms 10000 --json
373
377
  tiangong-lca dataset maintenance plan --scope ./derivative-rebuild-scope.json --operation rebuild-derivatives --out-dir /abs/path/to/derivative-rebuild --json
374
378
  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
379
+ tiangong-lca dataset maintenance apply --plan /abs/path/to/flow-delete-maintenance/maintenance-plan.json --commit --approve-plan <sha256> --confirm <current-account-email> --max-parallel 8 --timeout-ms 10000 --json
375
380
  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
376
381
  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
377
382
  tiangong-lca lifecyclemodel auto-build --input ./examples/lifecyclemodel-auto-build.request.json --out-dir /abs/path/to/lifecyclemodel-run --json
@@ -400,7 +405,9 @@ For `process build-plan` and `flow build-plan`, canonical payloads embedded in t
400
405
 
401
406
  For `process save-draft`, canonical process payloads are validated locally with `ProcessSchema` before any `--commit` write. Schema-invalid rows remain in `outputs/save-draft-rpc/failures.jsonl` instead of being persisted. Batch import callers should pass `--target-user-id`; the CLI then verifies the current auth session and any visible draft owner before writing, while downstream readback verification still proves the final owner and payload.
402
407
 
403
- For `dataset save-draft --execution-contract`, the JSON contract uses schema `dataset-save-draft-execution-contract.v1` and supplies `execution_id`, `project_ref`, an exact owner (`user_id`, lowercase `email`, `state_code: 0`), and ordered actions. Each action binds `action_id`, `desired_sha256`, `expected_operation` (`insert` or `save_draft`), table/id/version, `before_sha256`, and earlier `dependency_action_ids`. Contract mode requires `--commit`; account-local Unit Group or Flow Property support rows additionally require `--allow-account-local-support`. Attempts and outcomes are stored under the platform user-state directory (`$XDG_STATE_HOME/tiangong-lca-cli` when configured), not beside the contract or report. Any prior terminal or unresolved attempt is read back or retained without re-dispatch; exit status is nonzero unless every action has exact terminal success.
408
+ For `dataset save-draft --execution-contract`, the JSON contract uses schema `dataset-save-draft-execution-contract.v1` and supplies `execution_id`, `project_ref`, an exact owner (`user_id`, lowercase `email`, `state_code: 0`), and ordered actions. Each action binds `action_id`, `desired_sha256`, `expected_operation` (`insert` or `save_draft`), table/id/version, `before_sha256`, and earlier `dependency_action_ids`. Contract mode requires `--commit`; account-local Unit Group or Flow Property support rows additionally require `--allow-account-local-support`. `--max-parallel` defaults to 1 and is capped at 8. When it is greater than 1, every action through the highest referenced dependency remains serial; only the later table/id/version-unique suffix may overlap. The exact owner token is renewed and checked before each DML dispatch. Attempts and outcomes are stored under the platform user-state directory (`$XDG_STATE_HOME/tiangong-lca-cli` when configured), not beside the contract or report. Any prior terminal or unresolved attempt is read back or retained without re-dispatch; exit status is nonzero unless every action has exact terminal success.
409
+
410
+ For `dataset maintenance apply`, explicitly passing `--max-parallel 1..8` opts into the destructive flow-convergence profile. It accepts only a non-empty, unique-target, flow delete-only plan whose current and projected reference impacts are both zero. Before dispatch it also completes a fresh SELECT-only scan of every process visible to the owner session and rejects any inbound edge. Each action writes append-only `PREPARED` and `DISPATCHED` evidence before its protected owner-session RPC, then records `COMMITTED` only after exact absent readback. An ambiguous action is read back, marked `UNKNOWN`, and never replayed automatically; independent actions continue. Omit the flag to retain ordinary maintenance apply behavior.
404
411
 
405
412
  For `flow publish-version`, canonical flow payloads are validated locally with `FlowSchema` before remote visibility planning or writes. The command always writes `flow-publish-version-gate-report.json`; blocked rows are written to the remote-failure JSONL without calling the remote service.
406
413
 
package/dist/src/cli.js CHANGED
@@ -536,6 +536,7 @@ Options:
536
536
  --approve-plan <sha256> Exact SHA-256 recorded for the plan
537
537
  --confirm <email> Current authenticated account email
538
538
  --timeout-ms <n> Request timeout in milliseconds
539
+ --max-parallel <1-8> Opt into bounded flow delete-only execution with durable dispatch ledger
539
540
  --json Print compact JSON
540
541
  -h, --help
541
542
 
@@ -947,6 +948,8 @@ Options:
947
948
  --dry-run Validate and plan without remote writes (default)
948
949
  --execution-contract <file>
949
950
  Execute a content-bound ordered owner-draft batch with append-only attempt/readback evidence (requires --commit)
951
+ --max-parallel <1-8>
952
+ Keep the dependency prefix serial, then run only the target-unique suffix with this concurrency (default: 1)
950
953
  --allow-account-local-support
951
954
  Explicitly permit account-local Unit Group / Flow Property rows in the execution contract
952
955
  --json Print compact JSON
@@ -2484,6 +2487,7 @@ function parseDatasetSaveDraftFlags(args) {
2484
2487
  'dry-run': { type: 'boolean' },
2485
2488
  'allow-account-local-support': { type: 'boolean' },
2486
2489
  'execution-contract': { type: 'string' },
2490
+ 'max-parallel': { type: 'string' },
2487
2491
  },
2488
2492
  }));
2489
2493
  }
@@ -2499,6 +2503,18 @@ function parseDatasetSaveDraftFlags(args) {
2499
2503
  exitCode: 2,
2500
2504
  });
2501
2505
  }
2506
+ const maxParallelValue = values['max-parallel'];
2507
+ const maxParallel = typeof maxParallelValue === 'string' && /^\d+$/u.test(maxParallelValue)
2508
+ ? Number.parseInt(maxParallelValue, 10)
2509
+ : maxParallelValue === undefined
2510
+ ? 1
2511
+ : Number.NaN;
2512
+ if (!Number.isInteger(maxParallel) || maxParallel < 1 || maxParallel > 8) {
2513
+ throw new CliError('--max-parallel must be an integer from 1 to 8.', {
2514
+ code: 'INVALID_ARGS',
2515
+ exitCode: 2,
2516
+ });
2517
+ }
2502
2518
  return {
2503
2519
  help: Boolean(values.help),
2504
2520
  json: Boolean(values.json),
@@ -2508,6 +2524,7 @@ function parseDatasetSaveDraftFlags(args) {
2508
2524
  commit: Boolean(values.commit),
2509
2525
  allowReferenceOnlySupport: Boolean(values['allow-account-local-support']),
2510
2526
  executionContractPath: typeof values['execution-contract'] === 'string' ? values['execution-contract'] : null,
2527
+ maxParallel,
2511
2528
  };
2512
2529
  }
2513
2530
  function parseDatasetSourceUploadAttachmentsFlags(args) {
@@ -3443,6 +3460,7 @@ function parseDatasetMaintenanceApplyFlags(args) {
3443
3460
  confirm: { type: 'string' },
3444
3461
  'timeout-ms': { type: 'string' },
3445
3462
  'dry-run': { type: 'boolean' },
3463
+ 'max-parallel': { type: 'string' },
3446
3464
  },
3447
3465
  }));
3448
3466
  }
@@ -3452,6 +3470,19 @@ function parseDatasetMaintenanceApplyFlags(args) {
3452
3470
  exitCode: 2,
3453
3471
  });
3454
3472
  }
3473
+ const maxParallelValue = values['max-parallel'];
3474
+ const maxParallel = typeof maxParallelValue === 'string' && /^\d+$/u.test(maxParallelValue)
3475
+ ? Number.parseInt(maxParallelValue, 10)
3476
+ : maxParallelValue === undefined
3477
+ ? undefined
3478
+ : Number.NaN;
3479
+ if (maxParallel !== undefined &&
3480
+ (!Number.isInteger(maxParallel) || maxParallel < 1 || maxParallel > 8)) {
3481
+ throw new CliError('--max-parallel must be an integer from 1 to 8.', {
3482
+ code: 'INVALID_ARGS',
3483
+ exitCode: 2,
3484
+ });
3485
+ }
3455
3486
  return {
3456
3487
  help: Boolean(values.help),
3457
3488
  json: Boolean(values.json),
@@ -3461,6 +3492,7 @@ function parseDatasetMaintenanceApplyFlags(args) {
3461
3492
  confirm: typeof values.confirm === 'string' ? values.confirm : '',
3462
3493
  timeoutMs: parseDatasetMaintenancePositiveInteger(values['timeout-ms'], '--timeout-ms'),
3463
3494
  dryRun: Boolean(values['dry-run']),
3495
+ maxParallel,
3464
3496
  };
3465
3497
  }
3466
3498
  function parseDatasetMaintenanceFreezeProtectedFlags(args) {
@@ -5858,6 +5890,7 @@ export async function executeCli(argv, deps) {
5858
5890
  commit: datasetFlags.commit,
5859
5891
  allowReferenceOnlySupport: datasetFlags.allowReferenceOnlySupport,
5860
5892
  executionContractPath: datasetFlags.executionContractPath,
5893
+ maxParallel: datasetFlags.maxParallel,
5861
5894
  env: deps.env,
5862
5895
  fetchImpl: deps.fetchImpl,
5863
5896
  });
@@ -6384,11 +6417,14 @@ export async function executeCli(argv, deps) {
6384
6417
  approvePlan: datasetFlags.approvePlan,
6385
6418
  confirm: datasetFlags.confirm,
6386
6419
  timeoutMs: datasetFlags.timeoutMs,
6420
+ maxParallel: datasetFlags.maxParallel,
6387
6421
  env: deps.env,
6388
6422
  fetchImpl: deps.fetchImpl,
6389
6423
  });
6390
6424
  return {
6391
- exitCode: report.status === 'completed_with_failures' ? 1 : 0,
6425
+ exitCode: ['completed_with_failures', 'completed_with_unknowns'].includes(report.status)
6426
+ ? 1
6427
+ : 0,
6392
6428
  stdout: stringifyJson(report, datasetFlags.json),
6393
6429
  stderr: '',
6394
6430
  };