scene-capability-engine 3.3.26 → 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 +82 -0
- package/README.md +100 -711
- package/README.zh.md +103 -577
- package/bin/scene-capability-engine.js +103 -0
- package/docs/README.md +47 -249
- package/docs/command-reference.md +84 -9
- package/docs/images/wechat-qr.png +0 -0
- package/docs/spec-workflow.md +35 -4
- package/docs/zh/README.md +44 -331
- package/lib/adoption/adoption-strategy.js +5 -0
- package/lib/adoption/detection-engine.js +5 -0
- package/lib/adoption/file-classifier.js +6 -1
- package/lib/adoption/smart-orchestrator.js +5 -0
- package/lib/commands/adopt.js +32 -0
- package/lib/commands/errorbook.js +551 -4
- package/lib/commands/spec-domain.js +78 -2
- package/lib/commands/studio.js +550 -9
- package/lib/commands/upgrade.js +16 -0
- package/lib/problem/problem-evaluator.js +1035 -0
- package/lib/spec/domain-modeling.js +266 -5
- package/lib/workspace/takeover-baseline.js +514 -0
- package/package.json +1 -1
- package/template/.sce/config/problem-closure-policy.json +18 -0
- package/template/.sce/config/problem-eval-policy.json +78 -0
- package/template/.sce/config/session-governance.json +8 -0
- package/template/.sce/config/spec-domain-policy.json +14 -0
- package/template/.sce/config/takeover-baseline.json +33 -0
- package/template/.sce/steering/CORE_PRINCIPLES.md +4 -2
|
@@ -4,7 +4,19 @@ const path = require('path');
|
|
|
4
4
|
const DOMAIN_MAP_RELATIVE_PATH = path.join('custom', 'problem-domain-map.md');
|
|
5
5
|
const SCENE_SPEC_RELATIVE_PATH = path.join('custom', 'scene-spec.md');
|
|
6
6
|
const DOMAIN_CHAIN_RELATIVE_PATH = path.join('custom', 'problem-domain-chain.json');
|
|
7
|
+
const PROBLEM_CONTRACT_RELATIVE_PATH = path.join('custom', 'problem-contract.json');
|
|
7
8
|
const DOMAIN_CHAIN_API_VERSION = 'sce.problem-domain-chain/v0.1';
|
|
9
|
+
const DOMAIN_RESEARCH_DIMENSIONS = Object.freeze([
|
|
10
|
+
'scene_boundary',
|
|
11
|
+
'entity',
|
|
12
|
+
'relation',
|
|
13
|
+
'business_rule',
|
|
14
|
+
'decision_policy',
|
|
15
|
+
'execution_flow',
|
|
16
|
+
'failure_signal',
|
|
17
|
+
'debug_evidence_plan',
|
|
18
|
+
'verification_gate'
|
|
19
|
+
]);
|
|
8
20
|
|
|
9
21
|
function normalizeText(value) {
|
|
10
22
|
if (typeof value !== 'string') {
|
|
@@ -19,7 +31,30 @@ function resolveSpecPaths(projectPath, specId) {
|
|
|
19
31
|
specPath,
|
|
20
32
|
domainMapPath: path.join(specPath, DOMAIN_MAP_RELATIVE_PATH),
|
|
21
33
|
sceneSpecPath: path.join(specPath, SCENE_SPEC_RELATIVE_PATH),
|
|
22
|
-
domainChainPath: path.join(specPath, DOMAIN_CHAIN_RELATIVE_PATH)
|
|
34
|
+
domainChainPath: path.join(specPath, DOMAIN_CHAIN_RELATIVE_PATH),
|
|
35
|
+
problemContractPath: path.join(specPath, PROBLEM_CONTRACT_RELATIVE_PATH)
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function buildProblemContract(specId, options = {}) {
|
|
40
|
+
const sceneId = normalizeText(options.sceneId) || `scene.${specId.replace(/[^a-zA-Z0-9]+/g, '-').toLowerCase()}`;
|
|
41
|
+
const problemStatement = normalizeText(options.problemStatement) || 'TBD: describe the primary business problem';
|
|
42
|
+
const verificationPlan = normalizeText(options.verificationPlan) || 'TBD: define validation and rollback criteria';
|
|
43
|
+
return {
|
|
44
|
+
schema_version: '1.0',
|
|
45
|
+
spec_id: specId,
|
|
46
|
+
scene_id: sceneId,
|
|
47
|
+
issue_statement: problemStatement,
|
|
48
|
+
expected_outcome: verificationPlan,
|
|
49
|
+
reproduction_steps: [
|
|
50
|
+
'Reproduce the issue along the failing scene path.',
|
|
51
|
+
'Capture gate/test/runtime evidence for failed behavior.'
|
|
52
|
+
],
|
|
53
|
+
impact_scope: `scene=${sceneId}`,
|
|
54
|
+
forbidden_workarounds: [
|
|
55
|
+
'Do not bypass mandatory gates or tests.',
|
|
56
|
+
'Do not silence runtime errors without root-cause remediation.'
|
|
57
|
+
]
|
|
23
58
|
};
|
|
24
59
|
}
|
|
25
60
|
|
|
@@ -79,6 +114,20 @@ mindmap
|
|
|
79
114
|
4. Produce candidate fixes and risk tradeoffs.
|
|
80
115
|
5. Define verification path and measurable acceptance.
|
|
81
116
|
|
|
117
|
+
## Closed-Loop Research Coverage Matrix
|
|
118
|
+
|
|
119
|
+
| Dimension | Coverage Goal | Status |
|
|
120
|
+
| --- | --- | --- |
|
|
121
|
+
| Scene Boundary | Entry, scope, excluded boundaries are explicit | [ ] |
|
|
122
|
+
| Entity | Key entities are listed and scoped | [ ] |
|
|
123
|
+
| Relation | Entity relations and direction are explicit | [ ] |
|
|
124
|
+
| Business Rule | Enforceable rules are mapped | [ ] |
|
|
125
|
+
| Decision Policy | Decision branches and conditions are explicit | [ ] |
|
|
126
|
+
| Execution Flow | End-to-end action chain is explicit | [ ] |
|
|
127
|
+
| Failure Signal | Wrong-direction signals are listed | [ ] |
|
|
128
|
+
| Debug Evidence Plan | Debug-log/diagnostic evidence path is defined | [ ] |
|
|
129
|
+
| Verification Gate | Acceptance and gate criteria are explicit | [ ] |
|
|
130
|
+
|
|
82
131
|
## Correction Loop
|
|
83
132
|
|
|
84
133
|
- Expected Wrong-Direction Signals:
|
|
@@ -140,6 +189,12 @@ function buildSceneSpec(specId, options = {}) {
|
|
|
140
189
|
4. Expected outputs and side effects.
|
|
141
190
|
5. Failure path and rollback criteria.
|
|
142
191
|
|
|
192
|
+
## Closed-Loop Research Contract
|
|
193
|
+
|
|
194
|
+
- This Scene Spec is invalid if the domain mind map coverage matrix is missing.
|
|
195
|
+
- Decision and execution statements must map to ontology fields in \`problem-domain-chain.json\`.
|
|
196
|
+
- If two remediation rounds fail, debug evidence and diagnostic logs are mandatory before another patch round.
|
|
197
|
+
|
|
143
198
|
## Acceptance & Gate
|
|
144
199
|
|
|
145
200
|
- Functional acceptance: define testable behaviors.
|
|
@@ -208,6 +263,22 @@ function buildProblemDomainChain(specId, options = {}) {
|
|
|
208
263
|
expected_result: 'TBD: side effect and data change'
|
|
209
264
|
}
|
|
210
265
|
],
|
|
266
|
+
research_coverage: {
|
|
267
|
+
mode: 'scene-closed-loop',
|
|
268
|
+
required_dimensions: [...DOMAIN_RESEARCH_DIMENSIONS],
|
|
269
|
+
checklist: {
|
|
270
|
+
scene_boundary: true,
|
|
271
|
+
entity: true,
|
|
272
|
+
relation: true,
|
|
273
|
+
business_rule: true,
|
|
274
|
+
decision_policy: true,
|
|
275
|
+
execution_flow: true,
|
|
276
|
+
failure_signal: true,
|
|
277
|
+
debug_evidence_plan: true,
|
|
278
|
+
verification_gate: true
|
|
279
|
+
},
|
|
280
|
+
status: 'draft'
|
|
281
|
+
},
|
|
211
282
|
correction_loop: {
|
|
212
283
|
triggers: [
|
|
213
284
|
'gate failure',
|
|
@@ -227,6 +298,14 @@ function buildProblemDomainChain(specId, options = {}) {
|
|
|
227
298
|
'tests',
|
|
228
299
|
'release preflight'
|
|
229
300
|
]
|
|
301
|
+
},
|
|
302
|
+
problem_contract: buildProblemContract(specId, options),
|
|
303
|
+
ontology_evidence: {
|
|
304
|
+
entity: ['Entity mapping evidence: model/schema reference'],
|
|
305
|
+
relation: ['Relation mapping evidence: join/foreign-key or service linkage'],
|
|
306
|
+
business_rule: ['Rule evidence: validation/policy check reference'],
|
|
307
|
+
decision_policy: ['Decision evidence: branch condition and policy source'],
|
|
308
|
+
execution_flow: ['Execution evidence: service/screen/runtime trace path']
|
|
230
309
|
}
|
|
231
310
|
};
|
|
232
311
|
}
|
|
@@ -236,6 +315,7 @@ function validateProblemDomainMapContent(content = '') {
|
|
|
236
315
|
hasRootProblem: /##\s+Root Problem/i.test(content),
|
|
237
316
|
hasMindMapBlock: /```mermaid[\s\S]*mindmap/i.test(content),
|
|
238
317
|
hasLayeredExplorationChain: /##\s+Layered Exploration Chain/i.test(content),
|
|
318
|
+
hasCoverageMatrix: /##\s+Closed-Loop Research Coverage Matrix/i.test(content),
|
|
239
319
|
hasCorrectionLoop: /##\s+Correction Loop/i.test(content)
|
|
240
320
|
};
|
|
241
321
|
const passed = Object.values(checks).every(Boolean);
|
|
@@ -247,6 +327,7 @@ function validateSceneSpecContent(content = '') {
|
|
|
247
327
|
hasSceneDefinition: /##\s+Scene Definition/i.test(content),
|
|
248
328
|
hasOntologyCoverage: /##\s+Ontology Coverage/i.test(content),
|
|
249
329
|
hasDecisionExecutionPath: /##\s+Decision & Execution Path/i.test(content),
|
|
330
|
+
hasClosedLoopResearchContract: /##\s+Closed-Loop Research Contract/i.test(content),
|
|
250
331
|
hasAcceptanceGate: /##\s+Acceptance & Gate/i.test(content)
|
|
251
332
|
};
|
|
252
333
|
const passed = Object.values(checks).every(Boolean);
|
|
@@ -261,7 +342,41 @@ function hasNonEmptyStringArray(value) {
|
|
|
261
342
|
return Array.isArray(value) && value.some((item) => isNonEmptyString(item));
|
|
262
343
|
}
|
|
263
344
|
|
|
345
|
+
function isObject(value) {
|
|
346
|
+
return value && typeof value === 'object' && !Array.isArray(value);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
function isMeaningfulText(value) {
|
|
350
|
+
if (!isNonEmptyString(value)) {
|
|
351
|
+
return false;
|
|
352
|
+
}
|
|
353
|
+
const normalized = value.trim();
|
|
354
|
+
return !/^(tbd|todo|n\/a|na|待补|待定|待完善|placeholder)\b/i.test(normalized);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
function hasMeaningfulStringArray(value) {
|
|
358
|
+
return Array.isArray(value) && value.some((item) => isMeaningfulText(item));
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
function hasResearchCoverageChecklist(value) {
|
|
362
|
+
if (!isObject(value)) {
|
|
363
|
+
return false;
|
|
364
|
+
}
|
|
365
|
+
return DOMAIN_RESEARCH_DIMENSIONS.every((dimension) => typeof value[dimension] === 'boolean');
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
function hasResearchCoverageDimensions(value) {
|
|
369
|
+
if (!Array.isArray(value)) {
|
|
370
|
+
return false;
|
|
371
|
+
}
|
|
372
|
+
const normalized = new Set(value.map((item) => `${item || ''}`.trim()).filter(Boolean));
|
|
373
|
+
return DOMAIN_RESEARCH_DIMENSIONS.every((dimension) => normalized.has(dimension));
|
|
374
|
+
}
|
|
375
|
+
|
|
264
376
|
function validateProblemDomainChainPayload(payload = {}, specId = '') {
|
|
377
|
+
const researchCoverage = payload && isObject(payload.research_coverage)
|
|
378
|
+
? payload.research_coverage
|
|
379
|
+
: null;
|
|
265
380
|
const checks = {
|
|
266
381
|
apiVersion: isNonEmptyString(payload.api_version),
|
|
267
382
|
sceneId: isNonEmptyString(payload.scene_id),
|
|
@@ -275,6 +390,10 @@ function validateProblemDomainChainPayload(payload = {}, specId = '') {
|
|
|
275
390
|
hasHypotheses: Array.isArray(payload.hypotheses) && payload.hypotheses.length > 0,
|
|
276
391
|
hasRisks: Array.isArray(payload.risks) && payload.risks.length > 0,
|
|
277
392
|
hasDecisionPath: Array.isArray(payload.decision_execution_path) && payload.decision_execution_path.length >= 3,
|
|
393
|
+
hasResearchCoverageObject: Boolean(researchCoverage),
|
|
394
|
+
hasResearchCoverageMode: isNonEmptyString(researchCoverage && researchCoverage.mode),
|
|
395
|
+
hasResearchCoverageDimensions: hasResearchCoverageDimensions(researchCoverage && researchCoverage.required_dimensions),
|
|
396
|
+
hasResearchCoverageChecklist: hasResearchCoverageChecklist(researchCoverage && researchCoverage.checklist),
|
|
278
397
|
hasCorrectionTriggers: hasNonEmptyStringArray(payload?.correction_loop?.triggers),
|
|
279
398
|
hasCorrectionActions: hasNonEmptyStringArray(payload?.correction_loop?.actions),
|
|
280
399
|
hasVerificationGates: hasNonEmptyStringArray(payload?.verification?.gates)
|
|
@@ -285,6 +404,104 @@ function validateProblemDomainChainPayload(payload = {}, specId = '') {
|
|
|
285
404
|
};
|
|
286
405
|
}
|
|
287
406
|
|
|
407
|
+
function buildDomainCoverageItems(chainPayload = {}, validation = null) {
|
|
408
|
+
const ontology = isObject(chainPayload && chainPayload.ontology) ? chainPayload.ontology : {};
|
|
409
|
+
const correctionLoop = isObject(chainPayload && chainPayload.correction_loop) ? chainPayload.correction_loop : {};
|
|
410
|
+
const verification = isObject(chainPayload && chainPayload.verification) ? chainPayload.verification : {};
|
|
411
|
+
const researchCoverage = isObject(chainPayload && chainPayload.research_coverage)
|
|
412
|
+
? chainPayload.research_coverage
|
|
413
|
+
: {};
|
|
414
|
+
|
|
415
|
+
const structuralItems = [];
|
|
416
|
+
if (validation && isObject(validation.details)) {
|
|
417
|
+
structuralItems.push({
|
|
418
|
+
id: 'map_structure',
|
|
419
|
+
label: 'problem-domain-map structure',
|
|
420
|
+
covered: Boolean(validation.details.domain_map && validation.details.domain_map.exists && validation.details.domain_map.checks && Object.values(validation.details.domain_map.checks).every(Boolean)),
|
|
421
|
+
evidence: DOMAIN_MAP_RELATIVE_PATH
|
|
422
|
+
});
|
|
423
|
+
structuralItems.push({
|
|
424
|
+
id: 'scene_structure',
|
|
425
|
+
label: 'scene-spec structure',
|
|
426
|
+
covered: Boolean(validation.details.scene_spec && validation.details.scene_spec.exists && validation.details.scene_spec.checks && Object.values(validation.details.scene_spec.checks).every(Boolean)),
|
|
427
|
+
evidence: SCENE_SPEC_RELATIVE_PATH
|
|
428
|
+
});
|
|
429
|
+
structuralItems.push({
|
|
430
|
+
id: 'chain_structure',
|
|
431
|
+
label: 'problem-domain-chain structure',
|
|
432
|
+
covered: Boolean(validation.details.domain_chain && validation.details.domain_chain.exists && validation.details.domain_chain.checks && Object.values(validation.details.domain_chain.checks).every(Boolean)),
|
|
433
|
+
evidence: DOMAIN_CHAIN_RELATIVE_PATH
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
const domainItems = [
|
|
438
|
+
{
|
|
439
|
+
id: 'scene_boundary',
|
|
440
|
+
label: 'Scene boundary',
|
|
441
|
+
covered: isMeaningfulText(chainPayload?.problem?.statement) && isMeaningfulText(chainPayload?.problem?.scope),
|
|
442
|
+
evidence: 'problem.statement + problem.scope'
|
|
443
|
+
},
|
|
444
|
+
{
|
|
445
|
+
id: 'entity',
|
|
446
|
+
label: 'Ontology entity coverage',
|
|
447
|
+
covered: hasMeaningfulStringArray(ontology.entity),
|
|
448
|
+
evidence: 'ontology.entity[]'
|
|
449
|
+
},
|
|
450
|
+
{
|
|
451
|
+
id: 'relation',
|
|
452
|
+
label: 'Ontology relation coverage',
|
|
453
|
+
covered: hasMeaningfulStringArray(ontology.relation),
|
|
454
|
+
evidence: 'ontology.relation[]'
|
|
455
|
+
},
|
|
456
|
+
{
|
|
457
|
+
id: 'business_rule',
|
|
458
|
+
label: 'Business rule coverage',
|
|
459
|
+
covered: hasMeaningfulStringArray(ontology.business_rule),
|
|
460
|
+
evidence: 'ontology.business_rule[]'
|
|
461
|
+
},
|
|
462
|
+
{
|
|
463
|
+
id: 'decision_policy',
|
|
464
|
+
label: 'Decision policy coverage',
|
|
465
|
+
covered: hasMeaningfulStringArray(ontology.decision_policy),
|
|
466
|
+
evidence: 'ontology.decision_policy[]'
|
|
467
|
+
},
|
|
468
|
+
{
|
|
469
|
+
id: 'execution_flow',
|
|
470
|
+
label: 'Execution flow coverage',
|
|
471
|
+
covered: hasMeaningfulStringArray(ontology.execution_flow),
|
|
472
|
+
evidence: 'ontology.execution_flow[]'
|
|
473
|
+
},
|
|
474
|
+
{
|
|
475
|
+
id: 'failure_signal',
|
|
476
|
+
label: 'Failure-signal coverage',
|
|
477
|
+
covered: hasMeaningfulStringArray(correctionLoop.triggers),
|
|
478
|
+
evidence: 'correction_loop.triggers[]'
|
|
479
|
+
},
|
|
480
|
+
{
|
|
481
|
+
id: 'debug_evidence_plan',
|
|
482
|
+
label: 'Debug evidence plan',
|
|
483
|
+
covered: Array.isArray(correctionLoop.actions)
|
|
484
|
+
&& correctionLoop.actions.some((item) => /debug|diagnostic|日志|evidence/i.test(`${item || ''}`)),
|
|
485
|
+
evidence: 'correction_loop.actions[]'
|
|
486
|
+
},
|
|
487
|
+
{
|
|
488
|
+
id: 'verification_gate',
|
|
489
|
+
label: 'Verification gate coverage',
|
|
490
|
+
covered: hasMeaningfulStringArray(verification.gates),
|
|
491
|
+
evidence: 'verification.gates[]'
|
|
492
|
+
},
|
|
493
|
+
{
|
|
494
|
+
id: 'research_contract',
|
|
495
|
+
label: 'Research contract checklist',
|
|
496
|
+
covered: hasResearchCoverageChecklist(researchCoverage.checklist)
|
|
497
|
+
&& hasResearchCoverageDimensions(researchCoverage.required_dimensions),
|
|
498
|
+
evidence: 'research_coverage.required_dimensions + checklist'
|
|
499
|
+
}
|
|
500
|
+
];
|
|
501
|
+
|
|
502
|
+
return [...structuralItems, ...domainItems];
|
|
503
|
+
}
|
|
504
|
+
|
|
288
505
|
async function ensureSpecDomainArtifacts(projectPath, specId, options = {}) {
|
|
289
506
|
const fileSystem = options.fileSystem || fs;
|
|
290
507
|
const dryRun = options.dryRun === true;
|
|
@@ -294,11 +511,13 @@ async function ensureSpecDomainArtifacts(projectPath, specId, options = {}) {
|
|
|
294
511
|
const domainMapContent = buildProblemDomainMindMap(specId, options);
|
|
295
512
|
const sceneSpecContent = buildSceneSpec(specId, options);
|
|
296
513
|
const domainChainPayload = buildProblemDomainChain(specId, options);
|
|
514
|
+
const problemContractPayload = buildProblemContract(specId, options);
|
|
297
515
|
|
|
298
516
|
const created = {
|
|
299
517
|
domain_map: false,
|
|
300
518
|
scene_spec: false,
|
|
301
|
-
domain_chain: false
|
|
519
|
+
domain_chain: false,
|
|
520
|
+
problem_contract: false
|
|
302
521
|
};
|
|
303
522
|
|
|
304
523
|
if (!dryRun) {
|
|
@@ -321,23 +540,32 @@ async function ensureSpecDomainArtifacts(projectPath, specId, options = {}) {
|
|
|
321
540
|
await fileSystem.writeJson(paths.domainChainPath, domainChainPayload, { spaces: 2 });
|
|
322
541
|
created.domain_chain = true;
|
|
323
542
|
}
|
|
543
|
+
|
|
544
|
+
const hasProblemContract = await fileSystem.pathExists(paths.problemContractPath);
|
|
545
|
+
if (force || !hasProblemContract) {
|
|
546
|
+
await fileSystem.writeJson(paths.problemContractPath, problemContractPayload, { spaces: 2 });
|
|
547
|
+
created.problem_contract = true;
|
|
548
|
+
}
|
|
324
549
|
} else {
|
|
325
550
|
created.domain_map = true;
|
|
326
551
|
created.scene_spec = true;
|
|
327
552
|
created.domain_chain = true;
|
|
553
|
+
created.problem_contract = true;
|
|
328
554
|
}
|
|
329
555
|
|
|
330
556
|
return {
|
|
331
557
|
paths: {
|
|
332
558
|
domain_map: paths.domainMapPath,
|
|
333
559
|
scene_spec: paths.sceneSpecPath,
|
|
334
|
-
domain_chain: paths.domainChainPath
|
|
560
|
+
domain_chain: paths.domainChainPath,
|
|
561
|
+
problem_contract: paths.problemContractPath
|
|
335
562
|
},
|
|
336
563
|
created,
|
|
337
564
|
preview: {
|
|
338
565
|
domain_map: domainMapContent,
|
|
339
566
|
scene_spec: sceneSpecContent,
|
|
340
|
-
domain_chain: domainChainPayload
|
|
567
|
+
domain_chain: domainChainPayload,
|
|
568
|
+
problem_contract: problemContractPayload
|
|
341
569
|
}
|
|
342
570
|
};
|
|
343
571
|
}
|
|
@@ -426,14 +654,47 @@ async function validateSpecDomainArtifacts(projectPath, specId, fileSystem = fs)
|
|
|
426
654
|
};
|
|
427
655
|
}
|
|
428
656
|
|
|
657
|
+
async function analyzeSpecDomainCoverage(projectPath, specId, fileSystem = fs) {
|
|
658
|
+
const validation = await validateSpecDomainArtifacts(projectPath, specId, fileSystem);
|
|
659
|
+
const paths = resolveSpecPaths(projectPath, specId);
|
|
660
|
+
let chainPayload = null;
|
|
661
|
+
|
|
662
|
+
if (await fileSystem.pathExists(paths.domainChainPath)) {
|
|
663
|
+
try {
|
|
664
|
+
chainPayload = await fileSystem.readJson(paths.domainChainPath);
|
|
665
|
+
} catch (_error) {
|
|
666
|
+
chainPayload = null;
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
const items = buildDomainCoverageItems(chainPayload || {}, validation);
|
|
671
|
+
const coveredCount = items.filter((item) => item.covered).length;
|
|
672
|
+
const totalCount = items.length;
|
|
673
|
+
const uncovered = items.filter((item) => !item.covered).map((item) => item.id);
|
|
674
|
+
|
|
675
|
+
return {
|
|
676
|
+
passed: uncovered.length === 0,
|
|
677
|
+
coverage_ratio: totalCount > 0 ? coveredCount / totalCount : 0,
|
|
678
|
+
covered_count: coveredCount,
|
|
679
|
+
total_count: totalCount,
|
|
680
|
+
uncovered,
|
|
681
|
+
items,
|
|
682
|
+
validation
|
|
683
|
+
};
|
|
684
|
+
}
|
|
685
|
+
|
|
429
686
|
module.exports = {
|
|
430
687
|
DOMAIN_MAP_RELATIVE_PATH,
|
|
431
688
|
SCENE_SPEC_RELATIVE_PATH,
|
|
432
689
|
DOMAIN_CHAIN_RELATIVE_PATH,
|
|
690
|
+
PROBLEM_CONTRACT_RELATIVE_PATH,
|
|
433
691
|
DOMAIN_CHAIN_API_VERSION,
|
|
692
|
+
DOMAIN_RESEARCH_DIMENSIONS,
|
|
434
693
|
buildProblemDomainMindMap,
|
|
435
694
|
buildSceneSpec,
|
|
436
695
|
buildProblemDomainChain,
|
|
696
|
+
buildProblemContract,
|
|
437
697
|
ensureSpecDomainArtifacts,
|
|
438
|
-
validateSpecDomainArtifacts
|
|
698
|
+
validateSpecDomainArtifacts,
|
|
699
|
+
analyzeSpecDomainCoverage
|
|
439
700
|
};
|