import fs from 'node:fs';
|
import path from 'node:path';
|
import crypto from 'node:crypto';
|
import { spawnSync } from 'node:child_process';
|
import { pathToFileURL } from 'node:url';
|
import {
|
MANIFEST_COLUMNS,
|
parseAuthorityCsv,
|
serializeCsv,
|
serializeManifestDataRows,
|
validateAppendStableManifest,
|
} from './artifact_manifest_append_stable_parser_repair001_20260730.mjs';
|
import {
|
CASE_ID,
|
DESIGN_BATCH,
|
DESIGN_RUN,
|
EXEC_BATCH,
|
EXEC_RUN,
|
FROZEN_ANOMALOUS_MANIFEST,
|
IMMUTABLE_PRE_EXECUTION_PREFIX,
|
PARSER,
|
RUNTIME,
|
BUILDER,
|
ANOMALY_AUTHORITY,
|
CONTRACT,
|
SCHEMA,
|
EXEC_SET,
|
NEGATIVE_RESULTS,
|
DESIGN_BASELINE,
|
DESIGN_REQUEST,
|
DESIGN_SET,
|
DESIGN_VALIDATION,
|
DESIGN_PATHS,
|
ANOMALY_COLUMNS,
|
CONTRACT_COLUMNS,
|
SCHEMA_COLUMNS,
|
SET_COLUMNS,
|
NEGATIVE_COLUMNS,
|
anomalyAuthorityRows,
|
contractRows,
|
schemaRows,
|
executionSetRows,
|
designSetRows,
|
negativeRows,
|
designInputErrors,
|
fileIdentity,
|
} from './detail_strengthening_gap_triage_manifest_integrity_runtime_repair001_20260730.mjs';
|
|
const ROOT = process.cwd();
|
const BASE = 'ana-data/cases/机器人案例/ANA-ROBOT-INDUSTRY-001';
|
const MANIFEST = `${BASE}/manifest/artifact_manifest.csv`;
|
const AUDIT_REPORT = 'ana-doc/机器人案例/案例审计报告.md';
|
const SOURCE_AUDIT = 'AUDIT-ANA-ROBOT-DETAIL-STRENGTHENING-GAP-TRIAGE-EXEC-OUTPUT-001';
|
const SOURCE_AUDIT_IDENTITY = { rows: 60, bytes: 7393, sha256: '5aef313c086080b9b7b3c0f344bbdf991b3ff3de56e382ff29615ade55fc1b41' };
|
const ORIGINAL_EXEC_SET = `${BASE}/manifest/detail_strengthening_gap_triage_execution_artifact_set_repair002_20260730.csv`;
|
const SOURCE_REGISTER = `${BASE}/outputs/数据表/robot_detail_gap_triage_register_v01_repair002_20260730.csv`;
|
const SOURCE_SUMMARY = `${BASE}/outputs/数据表/robot_detail_gap_workstream_summary_v01_repair002_20260730.csv`;
|
const SOURCE_APPLICATION = `${BASE}/evidence/detail_strengthening_gap_triage_application_repair002_20260730.csv`;
|
const SOURCE_BASELINE = `${BASE}/evidence/detail_strengthening_gap_triage_execution_baseline_repair002_20260730.csv`;
|
const SOURCE_REQUEST = `${BASE}/manifest/review_request_detail_strengthening_gap_triage_execution_repair002_20260730.md`;
|
const SOURCE_VALIDATION = `${BASE}/manifest/detail_strengthening_gap_triage_execution_validation_repair002_20260730.csv`;
|
const GENERATED_DESIGN = [ANOMALY_AUTHORITY, CONTRACT, SCHEMA, EXEC_SET, NEGATIVE_RESULTS, DESIGN_BASELINE, DESIGN_REQUEST, DESIGN_SET, DESIGN_VALIDATION];
|
|
const BASELINE_COLUMNS = ['baseline_id', 'identity_type', 'artifact_path', 'rows', 'bytes', 'sha256', 'mtime', 'required_state'];
|
const VALIDATION_COLUMNS = ['check_id', 'check_description', 'expected', 'actual', 'status', 'evidence'];
|
const abs = relative => path.join(ROOT, ...relative.split('/'));
|
const sha = buffer => crypto.createHash('sha256').update(buffer).digest('hex');
|
const normalized = text => text.replace(/^\uFEFF/, '').replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
function writeText(relative, text) {
|
fs.mkdirSync(path.dirname(abs(relative)), { recursive: true });
|
fs.writeFileSync(abs(relative), text, 'utf8');
|
}
|
|
function readCsv(relative) {
|
const parsed = parseAuthorityCsv(fs.readFileSync(abs(relative), 'utf8'));
|
if (parsed.errors.length) throw new Error(`CSV_PARSE:${relative}:${parsed.errors.join('|')}`);
|
return parsed;
|
}
|
|
function auditEntry(auditId) {
|
const lines = normalized(fs.readFileSync(abs(AUDIT_REPORT), 'utf8')).split('\n');
|
const start = lines.findIndex(line => line.startsWith('### ') && line.includes(auditId));
|
if (start < 0) throw new Error(`AUDIT_MISSING:${auditId}`);
|
let end = lines.length;
|
for (let index = start + 1; index < lines.length; index++) if (lines[index].startsWith('### ')) { end = index; break; }
|
while (end > start && lines[end - 1] === '') end--;
|
const buffer = Buffer.from(`${lines.slice(start, end).join('\n')}\n`);
|
return { start: start + 1, end, rows: end - start, bytes: buffer.length, sha256: sha(buffer) };
|
}
|
|
function expectedManifestRows(paths, runId, batchId) {
|
return paths.map(artifactPath => {
|
const identity = fileIdentity(artifactPath);
|
return {
|
case_id: CASE_ID, run_id: runId, batch_id: batchId, artifact_path: artifactPath,
|
sha256: identity.sha256, bytes: String(identity.bytes), mtime: identity.mtime,
|
};
|
});
|
}
|
|
function exactRows(relative, expected, columns, code) {
|
if (!fs.existsSync(abs(relative))) return [`${code}_MISSING`];
|
const parsed = readCsv(relative);
|
const errors = [];
|
if (parsed.header.join('|') !== columns.join('|')) errors.push(`${code}_COLUMNS`);
|
if (parsed.rows.length !== expected.length) errors.push(`${code}_ROWS:${parsed.rows.length}:${expected.length}`);
|
for (let index = 0; index < Math.min(parsed.rows.length, expected.length); index++) {
|
if (columns.some(column => parsed.rows[index][column] !== String(expected[index][column] ?? ''))) {
|
errors.push(`${code}_FIELD:${index + 1}`);
|
break;
|
}
|
}
|
return errors;
|
}
|
|
function sourceAuditErrors() {
|
const entry = auditEntry(SOURCE_AUDIT);
|
return entry.rows === SOURCE_AUDIT_IDENTITY.rows && entry.bytes === SOURCE_AUDIT_IDENTITY.bytes && entry.sha256 === SOURCE_AUDIT_IDENTITY.sha256 ? [] : ['SOURCE_AUDIT_IDENTITY'];
|
}
|
|
function frozenManifestErrors({ requireExactWhole = false } = {}) {
|
const buffer = fs.readFileSync(abs(MANIFEST));
|
const errors = [];
|
if (buffer.length < FROZEN_ANOMALOUS_MANIFEST.bytes || sha(buffer.subarray(0, FROZEN_ANOMALOUS_MANIFEST.bytes)) !== FROZEN_ANOMALOUS_MANIFEST.sha256) errors.push('FROZEN_ANOMALOUS_MANIFEST_PREFIX');
|
if (requireExactWhole && (buffer.length !== FROZEN_ANOMALOUS_MANIFEST.bytes || sha(buffer) !== FROZEN_ANOMALOUS_MANIFEST.sha256)) errors.push('FROZEN_ANOMALOUS_MANIFEST_IDENTITY');
|
if (buffer.length < IMMUTABLE_PRE_EXECUTION_PREFIX.bytes || sha(buffer.subarray(0, IMMUTABLE_PRE_EXECUTION_PREFIX.bytes)) !== IMMUTABLE_PRE_EXECUTION_PREFIX.sha256) errors.push('IMMUTABLE_1603_PREFIX');
|
return errors;
|
}
|
|
function sourceOutputErrors() {
|
const expected = {
|
[SOURCE_REGISTER]: ['a40c6c4ca75e8eb753c37fc39d86ac2c19dd072bb37b1565657db22f5a6a2440', 1580662],
|
[SOURCE_SUMMARY]: ['a69856af1dac43fba8ffb492c4f22387400bf667637e41dd0740a18d658e5cad', 1377],
|
[SOURCE_APPLICATION]: ['78c3e4f23b02852f2e9cd185dbb929ec5a907aec61e38532ec5760ecf64d0265', 1339620],
|
[SOURCE_BASELINE]: ['4748159bd382d8e006dc73b5ce0f0368c44f4a6b38fbd316c3b55c4a801150a3', 2738],
|
[SOURCE_REQUEST]: ['60ebede0b7efe0e36f9b6580ff8f011d82770a36dda36dff67f4033e9a4f3f04', 754],
|
[SOURCE_VALIDATION]: ['44a9564fec6372d41911ab52727c20f0795feec6646e115fd150d8d43ba22d08', 2187],
|
};
|
const errors = [];
|
for (const [relative, identity] of Object.entries(expected)) {
|
if (!fs.existsSync(abs(relative))) { errors.push(`SOURCE_OUTPUT_MISSING:${relative}`); continue; }
|
const actual = fileIdentity(relative);
|
if (actual.sha256 !== identity[0] || actual.bytes !== identity[1]) errors.push(`SOURCE_OUTPUT_IDENTITY:${relative}`);
|
}
|
return errors;
|
}
|
|
function baseErrors() {
|
const errors = [...sourceAuditErrors(), ...frozenManifestErrors(), ...sourceOutputErrors()];
|
for (const relative of [PARSER, RUNTIME, BUILDER, ORIGINAL_EXEC_SET]) if (!fs.existsSync(abs(relative))) errors.push(`INPUT_MISSING:${relative}`);
|
return [...new Set(errors)];
|
}
|
|
function baselineRows() {
|
const rows = [];
|
const entry = auditEntry(SOURCE_AUDIT);
|
rows.push({ baseline_id: 'DGTMIR-DESIGN-BASE-001', identity_type: 'NORMALIZED_SOURCE_AUDIT_ENTRY', artifact_path: `${AUDIT_REPORT}#L${entry.start}-L${entry.end}`, rows: String(entry.rows), bytes: String(entry.bytes), sha256: entry.sha256, mtime: '', required_state: 'EXACT_EXECUTION_FAIL_ENTRY' });
|
rows.push({ baseline_id: 'DGTMIR-DESIGN-BASE-002', identity_type: 'RAW_ANOMALOUS_MANIFEST', artifact_path: MANIFEST, rows: String(FROZEN_ANOMALOUS_MANIFEST.logicalDataRows), bytes: String(FROZEN_ANOMALOUS_MANIFEST.bytes), sha256: FROZEN_ANOMALOUS_MANIFEST.sha256, mtime: fileIdentity(MANIFEST).mtime, required_state: 'EXACT_FULL_FILE_BEFORE_DESIGN_APPEND' });
|
rows.push({ baseline_id: 'DGTMIR-DESIGN-BASE-003', identity_type: 'RAW_IMMUTABLE_PREFIX', artifact_path: `${MANIFEST}#FIRST${IMMUTABLE_PRE_EXECUTION_PREFIX.bytes}BYTES`, rows: String(IMMUTABLE_PRE_EXECUTION_PREFIX.dataRows), bytes: String(IMMUTABLE_PRE_EXECUTION_PREFIX.bytes), sha256: IMMUTABLE_PRE_EXECUTION_PREFIX.sha256, mtime: '', required_state: 'EXACT_PREFIX' });
|
for (const relative of [PARSER, RUNTIME, BUILDER, ANOMALY_AUTHORITY, CONTRACT, SCHEMA, EXEC_SET, NEGATIVE_RESULTS, ORIGINAL_EXEC_SET, SOURCE_BASELINE, SOURCE_REGISTER, SOURCE_SUMMARY, SOURCE_APPLICATION, SOURCE_REQUEST, SOURCE_VALIDATION]) {
|
const identity = fileIdentity(relative);
|
rows.push({
|
baseline_id: `DGTMIR-DESIGN-BASE-${String(rows.length + 1).padStart(3, '0')}`,
|
identity_type: relative.startsWith('dev/') ? 'REPAIR_CODE' : relative.includes('manifest_integrity') ? 'REPAIR_AUTHORITY' : 'PASSED_SOURCE_ARTIFACT',
|
artifact_path: relative, rows: String(identity.rows), bytes: String(identity.bytes), sha256: identity.sha256, mtime: identity.mtime, required_state: 'EXACT_UNCHANGED',
|
});
|
}
|
return rows;
|
}
|
|
function requestText() {
|
return `# Detail strengthening gap triage EXECUTION-MANIFEST-INTEGRITY-REPAIR-001 design review request\n\ncase_id=${CASE_ID}\nsource_audit=${SOURCE_AUDIT}\nsource_execution_run=RUN-ANA-ROBOT-DETAIL-STRENGTHENING-GAP-TRIAGE-001\ndesign_batch=${DESIGN_BATCH}\ndesign_run=${DESIGN_RUN}\nrequested_release_audit=AUDIT-ANA-ROBOT-DETAIL-STRENGTHENING-GAP-TRIAGE-MANIFEST-INTEGRITY-DESIGN-REPAIR001-REREVIEW-001\nrequested_execution_batch=${EXEC_BATCH}\nrequested_execution_run=${EXEC_RUN}\nrepair_scope=append-only manifest integrity compatibility only\nfrozen_manifest=${FROZEN_ANOMALOUS_MANIFEST.bytes}|${FROZEN_ANOMALOUS_MANIFEST.sha256}\nauthorized_anomaly=physical_line_1605|LEGACY_DUPLICATE_HEADER_NON_DATA_ROW\noriginal_execution_rows=11\ndesign_manifest_append=${DESIGN_PATHS.length}_DATA_ROWS_ONLY_NO_HEADER\nexecution_exact_set=${executionSetRows().length}\nnegative_tests=${negativeRows().length}\nproposed_execution_outputs=0\nproposed_execution_manifest_rows=0\nmanifest_rewrite=NO\nbusiness_output_rewrite=NO\nformal_pool_effect=NO_AUTOMATIC_FORMAL_POOL_CHANGE\nevidence_strength_effect=NO_UPGRADE\n\nIf and only if this design independently passes, release exactly the named repair batch/run. The original generator and business outputs must not be rerun or rewritten.\n`;
|
}
|
|
function designValidationRows() {
|
const negatives = negativeRows();
|
const checks = [
|
['SOURCE_AUDIT', `${SOURCE_AUDIT_IDENTITY.rows}|${SOURCE_AUDIT_IDENTITY.bytes}|${SOURCE_AUDIT_IDENTITY.sha256}`, `${auditEntry(SOURCE_AUDIT).rows}|${auditEntry(SOURCE_AUDIT).bytes}|${auditEntry(SOURCE_AUDIT).sha256}`],
|
['FROZEN_MANIFEST', `${FROZEN_ANOMALOUS_MANIFEST.bytes}|${FROZEN_ANOMALOUS_MANIFEST.sha256}`, `${fileIdentity(MANIFEST).bytes}|${fileIdentity(MANIFEST).sha256}`],
|
['ANOMALY_AUTHORITY', '1|L1605|LEGACY_DUPLICATE_HEADER_NON_DATA_ROW', `${anomalyAuthorityRows().length}|L${anomalyAuthorityRows()[0].physical_line}|${anomalyAuthorityRows()[0].disposition}`],
|
['CONTRACT_ROWS', String(contractRows().length), String(contractRows().length)],
|
['SCHEMA_ROWS', String(schemaRows().length), String(schemaRows().length)],
|
['EXECUTION_EXACT_SET', String(executionSetRows().length), String(executionSetRows().length)],
|
['DESIGN_EXACT_SET', String(designSetRows().length), String(designSetRows().length)],
|
['NEGATIVE_TESTS', `${negatives.length}|${negatives.length}_PASS`, `${negatives.length}|${negatives.filter(row => row.result === 'PASS').length}_PASS`],
|
['ORIGINAL_OUTPUT_IDENTITIES', '0_errors', `${sourceOutputErrors().length}_errors`],
|
['DESIGN_APPEND_POLICY', 'DATA_ROWS_ONLY_NO_HEADER', 'DATA_ROWS_ONLY_NO_HEADER'],
|
['PROPOSED_EXECUTION_OUTPUTS', '0', '0'],
|
['PROPOSED_EXECUTION_MANIFEST_ROWS', '0', '0'],
|
['MANIFEST_REWRITE', 'NO', 'NO'],
|
['BUSINESS_OUTPUT_REWRITE', 'NO', 'NO'],
|
['FORMAL_POOL_EFFECT', 'NO_AUTOMATIC_FORMAL_POOL_CHANGE', 'NO_AUTOMATIC_FORMAL_POOL_CHANGE'],
|
['EVIDENCE_STRENGTH_EFFECT', 'NO_UPGRADE', 'NO_UPGRADE'],
|
];
|
const rows = checks.map((check, index) => ({ check_id: `DGTMIR-DESIGN-VAL-${String(index + 1).padStart(3, '0')}`, check_description: check[0], expected: check[1], actual: check[2], status: check[1] === check[2] ? 'PASS' : 'FAIL', evidence: 'manifest-integrity design repair001 fail-closed package' }));
|
rows.push({ check_id: 'DGTMIR-DESIGN-VAL-017', check_description: 'SELF_REFERENCE_EXCLUDED', expected: 'SELF_REFERENCE_EXCLUDED', actual: 'SELF_REFERENCE_EXCLUDED', status: 'INFO', evidence: 'design validation and manifest identities checked after freeze' });
|
return rows;
|
}
|
|
function designManifestErrors(required) {
|
const manifest = fs.readFileSync(abs(MANIFEST));
|
if (manifest.length < FROZEN_ANOMALOUS_MANIFEST.bytes) return ['MANIFEST_TRUNCATED'];
|
const expected = DESIGN_PATHS.every(relative => fs.existsSync(abs(relative))) ? expectedManifestRows(DESIGN_PATHS, DESIGN_RUN, DESIGN_BATCH) : [];
|
const state = validateAppendStableManifest(manifest, {
|
anomalyRows: anomalyAuthorityRows(), frozenPrefix: FROZEN_ANOMALOUS_MANIFEST,
|
originalRunId: 'RUN-ANA-ROBOT-DETAIL-STRENGTHENING-GAP-TRIAGE-001', originalRunExpectedRows: 11,
|
expectedRunId: DESIGN_RUN, expectedRunRows: expected, expectedPhysicalDelta: required ? DESIGN_PATHS.length : null,
|
filesystemIdentity: {
|
runIds: [DESIGN_RUN],
|
get(relative) { return fs.existsSync(abs(relative)) ? fileIdentity(relative) : null; },
|
},
|
});
|
if (!required && expected.length === 0) return [];
|
return state.errors;
|
}
|
|
function packageErrors({ requireManifest = false } = {}) {
|
const errors = [...baseErrors()];
|
errors.push(...exactRows(ANOMALY_AUTHORITY, anomalyAuthorityRows(), ANOMALY_COLUMNS, 'ANOMALY_AUTHORITY'));
|
errors.push(...exactRows(CONTRACT, contractRows(), CONTRACT_COLUMNS, 'CONTRACT'));
|
errors.push(...exactRows(SCHEMA, schemaRows(), SCHEMA_COLUMNS, 'SCHEMA'));
|
errors.push(...exactRows(EXEC_SET, executionSetRows(), SET_COLUMNS, 'EXEC_SET'));
|
errors.push(...exactRows(NEGATIVE_RESULTS, negativeRows(), NEGATIVE_COLUMNS, 'NEGATIVE_RESULTS'));
|
errors.push(...exactRows(DESIGN_SET, designSetRows(), SET_COLUMNS, 'DESIGN_SET'));
|
if (!fs.existsSync(abs(DESIGN_REQUEST)) || fs.readFileSync(abs(DESIGN_REQUEST), 'utf8') !== requestText()) errors.push('REQUEST_EXACT_TEXT');
|
if (!fs.existsSync(abs(DESIGN_BASELINE)) || readCsv(DESIGN_BASELINE).header.join('|') !== BASELINE_COLUMNS.join('|')) errors.push('BASELINE_SCHEMA');
|
if (!fs.existsSync(abs(DESIGN_VALIDATION))) errors.push('VALIDATION_MISSING');
|
else {
|
const rows = readCsv(DESIGN_VALIDATION).rows;
|
if (rows.some(row => row.status === 'FAIL' || (row.status === 'PASS' && row.expected !== row.actual)) || rows.filter(row => row.status === 'INFO').length !== 1) errors.push('VALIDATION_RESULT');
|
}
|
for (const relative of [PARSER, RUNTIME, BUILDER]) if (spawnSync(process.execPath, ['--check', relative], { cwd: ROOT }).status !== 0) errors.push(`NODE_CHECK:${relative}`);
|
if (requireManifest) errors.push(...designManifestErrors(true));
|
return [...new Set(errors)];
|
}
|
|
function cleanup(before, beforeMtime) {
|
for (const relative of GENERATED_DESIGN) if (fs.existsSync(abs(relative))) fs.rmSync(abs(relative));
|
fs.writeFileSync(abs(MANIFEST), before);
|
fs.utimesSync(abs(MANIFEST), beforeMtime, beforeMtime);
|
}
|
|
function build() {
|
const initialErrors = [...baseErrors(), ...frozenManifestErrors({ requireExactWhole: true })];
|
if (initialErrors.length) throw new Error(`BASE:${initialErrors.join('|')}`);
|
for (const relative of GENERATED_DESIGN) if (fs.existsSync(abs(relative))) throw new Error(`TARGET_EXISTS:${relative}`);
|
const before = fs.readFileSync(abs(MANIFEST));
|
const beforeMtime = fs.statSync(abs(MANIFEST)).mtime;
|
try {
|
writeText(ANOMALY_AUTHORITY, serializeCsv(anomalyAuthorityRows(), ANOMALY_COLUMNS));
|
writeText(CONTRACT, serializeCsv(contractRows(), CONTRACT_COLUMNS));
|
writeText(SCHEMA, serializeCsv(schemaRows(), SCHEMA_COLUMNS));
|
writeText(EXEC_SET, serializeCsv(executionSetRows(), SET_COLUMNS));
|
writeText(NEGATIVE_RESULTS, serializeCsv(negativeRows(), NEGATIVE_COLUMNS));
|
writeText(DESIGN_BASELINE, serializeCsv(baselineRows(), BASELINE_COLUMNS));
|
writeText(DESIGN_REQUEST, requestText());
|
writeText(DESIGN_SET, serializeCsv(designSetRows(), SET_COLUMNS));
|
writeText(DESIGN_VALIDATION, serializeCsv(designValidationRows(), VALIDATION_COLUMNS));
|
const beforeAppendErrors = packageErrors({ requireManifest: false });
|
if (beforeAppendErrors.length) throw new Error(`PACKAGE_PREAPPEND:${beforeAppendErrors.join('|')}`);
|
const designRows = expectedManifestRows(DESIGN_PATHS, DESIGN_RUN, DESIGN_BATCH);
|
const appendText = serializeManifestDataRows(designRows);
|
if (appendText.includes('"case_id","run_id","batch_id","artifact_path","sha256","bytes","mtime"\n')) throw new Error('DESIGN_APPEND_CONTAINS_HEADER');
|
const candidate = Buffer.concat([before, Buffer.from(appendText, 'utf8')]);
|
const candidateState = validateAppendStableManifest(candidate, {
|
anomalyRows: anomalyAuthorityRows(), frozenPrefix: FROZEN_ANOMALOUS_MANIFEST,
|
originalRunId: 'RUN-ANA-ROBOT-DETAIL-STRENGTHENING-GAP-TRIAGE-001', originalRunExpectedRows: 11,
|
expectedRunId: DESIGN_RUN, expectedRunRows: designRows, expectedPhysicalDelta: DESIGN_PATHS.length,
|
filesystemIdentity: { runIds: [DESIGN_RUN], get(relative) { return fileIdentity(relative); } },
|
});
|
if (candidateState.errors.length) throw new Error(`MANIFEST_CANDIDATE:${candidateState.errors.join('|')}`);
|
fs.appendFileSync(abs(MANIFEST), appendText, 'utf8');
|
if (!fs.readFileSync(abs(MANIFEST)).equals(candidate)) throw new Error('DESIGN_APPEND_BYTES_MISMATCH');
|
const finalErrors = packageErrors({ requireManifest: true });
|
if (finalErrors.length) throw new Error(`PACKAGE_FINAL:${finalErrors.join('|')}`);
|
return { status: 'DESIGN_REPAIR001_BUILT_PENDING_INDEPENDENT_REREVIEW', design_artifacts: DESIGN_PATHS.length, manifest_rows: DESIGN_PATHS.length, header_shape_count: candidateState.headerShapeCount, anomaly_count: candidateState.anomalies.length, logical_data_rows: candidateState.logicalDataRows };
|
} catch (error) {
|
cleanup(before, beforeMtime);
|
throw error;
|
}
|
}
|
|
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
const mode = process.argv[2] ?? '--validate-design';
|
if (mode === '--build-design') {
|
console.log(JSON.stringify(build(), null, 2));
|
} else if (mode === '--validate-design') {
|
const errors = packageErrors({ requireManifest: true });
|
console.log(JSON.stringify({ status: errors.length ? 'FAIL' : 'PASS_DESIGN_PACKAGE', errors }, null, 2));
|
if (errors.length) process.exitCode = 1;
|
} else if (mode === '--validate-package-manifest') {
|
const errors = designManifestErrors(true);
|
console.log(JSON.stringify({ status: errors.length ? 'FAIL' : 'PASS_DESIGN_MANIFEST', errors }, null, 2));
|
if (errors.length) process.exitCode = 1;
|
} else if (mode === '--self-test-json') {
|
const rows = negativeRows();
|
console.log(JSON.stringify(rows, null, 2));
|
if (rows.some(row => row.result !== 'PASS')) process.exitCode = 1;
|
} else {
|
throw new Error(`UNKNOWN_MODE:${mode}`);
|
}
|
}
|