@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
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { existsSync, readdirSync } from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { readJsonArtifact, writeJsonArtifact, writeJsonLinesArtifact, writeTextArtifact, } from './artifacts.js';
|
|
4
|
+
import { materializeDatasetRows } from './dataset-local.js';
|
|
4
5
|
import { CliError } from './errors.js';
|
|
5
6
|
function isRecord(value) {
|
|
6
7
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
@@ -56,6 +57,11 @@ function uniqueStrings(values) {
|
|
|
56
57
|
function copyJson(value) {
|
|
57
58
|
return JSON.parse(JSON.stringify(value));
|
|
58
59
|
}
|
|
60
|
+
function sanitizeFileName(value) {
|
|
61
|
+
return (String(value ?? 'missing')
|
|
62
|
+
.replace(/[^A-Za-z0-9._-]+/gu, '_')
|
|
63
|
+
.replace(/^_+|_+$/gu, '') || 'missing');
|
|
64
|
+
}
|
|
59
65
|
function emptySeverityCounts() {
|
|
60
66
|
return {
|
|
61
67
|
error: 0,
|
|
@@ -115,11 +121,15 @@ function readOptionalJsonArray(filePath, invalidCode, label) {
|
|
|
115
121
|
}
|
|
116
122
|
return value;
|
|
117
123
|
}
|
|
118
|
-
function buildLayout(
|
|
124
|
+
function buildLayout(options) {
|
|
125
|
+
const runRoot = options.runRoot;
|
|
126
|
+
const outDir = options.outDir;
|
|
119
127
|
const runId = path.basename(runRoot);
|
|
120
128
|
return {
|
|
121
129
|
runId,
|
|
122
130
|
runRoot,
|
|
131
|
+
rowsFile: options.rowsFile ?? '',
|
|
132
|
+
inputMode: options.inputMode ?? 'run_dir',
|
|
123
133
|
outDir,
|
|
124
134
|
modelsDir: path.join(runRoot, 'models'),
|
|
125
135
|
reportsDir: path.join(runRoot, 'reports'),
|
|
@@ -127,6 +137,7 @@ function buildLayout(runRoot, outDir) {
|
|
|
127
137
|
runManifestPath: path.join(runRoot, 'manifests', 'run-manifest.json'),
|
|
128
138
|
invocationIndexPath: path.join(runRoot, 'manifests', 'invocation-index.json'),
|
|
129
139
|
validationReportPath: path.join(runRoot, 'reports', 'lifecyclemodel-validate-build-report.json'),
|
|
140
|
+
qaInputSummaryPath: options.inputMode === 'rows_file' ? path.join(outDir, 'qa_input_summary.json') : null,
|
|
130
141
|
modelSummariesPath: path.join(outDir, 'model_summaries.jsonl'),
|
|
131
142
|
findingsPath: path.join(outDir, 'findings.jsonl'),
|
|
132
143
|
summaryPath: path.join(outDir, 'lifecyclemodel_qa_summary.json'),
|
|
@@ -137,13 +148,6 @@ function buildLayout(runRoot, outDir) {
|
|
|
137
148
|
};
|
|
138
149
|
}
|
|
139
150
|
function resolveLayout(options) {
|
|
140
|
-
const runDir = nonEmptyString(options.runDir);
|
|
141
|
-
if (!runDir) {
|
|
142
|
-
throw new CliError('Missing required --run-dir for qa lifecyclemodel.', {
|
|
143
|
-
code: 'LIFECYCLEMODEL_QA_RUN_DIR_REQUIRED',
|
|
144
|
-
exitCode: 2,
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
151
|
const outDir = nonEmptyString(options.outDir);
|
|
148
152
|
if (!outDir) {
|
|
149
153
|
throw new CliError('Missing required --out-dir for qa lifecyclemodel.', {
|
|
@@ -151,7 +155,34 @@ function resolveLayout(options) {
|
|
|
151
155
|
exitCode: 2,
|
|
152
156
|
});
|
|
153
157
|
}
|
|
154
|
-
|
|
158
|
+
const rowsFile = nonEmptyString(options.rowsFile);
|
|
159
|
+
const runDir = nonEmptyString(options.runDir);
|
|
160
|
+
if (rowsFile && runDir) {
|
|
161
|
+
throw new CliError('Use either --rows-file or --run-dir for qa lifecyclemodel, not both.', {
|
|
162
|
+
code: 'LIFECYCLEMODEL_QA_INPUT_MODE_CONFLICT',
|
|
163
|
+
exitCode: 2,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
if (rowsFile) {
|
|
167
|
+
const resolvedRowsFile = path.resolve(rowsFile);
|
|
168
|
+
return buildLayout({
|
|
169
|
+
runRoot: path.join(path.resolve(outDir), 'qa-input', sanitizeFileName(path.basename(rowsFile))),
|
|
170
|
+
rowsFile: resolvedRowsFile,
|
|
171
|
+
inputMode: 'rows_file',
|
|
172
|
+
outDir: path.resolve(outDir),
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
if (!runDir) {
|
|
176
|
+
throw new CliError('Missing required --rows-file or --run-dir for qa lifecyclemodel.', {
|
|
177
|
+
code: 'LIFECYCLEMODEL_QA_RUN_DIR_REQUIRED',
|
|
178
|
+
exitCode: 2,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
return buildLayout({
|
|
182
|
+
runRoot: path.resolve(runDir),
|
|
183
|
+
outDir: path.resolve(outDir),
|
|
184
|
+
inputMode: 'run_dir',
|
|
185
|
+
});
|
|
155
186
|
}
|
|
156
187
|
function ensureRunRootExists(layout) {
|
|
157
188
|
if (!existsSync(layout.runRoot)) {
|
|
@@ -228,6 +259,7 @@ function discoverModelEntries(layout) {
|
|
|
228
259
|
summaryPath: path.join(layout.modelsDir, runName, 'summary.json'),
|
|
229
260
|
connectionsPath: path.join(layout.modelsDir, runName, 'connections.json'),
|
|
230
261
|
processCatalogPath: path.join(layout.modelsDir, runName, 'process-catalog.json'),
|
|
262
|
+
inputMode: layout.inputMode,
|
|
231
263
|
},
|
|
232
264
|
];
|
|
233
265
|
});
|
|
@@ -239,6 +271,69 @@ function discoverModelEntries(layout) {
|
|
|
239
271
|
}
|
|
240
272
|
return entries;
|
|
241
273
|
}
|
|
274
|
+
function materializeRowsFile(layout) {
|
|
275
|
+
if (!layout.rowsFile || !existsSync(layout.rowsFile)) {
|
|
276
|
+
throw new CliError(`Lifecyclemodel QA rows file not found: ${layout.rowsFile}`, {
|
|
277
|
+
code: 'LIFECYCLEMODEL_QA_ROWS_FILE_NOT_FOUND',
|
|
278
|
+
exitCode: 2,
|
|
279
|
+
details: { rowsFile: layout.rowsFile },
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
const rows = materializeDatasetRows(layout.rowsFile);
|
|
283
|
+
const entries = [];
|
|
284
|
+
writeJsonArtifact(layout.runManifestPath, {
|
|
285
|
+
schemaVersion: 1,
|
|
286
|
+
runId: layout.runId,
|
|
287
|
+
input_mode: 'rows_file',
|
|
288
|
+
rows_file: layout.rowsFile,
|
|
289
|
+
row_count: rows.length,
|
|
290
|
+
});
|
|
291
|
+
writeJsonArtifact(layout.invocationIndexPath, {
|
|
292
|
+
schema_version: 1,
|
|
293
|
+
invocations: [],
|
|
294
|
+
});
|
|
295
|
+
rows.forEach((row) => {
|
|
296
|
+
if (row.kind && row.kind !== 'lifecyclemodel') {
|
|
297
|
+
throw new CliError(`Expected lifecyclemodel row at index ${row.index}; detected ${row.kind}.`, {
|
|
298
|
+
code: 'LIFECYCLEMODEL_QA_ROWS_FILE_KIND_MISMATCH',
|
|
299
|
+
exitCode: 2,
|
|
300
|
+
details: { index: row.index, detectedKind: row.kind },
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
const runName = sanitizeFileName(row.id ?? `row-${row.index + 1}`);
|
|
304
|
+
const modelFile = path.join(layout.modelsDir, runName, 'tidas_bundle', 'lifecyclemodels', `${runName}.json`);
|
|
305
|
+
writeJsonArtifact(modelFile, row.payload);
|
|
306
|
+
entries.push({
|
|
307
|
+
runName,
|
|
308
|
+
modelFiles: [modelFile],
|
|
309
|
+
summaryPath: path.join(layout.modelsDir, runName, 'summary.json'),
|
|
310
|
+
connectionsPath: path.join(layout.modelsDir, runName, 'connections.json'),
|
|
311
|
+
processCatalogPath: path.join(layout.modelsDir, runName, 'process-catalog.json'),
|
|
312
|
+
inputMode: 'rows_file',
|
|
313
|
+
});
|
|
314
|
+
});
|
|
315
|
+
if (layout.qaInputSummaryPath) {
|
|
316
|
+
writeJsonArtifact(layout.qaInputSummaryPath, {
|
|
317
|
+
input_mode: 'rows_file',
|
|
318
|
+
rows_file: layout.rowsFile,
|
|
319
|
+
run_root: layout.runRoot,
|
|
320
|
+
materialized_lifecyclemodel_count: entries.length,
|
|
321
|
+
materialized_models_dir: layout.modelsDir,
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
return {
|
|
325
|
+
invocationIndex: {
|
|
326
|
+
schema_version: 1,
|
|
327
|
+
invocations: [],
|
|
328
|
+
},
|
|
329
|
+
validationAggregate: {
|
|
330
|
+
ok: null,
|
|
331
|
+
reportPath: null,
|
|
332
|
+
modelReports: new Map(),
|
|
333
|
+
},
|
|
334
|
+
modelEntries: entries,
|
|
335
|
+
};
|
|
336
|
+
}
|
|
242
337
|
function normalizeValidationIssue(raw) {
|
|
243
338
|
if (!isRecord(raw)) {
|
|
244
339
|
return {
|
|
@@ -423,22 +518,22 @@ function buildModelReview(entry, validationAggregate) {
|
|
|
423
518
|
const multiplicationFactorCount = multiplicationFactors
|
|
424
519
|
? Object.keys(multiplicationFactors).length
|
|
425
520
|
: 0;
|
|
426
|
-
if (!summaryArtifact) {
|
|
521
|
+
if (entry.inputMode === 'run_dir' && !summaryArtifact) {
|
|
427
522
|
findings.push(makeFinding(entry.runName, entry.modelFiles[0] ?? null, 'warning', 'missing_model_summary', 'qa', 'Model bundle is missing summary.json generated by lifecyclemodel auto-build.', {
|
|
428
523
|
summary_path: entry.summaryPath,
|
|
429
524
|
}));
|
|
430
525
|
}
|
|
431
|
-
if (!connections) {
|
|
526
|
+
if (entry.inputMode === 'run_dir' && !connections) {
|
|
432
527
|
findings.push(makeFinding(entry.runName, entry.modelFiles[0] ?? null, 'warning', 'missing_connections_artifact', 'qa', 'Model bundle is missing connections.json generated by lifecyclemodel auto-build.', {
|
|
433
528
|
connections_path: entry.connectionsPath,
|
|
434
529
|
}));
|
|
435
530
|
}
|
|
436
|
-
if (!processCatalog) {
|
|
531
|
+
if (entry.inputMode === 'run_dir' && !processCatalog) {
|
|
437
532
|
findings.push(makeFinding(entry.runName, entry.modelFiles[0] ?? null, 'warning', 'missing_process_catalog', 'qa', 'Model bundle is missing process-catalog.json generated by lifecyclemodel auto-build.', {
|
|
438
533
|
process_catalog_path: entry.processCatalogPath,
|
|
439
534
|
}));
|
|
440
535
|
}
|
|
441
|
-
if (referenceProcessUuids.length === 0) {
|
|
536
|
+
if (entry.inputMode === 'run_dir' && referenceProcessUuids.length === 0) {
|
|
442
537
|
findings.push(makeFinding(entry.runName, entry.modelFiles[0] ?? null, 'warning', 'missing_reference_process_uuid', 'qa', 'QA could not resolve reference_process_uuid from summary.json.', {
|
|
443
538
|
summary_path: summaryArtifact ? entry.summaryPath : null,
|
|
444
539
|
}));
|
|
@@ -518,14 +613,14 @@ function buildInvocationIndex(layout, invocationIndex, options, now) {
|
|
|
518
613
|
const priorInvocations = Array.isArray(invocationIndex.invocations)
|
|
519
614
|
? [...invocationIndex.invocations]
|
|
520
615
|
: [];
|
|
521
|
-
const command = [
|
|
522
|
-
|
|
523
|
-
'
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
'--
|
|
527
|
-
|
|
528
|
-
|
|
616
|
+
const command = ['qa', 'lifecyclemodel'];
|
|
617
|
+
if (layout.inputMode === 'rows_file') {
|
|
618
|
+
command.push('--rows-file', options.rowsFile);
|
|
619
|
+
}
|
|
620
|
+
else {
|
|
621
|
+
command.push('--run-dir', options.runDir);
|
|
622
|
+
}
|
|
623
|
+
command.push('--out-dir', options.outDir);
|
|
529
624
|
if (nonEmptyString(options.logicVersion)) {
|
|
530
625
|
command.push('--logic-version', options.logicVersion);
|
|
531
626
|
}
|
|
@@ -552,6 +647,13 @@ function buildInvocationIndex(layout, invocationIndex, options, now) {
|
|
|
552
647
|
};
|
|
553
648
|
}
|
|
554
649
|
function buildNextActions(layout, validationAggregate) {
|
|
650
|
+
if (layout.inputMode === 'rows_file') {
|
|
651
|
+
return [
|
|
652
|
+
`inspect: ${layout.findingsPath}`,
|
|
653
|
+
`run: tiangong-lca dataset validate --type lifecyclemodel --input ${layout.rowsFile}`,
|
|
654
|
+
`run: tiangong-lca lifecyclemodel save-draft --input ${layout.rowsFile} --dry-run`,
|
|
655
|
+
];
|
|
656
|
+
}
|
|
555
657
|
return [
|
|
556
658
|
`inspect: ${layout.findingsPath}`,
|
|
557
659
|
validationAggregate.reportPath
|
|
@@ -566,6 +668,8 @@ function renderZhReview(options) {
|
|
|
566
668
|
`- run_id: \`${options.runId}\`\n`,
|
|
567
669
|
`- logic_version: \`${options.logicVersion}\`\n`,
|
|
568
670
|
`- run_root: \`${options.runRoot}\`\n`,
|
|
671
|
+
`- input_mode: \`${options.inputMode}\`\n`,
|
|
672
|
+
...(options.rowsFile ? [`- rows_file: \`${options.rowsFile}\`\n`] : []),
|
|
569
673
|
'\n## 总览\n',
|
|
570
674
|
`- model bundle 数量: **${options.modelSummaries.length}**\n`,
|
|
571
675
|
`- findings 数量: **${options.findings.length}**\n`,
|
|
@@ -585,7 +689,9 @@ function renderZhReview(options) {
|
|
|
585
689
|
lines.push(`|${finding.run_name}|${finding.severity}|${finding.source}|${finding.rule_id}|${finding.message.replace(/\|/gu, '/')}|\n`);
|
|
586
690
|
});
|
|
587
691
|
}
|
|
588
|
-
lines.push('\n## 说明\n',
|
|
692
|
+
lines.push('\n## 说明\n', options.inputMode === 'rows_file'
|
|
693
|
+
? '- 当前 qa lifecyclemodel rows-file 模式只做 payload-level deterministic QA,不要求 lifecyclemodel build-run 产物。\n'
|
|
694
|
+
: '- 当前 qa lifecyclemodel run-dir 模式保持 local-first / artifact-first,只读取现有 build run 与 validate-build 产物。\n', '- 当前命令不引入 Python、LangGraph 或 skill 私有 QA runtime。\n');
|
|
589
695
|
return lines.join('');
|
|
590
696
|
}
|
|
591
697
|
function renderEnReview(options) {
|
|
@@ -594,6 +700,8 @@ function renderEnReview(options) {
|
|
|
594
700
|
`- run_id: \`${options.runId}\`\n`,
|
|
595
701
|
`- logic_version: \`${options.logicVersion}\`\n`,
|
|
596
702
|
`- run_root: \`${options.runRoot}\`\n`,
|
|
703
|
+
`- input_mode: \`${options.inputMode}\`\n`,
|
|
704
|
+
...(options.rowsFile ? [`- rows_file: \`${options.rowsFile}\`\n`] : []),
|
|
597
705
|
'\n## Summary\n',
|
|
598
706
|
`- model bundles: **${options.modelSummaries.length}**\n`,
|
|
599
707
|
`- findings: **${options.findings.length}**\n`,
|
|
@@ -632,15 +740,21 @@ function renderTiming(options) {
|
|
|
632
740
|
}
|
|
633
741
|
export async function runLifecyclemodelQa(options) {
|
|
634
742
|
const layout = resolveLayout(options);
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
743
|
+
const input = layout.inputMode === 'rows_file'
|
|
744
|
+
? materializeRowsFile(layout)
|
|
745
|
+
: (() => {
|
|
746
|
+
ensureRunRootExists(layout);
|
|
747
|
+
readRequiredRunManifest(layout);
|
|
748
|
+
return {
|
|
749
|
+
invocationIndex: readInvocationIndex(layout),
|
|
750
|
+
validationAggregate: readValidationAggregate(layout),
|
|
751
|
+
modelEntries: discoverModelEntries(layout),
|
|
752
|
+
};
|
|
753
|
+
})();
|
|
640
754
|
const logicVersion = options.logicVersion?.trim() || 'lifecyclemodel-qa-v1.0';
|
|
641
755
|
const now = options.now ?? (() => new Date());
|
|
642
756
|
const generatedAt = now();
|
|
643
|
-
const reviewedModels = modelEntries.map((entry) => buildModelReview(entry, validationAggregate));
|
|
757
|
+
const reviewedModels = input.modelEntries.map((entry) => buildModelReview(entry, input.validationAggregate));
|
|
644
758
|
const modelSummaries = reviewedModels.map((model) => model.summary);
|
|
645
759
|
const findings = reviewedModels.flatMap((model) => model.findings);
|
|
646
760
|
const report = {
|
|
@@ -649,20 +763,23 @@ export async function runLifecyclemodelQa(options) {
|
|
|
649
763
|
status: 'completed_local_lifecyclemodel_qa',
|
|
650
764
|
run_id: layout.runId,
|
|
651
765
|
run_root: layout.runRoot,
|
|
766
|
+
rows_file: layout.rowsFile,
|
|
767
|
+
input_mode: layout.inputMode,
|
|
652
768
|
out_dir: layout.outDir,
|
|
653
769
|
logic_version: logicVersion,
|
|
654
770
|
model_count: modelSummaries.length,
|
|
655
771
|
finding_count: findings.length,
|
|
656
772
|
severity_counts: severityCounts(findings),
|
|
657
773
|
validation: {
|
|
658
|
-
available: validationAggregate.reportPath !== null,
|
|
659
|
-
ok: validationAggregate.ok,
|
|
660
|
-
report: validationAggregate.reportPath,
|
|
774
|
+
available: input.validationAggregate.reportPath !== null,
|
|
775
|
+
ok: input.validationAggregate.ok,
|
|
776
|
+
report: input.validationAggregate.reportPath,
|
|
661
777
|
},
|
|
662
778
|
files: {
|
|
663
779
|
run_manifest: layout.runManifestPath,
|
|
664
780
|
invocation_index: layout.invocationIndexPath,
|
|
665
|
-
|
|
781
|
+
qa_input_summary: layout.qaInputSummaryPath,
|
|
782
|
+
validation_report: input.validationAggregate.reportPath,
|
|
666
783
|
model_summaries: layout.modelSummariesPath,
|
|
667
784
|
findings: layout.findingsPath,
|
|
668
785
|
summary: layout.summaryPath,
|
|
@@ -672,13 +789,15 @@ export async function runLifecyclemodelQa(options) {
|
|
|
672
789
|
report: layout.reportPath,
|
|
673
790
|
},
|
|
674
791
|
model_summaries: modelSummaries,
|
|
675
|
-
next_actions: buildNextActions(layout, validationAggregate),
|
|
792
|
+
next_actions: buildNextActions(layout, input.validationAggregate),
|
|
676
793
|
};
|
|
677
|
-
writeJsonArtifact(layout.invocationIndexPath, buildInvocationIndex(layout, invocationIndex, options, generatedAt));
|
|
794
|
+
writeJsonArtifact(layout.invocationIndexPath, buildInvocationIndex(layout, input.invocationIndex, options, generatedAt));
|
|
678
795
|
writeJsonLinesArtifact(layout.modelSummariesPath, modelSummaries);
|
|
679
796
|
writeJsonLinesArtifact(layout.findingsPath, findings);
|
|
680
797
|
writeJsonArtifact(layout.summaryPath, {
|
|
681
798
|
run_id: report.run_id,
|
|
799
|
+
rows_file: report.rows_file,
|
|
800
|
+
input_mode: report.input_mode,
|
|
682
801
|
logic_version: report.logic_version,
|
|
683
802
|
model_count: report.model_count,
|
|
684
803
|
finding_count: report.finding_count,
|
|
@@ -689,6 +808,8 @@ export async function runLifecyclemodelQa(options) {
|
|
|
689
808
|
runId: report.run_id,
|
|
690
809
|
logicVersion: report.logic_version,
|
|
691
810
|
runRoot: report.run_root,
|
|
811
|
+
rowsFile: report.rows_file,
|
|
812
|
+
inputMode: report.input_mode,
|
|
692
813
|
modelSummaries,
|
|
693
814
|
findings,
|
|
694
815
|
validation: report.validation,
|
|
@@ -697,6 +818,8 @@ export async function runLifecyclemodelQa(options) {
|
|
|
697
818
|
runId: report.run_id,
|
|
698
819
|
logicVersion: report.logic_version,
|
|
699
820
|
runRoot: report.run_root,
|
|
821
|
+
rowsFile: report.rows_file,
|
|
822
|
+
inputMode: report.input_mode,
|
|
700
823
|
modelSummaries,
|
|
701
824
|
findings,
|
|
702
825
|
validation: report.validation,
|
|
@@ -716,6 +839,8 @@ export const __testInternals = {
|
|
|
716
839
|
readInvocationIndex,
|
|
717
840
|
discoverModelEntries,
|
|
718
841
|
readValidationAggregate,
|
|
842
|
+
materializeRowsFile,
|
|
843
|
+
sanitizeFileName,
|
|
719
844
|
readModelFileReviewInfo,
|
|
720
845
|
buildModelReview,
|
|
721
846
|
buildInvocationIndex,
|