scene-capability-engine 3.4.5 → 3.4.6
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 +20 -0
- package/README.md +28 -1
- package/README.zh.md +28 -1
- package/docs/command-reference.md +37 -7
- package/docs/images/wechat-qr.png +0 -0
- package/lib/adoption/adoption-strategy.js +1 -0
- package/lib/adoption/detection-engine.js +1 -0
- package/lib/adoption/file-classifier.js +2 -1
- package/lib/adoption/smart-orchestrator.js +1 -0
- package/lib/commands/errorbook.js +142 -2
- package/lib/commands/studio.js +301 -8
- package/lib/problem/problem-evaluator.js +431 -16
- package/lib/spec/domain-modeling.js +49 -4
- package/lib/workspace/takeover-baseline.js +72 -4
- package/package.json +1 -1
- package/template/.sce/config/problem-closure-policy.json +18 -0
- package/template/.sce/config/problem-eval-policy.json +43 -1
- package/template/.sce/config/spec-domain-policy.json +9 -1
- package/template/.sce/steering/CORE_PRINCIPLES.md +4 -2
package/lib/commands/studio.js
CHANGED
|
@@ -19,6 +19,8 @@ const STUDIO_EVENT_API_VERSION = 'sce.studio.event/v0.1';
|
|
|
19
19
|
const VERIFY_PROFILES = new Set(['fast', 'standard', 'strict']);
|
|
20
20
|
const RELEASE_PROFILES = new Set(['standard', 'strict']);
|
|
21
21
|
const STUDIO_REPORTS_DIR = '.sce/reports/studio';
|
|
22
|
+
const DEFAULT_INTERACTIVE_GOVERNANCE_REPORT = '.sce/reports/interactive-governance-report.json';
|
|
23
|
+
const DEFAULT_PROBLEM_CONTRACT_RELATIVE_PATH = path.join('custom', 'problem-contract.json');
|
|
22
24
|
const MAX_OUTPUT_PREVIEW_LENGTH = 2000;
|
|
23
25
|
const DEFAULT_STUDIO_SECURITY_POLICY = Object.freeze({
|
|
24
26
|
enabled: false,
|
|
@@ -368,6 +370,7 @@ async function buildVerifyGateSteps(options = {}, dependencies = {}) {
|
|
|
368
370
|
const projectPath = dependencies.projectPath || process.cwd();
|
|
369
371
|
const fileSystem = dependencies.fileSystem || fs;
|
|
370
372
|
const profile = normalizeString(options.profile) || 'standard';
|
|
373
|
+
const specId = normalizeString(options.specId || dependencies.specId);
|
|
371
374
|
|
|
372
375
|
if (!VERIFY_PROFILES.has(profile)) {
|
|
373
376
|
throw new Error(`Invalid verify profile "${profile}". Expected one of: ${Array.from(VERIFY_PROFILES).join(', ')}`);
|
|
@@ -403,6 +406,21 @@ async function buildVerifyGateSteps(options = {}, dependencies = {}) {
|
|
|
403
406
|
}
|
|
404
407
|
|
|
405
408
|
if (profile === 'standard' || profile === 'strict') {
|
|
409
|
+
const problemClosureGateScript = path.join(projectPath, 'scripts', 'problem-closure-gate.js');
|
|
410
|
+
const hasProblemClosureGateScript = await fileSystem.pathExists(problemClosureGateScript);
|
|
411
|
+
const canRunProblemClosureGate = hasProblemClosureGateScript && Boolean(specId);
|
|
412
|
+
steps.push({
|
|
413
|
+
id: 'problem-closure-gate',
|
|
414
|
+
name: 'problem closure gate (verify)',
|
|
415
|
+
command: 'node',
|
|
416
|
+
args: ['scripts/problem-closure-gate.js', '--stage', 'verify', '--spec', specId, '--fail-on-block', '--json'],
|
|
417
|
+
required: Boolean(specId),
|
|
418
|
+
enabled: canRunProblemClosureGate,
|
|
419
|
+
skip_reason: canRunProblemClosureGate
|
|
420
|
+
? ''
|
|
421
|
+
: (specId ? 'scripts/problem-closure-gate.js not found' : 'spec id unavailable for problem-closure gate')
|
|
422
|
+
});
|
|
423
|
+
|
|
406
424
|
const governanceScript = path.join(projectPath, 'scripts', 'interactive-governance-report.js');
|
|
407
425
|
const hasGovernanceScript = await fileSystem.pathExists(governanceScript);
|
|
408
426
|
steps.push({
|
|
@@ -435,11 +453,32 @@ async function buildReleaseGateSteps(options = {}, dependencies = {}) {
|
|
|
435
453
|
const projectPath = dependencies.projectPath || process.cwd();
|
|
436
454
|
const fileSystem = dependencies.fileSystem || fs;
|
|
437
455
|
const profile = normalizeString(options.profile) || 'standard';
|
|
456
|
+
const specId = normalizeString(options.specId || dependencies.specId);
|
|
457
|
+
const verifyReportPath = normalizeString(options.verifyReportPath || dependencies.verifyReportPath);
|
|
438
458
|
if (!RELEASE_PROFILES.has(profile)) {
|
|
439
459
|
throw new Error(`Invalid release profile "${profile}". Expected one of: ${Array.from(RELEASE_PROFILES).join(', ')}`);
|
|
440
460
|
}
|
|
441
461
|
|
|
442
462
|
const steps = [];
|
|
463
|
+
const problemClosureGateScript = path.join(projectPath, 'scripts', 'problem-closure-gate.js');
|
|
464
|
+
const hasProblemClosureGateScript = await fileSystem.pathExists(problemClosureGateScript);
|
|
465
|
+
const canRunProblemClosureGate = hasProblemClosureGateScript && Boolean(specId);
|
|
466
|
+
const problemClosureArgs = ['scripts/problem-closure-gate.js', '--stage', 'release', '--spec', specId, '--fail-on-block', '--json'];
|
|
467
|
+
if (verifyReportPath) {
|
|
468
|
+
problemClosureArgs.push('--verify-report', verifyReportPath);
|
|
469
|
+
}
|
|
470
|
+
steps.push({
|
|
471
|
+
id: 'problem-closure-gate',
|
|
472
|
+
name: 'problem closure gate (release)',
|
|
473
|
+
command: 'node',
|
|
474
|
+
args: problemClosureArgs,
|
|
475
|
+
required: Boolean(specId),
|
|
476
|
+
enabled: canRunProblemClosureGate,
|
|
477
|
+
skip_reason: canRunProblemClosureGate
|
|
478
|
+
? ''
|
|
479
|
+
: (specId ? 'scripts/problem-closure-gate.js not found' : 'spec id unavailable for problem-closure gate')
|
|
480
|
+
});
|
|
481
|
+
|
|
443
482
|
steps.push({
|
|
444
483
|
id: 'npm-pack-dry-run',
|
|
445
484
|
name: 'npm pack --dry-run',
|
|
@@ -710,6 +749,77 @@ async function readSpecDomainChain(projectPath, specId, fileSystem = fs) {
|
|
|
710
749
|
}
|
|
711
750
|
}
|
|
712
751
|
|
|
752
|
+
async function readSpecProblemContract(projectPath, specId, fileSystem = fs) {
|
|
753
|
+
const specRoot = path.join(projectPath, '.sce', 'specs', specId);
|
|
754
|
+
const contractPath = path.join(specRoot, DEFAULT_PROBLEM_CONTRACT_RELATIVE_PATH);
|
|
755
|
+
if (!await fileSystem.pathExists(contractPath)) {
|
|
756
|
+
return null;
|
|
757
|
+
}
|
|
758
|
+
try {
|
|
759
|
+
const payload = await fileSystem.readJson(contractPath);
|
|
760
|
+
const stat = await fileSystem.stat(contractPath);
|
|
761
|
+
return {
|
|
762
|
+
spec_id: specId,
|
|
763
|
+
contract_path: toRelativePosix(projectPath, contractPath),
|
|
764
|
+
payload,
|
|
765
|
+
updated_at: stat && stat.mtime ? stat.mtime.toISOString() : null,
|
|
766
|
+
mtime_ms: Number(stat && stat.mtimeMs) || 0
|
|
767
|
+
};
|
|
768
|
+
} catch (_error) {
|
|
769
|
+
return null;
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
async function readGovernanceSignals(projectPath, fileSystem = fs) {
|
|
774
|
+
const reportPath = path.join(projectPath, DEFAULT_INTERACTIVE_GOVERNANCE_REPORT);
|
|
775
|
+
if (!await fileSystem.pathExists(reportPath)) {
|
|
776
|
+
return {
|
|
777
|
+
available: false,
|
|
778
|
+
report_path: null,
|
|
779
|
+
high_breach_count: 0,
|
|
780
|
+
medium_breach_count: 0
|
|
781
|
+
};
|
|
782
|
+
}
|
|
783
|
+
const payload = await fileSystem.readJson(reportPath).catch(() => null);
|
|
784
|
+
const summary = extractGovernanceBreachSignals(payload || {});
|
|
785
|
+
return {
|
|
786
|
+
...summary,
|
|
787
|
+
report_path: toRelativePosix(projectPath, reportPath)
|
|
788
|
+
};
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
async function readVerifyReportSignals(projectPath, verifyReportPath = '', fileSystem = fs) {
|
|
792
|
+
const normalized = normalizeString(verifyReportPath);
|
|
793
|
+
if (!normalized) {
|
|
794
|
+
return {
|
|
795
|
+
available: false,
|
|
796
|
+
report_path: null,
|
|
797
|
+
passed: false,
|
|
798
|
+
failed_step_count: 0
|
|
799
|
+
};
|
|
800
|
+
}
|
|
801
|
+
const absolutePath = path.isAbsolute(normalized)
|
|
802
|
+
? normalized
|
|
803
|
+
: path.join(projectPath, normalized);
|
|
804
|
+
if (!await fileSystem.pathExists(absolutePath)) {
|
|
805
|
+
return {
|
|
806
|
+
available: false,
|
|
807
|
+
report_path: normalized,
|
|
808
|
+
passed: false,
|
|
809
|
+
failed_step_count: 0
|
|
810
|
+
};
|
|
811
|
+
}
|
|
812
|
+
const payload = await fileSystem.readJson(absolutePath).catch(() => null);
|
|
813
|
+
const steps = Array.isArray(payload && payload.steps) ? payload.steps : [];
|
|
814
|
+
const failedStepCount = steps.filter((step) => normalizeString(step && step.status) === 'failed').length;
|
|
815
|
+
return {
|
|
816
|
+
available: true,
|
|
817
|
+
report_path: toRelativePosix(projectPath, absolutePath),
|
|
818
|
+
passed: payload && payload.passed === true && failedStepCount === 0,
|
|
819
|
+
failed_step_count: failedStepCount
|
|
820
|
+
};
|
|
821
|
+
}
|
|
822
|
+
|
|
713
823
|
function normalizeChainList(value, limit = 5) {
|
|
714
824
|
if (!Array.isArray(value)) {
|
|
715
825
|
return [];
|
|
@@ -725,13 +835,97 @@ function normalizeChainList(value, limit = 5) {
|
|
|
725
835
|
});
|
|
726
836
|
}
|
|
727
837
|
|
|
838
|
+
function normalizeProblemContract(contract = {}, context = {}) {
|
|
839
|
+
const source = contract && typeof contract === 'object' ? contract : {};
|
|
840
|
+
const issueStatement = normalizeString(
|
|
841
|
+
source.issue_statement
|
|
842
|
+
|| source.issue
|
|
843
|
+
|| source.problem_statement
|
|
844
|
+
|| context.problem_statement
|
|
845
|
+
|| context.goal
|
|
846
|
+
);
|
|
847
|
+
const expectedOutcome = normalizeString(
|
|
848
|
+
source.expected_outcome
|
|
849
|
+
|| source.expected
|
|
850
|
+
|| source.success_criteria
|
|
851
|
+
|| context.verification_plan
|
|
852
|
+
|| (context.scene_id ? `Scene ${context.scene_id} reaches deterministic verification gates.` : '')
|
|
853
|
+
);
|
|
854
|
+
const reproductionSteps = normalizeChainList(
|
|
855
|
+
source.reproduction_steps || source.repro_steps || source.steps,
|
|
856
|
+
20
|
|
857
|
+
);
|
|
858
|
+
const fallbackRepro = reproductionSteps.length > 0
|
|
859
|
+
? reproductionSteps
|
|
860
|
+
: [
|
|
861
|
+
normalizeString(context.goal) || 'Reproduce the reported issue in the target scene.',
|
|
862
|
+
'Capture logs and gate evidence for the failing path.'
|
|
863
|
+
].filter(Boolean);
|
|
864
|
+
const forbiddenWorkarounds = normalizeChainList(
|
|
865
|
+
source.forbidden_workarounds || source.prohibited_workarounds || source.disallowed_workarounds,
|
|
866
|
+
20
|
|
867
|
+
);
|
|
868
|
+
const fallbackForbidden = forbiddenWorkarounds.length > 0
|
|
869
|
+
? forbiddenWorkarounds
|
|
870
|
+
: [
|
|
871
|
+
'Do not bypass gates or tests.',
|
|
872
|
+
'Do not silence runtime errors.'
|
|
873
|
+
];
|
|
874
|
+
|
|
875
|
+
return {
|
|
876
|
+
issue_statement: issueStatement,
|
|
877
|
+
expected_outcome: expectedOutcome,
|
|
878
|
+
reproduction_steps: fallbackRepro,
|
|
879
|
+
impact_scope: normalizeString(source.impact_scope || source.scope || context.scene_id),
|
|
880
|
+
forbidden_workarounds: fallbackForbidden
|
|
881
|
+
};
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
function extractGovernanceBreachSignals(report = {}) {
|
|
885
|
+
if (!report || typeof report !== 'object') {
|
|
886
|
+
return {
|
|
887
|
+
available: false,
|
|
888
|
+
high_breach_count: 0,
|
|
889
|
+
medium_breach_count: 0
|
|
890
|
+
};
|
|
891
|
+
}
|
|
892
|
+
const alerts = Array.isArray(report.alerts) ? report.alerts : [];
|
|
893
|
+
let highBreachCount = 0;
|
|
894
|
+
let mediumBreachCount = 0;
|
|
895
|
+
for (const alert of alerts) {
|
|
896
|
+
const status = normalizeString(alert && alert.status).toLowerCase();
|
|
897
|
+
const severity = normalizeString(alert && alert.severity).toLowerCase();
|
|
898
|
+
if (status !== 'breach') {
|
|
899
|
+
continue;
|
|
900
|
+
}
|
|
901
|
+
if (severity === 'high') {
|
|
902
|
+
highBreachCount += 1;
|
|
903
|
+
} else if (severity === 'medium') {
|
|
904
|
+
mediumBreachCount += 1;
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
return {
|
|
908
|
+
available: true,
|
|
909
|
+
high_breach_count: highBreachCount,
|
|
910
|
+
medium_breach_count: mediumBreachCount
|
|
911
|
+
};
|
|
912
|
+
}
|
|
913
|
+
|
|
728
914
|
function summarizeDomainChain(payload = {}) {
|
|
729
915
|
const ontology = payload && typeof payload.ontology === 'object' ? payload.ontology : {};
|
|
916
|
+
const ontologyEvidence = payload && typeof payload.ontology_evidence === 'object' ? payload.ontology_evidence : {};
|
|
730
917
|
const decisionPath = Array.isArray(payload.decision_execution_path) ? payload.decision_execution_path : [];
|
|
731
918
|
const correctionLoop = payload && typeof payload.correction_loop === 'object' ? payload.correction_loop : {};
|
|
732
919
|
const verification = payload && typeof payload.verification === 'object' ? payload.verification : {};
|
|
733
920
|
const hypotheses = Array.isArray(payload.hypotheses) ? payload.hypotheses : [];
|
|
734
921
|
const risks = Array.isArray(payload.risks) ? payload.risks : [];
|
|
922
|
+
const evidenceBindingCount = (
|
|
923
|
+
normalizeChainList(ontologyEvidence.entity, 50).length
|
|
924
|
+
+ normalizeChainList(ontologyEvidence.relation, 50).length
|
|
925
|
+
+ normalizeChainList(ontologyEvidence.business_rule, 50).length
|
|
926
|
+
+ normalizeChainList(ontologyEvidence.decision_policy, 50).length
|
|
927
|
+
+ normalizeChainList(ontologyEvidence.execution_flow, 50).length
|
|
928
|
+
);
|
|
735
929
|
|
|
736
930
|
return {
|
|
737
931
|
scene_id: normalizeString(payload.scene_id) || null,
|
|
@@ -747,6 +941,8 @@ function summarizeDomainChain(payload = {}) {
|
|
|
747
941
|
hypothesis_count: hypotheses.length,
|
|
748
942
|
risk_count: risks.length,
|
|
749
943
|
decision_path_steps: decisionPath.length,
|
|
944
|
+
evidence_binding_count: evidenceBindingCount,
|
|
945
|
+
verification_plan: normalizeString(verification.plan) || null,
|
|
750
946
|
correction_loop: {
|
|
751
947
|
triggers: normalizeChainList(correctionLoop.triggers, 5),
|
|
752
948
|
actions: normalizeChainList(correctionLoop.actions, 5)
|
|
@@ -781,7 +977,13 @@ function buildDomainChainRuntimeContext(payload = {}) {
|
|
|
781
977
|
verification: {
|
|
782
978
|
plan: normalizeString(payload?.verification?.plan) || null,
|
|
783
979
|
gates: normalizeChainList(payload?.verification?.gates, 10)
|
|
784
|
-
}
|
|
980
|
+
},
|
|
981
|
+
problem_contract: normalizeProblemContract(payload?.problem_contract || {}, {
|
|
982
|
+
scene_id: normalizeString(payload.scene_id) || '',
|
|
983
|
+
goal: normalizeString(payload?.problem?.statement) || '',
|
|
984
|
+
problem_statement: normalizeString(payload?.problem?.statement) || '',
|
|
985
|
+
verification_plan: normalizeString(payload?.verification?.plan) || ''
|
|
986
|
+
})
|
|
785
987
|
};
|
|
786
988
|
}
|
|
787
989
|
|
|
@@ -834,12 +1036,22 @@ async function resolveDomainChainBinding(options = {}, dependencies = {}) {
|
|
|
834
1036
|
problemStatement: goal || `Studio scene cycle for ${sceneId}`
|
|
835
1037
|
});
|
|
836
1038
|
const chain = await readSpecDomainChain(projectPath, explicitSpec, fileSystem);
|
|
1039
|
+
const problemContract = await readSpecProblemContract(projectPath, explicitSpec, fileSystem);
|
|
837
1040
|
if (!chain) {
|
|
838
1041
|
return {
|
|
839
1042
|
resolved: false,
|
|
840
1043
|
source: 'explicit-spec',
|
|
841
1044
|
spec_id: explicitSpec,
|
|
842
|
-
reason: 'domain_chain_missing'
|
|
1045
|
+
reason: 'domain_chain_missing',
|
|
1046
|
+
problem_contract: problemContract
|
|
1047
|
+
? normalizeProblemContract(problemContract.payload, {
|
|
1048
|
+
scene_id: sceneId,
|
|
1049
|
+
goal
|
|
1050
|
+
})
|
|
1051
|
+
: normalizeProblemContract({}, {
|
|
1052
|
+
scene_id: sceneId,
|
|
1053
|
+
goal
|
|
1054
|
+
})
|
|
843
1055
|
};
|
|
844
1056
|
}
|
|
845
1057
|
return {
|
|
@@ -849,7 +1061,17 @@ async function resolveDomainChainBinding(options = {}, dependencies = {}) {
|
|
|
849
1061
|
chain_path: chain.chain_path,
|
|
850
1062
|
updated_at: chain.updated_at,
|
|
851
1063
|
summary: summarizeDomainChain(chain.payload),
|
|
852
|
-
context: buildDomainChainRuntimeContext(chain.payload)
|
|
1064
|
+
context: buildDomainChainRuntimeContext(chain.payload),
|
|
1065
|
+
problem_contract: normalizeProblemContract(
|
|
1066
|
+
problemContract && problemContract.payload ? problemContract.payload : chain.payload?.problem_contract || {},
|
|
1067
|
+
{
|
|
1068
|
+
scene_id: sceneId,
|
|
1069
|
+
goal,
|
|
1070
|
+
problem_statement: normalizeString(chain?.payload?.problem?.statement),
|
|
1071
|
+
verification_plan: normalizeString(chain?.payload?.verification?.plan)
|
|
1072
|
+
}
|
|
1073
|
+
),
|
|
1074
|
+
problem_contract_path: problemContract ? problemContract.contract_path : null
|
|
853
1075
|
};
|
|
854
1076
|
}
|
|
855
1077
|
|
|
@@ -873,6 +1095,7 @@ async function resolveDomainChainBinding(options = {}, dependencies = {}) {
|
|
|
873
1095
|
}
|
|
874
1096
|
|
|
875
1097
|
const selected = candidates[0];
|
|
1098
|
+
const selectedContract = await readSpecProblemContract(projectPath, selected.spec_id, fileSystem);
|
|
876
1099
|
return {
|
|
877
1100
|
resolved: true,
|
|
878
1101
|
source: candidates.length === 1 ? 'scene-auto-single' : 'scene-auto-latest',
|
|
@@ -886,7 +1109,17 @@ async function resolveDomainChainBinding(options = {}, dependencies = {}) {
|
|
|
886
1109
|
updated_at: item.updated_at
|
|
887
1110
|
})),
|
|
888
1111
|
summary: summarizeDomainChain(selected.payload),
|
|
889
|
-
context: buildDomainChainRuntimeContext(selected.payload)
|
|
1112
|
+
context: buildDomainChainRuntimeContext(selected.payload),
|
|
1113
|
+
problem_contract: normalizeProblemContract(
|
|
1114
|
+
selectedContract && selectedContract.payload ? selectedContract.payload : selected.payload?.problem_contract || {},
|
|
1115
|
+
{
|
|
1116
|
+
scene_id: sceneId,
|
|
1117
|
+
goal,
|
|
1118
|
+
problem_statement: normalizeString(selected?.payload?.problem?.statement),
|
|
1119
|
+
verification_plan: normalizeString(selected?.payload?.verification?.plan)
|
|
1120
|
+
}
|
|
1121
|
+
),
|
|
1122
|
+
problem_contract_path: selectedContract ? selectedContract.contract_path : null
|
|
890
1123
|
};
|
|
891
1124
|
}
|
|
892
1125
|
|
|
@@ -949,6 +1182,14 @@ function buildJobDomainChainMetadata(job = {}) {
|
|
|
949
1182
|
: null;
|
|
950
1183
|
const summary = domainChain && domainChain.summary ? domainChain.summary : null;
|
|
951
1184
|
const context = domainChain && domainChain.context ? domainChain.context : null;
|
|
1185
|
+
const problemContract = job?.source?.problem_contract && typeof job.source.problem_contract === 'object'
|
|
1186
|
+
? job.source.problem_contract
|
|
1187
|
+
: normalizeProblemContract(context && context.problem_contract ? context.problem_contract : {}, {
|
|
1188
|
+
scene_id: normalizeString(job?.scene?.id),
|
|
1189
|
+
goal: normalizeString(job?.source?.goal),
|
|
1190
|
+
problem_statement: normalizeString(summary && summary.problem_statement),
|
|
1191
|
+
verification_plan: normalizeString(summary && summary.verification_plan)
|
|
1192
|
+
});
|
|
952
1193
|
return {
|
|
953
1194
|
resolved: domainChain && domainChain.resolved === true,
|
|
954
1195
|
source: domainChain && domainChain.source ? domainChain.source : 'none',
|
|
@@ -957,12 +1198,14 @@ function buildJobDomainChainMetadata(job = {}) {
|
|
|
957
1198
|
reason: domainChain && domainChain.reason ? domainChain.reason : null,
|
|
958
1199
|
decision_path_steps: summary ? Number(summary.decision_path_steps || 0) : 0,
|
|
959
1200
|
risk_count: summary ? Number(summary.risk_count || 0) : 0,
|
|
1201
|
+
evidence_binding_count: summary ? Number(summary.evidence_binding_count || 0) : 0,
|
|
960
1202
|
correction_triggers: summary && summary.correction_loop
|
|
961
1203
|
? normalizeChainList(summary.correction_loop.triggers, 10)
|
|
962
1204
|
: [],
|
|
963
1205
|
verification_gates: summary
|
|
964
1206
|
? normalizeChainList(summary.verification_gates, 10)
|
|
965
1207
|
: [],
|
|
1208
|
+
problem_contract: problemContract,
|
|
966
1209
|
summary: summary || null,
|
|
967
1210
|
context: context || null
|
|
968
1211
|
};
|
|
@@ -975,6 +1218,18 @@ function summarizeProblemEvaluation(evaluation = {}) {
|
|
|
975
1218
|
confidence_score: Number(evaluation.confidence_score || 0),
|
|
976
1219
|
risk_level: normalizeString(evaluation?.dimensions?.risk?.level) || 'low',
|
|
977
1220
|
strategy: normalizeString(evaluation?.dimensions?.strategy?.strategy) || 'direct-execution',
|
|
1221
|
+
contract_score: Number(evaluation?.dimensions?.problem_contract?.score || 0),
|
|
1222
|
+
ontology_score: Number(evaluation?.dimensions?.ontology_alignment?.score || 0),
|
|
1223
|
+
convergence_score: Number(evaluation?.dimensions?.convergence?.score || 0),
|
|
1224
|
+
contract_missing: Array.isArray(evaluation?.dimensions?.problem_contract?.missing)
|
|
1225
|
+
? evaluation.dimensions.problem_contract.missing
|
|
1226
|
+
: [],
|
|
1227
|
+
ontology_missing_axes: Array.isArray(evaluation?.dimensions?.ontology_alignment?.missing_axes)
|
|
1228
|
+
? evaluation.dimensions.ontology_alignment.missing_axes
|
|
1229
|
+
: [],
|
|
1230
|
+
convergence_missing: Array.isArray(evaluation?.dimensions?.convergence?.missing)
|
|
1231
|
+
? evaluation.dimensions.convergence.missing
|
|
1232
|
+
: [],
|
|
978
1233
|
blockers: Array.isArray(evaluation.blockers) ? evaluation.blockers : [],
|
|
979
1234
|
warnings: Array.isArray(evaluation.warnings) ? evaluation.warnings : [],
|
|
980
1235
|
recommendations: Array.isArray(evaluation.recommendations) ? evaluation.recommendations : [],
|
|
@@ -1044,6 +1299,7 @@ async function enforceProblemEvaluationForStage(job = {}, stage = '', context =
|
|
|
1044
1299
|
goal: normalizeString(context.goal || job?.source?.goal),
|
|
1045
1300
|
release_channel: normalizeString(context.release_channel || ''),
|
|
1046
1301
|
domain_chain: context.domain_chain || (job?.source?.domain_chain || {}),
|
|
1302
|
+
problem_contract: context.problem_contract || job?.source?.problem_contract || {},
|
|
1047
1303
|
related_specs_count: Number(context.related_specs_count || job?.source?.related_specs?.total_candidates || 0),
|
|
1048
1304
|
stage_readiness: context.stage_readiness || buildStageReadiness(job, stage),
|
|
1049
1305
|
gate_signals: context.gate_signals || {}
|
|
@@ -1127,6 +1383,15 @@ async function runStudioPlanCommand(options = {}, dependencies = {}) {
|
|
|
1127
1383
|
|
|
1128
1384
|
const jobId = normalizeString(options.job) || createJobId();
|
|
1129
1385
|
const now = nowIso();
|
|
1386
|
+
const problemContract = normalizeProblemContract(
|
|
1387
|
+
domainChainBinding.problem_contract || {},
|
|
1388
|
+
{
|
|
1389
|
+
scene_id: sceneId,
|
|
1390
|
+
goal: normalizeString(options.goal),
|
|
1391
|
+
problem_statement: normalizeString(domainChainBinding?.summary?.problem_statement),
|
|
1392
|
+
verification_plan: normalizeString(domainChainBinding?.summary?.verification_plan)
|
|
1393
|
+
}
|
|
1394
|
+
);
|
|
1130
1395
|
const planShadowJob = {
|
|
1131
1396
|
job_id: jobId,
|
|
1132
1397
|
scene: {
|
|
@@ -1136,6 +1401,8 @@ async function runStudioPlanCommand(options = {}, dependencies = {}) {
|
|
|
1136
1401
|
source: {
|
|
1137
1402
|
goal: normalizeString(options.goal) || null,
|
|
1138
1403
|
spec_id: domainChainBinding.spec_id || specId || null,
|
|
1404
|
+
problem_contract: problemContract,
|
|
1405
|
+
problem_contract_path: domainChainBinding.problem_contract_path || null,
|
|
1139
1406
|
domain_chain: {
|
|
1140
1407
|
resolved: domainChainBinding.resolved === true,
|
|
1141
1408
|
summary: domainChainBinding.summary || null
|
|
@@ -1150,6 +1417,7 @@ async function runStudioPlanCommand(options = {}, dependencies = {}) {
|
|
|
1150
1417
|
scene_id: sceneId,
|
|
1151
1418
|
spec_id: domainChainBinding.spec_id || specId || null,
|
|
1152
1419
|
goal: normalizeString(options.goal) || null,
|
|
1420
|
+
problem_contract: problemContract,
|
|
1153
1421
|
domain_chain: {
|
|
1154
1422
|
resolved: domainChainBinding.resolved === true,
|
|
1155
1423
|
summary: domainChainBinding.summary || null
|
|
@@ -1194,6 +1462,7 @@ async function runStudioPlanCommand(options = {}, dependencies = {}) {
|
|
|
1194
1462
|
domain_chain_path: domainChainBinding.chain_path || null,
|
|
1195
1463
|
domain_chain_summary: domainChainBinding.summary || null,
|
|
1196
1464
|
domain_chain_reason: domainChainBinding.reason || null,
|
|
1465
|
+
problem_contract: problemContract,
|
|
1197
1466
|
problem_evaluation: summarizeProblemEvaluation(planProblemEvaluation),
|
|
1198
1467
|
related_specs_total: Number(relatedSpecLookup.total_candidates || 0),
|
|
1199
1468
|
related_specs_top: relatedSpecItems
|
|
@@ -1210,6 +1479,8 @@ async function runStudioPlanCommand(options = {}, dependencies = {}) {
|
|
|
1210
1479
|
from_chat: fromChat,
|
|
1211
1480
|
goal: normalizeString(options.goal) || null,
|
|
1212
1481
|
spec_id: domainChainBinding.spec_id || specId || null,
|
|
1482
|
+
problem_contract: problemContract,
|
|
1483
|
+
problem_contract_path: domainChainBinding.problem_contract_path || null,
|
|
1213
1484
|
domain_chain: {
|
|
1214
1485
|
resolved: domainChainBinding.resolved === true,
|
|
1215
1486
|
source: domainChainBinding.source || 'none',
|
|
@@ -1267,6 +1538,7 @@ async function runStudioPlanCommand(options = {}, dependencies = {}) {
|
|
|
1267
1538
|
domain_chain_source: domainChainBinding.source || 'none',
|
|
1268
1539
|
domain_chain_spec_id: domainChainBinding.spec_id || null,
|
|
1269
1540
|
domain_chain_path: domainChainBinding.chain_path || null,
|
|
1541
|
+
problem_contract: problemContract,
|
|
1270
1542
|
problem_evaluation: summarizeProblemEvaluation(planProblemEvaluation),
|
|
1271
1543
|
related_specs_total: Number(relatedSpecLookup.total_candidates || 0),
|
|
1272
1544
|
related_spec_ids: relatedSpecItems.map((item) => item.spec_id)
|
|
@@ -1457,16 +1729,19 @@ async function runStudioVerifyCommand(options = {}, dependencies = {}) {
|
|
|
1457
1729
|
const autoErrorbookRecords = [];
|
|
1458
1730
|
const gateSteps = await buildVerifyGateSteps({ profile }, {
|
|
1459
1731
|
projectPath,
|
|
1460
|
-
fileSystem
|
|
1732
|
+
fileSystem,
|
|
1733
|
+
specId: normalizeString(domainChainMetadata.spec_id) || null
|
|
1461
1734
|
});
|
|
1462
1735
|
const verifyProblemEvaluation = await enforceProblemEvaluationForStage(job, 'verify', {
|
|
1463
1736
|
scene_id: normalizeString(job?.scene?.id),
|
|
1464
1737
|
spec_id: normalizeString(domainChainMetadata.spec_id) || normalizeString(job?.source?.spec_id),
|
|
1465
1738
|
goal: normalizeString(job?.source?.goal),
|
|
1466
1739
|
domain_chain: job?.source?.domain_chain || {},
|
|
1740
|
+
problem_contract: job?.source?.problem_contract || {},
|
|
1467
1741
|
related_specs_count: Number(job?.source?.related_specs?.total_candidates || 0),
|
|
1468
1742
|
stage_readiness: buildStageReadiness(job, 'verify', {
|
|
1469
|
-
gate_required_ready: deriveGateSignals(gateSteps).required_missing === 0
|
|
1743
|
+
gate_required_ready: deriveGateSignals(gateSteps).required_missing === 0,
|
|
1744
|
+
convergence_strict: profile === 'strict'
|
|
1470
1745
|
}),
|
|
1471
1746
|
gate_signals: deriveGateSignals(gateSteps)
|
|
1472
1747
|
}, {
|
|
@@ -1609,9 +1884,17 @@ async function runStudioReleaseCommand(options = {}, dependencies = {}) {
|
|
|
1609
1884
|
const releaseStartedAt = nowIso();
|
|
1610
1885
|
const domainChainMetadata = buildJobDomainChainMetadata(job);
|
|
1611
1886
|
const autoErrorbookRecords = [];
|
|
1612
|
-
const
|
|
1887
|
+
const verifyReportSignals = await readVerifyReportSignals(
|
|
1613
1888
|
projectPath,
|
|
1889
|
+
normalizeString(job?.artifacts?.verify_report),
|
|
1614
1890
|
fileSystem
|
|
1891
|
+
);
|
|
1892
|
+
const governanceSignals = await readGovernanceSignals(projectPath, fileSystem);
|
|
1893
|
+
const gateSteps = await buildReleaseGateSteps({ profile }, {
|
|
1894
|
+
projectPath,
|
|
1895
|
+
fileSystem,
|
|
1896
|
+
specId: normalizeString(domainChainMetadata.spec_id) || null,
|
|
1897
|
+
verifyReportPath: normalizeString(job?.artifacts?.verify_report) || null
|
|
1615
1898
|
});
|
|
1616
1899
|
const releaseGateSignals = deriveGateSignals(gateSteps);
|
|
1617
1900
|
const releaseProblemEvaluation = await enforceProblemEvaluationForStage(job, 'release', {
|
|
@@ -1620,9 +1903,17 @@ async function runStudioReleaseCommand(options = {}, dependencies = {}) {
|
|
|
1620
1903
|
goal: normalizeString(job?.source?.goal),
|
|
1621
1904
|
release_channel: channel,
|
|
1622
1905
|
domain_chain: job?.source?.domain_chain || {},
|
|
1906
|
+
problem_contract: job?.source?.problem_contract || {},
|
|
1623
1907
|
related_specs_count: Number(job?.source?.related_specs?.total_candidates || 0),
|
|
1624
1908
|
stage_readiness: buildStageReadiness(job, 'release', {
|
|
1625
|
-
gate_required_ready: releaseGateSignals.required_missing === 0
|
|
1909
|
+
gate_required_ready: releaseGateSignals.required_missing === 0,
|
|
1910
|
+
convergence_strict: profile === 'strict',
|
|
1911
|
+
verify_stage_passed: isStageCompleted(job, 'verify'),
|
|
1912
|
+
verify_report_ready: verifyReportSignals.available,
|
|
1913
|
+
verify_report_passed: verifyReportSignals.passed,
|
|
1914
|
+
regression_passed: verifyReportSignals.passed && verifyReportSignals.failed_step_count === 0,
|
|
1915
|
+
governance_report_ready: governanceSignals.available,
|
|
1916
|
+
high_alert_count: Number(governanceSignals.high_breach_count || 0)
|
|
1626
1917
|
}),
|
|
1627
1918
|
gate_signals: releaseGateSignals
|
|
1628
1919
|
}, {
|
|
@@ -1672,6 +1963,8 @@ async function runStudioReleaseCommand(options = {}, dependencies = {}) {
|
|
|
1672
1963
|
passed: gateResult.passed,
|
|
1673
1964
|
steps: gateResult.steps,
|
|
1674
1965
|
domain_chain: domainChainMetadata,
|
|
1966
|
+
verify_signals: verifyReportSignals,
|
|
1967
|
+
governance_signals: governanceSignals,
|
|
1675
1968
|
problem_evaluation: summarizeProblemEvaluation(releaseProblemEvaluation),
|
|
1676
1969
|
auto_errorbook_records: autoErrorbookRecords
|
|
1677
1970
|
};
|