@tiangong-lca/cli 0.0.22 → 0.0.24
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 +23 -7
- package/dist/src/cli.js +25 -12
- package/dist/src/cli.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-apply.js +274 -6
- package/dist/src/lib/dataset-maintenance-apply.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-clear-account.js +121 -58
- package/dist/src/lib/dataset-maintenance-clear-account.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-contract.js +126 -16
- package/dist/src/lib/dataset-maintenance-contract.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-derivatives.js +265 -0
- package/dist/src/lib/dataset-maintenance-derivatives.js.map +1 -0
- package/dist/src/lib/dataset-maintenance-pagination.js +270 -0
- package/dist/src/lib/dataset-maintenance-pagination.js.map +1 -0
- package/dist/src/lib/dataset-maintenance-plan.js +41 -6
- package/dist/src/lib/dataset-maintenance-plan.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-remote.js +76 -28
- package/dist/src/lib/dataset-maintenance-remote.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-verify.js +314 -5
- package/dist/src/lib/dataset-maintenance-verify.js.map +1 -1
- package/package.json +1 -1
|
@@ -3,9 +3,11 @@ 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
|
-
import { isJsonObject, maintenanceRowKey, parseMaintenancePlan, readJsonFile, readJsonLinesIfPresent, resolveMaintenancePlanArtifactPath, sha256Json, snapshotRemoteRow, } from './dataset-maintenance-contract.js';
|
|
6
|
+
import { MAINTENANCE_SCAN_TABLES, isJsonObject, maintenanceRowKey, parseMaintenancePlan, readJsonFile, readJsonLinesIfPresent, resolveMaintenancePlanArtifactPath, sha256Json, snapshotRemoteRow, } from './dataset-maintenance-contract.js';
|
|
7
|
+
import { derivativePlanAction, derivativeStatusCategory, parseDerivativeSnapshotResponse, parseDerivativeStatusResponse, parseDerivativeSubmitResponse, } from './dataset-maintenance-derivatives.js';
|
|
7
8
|
import { maintenanceProjectedReferenceFingerprint } from './dataset-maintenance-plan.js';
|
|
8
|
-
import {
|
|
9
|
+
import { isSnapshotCompletenessCompatible, } from './dataset-maintenance-pagination.js';
|
|
10
|
+
import { fetchMaintenanceAccountRows, fetchMaintenanceDerivativeSnapshot, fetchMaintenanceExactRows, normalizeMaintenancePageSize, readMaintenanceDerivativeRebuild, resolveMaintenanceRemoteContext, } from './dataset-maintenance-remote.js';
|
|
9
11
|
const POSITIVE_INTEGER_TEXT = /^[1-9]\d*$/u;
|
|
10
12
|
function issue(code, message, action, details) {
|
|
11
13
|
return {
|
|
@@ -50,19 +52,308 @@ function deletedTargetReferences(options) {
|
|
|
50
52
|
}));
|
|
51
53
|
});
|
|
52
54
|
}
|
|
55
|
+
function derivativeSubmitIdentity(proof) {
|
|
56
|
+
return sha256Json({
|
|
57
|
+
schema_version: proof.schema_version,
|
|
58
|
+
plan_sha256: proof.plan_sha256,
|
|
59
|
+
operation_id: proof.operation_id,
|
|
60
|
+
target_visibility: proof.target_visibility,
|
|
61
|
+
plan_request_sha256: proof.plan_request_sha256,
|
|
62
|
+
action_count: proof.action_count,
|
|
63
|
+
accepted_count: proof.accepted_count,
|
|
64
|
+
summary_audit_id: proof.summary_audit_id,
|
|
65
|
+
request_id: proof.request_id,
|
|
66
|
+
action_request_sha256: proof.action_request_sha256,
|
|
67
|
+
database_audit_id: proof.database_audit_id,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
function readDerivativeSubmitProof(options) {
|
|
71
|
+
const action = derivativePlanAction(options.plan);
|
|
72
|
+
const proofs = [];
|
|
73
|
+
for (const [index, value] of readJsonLinesIfPresent(options.progressPath).entries()) {
|
|
74
|
+
try {
|
|
75
|
+
if (!isJsonObject(value) ||
|
|
76
|
+
value.schema_version !== 1 ||
|
|
77
|
+
value.plan_sha256 !== options.plan.plan_sha256 ||
|
|
78
|
+
value.operation_id !== options.plan.operation_id ||
|
|
79
|
+
value.action_id !== action.action_id ||
|
|
80
|
+
value.target_mode !== 'owner_draft' ||
|
|
81
|
+
!isJsonObject(value.actor) ||
|
|
82
|
+
value.actor.user_id !== options.plan.account.user_id ||
|
|
83
|
+
value.actor.email !== options.plan.account.email ||
|
|
84
|
+
typeof value.started_at_utc !== 'string' ||
|
|
85
|
+
typeof value.ended_at_utc !== 'string' ||
|
|
86
|
+
value.result !== 'accepted' ||
|
|
87
|
+
!isJsonObject(value.proof)) {
|
|
88
|
+
throw new Error('wrapper mismatch');
|
|
89
|
+
}
|
|
90
|
+
proofs.push(parseDerivativeSubmitResponse({
|
|
91
|
+
ok: true,
|
|
92
|
+
command: 'cmd_dataset_derivative_rebuild_plan_guarded',
|
|
93
|
+
...value.proof,
|
|
94
|
+
}, options.plan));
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
options.problems.push({
|
|
98
|
+
code: 'DERIVATIVE_SUBMIT_PROGRESS_INVALID',
|
|
99
|
+
message: 'Derivative submit progress contains an invalid or foreign entry.',
|
|
100
|
+
details: { line: index + 1, error: String(error) },
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (proofs.length === 0) {
|
|
105
|
+
options.problems.push({
|
|
106
|
+
code: 'DERIVATIVE_ADMISSION_MISSING',
|
|
107
|
+
message: 'No valid guarded-RPC derivative admission proof exists.',
|
|
108
|
+
});
|
|
109
|
+
return { proof: null, admissions: 0 };
|
|
110
|
+
}
|
|
111
|
+
if (new Set(proofs.map(derivativeSubmitIdentity)).size !== 1) {
|
|
112
|
+
options.problems.push({
|
|
113
|
+
code: 'DERIVATIVE_ADMISSION_REPLAY_MISMATCH',
|
|
114
|
+
message: 'Derivative admission entries do not identify one durable request.',
|
|
115
|
+
});
|
|
116
|
+
return { proof: null, admissions: proofs.length };
|
|
117
|
+
}
|
|
118
|
+
return { proof: proofs.at(-1), admissions: proofs.length };
|
|
119
|
+
}
|
|
120
|
+
async function runDerivativeMaintenanceVerify(options) {
|
|
121
|
+
const action = derivativePlanAction(options.plan);
|
|
122
|
+
const baseline = action.derivative_before;
|
|
123
|
+
const problems = [];
|
|
124
|
+
const currentByKey = new Map(options.current.rows.map((row) => [maintenanceRowKey(row), row]));
|
|
125
|
+
let protectedPassed = 0;
|
|
126
|
+
for (const protectedRow of options.plan.protected_rows) {
|
|
127
|
+
const row = currentByKey.get(maintenanceRowKey(protectedRow));
|
|
128
|
+
if (row && snapshotRemoteRow(row).row_sha256 === protectedRow.row_sha256) {
|
|
129
|
+
protectedPassed += 1;
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
problems.push({
|
|
133
|
+
code: 'PROTECTED_ROW_CHANGED',
|
|
134
|
+
message: 'Protected primary row changed or disappeared after derivative admission.',
|
|
135
|
+
table: protectedRow.table,
|
|
136
|
+
id: protectedRow.id,
|
|
137
|
+
version: protectedRow.version,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
const expectedKeys = new Set([
|
|
142
|
+
...options.plan.protected_rows.map(maintenanceRowKey),
|
|
143
|
+
maintenanceRowKey(action),
|
|
144
|
+
]);
|
|
145
|
+
for (const row of options.current.rows) {
|
|
146
|
+
if (!expectedKeys.has(maintenanceRowKey(row))) {
|
|
147
|
+
problems.push({
|
|
148
|
+
code: 'UNEXPECTED_ACCOUNT_ROW',
|
|
149
|
+
message: 'Unexpected current-account primary row exists after derivative admission.',
|
|
150
|
+
table: row.table,
|
|
151
|
+
id: row.id,
|
|
152
|
+
version: row.version,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
const primaryRow = currentByKey.get(maintenanceRowKey(action));
|
|
157
|
+
if (!primaryRow || snapshotRemoteRow(primaryRow).row_sha256 !== action.before?.row_sha256) {
|
|
158
|
+
problems.push(issue('DERIVATIVE_PRIMARY_ROW_DRIFT', 'The process primary row changed after derivative planning.', action));
|
|
159
|
+
}
|
|
160
|
+
const referenceSha256 = sha256Json(maintenanceProjectedReferenceFingerprint(options.current.rows));
|
|
161
|
+
if (referenceSha256 !== options.plan.projected_reference_sha256) {
|
|
162
|
+
problems.push({
|
|
163
|
+
code: 'PROJECTED_REFERENCE_CLOSURE_MISMATCH',
|
|
164
|
+
message: 'Primary readback reference closure differs from the approved plan.',
|
|
165
|
+
details: { expected: options.plan.projected_reference_sha256, actual: referenceSha256 },
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
if (!existsSync(options.approvalRecordPath)) {
|
|
169
|
+
problems.push({ code: 'APPROVAL_RECORD_MISSING', message: 'approval-record.json is missing.' });
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
const approval = readJsonFile(options.approvalRecordPath, 'Maintenance approval record');
|
|
173
|
+
if (!isJsonObject(approval) ||
|
|
174
|
+
approval.schema_version !== 1 ||
|
|
175
|
+
approval.plan_sha256 !== options.plan.plan_sha256 ||
|
|
176
|
+
approval.task_id !== options.plan.task_id ||
|
|
177
|
+
approval.operation !== 'rebuild-derivatives' ||
|
|
178
|
+
approval.operation_id !== options.plan.operation_id ||
|
|
179
|
+
approval.target_mode !== 'owner_draft' ||
|
|
180
|
+
!isJsonObject(approval.account) ||
|
|
181
|
+
approval.account.user_id !== options.plan.account.user_id ||
|
|
182
|
+
approval.account.email !== options.plan.account.email ||
|
|
183
|
+
approval.confirmed_email !== options.plan.account.email ||
|
|
184
|
+
!isJsonObject(approval.row_counts) ||
|
|
185
|
+
sha256Json(approval.row_counts) !== sha256Json(options.plan.summary) ||
|
|
186
|
+
!isSnapshotCompletenessCompatible(approval.snapshot_completeness, options.plan.snapshot_completeness, MAINTENANCE_SCAN_TABLES)) {
|
|
187
|
+
problems.push({
|
|
188
|
+
code: 'APPROVAL_RECORD_INVALID',
|
|
189
|
+
message: 'approval-record.json does not match the immutable derivative plan and actor.',
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
const admission = readDerivativeSubmitProof({
|
|
194
|
+
plan: options.plan,
|
|
195
|
+
progressPath: options.progressPath,
|
|
196
|
+
problems,
|
|
197
|
+
});
|
|
198
|
+
if (!existsSync(options.commitReportPath)) {
|
|
199
|
+
problems.push({ code: 'COMMIT_REPORT_MISSING', message: 'commit-report.json is missing.' });
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
const commit = readJsonFile(options.commitReportPath, 'Maintenance commit report');
|
|
203
|
+
const commitProof = isJsonObject(commit) && isJsonObject(commit.derivative_admission)
|
|
204
|
+
? commit.derivative_admission
|
|
205
|
+
: null;
|
|
206
|
+
if (!isJsonObject(commit) ||
|
|
207
|
+
commit.schema_version !== 1 ||
|
|
208
|
+
commit.status !== 'accepted' ||
|
|
209
|
+
commit.plan_sha256 !== options.plan.plan_sha256 ||
|
|
210
|
+
commit.operation !== 'rebuild-derivatives' ||
|
|
211
|
+
commit.operation_id !== options.plan.operation_id ||
|
|
212
|
+
!commitProof ||
|
|
213
|
+
commitProof.admission !== 'accepted' ||
|
|
214
|
+
!admission.proof ||
|
|
215
|
+
derivativeSubmitIdentity(commitProof) !==
|
|
216
|
+
derivativeSubmitIdentity(admission.proof)) {
|
|
217
|
+
problems.push({
|
|
218
|
+
code: 'COMMIT_REPORT_INCOMPLETE',
|
|
219
|
+
message: 'commit-report.json does not prove guarded derivative admission.',
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
let statusProof = null;
|
|
224
|
+
let rawStatus = null;
|
|
225
|
+
let category = 'failed';
|
|
226
|
+
if (admission.proof) {
|
|
227
|
+
try {
|
|
228
|
+
rawStatus = await readMaintenanceDerivativeRebuild({
|
|
229
|
+
context: options.context,
|
|
230
|
+
requestId: admission.proof.request_id,
|
|
231
|
+
});
|
|
232
|
+
statusProof = parseDerivativeStatusResponse(rawStatus, options.plan, admission.proof);
|
|
233
|
+
category = derivativeStatusCategory(statusProof.status);
|
|
234
|
+
}
|
|
235
|
+
catch (error) {
|
|
236
|
+
problems.push({
|
|
237
|
+
code: 'DERIVATIVE_STATUS_READ_FAILED',
|
|
238
|
+
message: 'Guarded derivative request status could not be validated.',
|
|
239
|
+
details: String(error),
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
let currentSnapshot = null;
|
|
244
|
+
try {
|
|
245
|
+
currentSnapshot = parseDerivativeSnapshotResponse(await fetchMaintenanceDerivativeSnapshot({
|
|
246
|
+
context: options.context,
|
|
247
|
+
id: action.id,
|
|
248
|
+
version: action.version,
|
|
249
|
+
}), { id: action.id, version: action.version, userId: action.expected_user_id });
|
|
250
|
+
}
|
|
251
|
+
catch (error) {
|
|
252
|
+
problems.push(issue('DERIVATIVE_SNAPSHOT_READ_FAILED', 'Fresh action-scoped derivative snapshot could not be validated.', action, String(error)));
|
|
253
|
+
}
|
|
254
|
+
if (currentSnapshot &&
|
|
255
|
+
(currentSnapshot.modified_at !== baseline.modified_at ||
|
|
256
|
+
currentSnapshot.json_sha256 !== baseline.json_sha256 ||
|
|
257
|
+
currentSnapshot.json_ordered_sha256 !== baseline.json_ordered_sha256 ||
|
|
258
|
+
currentSnapshot.extracted_text_sha256 !== baseline.extracted_text_sha256)) {
|
|
259
|
+
problems.push(issue('DERIVATIVE_PRIMARY_SNAPSHOT_DRIFT', 'Fresh derivative snapshot no longer matches frozen primary preconditions.', action));
|
|
260
|
+
}
|
|
261
|
+
if (statusProof && category === 'failed') {
|
|
262
|
+
problems.push(issue('DERIVATIVE_REQUEST_FAILED', 'The durable derivative request reached a failed terminal state. This does not prove that its primary-write fence has been released; inspect raw_evidence.', action, { status: statusProof.status, error: statusProof.error }));
|
|
263
|
+
}
|
|
264
|
+
if (statusProof && category === 'passed') {
|
|
265
|
+
const currentEmbeddingAt = currentSnapshot?.embedding_ft_at
|
|
266
|
+
? Date.parse(currentSnapshot.embedding_ft_at)
|
|
267
|
+
: Number.NaN;
|
|
268
|
+
const baselineEmbeddingAt = baseline.embedding_ft_at
|
|
269
|
+
? Date.parse(baseline.embedding_ft_at)
|
|
270
|
+
: Number.NEGATIVE_INFINITY;
|
|
271
|
+
if (!currentSnapshot ||
|
|
272
|
+
statusProof.completed_snapshot_sha256 !== currentSnapshot.snapshot_sha256 ||
|
|
273
|
+
!currentSnapshot.extracted_md_sha256 ||
|
|
274
|
+
!currentSnapshot.embedding_ft_sha256 ||
|
|
275
|
+
!Number.isFinite(currentEmbeddingAt) ||
|
|
276
|
+
currentEmbeddingAt <= baselineEmbeddingAt) {
|
|
277
|
+
problems.push(issue('DERIVATIVE_COMPLETION_PROOF_MISMATCH', 'Completed status lacks matching current markdown/vector freshness proof.', action));
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
const finalStatus = problems.length
|
|
281
|
+
? 'failed'
|
|
282
|
+
: category;
|
|
283
|
+
const actionStatus = finalStatus;
|
|
284
|
+
const report = {
|
|
285
|
+
schema_version: 1,
|
|
286
|
+
generated_at_utc: (options.now ?? new Date()).toISOString(),
|
|
287
|
+
status: finalStatus,
|
|
288
|
+
task_id: options.plan.task_id,
|
|
289
|
+
operation: options.plan.operation,
|
|
290
|
+
operation_id: options.plan.operation_id,
|
|
291
|
+
target_mode: options.plan.target_mode,
|
|
292
|
+
plan_sha256: options.plan.plan_sha256,
|
|
293
|
+
actor: {
|
|
294
|
+
user_id: options.context.account.user_id,
|
|
295
|
+
email: options.context.account.email,
|
|
296
|
+
},
|
|
297
|
+
snapshot_completeness: options.current.completeness,
|
|
298
|
+
summary: {
|
|
299
|
+
actions: 1,
|
|
300
|
+
action_checks_passed: actionStatus === 'passed' ? 1 : 0,
|
|
301
|
+
protected_rows: options.plan.protected_rows.length,
|
|
302
|
+
protected_checks_passed: protectedPassed,
|
|
303
|
+
progress_successes: 0,
|
|
304
|
+
derivative_admissions: admission.admissions,
|
|
305
|
+
derivative_request_status: statusProof?.status ?? 'unknown',
|
|
306
|
+
dangling_deleted_target_references: 0,
|
|
307
|
+
issues: problems.length,
|
|
308
|
+
},
|
|
309
|
+
action_checks: [
|
|
310
|
+
{
|
|
311
|
+
action_id: action.action_id,
|
|
312
|
+
status: actionStatus,
|
|
313
|
+
observed: actionStatus === 'passed'
|
|
314
|
+
? 'derivative_current'
|
|
315
|
+
: actionStatus === 'pending'
|
|
316
|
+
? 'derivative_pending'
|
|
317
|
+
: 'mismatch',
|
|
318
|
+
},
|
|
319
|
+
],
|
|
320
|
+
issues: problems,
|
|
321
|
+
artifacts: {
|
|
322
|
+
plan: options.planPath,
|
|
323
|
+
approval_record: options.approvalRecordPath,
|
|
324
|
+
apply_progress: options.progressPath,
|
|
325
|
+
derivative_submit_progress: options.progressPath,
|
|
326
|
+
commit_report: options.commitReportPath,
|
|
327
|
+
report: options.reportPath,
|
|
328
|
+
},
|
|
329
|
+
...(statusProof && rawStatus
|
|
330
|
+
? {
|
|
331
|
+
derivative_status: {
|
|
332
|
+
proof: statusProof,
|
|
333
|
+
raw_evidence: rawStatus,
|
|
334
|
+
note: 'raw_evidence preserves database fence and timeout state; failed does not imply the primary row is editable unless that evidence explicitly proves fence release.',
|
|
335
|
+
},
|
|
336
|
+
}
|
|
337
|
+
: {}),
|
|
338
|
+
};
|
|
339
|
+
writeJsonArtifact(options.reportPath, report);
|
|
340
|
+
return report;
|
|
341
|
+
}
|
|
53
342
|
export async function runDatasetMaintenanceVerify(options) {
|
|
54
343
|
const planPath = path.resolve(options.planPath);
|
|
55
344
|
const planDir = path.dirname(planPath);
|
|
56
345
|
const outDir = path.resolve(options.outDir ?? path.join(planDir, 'verify'));
|
|
57
346
|
const reportPath = path.join(outDir, 'readback-verify-report.json');
|
|
58
347
|
const approvalRecordPath = path.join(planDir, 'approval-record.json');
|
|
59
|
-
const
|
|
348
|
+
const plan = parseMaintenancePlan(readJsonFile(planPath, 'Maintenance plan'));
|
|
349
|
+
const progressPath = path.join(planDir, plan.operation === 'rebuild-derivatives'
|
|
350
|
+
? 'derivative-submit-progress.jsonl'
|
|
351
|
+
: 'apply-progress.jsonl');
|
|
60
352
|
const commitReportPath = path.join(planDir, 'commit-report.json');
|
|
61
353
|
const aliasPlanProgressPath = path.join(planDir, 'alias-plan-progress.jsonl');
|
|
62
354
|
const aliasBatchProgressPath = path.join(planDir, 'alias-batch-progress.jsonl');
|
|
63
355
|
const aliasExchangeProgressPath = path.join(planDir, 'alias-exchange-progress.jsonl');
|
|
64
356
|
const pageSize = normalizeMaintenancePageSize(options.pageSize);
|
|
65
|
-
const plan = parseMaintenancePlan(readJsonFile(planPath, 'Maintenance plan'));
|
|
66
357
|
const context = await resolveMaintenanceRemoteContext({
|
|
67
358
|
env: options.env,
|
|
68
359
|
fetchImpl: options.fetchImpl,
|
|
@@ -82,6 +373,20 @@ export async function runDatasetMaintenanceVerify(options) {
|
|
|
82
373
|
userId: plan.account.user_id,
|
|
83
374
|
pageSize,
|
|
84
375
|
});
|
|
376
|
+
if (plan.operation === 'rebuild-derivatives') {
|
|
377
|
+
return runDerivativeMaintenanceVerify({
|
|
378
|
+
plan,
|
|
379
|
+
planPath,
|
|
380
|
+
planDir,
|
|
381
|
+
reportPath,
|
|
382
|
+
approvalRecordPath,
|
|
383
|
+
commitReportPath,
|
|
384
|
+
progressPath,
|
|
385
|
+
context,
|
|
386
|
+
current,
|
|
387
|
+
now: options.now,
|
|
388
|
+
});
|
|
389
|
+
}
|
|
85
390
|
const currentByKey = new Map(current.rows.map((row) => [maintenanceRowKey(row), row]));
|
|
86
391
|
const actionChecks = [];
|
|
87
392
|
for (const action of plan.actions) {
|
|
@@ -480,7 +785,8 @@ export async function runDatasetMaintenanceVerify(options) {
|
|
|
480
785
|
approvalRecord.account.email !== plan.account.email ||
|
|
481
786
|
approvalRecord.confirmed_email !== plan.account.email ||
|
|
482
787
|
!isJsonObject(approvalRecord.row_counts) ||
|
|
483
|
-
sha256Json(approvalRecord.row_counts) !== sha256Json(plan.summary)
|
|
788
|
+
sha256Json(approvalRecord.row_counts) !== sha256Json(plan.summary) ||
|
|
789
|
+
!isSnapshotCompletenessCompatible(approvalRecord.snapshot_completeness, plan.snapshot_completeness, MAINTENANCE_SCAN_TABLES)) {
|
|
484
790
|
problems.push({
|
|
485
791
|
code: 'APPROVAL_RECORD_INVALID',
|
|
486
792
|
message: 'approval-record.json does not match the immutable plan and actor.',
|
|
@@ -645,6 +951,7 @@ export async function runDatasetMaintenanceVerify(options) {
|
|
|
645
951
|
target_mode: plan.target_mode,
|
|
646
952
|
plan_sha256: plan.plan_sha256,
|
|
647
953
|
actor: { user_id: context.account.user_id, email: context.account.email },
|
|
954
|
+
snapshot_completeness: current.completeness,
|
|
648
955
|
summary: {
|
|
649
956
|
actions: plan.actions.length,
|
|
650
957
|
action_checks_passed: actionChecks.filter((check) => check.status === 'passed').length,
|
|
@@ -684,7 +991,9 @@ export async function runDatasetMaintenanceVerify(options) {
|
|
|
684
991
|
}
|
|
685
992
|
export const __testInternals = {
|
|
686
993
|
deletedTargetReferences,
|
|
994
|
+
derivativeSubmitIdentity,
|
|
687
995
|
desiredPayload,
|
|
688
996
|
issue,
|
|
997
|
+
readDerivativeSubmitProof,
|
|
689
998
|
};
|
|
690
999
|
//# sourceMappingURL=dataset-maintenance-verify.js.map
|