@tiangong-lca/cli 0.0.24 → 0.0.26

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 (28) hide show
  1. package/README.md +66 -5
  2. package/dist/src/cli.js +484 -5
  3. package/dist/src/cli.js.map +1 -1
  4. package/dist/src/lib/dataset-maintenance-alias-request.js +99 -0
  5. package/dist/src/lib/dataset-maintenance-alias-request.js.map +1 -0
  6. package/dist/src/lib/dataset-maintenance-apply.js +12 -367
  7. package/dist/src/lib/dataset-maintenance-apply.js.map +1 -1
  8. package/dist/src/lib/dataset-maintenance-protected-artifacts.js +100 -0
  9. package/dist/src/lib/dataset-maintenance-protected-artifacts.js.map +1 -0
  10. package/dist/src/lib/dataset-maintenance-protected-before.js +284 -0
  11. package/dist/src/lib/dataset-maintenance-protected-before.js.map +1 -0
  12. package/dist/src/lib/dataset-maintenance-protected-contract.js +918 -0
  13. package/dist/src/lib/dataset-maintenance-protected-contract.js.map +1 -0
  14. package/dist/src/lib/dataset-maintenance-protected-freeze.js +230 -0
  15. package/dist/src/lib/dataset-maintenance-protected-freeze.js.map +1 -0
  16. package/dist/src/lib/dataset-maintenance-protected-preparation.js +524 -0
  17. package/dist/src/lib/dataset-maintenance-protected-preparation.js.map +1 -0
  18. package/dist/src/lib/dataset-maintenance-protected-run.js +667 -0
  19. package/dist/src/lib/dataset-maintenance-protected-run.js.map +1 -0
  20. package/dist/src/lib/dataset-maintenance-protected-seal.js +160 -0
  21. package/dist/src/lib/dataset-maintenance-protected-seal.js.map +1 -0
  22. package/dist/src/lib/dataset-maintenance-protected-toolchain.js +86 -0
  23. package/dist/src/lib/dataset-maintenance-protected-toolchain.js.map +1 -0
  24. package/dist/src/lib/dataset-maintenance-protected-verify.js +435 -0
  25. package/dist/src/lib/dataset-maintenance-protected-verify.js.map +1 -0
  26. package/dist/src/lib/dataset-maintenance-remote.js +116 -2
  27. package/dist/src/lib/dataset-maintenance-remote.js.map +1 -1
  28. package/package.json +1 -1
package/README.md CHANGED
@@ -17,8 +17,8 @@ checkPaths:
17
17
  - bin/**
18
18
  - src/cli.ts
19
19
  - src/main.ts
20
- lastReviewedAt: 2026-07-14
21
- lastReviewedCommit: ce8c18f270725adad789ada8f4582ca0e97e4117
20
+ lastReviewedAt: 2026-07-15
21
+ lastReviewedCommit: bd145f692b3fd11e398302dd6a1d2831e058883a
22
22
  ---
23
23
 
24
24
  # TianGong LCA CLI
@@ -31,6 +31,10 @@ Review note, 2026-07-13: maintenance scans now prove exact-count pagination even
31
31
 
32
32
  Review note, 2026-07-14: maintenance now includes the protected derivative-only `rebuild-derivatives` operation. V1 plans exactly one current-owner state-0 process with `action=rebuild_derivatives`, `target_mode=owner_draft`, and components `extracted_md` plus `embedding_ft`. Apply only proves guarded-RPC admission (`accepted`/`queued`); independent verify reports `pending`, `passed`, or `failed`.
33
33
 
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
+
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
+
34
38
  ## Run
35
39
 
36
40
  One-off published run:
@@ -283,6 +287,7 @@ tiangong-lca dataset maintenance plan --scope ./maintenance-scope.json --operati
283
287
  tiangong-lca dataset maintenance plan --scope ./derivative-rebuild-scope.json --operation rebuild-derivatives --out-dir /abs/path/to/derivative-rebuild --json
284
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
285
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
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
286
291
  tiangong-lca lifecyclemodel auto-build --input ./examples/lifecyclemodel-auto-build.request.json --out-dir /abs/path/to/lifecyclemodel-run --json
287
292
  tiangong-lca lifecyclemodel validate-build --run-dir /abs/path/to/lifecyclemodel-run --json
288
293
  tiangong-lca lifecyclemodel publish-build --run-dir /abs/path/to/lifecyclemodel-run --json
@@ -327,12 +332,12 @@ For `dataset references rewrite`, `--commit` executes the state-aware save-draft
327
332
 
328
333
  ## Dataset Maintenance
329
334
 
330
- `dataset maintenance plan/apply/verify` is the row-level cleanup surface for bad imports, the fixed BAFU private alias rewrite, and one protected derivative-only process rebuild. It runs as the currently authenticated user and relies on RLS for visibility and ownership enforcement.
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.
331
336
 
332
337
  ```bash
333
338
  tiangong-lca dataset maintenance plan \
334
339
  --scope ./maintenance-scope.json \
335
- --operation merge-support-aliases \
340
+ --operation repair-references \
336
341
  --out-dir ./dataset-maintenance \
337
342
  --page-size 1000 \
338
343
  --timeout-ms 10000 \
@@ -352,8 +357,64 @@ tiangong-lca dataset maintenance verify \
352
357
  --page-size 1000 \
353
358
  --timeout-ms 10000 \
354
359
  --json
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
+
384
+ tiangong-lca dataset maintenance run-protected \
385
+ --plan ./protected-step2/maintenance-plan.json \
386
+ --freeze ./protected-step2/freeze/protected-execution-freeze.json \
387
+ --approval ./protected-step2/approval/protected-approval.json \
388
+ --out-dir ./protected-step2/run \
389
+ --commit \
390
+ --approve-execution <approved-execution-sha256> \
391
+ --confirm <current-account-email> \
392
+ --wait-seconds 60 \
393
+ --poll-ms 10000 \
394
+ --page-size 1000 \
395
+ --timeout-ms 10000 \
396
+ --json
397
+
398
+ tiangong-lca dataset maintenance run-protected \
399
+ --plan ./protected-step2/maintenance-plan.json \
400
+ --freeze ./protected-step2/freeze/protected-execution-freeze.json \
401
+ --approval ./protected-step2/approval/protected-approval.json \
402
+ --out-dir ./protected-step2/run \
403
+ --status-only \
404
+ --wait-seconds 60 \
405
+ --json
355
406
  ```
356
407
 
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.
413
+
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.
415
+
416
+ Success requires the terminal database proof and independent RLS readback to agree on the approved execution, exact row/exchange/audit closure, and exactly 50 derivative targets split into 23 flows and 27 processes. `pending`, `failed`, and `indeterminate` all return a non-zero exit status. The protected operation keeps all affected rows private to their owner, changes no `state_code`, and does not publish data.
417
+
357
418
  For the derivative-only profile, use the same three commands with `--operation rebuild-derivatives`. Its scope must contain exactly one `processes` action with `action: "rebuild_derivatives"`, `target_mode: "owner_draft"`, expected current owner, expected `state_code: 0`, and the exact component set `extracted_md` plus `embedding_ft`.
358
419
 
359
420
  `--page-size` accepts `1-5000` and is only the requested maximum. PostgREST may enforce a lower server-side cap. The CLI requests `Prefer: count=exact`, validates the exact total and returned range from each `Content-Range`, advances the next offset by the number of rows actually returned, and requires strict `id`/`version` ordering without missing or duplicate identities. Each accepted scan records per-table requested/effective page size, page count, rows fetched, exact total, and aggregate entity counts.
@@ -373,7 +434,7 @@ The scope is intentionally narrow:
373
434
 
374
435
  `plan` accepts the account scan only after its exact-count proof is complete, then writes the frozen `maintenance-scope.json`, `rls-visible-snapshot.json`, `protected-rows.jsonl`, `reference-impact-report.json`, `maintenance-plan.json`, and `dry-run-report.json`. The snapshot, dry-run report, and newly generated plan carry the aggregate completeness proof, so it is bound into the plan SHA-256. Alias plans additionally write `exchange-rewrite-plan.jsonl`, freeze current-owner state-0 target FP, target UG, and source UG snapshots for each batch, derive schema-valid desired payloads with matching embedded UUID/version, and include the exact closure, `modified_at`, hashes, conversion evidence, and postconditions in the approved plan. A derivative rebuild plan additionally obtains a database-produced snapshot for only the exact target action and binds its primary and derivative preconditions into the plan; large markdown/vector fields are not added to the account-wide scan. The plan SHA-256 is the approval identity; do not edit or recompute the plan after review.
375
436
 
376
- `apply` is write-disabled unless all three commit guards are present: `--commit`, `--approve-plan <sha256>`, and `--confirm <current-account-email>`. Before approval is persisted or any write runs, it requires a fresh complete exact-count account scan and re-checks the whole plan for drift; the current completeness proof is recorded in `approval-record.json`. Ordinary draft updates/deletes use their platform paths. The ordered `time` plus `length_time` alias request is sent once to `cmd_dataset_alias_plan_guarded` with `target_visibility=owner_draft`; the CLI has neither a per-dimension fallback nor a 52-write sequential fallback. The RPC locks and validates the complete 52-row/59-exchange closure before both dimensions commit, so a second-dimension failure rolls back the first. It checks actor ownership, state 0, exact payload/timestamp locks and embedded UUID/version, rejects missing or phantom flow/exchange references, and returns one plan summary audit id plus both batch and per-row audit proofs. The CLI writes `alias-plan-progress.jsonl` together with plan-bound per-batch, per-row, and per-exchange ledgers. A lost response or incomplete derived ledger is repaired only by replaying the same whole plan and matching every returned plan and batch proof.
437
+ `apply` is write-disabled unless all three commit guards are present: `--commit`, `--approve-plan <sha256>`, and `--confirm <current-account-email>`. Before approval is persisted or any write runs, it requires a fresh complete exact-count account scan and re-checks the whole plan for drift; the current completeness proof is recorded in `approval-record.json`. Ordinary draft updates/deletes use their platform paths. The original V1 alias adapter retains its frozen request and artifact contract for compatibility, but it is not an authorized execution or recovery fallback for a sealed production `merge-support-aliases` plan. That plan must use `run-protected`, whose database contract replaces replay with one durable attempt/admission identity.
377
438
 
378
439
  For `rebuild-derivatives`, apply submits the frozen single-action plan only to the authenticated guarded RPC. The database admission envelope must report `queued`; the CLI records that durable admission as an `accepted` action with queued proof. It does not mean markdown or embedding generation has completed. Replay must return the same durable request/proof rather than enqueueing a second rebuild. There is no fallback to a direct Edge call, `admin embedding-run`, a raw queue, SQL, service-role credentials, or raw REST mutation.
379
440