@tiangong-lca/cli 0.0.11 → 0.0.13

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 (60) hide show
  1. package/README.md +18 -7
  2. package/assets/tidas-schemas/tidas_contacts.json +312 -0
  3. package/assets/tidas-schemas/tidas_contacts_category.json +126 -0
  4. package/assets/tidas-schemas/tidas_data_types.json +359 -0
  5. package/assets/tidas-schemas/tidas_flowproperties.json +303 -0
  6. package/assets/tidas-schemas/tidas_flowproperties_category.json +61 -0
  7. package/assets/tidas-schemas/tidas_flows.json +809 -0
  8. package/assets/tidas-schemas/tidas_flows_elementary_category.json +720 -0
  9. package/assets/tidas-schemas/tidas_flows_product_category.json +59623 -0
  10. package/assets/tidas-schemas/tidas_lciamethods.json +1326 -0
  11. package/assets/tidas-schemas/tidas_lciamethods_category.json +685 -0
  12. package/assets/tidas-schemas/tidas_lifecyclemodels.json +1374 -0
  13. package/assets/tidas-schemas/tidas_locations_category.json +2593 -0
  14. package/assets/tidas-schemas/tidas_processes.json +1646 -0
  15. package/assets/tidas-schemas/tidas_processes_category.json +10795 -0
  16. package/assets/tidas-schemas/tidas_sources.json +228 -0
  17. package/assets/tidas-schemas/tidas_sources_category.json +100 -0
  18. package/assets/tidas-schemas/tidas_unitgroups.json +338 -0
  19. package/assets/tidas-schemas/tidas_unitgroups_category.json +61 -0
  20. package/dist/src/cli.js +847 -13
  21. package/dist/src/cli.js.map +1 -1
  22. package/dist/src/lib/dataset-classification.js +947 -0
  23. package/dist/src/lib/dataset-classification.js.map +1 -0
  24. package/dist/src/lib/dataset-command.js +11 -0
  25. package/dist/src/lib/dataset-command.js.map +1 -1
  26. package/dist/src/lib/dataset-contract.js +2 -0
  27. package/dist/src/lib/dataset-contract.js.map +1 -1
  28. package/dist/src/lib/dataset-curation-queue.js +359 -2
  29. package/dist/src/lib/dataset-curation-queue.js.map +1 -1
  30. package/dist/src/lib/dataset-import-lca.js +18 -0
  31. package/dist/src/lib/dataset-import-lca.js.map +1 -1
  32. package/dist/src/lib/dataset-local.js +94 -1
  33. package/dist/src/lib/dataset-local.js.map +1 -1
  34. package/dist/src/lib/dataset-maintenance-clear-account.js +506 -0
  35. package/dist/src/lib/dataset-maintenance-clear-account.js.map +1 -0
  36. package/dist/src/lib/dataset-patch.js +797 -0
  37. package/dist/src/lib/dataset-patch.js.map +1 -0
  38. package/dist/src/lib/dataset-remote-verify.js +188 -3
  39. package/dist/src/lib/dataset-remote-verify.js.map +1 -1
  40. package/dist/src/lib/dataset-save-draft-run.js +725 -0
  41. package/dist/src/lib/dataset-save-draft-run.js.map +1 -0
  42. package/dist/src/lib/dataset-validate.js +32 -2
  43. package/dist/src/lib/dataset-validate.js.map +1 -1
  44. package/dist/src/lib/flow-publish-version.js +7 -2
  45. package/dist/src/lib/flow-publish-version.js.map +1 -1
  46. package/dist/src/lib/flow-qa.js +8 -0
  47. package/dist/src/lib/flow-qa.js.map +1 -1
  48. package/dist/src/lib/identity-preflight.js +895 -117
  49. package/dist/src/lib/identity-preflight.js.map +1 -1
  50. package/dist/src/lib/lifecyclemodel-qa.js +159 -34
  51. package/dist/src/lib/lifecyclemodel-qa.js.map +1 -1
  52. package/dist/src/lib/process-required-fields.js +62 -12
  53. package/dist/src/lib/process-required-fields.js.map +1 -1
  54. package/dist/src/lib/process-save-draft-run.js +10 -0
  55. package/dist/src/lib/process-save-draft-run.js.map +1 -1
  56. package/dist/src/lib/process-save-draft.js +59 -3
  57. package/dist/src/lib/process-save-draft.js.map +1 -1
  58. package/dist/src/lib/supabase-client.js +19 -8
  59. package/dist/src/lib/supabase-client.js.map +1 -1
  60. package/package.json +2 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dataset-patch.js","sourceRoot":"","sources":["../../../src/lib/dataset-patch.ts"],"names":[],"mappings":"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","sourcesContent":["import crypto from 'node:crypto';\nimport { existsSync, readFileSync } from 'node:fs';\nimport path from 'node:path';\nimport { isDeepStrictEqual } from 'node:util';\nimport { writeJsonArtifact, writeJsonLinesArtifact } from './artifacts.js';\nimport {\n cloneJson,\n isRecord,\n materializeDatasetRows,\n trimToken,\n type JsonObject,\n} from './dataset-local.js';\nimport { CliError } from './errors.js';\nimport { readJsonInput } from './io.js';\n\ntype PatchApplyStatus = 'completed' | 'blocked';\ntype PatchOperationName = 'add' | 'remove' | 'replace' | 'test';\n\nexport type DatasetPatchEvidence =\n | string\n | {\n source?: string | null;\n quote?: string | null;\n path?: string | null;\n package?: string | null;\n reasoning?: string | null;\n trace_hash?: string | null;\n [key: string]: unknown;\n }\n | unknown[]\n | null;\n\nexport type DatasetPatchOperation = {\n op: PatchOperationName | string;\n path: string;\n value?: unknown;\n evidence?: DatasetPatchEvidence;\n basis?: string | null;\n resolution?: unknown;\n closes?: unknown;\n closes_action_items?: unknown;\n closesActionItems?: unknown;\n action_items?: unknown;\n actionItems?: unknown;\n};\n\nexport type DatasetPatchSet = {\n row_index?: number | string | null;\n dataset_id?: string | null;\n id?: string | null;\n uuid?: string | null;\n entity_id?: string | null;\n version?: string | null;\n dataset_version?: string | null;\n authoring_package?: string | null;\n operations?: DatasetPatchOperation[];\n patches?: DatasetPatchOperation[];\n};\n\nexport type DatasetPatchApplyBlocker = {\n code: string;\n message: string;\n row_index?: number;\n dataset_id?: string | null;\n dataset_version?: string | null;\n patch_index?: number;\n operation_index?: number;\n op?: string;\n path?: string;\n};\n\nexport type DatasetPatchEvidenceEntry = {\n row_index: number;\n dataset_id: string | null;\n dataset_version: string | null;\n patch_index: number;\n operation_index: number;\n op: PatchOperationName;\n path: string;\n basis: string | null;\n evidence: DatasetPatchEvidence;\n resolution?: unknown;\n authoring_package: string | null;\n authoring_package_sha256?: string | null;\n closes_action_items?: ActionItemClosure[];\n};\n\nexport type DatasetPatchApplyReport = {\n schema_version: 1;\n generated_at_utc: string;\n input_path: string;\n patch_path: string;\n out_path: string;\n status: PatchApplyStatus;\n row_count: number;\n patch_count: number;\n operation_count: number;\n applied_operation_count: number;\n evidence_count: number;\n closed_action_item_count?: number;\n blockers: DatasetPatchApplyBlocker[];\n files: {\n patched_rows: string;\n patch_evidence: string | null;\n report: string | null;\n };\n};\n\nexport type RunDatasetPatchApplyOptions = {\n inputPath: string;\n patchPath: string;\n outPath: string;\n outDir?: string | null;\n rawInput?: unknown;\n rawPatch?: unknown;\n authoringPackageDir?: string | null;\n requireAuthoringPackage?: boolean;\n requireActionItemClosure?: boolean;\n now?: Date;\n};\n\ntype NormalizedPatchSet = {\n rowIndex: number | null;\n datasetId: string | null;\n datasetVersion: string | null;\n authoringPackage: string | null;\n operations: DatasetPatchOperation[];\n};\n\ntype AuthoringPackageContext = {\n path: string;\n sha256: string;\n payload: JsonObject;\n actionItems: ActionItemClosure[];\n};\n\ntype ActionItemClosure = {\n code: string;\n path: string | null;\n};\n\ntype NormalizePatchResult = {\n patches: NormalizedPatchSet[];\n blockers: DatasetPatchApplyBlocker[];\n};\n\ntype PatchTarget = {\n container: JsonObject | unknown[];\n key: string | number;\n};\n\nconst decisionOnlyActionKinds = new Set([\n 'identity_decision_authoring',\n 'classification_decision_authoring',\n 'location_decision_authoring',\n]);\n\nfunction nowIso(now?: Date): string {\n return (now ?? new Date()).toISOString();\n}\n\nfunction hasOwn(value: object, key: string): boolean {\n return Object.prototype.hasOwnProperty.call(value, key);\n}\n\nfunction parseRowIndex(value: unknown): number | null {\n if (typeof value === 'number' && Number.isInteger(value) && value >= 0) {\n return value;\n }\n if (typeof value === 'string' && /^\\d+$/u.test(value)) {\n return Number.parseInt(value, 10);\n }\n return null;\n}\n\nfunction nonEmptyString(value: unknown): string | null {\n return trimToken(value);\n}\n\nfunction sha256Text(value: string): string {\n return crypto.createHash('sha256').update(value).digest('hex');\n}\n\nfunction caughtErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction normalizeClosure(value: unknown): ActionItemClosure | null {\n if (typeof value === 'string') {\n const code = value.trim();\n return code ? { code, path: null } : null;\n }\n if (!isRecord(value)) {\n return null;\n }\n const code =\n nonEmptyString(value.code) ??\n nonEmptyString(value.action_item_code) ??\n nonEmptyString(value.actionItemCode) ??\n nonEmptyString(value.rule_id) ??\n nonEmptyString(value.ruleId);\n if (!code) {\n return null;\n }\n return {\n code,\n path:\n nonEmptyString(value.path) ??\n nonEmptyString(value.json_path) ??\n nonEmptyString(value.jsonPath) ??\n null,\n };\n}\n\nfunction actionItemClosureKey(value: ActionItemClosure): string {\n return `${value.code}\\u0000${value.path ?? ''}`;\n}\n\nfunction normalizeClosureList(value: unknown): ActionItemClosure[] {\n const values = Array.isArray(value)\n ? value\n : value === undefined || value === null\n ? []\n : [value];\n const closures = values\n .map(normalizeClosure)\n .filter((closure): closure is ActionItemClosure => closure !== null);\n return [...new Map(closures.map((closure) => [actionItemClosureKey(closure), closure])).values()];\n}\n\nfunction operationClosures(operation: DatasetPatchOperation): ActionItemClosure[] {\n return normalizeClosureList(\n operation.closes ??\n operation.closes_action_items ??\n operation.closesActionItems ??\n operation.action_items ??\n operation.actionItems,\n );\n}\n\nfunction actionItemFromPackage(value: unknown): ActionItemClosure | null {\n if (!isRecord(value) || value.ai_required === false) {\n return null;\n }\n const actionKind = nonEmptyString(value.action_kind) ?? nonEmptyString(value.actionKind);\n if (actionKind && decisionOnlyActionKinds.has(actionKind)) {\n return null;\n }\n const code =\n nonEmptyString(value.code) ?? nonEmptyString(value.rule_id) ?? nonEmptyString(value.ruleId);\n if (!code) {\n return null;\n }\n return {\n code,\n path: nonEmptyString(value.path) ?? null,\n };\n}\n\nfunction closureMatchesActionItem(\n closure: ActionItemClosure,\n actionItem: ActionItemClosure,\n): boolean {\n return (\n closure.code === actionItem.code &&\n (!closure.path || !actionItem.path || closure.path === actionItem.path)\n );\n}\n\nfunction normalizeOperationArray(value: unknown): DatasetPatchOperation[] | null {\n if (!Array.isArray(value)) {\n return null;\n }\n if (!value.every(looksLikeOperation)) {\n return null;\n }\n return value as DatasetPatchOperation[];\n}\n\nfunction looksLikeOperation(value: unknown): boolean {\n return isRecord(value) && typeof value.op === 'string' && typeof value.path === 'string';\n}\n\nfunction normalizePatchSet(value: unknown): NormalizedPatchSet | null {\n if (!isRecord(value)) {\n return null;\n }\n const operations =\n normalizeOperationArray(value.operations) ?? normalizeOperationArray(value.patches);\n if (!operations) {\n return null;\n }\n return {\n rowIndex: parseRowIndex(value.row_index ?? value.rowIndex),\n datasetId:\n nonEmptyString(value.dataset_id) ??\n nonEmptyString(value.id) ??\n nonEmptyString(value.uuid) ??\n nonEmptyString(value.entity_id),\n datasetVersion: nonEmptyString(value.dataset_version) ?? nonEmptyString(value.version),\n authoringPackage:\n nonEmptyString(value.authoring_package) ?? nonEmptyString(value.authoringPackage),\n operations,\n };\n}\n\nfunction patchPayloadCompletionStatus(rawPatch: unknown): string | null {\n if (typeof rawPatch !== 'object' || rawPatch === null) {\n return null;\n }\n const value = rawPatch as Record<string, unknown>;\n return (\n nonEmptyString(value.patch_status) ??\n nonEmptyString(value.patchStatus) ??\n nonEmptyString(value.status)\n );\n}\n\nfunction normalizePatchPayload(rawPatch: unknown): NormalizePatchResult {\n const blockers: DatasetPatchApplyBlocker[] = [];\n const patches: NormalizedPatchSet[] = [];\n const addPatchSet = (value: unknown, patchIndex: number): void => {\n const patch = normalizePatchSet(value);\n if (patch) {\n patches.push(patch);\n return;\n }\n blockers.push({\n code: 'patch_set_invalid',\n message: 'Patch set must be an object with row_index or dataset_id and operations[].',\n patch_index: patchIndex,\n });\n };\n\n const patchStatus = patchPayloadCompletionStatus(rawPatch);\n if (patchStatus !== 'completed') {\n blockers.push({\n code: 'ai_patch_status_not_completed',\n message: 'Patch payload must declare patch_status=completed before deterministic apply.',\n });\n return { patches, blockers };\n }\n\n if (Array.isArray(rawPatch)) {\n if (rawPatch.every(looksLikeOperation)) {\n blockers.push({\n code: 'patch_row_required',\n message: 'Top-level operation arrays are not supported because they do not identify a row.',\n });\n return { patches, blockers };\n }\n rawPatch.forEach(addPatchSet);\n return { patches, blockers };\n }\n\n const patchObject = rawPatch as JsonObject;\n const directPatch = normalizePatchSet(patchObject);\n if (directPatch) {\n patches.push(directPatch);\n return { patches, blockers };\n }\n\n const candidateList =\n (Array.isArray(patchObject.patch_sets) ? patchObject.patch_sets : null) ??\n (Array.isArray(patchObject.patches) ? patchObject.patches : null) ??\n (Array.isArray(patchObject.suggestions) ? patchObject.suggestions : null) ??\n (Array.isArray(patchObject.items) ? patchObject.items : null);\n\n if (candidateList) {\n if (candidateList.every(looksLikeOperation)) {\n blockers.push({\n code: 'patch_row_required',\n message: 'Top-level operation arrays are not supported because they do not identify a row.',\n });\n return { patches, blockers };\n }\n candidateList.forEach(addPatchSet);\n return { patches, blockers };\n }\n\n blockers.push({\n code: 'patch_payload_invalid',\n message:\n 'Patch payload must contain operations[], patches[], patch_sets[], suggestions[], or items[].',\n });\n return { patches, blockers };\n}\n\nfunction decodePointerToken(token: string): string {\n if (/(^|[^~])~([^01]|$)/u.test(token)) {\n throw new Error(`Invalid JSON Pointer escape in token: ${token}`);\n }\n return token.replace(/~1/gu, '/').replace(/~0/gu, '~');\n}\n\nfunction parsePointer(pointer: unknown): string[] {\n if (typeof pointer !== 'string' || !pointer.startsWith('/')) {\n throw new Error('Patch path must be a JSON Pointer starting with /.');\n }\n return pointer\n .slice(1)\n .split('/')\n .map((token) => decodePointerToken(token));\n}\n\nfunction parseArrayIndex(token: string, length: number, allowAppend: boolean): number {\n if (allowAppend && token === '-') {\n return length;\n }\n if (!/^(0|[1-9]\\d*)$/u.test(token)) {\n throw new Error(`Expected array index, got ${token}.`);\n }\n const index = Number.parseInt(token, 10);\n if (index < 0 || index > length || (!allowAppend && index === length)) {\n throw new Error(`Array index out of bounds: ${token}.`);\n }\n return index;\n}\n\nfunction resolvePatchTarget(root: JsonObject, pointer: string, allowAdd: boolean): PatchTarget {\n const tokens = parsePointer(pointer);\n let current: unknown = root;\n for (const token of tokens.slice(0, -1)) {\n if (Array.isArray(current)) {\n current = current[parseArrayIndex(token, current.length, false)];\n continue;\n }\n if (isRecord(current)) {\n if (!hasOwn(current, token)) {\n throw new Error(`Patch parent path does not exist at ${token}.`);\n }\n current = current[token];\n continue;\n }\n throw new Error(`Patch parent is not an object or array at ${token}.`);\n }\n\n const keyToken = tokens[tokens.length - 1]!;\n if (Array.isArray(current)) {\n return {\n container: current,\n key: parseArrayIndex(keyToken, current.length, allowAdd),\n };\n }\n if (isRecord(current)) {\n return { container: current, key: keyToken };\n }\n throw new Error('Patch parent is not an object or array.');\n}\n\nfunction targetExists(target: PatchTarget): boolean {\n if (Array.isArray(target.container)) {\n return (\n typeof target.key === 'number' && target.key >= 0 && target.key < target.container.length\n );\n }\n return typeof target.key === 'string' && hasOwn(target.container, target.key);\n}\n\nfunction getTargetValue(target: PatchTarget): unknown {\n if (!targetExists(target)) {\n throw new Error('Patch target path does not exist.');\n }\n return target.container[target.key as never];\n}\n\nfunction setTargetValue(target: PatchTarget, value: unknown, insert: boolean): void {\n if (Array.isArray(target.container)) {\n const index = target.key as number;\n if (insert) {\n target.container.splice(index, 0, value);\n return;\n }\n target.container[index] = value;\n return;\n }\n target.container[target.key as string] = value;\n}\n\nfunction removeTargetValue(target: PatchTarget): void {\n if (!targetExists(target)) {\n throw new Error('Patch target path does not exist.');\n }\n if (Array.isArray(target.container)) {\n target.container.splice(target.key as number, 1);\n return;\n }\n delete target.container[target.key as string];\n}\n\nfunction evidenceIsPresent(evidence: unknown): boolean {\n if (typeof evidence === 'string') {\n return evidence.trim().length > 0;\n }\n if (Array.isArray(evidence)) {\n return evidence.length > 0;\n }\n if (isRecord(evidence)) {\n return Object.keys(evidence).length > 0;\n }\n return false;\n}\n\nfunction operationBasis(operation: DatasetPatchOperation): string | null {\n return nonEmptyString(operation.basis);\n}\n\nfunction requiresEvidence(operation: DatasetPatchOperation): boolean {\n return operation.op !== 'test';\n}\n\nfunction validateOperationShape(\n operation: DatasetPatchOperation,\n patchIndex: number,\n operationIndex: number,\n rowIndex: number,\n datasetId: string | null,\n datasetVersion: string | null,\n): DatasetPatchApplyBlocker | null {\n if (!['add', 'remove', 'replace', 'test'].includes(operation.op)) {\n return {\n code: 'patch_operation_unsupported',\n message: `Unsupported patch operation: ${operation.op}`,\n row_index: rowIndex,\n dataset_id: datasetId,\n dataset_version: datasetVersion,\n patch_index: patchIndex,\n operation_index: operationIndex,\n op: operation.op,\n path: operation.path,\n };\n }\n if (typeof operation.path !== 'string' || !operation.path.startsWith('/')) {\n return {\n code: 'patch_path_invalid',\n message: 'Patch operation path must be a JSON Pointer starting with /.',\n row_index: rowIndex,\n dataset_id: datasetId,\n dataset_version: datasetVersion,\n patch_index: patchIndex,\n operation_index: operationIndex,\n op: operation.op,\n path: operation.path,\n };\n }\n if (['add', 'replace', 'test'].includes(operation.op) && !hasOwn(operation, 'value')) {\n return {\n code: 'patch_value_required',\n message: `${operation.op} operation requires value.`,\n row_index: rowIndex,\n dataset_id: datasetId,\n dataset_version: datasetVersion,\n patch_index: patchIndex,\n operation_index: operationIndex,\n op: operation.op,\n path: operation.path,\n };\n }\n if (\n requiresEvidence(operation) &&\n !operationBasis(operation) &&\n !evidenceIsPresent(operation.evidence)\n ) {\n return {\n code: 'patch_evidence_required',\n message: 'Non-test patch operations require basis or evidence.',\n row_index: rowIndex,\n dataset_id: datasetId,\n dataset_version: datasetVersion,\n patch_index: patchIndex,\n operation_index: operationIndex,\n op: operation.op,\n path: operation.path,\n };\n }\n return null;\n}\n\nfunction applyOperation(root: JsonObject, operation: DatasetPatchOperation): void {\n const op = operation.op as PatchOperationName;\n const target = resolvePatchTarget(root, operation.path, op === 'add');\n if (op === 'test') {\n const actual = getTargetValue(target);\n if (!isDeepStrictEqual(actual, operation.value)) {\n throw new Error('Patch test failed.');\n }\n return;\n }\n if (op === 'remove') {\n removeTargetValue(target);\n return;\n }\n if (op === 'replace') {\n if (!targetExists(target)) {\n throw new Error('Patch target path does not exist.');\n }\n setTargetValue(target, operation.value, false);\n return;\n }\n setTargetValue(target, operation.value, Array.isArray(target.container));\n}\n\nfunction findTargetRow(\n patch: NormalizedPatchSet,\n rows: ReturnType<typeof materializeDatasetRows>,\n patchIndex: number,\n): { rowIndex: number; blocker: null } | { rowIndex: null; blocker: DatasetPatchApplyBlocker } {\n if (patch.rowIndex !== null) {\n if (patch.rowIndex >= rows.length) {\n return {\n rowIndex: null,\n blocker: {\n code: 'patch_row_index_invalid',\n message: `Patch row_index ${patch.rowIndex} is outside input row count ${rows.length}.`,\n row_index: patch.rowIndex,\n dataset_id: patch.datasetId,\n dataset_version: patch.datasetVersion,\n patch_index: patchIndex,\n },\n };\n }\n const row = rows[patch.rowIndex];\n if (patch.datasetId && row?.id !== patch.datasetId) {\n return {\n rowIndex: null,\n blocker: {\n code: 'patch_dataset_id_mismatch',\n message: `Patch dataset_id ${patch.datasetId} does not match row_index ${patch.rowIndex}.`,\n row_index: patch.rowIndex,\n dataset_id: patch.datasetId,\n dataset_version: patch.datasetVersion,\n patch_index: patchIndex,\n },\n };\n }\n if (patch.datasetVersion && row?.version !== patch.datasetVersion) {\n return {\n rowIndex: null,\n blocker: {\n code: 'patch_dataset_version_mismatch',\n message: `Patch dataset_version ${patch.datasetVersion} does not match row_index ${patch.rowIndex}.`,\n row_index: patch.rowIndex,\n dataset_id: patch.datasetId,\n dataset_version: patch.datasetVersion,\n patch_index: patchIndex,\n },\n };\n }\n return { rowIndex: patch.rowIndex, blocker: null };\n }\n\n if (!patch.datasetId) {\n return {\n rowIndex: null,\n blocker: {\n code: 'patch_row_required',\n message: 'Patch set must identify a target row by row_index or dataset_id.',\n dataset_id: patch.datasetId,\n dataset_version: patch.datasetVersion,\n patch_index: patchIndex,\n },\n };\n }\n\n const matches = rows.filter(\n (row) =>\n row.id === patch.datasetId && (!patch.datasetVersion || row.version === patch.datasetVersion),\n );\n if (matches.length === 0) {\n return {\n rowIndex: null,\n blocker: {\n code: 'patch_dataset_not_found',\n message: `No input row matched dataset_id ${patch.datasetId}.`,\n dataset_id: patch.datasetId,\n dataset_version: patch.datasetVersion,\n patch_index: patchIndex,\n },\n };\n }\n if (matches.length > 1) {\n return {\n rowIndex: null,\n blocker: {\n code: 'patch_dataset_ambiguous',\n message: `Multiple input rows matched dataset_id ${patch.datasetId}; use row_index or dataset_version.`,\n dataset_id: patch.datasetId,\n dataset_version: patch.datasetVersion,\n patch_index: patchIndex,\n },\n };\n }\n return { rowIndex: matches[0]!.index, blocker: null };\n}\n\nfunction resolveAuthoringPackagePath(\n authoringPackage: string | null,\n authoringPackageDir: string | null | undefined,\n): string | null {\n if (!authoringPackage) {\n return null;\n }\n const directPath = path.resolve(authoringPackage);\n if (existsSync(directPath)) {\n return directPath;\n }\n if (authoringPackageDir) {\n const fromDir = path.resolve(authoringPackageDir, authoringPackage);\n if (existsSync(fromDir)) {\n return fromDir;\n }\n const byBasename = path.resolve(authoringPackageDir, path.basename(authoringPackage));\n if (existsSync(byBasename)) {\n return byBasename;\n }\n }\n return directPath;\n}\n\nfunction readAuthoringPackageContext(options: {\n patch: NormalizedPatchSet;\n rowIndex: number;\n rowId: string | null | undefined;\n rowVersion: string | null | undefined;\n patchIndex: number;\n authoringPackageDir?: string | null;\n requireAuthoringPackage?: boolean;\n}): { context: AuthoringPackageContext | null; blockers: DatasetPatchApplyBlocker[] } {\n const blockers: DatasetPatchApplyBlocker[] = [];\n const packagePath = resolveAuthoringPackagePath(\n options.patch.authoringPackage,\n options.authoringPackageDir,\n );\n if (!packagePath) {\n if (options.requireAuthoringPackage) {\n blockers.push({\n code: 'authoring_package_required',\n message: 'Strict patch apply requires each patch set to identify an authoring_package.',\n row_index: options.rowIndex,\n dataset_id: options.rowId,\n dataset_version: options.rowVersion,\n patch_index: options.patchIndex,\n });\n }\n return { context: null, blockers };\n }\n if (!existsSync(packagePath)) {\n blockers.push({\n code: 'authoring_package_not_found',\n message: `Authoring package was not found: ${packagePath}`,\n row_index: options.rowIndex,\n dataset_id: options.rowId,\n dataset_version: options.rowVersion,\n patch_index: options.patchIndex,\n });\n return { context: null, blockers };\n }\n\n let rawText: string;\n let payload: unknown;\n try {\n rawText = readFileSync(packagePath, 'utf8');\n payload = JSON.parse(rawText);\n } catch (error) {\n blockers.push({\n code: 'authoring_package_invalid',\n message: caughtErrorMessage(error),\n row_index: options.rowIndex,\n dataset_id: options.rowId,\n dataset_version: options.rowVersion,\n patch_index: options.patchIndex,\n });\n return { context: null, blockers };\n }\n if (!isRecord(payload)) {\n blockers.push({\n code: 'authoring_package_invalid',\n message: 'Authoring package must be a JSON object.',\n row_index: options.rowIndex,\n dataset_id: options.rowId,\n dataset_version: options.rowVersion,\n patch_index: options.patchIndex,\n });\n return { context: null, blockers };\n }\n\n const packageEntityId = nonEmptyString(payload.entity_id) ?? nonEmptyString(payload.process_id);\n const packageVersion = nonEmptyString(payload.version);\n const rowId = nonEmptyString(options.rowId) ?? options.patch.datasetId;\n const rowVersion = nonEmptyString(options.rowVersion) ?? options.patch.datasetVersion;\n if (packageEntityId && rowId && packageEntityId !== rowId) {\n blockers.push({\n code: 'authoring_package_entity_mismatch',\n message: `Authoring package entity_id ${packageEntityId} does not match target row ${rowId}.`,\n row_index: options.rowIndex,\n dataset_id: rowId,\n dataset_version: rowVersion,\n patch_index: options.patchIndex,\n });\n }\n if (packageVersion && rowVersion && packageVersion !== rowVersion) {\n blockers.push({\n code: 'authoring_package_version_mismatch',\n message: `Authoring package version ${packageVersion} does not match target row ${rowVersion}.`,\n row_index: options.rowIndex,\n dataset_id: rowId,\n dataset_version: rowVersion,\n patch_index: options.patchIndex,\n });\n }\n\n const actionItems = normalizeClosureList(\n (Array.isArray(payload.action_items) ? payload.action_items : [])\n .map(actionItemFromPackage)\n .filter((item): item is ActionItemClosure => item !== null),\n );\n return {\n context: {\n path: packagePath,\n sha256: sha256Text(rawText),\n payload,\n actionItems,\n },\n blockers,\n };\n}\n\nexport async function runDatasetPatchApply(\n options: RunDatasetPatchApplyOptions,\n): Promise<DatasetPatchApplyReport> {\n if (!options.inputPath) {\n throw new CliError('Missing required --input value.', {\n code: 'DATASET_PATCH_INPUT_REQUIRED',\n exitCode: 2,\n });\n }\n if (!options.patchPath) {\n throw new CliError('Missing required --patch value.', {\n code: 'DATASET_PATCH_PATCH_REQUIRED',\n exitCode: 2,\n });\n }\n if (!options.outPath) {\n throw new CliError('Missing required --out value.', {\n code: 'DATASET_PATCH_OUT_REQUIRED',\n exitCode: 2,\n });\n }\n\n const rows = materializeDatasetRows(options.inputPath, options.rawInput);\n const originalRows = rows.map((row) => cloneJson(row.row));\n const candidateRows = rows.map((row) => cloneJson(row.row));\n const rawPatch = options.rawPatch ?? readJsonInput(path.resolve(options.patchPath));\n const normalized = normalizePatchPayload(rawPatch);\n const blockers = [...normalized.blockers];\n const evidenceEntries: DatasetPatchEvidenceEntry[] = [];\n let operationCount = 0;\n let tentativeAppliedCount = 0;\n\n normalized.patches.forEach((patch, patchIndex) => {\n operationCount += patch.operations.length;\n const target = findTargetRow(patch, rows, patchIndex);\n if (target.blocker) {\n blockers.push(target.blocker);\n return;\n }\n\n const rowIndex = target.rowIndex;\n const row = rows[rowIndex]!;\n const rowId = row.id ?? patch.datasetId;\n const rowVersion = row.version ?? patch.datasetVersion;\n if (patch.operations.length === 0) {\n blockers.push({\n code: 'patch_operations_missing',\n message: 'Patch set operations[] must not be empty.',\n row_index: rowIndex,\n dataset_id: rowId,\n dataset_version: rowVersion,\n patch_index: patchIndex,\n });\n return;\n }\n\n const candidateRow = candidateRows[rowIndex] as JsonObject;\n const shouldValidateAuthoringPackage =\n Boolean(options.authoringPackageDir) ||\n options.requireAuthoringPackage === true ||\n options.requireActionItemClosure === true;\n const packageResult = shouldValidateAuthoringPackage\n ? readAuthoringPackageContext({\n patch,\n rowIndex,\n rowId: row.id,\n rowVersion: row.version,\n patchIndex,\n authoringPackageDir: options.authoringPackageDir,\n requireAuthoringPackage:\n options.requireAuthoringPackage === true || options.requireActionItemClosure === true,\n })\n : { context: null, blockers: [] };\n blockers.push(...packageResult.blockers);\n if (packageResult.blockers.length > 0) {\n return;\n }\n const packageContext = packageResult.context;\n const closedActionItems: ActionItemClosure[] = [];\n\n patch.operations.forEach((operation, operationIndex) => {\n const shapeBlocker = validateOperationShape(\n operation,\n patchIndex,\n operationIndex,\n rowIndex,\n rowId,\n rowVersion,\n );\n if (shapeBlocker) {\n blockers.push(shapeBlocker);\n return;\n }\n const closesActionItems = operationClosures(operation);\n if (options.requireActionItemClosure === true && packageContext) {\n for (const closure of closesActionItems) {\n if (!packageContext.actionItems.some((item) => closureMatchesActionItem(closure, item))) {\n blockers.push({\n code: 'authoring_action_item_unknown',\n message: `Patch operation closes unknown authoring action item ${closure.code}.`,\n row_index: rowIndex,\n dataset_id: rowId,\n dataset_version: rowVersion,\n patch_index: patchIndex,\n operation_index: operationIndex,\n op: operation.op,\n path: operation.path,\n });\n }\n }\n }\n closedActionItems.push(...closesActionItems);\n\n try {\n applyOperation(candidateRow, operation);\n tentativeAppliedCount += operation.op === 'test' ? 0 : 1;\n if (operation.op !== 'test') {\n evidenceEntries.push({\n row_index: rowIndex,\n dataset_id: rowId,\n dataset_version: rowVersion,\n patch_index: patchIndex,\n operation_index: operationIndex,\n op: operation.op as PatchOperationName,\n path: operation.path,\n basis: operationBasis(operation),\n evidence: operation.evidence ?? null,\n resolution: operation.resolution ?? null,\n authoring_package: patch.authoringPackage,\n authoring_package_sha256: packageContext?.sha256 ?? null,\n closes_action_items: closesActionItems,\n });\n }\n } catch (error) {\n blockers.push({\n code: operation.op === 'test' ? 'patch_test_failed' : 'patch_apply_failed',\n message: caughtErrorMessage(error),\n row_index: rowIndex,\n dataset_id: rowId,\n dataset_version: rowVersion,\n patch_index: patchIndex,\n operation_index: operationIndex,\n op: operation.op,\n path: operation.path,\n });\n }\n });\n if (options.requireActionItemClosure === true && packageContext) {\n for (const actionItem of packageContext.actionItems) {\n if (!closedActionItems.some((closure) => closureMatchesActionItem(closure, actionItem))) {\n blockers.push({\n code: 'authoring_action_item_unclosed',\n message: `Authoring action item ${actionItem.code} was not closed by the AI patch set.`,\n row_index: rowIndex,\n dataset_id: rowId,\n dataset_version: rowVersion,\n patch_index: patchIndex,\n path: actionItem.path ?? undefined,\n });\n }\n }\n }\n });\n\n const resolvedOut = path.resolve(options.outPath);\n const resolvedOutDir = options.outDir ? path.resolve(options.outDir) : path.dirname(resolvedOut);\n const evidenceFile = path.join(resolvedOutDir, 'outputs', 'patch-evidence.jsonl');\n const reportFile = path.join(resolvedOutDir, 'outputs', 'dataset-patch-apply-report.json');\n const status: PatchApplyStatus = blockers.length > 0 ? 'blocked' : 'completed';\n const outputRows = status === 'completed' ? candidateRows : originalRows;\n\n writeJsonLinesArtifact(resolvedOut, outputRows);\n writeJsonLinesArtifact(evidenceFile, status === 'completed' ? evidenceEntries : []);\n\n const report: DatasetPatchApplyReport = {\n schema_version: 1,\n generated_at_utc: nowIso(options.now),\n input_path: options.inputPath,\n patch_path: options.patchPath,\n out_path: resolvedOut,\n status,\n row_count: rows.length,\n patch_count: normalized.patches.length,\n operation_count: operationCount,\n applied_operation_count: status === 'completed' ? tentativeAppliedCount : 0,\n evidence_count: status === 'completed' ? evidenceEntries.length : 0,\n closed_action_item_count:\n status === 'completed'\n ? evidenceEntries.reduce((total, entry) => total + entry.closes_action_items!.length, 0)\n : 0,\n blockers,\n files: {\n patched_rows: resolvedOut,\n patch_evidence: evidenceFile,\n report: reportFile,\n },\n };\n\n writeJsonArtifact(reportFile, report);\n return report;\n}\n\nexport const __testInternals = {\n actionItemFromPackage,\n applyOperation,\n closureMatchesActionItem,\n caughtErrorMessage,\n evidenceIsPresent,\n findTargetRow,\n getTargetValue,\n looksLikeOperation,\n normalizeClosure,\n normalizeClosureList,\n normalizeOperationArray,\n normalizePatchPayload,\n normalizePatchSet,\n operationBasis,\n operationClosures,\n parseArrayIndex,\n parsePointer,\n parseRowIndex,\n patchPayloadCompletionStatus,\n readAuthoringPackageContext,\n removeTargetValue,\n resolveAuthoringPackagePath,\n resolvePatchTarget,\n setTargetValue,\n targetExists,\n validateOperationShape,\n};\n"]}
@@ -1,3 +1,4 @@
1
+ import crypto from 'node:crypto';
1
2
  import path from 'node:path';
2
3
  import { writeJsonArtifact, writeJsonLinesArtifact } from './artifacts.js';
3
4
  import { CliError } from './errors.js';
@@ -40,7 +41,7 @@ const ROOT_DATASET_DESCRIPTORS = [
40
41
  wrapper: 'flowPropertyDataSet',
41
42
  table: 'flowproperties',
42
43
  type: 'flow property data set',
43
- information_key: 'flowPropertyInformation',
44
+ information_key: 'flowPropertiesInformation',
44
45
  },
45
46
  {
46
47
  wrapper: 'unitGroupDataSet',
@@ -108,6 +109,10 @@ const EMPTY_STATUS_COUNTS = {
108
109
  lookup_failed: 0,
109
110
  missing_dataset: 0,
110
111
  missing_version: 0,
112
+ owner_mismatch: 0,
113
+ payload_mismatch: 0,
114
+ remote_payload_missing: 0,
115
+ state_code_mismatch: 0,
111
116
  unsupported_type: 0,
112
117
  version_missing: 0,
113
118
  version_outdated: 0,
@@ -174,6 +179,14 @@ function pointerPath(basePath, segment) {
174
179
  const encoded = String(segment).replace(/~/gu, '~0').replace(/\//gu, '~1');
175
180
  return `${basePath}/${encoded}`;
176
181
  }
182
+ function unescapePointerSegment(segment) {
183
+ return segment.replace(/~1/gu, '/').replace(/~0/gu, '~');
184
+ }
185
+ function isFoundryTracePath(pathExpression) {
186
+ const segments = pathExpression.split('/').filter(Boolean).map(unescapePointerSegment);
187
+ return (segments.includes('common:other') &&
188
+ segments.some((segment) => segment.startsWith('tiangongfoundry:') && segment.toLowerCase().includes('trace')));
189
+ }
177
190
  function rootOf(payload) {
178
191
  for (const descriptor of ROOT_DATASET_DESCRIPTORS) {
179
192
  if (isRecord(payload[descriptor.wrapper])) {
@@ -244,6 +257,9 @@ function flowReferenceFromRecord(rowIndex, value, pathExpression) {
244
257
  : null;
245
258
  }
246
259
  function collectReferencesFromValue(rowIndex, value, pathExpression, references) {
260
+ if (isFoundryTracePath(pathExpression)) {
261
+ return;
262
+ }
247
263
  if (Array.isArray(value)) {
248
264
  value.forEach((entry, index) => collectReferencesFromValue(rowIndex, entry, pointerPath(pathExpression, index), references));
249
265
  return;
@@ -263,7 +279,7 @@ function collectReferencesFromValue(rowIndex, value, pathExpression, references)
263
279
  collectReferencesFromValue(rowIndex, nested, pointerPath(pathExpression, key), references);
264
280
  }
265
281
  }
266
- function collectRemoteReferences(rows) {
282
+ export function collectRemoteReferences(rows) {
267
283
  const references = [];
268
284
  rows.forEach((row, index) => {
269
285
  const payload = unwrapDatasetPayload(row);
@@ -330,7 +346,50 @@ function normalizeRows(value) {
330
346
  .filter((row) => Boolean(row.id))
331
347
  : [];
332
348
  }
333
- async function lookupRemoteDataset(options) {
349
+ function stableJson(value) {
350
+ if (Array.isArray(value)) {
351
+ return value.map(stableJson);
352
+ }
353
+ if (isRecord(value)) {
354
+ return Object.fromEntries(Object.keys(value)
355
+ .sort()
356
+ .map((key) => [key, stableJson(value[key])]));
357
+ }
358
+ return value;
359
+ }
360
+ function sha256Json(value) {
361
+ return crypto
362
+ .createHash('sha256')
363
+ .update(JSON.stringify(stableJson(value)))
364
+ .digest('hex');
365
+ }
366
+ function buildRemotePayloadUrl(restBaseUrl, table, id, version) {
367
+ const url = new URL(`${restBaseUrl.replace(/\/+$/u, '')}/${table}`);
368
+ url.searchParams.set('select', 'id,version,user_id,state_code,modified_at,json,json_ordered');
369
+ url.searchParams.set('id', `eq.${id}`);
370
+ url.searchParams.set('version', `eq.${version}`);
371
+ return url.toString();
372
+ }
373
+ function normalizePayloadRow(value) {
374
+ if (!isRecord(value)) {
375
+ return null;
376
+ }
377
+ const payload = isRecord(value.json_ordered)
378
+ ? value.json_ordered
379
+ : isRecord(value.json)
380
+ ? value.json
381
+ : null;
382
+ return {
383
+ id: firstNonEmpty(value.id) ?? '',
384
+ version: firstNonEmpty(value.version),
385
+ user_id: firstNonEmpty(value.user_id),
386
+ state_code: typeof value.state_code === 'number' ? value.state_code : null,
387
+ modified_at: firstNonEmpty(value.modified_at),
388
+ payload: payload,
389
+ source_url: null,
390
+ };
391
+ }
392
+ export async function lookupRemoteDataset(options) {
334
393
  const { client, restBaseUrl } = createSupabaseDataClient(options.runtime, options.fetchImpl, options.timeoutMs);
335
394
  const exactSourceUrl = options.request.version
336
395
  ? buildRemoteUrl(restBaseUrl, options.request.table, options.request.id, options.request.version)
@@ -356,6 +415,20 @@ async function lookupRemoteDataset(options) {
356
415
  latest_source_url: latestSourceUrl,
357
416
  };
358
417
  }
418
+ async function lookupRemoteDatasetPayload(options) {
419
+ if (!options.request.version) {
420
+ return null;
421
+ }
422
+ const { client, restBaseUrl } = createSupabaseDataClient(options.runtime, options.fetchImpl, options.timeoutMs);
423
+ const sourceUrl = buildRemotePayloadUrl(restBaseUrl, options.request.table, options.request.id, options.request.version);
424
+ const rows = await runSupabaseArrayQuery(client
425
+ .from(options.request.table)
426
+ .select('id,version,user_id,state_code,modified_at,json,json_ordered')
427
+ .eq('id', options.request.id)
428
+ .eq('version', options.request.version), sourceUrl);
429
+ const payloadRow = normalizePayloadRow(Array.isArray(rows) ? rows[0] : null);
430
+ return payloadRow ? { ...payloadRow, source_url: sourceUrl } : null;
431
+ }
359
432
  function checkMessage(reference, status) {
360
433
  const label = `${reference.table ?? reference.type ?? 'unknown'}:${reference.id ?? '-'}@${reference.version ?? '-'}`;
361
434
  switch (status) {
@@ -414,6 +487,7 @@ function classifyCheck(reference, lookup, lookupFailed, rootPolicy) {
414
487
  return {
415
488
  ...reference,
416
489
  status,
490
+ exact_version: lookup?.exact?.version ?? null,
417
491
  latest_version: lookup?.latest?.version ?? null,
418
492
  exact_source_url: lookup?.exact_source_url ?? null,
419
493
  latest_source_url: lookup?.latest_source_url ?? null,
@@ -436,6 +510,59 @@ function blockerFromCheck(check) {
436
510
  path: check.path,
437
511
  };
438
512
  }
513
+ function makeRootReadbackCheck(reference, status, message, remote, hashes = { local: null, remote: null }) {
514
+ return {
515
+ ...reference,
516
+ path: `${reference.path}#readback`,
517
+ status,
518
+ exact_version: remote?.version ?? null,
519
+ latest_version: null,
520
+ exact_source_url: remote?.source_url ?? null,
521
+ latest_source_url: null,
522
+ message,
523
+ remote_user_id: remote?.user_id ?? null,
524
+ remote_state_code: remote?.state_code ?? null,
525
+ remote_modified_at: remote?.modified_at ?? null,
526
+ local_payload_sha256: hashes.local,
527
+ remote_payload_sha256: hashes.remote,
528
+ };
529
+ }
530
+ function rootReadbackChecks(options) {
531
+ const { reference, localPayload, remote, compareRootPayload, targetUserId, stateCode } = options;
532
+ if (!remote) {
533
+ return [
534
+ makeRootReadbackCheck(reference, 'missing_dataset', `Remote root payload was not found for ${reference.table}:${reference.id}@${reference.version}.`, null),
535
+ ];
536
+ }
537
+ const checks = [];
538
+ if (targetUserId && remote.user_id !== targetUserId) {
539
+ checks.push(makeRootReadbackCheck(reference, 'owner_mismatch', `Remote root owner ${remote.user_id ?? '<missing>'} does not match target user ${targetUserId}.`, remote));
540
+ }
541
+ if (stateCode !== null && remote.state_code !== stateCode) {
542
+ checks.push(makeRootReadbackCheck(reference, 'state_code_mismatch', `Remote root state_code ${remote.state_code ?? '<missing>'} does not match required state_code ${stateCode}.`, remote));
543
+ }
544
+ let hashes = { local: null, remote: null };
545
+ if (compareRootPayload) {
546
+ if (!remote.payload) {
547
+ checks.push(makeRootReadbackCheck(reference, 'remote_payload_missing', `Remote root payload is missing for ${reference.table}:${reference.id}@${reference.version}.`, remote));
548
+ }
549
+ else {
550
+ hashes = {
551
+ local: sha256Json(localPayload),
552
+ remote: sha256Json(remote.payload),
553
+ };
554
+ if (hashes.local !== hashes.remote) {
555
+ checks.push(makeRootReadbackCheck(reference, 'payload_mismatch', `Remote root payload hash does not match local row for ${reference.table}:${reference.id}@${reference.version}.`, remote, hashes));
556
+ }
557
+ }
558
+ }
559
+ if (checks.length > 0) {
560
+ return checks;
561
+ }
562
+ return [
563
+ makeRootReadbackCheck(reference, 'ok', `Remote root readback matches required owner, state, and payload checks for ${reference.table}:${reference.id}@${reference.version}.`, remote, hashes),
564
+ ];
565
+ }
439
566
  function buildFiles(outDir) {
440
567
  const resolved = path.resolve(outDir);
441
568
  return {
@@ -455,6 +582,10 @@ export async function runDatasetRemoteVerify(options) {
455
582
  const rows = readDatasetRowsInput(inputPath, options.rawInput);
456
583
  const references = collectRemoteReferences(rows);
457
584
  const rootPolicy = options.rootPolicy ?? 'existing';
585
+ const compareRootPayload = options.compareRootPayload === true;
586
+ const targetUserId = trimToken(options.targetUserId);
587
+ const stateCode = options.stateCode ?? null;
588
+ const needsRootReadback = compareRootPayload || Boolean(targetUserId) || stateCode !== null;
458
589
  const fetchImpl = options.fetchImpl ?? fetch;
459
590
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
460
591
  const runtime = options.lookupDatasetImpl === undefined
@@ -472,6 +603,15 @@ export async function runDatasetRemoteVerify(options) {
472
603
  timeoutMs,
473
604
  request,
474
605
  }));
606
+ const rootPayloadLookupImpl = options.lookupRootPayloadImpl ??
607
+ (runtime
608
+ ? (request) => lookupRemoteDatasetPayload({
609
+ runtime: runtime,
610
+ fetchImpl,
611
+ timeoutMs,
612
+ request,
613
+ })
614
+ : null);
475
615
  const lookupCache = new Map();
476
616
  const checks = [];
477
617
  for (const reference of references) {
@@ -495,17 +635,53 @@ export async function runDatasetRemoteVerify(options) {
495
635
  }
496
636
  checks.push(classifyCheck(reference, lookup, lookupFailed, rootPolicy));
497
637
  }
638
+ if (needsRootReadback) {
639
+ const rootChecks = checks.filter((check) => check.role === 'root' &&
640
+ check.status === 'ok' &&
641
+ check.table &&
642
+ check.id &&
643
+ (compareRootPayload || rootPolicy !== 'candidate' || Boolean(check.exact_version)));
644
+ for (const check of rootChecks) {
645
+ const localPayload = unwrapDatasetPayload(rows[check.row_index]);
646
+ let remotePayload;
647
+ try {
648
+ if (!rootPayloadLookupImpl) {
649
+ throw new Error('root payload lookup is not available');
650
+ }
651
+ remotePayload = await rootPayloadLookupImpl({
652
+ table: check.table,
653
+ id: check.id,
654
+ version: check.version,
655
+ });
656
+ }
657
+ catch {
658
+ checks.push(makeRootReadbackCheck(check, 'lookup_failed', `Remote root payload lookup failed for ${check.table}:${check.id}@${check.version}.`, null));
659
+ continue;
660
+ }
661
+ checks.push(...rootReadbackChecks({
662
+ reference: check,
663
+ localPayload,
664
+ remote: remotePayload,
665
+ compareRootPayload,
666
+ targetUserId,
667
+ stateCode,
668
+ }));
669
+ }
670
+ }
498
671
  const blockers = checks
499
672
  .map(blockerFromCheck)
500
673
  .filter((blocker) => blocker !== null);
501
674
  const byStatus = { ...EMPTY_STATUS_COUNTS };
502
675
  const byTable = { ...EMPTY_TABLE_COUNTS };
503
676
  checks.forEach((check) => {
677
+ byStatus[check.status] ??= 0;
504
678
  byStatus[check.status] += 1;
505
679
  if (check.table) {
506
680
  byTable[check.table] += 1;
507
681
  }
508
682
  });
683
+ const rootReadbackChecksCount = checks.filter((check) => check.path.endsWith('#readback')).length;
684
+ const rootPayloadMismatches = checks.filter((check) => check.status === 'payload_mismatch').length;
509
685
  const files = buildFiles(outDir);
510
686
  const report = {
511
687
  schema_version: 1,
@@ -519,6 +695,8 @@ export async function runDatasetRemoteVerify(options) {
519
695
  references: references.length,
520
696
  checked: checks.length,
521
697
  blockers: blockers.length,
698
+ ...(needsRootReadback ? { root_readback_checks: rootReadbackChecksCount } : {}),
699
+ ...(needsRootReadback ? { root_payload_mismatches: rootPayloadMismatches } : {}),
522
700
  by_status: byStatus,
523
701
  by_table: byTable,
524
702
  },
@@ -531,11 +709,18 @@ export async function runDatasetRemoteVerify(options) {
531
709
  return report;
532
710
  }
533
711
  export const __testInternals = {
712
+ buildRemotePayloadUrl,
534
713
  buildRemoteUrl,
535
714
  collectRemoteReferences,
536
715
  compareVersions,
716
+ isFoundryTracePath,
717
+ lookupRemoteDatasetPayload,
537
718
  lookupRemoteDataset,
719
+ makeRootReadbackCheck,
720
+ normalizePayloadRow,
538
721
  normalizeRows,
722
+ rootReadbackChecks,
723
+ sha256Json,
539
724
  shortDescription,
540
725
  tableFromPath,
541
726
  tableFromType,