@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.
- package/README.md +18 -7
- package/assets/tidas-schemas/tidas_contacts.json +312 -0
- package/assets/tidas-schemas/tidas_contacts_category.json +126 -0
- package/assets/tidas-schemas/tidas_data_types.json +359 -0
- package/assets/tidas-schemas/tidas_flowproperties.json +303 -0
- package/assets/tidas-schemas/tidas_flowproperties_category.json +61 -0
- package/assets/tidas-schemas/tidas_flows.json +809 -0
- package/assets/tidas-schemas/tidas_flows_elementary_category.json +720 -0
- package/assets/tidas-schemas/tidas_flows_product_category.json +59623 -0
- package/assets/tidas-schemas/tidas_lciamethods.json +1326 -0
- package/assets/tidas-schemas/tidas_lciamethods_category.json +685 -0
- package/assets/tidas-schemas/tidas_lifecyclemodels.json +1374 -0
- package/assets/tidas-schemas/tidas_locations_category.json +2593 -0
- package/assets/tidas-schemas/tidas_processes.json +1646 -0
- package/assets/tidas-schemas/tidas_processes_category.json +10795 -0
- package/assets/tidas-schemas/tidas_sources.json +228 -0
- package/assets/tidas-schemas/tidas_sources_category.json +100 -0
- package/assets/tidas-schemas/tidas_unitgroups.json +338 -0
- package/assets/tidas-schemas/tidas_unitgroups_category.json +61 -0
- package/dist/src/cli.js +847 -13
- package/dist/src/cli.js.map +1 -1
- package/dist/src/lib/dataset-classification.js +947 -0
- package/dist/src/lib/dataset-classification.js.map +1 -0
- package/dist/src/lib/dataset-command.js +11 -0
- package/dist/src/lib/dataset-command.js.map +1 -1
- package/dist/src/lib/dataset-contract.js +2 -0
- package/dist/src/lib/dataset-contract.js.map +1 -1
- package/dist/src/lib/dataset-curation-queue.js +359 -2
- package/dist/src/lib/dataset-curation-queue.js.map +1 -1
- package/dist/src/lib/dataset-import-lca.js +18 -0
- package/dist/src/lib/dataset-import-lca.js.map +1 -1
- package/dist/src/lib/dataset-local.js +94 -1
- package/dist/src/lib/dataset-local.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-clear-account.js +506 -0
- package/dist/src/lib/dataset-maintenance-clear-account.js.map +1 -0
- package/dist/src/lib/dataset-patch.js +797 -0
- package/dist/src/lib/dataset-patch.js.map +1 -0
- package/dist/src/lib/dataset-remote-verify.js +188 -3
- package/dist/src/lib/dataset-remote-verify.js.map +1 -1
- package/dist/src/lib/dataset-save-draft-run.js +725 -0
- package/dist/src/lib/dataset-save-draft-run.js.map +1 -0
- package/dist/src/lib/dataset-validate.js +32 -2
- package/dist/src/lib/dataset-validate.js.map +1 -1
- package/dist/src/lib/flow-publish-version.js +7 -2
- package/dist/src/lib/flow-publish-version.js.map +1 -1
- package/dist/src/lib/flow-qa.js +8 -0
- package/dist/src/lib/flow-qa.js.map +1 -1
- package/dist/src/lib/identity-preflight.js +895 -117
- package/dist/src/lib/identity-preflight.js.map +1 -1
- package/dist/src/lib/lifecyclemodel-qa.js +159 -34
- package/dist/src/lib/lifecyclemodel-qa.js.map +1 -1
- package/dist/src/lib/process-required-fields.js +62 -12
- package/dist/src/lib/process-required-fields.js.map +1 -1
- package/dist/src/lib/process-save-draft-run.js +10 -0
- package/dist/src/lib/process-save-draft-run.js.map +1 -1
- package/dist/src/lib/process-save-draft.js +59 -3
- package/dist/src/lib/process-save-draft.js.map +1 -1
- package/dist/src/lib/supabase-client.js +19 -8
- package/dist/src/lib/supabase-client.js.map +1 -1
- 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: '
|
|
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
|
-
|
|
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,
|