@tiangong-lca/cli 0.0.33 → 0.1.0
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/LICENSE +21 -0
- package/README.md +29 -13
- package/assets/import-smoke/simapro.csv +20 -0
- package/bin/tiangong-lca.js +1 -1
- package/dist/src/cli.js +83 -64
- package/dist/src/cli.js.map +1 -1
- package/dist/src/lib/dataset-bilingual.js.map +1 -1
- package/dist/src/lib/dataset-classification.js.map +1 -1
- package/dist/src/lib/dataset-contract.js.map +1 -1
- package/dist/src/lib/dataset-evidence-search.js.map +1 -1
- package/dist/src/lib/dataset-import-lca.js +302 -131
- package/dist/src/lib/dataset-import-lca.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-apply.js +213 -46
- package/dist/src/lib/dataset-maintenance-apply.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-clear-account.js +10 -4
- package/dist/src/lib/dataset-maintenance-clear-account.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-contract.js +1 -6
- package/dist/src/lib/dataset-maintenance-contract.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-derivatives.js +0 -1
- package/dist/src/lib/dataset-maintenance-derivatives.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-flow-identity-capture.js +1 -0
- package/dist/src/lib/dataset-maintenance-flow-identity-capture.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-pagination.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-protected-before.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-protected-contract.js +0 -1
- package/dist/src/lib/dataset-maintenance-protected-contract.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-protected-freeze.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-protected-preparation.js +0 -2
- package/dist/src/lib/dataset-maintenance-protected-preparation.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-protected-seal.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-protected-verify.js +0 -3
- package/dist/src/lib/dataset-maintenance-protected-verify.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-remote.js +36 -14
- package/dist/src/lib/dataset-maintenance-remote.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-verify.js +1 -2
- package/dist/src/lib/dataset-maintenance-verify.js.map +1 -1
- package/dist/src/lib/dataset-remote-refresh.js.map +1 -1
- package/dist/src/lib/dataset-remote-verify.js +2 -0
- package/dist/src/lib/dataset-remote-verify.js.map +1 -1
- package/dist/src/lib/dataset-save-draft-run.js +2 -0
- package/dist/src/lib/dataset-save-draft-run.js.map +1 -1
- package/dist/src/lib/flow-build-alias-map.js.map +1 -1
- package/dist/src/lib/flow-fetch-rows.js.map +1 -1
- package/dist/src/lib/flow-get.js.map +1 -1
- package/dist/src/lib/flow-governance.js.map +1 -1
- package/dist/src/lib/flow-list.js +1 -0
- package/dist/src/lib/flow-list.js.map +1 -1
- package/dist/src/lib/flow-payload-validation.js.map +1 -1
- package/dist/src/lib/flow-publish-version.js +1 -0
- package/dist/src/lib/flow-publish-version.js.map +1 -1
- package/dist/src/lib/flow-read.js +1 -0
- package/dist/src/lib/flow-read.js.map +1 -1
- package/dist/src/lib/flow-regen-product.js.map +1 -1
- package/dist/src/lib/flow-remediate.js.map +1 -1
- package/dist/src/lib/identity-preflight.js +4 -10
- package/dist/src/lib/identity-preflight.js.map +1 -1
- package/dist/src/lib/lifecyclemodel-bundle-save.js +1 -0
- package/dist/src/lib/lifecyclemodel-bundle-save.js.map +1 -1
- package/dist/src/lib/lifecyclemodel-orchestrate.js.map +1 -1
- package/dist/src/lib/lifecyclemodel-publish-resulting-process.js.map +1 -1
- package/dist/src/lib/lifecyclemodel-resulting-process.js.map +1 -1
- package/dist/src/lib/lifecyclemodel-save-draft-run.js.map +1 -1
- package/dist/src/lib/lifecyclemodel-validate-build.js.map +1 -1
- package/dist/src/lib/package-version.js.map +1 -1
- package/dist/src/lib/process-auto-build.js.map +1 -1
- package/dist/src/lib/process-dedup-review.js +14 -7
- package/dist/src/lib/process-dedup-review.js.map +1 -1
- package/dist/src/lib/process-flow-build-plan.js +111 -30
- package/dist/src/lib/process-flow-build-plan.js.map +1 -1
- package/dist/src/lib/process-get.js +1 -0
- package/dist/src/lib/process-get.js.map +1 -1
- package/dist/src/lib/process-list.js +1 -0
- package/dist/src/lib/process-list.js.map +1 -1
- package/dist/src/lib/process-payload-validation.js.map +1 -1
- package/dist/src/lib/process-qa.js.map +1 -1
- package/dist/src/lib/process-refresh-references.js +15 -10
- package/dist/src/lib/process-refresh-references.js.map +1 -1
- package/dist/src/lib/process-save-draft.js +9 -3
- package/dist/src/lib/process-save-draft.js.map +1 -1
- package/dist/src/lib/process-scope-statistics.js +11 -4
- package/dist/src/lib/process-scope-statistics.js.map +1 -1
- package/dist/src/lib/process-verify-rows.js.map +1 -1
- package/dist/src/lib/publish.js.map +1 -1
- package/dist/src/lib/run.js.map +1 -1
- package/dist/src/lib/supabase-client.js +13 -1
- package/dist/src/lib/supabase-client.js.map +1 -1
- package/dist/src/lib/supabase-data-api-contract.js +328 -0
- package/dist/src/lib/supabase-data-api-contract.js.map +1 -0
- package/dist/src/lib/supabase-data-api-replay.js +69 -0
- package/dist/src/lib/supabase-data-api-replay.js.map +1 -0
- package/dist/src/lib/supabase-json-ordered-write.js +2 -0
- package/dist/src/lib/supabase-json-ordered-write.js.map +1 -1
- package/dist/src/lib/supabase-rest.js +1 -0
- package/dist/src/lib/supabase-rest.js.map +1 -1
- package/dist/src/lib/tidas-sdk-package-validator.js +5 -5
- package/dist/src/lib/tidas-sdk-package-validator.js.map +1 -1
- package/dist/src/lib/validation.js.map +1 -1
- package/dist/src/main.js.map +1 -1
- package/package.json +40 -40
- package/dist/scripts/assert-full-coverage.js +0 -77
- package/dist/scripts/assert-full-coverage.js.map +0 -1
|
@@ -1,15 +1,21 @@
|
|
|
1
|
-
import { closeSync, existsSync, fchmodSync, fsyncSync, openSync, writeFileSync } from 'node:fs';
|
|
1
|
+
import { closeSync, existsSync, fchmodSync, fsyncSync, openSync, readFileSync, writeFileSync, } from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { writeJsonArtifact } from './artifacts.js';
|
|
4
4
|
import { collectRemoteReferences } from './dataset-remote-verify.js';
|
|
5
5
|
import { CliError } from './errors.js';
|
|
6
6
|
import { withStateFileLock } from './state-lock.js';
|
|
7
7
|
import { buildAliasBatchRequest, buildAliasPlanRequest, loadMaintenanceDesiredPayload, orderedAliasBatches, } from './dataset-maintenance-alias-request.js';
|
|
8
|
-
import { MAINTENANCE_SCAN_TABLES, appendStableJsonLine, isJsonObject, maintenanceRowKey, parseMaintenancePlan, readJsonFile, readJsonLinesIfPresent, sha256Json, snapshotRemoteRow, stableJsonText, writeImmutableJson, } from './dataset-maintenance-contract.js';
|
|
8
|
+
import { MAINTENANCE_SCAN_TABLES, appendStableJsonLine, isJsonObject, maintenanceRowKey, parseMaintenancePlan, readJsonFile, readJsonLinesIfPresent, sha256Json, sha256Text, snapshotRemoteRow, stableJsonText, writeImmutableJson, } from './dataset-maintenance-contract.js';
|
|
9
9
|
import { buildDerivativePlanRequest, derivativePlanAction, parseDerivativeSnapshotResponse, parseDerivativeSubmitResponse, } from './dataset-maintenance-derivatives.js';
|
|
10
10
|
import { maintenanceProjectedReferenceFingerprint } from './dataset-maintenance-plan.js';
|
|
11
11
|
import { isSnapshotCompletenessCompatible } from './dataset-maintenance-pagination.js';
|
|
12
|
-
import {
|
|
12
|
+
import { applyMaintenanceDerivativeRebuild, deleteMaintenanceRow, fetchMaintenanceAccountRows, fetchMaintenanceDerivativeSnapshot, fetchMaintenanceExactRows, fetchMaintenanceVisibleTableRows, resolveMaintenanceRemoteContext, saveDraftMaintenanceRow, } from './dataset-maintenance-remote.js';
|
|
13
|
+
// Process payloads can be large enough for the default 1,000-row page to exceed
|
|
14
|
+
// the database statement timeout. Keep the destructive all-visible RLS fence,
|
|
15
|
+
// but bound each SELECT-only page so admission can complete without weakening it.
|
|
16
|
+
const PARALLEL_DELETE_VISIBLE_PROCESS_PAGE_SIZE = 250;
|
|
17
|
+
const GLOBAL_INBOUND_PROOF_MAX_AGE_MS = 30 * 60 * 1_000;
|
|
18
|
+
const SHA256_PATTERN = /^[0-9a-f]{64}$/u;
|
|
13
19
|
const POSITIVE_INTEGER_TEXT = /^[1-9]\d*$/u;
|
|
14
20
|
function clock(options) {
|
|
15
21
|
return (options.now ?? new Date()).toISOString();
|
|
@@ -65,6 +71,159 @@ function assertParallelDeletePlan(plan) {
|
|
|
65
71
|
targets.add(target);
|
|
66
72
|
}
|
|
67
73
|
}
|
|
74
|
+
function parallelDeleteTargetBindingSha256(plan) {
|
|
75
|
+
return sha256Json(plan.actions.map((action, index) => ({
|
|
76
|
+
index,
|
|
77
|
+
ordinal: action.ordinal,
|
|
78
|
+
action_id: action.action_id,
|
|
79
|
+
table: action.table,
|
|
80
|
+
id: action.id,
|
|
81
|
+
version: action.version,
|
|
82
|
+
expected_user_id: action.expected_user_id,
|
|
83
|
+
expected_state_code: action.expected_state_code,
|
|
84
|
+
before_sha256: action.before?.row_sha256 ?? null,
|
|
85
|
+
})));
|
|
86
|
+
}
|
|
87
|
+
function invalidGlobalInboundProof(message, details) {
|
|
88
|
+
throw new CliError(message, {
|
|
89
|
+
code: 'DATASET_MAINTENANCE_GLOBAL_INBOUND_PROOF_INVALID',
|
|
90
|
+
exitCode: 1,
|
|
91
|
+
details,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
function assertGlobalInboundProofOptionShape(options) {
|
|
95
|
+
const hasPath = typeof options.proofPath === 'string' && options.proofPath.length > 0;
|
|
96
|
+
const hasApproval = typeof options.approveProof === 'string' && options.approveProof.length > 0;
|
|
97
|
+
if (hasPath !== hasApproval) {
|
|
98
|
+
throw new CliError('--global-inbound-proof and --approve-global-inbound-proof must be provided together.', {
|
|
99
|
+
code: 'DATASET_MAINTENANCE_GLOBAL_INBOUND_PROOF_OPTIONS_INCOMPLETE',
|
|
100
|
+
exitCode: 2,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
if ((hasPath || hasApproval) && !options.parallelDeleteMode) {
|
|
104
|
+
throw new CliError('A global inbound proof is allowed only with --max-parallel flow delete-only execution.', {
|
|
105
|
+
code: 'DATASET_MAINTENANCE_GLOBAL_INBOUND_PROOF_MODE_INVALID',
|
|
106
|
+
exitCode: 2,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
if (hasApproval && !SHA256_PATTERN.test(options.approveProof)) {
|
|
110
|
+
throw new CliError('--approve-global-inbound-proof must be a lowercase SHA-256.', {
|
|
111
|
+
code: 'DATASET_MAINTENANCE_GLOBAL_INBOUND_PROOF_APPROVAL_INVALID',
|
|
112
|
+
exitCode: 2,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function validateParallelDeleteGlobalInboundProof(options) {
|
|
117
|
+
if (!options.proofPath || !options.approveProof)
|
|
118
|
+
return null;
|
|
119
|
+
if (!path.isAbsolute(options.proofPath)) {
|
|
120
|
+
invalidGlobalInboundProof('Global inbound proof path must be absolute.');
|
|
121
|
+
}
|
|
122
|
+
let proofText;
|
|
123
|
+
try {
|
|
124
|
+
proofText = readFileSync(options.proofPath, 'utf8');
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
invalidGlobalInboundProof('Global inbound proof file could not be read.', errorMessage(error));
|
|
128
|
+
}
|
|
129
|
+
const proofSha256 = sha256Text(proofText);
|
|
130
|
+
if (proofSha256 !== options.approveProof) {
|
|
131
|
+
invalidGlobalInboundProof('Global inbound proof file SHA-256 does not match approval.', {
|
|
132
|
+
expected: options.approveProof,
|
|
133
|
+
actual: proofSha256,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
let value;
|
|
137
|
+
try {
|
|
138
|
+
value = JSON.parse(proofText);
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
invalidGlobalInboundProof('Global inbound proof is not valid JSON.', errorMessage(error));
|
|
142
|
+
}
|
|
143
|
+
if (!isJsonObject(value)) {
|
|
144
|
+
invalidGlobalInboundProof('Global inbound proof must be a JSON object.');
|
|
145
|
+
}
|
|
146
|
+
const expectedBinding = parallelDeleteTargetBindingSha256(options.plan);
|
|
147
|
+
const capturedAt = typeof value.captured_at_utc === 'string' ? Date.parse(value.captured_at_utc) : NaN;
|
|
148
|
+
const nowMs = options.now.getTime();
|
|
149
|
+
const capturedAgeMs = nowMs - capturedAt;
|
|
150
|
+
const safePositiveInteger = (candidate) => Number.isSafeInteger(candidate) && Number(candidate) > 0;
|
|
151
|
+
if (value.schema_version !== 'dataset-maintenance-global-inbound-proof.v1' ||
|
|
152
|
+
value.status !== 'PASS_GLOBAL_ALL_PROCESS_INBOUND_ZERO' ||
|
|
153
|
+
value.statement_kind !== 'SELECT' ||
|
|
154
|
+
value.source !== 'supabase_select_only_raw_sql' ||
|
|
155
|
+
value.process_scope !== 'all_process_rows_without_rls_restriction' ||
|
|
156
|
+
!Number.isFinite(capturedAt) ||
|
|
157
|
+
capturedAgeMs < -30_000 ||
|
|
158
|
+
capturedAgeMs > GLOBAL_INBOUND_PROOF_MAX_AGE_MS ||
|
|
159
|
+
value.project_ref !== options.context.project_ref ||
|
|
160
|
+
value.actor_user_id !== options.context.account.user_id ||
|
|
161
|
+
value.plan_sha256 !== options.plan.plan_sha256 ||
|
|
162
|
+
value.operation !== 'delete' ||
|
|
163
|
+
value.target_table !== 'flows' ||
|
|
164
|
+
value.target_count !== options.plan.actions.length ||
|
|
165
|
+
value.target_binding_sha256 !== expectedBinding ||
|
|
166
|
+
!safePositiveInteger(value.global_process_rows) ||
|
|
167
|
+
!safePositiveInteger(value.global_exchange_rows) ||
|
|
168
|
+
value.inbound_exchanges !== 0 ||
|
|
169
|
+
value.old_flow_identities_with_inbound !== 0 ||
|
|
170
|
+
value.process_identities_with_inbound !== 0 ||
|
|
171
|
+
value.p0 !== 0 ||
|
|
172
|
+
value.p1 !== 0 ||
|
|
173
|
+
!Array.isArray(value.chunks) ||
|
|
174
|
+
value.chunks.length === 0) {
|
|
175
|
+
invalidGlobalInboundProof('Global inbound proof metadata or zero-inbound result is invalid.', {
|
|
176
|
+
expected_project_ref: options.context.project_ref,
|
|
177
|
+
expected_actor_user_id: options.context.account.user_id,
|
|
178
|
+
expected_plan_sha256: options.plan.plan_sha256,
|
|
179
|
+
expected_target_count: options.plan.actions.length,
|
|
180
|
+
expected_target_binding_sha256: expectedBinding,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
let expectedStart = 0;
|
|
184
|
+
for (const [index, rawChunk] of value.chunks.entries()) {
|
|
185
|
+
if (!isJsonObject(rawChunk)) {
|
|
186
|
+
invalidGlobalInboundProof('Global inbound proof contains a non-object chunk.', { index });
|
|
187
|
+
}
|
|
188
|
+
const chunkCapturedAt = typeof rawChunk.captured_at_utc === 'string' ? Date.parse(rawChunk.captured_at_utc) : NaN;
|
|
189
|
+
const chunkAgeMs = nowMs - chunkCapturedAt;
|
|
190
|
+
if (rawChunk.index !== index ||
|
|
191
|
+
rawChunk.start !== expectedStart ||
|
|
192
|
+
!Number.isSafeInteger(rawChunk.end_exclusive) ||
|
|
193
|
+
Number(rawChunk.end_exclusive) <= expectedStart ||
|
|
194
|
+
Number(rawChunk.end_exclusive) > options.plan.actions.length ||
|
|
195
|
+
rawChunk.target_count !== Number(rawChunk.end_exclusive) - expectedStart ||
|
|
196
|
+
!Number.isFinite(chunkCapturedAt) ||
|
|
197
|
+
chunkAgeMs < -30_000 ||
|
|
198
|
+
chunkAgeMs > GLOBAL_INBOUND_PROOF_MAX_AGE_MS ||
|
|
199
|
+
rawChunk.inbound_exchanges !== 0 ||
|
|
200
|
+
rawChunk.old_flow_identities_with_inbound !== 0 ||
|
|
201
|
+
rawChunk.process_identities_with_inbound !== 0 ||
|
|
202
|
+
rawChunk.owner_draft_inbound !== 0 ||
|
|
203
|
+
rawChunk.public_inbound !== 0 ||
|
|
204
|
+
rawChunk.foreign_private_inbound !== 0 ||
|
|
205
|
+
rawChunk.other_state_inbound !== 0 ||
|
|
206
|
+
typeof rawChunk.sql_sha256 !== 'string' ||
|
|
207
|
+
!SHA256_PATTERN.test(rawChunk.sql_sha256)) {
|
|
208
|
+
invalidGlobalInboundProof('Global inbound proof contains an invalid or incomplete chunk.', {
|
|
209
|
+
index,
|
|
210
|
+
expected_start: expectedStart,
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
expectedStart = Number(rawChunk.end_exclusive);
|
|
214
|
+
}
|
|
215
|
+
if (expectedStart !== options.plan.actions.length) {
|
|
216
|
+
invalidGlobalInboundProof('Global inbound proof chunks do not cover every delete target.', {
|
|
217
|
+
expected_end: options.plan.actions.length,
|
|
218
|
+
actual_end: expectedStart,
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
return {
|
|
222
|
+
...value,
|
|
223
|
+
proof_path: options.proofPath,
|
|
224
|
+
proof_sha256: proofSha256,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
68
227
|
function parseParallelDeleteExecutionLog(plan, executionLogPath) {
|
|
69
228
|
const actions = new Map(plan.actions.map((action) => [action.action_id, action]));
|
|
70
229
|
const entries = [];
|
|
@@ -881,39 +1040,6 @@ function validateAliasPlanRpcResult(value, plan) {
|
|
|
881
1040
|
raw: value,
|
|
882
1041
|
};
|
|
883
1042
|
}
|
|
884
|
-
async function executeAliasPlan(options) {
|
|
885
|
-
const request = buildAliasPlanRequest(options);
|
|
886
|
-
const remoteResult = await applyMaintenanceAliasPlan({
|
|
887
|
-
context: options.context,
|
|
888
|
-
plan: request,
|
|
889
|
-
});
|
|
890
|
-
const rpc = validateAliasPlanRpcResult(remoteResult, options.plan);
|
|
891
|
-
const afterByAction = new Map();
|
|
892
|
-
for (const action of options.plan.actions) {
|
|
893
|
-
const exact = await fetchMaintenanceExactRows({
|
|
894
|
-
context: options.context,
|
|
895
|
-
table: action.table,
|
|
896
|
-
id: action.id,
|
|
897
|
-
version: action.version,
|
|
898
|
-
});
|
|
899
|
-
const row = exact.rows.length === 1 ? exact.rows[0] : null;
|
|
900
|
-
const snapshot = row ? snapshotRemoteRow(row) : null;
|
|
901
|
-
if (!row ||
|
|
902
|
-
row.user_id !== action.expected_user_id ||
|
|
903
|
-
row.state_code !== 0 ||
|
|
904
|
-
snapshot?.payload_sha256 !== action.desired_payload?.sha256 ||
|
|
905
|
-
row.model_id !== action.before?.model_id ||
|
|
906
|
-
row.rule_verification !== action.before?.rule_verification) {
|
|
907
|
-
throw new CliError(`Alias plan readback failed for action ${action.action_id}.`, {
|
|
908
|
-
code: 'DATASET_MAINTENANCE_ALIAS_READBACK_FAILED',
|
|
909
|
-
exitCode: 1,
|
|
910
|
-
});
|
|
911
|
-
}
|
|
912
|
-
afterByAction.set(action.action_id, snapshot.row_sha256);
|
|
913
|
-
}
|
|
914
|
-
await assertAliasSupportSnapshots({ plan: options.plan, context: options.context });
|
|
915
|
-
return { rpc, after_by_action: afterByAction };
|
|
916
|
-
}
|
|
917
1043
|
function aliasExchangeProgressKey(value) {
|
|
918
1044
|
return `${value.batch_id}\u0000${value.action_id}\u0000${value.exchange_index}\u0000${value.data_set_internal_id}`;
|
|
919
1045
|
}
|
|
@@ -1619,8 +1745,7 @@ async function executeDerivativeAdmission(options) {
|
|
|
1619
1745
|
}), { id: action.id, version: action.version, userId: action.expected_user_id });
|
|
1620
1746
|
if (preflight.modified_at !== plannedSnapshot.modified_at ||
|
|
1621
1747
|
preflight.json_sha256 !== plannedSnapshot.json_sha256 ||
|
|
1622
|
-
preflight.json_ordered_sha256 !== plannedSnapshot.json_ordered_sha256
|
|
1623
|
-
preflight.extracted_text_sha256 !== plannedSnapshot.extracted_text_sha256) {
|
|
1748
|
+
preflight.json_ordered_sha256 !== plannedSnapshot.json_ordered_sha256) {
|
|
1624
1749
|
throw new CliError('Derivative action primary preconditions drifted after planning.', {
|
|
1625
1750
|
code: 'DATASET_MAINTENANCE_DERIVATIVE_PRIMARY_DRIFT',
|
|
1626
1751
|
exitCode: 1,
|
|
@@ -1689,6 +1814,11 @@ export async function runDatasetMaintenanceApply(options) {
|
|
|
1689
1814
|
const plan = parseMaintenancePlan(readJsonFile(planPath, 'Maintenance plan'));
|
|
1690
1815
|
const parallelDeleteMode = options.maxParallel !== undefined;
|
|
1691
1816
|
const maxParallel = normalizeMaintenanceMaxParallel(options.maxParallel);
|
|
1817
|
+
assertGlobalInboundProofOptionShape({
|
|
1818
|
+
parallelDeleteMode,
|
|
1819
|
+
proofPath: options.globalInboundProofPath,
|
|
1820
|
+
approveProof: options.approveGlobalInboundProof,
|
|
1821
|
+
});
|
|
1692
1822
|
if (parallelDeleteMode) {
|
|
1693
1823
|
assertParallelDeletePlan(plan);
|
|
1694
1824
|
}
|
|
@@ -1742,6 +1872,15 @@ export async function runDatasetMaintenanceApply(options) {
|
|
|
1742
1872
|
exitCode: 2,
|
|
1743
1873
|
});
|
|
1744
1874
|
}
|
|
1875
|
+
const globalInboundProof = parallelDeleteMode
|
|
1876
|
+
? validateParallelDeleteGlobalInboundProof({
|
|
1877
|
+
proofPath: options.globalInboundProofPath,
|
|
1878
|
+
approveProof: options.approveGlobalInboundProof,
|
|
1879
|
+
plan,
|
|
1880
|
+
context,
|
|
1881
|
+
now: options.now ?? new Date(),
|
|
1882
|
+
})
|
|
1883
|
+
: null;
|
|
1745
1884
|
const derivativeProgress = plan.operation === 'rebuild-derivatives'
|
|
1746
1885
|
? parseDerivativeSubmitProgress(plan, progressPath)
|
|
1747
1886
|
: { entries: [], latest: null };
|
|
@@ -1758,8 +1897,12 @@ export async function runDatasetMaintenanceApply(options) {
|
|
|
1758
1897
|
context,
|
|
1759
1898
|
userId: plan.account.user_id,
|
|
1760
1899
|
}),
|
|
1761
|
-
parallelDeleteMode
|
|
1762
|
-
? fetchMaintenanceVisibleTableRows({
|
|
1900
|
+
parallelDeleteMode && !globalInboundProof
|
|
1901
|
+
? fetchMaintenanceVisibleTableRows({
|
|
1902
|
+
context,
|
|
1903
|
+
table: 'processes',
|
|
1904
|
+
pageSize: PARALLEL_DELETE_VISIBLE_PROCESS_PAGE_SIZE,
|
|
1905
|
+
})
|
|
1763
1906
|
: Promise.resolve(null),
|
|
1764
1907
|
]);
|
|
1765
1908
|
assertApplyPreconditions({
|
|
@@ -1771,10 +1914,16 @@ export async function runDatasetMaintenanceApply(options) {
|
|
|
1771
1914
|
attemptedDeleteActionIds: parallelDeleteExecution.dispatched,
|
|
1772
1915
|
});
|
|
1773
1916
|
const inboundBarrierPath = nextParallelDeleteInboundBarrierPath(planDir);
|
|
1774
|
-
const inboundBarrier =
|
|
1775
|
-
?
|
|
1776
|
-
|
|
1777
|
-
|
|
1917
|
+
const inboundBarrier = globalInboundProof
|
|
1918
|
+
? {
|
|
1919
|
+
process_rows: globalInboundProof.global_process_rows,
|
|
1920
|
+
process_references: globalInboundProof.global_exchange_rows,
|
|
1921
|
+
snapshot_sha256: globalInboundProof.proof_sha256,
|
|
1922
|
+
}
|
|
1923
|
+
: parallelDeleteMode && visibleProcesses
|
|
1924
|
+
? assertNoVisibleProcessInboundReferences({ plan, rows: visibleProcesses.rows })
|
|
1925
|
+
: null;
|
|
1926
|
+
if (inboundBarrier && (visibleProcesses || globalInboundProof)) {
|
|
1778
1927
|
writeImmutableJson(inboundBarrierPath, {
|
|
1779
1928
|
schema_version: 1,
|
|
1780
1929
|
generated_at_utc: clock(options),
|
|
@@ -1785,7 +1934,23 @@ export async function runDatasetMaintenanceApply(options) {
|
|
|
1785
1934
|
target_count: plan.actions.length,
|
|
1786
1935
|
inbound_reference_count: 0,
|
|
1787
1936
|
...inboundBarrier,
|
|
1788
|
-
completeness:
|
|
1937
|
+
completeness: globalInboundProof
|
|
1938
|
+
? {
|
|
1939
|
+
status: 'complete',
|
|
1940
|
+
complete: true,
|
|
1941
|
+
strategy: 'sha256_approved_global_select_only_all_processes',
|
|
1942
|
+
statement_kind: globalInboundProof.statement_kind,
|
|
1943
|
+
process_scope: globalInboundProof.process_scope,
|
|
1944
|
+
proof_path: globalInboundProof.proof_path,
|
|
1945
|
+
proof_sha256: globalInboundProof.proof_sha256,
|
|
1946
|
+
captured_at_utc: globalInboundProof.captured_at_utc,
|
|
1947
|
+
target_binding_sha256: globalInboundProof.target_binding_sha256,
|
|
1948
|
+
chunk_count: globalInboundProof.chunks.length,
|
|
1949
|
+
global_process_rows: globalInboundProof.global_process_rows,
|
|
1950
|
+
global_exchange_rows: globalInboundProof.global_exchange_rows,
|
|
1951
|
+
inbound_exchanges: globalInboundProof.inbound_exchanges,
|
|
1952
|
+
}
|
|
1953
|
+
: visibleProcesses.completeness,
|
|
1789
1954
|
});
|
|
1790
1955
|
}
|
|
1791
1956
|
const approvalPath = path.join(planDir, 'approval-record.json');
|
|
@@ -2127,13 +2292,13 @@ export const __testInternals = {
|
|
|
2127
2292
|
assertNoVisibleProcessInboundReferences,
|
|
2128
2293
|
assertApplyPreconditions,
|
|
2129
2294
|
assertAliasSupportSnapshots,
|
|
2295
|
+
assertGlobalInboundProofOptionShape,
|
|
2130
2296
|
assertParallelDeletePlan,
|
|
2131
2297
|
buildAliasBatchRequest,
|
|
2132
2298
|
buildAliasPlanRequest,
|
|
2133
2299
|
clock,
|
|
2134
2300
|
errorMessage,
|
|
2135
2301
|
executeDerivativeAdmission,
|
|
2136
|
-
executeAliasPlan,
|
|
2137
2302
|
executeAction,
|
|
2138
2303
|
executeParallelDeletePlan,
|
|
2139
2304
|
finalProjectedRows,
|
|
@@ -2142,6 +2307,7 @@ export const __testInternals = {
|
|
|
2142
2307
|
nextParallelDeleteInboundBarrierPath,
|
|
2143
2308
|
normalizeMaintenanceMaxParallel,
|
|
2144
2309
|
parallelDeleteDesiredSha256,
|
|
2310
|
+
parallelDeleteTargetBindingSha256,
|
|
2145
2311
|
parseDerivativeSubmitProgress,
|
|
2146
2312
|
validateDerivativeAdmissionAttempt,
|
|
2147
2313
|
parseAliasBatchProgress,
|
|
@@ -2152,5 +2318,6 @@ export const __testInternals = {
|
|
|
2152
2318
|
validateAliasRpcResult,
|
|
2153
2319
|
validateAliasPlanRpcResult,
|
|
2154
2320
|
validateApprovalRecord,
|
|
2321
|
+
validateParallelDeleteGlobalInboundProof,
|
|
2155
2322
|
};
|
|
2156
2323
|
//# sourceMappingURL=dataset-maintenance-apply.js.map
|