@tiangong-lca/cli 0.0.6 → 0.0.8
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 +154 -30
- package/dist/src/cli.js +2235 -149
- package/dist/src/cli.js.map +1 -1
- package/dist/src/lib/dataset-author.js +100 -0
- package/dist/src/lib/dataset-author.js.map +1 -0
- package/dist/src/lib/dataset-bilingual.js +545 -0
- package/dist/src/lib/dataset-bilingual.js.map +1 -0
- package/dist/src/lib/dataset-contract.js +350 -0
- package/dist/src/lib/dataset-contract.js.map +1 -0
- package/dist/src/lib/dataset-evidence-search.js +636 -0
- package/dist/src/lib/dataset-evidence-search.js.map +1 -0
- package/dist/src/lib/dataset-import-lca.js +171 -0
- package/dist/src/lib/dataset-import-lca.js.map +1 -0
- package/dist/src/lib/dataset-local.js +231 -0
- package/dist/src/lib/dataset-local.js.map +1 -0
- package/dist/src/lib/dataset-references-rewrite.js +214 -0
- package/dist/src/lib/dataset-references-rewrite.js.map +1 -0
- package/dist/src/lib/dataset-remote-refresh.js +166 -0
- package/dist/src/lib/dataset-remote-refresh.js.map +1 -0
- package/dist/src/lib/dataset-remote-verify.js +543 -0
- package/dist/src/lib/dataset-remote-verify.js.map +1 -0
- package/dist/src/lib/dataset-validate.js +247 -0
- package/dist/src/lib/dataset-validate.js.map +1 -0
- package/dist/src/lib/flow-payload-validation.js +51 -0
- package/dist/src/lib/flow-payload-validation.js.map +1 -0
- package/dist/src/lib/flow-publish-reviewed-data.js +16 -0
- package/dist/src/lib/flow-publish-reviewed-data.js.map +1 -1
- package/dist/src/lib/flow-publish-version.js +182 -12
- package/dist/src/lib/flow-publish-version.js.map +1 -1
- package/dist/src/lib/flow-regen-product.js +2 -10
- package/dist/src/lib/flow-regen-product.js.map +1 -1
- package/dist/src/lib/flow-remediate.js +4 -8
- package/dist/src/lib/flow-remediate.js.map +1 -1
- package/dist/src/lib/identity-preflight.js +1021 -0
- package/dist/src/lib/identity-preflight.js.map +1 -0
- package/dist/src/lib/lifecyclemodel-auto-build.js +11 -8
- package/dist/src/lib/lifecyclemodel-auto-build.js.map +1 -1
- package/dist/src/lib/lifecyclemodel-graph.js +248 -0
- package/dist/src/lib/lifecyclemodel-graph.js.map +1 -0
- package/dist/src/lib/lifecyclemodel-publish-build.js +1 -1
- package/dist/src/lib/lifecyclemodel-publish-build.js.map +1 -1
- package/dist/src/lib/lifecyclemodel-save-draft-run.js +245 -0
- package/dist/src/lib/lifecyclemodel-save-draft-run.js.map +1 -0
- package/dist/src/lib/lifecyclemodel-validate-build.js +1 -1
- package/dist/src/lib/lifecyclemodel-validate-build.js.map +1 -1
- package/dist/src/lib/process-auto-build.js +158 -8
- package/dist/src/lib/process-auto-build.js.map +1 -1
- package/dist/src/lib/process-batch-build.js +6 -3
- package/dist/src/lib/process-batch-build.js.map +1 -1
- package/dist/src/lib/process-dedup-review.js +921 -0
- package/dist/src/lib/process-dedup-review.js.map +1 -0
- package/dist/src/lib/process-flow-build-plan.js +1071 -0
- package/dist/src/lib/process-flow-build-plan.js.map +1 -0
- package/dist/src/lib/process-payload-validation.js +57 -0
- package/dist/src/lib/process-payload-validation.js.map +1 -0
- package/dist/src/lib/process-publish-build.js +126 -10
- package/dist/src/lib/process-publish-build.js.map +1 -1
- package/dist/src/lib/process-refresh-references.js +1037 -0
- package/dist/src/lib/process-refresh-references.js.map +1 -0
- package/dist/src/lib/process-required-fields.js +810 -0
- package/dist/src/lib/process-required-fields.js.map +1 -0
- package/dist/src/lib/process-resume-build.js +4 -6
- package/dist/src/lib/process-resume-build.js.map +1 -1
- package/dist/src/lib/process-save-draft-run.js +35 -13
- package/dist/src/lib/process-save-draft-run.js.map +1 -1
- package/dist/src/lib/process-scope-statistics.js +859 -0
- package/dist/src/lib/process-scope-statistics.js.map +1 -0
- package/dist/src/lib/process-verify-rows.js +250 -0
- package/dist/src/lib/process-verify-rows.js.map +1 -0
- package/dist/src/lib/publish.js +101 -1
- package/dist/src/lib/publish.js.map +1 -1
- package/dist/src/lib/remote.js +4 -4
- package/dist/src/lib/remote.js.map +1 -1
- package/dist/src/lib/review-flow.js +58 -0
- package/dist/src/lib/review-flow.js.map +1 -1
- package/dist/src/lib/review-lifecyclemodel.js +2 -2
- package/dist/src/lib/review-lifecyclemodel.js.map +1 -1
- package/dist/src/lib/review-process.js +150 -2
- package/dist/src/lib/review-process.js.map +1 -1
- package/dist/src/lib/runtime-rulesets.js +283 -0
- package/dist/src/lib/runtime-rulesets.js.map +1 -0
- package/dist/src/lib/tidas-sdk-package-validator.js +28 -9
- package/dist/src/lib/tidas-sdk-package-validator.js.map +1 -1
- package/dist/src/lib/tidas-sdk-validation.js +96 -0
- package/dist/src/lib/tidas-sdk-validation.js.map +1 -0
- package/dist/src/lib/user-api-key.js +1 -1
- package/dist/src/lib/user-api-key.js.map +1 -1
- package/package.json +5 -5
- /package/bin/{tiangong.d.ts → tiangong-lca.d.ts} +0 -0
- /package/bin/{tiangong.js → tiangong-lca.js} +0 -0
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import * as tidasSdk from '@tiangong-lca/tidas-sdk';
|
|
3
|
+
import { writeJsonArtifact, writeJsonLinesArtifact } from './artifacts.js';
|
|
4
|
+
import { CliError } from './errors.js';
|
|
5
|
+
import { firstNonEmpty, isRecord, materializeDatasetRows, } from './dataset-local.js';
|
|
6
|
+
import { syncLifecyclemodelBundleRecord, } from './lifecyclemodel-bundle-save.js';
|
|
7
|
+
import { buildRunId, resolveRunLayout } from './run.js';
|
|
8
|
+
import { normalizeIssuePath, validateSchemaWithDeepFallback, } from './tidas-sdk-validation.js';
|
|
9
|
+
const VALIDATOR_NAME = '@tiangong-lca/tidas-sdk/LifeCycleModelSchema';
|
|
10
|
+
function getLifecyclemodelSchema(sdk = tidasSdk) {
|
|
11
|
+
const schema = sdk.LifeCycleModelSchema;
|
|
12
|
+
if (!schema?.safeParse) {
|
|
13
|
+
throw new Error(`${VALIDATOR_NAME} is unavailable in the published CLI runtime.`);
|
|
14
|
+
}
|
|
15
|
+
return schema;
|
|
16
|
+
}
|
|
17
|
+
function getLifecyclemodelFactory(sdk = tidasSdk) {
|
|
18
|
+
const createLifeCycleModel = sdk.createLifeCycleModel;
|
|
19
|
+
return typeof createLifeCycleModel === 'function'
|
|
20
|
+
? createLifeCycleModel
|
|
21
|
+
: null;
|
|
22
|
+
}
|
|
23
|
+
export function validateLifecyclemodelPayload(payload, schema, createEntity) {
|
|
24
|
+
const activeSchema = schema ?? getLifecyclemodelSchema();
|
|
25
|
+
const activeCreateEntity = createEntity === undefined && schema === undefined ? getLifecyclemodelFactory() : createEntity;
|
|
26
|
+
const outcome = validateSchemaWithDeepFallback(activeSchema, payload, activeCreateEntity);
|
|
27
|
+
if (outcome.success) {
|
|
28
|
+
return {
|
|
29
|
+
ok: true,
|
|
30
|
+
validator: VALIDATOR_NAME,
|
|
31
|
+
issue_count: 0,
|
|
32
|
+
issues: [],
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const issues = outcome.issues.map((issue) => ({
|
|
36
|
+
path: normalizeIssuePath(issue.path),
|
|
37
|
+
message: issue.message ?? 'Validation failed',
|
|
38
|
+
code: issue.code ?? 'custom',
|
|
39
|
+
}));
|
|
40
|
+
return {
|
|
41
|
+
ok: false,
|
|
42
|
+
validator: VALIDATOR_NAME,
|
|
43
|
+
issue_count: issues.length,
|
|
44
|
+
issues,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function summarizeValidation(result) {
|
|
48
|
+
if (result.ok) {
|
|
49
|
+
return 'local LifeCycleModelSchema validation passed';
|
|
50
|
+
}
|
|
51
|
+
const preview = result.issues
|
|
52
|
+
.slice(0, 3)
|
|
53
|
+
.map((issue) => `${issue.path}: ${issue.message}`)
|
|
54
|
+
.join('; ');
|
|
55
|
+
return `local LifeCycleModelSchema validation failed with ${result.issue_count} issue(s)${preview ? ` (${preview})` : ''}`;
|
|
56
|
+
}
|
|
57
|
+
function extractMetadata(row) {
|
|
58
|
+
const metadata = {};
|
|
59
|
+
const jsonTg = isRecord(row.json_tg) ? row.json_tg : isRecord(row.jsonTg) ? row.jsonTg : null;
|
|
60
|
+
if (jsonTg) {
|
|
61
|
+
metadata.json_tg = jsonTg;
|
|
62
|
+
}
|
|
63
|
+
if (Array.isArray(row.processMutations)) {
|
|
64
|
+
metadata.processMutations = row.processMutations.filter(isRecord);
|
|
65
|
+
}
|
|
66
|
+
else if (Array.isArray(row.process_mutations)) {
|
|
67
|
+
metadata.processMutations = row.process_mutations.filter(isRecord);
|
|
68
|
+
}
|
|
69
|
+
if (typeof row.ruleVerification === 'boolean') {
|
|
70
|
+
metadata.ruleVerification = row.ruleVerification;
|
|
71
|
+
}
|
|
72
|
+
else if (typeof row.rule_verification === 'boolean') {
|
|
73
|
+
metadata.ruleVerification = row.rule_verification;
|
|
74
|
+
}
|
|
75
|
+
return Object.keys(metadata).length > 0 ? metadata : null;
|
|
76
|
+
}
|
|
77
|
+
function candidateError(message) {
|
|
78
|
+
return { message };
|
|
79
|
+
}
|
|
80
|
+
function buildCandidate(row, payload, validate) {
|
|
81
|
+
const root = isRecord(payload.lifeCycleModelDataSet) ? payload.lifeCycleModelDataSet : payload;
|
|
82
|
+
const information = isRecord(root.lifeCycleModelInformation)
|
|
83
|
+
? root.lifeCycleModelInformation
|
|
84
|
+
: {};
|
|
85
|
+
const dataSetInformation = isRecord(information.dataSetInformation)
|
|
86
|
+
? information.dataSetInformation
|
|
87
|
+
: {};
|
|
88
|
+
const administrativeInformation = isRecord(root.administrativeInformation)
|
|
89
|
+
? root.administrativeInformation
|
|
90
|
+
: {};
|
|
91
|
+
const publicationAndOwnership = isRecord(administrativeInformation.publicationAndOwnership)
|
|
92
|
+
? administrativeInformation.publicationAndOwnership
|
|
93
|
+
: {};
|
|
94
|
+
const id = firstNonEmpty(row.id, dataSetInformation['common:UUID']);
|
|
95
|
+
const version = firstNonEmpty(row.version, publicationAndOwnership['common:dataSetVersion'], '01.01.000');
|
|
96
|
+
if (!id) {
|
|
97
|
+
return {
|
|
98
|
+
id: null,
|
|
99
|
+
version,
|
|
100
|
+
payload,
|
|
101
|
+
metadata: extractMetadata(row),
|
|
102
|
+
error: candidateError('Lifecyclemodel payload missing lifeCycleModelInformation.dataSetInformation.common:UUID.'),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
const validation = validate(payload);
|
|
106
|
+
if (!validation.ok) {
|
|
107
|
+
return {
|
|
108
|
+
id,
|
|
109
|
+
version,
|
|
110
|
+
payload,
|
|
111
|
+
metadata: extractMetadata(row),
|
|
112
|
+
validation,
|
|
113
|
+
error: candidateError(summarizeValidation(validation)),
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
id,
|
|
118
|
+
version,
|
|
119
|
+
payload,
|
|
120
|
+
metadata: extractMetadata(row),
|
|
121
|
+
validation,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
function defaultOutDir(inputPath, commit, now) {
|
|
125
|
+
const runId = buildRunId({
|
|
126
|
+
namespace: 'lifecyclemodel_save_draft',
|
|
127
|
+
operation: commit ? 'commit' : 'dry_run',
|
|
128
|
+
now,
|
|
129
|
+
});
|
|
130
|
+
return resolveRunLayout(path.join(path.dirname(inputPath), 'artifacts'), 'lifecyclemodel_save_draft', runId).runRoot;
|
|
131
|
+
}
|
|
132
|
+
function buildFiles(outDir) {
|
|
133
|
+
const outputDir = path.join(outDir, 'outputs', 'save-draft-bundle');
|
|
134
|
+
return {
|
|
135
|
+
normalized_input: path.join(outDir, 'inputs', 'normalized-input.json'),
|
|
136
|
+
selected_lifecyclemodels: path.join(outputDir, 'selected-lifecyclemodels.jsonl'),
|
|
137
|
+
progress_jsonl: path.join(outputDir, 'progress.jsonl'),
|
|
138
|
+
failures_jsonl: path.join(outputDir, 'failures.jsonl'),
|
|
139
|
+
summary_json: path.join(outputDir, 'summary.json'),
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
function compactCandidate(candidate) {
|
|
143
|
+
return {
|
|
144
|
+
id: candidate.id,
|
|
145
|
+
version: candidate.version,
|
|
146
|
+
payload: candidate.payload,
|
|
147
|
+
metadata: candidate.metadata,
|
|
148
|
+
...(candidate.validation ? { validation: candidate.validation } : {}),
|
|
149
|
+
...(candidate.error ? { error: candidate.error } : {}),
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
function serializeError(error) {
|
|
153
|
+
return {
|
|
154
|
+
message: error instanceof Error ? error.message : String(error),
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
export async function runLifecyclemodelSaveDraft(options) {
|
|
158
|
+
const now = options.now ?? new Date();
|
|
159
|
+
const inputPath = path.resolve(options.inputPath);
|
|
160
|
+
const commit = options.commit === true;
|
|
161
|
+
const outDir = path.resolve(options.outDir ?? defaultOutDir(inputPath, commit, now));
|
|
162
|
+
const validate = options.validateLifecyclemodelPayloadImpl ?? validateLifecyclemodelPayload;
|
|
163
|
+
const datasetRows = materializeDatasetRows(inputPath, options.rawInput);
|
|
164
|
+
const candidates = datasetRows.map((row) => buildCandidate(row.row, row.payload, validate));
|
|
165
|
+
const files = buildFiles(outDir);
|
|
166
|
+
if (commit && (!options.env || !options.fetchImpl)) {
|
|
167
|
+
throw new CliError('Lifecyclemodel save-draft commit requires env and fetch runtime bindings.', {
|
|
168
|
+
code: 'LIFECYCLEMODEL_SAVE_DRAFT_RUNTIME_REQUIRED',
|
|
169
|
+
exitCode: 2,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
writeJsonArtifact(files.normalized_input, {
|
|
173
|
+
input_kind: 'rows_file',
|
|
174
|
+
input_path: inputPath,
|
|
175
|
+
row_count: candidates.length,
|
|
176
|
+
});
|
|
177
|
+
writeJsonLinesArtifact(files.selected_lifecyclemodels, candidates.map(compactCandidate));
|
|
178
|
+
const reports = [];
|
|
179
|
+
for (const candidate of candidates) {
|
|
180
|
+
const report = {
|
|
181
|
+
id: candidate.id,
|
|
182
|
+
version: candidate.version,
|
|
183
|
+
status: 'prepared',
|
|
184
|
+
...(candidate.validation ? { validation: candidate.validation } : {}),
|
|
185
|
+
};
|
|
186
|
+
if (candidate.error) {
|
|
187
|
+
report.status = 'failed';
|
|
188
|
+
report.error = candidate.error;
|
|
189
|
+
reports.push(report);
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
if (!commit) {
|
|
193
|
+
reports.push(report);
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
try {
|
|
197
|
+
report.execution = await syncLifecyclemodelBundleRecord({
|
|
198
|
+
id: candidate.id,
|
|
199
|
+
version: candidate.version,
|
|
200
|
+
payload: candidate.payload,
|
|
201
|
+
metadata: candidate.metadata,
|
|
202
|
+
env: options.env,
|
|
203
|
+
fetchImpl: options.fetchImpl,
|
|
204
|
+
timeoutMs: options.timeoutMs,
|
|
205
|
+
});
|
|
206
|
+
report.status = 'executed';
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
report.status = 'failed';
|
|
210
|
+
report.error = serializeError(error);
|
|
211
|
+
}
|
|
212
|
+
reports.push(report);
|
|
213
|
+
}
|
|
214
|
+
const failures = reports.filter((report) => report.status === 'failed');
|
|
215
|
+
writeJsonLinesArtifact(files.progress_jsonl, reports);
|
|
216
|
+
writeJsonLinesArtifact(files.failures_jsonl, failures);
|
|
217
|
+
const report = {
|
|
218
|
+
generated_at_utc: now.toISOString(),
|
|
219
|
+
input_path: inputPath,
|
|
220
|
+
out_dir: outDir,
|
|
221
|
+
commit,
|
|
222
|
+
mode: commit ? 'commit' : 'dry_run',
|
|
223
|
+
status: failures.length > 0 ? 'completed_with_failures' : 'completed',
|
|
224
|
+
counts: {
|
|
225
|
+
selected: candidates.length,
|
|
226
|
+
prepared: reports.filter((entry) => entry.status === 'prepared').length,
|
|
227
|
+
executed: reports.filter((entry) => entry.status === 'executed').length,
|
|
228
|
+
failed: failures.length,
|
|
229
|
+
},
|
|
230
|
+
files,
|
|
231
|
+
lifecyclemodels: reports,
|
|
232
|
+
};
|
|
233
|
+
writeJsonArtifact(files.summary_json, report);
|
|
234
|
+
return report;
|
|
235
|
+
}
|
|
236
|
+
export const __testInternals = {
|
|
237
|
+
buildCandidate,
|
|
238
|
+
getLifecyclemodelFactory,
|
|
239
|
+
getLifecyclemodelSchema,
|
|
240
|
+
normalizeIssuePath,
|
|
241
|
+
serializeError,
|
|
242
|
+
summarizeValidation,
|
|
243
|
+
validateLifecyclemodelPayload,
|
|
244
|
+
};
|
|
245
|
+
//# sourceMappingURL=lifecyclemodel-save-draft-run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecyclemodel-save-draft-run.js","sourceRoot":"","sources":["../../../src/lib/lifecyclemodel-save-draft-run.ts"],"names":[],"mappings":"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","sourcesContent":["import path from 'node:path';\nimport * as tidasSdk from '@tiangong-lca/tidas-sdk';\nimport { writeJsonArtifact, writeJsonLinesArtifact } from './artifacts.js';\nimport { CliError } from './errors.js';\nimport type { FetchLike } from './http.js';\nimport {\n firstNonEmpty,\n isRecord,\n materializeDatasetRows,\n type JsonObject,\n} from './dataset-local.js';\nimport {\n syncLifecyclemodelBundleRecord,\n type LifecyclemodelBundleWriteResult,\n type LifecyclemodelPublishMetadata,\n} from './lifecyclemodel-bundle-save.js';\nimport { buildRunId, resolveRunLayout } from './run.js';\nimport {\n normalizeIssuePath,\n type SafeParseSchema,\n type SdkValidationFactory,\n validateSchemaWithDeepFallback,\n} from './tidas-sdk-validation.js';\n\nexport type LifecyclemodelPayloadValidationIssue = {\n path: string;\n message: string;\n code: string;\n};\n\nexport type LifecyclemodelPayloadValidationResult =\n | {\n ok: true;\n validator: string;\n issue_count: 0;\n issues: [];\n }\n | {\n ok: false;\n validator: string;\n issue_count: number;\n issues: LifecyclemodelPayloadValidationIssue[];\n };\n\ntype LifecyclemodelSaveDraftCandidate = {\n id: string | null;\n version: string | null;\n payload: JsonObject;\n metadata: LifecyclemodelPublishMetadata | null;\n validation?: LifecyclemodelPayloadValidationResult;\n error?: { message: string };\n};\n\nexport type LifecyclemodelSaveDraftModelReport = {\n id: string | null;\n version: string | null;\n status: 'prepared' | 'executed' | 'failed';\n validation?: LifecyclemodelPayloadValidationResult;\n execution?: LifecyclemodelBundleWriteResult;\n error?: { message: string };\n};\n\nexport type LifecyclemodelSaveDraftReport = {\n generated_at_utc: string;\n input_path: string;\n out_dir: string;\n commit: boolean;\n mode: 'dry_run' | 'commit';\n status: 'completed' | 'completed_with_failures';\n counts: {\n selected: number;\n prepared: number;\n executed: number;\n failed: number;\n };\n files: {\n normalized_input: string;\n selected_lifecyclemodels: string;\n progress_jsonl: string;\n failures_jsonl: string;\n summary_json: string;\n };\n lifecyclemodels: LifecyclemodelSaveDraftModelReport[];\n};\n\nexport type RunLifecyclemodelSaveDraftOptions = {\n inputPath: string;\n outDir?: string | null;\n commit?: boolean | null;\n rawInput?: unknown;\n env?: NodeJS.ProcessEnv;\n fetchImpl?: FetchLike;\n timeoutMs?: number;\n now?: Date;\n validateLifecyclemodelPayloadImpl?: (\n payload: JsonObject,\n ) => LifecyclemodelPayloadValidationResult;\n};\n\nconst VALIDATOR_NAME = '@tiangong-lca/tidas-sdk/LifeCycleModelSchema';\n\nfunction getLifecyclemodelSchema(\n sdk: { LifeCycleModelSchema?: unknown } = tidasSdk,\n): SafeParseSchema {\n const schema = sdk.LifeCycleModelSchema as SafeParseSchema | undefined;\n if (!schema?.safeParse) {\n throw new Error(`${VALIDATOR_NAME} is unavailable in the published CLI runtime.`);\n }\n return schema;\n}\n\nfunction getLifecyclemodelFactory(\n sdk: { createLifeCycleModel?: unknown } = tidasSdk,\n): SdkValidationFactory | null {\n const createLifeCycleModel = sdk.createLifeCycleModel;\n return typeof createLifeCycleModel === 'function'\n ? (createLifeCycleModel as SdkValidationFactory)\n : null;\n}\n\nexport function validateLifecyclemodelPayload(\n payload: JsonObject,\n schema?: SafeParseSchema,\n createEntity?: SdkValidationFactory | null,\n): LifecyclemodelPayloadValidationResult {\n const activeSchema = schema ?? getLifecyclemodelSchema();\n const activeCreateEntity =\n createEntity === undefined && schema === undefined ? getLifecyclemodelFactory() : createEntity;\n const outcome = validateSchemaWithDeepFallback(activeSchema, payload, activeCreateEntity);\n if (outcome.success) {\n return {\n ok: true,\n validator: VALIDATOR_NAME,\n issue_count: 0,\n issues: [],\n };\n }\n\n const issues = outcome.issues.map((issue) => ({\n path: normalizeIssuePath(issue.path),\n message: issue.message ?? 'Validation failed',\n code: issue.code ?? 'custom',\n }));\n\n return {\n ok: false,\n validator: VALIDATOR_NAME,\n issue_count: issues.length,\n issues,\n };\n}\n\nfunction summarizeValidation(result: LifecyclemodelPayloadValidationResult): string {\n if (result.ok) {\n return 'local LifeCycleModelSchema validation passed';\n }\n const preview = result.issues\n .slice(0, 3)\n .map((issue) => `${issue.path}: ${issue.message}`)\n .join('; ');\n return `local LifeCycleModelSchema validation failed with ${result.issue_count} issue(s)${\n preview ? ` (${preview})` : ''\n }`;\n}\n\nfunction extractMetadata(row: JsonObject): LifecyclemodelPublishMetadata | null {\n const metadata: LifecyclemodelPublishMetadata = {};\n const jsonTg = isRecord(row.json_tg) ? row.json_tg : isRecord(row.jsonTg) ? row.jsonTg : null;\n if (jsonTg) {\n metadata.json_tg = jsonTg;\n }\n if (Array.isArray(row.processMutations)) {\n metadata.processMutations = row.processMutations.filter(isRecord);\n } else if (Array.isArray(row.process_mutations)) {\n metadata.processMutations = row.process_mutations.filter(isRecord);\n }\n if (typeof row.ruleVerification === 'boolean') {\n metadata.ruleVerification = row.ruleVerification;\n } else if (typeof row.rule_verification === 'boolean') {\n metadata.ruleVerification = row.rule_verification;\n }\n\n return Object.keys(metadata).length > 0 ? metadata : null;\n}\n\nfunction candidateError(message: string): { message: string } {\n return { message };\n}\n\nfunction buildCandidate(\n row: JsonObject,\n payload: JsonObject,\n validate: (payload: JsonObject) => LifecyclemodelPayloadValidationResult,\n): LifecyclemodelSaveDraftCandidate {\n const root = isRecord(payload.lifeCycleModelDataSet) ? payload.lifeCycleModelDataSet : payload;\n const information = isRecord(root.lifeCycleModelInformation)\n ? root.lifeCycleModelInformation\n : {};\n const dataSetInformation = isRecord(information.dataSetInformation)\n ? information.dataSetInformation\n : {};\n const administrativeInformation = isRecord(root.administrativeInformation)\n ? root.administrativeInformation\n : {};\n const publicationAndOwnership = isRecord(administrativeInformation.publicationAndOwnership)\n ? administrativeInformation.publicationAndOwnership\n : {};\n const id = firstNonEmpty(row.id, dataSetInformation['common:UUID']);\n const version = firstNonEmpty(\n row.version,\n publicationAndOwnership['common:dataSetVersion'],\n '01.01.000',\n );\n\n if (!id) {\n return {\n id: null,\n version,\n payload,\n metadata: extractMetadata(row),\n error: candidateError(\n 'Lifecyclemodel payload missing lifeCycleModelInformation.dataSetInformation.common:UUID.',\n ),\n };\n }\n\n const validation = validate(payload);\n if (!validation.ok) {\n return {\n id,\n version,\n payload,\n metadata: extractMetadata(row),\n validation,\n error: candidateError(summarizeValidation(validation)),\n };\n }\n\n return {\n id,\n version,\n payload,\n metadata: extractMetadata(row),\n validation,\n };\n}\n\nfunction defaultOutDir(inputPath: string, commit: boolean, now: Date): string {\n const runId = buildRunId({\n namespace: 'lifecyclemodel_save_draft',\n operation: commit ? 'commit' : 'dry_run',\n now,\n });\n return resolveRunLayout(\n path.join(path.dirname(inputPath), 'artifacts'),\n 'lifecyclemodel_save_draft',\n runId,\n ).runRoot;\n}\n\nfunction buildFiles(outDir: string): LifecyclemodelSaveDraftReport['files'] {\n const outputDir = path.join(outDir, 'outputs', 'save-draft-bundle');\n return {\n normalized_input: path.join(outDir, 'inputs', 'normalized-input.json'),\n selected_lifecyclemodels: path.join(outputDir, 'selected-lifecyclemodels.jsonl'),\n progress_jsonl: path.join(outputDir, 'progress.jsonl'),\n failures_jsonl: path.join(outputDir, 'failures.jsonl'),\n summary_json: path.join(outputDir, 'summary.json'),\n };\n}\n\nfunction compactCandidate(candidate: LifecyclemodelSaveDraftCandidate): JsonObject {\n return {\n id: candidate.id,\n version: candidate.version,\n payload: candidate.payload,\n metadata: candidate.metadata,\n ...(candidate.validation ? { validation: candidate.validation } : {}),\n ...(candidate.error ? { error: candidate.error } : {}),\n };\n}\n\nfunction serializeError(error: unknown): { message: string } {\n return {\n message: error instanceof Error ? error.message : String(error),\n };\n}\n\nexport async function runLifecyclemodelSaveDraft(\n options: RunLifecyclemodelSaveDraftOptions,\n): Promise<LifecyclemodelSaveDraftReport> {\n const now = options.now ?? new Date();\n const inputPath = path.resolve(options.inputPath);\n const commit = options.commit === true;\n const outDir = path.resolve(options.outDir ?? defaultOutDir(inputPath, commit, now));\n const validate = options.validateLifecyclemodelPayloadImpl ?? validateLifecyclemodelPayload;\n const datasetRows = materializeDatasetRows(inputPath, options.rawInput);\n const candidates = datasetRows.map((row) => buildCandidate(row.row, row.payload, validate));\n const files = buildFiles(outDir);\n\n if (commit && (!options.env || !options.fetchImpl)) {\n throw new CliError(\n 'Lifecyclemodel save-draft commit requires env and fetch runtime bindings.',\n {\n code: 'LIFECYCLEMODEL_SAVE_DRAFT_RUNTIME_REQUIRED',\n exitCode: 2,\n },\n );\n }\n\n writeJsonArtifact(files.normalized_input, {\n input_kind: 'rows_file',\n input_path: inputPath,\n row_count: candidates.length,\n });\n writeJsonLinesArtifact(files.selected_lifecyclemodels, candidates.map(compactCandidate));\n\n const reports: LifecyclemodelSaveDraftModelReport[] = [];\n for (const candidate of candidates) {\n const report: LifecyclemodelSaveDraftModelReport = {\n id: candidate.id,\n version: candidate.version,\n status: 'prepared',\n ...(candidate.validation ? { validation: candidate.validation } : {}),\n };\n\n if (candidate.error) {\n report.status = 'failed';\n report.error = candidate.error;\n reports.push(report);\n continue;\n }\n\n if (!commit) {\n reports.push(report);\n continue;\n }\n\n try {\n report.execution = await syncLifecyclemodelBundleRecord({\n id: candidate.id!,\n version: candidate.version!,\n payload: candidate.payload,\n metadata: candidate.metadata,\n env: options.env!,\n fetchImpl: options.fetchImpl!,\n timeoutMs: options.timeoutMs,\n });\n report.status = 'executed';\n } catch (error) {\n report.status = 'failed';\n report.error = serializeError(error);\n }\n reports.push(report);\n }\n\n const failures = reports.filter((report) => report.status === 'failed');\n writeJsonLinesArtifact(files.progress_jsonl, reports);\n writeJsonLinesArtifact(files.failures_jsonl, failures);\n\n const report: LifecyclemodelSaveDraftReport = {\n generated_at_utc: now.toISOString(),\n input_path: inputPath,\n out_dir: outDir,\n commit,\n mode: commit ? 'commit' : 'dry_run',\n status: failures.length > 0 ? 'completed_with_failures' : 'completed',\n counts: {\n selected: candidates.length,\n prepared: reports.filter((entry) => entry.status === 'prepared').length,\n executed: reports.filter((entry) => entry.status === 'executed').length,\n failed: failures.length,\n },\n files,\n lifecyclemodels: reports,\n };\n writeJsonArtifact(files.summary_json, report);\n return report;\n}\n\nexport const __testInternals = {\n buildCandidate,\n getLifecyclemodelFactory,\n getLifecyclemodelSchema,\n normalizeIssuePath,\n serializeError,\n summarizeValidation,\n validateLifecyclemodelPayload,\n};\n"]}
|
|
@@ -164,7 +164,7 @@ function buildNextActions(layout) {
|
|
|
164
164
|
return [
|
|
165
165
|
`inspect: ${layout.reportPath}`,
|
|
166
166
|
`inspect: ${layout.modelReportsDir}`,
|
|
167
|
-
`run: tiangong lifecyclemodel publish-build --run-dir ${layout.runRoot}`,
|
|
167
|
+
`run: tiangong-lca lifecyclemodel publish-build --run-dir ${layout.runRoot}`,
|
|
168
168
|
];
|
|
169
169
|
}
|
|
170
170
|
function resolveValidationImpl(deps) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lifecyclemodel-validate-build.js","sourceRoot":"","sources":["../../../src/lib/lifecyclemodel-validate-build.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readdirSync } from 'node:fs';\nimport path from 'node:path';\nimport { readJsonArtifact, writeJsonArtifact } from './artifacts.js';\nimport { CliError } from './errors.js';\nimport {\n runValidation,\n type RunValidationOptions,\n type ValidationRunReport,\n} from './validation.js';\n\ntype JsonObject = Record<string, unknown>;\n\ntype ModelBundleEntry = {\n runName: string;\n inputDir: string;\n modelFiles: string[];\n};\n\nfunction isRecord(value: unknown): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction nonEmptyString(value: unknown): string | null {\n if (typeof value !== 'string') {\n return null;\n }\n\n const normalized = value.trim();\n return normalized || null;\n}\n\nfunction readRequiredJsonObject(\n filePath: string,\n missingCode: string,\n invalidCode: string,\n label: string,\n): JsonObject {\n if (!existsSync(filePath)) {\n throw new CliError(`Required lifecyclemodel ${label} artifact not found: ${filePath}`, {\n code: missingCode,\n exitCode: 2,\n details: { filePath, label },\n });\n }\n\n const value = readJsonArtifact(filePath);\n if (!isRecord(value)) {\n throw new CliError(`Expected lifecyclemodel ${label} artifact JSON object: ${filePath}`, {\n code: invalidCode,\n exitCode: 2,\n details: { filePath, label },\n });\n }\n\n return value;\n}\n\nexport type LifecyclemodelValidateBuildLayout = {\n runId: string;\n runRoot: string;\n modelsDir: string;\n reportsDir: string;\n modelReportsDir: string;\n manifestsDir: string;\n runManifestPath: string;\n invocationIndexPath: string;\n autoBuildReportPath: string;\n reportPath: string;\n};\n\nexport type LifecyclemodelValidateBuildModelReport = {\n run_name: string;\n input_dir: string;\n model_files: string[];\n report_file: string;\n validation: ValidationRunReport;\n};\n\nexport type LifecyclemodelValidateBuildReport = {\n schema_version: 1;\n generated_at_utc: string;\n status: 'completed_lifecyclemodel_validate_build';\n run_id: string;\n run_root: string;\n ok: boolean;\n engine: string;\n counts: {\n models: number;\n ok: number;\n failed: number;\n };\n files: {\n run_manifest: string;\n invocation_index: string;\n auto_build_report: string | null;\n report: string;\n model_reports_dir: string;\n };\n model_reports: LifecyclemodelValidateBuildModelReport[];\n next_actions: string[];\n};\n\nexport type RunLifecyclemodelValidateBuildOptions = {\n runDir: string;\n engine?: string;\n now?: Date;\n cwd?: string;\n};\n\nexport type LifecyclemodelValidateBuildDeps = {\n runValidationImpl?: (options: RunValidationOptions) => Promise<ValidationRunReport>;\n};\n\nfunction buildLayout(runRoot: string): LifecyclemodelValidateBuildLayout {\n const runId = path.basename(runRoot);\n return {\n runId,\n runRoot,\n modelsDir: path.join(runRoot, 'models'),\n reportsDir: path.join(runRoot, 'reports'),\n modelReportsDir: path.join(runRoot, 'reports', 'model-validations'),\n manifestsDir: path.join(runRoot, 'manifests'),\n runManifestPath: path.join(runRoot, 'manifests', 'run-manifest.json'),\n invocationIndexPath: path.join(runRoot, 'manifests', 'invocation-index.json'),\n autoBuildReportPath: path.join(runRoot, 'reports', 'lifecyclemodel-auto-build-report.json'),\n reportPath: path.join(runRoot, 'reports', 'lifecyclemodel-validate-build-report.json'),\n };\n}\n\nfunction resolveLayout(\n options: RunLifecyclemodelValidateBuildOptions,\n): LifecyclemodelValidateBuildLayout {\n const runDir = nonEmptyString(options.runDir);\n if (!runDir) {\n throw new CliError('Missing required --run-dir for lifecyclemodel validate-build.', {\n code: 'LIFECYCLEMODEL_VALIDATE_RUN_DIR_REQUIRED',\n exitCode: 2,\n });\n }\n\n return buildLayout(path.resolve(runDir));\n}\n\nfunction ensureRunRootExists(layout: LifecyclemodelValidateBuildLayout): void {\n if (!existsSync(layout.runRoot)) {\n throw new CliError(`lifecyclemodel validate-build run root not found: ${layout.runRoot}`, {\n code: 'LIFECYCLEMODEL_VALIDATE_RUN_NOT_FOUND',\n exitCode: 2,\n });\n }\n}\n\nfunction readRequiredRunManifest(layout: LifecyclemodelValidateBuildLayout): JsonObject {\n const manifest = readRequiredJsonObject(\n layout.runManifestPath,\n 'LIFECYCLEMODEL_VALIDATE_RUN_MANIFEST_MISSING',\n 'LIFECYCLEMODEL_VALIDATE_RUN_MANIFEST_INVALID',\n 'run-manifest',\n );\n\n const manifestRunId = nonEmptyString(manifest.runId);\n if (manifestRunId && manifestRunId !== layout.runId) {\n throw new CliError(\n `lifecyclemodel validate-build run manifest runId mismatch: ${layout.runManifestPath}`,\n {\n code: 'LIFECYCLEMODEL_VALIDATE_RUN_MANIFEST_MISMATCH',\n exitCode: 2,\n details: {\n expected: layout.runId,\n actual: manifestRunId,\n },\n },\n );\n }\n\n return manifest;\n}\n\nfunction readInvocationIndex(layout: LifecyclemodelValidateBuildLayout): JsonObject {\n if (!existsSync(layout.invocationIndexPath)) {\n return {\n schema_version: 1,\n invocations: [],\n };\n }\n\n const value = readJsonArtifact(layout.invocationIndexPath);\n if (!isRecord(value)) {\n throw new CliError(\n `Expected lifecyclemodel validate invocation index JSON object: ${layout.invocationIndexPath}`,\n {\n code: 'LIFECYCLEMODEL_VALIDATE_INVOCATION_INDEX_INVALID',\n exitCode: 2,\n },\n );\n }\n\n if (value.invocations === undefined) {\n return {\n schema_version: 1,\n invocations: [],\n };\n }\n\n if (!Array.isArray(value.invocations)) {\n throw new CliError(\n `Expected lifecyclemodel validate invocation index to contain an invocations array: ${layout.invocationIndexPath}`,\n {\n code: 'LIFECYCLEMODEL_VALIDATE_INVOCATION_INDEX_INVALID',\n exitCode: 2,\n },\n );\n }\n\n return value;\n}\n\nfunction discoverModelEntries(layout: LifecyclemodelValidateBuildLayout): ModelBundleEntry[] {\n const runNames = existsSync(layout.modelsDir) ? readdirSync(layout.modelsDir).sort() : [];\n const entries = runNames.flatMap((runName) => {\n const inputDir = path.join(layout.modelsDir, runName, 'tidas_bundle');\n const lifecyclemodelsDir = path.join(inputDir, 'lifecyclemodels');\n if (!existsSync(lifecyclemodelsDir)) {\n return [];\n }\n\n const modelFiles = readdirSync(lifecyclemodelsDir)\n .filter((entry) => entry.endsWith('.json'))\n .sort()\n .map((entry) => path.join(lifecyclemodelsDir, entry));\n\n if (modelFiles.length === 0) {\n throw new CliError(\n `lifecyclemodel validate-build found a bundle without lifecyclemodel JSON files: ${lifecyclemodelsDir}`,\n {\n code: 'LIFECYCLEMODEL_VALIDATE_MODELS_EMPTY',\n exitCode: 2,\n },\n );\n }\n\n return [{ runName, inputDir, modelFiles }];\n });\n\n if (entries.length === 0) {\n throw new CliError(\n `lifecyclemodel validate-build run does not contain any model bundles: ${layout.modelsDir}`,\n {\n code: 'LIFECYCLEMODEL_VALIDATE_MODELS_NOT_FOUND',\n exitCode: 2,\n },\n );\n }\n\n return entries;\n}\n\nfunction buildInvocationIndex(\n layout: LifecyclemodelValidateBuildLayout,\n invocationIndex: JsonObject,\n options: RunLifecyclemodelValidateBuildOptions,\n now: Date,\n): JsonObject {\n const priorInvocations = Array.isArray(invocationIndex.invocations)\n ? [...invocationIndex.invocations]\n : [];\n const command = ['lifecyclemodel', 'validate-build', '--run-dir', options.runDir];\n if (options.engine) {\n command.push('--engine', options.engine);\n }\n\n return {\n ...invocationIndex,\n schema_version:\n typeof invocationIndex.schema_version === 'number' ? invocationIndex.schema_version : 1,\n invocations: [\n ...priorInvocations,\n {\n command,\n cwd: options.cwd ?? process.cwd(),\n created_at: now.toISOString(),\n run_id: layout.runId,\n run_root: layout.runRoot,\n report_path: layout.reportPath,\n model_reports_dir: layout.modelReportsDir,\n },\n ],\n };\n}\n\nfunction buildNextActions(layout: LifecyclemodelValidateBuildLayout): string[] {\n return [\n `inspect: ${layout.reportPath}`,\n `inspect: ${layout.modelReportsDir}`,\n `run: tiangong lifecyclemodel publish-build --run-dir ${layout.runRoot}`,\n ];\n}\n\nfunction resolveValidationImpl(\n deps: LifecyclemodelValidateBuildDeps,\n): (options: RunValidationOptions) => Promise<ValidationRunReport> {\n return deps.runValidationImpl ?? runValidation;\n}\n\nfunction resolveReportEngine(\n modelReports: LifecyclemodelValidateBuildModelReport[],\n requestedEngine?: string,\n): string {\n return modelReports[0]?.validation.mode ?? requestedEngine ?? 'auto';\n}\n\nexport async function runLifecyclemodelValidateBuild(\n options: RunLifecyclemodelValidateBuildOptions,\n deps: LifecyclemodelValidateBuildDeps = {},\n): Promise<LifecyclemodelValidateBuildReport> {\n const now = options.now ?? new Date();\n const layout = resolveLayout(options);\n ensureRunRootExists(layout);\n readRequiredRunManifest(layout);\n const invocationIndex = readInvocationIndex(layout);\n const validationImpl = resolveValidationImpl(deps);\n const modelEntries = discoverModelEntries(layout);\n\n const modelReports: LifecyclemodelValidateBuildModelReport[] = [];\n for (const entry of modelEntries) {\n const reportFile = path.join(layout.modelReportsDir, `${entry.runName}.json`);\n const validation = await validationImpl({\n inputDir: entry.inputDir,\n engine: options.engine,\n reportFile,\n });\n modelReports.push({\n run_name: entry.runName,\n input_dir: entry.inputDir,\n model_files: entry.modelFiles,\n report_file: reportFile,\n validation,\n });\n }\n\n const okCount = modelReports.filter((entry) => entry.validation.ok).length;\n const report: LifecyclemodelValidateBuildReport = {\n schema_version: 1,\n generated_at_utc: now.toISOString(),\n status: 'completed_lifecyclemodel_validate_build',\n run_id: layout.runId,\n run_root: layout.runRoot,\n ok: okCount === modelReports.length,\n engine: resolveReportEngine(modelReports, options.engine),\n counts: {\n models: modelReports.length,\n ok: okCount,\n failed: modelReports.length - okCount,\n },\n files: {\n run_manifest: layout.runManifestPath,\n invocation_index: layout.invocationIndexPath,\n auto_build_report: existsSync(layout.autoBuildReportPath) ? layout.autoBuildReportPath : null,\n report: layout.reportPath,\n model_reports_dir: layout.modelReportsDir,\n },\n model_reports: modelReports,\n next_actions: buildNextActions(layout),\n };\n\n writeJsonArtifact(\n layout.invocationIndexPath,\n buildInvocationIndex(layout, invocationIndex, options, now),\n );\n writeJsonArtifact(layout.reportPath, report);\n return report;\n}\n\nexport const __testInternals = {\n buildLayout,\n resolveLayout,\n readInvocationIndex,\n discoverModelEntries,\n buildInvocationIndex,\n buildNextActions,\n resolveValidationImpl,\n resolveReportEngine,\n};\n"]}
|
|
1
|
+
{"version":3,"file":"lifecyclemodel-validate-build.js","sourceRoot":"","sources":["../../../src/lib/lifecyclemodel-validate-build.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readdirSync } from 'node:fs';\nimport path from 'node:path';\nimport { readJsonArtifact, writeJsonArtifact } from './artifacts.js';\nimport { CliError } from './errors.js';\nimport {\n runValidation,\n type RunValidationOptions,\n type ValidationRunReport,\n} from './validation.js';\n\ntype JsonObject = Record<string, unknown>;\n\ntype ModelBundleEntry = {\n runName: string;\n inputDir: string;\n modelFiles: string[];\n};\n\nfunction isRecord(value: unknown): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction nonEmptyString(value: unknown): string | null {\n if (typeof value !== 'string') {\n return null;\n }\n\n const normalized = value.trim();\n return normalized || null;\n}\n\nfunction readRequiredJsonObject(\n filePath: string,\n missingCode: string,\n invalidCode: string,\n label: string,\n): JsonObject {\n if (!existsSync(filePath)) {\n throw new CliError(`Required lifecyclemodel ${label} artifact not found: ${filePath}`, {\n code: missingCode,\n exitCode: 2,\n details: { filePath, label },\n });\n }\n\n const value = readJsonArtifact(filePath);\n if (!isRecord(value)) {\n throw new CliError(`Expected lifecyclemodel ${label} artifact JSON object: ${filePath}`, {\n code: invalidCode,\n exitCode: 2,\n details: { filePath, label },\n });\n }\n\n return value;\n}\n\nexport type LifecyclemodelValidateBuildLayout = {\n runId: string;\n runRoot: string;\n modelsDir: string;\n reportsDir: string;\n modelReportsDir: string;\n manifestsDir: string;\n runManifestPath: string;\n invocationIndexPath: string;\n autoBuildReportPath: string;\n reportPath: string;\n};\n\nexport type LifecyclemodelValidateBuildModelReport = {\n run_name: string;\n input_dir: string;\n model_files: string[];\n report_file: string;\n validation: ValidationRunReport;\n};\n\nexport type LifecyclemodelValidateBuildReport = {\n schema_version: 1;\n generated_at_utc: string;\n status: 'completed_lifecyclemodel_validate_build';\n run_id: string;\n run_root: string;\n ok: boolean;\n engine: string;\n counts: {\n models: number;\n ok: number;\n failed: number;\n };\n files: {\n run_manifest: string;\n invocation_index: string;\n auto_build_report: string | null;\n report: string;\n model_reports_dir: string;\n };\n model_reports: LifecyclemodelValidateBuildModelReport[];\n next_actions: string[];\n};\n\nexport type RunLifecyclemodelValidateBuildOptions = {\n runDir: string;\n engine?: string;\n now?: Date;\n cwd?: string;\n};\n\nexport type LifecyclemodelValidateBuildDeps = {\n runValidationImpl?: (options: RunValidationOptions) => Promise<ValidationRunReport>;\n};\n\nfunction buildLayout(runRoot: string): LifecyclemodelValidateBuildLayout {\n const runId = path.basename(runRoot);\n return {\n runId,\n runRoot,\n modelsDir: path.join(runRoot, 'models'),\n reportsDir: path.join(runRoot, 'reports'),\n modelReportsDir: path.join(runRoot, 'reports', 'model-validations'),\n manifestsDir: path.join(runRoot, 'manifests'),\n runManifestPath: path.join(runRoot, 'manifests', 'run-manifest.json'),\n invocationIndexPath: path.join(runRoot, 'manifests', 'invocation-index.json'),\n autoBuildReportPath: path.join(runRoot, 'reports', 'lifecyclemodel-auto-build-report.json'),\n reportPath: path.join(runRoot, 'reports', 'lifecyclemodel-validate-build-report.json'),\n };\n}\n\nfunction resolveLayout(\n options: RunLifecyclemodelValidateBuildOptions,\n): LifecyclemodelValidateBuildLayout {\n const runDir = nonEmptyString(options.runDir);\n if (!runDir) {\n throw new CliError('Missing required --run-dir for lifecyclemodel validate-build.', {\n code: 'LIFECYCLEMODEL_VALIDATE_RUN_DIR_REQUIRED',\n exitCode: 2,\n });\n }\n\n return buildLayout(path.resolve(runDir));\n}\n\nfunction ensureRunRootExists(layout: LifecyclemodelValidateBuildLayout): void {\n if (!existsSync(layout.runRoot)) {\n throw new CliError(`lifecyclemodel validate-build run root not found: ${layout.runRoot}`, {\n code: 'LIFECYCLEMODEL_VALIDATE_RUN_NOT_FOUND',\n exitCode: 2,\n });\n }\n}\n\nfunction readRequiredRunManifest(layout: LifecyclemodelValidateBuildLayout): JsonObject {\n const manifest = readRequiredJsonObject(\n layout.runManifestPath,\n 'LIFECYCLEMODEL_VALIDATE_RUN_MANIFEST_MISSING',\n 'LIFECYCLEMODEL_VALIDATE_RUN_MANIFEST_INVALID',\n 'run-manifest',\n );\n\n const manifestRunId = nonEmptyString(manifest.runId);\n if (manifestRunId && manifestRunId !== layout.runId) {\n throw new CliError(\n `lifecyclemodel validate-build run manifest runId mismatch: ${layout.runManifestPath}`,\n {\n code: 'LIFECYCLEMODEL_VALIDATE_RUN_MANIFEST_MISMATCH',\n exitCode: 2,\n details: {\n expected: layout.runId,\n actual: manifestRunId,\n },\n },\n );\n }\n\n return manifest;\n}\n\nfunction readInvocationIndex(layout: LifecyclemodelValidateBuildLayout): JsonObject {\n if (!existsSync(layout.invocationIndexPath)) {\n return {\n schema_version: 1,\n invocations: [],\n };\n }\n\n const value = readJsonArtifact(layout.invocationIndexPath);\n if (!isRecord(value)) {\n throw new CliError(\n `Expected lifecyclemodel validate invocation index JSON object: ${layout.invocationIndexPath}`,\n {\n code: 'LIFECYCLEMODEL_VALIDATE_INVOCATION_INDEX_INVALID',\n exitCode: 2,\n },\n );\n }\n\n if (value.invocations === undefined) {\n return {\n schema_version: 1,\n invocations: [],\n };\n }\n\n if (!Array.isArray(value.invocations)) {\n throw new CliError(\n `Expected lifecyclemodel validate invocation index to contain an invocations array: ${layout.invocationIndexPath}`,\n {\n code: 'LIFECYCLEMODEL_VALIDATE_INVOCATION_INDEX_INVALID',\n exitCode: 2,\n },\n );\n }\n\n return value;\n}\n\nfunction discoverModelEntries(layout: LifecyclemodelValidateBuildLayout): ModelBundleEntry[] {\n const runNames = existsSync(layout.modelsDir) ? readdirSync(layout.modelsDir).sort() : [];\n const entries = runNames.flatMap((runName) => {\n const inputDir = path.join(layout.modelsDir, runName, 'tidas_bundle');\n const lifecyclemodelsDir = path.join(inputDir, 'lifecyclemodels');\n if (!existsSync(lifecyclemodelsDir)) {\n return [];\n }\n\n const modelFiles = readdirSync(lifecyclemodelsDir)\n .filter((entry) => entry.endsWith('.json'))\n .sort()\n .map((entry) => path.join(lifecyclemodelsDir, entry));\n\n if (modelFiles.length === 0) {\n throw new CliError(\n `lifecyclemodel validate-build found a bundle without lifecyclemodel JSON files: ${lifecyclemodelsDir}`,\n {\n code: 'LIFECYCLEMODEL_VALIDATE_MODELS_EMPTY',\n exitCode: 2,\n },\n );\n }\n\n return [{ runName, inputDir, modelFiles }];\n });\n\n if (entries.length === 0) {\n throw new CliError(\n `lifecyclemodel validate-build run does not contain any model bundles: ${layout.modelsDir}`,\n {\n code: 'LIFECYCLEMODEL_VALIDATE_MODELS_NOT_FOUND',\n exitCode: 2,\n },\n );\n }\n\n return entries;\n}\n\nfunction buildInvocationIndex(\n layout: LifecyclemodelValidateBuildLayout,\n invocationIndex: JsonObject,\n options: RunLifecyclemodelValidateBuildOptions,\n now: Date,\n): JsonObject {\n const priorInvocations = Array.isArray(invocationIndex.invocations)\n ? [...invocationIndex.invocations]\n : [];\n const command = ['lifecyclemodel', 'validate-build', '--run-dir', options.runDir];\n if (options.engine) {\n command.push('--engine', options.engine);\n }\n\n return {\n ...invocationIndex,\n schema_version:\n typeof invocationIndex.schema_version === 'number' ? invocationIndex.schema_version : 1,\n invocations: [\n ...priorInvocations,\n {\n command,\n cwd: options.cwd ?? process.cwd(),\n created_at: now.toISOString(),\n run_id: layout.runId,\n run_root: layout.runRoot,\n report_path: layout.reportPath,\n model_reports_dir: layout.modelReportsDir,\n },\n ],\n };\n}\n\nfunction buildNextActions(layout: LifecyclemodelValidateBuildLayout): string[] {\n return [\n `inspect: ${layout.reportPath}`,\n `inspect: ${layout.modelReportsDir}`,\n `run: tiangong-lca lifecyclemodel publish-build --run-dir ${layout.runRoot}`,\n ];\n}\n\nfunction resolveValidationImpl(\n deps: LifecyclemodelValidateBuildDeps,\n): (options: RunValidationOptions) => Promise<ValidationRunReport> {\n return deps.runValidationImpl ?? runValidation;\n}\n\nfunction resolveReportEngine(\n modelReports: LifecyclemodelValidateBuildModelReport[],\n requestedEngine?: string,\n): string {\n return modelReports[0]?.validation.mode ?? requestedEngine ?? 'auto';\n}\n\nexport async function runLifecyclemodelValidateBuild(\n options: RunLifecyclemodelValidateBuildOptions,\n deps: LifecyclemodelValidateBuildDeps = {},\n): Promise<LifecyclemodelValidateBuildReport> {\n const now = options.now ?? new Date();\n const layout = resolveLayout(options);\n ensureRunRootExists(layout);\n readRequiredRunManifest(layout);\n const invocationIndex = readInvocationIndex(layout);\n const validationImpl = resolveValidationImpl(deps);\n const modelEntries = discoverModelEntries(layout);\n\n const modelReports: LifecyclemodelValidateBuildModelReport[] = [];\n for (const entry of modelEntries) {\n const reportFile = path.join(layout.modelReportsDir, `${entry.runName}.json`);\n const validation = await validationImpl({\n inputDir: entry.inputDir,\n engine: options.engine,\n reportFile,\n });\n modelReports.push({\n run_name: entry.runName,\n input_dir: entry.inputDir,\n model_files: entry.modelFiles,\n report_file: reportFile,\n validation,\n });\n }\n\n const okCount = modelReports.filter((entry) => entry.validation.ok).length;\n const report: LifecyclemodelValidateBuildReport = {\n schema_version: 1,\n generated_at_utc: now.toISOString(),\n status: 'completed_lifecyclemodel_validate_build',\n run_id: layout.runId,\n run_root: layout.runRoot,\n ok: okCount === modelReports.length,\n engine: resolveReportEngine(modelReports, options.engine),\n counts: {\n models: modelReports.length,\n ok: okCount,\n failed: modelReports.length - okCount,\n },\n files: {\n run_manifest: layout.runManifestPath,\n invocation_index: layout.invocationIndexPath,\n auto_build_report: existsSync(layout.autoBuildReportPath) ? layout.autoBuildReportPath : null,\n report: layout.reportPath,\n model_reports_dir: layout.modelReportsDir,\n },\n model_reports: modelReports,\n next_actions: buildNextActions(layout),\n };\n\n writeJsonArtifact(\n layout.invocationIndexPath,\n buildInvocationIndex(layout, invocationIndex, options, now),\n );\n writeJsonArtifact(layout.reportPath, report);\n return report;\n}\n\nexport const __testInternals = {\n buildLayout,\n resolveLayout,\n readInvocationIndex,\n discoverModelEntries,\n buildInvocationIndex,\n buildNextActions,\n resolveValidationImpl,\n resolveReportEngine,\n};\n"]}
|
|
@@ -269,7 +269,7 @@ function buildProcessAutoBuildRunId(flowFilePath, operation, summary, now = new
|
|
|
269
269
|
const operationToken = operation === 'treat' ? 'treat' : 'produce';
|
|
270
270
|
return `pfw_${flowCode}_${flowUuidShort}_${operationToken}_${buildUtcTimestamp(now)}`;
|
|
271
271
|
}
|
|
272
|
-
function resolveRunRoot(requestDir,
|
|
272
|
+
function resolveRunRoot(requestDir, outDirOverride, requestRunRoot) {
|
|
273
273
|
const override = nonEmptyString(outDirOverride);
|
|
274
274
|
if (override) {
|
|
275
275
|
return path.resolve(requestDir, override);
|
|
@@ -278,7 +278,10 @@ function resolveRunRoot(requestDir, runId, outDirOverride, requestRunRoot) {
|
|
|
278
278
|
if (requestValue) {
|
|
279
279
|
return path.resolve(requestDir, requestValue);
|
|
280
280
|
}
|
|
281
|
-
|
|
281
|
+
throw new CliError('Missing required process auto-build run root. Provide --out-dir or request.workspace_run_root.', {
|
|
282
|
+
code: 'PROCESS_AUTO_BUILD_RUN_ROOT_REQUIRED',
|
|
283
|
+
exitCode: 2,
|
|
284
|
+
});
|
|
282
285
|
}
|
|
283
286
|
function normalizeSourceInputType(value) {
|
|
284
287
|
const normalized = nonEmptyString(value);
|
|
@@ -376,6 +379,7 @@ function buildLayout(runRoot, runId) {
|
|
|
376
379
|
sourcePolicyPath: path.join(runRoot, 'request', 'source-policy.json'),
|
|
377
380
|
flowSummaryPath: path.join(runRoot, 'manifests', 'flow-summary.json'),
|
|
378
381
|
inputManifestPath: path.join(runRoot, 'input', 'input_manifest.json'),
|
|
382
|
+
buildPlanPath: path.join(runRoot, 'manifests', 'process-build-plan.json'),
|
|
379
383
|
assemblyPlanPath: path.join(runRoot, 'manifests', 'assembly-plan.json'),
|
|
380
384
|
lineageManifestPath: path.join(runRoot, 'manifests', 'lineage-manifest.json'),
|
|
381
385
|
invocationIndexPath: path.join(runRoot, 'manifests', 'invocation-index.json'),
|
|
@@ -452,6 +456,147 @@ function buildAssemblyPlan(runRoot) {
|
|
|
452
456
|
})),
|
|
453
457
|
};
|
|
454
458
|
}
|
|
459
|
+
function flowReferencePropertySummary(flowDataset) {
|
|
460
|
+
const flowInformation = isRecord(flowDataset.flowInformation) ? flowDataset.flowInformation : {};
|
|
461
|
+
const quantitativeReference = isRecord(flowInformation.quantitativeReference)
|
|
462
|
+
? flowInformation.quantitativeReference
|
|
463
|
+
: {};
|
|
464
|
+
const referenceId = nonEmptyString(quantitativeReference.referenceToReferenceFlowProperty);
|
|
465
|
+
const flowProperties = isRecord(flowDataset.flowProperties) ? flowDataset.flowProperties : {};
|
|
466
|
+
const propertyRows = Array.isArray(flowProperties.flowProperty)
|
|
467
|
+
? flowProperties.flowProperty
|
|
468
|
+
: flowProperties.flowProperty
|
|
469
|
+
? [flowProperties.flowProperty]
|
|
470
|
+
: [];
|
|
471
|
+
const referenceProperty = propertyRows.find((entry) => isRecord(entry) && nonEmptyString(entry['@dataSetInternalID']) === (referenceId ?? '0'));
|
|
472
|
+
const propertyRef = isRecord(referenceProperty) && isRecord(referenceProperty.referenceToFlowPropertyDataSet)
|
|
473
|
+
? referenceProperty.referenceToFlowPropertyDataSet
|
|
474
|
+
: {};
|
|
475
|
+
const shortDescription = isRecord(propertyRef['common:shortDescription'])
|
|
476
|
+
? propertyRef['common:shortDescription']
|
|
477
|
+
: {};
|
|
478
|
+
const propertyText = extractText(shortDescription) ?? extractText(propertyRef['common:shortDescription']);
|
|
479
|
+
return {
|
|
480
|
+
reference_property: propertyText ?? 'Reference flow property',
|
|
481
|
+
reference_property_id: nonEmptyString(propertyRef['@refObjectId']),
|
|
482
|
+
reference_unit: null,
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
function buildInitialProcessBuildPlan(normalized, flowArtifactPath) {
|
|
486
|
+
const flowProperty = flowReferencePropertySummary(normalized.flow_dataset);
|
|
487
|
+
const referenceFlowId = normalized.flow_summary.uuid ??
|
|
488
|
+
nonEmptyString(normalized.flow_dataset['@id']) ??
|
|
489
|
+
sanitizeRunToken(normalized.flow_summary.base_name ?? normalized.run_id, 'reference-flow');
|
|
490
|
+
const referenceFlowVersion = normalized.flow_summary.version ?? '00.00.000';
|
|
491
|
+
const baseName = normalized.flow_summary.base_name
|
|
492
|
+
? `${normalized.operation === 'treat' ? 'Treatment of' : 'Production of'} ${normalized.flow_summary.base_name}`
|
|
493
|
+
: `${normalized.operation === 'treat' ? 'Treatment' : 'Production'} process from reference flow`;
|
|
494
|
+
return {
|
|
495
|
+
schema_version: 1,
|
|
496
|
+
kind: 'process',
|
|
497
|
+
ruleset: {
|
|
498
|
+
id: 'process-authoring/strict',
|
|
499
|
+
version: '1',
|
|
500
|
+
},
|
|
501
|
+
target: {
|
|
502
|
+
geography: 'GLO',
|
|
503
|
+
technology_route: normalized.operation === 'treat'
|
|
504
|
+
? 'Treatment route to be evidenced during process auto-build'
|
|
505
|
+
: 'Production route to be evidenced during process auto-build',
|
|
506
|
+
classification_path: [
|
|
507
|
+
'Technosphere',
|
|
508
|
+
normalized.operation === 'treat' ? 'Treatment' : 'Production',
|
|
509
|
+
flowProperty.reference_property,
|
|
510
|
+
normalized.flow_summary.base_name ?? 'Reference flow',
|
|
511
|
+
],
|
|
512
|
+
},
|
|
513
|
+
identity_decision: {
|
|
514
|
+
decision: 'create_new',
|
|
515
|
+
rationale: 'Initial process auto-build scaffold; identity preflight must be rerun with remote/local candidates before write.',
|
|
516
|
+
},
|
|
517
|
+
evidence_manifest: {
|
|
518
|
+
sources: [
|
|
519
|
+
{
|
|
520
|
+
id: `flow:${referenceFlowId}`,
|
|
521
|
+
type: 'input_flow_dataset',
|
|
522
|
+
path: flowArtifactPath,
|
|
523
|
+
title: normalized.flow_summary.base_name ?? referenceFlowId,
|
|
524
|
+
version: referenceFlowVersion,
|
|
525
|
+
},
|
|
526
|
+
...normalized.source_inputs.map((source) => ({
|
|
527
|
+
id: source.source_id,
|
|
528
|
+
type: source.type,
|
|
529
|
+
path: source.artifact_path,
|
|
530
|
+
title: source.artifact_file_name,
|
|
531
|
+
intended_roles: source.intended_roles,
|
|
532
|
+
})),
|
|
533
|
+
],
|
|
534
|
+
field_bindings: [
|
|
535
|
+
{ field_path: 'target', source_id: `flow:${referenceFlowId}` },
|
|
536
|
+
{ field_path: 'identity_decision.decision', source_id: `flow:${referenceFlowId}` },
|
|
537
|
+
{ field_path: 'unit_of_analysis', source_id: `flow:${referenceFlowId}` },
|
|
538
|
+
{ field_path: 'name_plan.base_name', source_id: `flow:${referenceFlowId}` },
|
|
539
|
+
{ field_path: 'target.geography', source_id: `flow:${referenceFlowId}` },
|
|
540
|
+
{ field_path: 'target.technology_route', source_id: `flow:${referenceFlowId}` },
|
|
541
|
+
{
|
|
542
|
+
field_path: 'quantitative_reference_plan.reference_flow_id',
|
|
543
|
+
source_id: `flow:${referenceFlowId}`,
|
|
544
|
+
},
|
|
545
|
+
],
|
|
546
|
+
},
|
|
547
|
+
unit_of_analysis: {
|
|
548
|
+
target_kind: normalized.operation === 'treat' ? 'treatment' : 'process_from_flow_scaffold',
|
|
549
|
+
decision: 'manual_review',
|
|
550
|
+
functional_unit: {
|
|
551
|
+
what: normalized.operation === 'treat'
|
|
552
|
+
? `treat ${normalized.flow_summary.base_name ?? 'the reference flow'}`
|
|
553
|
+
: `produce ${normalized.flow_summary.base_name ?? 'the reference flow'}`,
|
|
554
|
+
how_much: `1 ${flowProperty.reference_unit ?? flowProperty.reference_property}`,
|
|
555
|
+
how_well: 'to be determined from source evidence before materialization',
|
|
556
|
+
how_long: 'not determined in the initial scaffold',
|
|
557
|
+
},
|
|
558
|
+
reference_flow: {
|
|
559
|
+
flow_identity: normalized.flow_summary.base_name ?? referenceFlowId,
|
|
560
|
+
reference_unit: flowProperty.reference_unit ?? flowProperty.reference_property,
|
|
561
|
+
reference_amount: 1,
|
|
562
|
+
flow_property: flowProperty.reference_property,
|
|
563
|
+
},
|
|
564
|
+
declared_unit_allowed: false,
|
|
565
|
+
scaling_evidence_status: 'source_required',
|
|
566
|
+
notes: [
|
|
567
|
+
'Initial scaffold only. A skill/Codex workflow must revise unit_of_analysis before build-plan materialize.',
|
|
568
|
+
],
|
|
569
|
+
},
|
|
570
|
+
name_plan: {
|
|
571
|
+
base_name: baseName,
|
|
572
|
+
treatment_standards_routes: normalized.operation === 'treat' ? 'treatment route' : 'production route',
|
|
573
|
+
mix_and_location_types: 'global average',
|
|
574
|
+
functional_unit_flow_properties: flowProperty.reference_unit ?? flowProperty.reference_property,
|
|
575
|
+
},
|
|
576
|
+
quantitative_reference_plan: {
|
|
577
|
+
reference_flow_id: referenceFlowId,
|
|
578
|
+
reference_flow_version: referenceFlowVersion,
|
|
579
|
+
reference_flow_name: normalized.flow_summary.base_name ?? referenceFlowId,
|
|
580
|
+
reference_flow_internal_id: '1',
|
|
581
|
+
mean_amount: '1.0',
|
|
582
|
+
resulting_amount: '1.0',
|
|
583
|
+
reference_unit: flowProperty.reference_unit ?? flowProperty.reference_property,
|
|
584
|
+
},
|
|
585
|
+
flow_property_plan: flowProperty,
|
|
586
|
+
exchange_plan: {
|
|
587
|
+
exchanges: [],
|
|
588
|
+
},
|
|
589
|
+
materialization_readiness: {
|
|
590
|
+
status: 'scaffold_only',
|
|
591
|
+
next_required_steps: [
|
|
592
|
+
'replace scaffold unit_of_analysis with a skill-authored decision artifact',
|
|
593
|
+
'run process identity-preflight with local and remote candidates',
|
|
594
|
+
'replace scaffold geography, technology, classification, exchange values, and annual volume with evidence-backed values',
|
|
595
|
+
'run process build-plan validate/materialize before save-draft or publish-build',
|
|
596
|
+
],
|
|
597
|
+
},
|
|
598
|
+
};
|
|
599
|
+
}
|
|
455
600
|
function buildLineageManifest(normalized) {
|
|
456
601
|
return {
|
|
457
602
|
schema_version: 1,
|
|
@@ -537,13 +682,13 @@ function buildInitialState(normalized, flowArtifactPath, now) {
|
|
|
537
682
|
step_markers: buildStepMarkers(now),
|
|
538
683
|
};
|
|
539
684
|
}
|
|
540
|
-
function buildNextActions(layout
|
|
685
|
+
function buildNextActions(layout) {
|
|
541
686
|
return [
|
|
542
687
|
`inspect: ${layout.normalizedRequestPath}`,
|
|
543
688
|
`inspect: ${layout.statePath}`,
|
|
544
689
|
`inspect: ${layout.assemblyPlanPath}`,
|
|
545
|
-
`future: tiangong process resume-build --run-
|
|
546
|
-
`future: tiangong process publish-build --run-
|
|
690
|
+
`future: tiangong-lca process resume-build --run-dir ${layout.runRoot}`,
|
|
691
|
+
`future: tiangong-lca process publish-build --run-dir ${layout.runRoot}`,
|
|
547
692
|
];
|
|
548
693
|
}
|
|
549
694
|
function buildAgentHandoffSummary(normalized, layout, flowArtifactPath, now) {
|
|
@@ -572,9 +717,10 @@ function buildAgentHandoffSummary(normalized, layout, flowArtifactPath, now) {
|
|
|
572
717
|
request_snapshot: layout.requestSnapshotPath,
|
|
573
718
|
normalized_request: layout.normalizedRequestPath,
|
|
574
719
|
assembly_plan: layout.assemblyPlanPath,
|
|
720
|
+
build_plan: layout.buildPlanPath,
|
|
575
721
|
flow_copy: flowArtifactPath,
|
|
576
722
|
},
|
|
577
|
-
next_actions: buildNextActions(layout
|
|
723
|
+
next_actions: buildNextActions(layout),
|
|
578
724
|
extra: {
|
|
579
725
|
status: 'prepared_local_process_auto_build_run',
|
|
580
726
|
request_id: normalized.request_id,
|
|
@@ -608,6 +754,7 @@ function buildReport(normalized, layout, flowArtifactPath, now) {
|
|
|
608
754
|
source_policy: layout.sourcePolicyPath,
|
|
609
755
|
flow_summary: layout.flowSummaryPath,
|
|
610
756
|
input_manifest: layout.inputManifestPath,
|
|
757
|
+
build_plan: layout.buildPlanPath,
|
|
611
758
|
assembly_plan: layout.assemblyPlanPath,
|
|
612
759
|
lineage_manifest: layout.lineageManifestPath,
|
|
613
760
|
invocation_index: layout.invocationIndexPath,
|
|
@@ -616,7 +763,7 @@ function buildReport(normalized, layout, flowArtifactPath, now) {
|
|
|
616
763
|
handoff_summary: layout.handoffSummaryPath,
|
|
617
764
|
report: layout.reportPath,
|
|
618
765
|
},
|
|
619
|
-
next_actions: buildNextActions(layout
|
|
766
|
+
next_actions: buildNextActions(layout),
|
|
620
767
|
};
|
|
621
768
|
}
|
|
622
769
|
export function normalizeProcessAutoBuildRequest(input, options) {
|
|
@@ -630,7 +777,7 @@ export function normalizeProcessAutoBuildRequest(input, options) {
|
|
|
630
777
|
const runId = nonEmptyString(options.runIdOverride) ??
|
|
631
778
|
nonEmptyString(request.run_id) ??
|
|
632
779
|
buildProcessAutoBuildRunId(flowFile, operation, flowSummary, options.now);
|
|
633
|
-
const runRoot = resolveRunRoot(requestDir,
|
|
780
|
+
const runRoot = resolveRunRoot(requestDir, options.outDir, request.workspace_run_root);
|
|
634
781
|
const layout = buildLayout(runRoot, runId);
|
|
635
782
|
return {
|
|
636
783
|
schema_version: 1,
|
|
@@ -676,7 +823,9 @@ export async function runProcessAutoBuild(options) {
|
|
|
676
823
|
flow_path: normalized.flow_file,
|
|
677
824
|
flow_artifact_path: flowArtifactPath,
|
|
678
825
|
operation: normalized.operation,
|
|
826
|
+
build_plan_path: layout.buildPlanPath,
|
|
679
827
|
});
|
|
828
|
+
writeJsonArtifact(layout.buildPlanPath, buildInitialProcessBuildPlan(normalized, flowArtifactPath));
|
|
680
829
|
writeJsonArtifact(layout.assemblyPlanPath, buildAssemblyPlan(layout.runRoot));
|
|
681
830
|
writeJsonArtifact(layout.lineageManifestPath, buildLineageManifest(normalized));
|
|
682
831
|
writeJsonArtifact(layout.invocationIndexPath, buildInvocationIndex(normalized, options, layout.reportPath, now));
|
|
@@ -708,6 +857,7 @@ export const __testInternals = {
|
|
|
708
857
|
buildProcessAutoBuildRunId,
|
|
709
858
|
buildLayout,
|
|
710
859
|
buildAssemblyPlan,
|
|
860
|
+
buildInitialProcessBuildPlan,
|
|
711
861
|
buildLineageManifest,
|
|
712
862
|
buildInvocationIndex,
|
|
713
863
|
buildInitialState,
|