scene-capability-engine 3.3.25 → 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.
- package/CHANGELOG.md +68 -0
- package/README.md +81 -719
- package/README.zh.md +85 -586
- package/bin/scene-capability-engine.js +105 -0
- package/docs/README.md +47 -249
- package/docs/command-reference.md +80 -4
- package/docs/spec-workflow.md +35 -4
- package/docs/zh/README.md +44 -331
- package/lib/adoption/adoption-strategy.js +4 -0
- package/lib/adoption/detection-engine.js +4 -0
- package/lib/adoption/file-classifier.js +5 -1
- package/lib/adoption/smart-orchestrator.js +4 -0
- package/lib/commands/adopt.js +32 -0
- package/lib/commands/errorbook.js +409 -2
- package/lib/commands/session.js +27 -0
- package/lib/commands/spec-domain.js +78 -2
- package/lib/commands/studio.js +283 -12
- package/lib/commands/timeline.js +287 -0
- package/lib/commands/upgrade.js +16 -0
- package/lib/problem/problem-evaluator.js +620 -0
- package/lib/runtime/project-timeline.js +598 -0
- package/lib/spec/domain-modeling.js +217 -1
- package/lib/workspace/takeover-baseline.js +446 -0
- package/package.json +1 -1
- package/template/.sce/config/problem-eval-policy.json +36 -0
- package/template/.sce/config/session-governance.json +8 -0
- package/template/.sce/config/spec-domain-policy.json +6 -0
- package/template/.sce/config/takeover-baseline.json +33 -0
package/lib/commands/studio.js
CHANGED
|
@@ -9,6 +9,8 @@ const {
|
|
|
9
9
|
ensureSpecDomainArtifacts
|
|
10
10
|
} = require('../spec/domain-modeling');
|
|
11
11
|
const { findRelatedSpecs } = require('../spec/related-specs');
|
|
12
|
+
const { captureTimelineCheckpoint } = require('../runtime/project-timeline');
|
|
13
|
+
const { runProblemEvaluation } = require('../problem/problem-evaluator');
|
|
12
14
|
|
|
13
15
|
const STUDIO_JOB_API_VERSION = 'sce.studio.job/v0.1';
|
|
14
16
|
const STAGE_ORDER = ['plan', 'generate', 'apply', 'verify', 'release'];
|
|
@@ -966,6 +968,119 @@ function buildJobDomainChainMetadata(job = {}) {
|
|
|
966
968
|
};
|
|
967
969
|
}
|
|
968
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
|
+
|
|
969
1084
|
async function runStudioPlanCommand(options = {}, dependencies = {}) {
|
|
970
1085
|
const projectPath = dependencies.projectPath || process.cwd();
|
|
971
1086
|
const fileSystem = dependencies.fileSystem || fs;
|
|
@@ -1012,6 +1127,51 @@ async function runStudioPlanCommand(options = {}, dependencies = {}) {
|
|
|
1012
1127
|
|
|
1013
1128
|
const jobId = normalizeString(options.job) || createJobId();
|
|
1014
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
|
+
}
|
|
1015
1175
|
const stages = createStageState();
|
|
1016
1176
|
const sessionStore = dependencies.sessionStore || new SessionStore(projectPath);
|
|
1017
1177
|
const sceneSessionBinding = await sessionStore.beginSceneSession({
|
|
@@ -1034,6 +1194,7 @@ async function runStudioPlanCommand(options = {}, dependencies = {}) {
|
|
|
1034
1194
|
domain_chain_path: domainChainBinding.chain_path || null,
|
|
1035
1195
|
domain_chain_summary: domainChainBinding.summary || null,
|
|
1036
1196
|
domain_chain_reason: domainChainBinding.reason || null,
|
|
1197
|
+
problem_evaluation: summarizeProblemEvaluation(planProblemEvaluation),
|
|
1037
1198
|
related_specs_total: Number(relatedSpecLookup.total_candidates || 0),
|
|
1038
1199
|
related_specs_top: relatedSpecItems
|
|
1039
1200
|
}
|
|
@@ -1087,7 +1248,10 @@ async function runStudioPlanCommand(options = {}, dependencies = {}) {
|
|
|
1087
1248
|
artifacts: {
|
|
1088
1249
|
patch_bundle_id: null,
|
|
1089
1250
|
verify_report: null,
|
|
1090
|
-
release_ref: null
|
|
1251
|
+
release_ref: null,
|
|
1252
|
+
problem_eval_reports: {
|
|
1253
|
+
plan: normalizeString(planProblemEvaluation.report_file) || null
|
|
1254
|
+
}
|
|
1091
1255
|
}
|
|
1092
1256
|
};
|
|
1093
1257
|
|
|
@@ -1103,6 +1267,7 @@ async function runStudioPlanCommand(options = {}, dependencies = {}) {
|
|
|
1103
1267
|
domain_chain_source: domainChainBinding.source || 'none',
|
|
1104
1268
|
domain_chain_spec_id: domainChainBinding.spec_id || null,
|
|
1105
1269
|
domain_chain_path: domainChainBinding.chain_path || null,
|
|
1270
|
+
problem_evaluation: summarizeProblemEvaluation(planProblemEvaluation),
|
|
1106
1271
|
related_specs_total: Number(relatedSpecLookup.total_candidates || 0),
|
|
1107
1272
|
related_spec_ids: relatedSpecItems.map((item) => item.spec_id)
|
|
1108
1273
|
}, fileSystem);
|
|
@@ -1137,6 +1302,21 @@ async function runStudioGenerateCommand(options = {}, dependencies = {}) {
|
|
|
1137
1302
|
throw new Error(`Scene mismatch: planned scene is "${jobSceneId}" but --scene provided "${sceneArg}"`);
|
|
1138
1303
|
}
|
|
1139
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
|
+
}
|
|
1140
1320
|
const patchBundleId = normalizeString(options.patchBundle) || `patch-${sceneId}-${Date.now()}`;
|
|
1141
1321
|
const domainChainMetadata = buildJobDomainChainMetadata(job);
|
|
1142
1322
|
const generateReportPath = `${STUDIO_REPORTS_DIR}/generate-${job.job_id}.json`;
|
|
@@ -1166,6 +1346,7 @@ async function runStudioGenerateCommand(options = {}, dependencies = {}) {
|
|
|
1166
1346
|
scene_id: sceneId,
|
|
1167
1347
|
target: job.target,
|
|
1168
1348
|
patch_bundle_id: patchBundleId,
|
|
1349
|
+
problem_evaluation: summarizeProblemEvaluation(generateProblemEvaluation),
|
|
1169
1350
|
domain_chain: domainChainMetadata,
|
|
1170
1351
|
report: generateReportPath
|
|
1171
1352
|
});
|
|
@@ -1175,6 +1356,7 @@ async function runStudioGenerateCommand(options = {}, dependencies = {}) {
|
|
|
1175
1356
|
scene_id: sceneId,
|
|
1176
1357
|
target: job.target,
|
|
1177
1358
|
patch_bundle_id: patchBundleId,
|
|
1359
|
+
problem_evaluation: summarizeProblemEvaluation(generateProblemEvaluation),
|
|
1178
1360
|
domain_chain: domainChainMetadata,
|
|
1179
1361
|
report: generateReportPath
|
|
1180
1362
|
}, fileSystem);
|
|
@@ -1210,6 +1392,23 @@ async function runStudioApplyCommand(options = {}, dependencies = {}) {
|
|
|
1210
1392
|
if (!patchBundleId) {
|
|
1211
1393
|
throw new Error('--patch-bundle is required (or generate stage must provide one)');
|
|
1212
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
|
+
}
|
|
1213
1412
|
|
|
1214
1413
|
job.status = 'applied';
|
|
1215
1414
|
job.artifacts = job.artifacts || {};
|
|
@@ -1218,13 +1417,15 @@ async function runStudioApplyCommand(options = {}, dependencies = {}) {
|
|
|
1218
1417
|
|
|
1219
1418
|
ensureStageCompleted(job, 'apply', {
|
|
1220
1419
|
patch_bundle_id: patchBundleId,
|
|
1221
|
-
auth_required: authResult.required
|
|
1420
|
+
auth_required: authResult.required,
|
|
1421
|
+
problem_evaluation: summarizeProblemEvaluation(applyProblemEvaluation)
|
|
1222
1422
|
});
|
|
1223
1423
|
|
|
1224
1424
|
await saveJob(paths, job, fileSystem);
|
|
1225
1425
|
await appendStudioEvent(paths, job, 'stage.apply.completed', {
|
|
1226
1426
|
patch_bundle_id: patchBundleId,
|
|
1227
|
-
auth_required: authResult.required
|
|
1427
|
+
auth_required: authResult.required,
|
|
1428
|
+
problem_evaluation: summarizeProblemEvaluation(applyProblemEvaluation)
|
|
1228
1429
|
}, fileSystem);
|
|
1229
1430
|
await writeLatestJob(paths, jobId, fileSystem);
|
|
1230
1431
|
|
|
@@ -1258,6 +1459,24 @@ async function runStudioVerifyCommand(options = {}, dependencies = {}) {
|
|
|
1258
1459
|
projectPath,
|
|
1259
1460
|
fileSystem
|
|
1260
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
|
+
}
|
|
1261
1480
|
const gateResult = await executeGateSteps(gateSteps, {
|
|
1262
1481
|
projectPath,
|
|
1263
1482
|
commandRunner: dependencies.commandRunner,
|
|
@@ -1295,6 +1514,7 @@ async function runStudioVerifyCommand(options = {}, dependencies = {}) {
|
|
|
1295
1514
|
passed: gateResult.passed,
|
|
1296
1515
|
steps: gateResult.steps,
|
|
1297
1516
|
domain_chain: domainChainMetadata,
|
|
1517
|
+
problem_evaluation: summarizeProblemEvaluation(verifyProblemEvaluation),
|
|
1298
1518
|
auto_errorbook_records: autoErrorbookRecords
|
|
1299
1519
|
};
|
|
1300
1520
|
|
|
@@ -1313,6 +1533,7 @@ async function runStudioVerifyCommand(options = {}, dependencies = {}) {
|
|
|
1313
1533
|
profile,
|
|
1314
1534
|
passed: false,
|
|
1315
1535
|
report: verifyReportPath,
|
|
1536
|
+
problem_evaluation: summarizeProblemEvaluation(verifyProblemEvaluation),
|
|
1316
1537
|
domain_chain: domainChainMetadata,
|
|
1317
1538
|
auto_errorbook_records: autoErrorbookRecords
|
|
1318
1539
|
}
|
|
@@ -1321,6 +1542,7 @@ async function runStudioVerifyCommand(options = {}, dependencies = {}) {
|
|
|
1321
1542
|
await appendStudioEvent(paths, job, 'stage.verify.failed', {
|
|
1322
1543
|
profile,
|
|
1323
1544
|
report: verifyReportPath,
|
|
1545
|
+
problem_evaluation: summarizeProblemEvaluation(verifyProblemEvaluation),
|
|
1324
1546
|
domain_chain: domainChainMetadata,
|
|
1325
1547
|
auto_errorbook_records: autoErrorbookRecords
|
|
1326
1548
|
}, fileSystem);
|
|
@@ -1333,6 +1555,7 @@ async function runStudioVerifyCommand(options = {}, dependencies = {}) {
|
|
|
1333
1555
|
profile,
|
|
1334
1556
|
passed: true,
|
|
1335
1557
|
report: verifyReportPath,
|
|
1558
|
+
problem_evaluation: summarizeProblemEvaluation(verifyProblemEvaluation),
|
|
1336
1559
|
domain_chain: domainChainMetadata,
|
|
1337
1560
|
auto_errorbook_records: autoErrorbookRecords
|
|
1338
1561
|
});
|
|
@@ -1342,6 +1565,7 @@ async function runStudioVerifyCommand(options = {}, dependencies = {}) {
|
|
|
1342
1565
|
profile,
|
|
1343
1566
|
passed: true,
|
|
1344
1567
|
report: verifyReportPath,
|
|
1568
|
+
problem_evaluation: summarizeProblemEvaluation(verifyProblemEvaluation),
|
|
1345
1569
|
domain_chain: domainChainMetadata,
|
|
1346
1570
|
auto_errorbook_records: autoErrorbookRecords
|
|
1347
1571
|
}, fileSystem);
|
|
@@ -1389,6 +1613,26 @@ async function runStudioReleaseCommand(options = {}, dependencies = {}) {
|
|
|
1389
1613
|
projectPath,
|
|
1390
1614
|
fileSystem
|
|
1391
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
|
+
}
|
|
1392
1636
|
const gateResult = await executeGateSteps(gateSteps, {
|
|
1393
1637
|
projectPath,
|
|
1394
1638
|
commandRunner: dependencies.commandRunner,
|
|
@@ -1428,6 +1672,7 @@ async function runStudioReleaseCommand(options = {}, dependencies = {}) {
|
|
|
1428
1672
|
passed: gateResult.passed,
|
|
1429
1673
|
steps: gateResult.steps,
|
|
1430
1674
|
domain_chain: domainChainMetadata,
|
|
1675
|
+
problem_evaluation: summarizeProblemEvaluation(releaseProblemEvaluation),
|
|
1431
1676
|
auto_errorbook_records: autoErrorbookRecords
|
|
1432
1677
|
};
|
|
1433
1678
|
|
|
@@ -1449,6 +1694,7 @@ async function runStudioReleaseCommand(options = {}, dependencies = {}) {
|
|
|
1449
1694
|
passed: false,
|
|
1450
1695
|
report: releaseReportPath,
|
|
1451
1696
|
auth_required: authResult.required,
|
|
1697
|
+
problem_evaluation: summarizeProblemEvaluation(releaseProblemEvaluation),
|
|
1452
1698
|
domain_chain: domainChainMetadata,
|
|
1453
1699
|
auto_errorbook_records: autoErrorbookRecords
|
|
1454
1700
|
}
|
|
@@ -1459,6 +1705,7 @@ async function runStudioReleaseCommand(options = {}, dependencies = {}) {
|
|
|
1459
1705
|
release_ref: releaseRef,
|
|
1460
1706
|
report: releaseReportPath,
|
|
1461
1707
|
auth_required: authResult.required,
|
|
1708
|
+
problem_evaluation: summarizeProblemEvaluation(releaseProblemEvaluation),
|
|
1462
1709
|
domain_chain: domainChainMetadata,
|
|
1463
1710
|
auto_errorbook_records: autoErrorbookRecords
|
|
1464
1711
|
}, fileSystem);
|
|
@@ -1472,6 +1719,7 @@ async function runStudioReleaseCommand(options = {}, dependencies = {}) {
|
|
|
1472
1719
|
release_ref: releaseRef,
|
|
1473
1720
|
report: releaseReportPath,
|
|
1474
1721
|
auth_required: authResult.required,
|
|
1722
|
+
problem_evaluation: summarizeProblemEvaluation(releaseProblemEvaluation),
|
|
1475
1723
|
domain_chain: domainChainMetadata,
|
|
1476
1724
|
auto_errorbook_records: autoErrorbookRecords
|
|
1477
1725
|
});
|
|
@@ -1503,6 +1751,7 @@ async function runStudioReleaseCommand(options = {}, dependencies = {}) {
|
|
|
1503
1751
|
release_ref: releaseRef,
|
|
1504
1752
|
report: releaseReportPath,
|
|
1505
1753
|
auth_required: authResult.required,
|
|
1754
|
+
problem_evaluation: summarizeProblemEvaluation(releaseProblemEvaluation),
|
|
1506
1755
|
domain_chain: domainChainMetadata,
|
|
1507
1756
|
auto_errorbook_records: autoErrorbookRecords
|
|
1508
1757
|
}, fileSystem);
|
|
@@ -1636,8 +1885,30 @@ async function runStudioEventsCommand(options = {}, dependencies = {}) {
|
|
|
1636
1885
|
return payload;
|
|
1637
1886
|
}
|
|
1638
1887
|
|
|
1639
|
-
async function runStudioCommand(handler, options) {
|
|
1888
|
+
async function runStudioCommand(handler, options, stageName = '') {
|
|
1640
1889
|
try {
|
|
1890
|
+
const stage = normalizeString(stageName) || 'unknown';
|
|
1891
|
+
const sceneId = normalizeString(options && options.scene);
|
|
1892
|
+
const summaryGoal = normalizeString(options && options.goal);
|
|
1893
|
+
const fromChat = normalizeString(options && options.fromChat);
|
|
1894
|
+
const summaryParts = [
|
|
1895
|
+
'studio',
|
|
1896
|
+
stage,
|
|
1897
|
+
sceneId ? `scene=${sceneId}` : '',
|
|
1898
|
+
summaryGoal ? `goal=${summaryGoal}` : '',
|
|
1899
|
+
fromChat ? `chat=${fromChat}` : ''
|
|
1900
|
+
].filter(Boolean);
|
|
1901
|
+
|
|
1902
|
+
await captureTimelineCheckpoint({
|
|
1903
|
+
trigger: 'key-event',
|
|
1904
|
+
event: `studio.${stage}`,
|
|
1905
|
+
summary: summaryParts.join(' | '),
|
|
1906
|
+
command: `sce studio ${stage}`.trim(),
|
|
1907
|
+
sceneId
|
|
1908
|
+
}, {
|
|
1909
|
+
projectPath: process.cwd()
|
|
1910
|
+
});
|
|
1911
|
+
|
|
1641
1912
|
await handler(options);
|
|
1642
1913
|
} catch (error) {
|
|
1643
1914
|
console.error(chalk.red(`Studio command failed: ${error.message}`));
|
|
@@ -1660,7 +1931,7 @@ function registerStudioCommands(program) {
|
|
|
1660
1931
|
.option('--target <target>', 'Target integration profile', 'default')
|
|
1661
1932
|
.option('--job <job-id>', 'Reuse an explicit studio job id')
|
|
1662
1933
|
.option('--json', 'Print machine-readable JSON output')
|
|
1663
|
-
.action(async (options) => runStudioCommand(runStudioPlanCommand, options));
|
|
1934
|
+
.action(async (options) => runStudioCommand(runStudioPlanCommand, options, 'plan'));
|
|
1664
1935
|
|
|
1665
1936
|
studio
|
|
1666
1937
|
.command('generate')
|
|
@@ -1670,7 +1941,7 @@ function registerStudioCommands(program) {
|
|
|
1670
1941
|
.option('--patch-bundle <id>', 'Explicit patch bundle id')
|
|
1671
1942
|
.option('--job <job-id>', 'Studio job id (defaults to latest)')
|
|
1672
1943
|
.option('--json', 'Print machine-readable JSON output')
|
|
1673
|
-
.action(async (options) => runStudioCommand(runStudioGenerateCommand, options));
|
|
1944
|
+
.action(async (options) => runStudioCommand(runStudioGenerateCommand, options, 'generate'));
|
|
1674
1945
|
|
|
1675
1946
|
studio
|
|
1676
1947
|
.command('apply')
|
|
@@ -1680,7 +1951,7 @@ function registerStudioCommands(program) {
|
|
|
1680
1951
|
.option('--require-auth', 'Require authorization even when policy is advisory')
|
|
1681
1952
|
.option('--job <job-id>', 'Studio job id (defaults to latest)')
|
|
1682
1953
|
.option('--json', 'Print machine-readable JSON output')
|
|
1683
|
-
.action(async (options) => runStudioCommand(runStudioApplyCommand, options));
|
|
1954
|
+
.action(async (options) => runStudioCommand(runStudioApplyCommand, options, 'apply'));
|
|
1684
1955
|
|
|
1685
1956
|
studio
|
|
1686
1957
|
.command('verify')
|
|
@@ -1688,7 +1959,7 @@ function registerStudioCommands(program) {
|
|
|
1688
1959
|
.option('--profile <profile>', 'Verification profile', 'standard')
|
|
1689
1960
|
.option('--job <job-id>', 'Studio job id (defaults to latest)')
|
|
1690
1961
|
.option('--json', 'Print machine-readable JSON output')
|
|
1691
|
-
.action(async (options) => runStudioCommand(runStudioVerifyCommand, options));
|
|
1962
|
+
.action(async (options) => runStudioCommand(runStudioVerifyCommand, options, 'verify'));
|
|
1692
1963
|
|
|
1693
1964
|
studio
|
|
1694
1965
|
.command('release')
|
|
@@ -1700,14 +1971,14 @@ function registerStudioCommands(program) {
|
|
|
1700
1971
|
.option('--release-ref <ref>', 'Explicit release reference/tag')
|
|
1701
1972
|
.option('--job <job-id>', 'Studio job id (defaults to latest)')
|
|
1702
1973
|
.option('--json', 'Print machine-readable JSON output')
|
|
1703
|
-
.action(async (options) => runStudioCommand(runStudioReleaseCommand, options));
|
|
1974
|
+
.action(async (options) => runStudioCommand(runStudioReleaseCommand, options, 'release'));
|
|
1704
1975
|
|
|
1705
1976
|
studio
|
|
1706
1977
|
.command('resume')
|
|
1707
1978
|
.description('Inspect current studio job and next action')
|
|
1708
1979
|
.option('--job <job-id>', 'Studio job id (defaults to latest)')
|
|
1709
1980
|
.option('--json', 'Print machine-readable JSON output')
|
|
1710
|
-
.action(async (options) => runStudioCommand(runStudioResumeCommand, options));
|
|
1981
|
+
.action(async (options) => runStudioCommand(runStudioResumeCommand, options, 'resume'));
|
|
1711
1982
|
|
|
1712
1983
|
studio
|
|
1713
1984
|
.command('events')
|
|
@@ -1715,7 +1986,7 @@ function registerStudioCommands(program) {
|
|
|
1715
1986
|
.option('--job <job-id>', 'Studio job id (defaults to latest)')
|
|
1716
1987
|
.option('--limit <number>', 'Maximum number of recent events to return', '50')
|
|
1717
1988
|
.option('--json', 'Print machine-readable JSON output')
|
|
1718
|
-
.action(async (options) => runStudioCommand(runStudioEventsCommand, options));
|
|
1989
|
+
.action(async (options) => runStudioCommand(runStudioEventsCommand, options, 'events'));
|
|
1719
1990
|
|
|
1720
1991
|
studio
|
|
1721
1992
|
.command('rollback')
|
|
@@ -1725,7 +1996,7 @@ function registerStudioCommands(program) {
|
|
|
1725
1996
|
.option('--auth-password <password>', 'Authorization password for protected rollback action')
|
|
1726
1997
|
.option('--require-auth', 'Require authorization even when policy is advisory')
|
|
1727
1998
|
.option('--json', 'Print machine-readable JSON output')
|
|
1728
|
-
.action(async (options) => runStudioCommand(runStudioRollbackCommand, options));
|
|
1999
|
+
.action(async (options) => runStudioCommand(runStudioRollbackCommand, options, 'rollback'));
|
|
1729
2000
|
}
|
|
1730
2001
|
|
|
1731
2002
|
module.exports = {
|