scene-capability-engine 3.3.26 → 3.4.5

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.
@@ -10,6 +10,7 @@ const {
10
10
  } = require('../spec/domain-modeling');
11
11
  const { findRelatedSpecs } = require('../spec/related-specs');
12
12
  const { captureTimelineCheckpoint } = require('../runtime/project-timeline');
13
+ const { runProblemEvaluation } = require('../problem/problem-evaluator');
13
14
 
14
15
  const STUDIO_JOB_API_VERSION = 'sce.studio.job/v0.1';
15
16
  const STAGE_ORDER = ['plan', 'generate', 'apply', 'verify', 'release'];
@@ -967,6 +968,119 @@ function buildJobDomainChainMetadata(job = {}) {
967
968
  };
968
969
  }
969
970
 
971
+ function summarizeProblemEvaluation(evaluation = {}) {
972
+ return {
973
+ passed: evaluation.passed === true,
974
+ blocked: evaluation.blocked === true,
975
+ confidence_score: Number(evaluation.confidence_score || 0),
976
+ risk_level: normalizeString(evaluation?.dimensions?.risk?.level) || 'low',
977
+ strategy: normalizeString(evaluation?.dimensions?.strategy?.strategy) || 'direct-execution',
978
+ blockers: Array.isArray(evaluation.blockers) ? evaluation.blockers : [],
979
+ warnings: Array.isArray(evaluation.warnings) ? evaluation.warnings : [],
980
+ recommendations: Array.isArray(evaluation.recommendations) ? evaluation.recommendations : [],
981
+ report_file: normalizeString(evaluation.report_file) || null
982
+ };
983
+ }
984
+
985
+ function deriveGateSignals(steps = []) {
986
+ const normalized = Array.isArray(steps) ? steps : [];
987
+ const requiredTotal = normalized.filter((step) => step && step.required !== false).length;
988
+ const requiredEnabled = normalized.filter((step) => step && step.required !== false && step.enabled !== false).length;
989
+ return {
990
+ required_total: requiredTotal,
991
+ required_enabled: requiredEnabled,
992
+ required_missing: Math.max(0, requiredTotal - requiredEnabled)
993
+ };
994
+ }
995
+
996
+ function buildStageReadiness(job = {}, stage = '', overrides = {}) {
997
+ const normalizedStage = normalizeString(stage).toLowerCase();
998
+ const patchBundleReady = normalizeString(job?.artifacts?.patch_bundle_id).length > 0;
999
+ const verifyReportReady = normalizeString(job?.artifacts?.verify_report).length > 0;
1000
+ const readiness = {
1001
+ prerequisites_ready: true,
1002
+ rollback_ready: isStageCompleted(job, 'apply'),
1003
+ patch_bundle_ready: patchBundleReady,
1004
+ verify_report_ready: verifyReportReady
1005
+ };
1006
+
1007
+ if (normalizedStage === 'generate') {
1008
+ readiness.prerequisites_ready = isStageCompleted(job, 'plan');
1009
+ } else if (normalizedStage === 'apply') {
1010
+ readiness.prerequisites_ready = isStageCompleted(job, 'generate');
1011
+ } else if (normalizedStage === 'verify') {
1012
+ readiness.prerequisites_ready = isStageCompleted(job, 'apply');
1013
+ } else if (normalizedStage === 'release') {
1014
+ readiness.prerequisites_ready = isStageCompleted(job, 'verify');
1015
+ }
1016
+
1017
+ return {
1018
+ ...readiness,
1019
+ ...overrides
1020
+ };
1021
+ }
1022
+
1023
+ function assignProblemEvalArtifact(job = {}, stage = '', evaluation = {}) {
1024
+ const normalizedStage = normalizeString(stage).toLowerCase();
1025
+ if (!normalizedStage) {
1026
+ return;
1027
+ }
1028
+ job.artifacts = job.artifacts || {};
1029
+ const reports = job.artifacts.problem_eval_reports && typeof job.artifacts.problem_eval_reports === 'object'
1030
+ ? job.artifacts.problem_eval_reports
1031
+ : {};
1032
+ reports[normalizedStage] = normalizeString(evaluation.report_file) || null;
1033
+ job.artifacts.problem_eval_reports = reports;
1034
+ }
1035
+
1036
+ async function enforceProblemEvaluationForStage(job = {}, stage = '', context = {}, dependencies = {}) {
1037
+ const projectPath = dependencies.projectPath || process.cwd();
1038
+ const fileSystem = dependencies.fileSystem || fs;
1039
+ const evaluation = await runProblemEvaluation({
1040
+ stage,
1041
+ job_id: normalizeString(job.job_id),
1042
+ scene_id: normalizeString(context.scene_id || job?.scene?.id),
1043
+ spec_id: normalizeString(context.spec_id || job?.source?.spec_id || job?.scene?.spec_id),
1044
+ goal: normalizeString(context.goal || job?.source?.goal),
1045
+ release_channel: normalizeString(context.release_channel || ''),
1046
+ domain_chain: context.domain_chain || (job?.source?.domain_chain || {}),
1047
+ related_specs_count: Number(context.related_specs_count || job?.source?.related_specs?.total_candidates || 0),
1048
+ stage_readiness: context.stage_readiness || buildStageReadiness(job, stage),
1049
+ gate_signals: context.gate_signals || {}
1050
+ }, {
1051
+ projectPath,
1052
+ fileSystem,
1053
+ env: dependencies.env,
1054
+ writeReport: true
1055
+ });
1056
+ assignProblemEvalArtifact(job, stage, evaluation);
1057
+ return evaluation;
1058
+ }
1059
+
1060
+ async function markStudioStageBlockedByProblemEval(paths, job, stageName, evaluation, fileSystem = fs) {
1061
+ const summary = summarizeProblemEvaluation(evaluation);
1062
+ job.status = `${stageName}_blocked`;
1063
+ job.updated_at = nowIso();
1064
+ job.stages = job.stages || createStageState();
1065
+ job.stages[stageName] = {
1066
+ status: 'blocked',
1067
+ completed_at: null,
1068
+ metadata: {
1069
+ problem_evaluation: summary
1070
+ }
1071
+ };
1072
+ await saveJob(paths, job, fileSystem);
1073
+ await appendStudioEvent(paths, job, `stage.${stageName}.blocked`, {
1074
+ problem_evaluation: summary
1075
+ }, fileSystem);
1076
+ await writeLatestJob(paths, job.job_id, fileSystem);
1077
+
1078
+ const reason = summary.blockers.length > 0
1079
+ ? summary.blockers.join(', ')
1080
+ : 'problem-evaluation-policy';
1081
+ throw new Error(`studio ${stageName} blocked by problem evaluation: ${reason}`);
1082
+ }
1083
+
970
1084
  async function runStudioPlanCommand(options = {}, dependencies = {}) {
971
1085
  const projectPath = dependencies.projectPath || process.cwd();
972
1086
  const fileSystem = dependencies.fileSystem || fs;
@@ -1013,6 +1127,51 @@ async function runStudioPlanCommand(options = {}, dependencies = {}) {
1013
1127
 
1014
1128
  const jobId = normalizeString(options.job) || createJobId();
1015
1129
  const now = nowIso();
1130
+ const planShadowJob = {
1131
+ job_id: jobId,
1132
+ scene: {
1133
+ id: sceneId,
1134
+ spec_id: domainChainBinding.spec_id || specId || null
1135
+ },
1136
+ source: {
1137
+ goal: normalizeString(options.goal) || null,
1138
+ spec_id: domainChainBinding.spec_id || specId || null,
1139
+ domain_chain: {
1140
+ resolved: domainChainBinding.resolved === true,
1141
+ summary: domainChainBinding.summary || null
1142
+ },
1143
+ related_specs: {
1144
+ total_candidates: Number(relatedSpecLookup.total_candidates || 0)
1145
+ }
1146
+ },
1147
+ artifacts: {}
1148
+ };
1149
+ const planProblemEvaluation = await enforceProblemEvaluationForStage(planShadowJob, 'plan', {
1150
+ scene_id: sceneId,
1151
+ spec_id: domainChainBinding.spec_id || specId || null,
1152
+ goal: normalizeString(options.goal) || null,
1153
+ domain_chain: {
1154
+ resolved: domainChainBinding.resolved === true,
1155
+ summary: domainChainBinding.summary || null
1156
+ },
1157
+ related_specs_count: Number(relatedSpecLookup.total_candidates || 0),
1158
+ stage_readiness: {
1159
+ prerequisites_ready: true,
1160
+ rollback_ready: false,
1161
+ patch_bundle_ready: false,
1162
+ verify_report_ready: false
1163
+ }
1164
+ }, {
1165
+ projectPath,
1166
+ fileSystem,
1167
+ env: dependencies.env
1168
+ });
1169
+ if (!planProblemEvaluation.passed) {
1170
+ const blockers = Array.isArray(planProblemEvaluation.blockers) && planProblemEvaluation.blockers.length > 0
1171
+ ? planProblemEvaluation.blockers.join(', ')
1172
+ : 'problem-evaluation-policy';
1173
+ throw new Error(`studio plan blocked by problem evaluation: ${blockers}`);
1174
+ }
1016
1175
  const stages = createStageState();
1017
1176
  const sessionStore = dependencies.sessionStore || new SessionStore(projectPath);
1018
1177
  const sceneSessionBinding = await sessionStore.beginSceneSession({
@@ -1035,6 +1194,7 @@ async function runStudioPlanCommand(options = {}, dependencies = {}) {
1035
1194
  domain_chain_path: domainChainBinding.chain_path || null,
1036
1195
  domain_chain_summary: domainChainBinding.summary || null,
1037
1196
  domain_chain_reason: domainChainBinding.reason || null,
1197
+ problem_evaluation: summarizeProblemEvaluation(planProblemEvaluation),
1038
1198
  related_specs_total: Number(relatedSpecLookup.total_candidates || 0),
1039
1199
  related_specs_top: relatedSpecItems
1040
1200
  }
@@ -1088,7 +1248,10 @@ async function runStudioPlanCommand(options = {}, dependencies = {}) {
1088
1248
  artifacts: {
1089
1249
  patch_bundle_id: null,
1090
1250
  verify_report: null,
1091
- release_ref: null
1251
+ release_ref: null,
1252
+ problem_eval_reports: {
1253
+ plan: normalizeString(planProblemEvaluation.report_file) || null
1254
+ }
1092
1255
  }
1093
1256
  };
1094
1257
 
@@ -1104,6 +1267,7 @@ async function runStudioPlanCommand(options = {}, dependencies = {}) {
1104
1267
  domain_chain_source: domainChainBinding.source || 'none',
1105
1268
  domain_chain_spec_id: domainChainBinding.spec_id || null,
1106
1269
  domain_chain_path: domainChainBinding.chain_path || null,
1270
+ problem_evaluation: summarizeProblemEvaluation(planProblemEvaluation),
1107
1271
  related_specs_total: Number(relatedSpecLookup.total_candidates || 0),
1108
1272
  related_spec_ids: relatedSpecItems.map((item) => item.spec_id)
1109
1273
  }, fileSystem);
@@ -1138,6 +1302,21 @@ async function runStudioGenerateCommand(options = {}, dependencies = {}) {
1138
1302
  throw new Error(`Scene mismatch: planned scene is "${jobSceneId}" but --scene provided "${sceneArg}"`);
1139
1303
  }
1140
1304
  const sceneId = sceneArg || jobSceneId;
1305
+ const generateProblemEvaluation = await enforceProblemEvaluationForStage(job, 'generate', {
1306
+ scene_id: sceneId,
1307
+ spec_id: normalizeString(job?.source?.spec_id) || normalizeString(job?.scene?.spec_id) || null,
1308
+ goal: normalizeString(job?.source?.goal),
1309
+ domain_chain: job?.source?.domain_chain || {},
1310
+ related_specs_count: Number(job?.source?.related_specs?.total_candidates || 0),
1311
+ stage_readiness: buildStageReadiness(job, 'generate')
1312
+ }, {
1313
+ projectPath,
1314
+ fileSystem,
1315
+ env: dependencies.env
1316
+ });
1317
+ if (!generateProblemEvaluation.passed) {
1318
+ await markStudioStageBlockedByProblemEval(paths, job, 'generate', generateProblemEvaluation, fileSystem);
1319
+ }
1141
1320
  const patchBundleId = normalizeString(options.patchBundle) || `patch-${sceneId}-${Date.now()}`;
1142
1321
  const domainChainMetadata = buildJobDomainChainMetadata(job);
1143
1322
  const generateReportPath = `${STUDIO_REPORTS_DIR}/generate-${job.job_id}.json`;
@@ -1167,6 +1346,7 @@ async function runStudioGenerateCommand(options = {}, dependencies = {}) {
1167
1346
  scene_id: sceneId,
1168
1347
  target: job.target,
1169
1348
  patch_bundle_id: patchBundleId,
1349
+ problem_evaluation: summarizeProblemEvaluation(generateProblemEvaluation),
1170
1350
  domain_chain: domainChainMetadata,
1171
1351
  report: generateReportPath
1172
1352
  });
@@ -1176,6 +1356,7 @@ async function runStudioGenerateCommand(options = {}, dependencies = {}) {
1176
1356
  scene_id: sceneId,
1177
1357
  target: job.target,
1178
1358
  patch_bundle_id: patchBundleId,
1359
+ problem_evaluation: summarizeProblemEvaluation(generateProblemEvaluation),
1179
1360
  domain_chain: domainChainMetadata,
1180
1361
  report: generateReportPath
1181
1362
  }, fileSystem);
@@ -1211,6 +1392,23 @@ async function runStudioApplyCommand(options = {}, dependencies = {}) {
1211
1392
  if (!patchBundleId) {
1212
1393
  throw new Error('--patch-bundle is required (or generate stage must provide one)');
1213
1394
  }
1395
+ const applyProblemEvaluation = await enforceProblemEvaluationForStage(job, 'apply', {
1396
+ scene_id: normalizeString(job?.scene?.id),
1397
+ spec_id: normalizeString(job?.source?.spec_id) || normalizeString(job?.scene?.spec_id) || null,
1398
+ goal: normalizeString(job?.source?.goal),
1399
+ domain_chain: job?.source?.domain_chain || {},
1400
+ related_specs_count: Number(job?.source?.related_specs?.total_candidates || 0),
1401
+ stage_readiness: buildStageReadiness(job, 'apply', {
1402
+ patch_bundle_ready: normalizeString(patchBundleId).length > 0
1403
+ })
1404
+ }, {
1405
+ projectPath,
1406
+ fileSystem,
1407
+ env: dependencies.env
1408
+ });
1409
+ if (!applyProblemEvaluation.passed) {
1410
+ await markStudioStageBlockedByProblemEval(paths, job, 'apply', applyProblemEvaluation, fileSystem);
1411
+ }
1214
1412
 
1215
1413
  job.status = 'applied';
1216
1414
  job.artifacts = job.artifacts || {};
@@ -1219,13 +1417,15 @@ async function runStudioApplyCommand(options = {}, dependencies = {}) {
1219
1417
 
1220
1418
  ensureStageCompleted(job, 'apply', {
1221
1419
  patch_bundle_id: patchBundleId,
1222
- auth_required: authResult.required
1420
+ auth_required: authResult.required,
1421
+ problem_evaluation: summarizeProblemEvaluation(applyProblemEvaluation)
1223
1422
  });
1224
1423
 
1225
1424
  await saveJob(paths, job, fileSystem);
1226
1425
  await appendStudioEvent(paths, job, 'stage.apply.completed', {
1227
1426
  patch_bundle_id: patchBundleId,
1228
- auth_required: authResult.required
1427
+ auth_required: authResult.required,
1428
+ problem_evaluation: summarizeProblemEvaluation(applyProblemEvaluation)
1229
1429
  }, fileSystem);
1230
1430
  await writeLatestJob(paths, jobId, fileSystem);
1231
1431
 
@@ -1259,6 +1459,24 @@ async function runStudioVerifyCommand(options = {}, dependencies = {}) {
1259
1459
  projectPath,
1260
1460
  fileSystem
1261
1461
  });
1462
+ const verifyProblemEvaluation = await enforceProblemEvaluationForStage(job, 'verify', {
1463
+ scene_id: normalizeString(job?.scene?.id),
1464
+ spec_id: normalizeString(domainChainMetadata.spec_id) || normalizeString(job?.source?.spec_id),
1465
+ goal: normalizeString(job?.source?.goal),
1466
+ domain_chain: job?.source?.domain_chain || {},
1467
+ related_specs_count: Number(job?.source?.related_specs?.total_candidates || 0),
1468
+ stage_readiness: buildStageReadiness(job, 'verify', {
1469
+ gate_required_ready: deriveGateSignals(gateSteps).required_missing === 0
1470
+ }),
1471
+ gate_signals: deriveGateSignals(gateSteps)
1472
+ }, {
1473
+ projectPath,
1474
+ fileSystem,
1475
+ env: dependencies.env
1476
+ });
1477
+ if (!verifyProblemEvaluation.passed) {
1478
+ await markStudioStageBlockedByProblemEval(paths, job, 'verify', verifyProblemEvaluation, fileSystem);
1479
+ }
1262
1480
  const gateResult = await executeGateSteps(gateSteps, {
1263
1481
  projectPath,
1264
1482
  commandRunner: dependencies.commandRunner,
@@ -1296,6 +1514,7 @@ async function runStudioVerifyCommand(options = {}, dependencies = {}) {
1296
1514
  passed: gateResult.passed,
1297
1515
  steps: gateResult.steps,
1298
1516
  domain_chain: domainChainMetadata,
1517
+ problem_evaluation: summarizeProblemEvaluation(verifyProblemEvaluation),
1299
1518
  auto_errorbook_records: autoErrorbookRecords
1300
1519
  };
1301
1520
 
@@ -1314,6 +1533,7 @@ async function runStudioVerifyCommand(options = {}, dependencies = {}) {
1314
1533
  profile,
1315
1534
  passed: false,
1316
1535
  report: verifyReportPath,
1536
+ problem_evaluation: summarizeProblemEvaluation(verifyProblemEvaluation),
1317
1537
  domain_chain: domainChainMetadata,
1318
1538
  auto_errorbook_records: autoErrorbookRecords
1319
1539
  }
@@ -1322,6 +1542,7 @@ async function runStudioVerifyCommand(options = {}, dependencies = {}) {
1322
1542
  await appendStudioEvent(paths, job, 'stage.verify.failed', {
1323
1543
  profile,
1324
1544
  report: verifyReportPath,
1545
+ problem_evaluation: summarizeProblemEvaluation(verifyProblemEvaluation),
1325
1546
  domain_chain: domainChainMetadata,
1326
1547
  auto_errorbook_records: autoErrorbookRecords
1327
1548
  }, fileSystem);
@@ -1334,6 +1555,7 @@ async function runStudioVerifyCommand(options = {}, dependencies = {}) {
1334
1555
  profile,
1335
1556
  passed: true,
1336
1557
  report: verifyReportPath,
1558
+ problem_evaluation: summarizeProblemEvaluation(verifyProblemEvaluation),
1337
1559
  domain_chain: domainChainMetadata,
1338
1560
  auto_errorbook_records: autoErrorbookRecords
1339
1561
  });
@@ -1343,6 +1565,7 @@ async function runStudioVerifyCommand(options = {}, dependencies = {}) {
1343
1565
  profile,
1344
1566
  passed: true,
1345
1567
  report: verifyReportPath,
1568
+ problem_evaluation: summarizeProblemEvaluation(verifyProblemEvaluation),
1346
1569
  domain_chain: domainChainMetadata,
1347
1570
  auto_errorbook_records: autoErrorbookRecords
1348
1571
  }, fileSystem);
@@ -1390,6 +1613,26 @@ async function runStudioReleaseCommand(options = {}, dependencies = {}) {
1390
1613
  projectPath,
1391
1614
  fileSystem
1392
1615
  });
1616
+ const releaseGateSignals = deriveGateSignals(gateSteps);
1617
+ const releaseProblemEvaluation = await enforceProblemEvaluationForStage(job, 'release', {
1618
+ scene_id: normalizeString(job?.scene?.id),
1619
+ spec_id: normalizeString(domainChainMetadata.spec_id) || normalizeString(job?.source?.spec_id),
1620
+ goal: normalizeString(job?.source?.goal),
1621
+ release_channel: channel,
1622
+ domain_chain: job?.source?.domain_chain || {},
1623
+ related_specs_count: Number(job?.source?.related_specs?.total_candidates || 0),
1624
+ stage_readiness: buildStageReadiness(job, 'release', {
1625
+ gate_required_ready: releaseGateSignals.required_missing === 0
1626
+ }),
1627
+ gate_signals: releaseGateSignals
1628
+ }, {
1629
+ projectPath,
1630
+ fileSystem,
1631
+ env: dependencies.env
1632
+ });
1633
+ if (!releaseProblemEvaluation.passed) {
1634
+ await markStudioStageBlockedByProblemEval(paths, job, 'release', releaseProblemEvaluation, fileSystem);
1635
+ }
1393
1636
  const gateResult = await executeGateSteps(gateSteps, {
1394
1637
  projectPath,
1395
1638
  commandRunner: dependencies.commandRunner,
@@ -1429,6 +1672,7 @@ async function runStudioReleaseCommand(options = {}, dependencies = {}) {
1429
1672
  passed: gateResult.passed,
1430
1673
  steps: gateResult.steps,
1431
1674
  domain_chain: domainChainMetadata,
1675
+ problem_evaluation: summarizeProblemEvaluation(releaseProblemEvaluation),
1432
1676
  auto_errorbook_records: autoErrorbookRecords
1433
1677
  };
1434
1678
 
@@ -1450,6 +1694,7 @@ async function runStudioReleaseCommand(options = {}, dependencies = {}) {
1450
1694
  passed: false,
1451
1695
  report: releaseReportPath,
1452
1696
  auth_required: authResult.required,
1697
+ problem_evaluation: summarizeProblemEvaluation(releaseProblemEvaluation),
1453
1698
  domain_chain: domainChainMetadata,
1454
1699
  auto_errorbook_records: autoErrorbookRecords
1455
1700
  }
@@ -1460,6 +1705,7 @@ async function runStudioReleaseCommand(options = {}, dependencies = {}) {
1460
1705
  release_ref: releaseRef,
1461
1706
  report: releaseReportPath,
1462
1707
  auth_required: authResult.required,
1708
+ problem_evaluation: summarizeProblemEvaluation(releaseProblemEvaluation),
1463
1709
  domain_chain: domainChainMetadata,
1464
1710
  auto_errorbook_records: autoErrorbookRecords
1465
1711
  }, fileSystem);
@@ -1473,6 +1719,7 @@ async function runStudioReleaseCommand(options = {}, dependencies = {}) {
1473
1719
  release_ref: releaseRef,
1474
1720
  report: releaseReportPath,
1475
1721
  auth_required: authResult.required,
1722
+ problem_evaluation: summarizeProblemEvaluation(releaseProblemEvaluation),
1476
1723
  domain_chain: domainChainMetadata,
1477
1724
  auto_errorbook_records: autoErrorbookRecords
1478
1725
  });
@@ -1504,6 +1751,7 @@ async function runStudioReleaseCommand(options = {}, dependencies = {}) {
1504
1751
  release_ref: releaseRef,
1505
1752
  report: releaseReportPath,
1506
1753
  auth_required: authResult.required,
1754
+ problem_evaluation: summarizeProblemEvaluation(releaseProblemEvaluation),
1507
1755
  domain_chain: domainChainMetadata,
1508
1756
  auto_errorbook_records: autoErrorbookRecords
1509
1757
  }, fileSystem);
@@ -11,6 +11,7 @@ const path = require('path');
11
11
  const VersionManager = require('../version/version-manager');
12
12
  const MigrationEngine = require('../upgrade/migration-engine');
13
13
  const BackupSystem = require('../backup/backup-system');
14
+ const { applyTakeoverBaseline } = require('../workspace/takeover-baseline');
14
15
 
15
16
  /**
16
17
  * Executes the upgrade command
@@ -177,6 +178,12 @@ async function upgradeCommand(options = {}) {
177
178
 
178
179
  // 9. Report results
179
180
  if (result.success) {
181
+ const takeoverReport = await applyTakeoverBaseline(projectPath, {
182
+ apply: true,
183
+ writeReport: true,
184
+ sceVersion: packageJson.version
185
+ });
186
+
180
187
  console.log(chalk.green('✅ Upgrade completed successfully!'));
181
188
  console.log();
182
189
  console.log(` Upgraded from ${chalk.cyan(result.fromVersion)} to ${chalk.cyan(result.toVersion)}`);
@@ -200,6 +207,15 @@ async function upgradeCommand(options = {}) {
200
207
  console.log(chalk.yellow('⚠️ Warnings:'));
201
208
  result.warnings.forEach(warning => console.log(` ${warning}`));
202
209
  }
210
+
211
+ if (takeoverReport.detected_project && (takeoverReport.summary.created > 0 || takeoverReport.summary.updated > 0)) {
212
+ console.log();
213
+ console.log(chalk.blue('🧭 Takeover baseline aligned with current SCE defaults'));
214
+ console.log(chalk.gray(` created=${takeoverReport.summary.created}, updated=${takeoverReport.summary.updated}`));
215
+ if (takeoverReport.report_file) {
216
+ console.log(chalk.gray(` report: ${takeoverReport.report_file}`));
217
+ }
218
+ }
203
219
 
204
220
  console.log();
205
221
  console.log(chalk.blue('📦 Backup:'), backup.id);